/* -------Arduino Proto-Synth 08/07/07 --------Collin Cunningham - Narbotic.net --------with portions of code from "Freqout" by Paul Badger and "MIDI drum kit" by Tod E. Kurt This is my stab at a monophonic synthesizer for the Arduino and my first stab at coding anything really. It reads input on Analog0 for a stepped pitch transposition. Each note switch(digipins 1-10 & 13) connects to ground in order to register. Higher notes get priority. Pin 11 is speaker output. I used a little RC Low Pass Filter to smooth out the sound: PIN11->------\/\/\---o----\/\/\----o-------> OUTPUT 1K | 1K | | | .1uF_cap .1uF_cap | | GND GND (no clue how to draw caps in ascii) Features I'd like to add - Another octave (maybe add a transpose switch on each of the next octave, then they can share pins with the first) - Last note hit priority - Portamento (note-slide) - Real sine wave out (no external LPF anymore please) - Polyphony (I had it working badly, need better math) - any real keyboard feature in existance(or not) attack, decay, waveform, vibrato, etc. Contact me at narbotic.net with any suggestions/help - and if you improve any of the code please send it on over. */ #include #define switchAPin 0 #define switchBPin 1 #define switchCPin 2 #define switchDPin 3 #define switchEPin 4 #define switchFPin 5 #define switchGPin 6 #define switchHPin 7 #define switchIPin 8 #define switchJPin 9 #define switchKPin 10 #define switchLPin 12 #define switchMPin 13 #define pitchPin 0 #define speakerOut 11 int pitchval = 1; int val = 0; int freq,t; float noteval; //note values float C = 130.8; float CS = 138.6; float D = 146.8; float DS = 155.6; float E = 164.8; float F = 174.6; float FS = 185; float G = 196; float GS = 207.7; float A2 = 220; float A2S = 233.1; float B2 = 246.9; float C2 = 261.6; float C2S = 277.2; float D2 = 293.7; float D2S = 311.1; float E2 = 329.6; float F2 = 349.2; float F2S = 370; float G2 = 392; float G2S = 415.3; float A3 = 440; void setup() { pinMode(switchAPin, INPUT); pinMode(switchBPin, INPUT); pinMode(switchCPin, INPUT); pinMode(switchDPin, INPUT); pinMode(switchEPin, INPUT); pinMode(switchFPin, INPUT); pinMode(switchGPin, INPUT); pinMode(switchHPin, INPUT); pinMode(switchIPin, INPUT); pinMode(switchJPin, INPUT); pinMode(switchKPin, INPUT); pinMode(switchLPin, INPUT); pinMode(switchMPin, INPUT); pinMode(speakerOut, OUTPUT); digitalWrite(switchAPin, HIGH); // turn on internal pullup digitalWrite(switchBPin, HIGH); // turn on internal pullup digitalWrite(switchCPin, HIGH); // turn on internal pullup digitalWrite(switchDPin, HIGH); // turn on internal pullup digitalWrite(switchEPin, HIGH); // turn on internal pullup digitalWrite(switchFPin, HIGH); // turn on internal pullup digitalWrite(switchGPin, HIGH); // turn on internal pullup digitalWrite(switchHPin, HIGH); // turn on internal pullup digitalWrite(switchIPin, HIGH); // turn on internal pullup digitalWrite(switchJPin, HIGH); // turn on internal pullup digitalWrite(switchKPin, HIGH); // turn on internal pullup digitalWrite(switchLPin, HIGH); // turn on internal pullup digitalWrite(switchMPin, HIGH); // turn on internal pullup } // Pins are read in reverse to give higher key priority void loop() { if( analogRead(pitchPin) > 150) { pitchval = (analogRead(pitchPin) / 100); //a shot in the dark } else if( analogRead(pitchPin) <= 15) { pitchval = 1; } if( digitalRead(switchMPin) == LOW ) { noteval = C2; freqout((int)noteval, t); } else if( digitalRead(switchLPin) == LOW ) { noteval = B2; freqout((int)noteval, t); } else if( digitalRead(switchKPin) == LOW ) { noteval = A2S; freqout((int)noteval, t); } else if( digitalRead(switchJPin) == LOW ) { noteval = A2; freqout((int)noteval, t); } else if( digitalRead(switchIPin) == LOW ) { noteval = GS; freqout((int)noteval, t); } else if( digitalRead(switchHPin) == LOW ) { noteval = G; freqout((int)noteval, t); } else if( digitalRead(switchGPin) == LOW ) { noteval = FS; freqout((int)noteval, t); } else if( digitalRead(switchFPin) == LOW ) { noteval = F; freqout((int)noteval, t); } else if( digitalRead(switchEPin) == LOW ) { noteval = E; freqout((int)noteval, t); } else if( digitalRead(switchDPin) == LOW ) { noteval = DS; freqout((int)noteval, t); } else if( digitalRead(switchCPin) == LOW ) { noteval = D; freqout((int)noteval, t); } else if( digitalRead(switchBPin) == LOW ) { noteval = CS; freqout((int)noteval, t); } else if( digitalRead(switchAPin) == LOW ) { noteval = C; freqout((int)noteval, t); } else { digitalWrite(speakerOut, LOW); } } //freqout code by Paul Badger (and hacked a bit by me) void freqout(int freq, int t) { int hperiod; //calculate 1/2 period in us long cycles, i; hperiod = (500000 / ((freq - 7) * pitchval)); // subtract 7 us to make up for digitalWrite overhead - determined empirically // calculate cycles cycles = ((long)freq * (long)t) / 1000; // calculate cycles for (i=0; i<= cycles; i++){ // play note for t ms digitalWrite(speakerOut, HIGH); delayMicroseconds(hperiod); digitalWrite(speakerOut, LOW); delayMicroseconds(hperiod - 1); // - 1 to make up for fractional microsecond in digitaWrite overhead } }