Bluetooth Enabled Keyboard/Synthesizer for mbed

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

Revision:
21:0df25c61c475
Parent:
19:2f635d03467c
Child:
22:9c80f7bcef86
--- a/main.cpp	Fri Apr 29 23:26:49 2016 +0000
+++ b/main.cpp	Sat Apr 30 20:44:20 2016 +0000
@@ -4,6 +4,7 @@
 #include <vector>
 #include "uLCD_4DGL.h"
 #include "synthesizer.h"
+#include  "Speaker.h"
 RawSerial Blue(p13,p14);
 RawSerial PC(USBTX,USBRX);
 DigitalOut myled(LED1);
@@ -13,7 +14,7 @@
 
 uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;
 
-AnalogOut synthPin(p18);     // p18 is the pin that will have the output voltages on it
+Speaker mySpeaker(p18);;     // p18 is the pin that will have the output voltages on it
 
 
 //global variables for main and interrupt routine
@@ -29,8 +30,9 @@
 double *currentDecayTable;             // pointer to the correct decay coefficient table
 double *currentSustainTable;           // pointer to the correct sustain coefficient table
 double *currentReleaseTable;           // pointer to the correct release coefficient table
-vector<float> sampleBuffer;        // vector to hold samples of generated waveform
-int num_samples = 256;              // number of samples 
+//vector<float> sampleBuffer;        // vector to hold samples of generated waveform
+short unsigned Analog_out_data[32];
+//int num_samples = 256;              // number of samples 
 volatile int noteFreq;              // the current frequency of the note being played
 double timeIncrement = (2/256);     // 2 seconds with 256 samples
 
@@ -242,13 +244,13 @@
     }
 }
 
-void clear_Buffer(void){        // clears buffer that holds samples
-    sampleBuffer.clear();
-}
+//void clear_Buffer(void){        // clears buffer that holds samples
+//    sampleBuffer.clear();
+//}
 
 void set_Note_Freq(int frequency){      // updates the frequency of the note being played
     noteFreq = frequency;
-    clear_Buffer();
+    //clear_Buffer();
 }
 
 void change_Attack_Table(int attackVal)     // change which table of coefficients to use for altering the attack portion of the waveform
@@ -367,59 +369,55 @@
 
 void apply_Envelope(void){                                          
     int attack_range, decay_range, sustain_range, release_range;
-    attack_range = sampleBuffer.size() * (1/8);                     // The attack portion of the waveform will take (1/8) of the note's duration
-    decay_range = attack_range + (sampleBuffer.size() * (1/8));     // The decay portion of the waveform will take (1/8) of the note's duration
-    sustain_range = sustain_range + (sampleBuffer.size() * (5/8));  // The sustain portion of the waveform will take (5/8) of the note's duration
-    release_range = release_range + (sampleBuffer.size() * (1/8));  // The release portion of the waveform will take (1/8) of the note's duration
+    //attack_range = sampleBuffer.size() * (1/8);                     // The attack portion of the waveform will take (1/8) of the note's duration
+    //decay_range = attack_range + (sampleBuffer.size() * (1/8));     // The decay portion of the waveform will take (1/8) of the note's duration
+    //sustain_range = sustain_range + (sampleBuffer.size() * (5/8));  // The sustain portion of the waveform will take (5/8) of the note's duration
+    //release_range = release_range + (sampleBuffer.size() * (1/8));  // The release portion of the waveform will take (1/8) of the note's duration
     for(int i = 0; i < attack_range; i++)
     {
-        sampleBuffer[i] = sampleBuffer[i] * currentAttackTable[i];
+        //sampleBuffer[i] = sampleBuffer[i] * currentAttackTable[i];
     }
     for(int k = attack_range; k < decay_range; k++)
     {
-        sampleBuffer[k] = sampleBuffer[k] * currentDecayTable[k-attack_range];
+        //sampleBuffer[k] = sampleBuffer[k] * currentDecayTable[k-attack_range];
     }
     for(int m = decay_range; m < sustain_range; m++)
     {
-        sampleBuffer[m] = sampleBuffer[m] * currentSustainTable[m-decay_range];
+        //sampleBuffer[m] = sampleBuffer[m] * currentSustainTable[m-decay_range];
     }
     for(int n = sustain_range; n < release_range; n++)
     {
-        sampleBuffer[n] = sampleBuffer[n] * currentReleaseTable[n-sustain_range];
+        //sampleBuffer[n] = sampleBuffer[n] * currentReleaseTable[n-sustain_range];
     }     
 }
 
 void generate_sineWave(int frequency)       // Generates samples for a sine wave of a given input frequency
 {
-    double t = 0;                           // Represents time, since we want each note to last 2 seconds and have 256 samples
-    for(int i = 0; i < 256 ; i++)
+    for(int i = 0; i < 32 ; i++)
     {
-        sampleBuffer.push_back(((sin(2*(PI)*frequency*(float)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   
+        Analog_out_data[i] = int (65536.0 * ((1.0 + sin((float(i)/32.0*6.28318530717959)))/2.0));  // scaled to be 16bit
     }
 }
 
 void generate_sawtoothWave(int frequency)   // Generates samples for a sawtooth wave of a given input frequency
 {
-    double t = 0;                           // Represents time, since we want each note to last 2 seconds and have 256 samples
-    for(int i = 0; i<256 ; i++)
+    float t = 0;                           // Represents time
+    for(int i = 0; i<32 ; i++)
     {
-        sampleBuffer.push_back((2*((float)t*frequency) - (.5 + (t*frequency)) + 1) / 2);
-        t = t + timeIncrement;              // increment t for calculation of next value in the waveform   
+        Analog_out_data[i] = int(t * 65536.0); //scaled to 16bit  
+        t+= 1.0/32.0;             // increment t for calculation of next value in the waveform    
     }
 }
 
 void generate_squareWave(int frequency)     // Generates samples for a square wave of a given input frequency. Looks at whether we have seen an even or odd number of 'widths' to determine if wave should be high or low at given t
 {
-    double width = (1 / (2 * frequency));     // Width of a half period of the square wave
-    double t = 0;                           // Represents time, since we want a 2 second note with 256 samples
-    for(int i = 0; i < 256; i++)
-    {
-        if(((int)(t / width) % 2 ) == 0)     // Even, write a 1 for the square wave
-        sampleBuffer.push_back((float)1.0);
-        else                                // Odd, write a 0 for the square wave
-        sampleBuffer.push_back((float)0.0);
-        t = t + timeIncrement;              // increment t for calculation of next value in the waveform
+    for(int i = 0; i < 32; i++){
+        if(i<16){
+            Analog_out_data[i] = 65535; //scaled to 16bit    
+        }
+        else{
+            Analog_out_data[i] = 0; //scaled to 16bit
+        }
     }
 }
 
@@ -436,7 +434,7 @@
         case sine:
             //Generate sine wave values
             generate_sineWave(frequency);
-            apply_Envelope();
+            //apply_Envelope();
             break;
         case square:
             //Generate square wave values
@@ -452,24 +450,7 @@
         break;
     }
 }
-
-
-/* Outputs the samples that are currently in the buffer one at a time. There is a period of time
-where the program waits so that the 256 samples fill up the entire 2 seconds. The buffer is cleared
-after the output is finished so that next time the buffer will be ready for new samples.
-*/
-void output_samples()
-{
-    for( int sample = 0; sample < 256; sample++)
-    {
-        //synthPin = sampleBuffer[sample];
-        PC.printf("Current Sample: %f",sampleBuffer[sample]);
-    }
-    clear_Buffer();
-}
         
-    
-    
 
 //Interrupt routine to parse message with one new character per serial RX interrupt
 void parse_message()
@@ -478,11 +459,7 @@
     while(Blue.readable())
     {
         keyPress = Blue.getc();
-        //PC.putc(keyPress);
         readyFlag = true;
-        //PC.printf("\n\r Value of readyFlag is: %i",readyFlag);
-        //PC.printf("Value of keyPress is: %c\n\r",keyPress);
-        //wait(1);
     }
 }
 
@@ -564,7 +541,7 @@
         if((keyPress == C_NOTE_KEY) && (readyFlag)){        // Play note C
             set_Note_Freq(noteArray[currentOctave-1][0]);   // set the note frequency to the proper value 
             create_samples(noteFreq, myWave);               // creates the samples that are going to be output to the waveform
-            output_samples();                               // outputs the samples that are currently in the buffer to p18
+            mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);                              // outputs the samples that are currently in the buffer to p18
             write_to_SDCard('C');                           // writes to the SD card
             readyFlag = false;                              // set this flag to false so that the program will not try to process the key press more than once
             
@@ -572,7 +549,7 @@
         else if((keyPress == D_NOTE_KEY) && (readyFlag)){ // Play note D
             set_Note_Freq(noteArray[currentOctave-1][1]);
             create_samples(noteFreq, myWave);
-            output_samples();
+            mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
             write_to_SDCard('D');
             readyFlag = false;
             
@@ -580,35 +557,35 @@
         else if((keyPress == E_NOTE_KEY) && (readyFlag)){ // Play note E
             set_Note_Freq(noteArray[currentOctave-1][2]);
             create_samples(noteFreq, myWave);
-            output_samples();
+            mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
             write_to_SDCard('E');
             readyFlag = false;
         }
         else if((keyPress == F_NOTE_KEY) && (readyFlag)){ // Play note F
             set_Note_Freq(noteArray[currentOctave-1][3]);
             create_samples(noteFreq, myWave);
-            output_samples();
+            mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
             write_to_SDCard('F');
             readyFlag = false;
         }
         else if((keyPress == G_NOTE_KEY) && (readyFlag)){ // Play note G
             set_Note_Freq(noteArray[currentOctave-1][4]);
             create_samples(noteFreq, myWave);
-            output_samples();
+            mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
             write_to_SDCard('G');
             readyFlag = false;
         }
         else if((keyPress == A_NOTE_KEY) && (readyFlag)){ // Play note A
             set_Note_Freq(noteArray[currentOctave][5]);
             create_samples(noteFreq, myWave);
-            output_samples();
+            mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
             write_to_SDCard('A');
             readyFlag = false;
         }
         else if((keyPress == B_NOTE_KEY) && (readyFlag)){ // Play note B
             set_Note_Freq(noteArray[currentOctave][6]);
             create_samples(noteFreq, myWave);
-            output_samples();
+            mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
             write_to_SDCard('B');
             readyFlag = false;
         }