Skip to content

Instantly share code, notes, and snippets.

@LeoAdamek
Created May 6, 2017 22:02
Show Gist options
  • Save LeoAdamek/2adc26d593a3de9257b63c17643ab016 to your computer and use it in GitHub Desktop.
Save LeoAdamek/2adc26d593a3de9257b63c17643ab016 to your computer and use it in GitHub Desktop.
Polyphonic Synth
#include <Audio.h>
#include <MIDI.h>
typedef struct {
AudioSynthWaveformSine osc;
byte note;
float freq;
float amp;
AudioConnection w_lft;
AudioConnection w_rgt;
} Voice;
AudioOutputAnalog uselessOutput;
AudioOutputUSB audioRet;
AudioMixer4 mixA, mixB, mixC;
Voice* voices;
unsigned char activeVoices, i;
void setup() {
AudioMemory(32);
activeVoices = 0x00;
voices = (Voice*)malloc(6 * sizeof(Voice));
// Connect the first 3 voices to mixA
AudioConnection v0mA(voices[0].osc, 0, mixA, 0);
AudioConnection v1mA(voices[1].osc, 0, mixA, 1);
AudioConnection v2mA(voices[2].osc, 0, mixA, 2);
// Connect the last 3 voices to mixB
AudioConnection v3mB(voices[3].osc, 0, mixB, 0);
AudioConnection v4mB(voices[4].osc, 0, mixB, 1);
AudioConnection v5mB(voices[5].osc, 0, mixB, 2);
// Connect mix A and B to mix C
AudioConnection mAmC(mixA, 0, mixC, 0);
AudioConnection mBmC(mixB, 0, mixC, 1);
// Connect mix C to Output L and R
AudioConnection mCoL(mixC, 0, audioRet, 0);
AudioConnection mCoR(mixC, 0, audioRet, 1);
// Serial will be used for debugging messages.
Serial.begin(9600);
// Callbacks for note handling.
usbMIDI.setHandleNoteOff(OnNoteOff);
usbMIDI.setHandleNoteOn(OnNoteOn);
Serial.println("Teensynth (teensy-unth) v0 @ " __FILE__);
}
void loop() {
// Continuously read and handle MIDI messages.
usbMIDI.read();
}
void OnNoteOn(byte channel, byte note, byte vel) {
for(i = 0; i < 6; i++) {
// Serial.printf("i = %d \t v = %01x \t a = %01x\n", i, (1<<i), (activeVoices & (1<<i)));
if ( (activeVoices & (1<<i)) == 0) {
//Serial.printf("Voice %0d on.\n", i);
activeVoices |= (1<<i);
voices[i].amp = 1;
voices[i].note = note;
voices[i].freq = noteToFreq(note);
voices[i].osc.amplitude(1);
voices[i].osc.frequency(voices[i].freq);
break;
}
}
Serial.printf("Active Voices: %0x\n", activeVoices);
}
void OnNoteOff(byte channel, byte note, byte vel) {
for(i = 0; i < 6; i++) {
//Serial.printf("i = %0d \t v = %02x \t a = %02x\n", i, (1<<i), (activeVoices & (1<<i)));
//Serial.printf("v[i].note = %02x\n", voices[i].note);
if(voices[i].note == note && (activeVoices & (1<<i)) != 0 ) {
//Serial.printf("Voice %0d Off.", i);
voices[i].note = 0xff;
voices[i].amp = 0;
voices[i].osc.amplitude(0);
activeVoices &= ~(1<<i);
break;
}
}
Serial.printf("Active Voices: %0x\n", activeVoices);
}
// Convert MIDI note to tonal freq.
//
// Formula: 440 * 2^( midi_note_val - 69) / 12)
float noteToFreq(byte note) {
float freq = 440 * pow(2, (float(note - 69) / 12));
// Serial.printf("Note: %x // Freq: %.2fHz\n", note, freq);
return freq;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment