Skip to content

Instantly share code, notes, and snippets.

@LeoAdamek
Created May 6, 2017 23:17
Show Gist options
  • Save LeoAdamek/040ceed870821411a34f5a9764011ac5 to your computer and use it in GitHub Desktop.
Save LeoAdamek/040ceed870821411a34f5a9764011ac5 to your computer and use it in GitHub Desktop.
Polysynth
#include <Audio.h>
#include <MIDI.h>
typedef struct {
AudioSynthWaveformSine* osc;
byte note;
float freq;
float amp;
} Voice;
AudioSynthWaveformSine voice0, voice1, voice2, voice3, voice4, voice5;
AudioOutputAnalog uselessOutput;
AudioOutputUSB audioRet;
AudioMixer4 mixA, mixB, mixC;
Voice* voices;
unsigned char activeVoices, i;
// Connect the first 3 voices to mixA
AudioConnection v0mA(voice0, 0, mixA, 0);
AudioConnection v1mA(voice1, 0, mixA, 1);
AudioConnection v2mA(voice2, 0, mixA, 2);
// Connect the last 3 voices to mixB
AudioConnection v3mB(voice3, 0, mixB, 0);
AudioConnection v4mB(voice4, 0, mixB, 1);
AudioConnection v5mB(voice5, 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);
void setup() {
AudioMemory(32);
activeVoices = 0x00;
voices = (Voice*)malloc(6 * sizeof(Voice));
// Doesn't like this for some reason... not sure why :(
voices[0].osc = &voice0;
voices[1].osc = &voice1;
voices[2].osc = &voice2;
voices[3].osc = &voice3;
voices[4].osc = &voice4;
voices[5].osc = &voice5;
// 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);
/*
AudioSynthWaveformSine* osc = voices[i]->osc;
osc->amplitude(1);
osc->frequency(voices[i]->freq);
*/
break;
}
}
Serial.printf("Active Voices: %0x\n", activeVoices);
//Serial.printf("Audio Memory: %02x\n", AudioMemoryUsage());
}
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;
/*
AudioSynthWaveformSine* osc;
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