Created
May 6, 2017 23:17
-
-
Save LeoAdamek/040ceed870821411a34f5a9764011ac5 to your computer and use it in GitHub Desktop.
Polysynth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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