Bluetooth Enabled Keyboard/Synthesizer for mbed

Dependencies:   mbed 4DGL-uLCD-SE SDFileSystem mbed-rtos

Revision:
8:f6699fd30737
Parent:
7:d4c3260cb092
Child:
9:e4df1a31a098
--- a/main.cpp	Thu Apr 28 19:31:28 2016 +0000
+++ b/main.cpp	Thu Apr 28 22:16:40 2016 +0000
@@ -15,6 +15,8 @@
 
 uLCD_4DGL uLCD(p13,p14,p11); // serial tx, serial rx, reset pin;
 
+AnalogOut synthPin(p18);     // p18 is the pin that will have the output voltages on it
+
 
 //global variables for main and interrupt routine
 volatile bool readyFlag = true;
@@ -39,6 +41,7 @@
 volatile int frequencyTuner;        // the frequency tuner used to increment the accumulator which indexes values in the lookup table
 volatile int noteFreq;              // the current frequency of the note being played
 volatile int sustainAmplitude;      // the desired amplitude of the sustain level
+double timeIncrement = (2/256);     // 2 seconds with 256 samples
 
 /* Coefficient Matrices Corresponding to Different Attack Values
 each matrix is comprised of 32 elements (256/8). The first matrix corresponds
@@ -146,56 +149,12 @@
 0.690322581 , 0.677419355 , 0.664516129 , 0.651612903 , 
 0.638709677 , 0.625806452 , 0.612903226 , 0.6
 };
-double sustainVals5[160] = {  //Highest level of sustain, the note will cap out at an amplitude of 1 - corresponds to sustain value of 5
-.8 , .6 , .6 , .6 ,
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6  
-};
-double sustainVal4[160] = {   //Sustain value of 4
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6
-};
-double sustainVals3[160] = {  //Sustain value of 3
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6
-};
-double sustainVals2[160] = {  //Sustain value of 2
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6
-};
-double sustainVals1[160] = {  //Lowest level of sustain, the note will cap at at an amplitude of .2 - corresponds to sustain value of 1
-.6 , .6 , .6 , .6 ,
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6 , 
-.6 , .6 , .6 , .6
-};
+
+double sustainVals5[160]; 
+double sustainVals4[160];
+double sustainVals3[160];
+double sustainVals2[160];
+double sustainVals1[160];
 double releaseVals5[32] = {
     };
 double releaseVals4[32] = {
@@ -470,6 +429,17 @@
     break;
     }
 } 
+void initialize_sustainVals()
+{
+    for(int j = 0; j < 160; j++)
+    {
+        sustainVals5[j] = .6;
+        sustainVals4[j] = .6;
+        sustainVals3[j] = .6;
+        sustainVals2[j] = .6;
+        sustainVals1[j] = .6;
+    }
+}
 
 void clear_Buffer(void){
     sampleBuffer.clear();
@@ -507,14 +477,73 @@
     }     
 }
 
-
+void create_samples(int frequency, waveType currentWaveType)
+{
+    switch(currentWaveType){
+        case sine:
+            //Generate sine wave values
+            generate_sineWave(frequency);
+            apply_Envelope();
+            break;
+        case square:
+            //Generate square wave values
+            generate_squareWave(frequency);
+            apply_Envelope();
+            break;
+        case sawtooth:
+            //Generate sawtooth wave values
+            generate_sawtoothWave(frequency);
+            apply_Envelope();
+            break;
+        default:
+        break;
+    }
+}
 
-
+void generate_sineWave(int frequency)
+{
+    double t = 0;   
+    for(i = 0; i < 256 ; i++)
+    {
+        sampleBuffer.push_back(((sin(2*(PI)*frequency*t)) + 1)/2);  // scaled to be a % of maximum output voltage (3.3V)
+        t = t + timeIncrement;                                       // increment t for calculation of next value in the waveform   
+    }
+}
 
-
+void generate_sawtoothWave(int frequency)
+{
+    double t = 0;
+    for(i = 0; i<256 ; i++)
+    {
+        sampleBuffer.push_back((2*(t*frequency) - (.5 + (t*frequency)) + 1) / 2);
+        t = t + timeIncrement;                       // increment t for calculation of next value in the waveform   
+    }
+}
 
+void generate_squareWave(int frequency)
+{
+    double width = (1 / 2 * frequency);     //Width of a half period of the square wave
+    double t = 0;
+    for(i = 0; i < 256; i++)
+    {
+        if((int)(t / width) % 2 ) == 0)     // Even, write a 1 for the square wave
+        sampleBuffer.push_back(1.0);
+        else                                // Odd, write a 0 for the square wave
+        sampleBuffer.push_back(0.0);
+        t = t + timeIncrement;              // increment t for calculation of next value in the waveform
+    }
+}
 
-
+void output_samples()
+{
+    for( int sample = 0; sample < 256; sample++)
+    {
+        synthPin = sampleBuffer[sample];
+        Thread::wait(timeIncrement * 1000);
+    }
+        
+    
+    
 
 //Interrupt routine to parse message with one new character per serial RX interrupt
 void parse_message()
@@ -591,6 +620,7 @@
 // make directory to hold the record of notes played
 mkdir("/sd/noteRecords", 0777);
 
+initialize_sustainVals();      // fill the lookup tables with the sustain values in them
 
 //attach interrupt function for each new Bluetooth serial character
     Blue.attach(&parse_message,Serial::RxIrq);
@@ -598,6 +628,7 @@
         //check for a new button message ready
         if((keyPress == C_NOTE_KEY) && (readyFlag)){ // button Z pressed
             set_Note_Freq(noteArray[currentOctave-1][0]);
+            create_samples(note_freq, myWave);
             write_to_SDCard('C');
             readyFlag = false;
             // Play note that corresponds to Z