I have described in my last blog how to build a simple Synthesizer with my Arduino Audio Tools library to support the AI Thinker Audio Kit which is based on the ES8388 audio chip.

Audio Kit

In the meantime I have decided to wrap the described solution into it’s own Synthesizer class and solve the problem that we can generate only one tone at the time by putting the audio chain into a separate class for each output channel.

Here is the result and you can now create a multi channel Synth with 30 lines of code:

The Basic Synthesizer Arduino Sketch


#include "AudioTools.h" #include "AudioTools/Synthesizer.h" #include "AudioLibs/AudioKit.h" AudioKitStream kit; Synthesizer synthesizer; GeneratedSoundStream<int16_t> in(synthesizer); StreamCopy copier(kit, in); SynthesizerKey keys[] = {{PIN_KEY1, N_C3},{PIN_KEY2, N_D3},{PIN_KEY3, N_E3},{PIN_KEY4, N_F3},{PIN_KEY5, N_G3},{PIN_KEY6, N_A3},{0,0}}; void setup() { Serial.begin(115200); AudioLogger::instance().begin(Serial,AudioLogger::Warning); // Setup output auto cfg = kit.defaultConfig(TX_MODE); kit.setVolume(80); kit.begin(cfg); // define synthesizer keys for AudioKit synthesizer.setKeys(kit.audioActions(), keys, AudioActions::ActiveLow); // Setup sound generation & synthesizer based on AudioKit default settings in.begin(cfg); } void loop() { copier.copy(); kit.processActions(); }

The Synthesizer has been set up as a subclass of a SoundGenerator. So we can convert it to a Stream with the help of a GeneratedSoundStream. From there we just copy the generated audio data to the output stream: AudioKitStream in our case. Please note that you can replace this with any output stream that the framework offers!

Clicking individual keys is working fine…but hitting multiple keys at once is producing some nasty noise. I wonder what the issue could be Let’s try to output the sound on some better quality Bluetooth Speakers. But that’s for my next post

Extending the Synthesizer

You might have noticed that we seem to have lost a lot of flexibility and the question is how can change the underlying sound generation ?
We have a few possibilities:

  • Create your own implementation of AbstractSyntheizerChannel from scratch
  • Configure the DefaultSyntheizerChannel

Here is a demo for the configuration option:

auto *channel = new DefaultSynthesizerChannel<AudioEffects<SquareWaveGenerator<int16_t>>>();
Synthesizer synthesizer(channel);


void setup() {
  Serial.begin(115200);
  AudioLogger::instance().begin(Serial,AudioLogger::Warning);

  // Setup output
  auto cfg = kit.defaultConfig(TX_MODE);
  kit.begin(cfg);

  // define Effects
  channel->addEffect(new Tremolo(2000, 50, cfg.sample_rate));

  // define synthesizer keys for AudioKit
  synthesizer.setKeys(kit.audioActions(), keys, AudioActions::ActiveLow);

  // Setup sound generation based on AudioKit settings
  in.begin(cfg);
}

Here we configure our own sound generation channel to use a AudioEffects which starts with our own “bad-ass” SquareWaveGenerator and (in the setup) we add a Tremolo effect…

Source Code

The (potentially updated) source code is available in the examples directory.


0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published.