Bluetooth Enabled Keyboard/Synthesizer for mbed

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

Committer:
jmpin
Date:
Sat Apr 30 21:54:33 2016 +0000
Revision:
22:9c80f7bcef86
Parent:
21:0df25c61c475
Child:
23:cf9d43d5a5b4
Modified all the coefficient matrices as well as the function that forms the envelope. Also changed the permission on the file on the SD card from 'w' to 'a'

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jmpin 0:48311ffdfa96 1 #include "mbed.h"
jmpin 3:3aba1d783730 2 #include "SDFileSystem.h"
jmpin 6:68c6a50e1437 3 #include "rtos.h"
jmpin 6:68c6a50e1437 4 #include <vector>
jmpin 6:68c6a50e1437 5 #include "uLCD_4DGL.h"
jmpin 3:3aba1d783730 6 #include "synthesizer.h"
Jake867 21:0df25c61c475 7 #include "Speaker.h"
Jake867 11:c87f55a3b9e0 8 RawSerial Blue(p13,p14);
Jake867 11:c87f55a3b9e0 9 RawSerial PC(USBTX,USBRX);
jmpin 0:48311ffdfa96 10 DigitalOut myled(LED1);
jmpin 0:48311ffdfa96 11 DigitalOut myled4(LED4);
jmpin 3:3aba1d783730 12
jmpin 3:3aba1d783730 13 SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card setup
jmpin 3:3aba1d783730 14
Jake867 11:c87f55a3b9e0 15 uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;
jmpin 6:68c6a50e1437 16
Jake867 21:0df25c61c475 17 Speaker mySpeaker(p18);; // p18 is the pin that will have the output voltages on it
jmpin 8:f6699fd30737 18
jmpin 6:68c6a50e1437 19
jmpin 0:48311ffdfa96 20 //global variables for main and interrupt routine
Jake867 11:c87f55a3b9e0 21 volatile bool readyFlag = false;
jmpin 0:48311ffdfa96 22 volatile char keyPress;
jmpin 3:3aba1d783730 23 WaveType myWave = sine; // default to sine wave
jmpin 3:3aba1d783730 24 volatile int currentOctave = 4; // default to 4 because thats where middle C is
jmpin 3:3aba1d783730 25 volatile int currentAttackVal = 3; // values will range from 1-5, default to 3
jmpin 6:68c6a50e1437 26 volatile int currentDecayVal = 3; // values will range from 1-5, default to 3
jmpin 3:3aba1d783730 27 volatile int currentSustainVal = 3; // values will range from 1-5, default to 3
jmpin 3:3aba1d783730 28 volatile int currentReleaseVal = 3; // values will range from 1-5, default to 3
jmpin 9:e4df1a31a098 29 double *currentAttackTable; // pointer to the correct attack coefficient table
jmpin 9:e4df1a31a098 30 double *currentDecayTable; // pointer to the correct decay coefficient table
jmpin 9:e4df1a31a098 31 double *currentSustainTable; // pointer to the correct sustain coefficient table
jmpin 9:e4df1a31a098 32 double *currentReleaseTable; // pointer to the correct release coefficient table
Jake867 21:0df25c61c475 33 short unsigned Analog_out_data[32];
jmpin 6:68c6a50e1437 34 volatile int noteFreq; // the current frequency of the note being played
jmpin 5:afd67e985df0 35
jmpin 5:afd67e985df0 36 /* Coefficient Matrices Corresponding to Different Attack Values
jmpin 22:9c80f7bcef86 37 each matrix is comprised of 4 elements (32/8). The first matrix corresponds
jmpin 12:d60a9d0052a7 38 to an attack value of 5.
jmpin 5:afd67e985df0 39 */
jmpin 5:afd67e985df0 40
jmpin 22:9c80f7bcef86 41 double attackVals5[4] = {0 , 0.9 , 0.98 , 1}; //Approaches the maximum amplitude the quickest - corresponds to an attackValue of 5
jmpin 22:9c80f7bcef86 42
jmpin 22:9c80f7bcef86 43 double attackVals4[4] = {0 , 0.78 , 0.92 , 1}; //Corresponds to an attackValue of 4
jmpin 22:9c80f7bcef86 44
jmpin 22:9c80f7bcef86 45 double attackVals3[4] = {0 , 0.63 , 0.84 , 1}; //Corresponds to an attackValue of 3
jmpin 22:9c80f7bcef86 46
jmpin 22:9c80f7bcef86 47 double attackVals2[4] = {0 , 0.5 , 0.75 , 1}; //Corresponds to an attackValue of 2
jmpin 22:9c80f7bcef86 48
jmpin 22:9c80f7bcef86 49 double attackVals1[4] = {0 , 0.33 , 0.66 , 1}; //Approaches the mamimum amplitude the slowest, in a linear fashion - corresponds to an attackValue of 1
jmpin 22:9c80f7bcef86 50
jmpin 5:afd67e985df0 51
jmpin 12:d60a9d0052a7 52 /* Coefficient Matrices Corresponding to Different Decay Values
jmpin 22:9c80f7bcef86 53 each matrix is comprised of 4 elements (32/8). The first matrix corresponds
jmpin 12:d60a9d0052a7 54 to a decay value of 5.
jmpin 12:d60a9d0052a7 55 */
jmpin 12:d60a9d0052a7 56
jmpin 22:9c80f7bcef86 57 double decayVals5[4] = {0.67 , 0.63 , 0.62 , 0.6}; //Approaches the sustain amplitude the quickest - corresponds to a decay value of 5
jmpin 22:9c80f7bcef86 58 double decayVals4[4] = {0.73 , 0.675 , 0.63 , 0.60}; // Decay value of 4
jmpin 22:9c80f7bcef86 59 double decayVals3[4] = {0.77 , 0.7 , 0.63 , 0.60}; // Decay value of 3
jmpin 22:9c80f7bcef86 60 double decayVals2[4] = {0.84 , 0.73 , 0.65 , 0.6}; // Decay value of 2
jmpin 22:9c80f7bcef86 61 double decayVals1[4] = {0.9 , 0.8 , 0.7 , 0.6}; // Decays the slowest, in a linear fashion - corresponds to a decay value of 1
jmpin 8:f6699fd30737 62
jmpin 12:d60a9d0052a7 63 /* Coefficient Matrices Corresponding to Different sustain values
jmpin 22:9c80f7bcef86 64 each matrix is comprised of 20 elements 5 * (32/8). The first matrix corresponds
jmpin 12:d60a9d0052a7 65 to a sustain value of 5. The matrices get initialized later in a for loop due to their size.
jmpin 12:d60a9d0052a7 66 */
jmpin 12:d60a9d0052a7 67
jmpin 22:9c80f7bcef86 68 double sustainVals5[20];
jmpin 22:9c80f7bcef86 69 double sustainVals4[20];
jmpin 22:9c80f7bcef86 70 double sustainVals3[20];
jmpin 22:9c80f7bcef86 71 double sustainVals2[20];
jmpin 22:9c80f7bcef86 72 double sustainVals1[20];
jmpin 12:d60a9d0052a7 73
jmpin 12:d60a9d0052a7 74 /* Coefficient Matrices Corresponding to Different release values
jmpin 12:d60a9d0052a7 75 each matrix is comprised of 32 elements (256/8). The first matrix corresponds
jmpin 12:d60a9d0052a7 76 to a release value of 5.
jmpin 12:d60a9d0052a7 77 */
jmpin 12:d60a9d0052a7 78
jmpin 22:9c80f7bcef86 79 double releaseVals5[4] = {0.1 , 0.03 , 0.01 , 0}; // Releases (goes to 0 amplitude) the quickest - corresponds to a release value of 5
jmpin 22:9c80f7bcef86 80 double releaseVals4[4] = {0.2 , 0.1 , .04 , 0}; // Release value of 4
jmpin 22:9c80f7bcef86 81 double releaseVals3[4] = {0.33 , 0.16 , 0.08 , 0}; // Release value of 3
jmpin 22:9c80f7bcef86 82 double releaseVals2[4] = {0.4 , 0.23 , 0.1 , 0}; // Release value of 2
jmpin 22:9c80f7bcef86 83 double releaseVals1[4] = {0.45 , 0.30 , 0.15 , 0}; // Release value of 1 - proceeds slowest, in a linear fashion
jmpin 22:9c80f7bcef86 84
jmpin 5:afd67e985df0 85
jmpin 6:68c6a50e1437 86 int noteArray[7][7] = { // Array holding different note frequencies
jmpin 6:68c6a50e1437 87 C1 , D1 , E1 , F1 , G1 , A1 , B1 ,
jmpin 6:68c6a50e1437 88 C2 , D2 , E2 , F2 , G2 , A2 , B2,
jmpin 6:68c6a50e1437 89 C3 , D3 , E3 , F3 , G3 , A3 , B2 ,
jmpin 6:68c6a50e1437 90 C4 , D4 , E4 , F4 , G4 , A4 , B4 ,
jmpin 6:68c6a50e1437 91 C5 , D5 , E5 , F5 , G5 , A5 , B5 ,
jmpin 6:68c6a50e1437 92 C6 , D6 , E6 , F6 , G6 , A6 , B6 ,
jmpin 6:68c6a50e1437 93 C7 , D7 , E7 , F7 , G7 , A7 , B7
jmpin 6:68c6a50e1437 94 };
jmpin 5:afd67e985df0 95
jmpin 12:d60a9d0052a7 96 void uLCD_Display_Thread(void const *args){ // uLCD displays curernt waveform shape, current octave, and the values for the ADSR coefficients
Jake867 11:c87f55a3b9e0 97 while(1){
Jake867 11:c87f55a3b9e0 98 uLCD.locate(0,0);
jmpin 12:d60a9d0052a7 99 switch(myWave){
jmpin 12:d60a9d0052a7 100 case sine:
jmpin 15:8ff317cc5d2c 101 uLCD.printf("Shape: Sine \r\n"); // if wave type is sine wave, display sine
jmpin 12:d60a9d0052a7 102 break;
jmpin 12:d60a9d0052a7 103 case square:
jmpin 15:8ff317cc5d2c 104 uLCD.printf("Shape: Square \r\n"); // if wave type is square wave, display square
jmpin 12:d60a9d0052a7 105 break;
jmpin 12:d60a9d0052a7 106 case sawtooth:
jmpin 12:d60a9d0052a7 107 uLCD.printf("Shape: Sawtooth\r\n"); // if wave type is sawtooth wave, display sawtooth
jmpin 12:d60a9d0052a7 108 break;
jmpin 12:d60a9d0052a7 109 default:
jmpin 12:d60a9d0052a7 110 break;
jmpin 12:d60a9d0052a7 111 }
jmpin 12:d60a9d0052a7 112 uLCD.printf("Octave: %i\r\n",currentOctave); // displays octave
jmpin 12:d60a9d0052a7 113 uLCD.printf("Attack: %i\r\n",currentAttackVal); // displays attack value
jmpin 12:d60a9d0052a7 114 uLCD.printf("Decay: %i\r\n",currentDecayVal); // displays decay value
jmpin 12:d60a9d0052a7 115 uLCD.printf("Sustain: %i\r\n",currentSustainVal); // displays sustain value
jmpin 12:d60a9d0052a7 116 uLCD.printf("Release: %i\r\n",currentReleaseVal); // displays release value
Jake867 11:c87f55a3b9e0 117 }
jmpin 12:d60a9d0052a7 118 }
jmpin 6:68c6a50e1437 119
jmpin 12:d60a9d0052a7 120 void set_Note_Freq(int frequency){ // updates the frequency of the note being played
jmpin 6:68c6a50e1437 121 noteFreq = frequency;
jmpin 6:68c6a50e1437 122 }
jmpin 6:68c6a50e1437 123
jmpin 12:d60a9d0052a7 124 void change_Attack_Table(int attackVal) // change which table of coefficients to use for altering the attack portion of the waveform
jmpin 6:68c6a50e1437 125 {
jmpin 6:68c6a50e1437 126 switch(attackVal){
jmpin 6:68c6a50e1437 127 case 5:
jmpin 6:68c6a50e1437 128 currentAttackTable = attackVals5;
jmpin 6:68c6a50e1437 129 break;
jmpin 6:68c6a50e1437 130 case 4:
jmpin 6:68c6a50e1437 131 currentAttackTable = attackVals4;
jmpin 6:68c6a50e1437 132 break;
jmpin 6:68c6a50e1437 133 case 3:
jmpin 6:68c6a50e1437 134 currentAttackTable = attackVals3;
jmpin 6:68c6a50e1437 135 break;
jmpin 6:68c6a50e1437 136 case 2:
jmpin 6:68c6a50e1437 137 currentAttackTable = attackVals2;
jmpin 6:68c6a50e1437 138 break;
jmpin 6:68c6a50e1437 139 case 1:
jmpin 6:68c6a50e1437 140 currentAttackTable = attackVals1;
jmpin 6:68c6a50e1437 141 break;
jmpin 6:68c6a50e1437 142 default:
jmpin 6:68c6a50e1437 143 break;
jmpin 6:68c6a50e1437 144 }
jmpin 6:68c6a50e1437 145 }
jmpin 5:afd67e985df0 146
jmpin 12:d60a9d0052a7 147 void change_Decay_Table(int decayVal) // change which table of coefficients to use for altering the decay portion of the waveform
jmpin 6:68c6a50e1437 148 {
jmpin 6:68c6a50e1437 149 switch(decayVal){
jmpin 6:68c6a50e1437 150 case 5:
jmpin 6:68c6a50e1437 151 currentDecayTable = decayVals5;
jmpin 6:68c6a50e1437 152 break;
jmpin 6:68c6a50e1437 153 case 4:
jmpin 6:68c6a50e1437 154 currentDecayTable = decayVals4;
jmpin 6:68c6a50e1437 155 break;
jmpin 6:68c6a50e1437 156 case 3:
jmpin 6:68c6a50e1437 157 currentDecayTable = decayVals3;
jmpin 6:68c6a50e1437 158 break;
jmpin 6:68c6a50e1437 159 case 2:
jmpin 6:68c6a50e1437 160 currentDecayTable = decayVals2;
jmpin 6:68c6a50e1437 161 break;
jmpin 6:68c6a50e1437 162 case 1:
jmpin 6:68c6a50e1437 163 currentDecayTable = decayVals1;
jmpin 6:68c6a50e1437 164 break;
jmpin 6:68c6a50e1437 165 default:
jmpin 6:68c6a50e1437 166 break;
jmpin 6:68c6a50e1437 167 }
jmpin 6:68c6a50e1437 168 }
jmpin 5:afd67e985df0 169
jmpin 12:d60a9d0052a7 170 void change_Sustain_Table(int sustainVal) // change which table of coefficients to use for altering the sustain portion of the waveform
jmpin 6:68c6a50e1437 171 {
jmpin 6:68c6a50e1437 172 switch(sustainVal){
jmpin 6:68c6a50e1437 173 case 5:
jmpin 6:68c6a50e1437 174 currentSustainTable = sustainVals5;
jmpin 6:68c6a50e1437 175 break;
jmpin 6:68c6a50e1437 176 case 4:
jmpin 6:68c6a50e1437 177 currentSustainTable = sustainVals4;
jmpin 6:68c6a50e1437 178 break;
jmpin 6:68c6a50e1437 179 case 3:
jmpin 6:68c6a50e1437 180 currentSustainTable = sustainVals3;
jmpin 6:68c6a50e1437 181 break;
jmpin 6:68c6a50e1437 182 case 2:
jmpin 6:68c6a50e1437 183 currentSustainTable = sustainVals2;
jmpin 6:68c6a50e1437 184 break;
jmpin 6:68c6a50e1437 185 case 1:
jmpin 6:68c6a50e1437 186 currentSustainTable = sustainVals1;
jmpin 6:68c6a50e1437 187 break;
jmpin 6:68c6a50e1437 188 default:
jmpin 6:68c6a50e1437 189 break;
jmpin 6:68c6a50e1437 190 }
jmpin 6:68c6a50e1437 191 }
jmpin 6:68c6a50e1437 192
jmpin 12:d60a9d0052a7 193 void change_Release_Table(int releaseVal) // change which table of coefficients to use for altering the release portion of the waveform
jmpin 6:68c6a50e1437 194 {
jmpin 6:68c6a50e1437 195 switch(releaseVal){
jmpin 6:68c6a50e1437 196 case 5:
jmpin 6:68c6a50e1437 197 currentReleaseTable = releaseVals5;
jmpin 6:68c6a50e1437 198 break;
jmpin 6:68c6a50e1437 199 case 4:
jmpin 6:68c6a50e1437 200 currentReleaseTable = releaseVals4;
jmpin 6:68c6a50e1437 201 break;
jmpin 6:68c6a50e1437 202 case 3:
jmpin 6:68c6a50e1437 203 currentReleaseTable = releaseVals3;
jmpin 6:68c6a50e1437 204 break;
jmpin 6:68c6a50e1437 205 case 2:
jmpin 6:68c6a50e1437 206 currentReleaseTable = releaseVals2;
jmpin 6:68c6a50e1437 207 break;
jmpin 6:68c6a50e1437 208 case 1:
jmpin 6:68c6a50e1437 209 currentReleaseTable = releaseVals1;
jmpin 6:68c6a50e1437 210 break;
jmpin 6:68c6a50e1437 211 default:
jmpin 6:68c6a50e1437 212 break;
jmpin 6:68c6a50e1437 213 }
jmpin 6:68c6a50e1437 214 }
jmpin 12:d60a9d0052a7 215
jmpin 12:d60a9d0052a7 216 /* Having different sustain values for the amplitude of the wave would make the math neccesary to generate the other
jmpin 12:d60a9d0052a7 217 coefficient matrices very complex, so only .6 is used, meaning a sustain value of 1-5 will all correspond to a sustain amplitude
jmpin 22:9c80f7bcef86 218 of .6. Since the sustain coefficient matrices are 20 elements long, they are all filled in a for loop with this function call.
jmpin 12:d60a9d0052a7 219 */
jmpin 12:d60a9d0052a7 220
jmpin 12:d60a9d0052a7 221 void initialize_sustainVals()
jmpin 8:f6699fd30737 222 {
jmpin 22:9c80f7bcef86 223 for(int j = 0; j < 20; j++)
jmpin 8:f6699fd30737 224 {
jmpin 8:f6699fd30737 225 sustainVals5[j] = .6;
jmpin 8:f6699fd30737 226 sustainVals4[j] = .6;
jmpin 8:f6699fd30737 227 sustainVals3[j] = .6;
jmpin 8:f6699fd30737 228 sustainVals2[j] = .6;
jmpin 8:f6699fd30737 229 sustainVals1[j] = .6;
jmpin 8:f6699fd30737 230 }
jmpin 8:f6699fd30737 231 }
jmpin 12:d60a9d0052a7 232 /* Applies the envelope to the waveform. Each set of coefficients is applied to a certain portion of the waveform to alter its shape.
jmpin 22:9c80f7bcef86 233 The attack coefficients are appplied to the first 4 samples, the decay coefficients are applied to samples 5-8, the sustain coefficients
jmpin 22:9c80f7bcef86 234 are applied to samples 9 - 28, and the release coefficients are appplied to samples 29-32.
jmpin 12:d60a9d0052a7 235 */
jmpin 6:68c6a50e1437 236
jmpin 12:d60a9d0052a7 237
jmpin 12:d60a9d0052a7 238 void apply_Envelope(void){
jmpin 22:9c80f7bcef86 239 double coefficientMatrix[32]; // Array to hold all 32 coefficients for modulating the amplitude of the waveform
jmpin 22:9c80f7bcef86 240 for(int j = 0; j < 32 ; j++)
jmpin 6:68c6a50e1437 241 {
jmpin 22:9c80f7bcef86 242 if( j < 4 )
jmpin 22:9c80f7bcef86 243 coefficientMatrix[j] = currentAttackTable[j];
jmpin 22:9c80f7bcef86 244 else if(( j < 8) && ( j > 3))
jmpin 22:9c80f7bcef86 245 coefficientMatrix[j] = currentDecayTable[j];
jmpin 22:9c80f7bcef86 246 else if(( j < 28) && (j > 7))
jmpin 22:9c80f7bcef86 247 coefficientMatrix[j] = currentSustainTable[j];
jmpin 22:9c80f7bcef86 248 else if(( j < 32) && (j > 27))
jmpin 22:9c80f7bcef86 249 coefficientMatrix[j] = currentReleaseTable[j];
jmpin 6:68c6a50e1437 250 }
jmpin 6:68c6a50e1437 251 }
jmpin 5:afd67e985df0 252
jmpin 12:d60a9d0052a7 253 void generate_sineWave(int frequency) // Generates samples for a sine wave of a given input frequency
jmpin 9:e4df1a31a098 254 {
Jake867 21:0df25c61c475 255 for(int i = 0; i < 32 ; i++)
jmpin 9:e4df1a31a098 256 {
Jake867 21:0df25c61c475 257 Analog_out_data[i] = int (65536.0 * ((1.0 + sin((float(i)/32.0*6.28318530717959)))/2.0)); // scaled to be 16bit
jmpin 9:e4df1a31a098 258 }
jmpin 9:e4df1a31a098 259 }
jmpin 9:e4df1a31a098 260
jmpin 12:d60a9d0052a7 261 void generate_sawtoothWave(int frequency) // Generates samples for a sawtooth wave of a given input frequency
jmpin 9:e4df1a31a098 262 {
Jake867 21:0df25c61c475 263 float t = 0; // Represents time
Jake867 21:0df25c61c475 264 for(int i = 0; i<32 ; i++)
jmpin 9:e4df1a31a098 265 {
Jake867 21:0df25c61c475 266 Analog_out_data[i] = int(t * 65536.0); //scaled to 16bit
Jake867 21:0df25c61c475 267 t+= 1.0/32.0; // increment t for calculation of next value in the waveform
jmpin 9:e4df1a31a098 268 }
jmpin 9:e4df1a31a098 269 }
jmpin 9:e4df1a31a098 270
jmpin 12:d60a9d0052a7 271 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
jmpin 9:e4df1a31a098 272 {
Jake867 21:0df25c61c475 273 for(int i = 0; i < 32; i++){
Jake867 21:0df25c61c475 274 if(i<16){
Jake867 21:0df25c61c475 275 Analog_out_data[i] = 65535; //scaled to 16bit
Jake867 21:0df25c61c475 276 }
Jake867 21:0df25c61c475 277 else{
Jake867 21:0df25c61c475 278 Analog_out_data[i] = 0; //scaled to 16bit
Jake867 21:0df25c61c475 279 }
jmpin 9:e4df1a31a098 280 }
jmpin 9:e4df1a31a098 281 }
jmpin 9:e4df1a31a098 282
jmpin 12:d60a9d0052a7 283 /* Generates the waveforms that will be output to the AnalogOut pin after being altered by the ADSR coefficient matrices.
jmpin 12:d60a9d0052a7 284 The envelope is only applied to sine waves here because when applied to the other wave shapes, the sound does not sounds good.
jmpin 12:d60a9d0052a7 285 @param: frequency - the frequency of the waveform to be generated
jmpin 12:d60a9d0052a7 286 @param: currentWaveType - the shape of the wave that needs to be generated
jmpin 12:d60a9d0052a7 287 */
jmpin 12:d60a9d0052a7 288
jmpin 12:d60a9d0052a7 289
jmpin 9:e4df1a31a098 290 void create_samples(int frequency, WaveType currentWaveType)
jmpin 8:f6699fd30737 291 {
jmpin 8:f6699fd30737 292 switch(currentWaveType){
jmpin 8:f6699fd30737 293 case sine:
jmpin 8:f6699fd30737 294 //Generate sine wave values
jmpin 8:f6699fd30737 295 generate_sineWave(frequency);
Jake867 21:0df25c61c475 296 //apply_Envelope();
jmpin 8:f6699fd30737 297 break;
jmpin 8:f6699fd30737 298 case square:
jmpin 8:f6699fd30737 299 //Generate square wave values
jmpin 8:f6699fd30737 300 generate_squareWave(frequency);
jmpin 9:e4df1a31a098 301 //apply_Envelope();
jmpin 8:f6699fd30737 302 break;
jmpin 8:f6699fd30737 303 case sawtooth:
jmpin 8:f6699fd30737 304 //Generate sawtooth wave values
jmpin 8:f6699fd30737 305 generate_sawtoothWave(frequency);
jmpin 9:e4df1a31a098 306 //apply_Envelope();
jmpin 8:f6699fd30737 307 break;
jmpin 8:f6699fd30737 308 default:
jmpin 8:f6699fd30737 309 break;
jmpin 8:f6699fd30737 310 }
jmpin 8:f6699fd30737 311 }
jmpin 8:f6699fd30737 312
jmpin 5:afd67e985df0 313
jmpin 0:48311ffdfa96 314 //Interrupt routine to parse message with one new character per serial RX interrupt
jmpin 0:48311ffdfa96 315 void parse_message()
jmpin 0:48311ffdfa96 316 {
jmpin 12:d60a9d0052a7 317 //PC.printf("Parse_message was called");
Jake867 11:c87f55a3b9e0 318 while(Blue.readable())
jmpin 10:085c49fe2509 319 {
Jake867 11:c87f55a3b9e0 320 keyPress = Blue.getc();
Jake867 11:c87f55a3b9e0 321 readyFlag = true;
jmpin 10:085c49fe2509 322 }
jmpin 0:48311ffdfa96 323 }
jmpin 3:3aba1d783730 324
jmpin 3:3aba1d783730 325
jmpin 3:3aba1d783730 326 /*
jmpin 3:3aba1d783730 327 This function writes which note was just played to a text file on the SDCard.
jmpin 3:3aba1d783730 328 The note played will be encoded in hexadecimal, as well as the octave, Attack Value,
jmpin 3:3aba1d783730 329 Delay Value, Sustain Value, and Release Value. The format of the bits will be as follows:
jmpin 3:3aba1d783730 330 | 3 bits | 3 bits | 3 bits | 3 bits | 3 bits | 3 bits |
jmpin 6:68c6a50e1437 331 | Attack | Decay | Susttain | Release | Octave | Note |
jmpin 3:3aba1d783730 332 For the 3 bits representing note, A will correspond to 1, B to 2, and so on.
jmpin 3:3aba1d783730 333 For example, if the lower 3 bits corresponding to note are 001, then the note is an A.
jmpin 3:3aba1d783730 334
jmpin 3:3aba1d783730 335 @param: The note that is being played/recorded into the text file
jmpin 3:3aba1d783730 336 */
jmpin 3:3aba1d783730 337
jmpin 3:3aba1d783730 338 void write_to_SDCard(char note)
jmpin 3:3aba1d783730 339 {
jmpin 6:68c6a50e1437 340 int AttackBits, SustainBits, DecayBits, ReleaseBits, OctaveBits, NoteBits;
jmpin 2:f06ba516b1ad 341
jmpin 12:d60a9d0052a7 342 AttackBits = currentAttackVal; // Holds the value of the attack parameter
jmpin 12:d60a9d0052a7 343 DecayBits = currentDecayVal; // Holds the value of the decay parameter
jmpin 12:d60a9d0052a7 344 SustainBits = currentSustainVal;// Holds the value of the sustain parameter
jmpin 12:d60a9d0052a7 345 ReleaseBits = currentReleaseVal;// Holds the value of the release parameter
jmpin 3:3aba1d783730 346 OctaveBits = currentOctave;
jmpin 3:3aba1d783730 347 switch(note){
jmpin 12:d60a9d0052a7 348 case 'C': // a C corresponds to a 3
jmpin 3:3aba1d783730 349 NoteBits = 3;
jmpin 3:3aba1d783730 350 break;
jmpin 3:3aba1d783730 351 case 'D':
jmpin 12:d60a9d0052a7 352 NoteBits = 4; // a D corresponds to a 4
jmpin 3:3aba1d783730 353 break;
jmpin 3:3aba1d783730 354 case 'E':
jmpin 12:d60a9d0052a7 355 NoteBits = 5; // an E corresponds to a 5
jmpin 3:3aba1d783730 356 break;
jmpin 3:3aba1d783730 357 case 'F':
jmpin 12:d60a9d0052a7 358 NoteBits = 6; // an F corresponds to a 6
jmpin 3:3aba1d783730 359 break;
jmpin 3:3aba1d783730 360 case 'G':
jmpin 12:d60a9d0052a7 361 NoteBits = 7; // a G corresponds to a 7
jmpin 3:3aba1d783730 362 break;
jmpin 3:3aba1d783730 363 case 'A':
jmpin 12:d60a9d0052a7 364 NoteBits = 1; // an A corresponds to a 1
jmpin 3:3aba1d783730 365 break;
jmpin 3:3aba1d783730 366 case 'B':
jmpin 12:d60a9d0052a7 367 NoteBits = 2; // a B corresponds to a 2
jmpin 3:3aba1d783730 368 break;
jmpin 3:3aba1d783730 369 default:
jmpin 3:3aba1d783730 370 NoteBits = 0;
jmpin 3:3aba1d783730 371 break;
jmpin 3:3aba1d783730 372 }
jmpin 3:3aba1d783730 373 int writeVal;
jmpin 6:68c6a50e1437 374 writeVal = (AttackBits << 15) | (DecayBits << 12) | (SustainBits << 9) | (ReleaseBits << 6) | (OctaveBits << 3) | (NoteBits);
jmpin 22:9c80f7bcef86 375 FILE *fp = fopen("/sd/noteRecords/note_record_01.txt", "a"); // creates handle for file we want to write to
jmpin 3:3aba1d783730 376 if(fp == NULL) {
jmpin 12:d60a9d0052a7 377 error("Could not open file for write\n"); // if this is not a valid name, tell user there is an error
jmpin 3:3aba1d783730 378 }
jmpin 3:3aba1d783730 379 fprintf(fp,"%X\r\n",writeVal); // writes value to the text file in hexadecimal
jmpin 3:3aba1d783730 380 fclose(fp);
jmpin 3:3aba1d783730 381 }
jmpin 3:3aba1d783730 382
jmpin 0:48311ffdfa96 383 int main()
jmpin 0:48311ffdfa96 384 {
jmpin 12:d60a9d0052a7 385 Thread thread1(uLCD_Display_Thread); // the thread that displays the current values of the parameters as well as the octave and wave shape
jmpin 10:085c49fe2509 386
jmpin 12:d60a9d0052a7 387
jmpin 12:d60a9d0052a7 388 mkdir("/sd/noteRecords", 0777); // make directory to hold the record of notes played
jmpin 3:3aba1d783730 389
jmpin 12:d60a9d0052a7 390 initialize_sustainVals(); // fill the lookup tables with the sustain values in them
Jake867 11:c87f55a3b9e0 391
jmpin 12:d60a9d0052a7 392 PC.baud(9600); // setup baud rate for PC serial connection
jmpin 12:d60a9d0052a7 393 Blue.baud(9600); // setup baud rate for bluetooth serial connection
jmpin 3:3aba1d783730 394
jmpin 12:d60a9d0052a7 395
jmpin 12:d60a9d0052a7 396 Blue.attach(&parse_message,Serial::RxIrq); //attach interrupt function for each new Bluetooth serial character
jmpin 0:48311ffdfa96 397 while(1) {
jmpin 0:48311ffdfa96 398 //check for a new button message ready
jmpin 13:25d53936d385 399 if((keyPress == C_NOTE_KEY) && (readyFlag)){ // Play note C
jmpin 12:d60a9d0052a7 400 set_Note_Freq(noteArray[currentOctave-1][0]); // set the note frequency to the proper value
jmpin 13:25d53936d385 401 create_samples(noteFreq, myWave); // creates the samples that are going to be output to the waveform
Jake867 21:0df25c61c475 402 mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data); // outputs the samples that are currently in the buffer to p18
jmpin 13:25d53936d385 403 write_to_SDCard('C'); // writes to the SD card
jmpin 13:25d53936d385 404 readyFlag = false; // set this flag to false so that the program will not try to process the key press more than once
jmpin 13:25d53936d385 405
Jake867 11:c87f55a3b9e0 406 }
jmpin 13:25d53936d385 407 else if((keyPress == D_NOTE_KEY) && (readyFlag)){ // Play note D
jmpin 15:8ff317cc5d2c 408 set_Note_Freq(noteArray[currentOctave-1][1]);
jmpin 15:8ff317cc5d2c 409 create_samples(noteFreq, myWave);
Jake867 21:0df25c61c475 410 mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
jmpin 15:8ff317cc5d2c 411 write_to_SDCard('D');
jmpin 15:8ff317cc5d2c 412 readyFlag = false;
jmpin 13:25d53936d385 413
Jake867 11:c87f55a3b9e0 414 }
jmpin 13:25d53936d385 415 else if((keyPress == E_NOTE_KEY) && (readyFlag)){ // Play note E
jmpin 6:68c6a50e1437 416 set_Note_Freq(noteArray[currentOctave-1][2]);
jmpin 9:e4df1a31a098 417 create_samples(noteFreq, myWave);
Jake867 21:0df25c61c475 418 mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
jmpin 3:3aba1d783730 419 write_to_SDCard('E');
jmpin 4:406f59c6a1a6 420 readyFlag = false;
Jake867 11:c87f55a3b9e0 421 }
jmpin 13:25d53936d385 422 else if((keyPress == F_NOTE_KEY) && (readyFlag)){ // Play note F
jmpin 6:68c6a50e1437 423 set_Note_Freq(noteArray[currentOctave-1][3]);
jmpin 9:e4df1a31a098 424 create_samples(noteFreq, myWave);
Jake867 21:0df25c61c475 425 mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
jmpin 3:3aba1d783730 426 write_to_SDCard('F');
jmpin 4:406f59c6a1a6 427 readyFlag = false;
Jake867 11:c87f55a3b9e0 428 }
jmpin 13:25d53936d385 429 else if((keyPress == G_NOTE_KEY) && (readyFlag)){ // Play note G
jmpin 6:68c6a50e1437 430 set_Note_Freq(noteArray[currentOctave-1][4]);
jmpin 9:e4df1a31a098 431 create_samples(noteFreq, myWave);
Jake867 21:0df25c61c475 432 mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
jmpin 3:3aba1d783730 433 write_to_SDCard('G');
jmpin 4:406f59c6a1a6 434 readyFlag = false;
Jake867 11:c87f55a3b9e0 435 }
jmpin 13:25d53936d385 436 else if((keyPress == A_NOTE_KEY) && (readyFlag)){ // Play note A
jmpin 6:68c6a50e1437 437 set_Note_Freq(noteArray[currentOctave][5]);
jmpin 9:e4df1a31a098 438 create_samples(noteFreq, myWave);
Jake867 21:0df25c61c475 439 mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
jmpin 3:3aba1d783730 440 write_to_SDCard('A');
jmpin 4:406f59c6a1a6 441 readyFlag = false;
Jake867 11:c87f55a3b9e0 442 }
jmpin 15:8ff317cc5d2c 443 else if((keyPress == B_NOTE_KEY) && (readyFlag)){ // Play note B
jmpin 6:68c6a50e1437 444 set_Note_Freq(noteArray[currentOctave][6]);
jmpin 9:e4df1a31a098 445 create_samples(noteFreq, myWave);
Jake867 21:0df25c61c475 446 mySpeaker.PlayNote(noteFreq, 2, 1.0, Analog_out_data);
jmpin 3:3aba1d783730 447 write_to_SDCard('B');
jmpin 4:406f59c6a1a6 448 readyFlag = false;
Jake867 11:c87f55a3b9e0 449 }
jmpin 2:f06ba516b1ad 450 else if((keyPress == RAISE_OCTAVE_KEY) && (readyFlag)){ // button O pressed
jmpin 0:48311ffdfa96 451 // Raise an octave
jmpin 6:68c6a50e1437 452 if(currentOctave < 7)
jmpin 2:f06ba516b1ad 453 currentOctave++;
jmpin 4:406f59c6a1a6 454 else
jmpin 4:406f59c6a1a6 455 printf("Cannot raise octave above 7.\r\n");
Jake867 11:c87f55a3b9e0 456 readyFlag = false;
Jake867 11:c87f55a3b9e0 457 }
jmpin 2:f06ba516b1ad 458 else if((keyPress == LOWER_OCTAVE_KEY) && (readyFlag)){ // button L pressed
jmpin 2:f06ba516b1ad 459 // Lower an octave
jmpin 4:406f59c6a1a6 460 if(currentOctave > 1)
jmpin 2:f06ba516b1ad 461 currentOctave--;
jmpin 4:406f59c6a1a6 462 else
jmpin 4:406f59c6a1a6 463 printf("Cannot lower octave below 1.\r\n");
Jake867 11:c87f55a3b9e0 464 readyFlag = false;
Jake867 11:c87f55a3b9e0 465 }
jmpin 2:f06ba516b1ad 466 else if((keyPress == RAISE_ATTACK_KEY) && (readyFlag)){ // button Q pressed
jmpin 0:48311ffdfa96 467 // Raise Attack Value
jmpin 6:68c6a50e1437 468 if(currentAttackVal < 5){
jmpin 2:f06ba516b1ad 469 currentAttackVal++;
jmpin 6:68c6a50e1437 470 change_Attack_Table(currentAttackVal);
jmpin 6:68c6a50e1437 471 }
jmpin 4:406f59c6a1a6 472 else
jmpin 4:406f59c6a1a6 473 printf("Cannot raise value above 5.\r\n");
Jake867 11:c87f55a3b9e0 474 readyFlag = false;
Jake867 11:c87f55a3b9e0 475 }
jmpin 2:f06ba516b1ad 476 else if((keyPress == LOWER_ATTACK_KEY) && (readyFlag)){ // button A pressed
jmpin 0:48311ffdfa96 477 // Lower Attack Value
jmpin 6:68c6a50e1437 478 if(currentAttackVal > 1){
jmpin 2:f06ba516b1ad 479 currentAttackVal--;
jmpin 6:68c6a50e1437 480 change_Attack_Table(currentAttackVal);
jmpin 6:68c6a50e1437 481 }
jmpin 4:406f59c6a1a6 482 else
jmpin 6:68c6a50e1437 483 printf("Cannot lower value below 1.\r\n");
Jake867 11:c87f55a3b9e0 484 readyFlag = false;
Jake867 11:c87f55a3b9e0 485 }
jmpin 2:f06ba516b1ad 486 else if((keyPress == RAISE_DELAY_KEY) && (readyFlag)){ // button W pressed
jmpin 0:48311ffdfa96 487 // Raise Delay Value
jmpin 6:68c6a50e1437 488 if(currentDecayVal < 5){
jmpin 6:68c6a50e1437 489 currentDecayVal++;
jmpin 6:68c6a50e1437 490 change_Decay_Table(currentDecayVal);
jmpin 6:68c6a50e1437 491 }
jmpin 4:406f59c6a1a6 492 else
jmpin 4:406f59c6a1a6 493 printf("Cannot raise value above 5.\r\n");
Jake867 11:c87f55a3b9e0 494 readyFlag = false;
Jake867 11:c87f55a3b9e0 495 }
jmpin 2:f06ba516b1ad 496 else if((keyPress == LOWER_DELAY_KEY) && (readyFlag)){ // button S pressed
jmpin 0:48311ffdfa96 497 // Lower Delay Value
jmpin 6:68c6a50e1437 498 if(currentDecayVal > 1){
jmpin 6:68c6a50e1437 499 currentDecayVal--;
jmpin 6:68c6a50e1437 500 change_Decay_Table(currentDecayVal);
jmpin 6:68c6a50e1437 501 }
jmpin 4:406f59c6a1a6 502 else
jmpin 6:68c6a50e1437 503 printf("Cannot lower value below 1.\r\n");
Jake867 11:c87f55a3b9e0 504 readyFlag = false;
Jake867 11:c87f55a3b9e0 505 }
jmpin 2:f06ba516b1ad 506 else if((keyPress == RAISE_SUSTAIN_KEY) && (readyFlag)){ // button E pressed
jmpin 0:48311ffdfa96 507 // Raise Sustain Value
jmpin 6:68c6a50e1437 508 if(currentSustainVal < 5){
jmpin 2:f06ba516b1ad 509 currentSustainVal++;
jmpin 6:68c6a50e1437 510 change_Sustain_Table(currentSustainVal);
jmpin 6:68c6a50e1437 511 }
jmpin 4:406f59c6a1a6 512 else
jmpin 4:406f59c6a1a6 513 printf("Cannot raise value above 5.\r\n");
Jake867 11:c87f55a3b9e0 514 readyFlag = false;
Jake867 11:c87f55a3b9e0 515 }
jmpin 2:f06ba516b1ad 516 else if((keyPress == LOWER_SUSTAIN_KEY) && (readyFlag)){ // button D pressed
jmpin 0:48311ffdfa96 517 // Lower Sustain Value
jmpin 6:68c6a50e1437 518 if(currentSustainVal > 1){
jmpin 2:f06ba516b1ad 519 currentSustainVal--;
jmpin 6:68c6a50e1437 520 change_Sustain_Table(currentSustainVal);
jmpin 6:68c6a50e1437 521 }
jmpin 4:406f59c6a1a6 522 else
jmpin 6:68c6a50e1437 523 printf("Cannot lower value below 1.\r\n");
Jake867 11:c87f55a3b9e0 524 readyFlag = false;
Jake867 11:c87f55a3b9e0 525 }
jmpin 2:f06ba516b1ad 526 else if((keyPress == RAISE_RELEASE_KEY) && (readyFlag)){ // button R pressed
jmpin 0:48311ffdfa96 527 // Raise Release Value
jmpin 6:68c6a50e1437 528 if(currentReleaseVal < 5){
jmpin 2:f06ba516b1ad 529 currentReleaseVal++;
jmpin 6:68c6a50e1437 530 change_Release_Table(currentReleaseVal);
jmpin 6:68c6a50e1437 531 }
jmpin 4:406f59c6a1a6 532 else
jmpin 4:406f59c6a1a6 533 printf("Cannot raise value above 5.\r\n");
Jake867 11:c87f55a3b9e0 534 readyFlag = false;
Jake867 11:c87f55a3b9e0 535 }
jmpin 2:f06ba516b1ad 536 else if((keyPress == LOWER_RELEASE_KEY) && (readyFlag)){ // button F pressed
jmpin 0:48311ffdfa96 537 // Lower Release Value
jmpin 6:68c6a50e1437 538 if(currentReleaseVal > 1){
jmpin 2:f06ba516b1ad 539 currentReleaseVal--;
jmpin 6:68c6a50e1437 540 change_Release_Table(currentReleaseVal);
jmpin 6:68c6a50e1437 541 }
jmpin 4:406f59c6a1a6 542 else
jmpin 6:68c6a50e1437 543 printf("Cannot lower value below 1.\r\n");
Jake867 11:c87f55a3b9e0 544 readyFlag = false;
Jake867 11:c87f55a3b9e0 545 }
jmpin 2:f06ba516b1ad 546 else if((keyPress == CHANGE_WAVESHAPE_UP) && (readyFlag)){ // button T pressed
jmpin 2:f06ba516b1ad 547 // Change waveform shape to next waveform type
jmpin 2:f06ba516b1ad 548 switch(myWave){
jmpin 2:f06ba516b1ad 549 case sine:
jmpin 2:f06ba516b1ad 550 myWave = square;
jmpin 2:f06ba516b1ad 551 break;
jmpin 2:f06ba516b1ad 552 case square:
jmpin 2:f06ba516b1ad 553 myWave = sawtooth;
jmpin 2:f06ba516b1ad 554 break;
jmpin 2:f06ba516b1ad 555 case sawtooth:
jmpin 2:f06ba516b1ad 556 myWave = sine;
jmpin 2:f06ba516b1ad 557 break;
jmpin 2:f06ba516b1ad 558 default:
jmpin 2:f06ba516b1ad 559 break;
jmpin 2:f06ba516b1ad 560 }
Jake867 11:c87f55a3b9e0 561 readyFlag = false;
Jake867 11:c87f55a3b9e0 562 }
jmpin 2:f06ba516b1ad 563 else if((keyPress == CHANGE_WAVESHAPE_DOWN) && (readyFlag)){ // button G pressed
jmpin 2:f06ba516b1ad 564 // Change waveform shape to previous waveform type
jmpin 2:f06ba516b1ad 565 switch(myWave){
jmpin 2:f06ba516b1ad 566 case sine:
jmpin 2:f06ba516b1ad 567 myWave = sawtooth;
jmpin 2:f06ba516b1ad 568 break;
jmpin 2:f06ba516b1ad 569 case square:
jmpin 2:f06ba516b1ad 570 myWave = sine;
jmpin 2:f06ba516b1ad 571 break;
jmpin 2:f06ba516b1ad 572 case sawtooth:
jmpin 2:f06ba516b1ad 573 myWave = square;
jmpin 2:f06ba516b1ad 574 break;
jmpin 2:f06ba516b1ad 575 default:
jmpin 2:f06ba516b1ad 576 break;
jmpin 2:f06ba516b1ad 577 }
Jake867 11:c87f55a3b9e0 578 readyFlag = false;
Jake867 11:c87f55a3b9e0 579
Jake867 11:c87f55a3b9e0 580 }
jmpin 10:085c49fe2509 581 }
jmpin 0:48311ffdfa96 582 }