From be4889600b18b90511eb64993500785851859a5a Mon Sep 17 00:00:00 2001 From: chee Date: Mon, 11 Jan 2021 23:25:29 +0000 Subject: [PATCH] add polyphony --- README.md | 5 +++ src/main.cc | 112 ++++++++++++++++++++++++++++++++++++++++------------ 2 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..5bcde72 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# wavetablet + +This is mostly just a little wrapper around paul's teensy audio library synth_wavetable, updated to make sure it runs on the ATSAMD51 with adafruit's atsamd fork of Audio. + +the `decoder.py` here is taken the teensy AudioSynthWaveform repo, with changes to make it output parsed soundfonts in the format expressed in the `synth_wavetable.cpp` file from the Audio repo \ No newline at end of file diff --git a/src/main.cc b/src/main.cc index e770e32..c0c6bfc 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,23 +1,37 @@ #include -#include -#include -#include #include +#include +#include #include +#include #include -#include -#include + +// #include +// #include #include +auto instrument = lead; // Audio mixers can take 4 inputs // Let's have 8 inputs in total for an 8-finger polyphonic synth AudioMixer4 left_hand; AudioMixer4 right_hand; -AudioSynthWavetable synth1; -AudioSynthKarplusStrong string1; -AudioConnection patch1(synth1, 0, left_hand, 0); -AudioConnection patch2(string1, 0, left_hand, 1); +const int len_voices = 4 * 2; + +AudioSynthWavetable wavetable0, wavetable1, wavetable2, wavetable3, wavetable4, + wavetable5, wavetable6, wavetable7; +AudioSynthWavetable *wavetables[]{&wavetable0, &wavetable1, &wavetable2, + &wavetable3, &wavetable4, &wavetable5, + &wavetable6, &wavetable7}; + +AudioConnection tl0(wavetable0, 0, left_hand, 0); +AudioConnection tl1(wavetable1, 0, left_hand, 1); +AudioConnection tl2(wavetable2, 0, left_hand, 2); +AudioConnection tl3(wavetable3, 0, left_hand, 3); +AudioConnection tr4(wavetable4, 0, right_hand, 0); +AudioConnection tr5(wavetable5, 0, right_hand, 1); +AudioConnection tr6(wavetable6, 0, right_hand, 2); +AudioConnection tr7(wavetable7, 0, right_hand, 3); // mixers can take mixers as inputs, so let's create another to be sent to both // speakers. pc2064v1 will be a polyphonic synth with monophonic output @@ -33,27 +47,75 @@ AudioConnection patch_right_ear(mixer, 0, audioOut, 1); // some day to replace this with tinyusb again USBMIDI_CREATE_DEFAULT_INSTANCE(); +class Voice { +public: + int id; + byte note; + int age; +}; + +Voice voices[len_voices]; + +int age = 0; + +void play(Voice *voice, byte note, byte velocity) { + auto wt = wavetables[voice->id]; + voice->note = note; + voice->age = age++; + wt->playNote(voice->note, velocity); +} + void noteOn(byte channel, byte note, byte velocity) { - Serial.printf("c: %d, note: %d, v: %d", channel, note, velocity); - AudioNoInterrupts(); - synth1.playNote(note, 100); - // string1.noteOn(synth1.noteToFreq(note), 0.9); - AudioInterrupts(); + int oldest_age = infinity(); + int oldest_index = 0; + + // get a free one + for (int i = 0; i < len_voices; i++) { + if (wavetables[i]->getEnvState() == + AudioSynthWavetable::envelopeStateEnum::STATE_IDLE) { + return play(&voices[i], note, velocity); + } + + // ok, a releasing one then + if (wavetables[i]->getEnvState() == + AudioSynthWavetable::envelopeStateEnum::STATE_RELEASE) { + return play(&voices[i], note, velocity); + } + + // or the eldest + if (voices[i].age < oldest_age) { + oldest_index = i; + oldest_age = voices[i].age; + } + } + + play(&voices[oldest_index], note, velocity); } void noteOff(byte channel, byte note, byte velocity) { - Serial.printf("c: %d, note: %d, v: %d", channel, note, velocity); - synth1.stop(); + bool nothing = true; + for (int i = 0; i < len_voices; i++) { + if (wavetables[i]->getEnvState()) { + nothing = false; + } + if (voices[i].note == note) { + wavetables[i]->stop(); + } + } + if (nothing) { + age = 0; + } } void setup() { - synth1.setInstrument(lead); - synth1.amplitude(1); - Serial.println("hello, jerg"); - left_hand.gain(0, 1.0); - right_hand.gain(0, 1.0); - mixer.gain(0, 0.5); - mixer.gain(1, 0.5); + for (int i = 0; i < len_voices; i++) { + voices[i].id = i; + wavetables[i]->setInstrument(instrument); + wavetables[i]->amplitude(1); + } + + mixer.gain(0, 0.01); + mixer.gain(1, 0.01); AudioMemory(22); AudioProcessorUsageMaxReset(); AudioMemoryUsageMaxReset(); @@ -62,6 +124,4 @@ void setup() { MIDI.setHandleNoteOff(noteOff); } -void loop() { - MIDI.read(); -} \ No newline at end of file +void loop() { MIDI.read(); } \ No newline at end of file