
Bluetooth Enabled Keyboard/Synthesizer for mbed
Dependencies: mbed 4DGL-uLCD-SE SDFileSystem mbed-rtos
Diff: main.cpp
- 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; }