Adapted code from original GT_Tuner code (by Andrew Durand) for a school project by Tapton School.

Dependencies:   mbed

Committer:
mptapton
Date:
Tue Jan 03 13:46:19 2017 +0000
Revision:
0:6b0b61d411ad
Child:
1:c8ec50d75f80
Adaptation to original GT_Tuner code (by Andrew Durand), as part of a school project for Tapton school

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mptapton 0:6b0b61d411ad 1 // Guitar Tuner and Chord Learning Tool using Goertzel's Algorithm //
mptapton 0:6b0b61d411ad 2 // Based on original code created by: Andrew Durand //
mptapton 0:6b0b61d411ad 3 // Adjusted and modified by Tapton School EDS Project Team //
mptapton 0:6b0b61d411ad 4
mptapton 0:6b0b61d411ad 5 #include "TextLCD.h"
mptapton 0:6b0b61d411ad 6 #include "mbed.h"
mptapton 0:6b0b61d411ad 7 #include "adc.h"
mptapton 0:6b0b61d411ad 8 #include <math.h>
mptapton 0:6b0b61d411ad 9 #define PI 3.1415
mptapton 0:6b0b61d411ad 10 #define SAMPLE_RATE 24000
mptapton 0:6b0b61d411ad 11
mptapton 0:6b0b61d411ad 12 DigitalOut led_low(LED1);
mptapton 0:6b0b61d411ad 13 DigitalOut led_ok(LED2);
mptapton 0:6b0b61d411ad 14 DigitalOut led_high(LED4);
mptapton 0:6b0b61d411ad 15 InterruptIn button1(p6); //mosi
mptapton 0:6b0b61d411ad 16 DigitalIn myInputPin (p21); //select tuner or chord learning mode
mptapton 0:6b0b61d411ad 17
mptapton 0:6b0b61d411ad 18 //LCD and Other Random Variables
mptapton 0:6b0b61d411ad 19 //NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type
mptapton 0:6b0b61d411ad 20
mptapton 0:6b0b61d411ad 21 /* This code uses libraries created for 4-bit LCD's based on the HD44780. This
mptapton 0:6b0b61d411ad 22 program was designed for a similar product (Winstar's WH1602B 2x16 LC) working
mptapton 0:6b0b61d411ad 23 into an Mbed LPC1768.
mptapton 0:6b0b61d411ad 24 LCD pins: Pin 1(VSS) to Mbed Gnd, Pin 2(VDD) to Mbed 5v USB output, Pin 3(Vo- contrast)
mptapton 0:6b0b61d411ad 25 to Mbed Gnd (via a 4k7 resistor), Pin 5(R/W) to Mbed Gnd, Pin 15(A)to Mbed 5v USB output, Pin 16(B) to
mptapton 0:6b0b61d411ad 26 MBed Gnd, Pins 4(RS),20(E) and the 4 data bits (DB4 [11] through to DB7 [14])
mptapton 0:6b0b61d411ad 27 go to the Mbed pins described below: */
mptapton 0:6b0b61d411ad 28
mptapton 0:6b0b61d411ad 29 TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d4-d7
mptapton 0:6b0b61d411ad 30
mptapton 0:6b0b61d411ad 31 int string_select = 0;
mptapton 0:6b0b61d411ad 32 int chord_select = 0;
mptapton 0:6b0b61d411ad 33 float high, high1, in_tune, in_tune1, in_tune2, in_tune3,
mptapton 0:6b0b61d411ad 34 low, low1, note, low_mod, high_mod;
mptapton 0:6b0b61d411ad 35 char* key;
mptapton 0:6b0b61d411ad 36 int Counter = 0;
mptapton 0:6b0b61d411ad 37 int Buffer[6000];
mptapton 0:6b0b61d411ad 38
mptapton 0:6b0b61d411ad 39 float goertzelFilter(int samples[], float freq, int N) {
mptapton 0:6b0b61d411ad 40 float s_prev = 0.0;
mptapton 0:6b0b61d411ad 41 float s_prev2 = 0.0;
mptapton 0:6b0b61d411ad 42 float coeff,normalizedfreq,power,s;
mptapton 0:6b0b61d411ad 43 int i;
mptapton 0:6b0b61d411ad 44 normalizedfreq = freq / SAMPLE_RATE;
mptapton 0:6b0b61d411ad 45 coeff = 2*cos(2*PI*normalizedfreq);
mptapton 0:6b0b61d411ad 46 for (i=0; i<N; i++) {
mptapton 0:6b0b61d411ad 47 s = samples[i] + coeff * s_prev - s_prev2;
mptapton 0:6b0b61d411ad 48 s_prev2 = s_prev;
mptapton 0:6b0b61d411ad 49 s_prev = s;
mptapton 0:6b0b61d411ad 50 }
mptapton 0:6b0b61d411ad 51 power = s_prev2*s_prev2+s_prev*s_prev-coeff*s_prev*s_prev2;
mptapton 0:6b0b61d411ad 52 return power;
mptapton 0:6b0b61d411ad 53 }
mptapton 0:6b0b61d411ad 54
mptapton 0:6b0b61d411ad 55 ADC adc(SAMPLE_RATE, 1);
mptapton 0:6b0b61d411ad 56
mptapton 0:6b0b61d411ad 57 void sample_audio(int chan, uint32_t value) {
mptapton 0:6b0b61d411ad 58 Buffer[Counter] = adc.read(p20);
mptapton 0:6b0b61d411ad 59 Counter += 1;
mptapton 0:6b0b61d411ad 60 }
mptapton 0:6b0b61d411ad 61
mptapton 0:6b0b61d411ad 62 void button1_pressed() {
mptapton 0:6b0b61d411ad 63 string_select++;
mptapton 0:6b0b61d411ad 64 chord_select++;
mptapton 0:6b0b61d411ad 65 if (string_select > 5) string_select = 0;
mptapton 0:6b0b61d411ad 66 if (chord_select > 9) chord_select = 0;//change for number of chords supported
mptapton 0:6b0b61d411ad 67 }
mptapton 0:6b0b61d411ad 68
mptapton 0:6b0b61d411ad 69 int main() {
mptapton 0:6b0b61d411ad 70 while (1) {
mptapton 0:6b0b61d411ad 71 myInputPin.mode(PullUp); //set the mbed to use a pullup resistor
mptapton 0:6b0b61d411ad 72 if (myInputPin) { //select guitar tuner or chord teaching
mptapton 0:6b0b61d411ad 73 lcd.cls (); // Guitar Tuner Section based on p21 being +3v
mptapton 0:6b0b61d411ad 74
mptapton 0:6b0b61d411ad 75 //Interupt for Switching Strings
mptapton 0:6b0b61d411ad 76 button1.mode(PullDown);
mptapton 0:6b0b61d411ad 77 button1.rise(&button1_pressed);
mptapton 0:6b0b61d411ad 78
mptapton 0:6b0b61d411ad 79 while (1) {
mptapton 0:6b0b61d411ad 80
mptapton 0:6b0b61d411ad 81 switch (string_select) {
mptapton 0:6b0b61d411ad 82 case 0:
mptapton 0:6b0b61d411ad 83 note = 82;
mptapton 0:6b0b61d411ad 84 key= "E2";
mptapton 0:6b0b61d411ad 85 break;
mptapton 0:6b0b61d411ad 86 case 1:
mptapton 0:6b0b61d411ad 87 note = 110;
mptapton 0:6b0b61d411ad 88 key= "A2";
mptapton 0:6b0b61d411ad 89 break;
mptapton 0:6b0b61d411ad 90 case 2:
mptapton 0:6b0b61d411ad 91 note = 147;
mptapton 0:6b0b61d411ad 92 key= "D3";
mptapton 0:6b0b61d411ad 93 break;
mptapton 0:6b0b61d411ad 94 case 3:
mptapton 0:6b0b61d411ad 95 note = 196;
mptapton 0:6b0b61d411ad 96 key= "G3";
mptapton 0:6b0b61d411ad 97 break;
mptapton 0:6b0b61d411ad 98 case 4:
mptapton 0:6b0b61d411ad 99 note = 247;
mptapton 0:6b0b61d411ad 100 key= "B3";
mptapton 0:6b0b61d411ad 101 break;
mptapton 0:6b0b61d411ad 102 case 5:
mptapton 0:6b0b61d411ad 103 note = 330;
mptapton 0:6b0b61d411ad 104 key= "E4";
mptapton 0:6b0b61d411ad 105 break;
mptapton 0:6b0b61d411ad 106 }
mptapton 0:6b0b61d411ad 107
mptapton 0:6b0b61d411ad 108 //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford
mptapton 0:6b0b61d411ad 109 adc.append(sample_audio);
mptapton 0:6b0b61d411ad 110 adc.startmode(0,0);
mptapton 0:6b0b61d411ad 111 adc.burst(1);
mptapton 0:6b0b61d411ad 112 adc.setup(p20,1);
mptapton 0:6b0b61d411ad 113
mptapton 0:6b0b61d411ad 114 //start the interrupt and wait for about 4096 samples
mptapton 0:6b0b61d411ad 115 adc.interrupt_state(p20,1);
mptapton 0:6b0b61d411ad 116 wait(.2);
mptapton 0:6b0b61d411ad 117
mptapton 0:6b0b61d411ad 118 //Finsh up - Unset pin 20
mptapton 0:6b0b61d411ad 119 adc.interrupt_state(p20,0);
mptapton 0:6b0b61d411ad 120 adc.setup(p20,0);
mptapton 0:6b0b61d411ad 121 int actual_rate = adc.actual_sample_rate();
mptapton 0:6b0b61d411ad 122
mptapton 0:6b0b61d411ad 123 //for debugging tell the terminal sample rate and how many samples we took
mptapton 0:6b0b61d411ad 124 printf("Requested max sample rate is %u, actual max sample rate is %u.\n",
mptapton 0:6b0b61d411ad 125 SAMPLE_RATE, actual_rate);
mptapton 0:6b0b61d411ad 126 printf("We did %i samples\n",Counter);
mptapton 0:6b0b61d411ad 127
mptapton 0:6b0b61d411ad 128 high = 0;
mptapton 0:6b0b61d411ad 129 low = 0;
mptapton 0:6b0b61d411ad 130 for (int i=3; i<46; i+=3) {
mptapton 0:6b0b61d411ad 131 high1 = goertzelFilter(Buffer, (note + i ), Counter);
mptapton 0:6b0b61d411ad 132 if (high1 > high) high=high1;
mptapton 0:6b0b61d411ad 133 }
mptapton 0:6b0b61d411ad 134 for (int i=3; i<46; i+=3) {
mptapton 0:6b0b61d411ad 135 low1 = goertzelFilter(Buffer, (note - i ), Counter);
mptapton 0:6b0b61d411ad 136 if (low1 > low) low=low1;
mptapton 0:6b0b61d411ad 137 }
mptapton 0:6b0b61d411ad 138 in_tune1 = goertzelFilter(Buffer, (note+1), Counter);
mptapton 0:6b0b61d411ad 139 in_tune2 = goertzelFilter(Buffer, note, Counter);
mptapton 0:6b0b61d411ad 140 in_tune3 = goertzelFilter(Buffer, (note-1), Counter);
mptapton 0:6b0b61d411ad 141
mptapton 0:6b0b61d411ad 142 if ((in_tune1 > in_tune2) && (in_tune1 > in_tune3)) in_tune = in_tune1;
mptapton 0:6b0b61d411ad 143 else if ((in_tune2 > in_tune1) && (in_tune2 > in_tune3)) in_tune = in_tune2;
mptapton 0:6b0b61d411ad 144 else in_tune = in_tune3;
mptapton 0:6b0b61d411ad 145
mptapton 0:6b0b61d411ad 146 if ((in_tune > high) && (in_tune > low)) {
mptapton 0:6b0b61d411ad 147 led_high = 0;
mptapton 0:6b0b61d411ad 148 led_ok = 1;
mptapton 0:6b0b61d411ad 149 led_low = 0;
mptapton 0:6b0b61d411ad 150 } else if (high > in_tune) {
mptapton 0:6b0b61d411ad 151 led_high = 1;
mptapton 0:6b0b61d411ad 152 led_ok = 0;
mptapton 0:6b0b61d411ad 153 led_low = 0;
mptapton 0:6b0b61d411ad 154 } else if (low > in_tune) {
mptapton 0:6b0b61d411ad 155 led_high = 0;
mptapton 0:6b0b61d411ad 156 led_ok = 0;
mptapton 0:6b0b61d411ad 157 led_low = 1;
mptapton 0:6b0b61d411ad 158 } else {
mptapton 0:6b0b61d411ad 159 led_high = 0;
mptapton 0:6b0b61d411ad 160 led_ok = 0;
mptapton 0:6b0b61d411ad 161 led_low = 0;
mptapton 0:6b0b61d411ad 162 }
mptapton 0:6b0b61d411ad 163
mptapton 0:6b0b61d411ad 164 int pintwenty = adc.read(p20); //read pin 20
mptapton 0:6b0b61d411ad 165 lcd.locate(0,1);
mptapton 0:6b0b61d411ad 166 lcd.printf("%s %iHz %d\n",key, (int) note, pintwenty);
mptapton 0:6b0b61d411ad 167 if (led_ok) lcd.printf("Tuner- In Tune");
mptapton 0:6b0b61d411ad 168 else if (led_low) lcd.printf("Tuner- 2Low ");
mptapton 0:6b0b61d411ad 169 else if (led_high) lcd.printf("Tuner- 2High ");
mptapton 0:6b0b61d411ad 170 else lcd.printf("~~~~~~~~");
mptapton 0:6b0b61d411ad 171
mptapton 0:6b0b61d411ad 172 Counter = 0;
mptapton 0:6b0b61d411ad 173 } //inner while (1)loop
mptapton 0:6b0b61d411ad 174 } else { //if myinputpin
mptapton 0:6b0b61d411ad 175
mptapton 0:6b0b61d411ad 176 lcd.cls (); //Chord Tutor Section based on p21 being 0v
mptapton 0:6b0b61d411ad 177
mptapton 0:6b0b61d411ad 178 //Interupt for Switching chord selection
mptapton 0:6b0b61d411ad 179 button1.mode(PullDown);
mptapton 0:6b0b61d411ad 180 button1.rise(&button1_pressed);
mptapton 0:6b0b61d411ad 181
mptapton 0:6b0b61d411ad 182
mptapton 0:6b0b61d411ad 183
mptapton 0:6b0b61d411ad 184 while (1) {
mptapton 0:6b0b61d411ad 185
mptapton 0:6b0b61d411ad 186 switch (chord_select) {
mptapton 0:6b0b61d411ad 187 case 0:
mptapton 0:6b0b61d411ad 188 note = 82;
mptapton 0:6b0b61d411ad 189 key= "E2";
mptapton 0:6b0b61d411ad 190 //send E chord white LED pattern
mptapton 0:6b0b61d411ad 191 break;
mptapton 0:6b0b61d411ad 192 case 1:
mptapton 0:6b0b61d411ad 193 note = 110;
mptapton 0:6b0b61d411ad 194 key= "A2";
mptapton 0:6b0b61d411ad 195 //send A chord white LED pattern
mptapton 0:6b0b61d411ad 196 break;
mptapton 0:6b0b61d411ad 197 case 2:
mptapton 0:6b0b61d411ad 198 note = 147;
mptapton 0:6b0b61d411ad 199 key= "D3";
mptapton 0:6b0b61d411ad 200 //send D chord white LED pattern
mptapton 0:6b0b61d411ad 201 break;
mptapton 0:6b0b61d411ad 202 case 3:
mptapton 0:6b0b61d411ad 203 note = 196;
mptapton 0:6b0b61d411ad 204 key= "G3";
mptapton 0:6b0b61d411ad 205 //send G chord white LED pattern
mptapton 0:6b0b61d411ad 206 break;
mptapton 0:6b0b61d411ad 207 case 4:
mptapton 0:6b0b61d411ad 208 note = 247;
mptapton 0:6b0b61d411ad 209 key= "B3";
mptapton 0:6b0b61d411ad 210 //send B chord white LED pattern
mptapton 0:6b0b61d411ad 211 break;
mptapton 0:6b0b61d411ad 212 case 5:
mptapton 0:6b0b61d411ad 213 note = 2349;
mptapton 0:6b0b61d411ad 214 key= "D7";
mptapton 0:6b0b61d411ad 215 //send D7 chord white LED pattern
mptapton 0:6b0b61d411ad 216 break;
mptapton 0:6b0b61d411ad 217 case 6:
mptapton 0:6b0b61d411ad 218 note = 131;
mptapton 0:6b0b61d411ad 219 key= "C3";
mptapton 0:6b0b61d411ad 220 //send C chord white LED pattern
mptapton 0:6b0b61d411ad 221 break;
mptapton 0:6b0b61d411ad 222 case 7:
mptapton 0:6b0b61d411ad 223 note = 174;
mptapton 0:6b0b61d411ad 224 key= "F3";
mptapton 0:6b0b61d411ad 225 //send F chord white LED pattern
mptapton 0:6b0b61d411ad 226 break;
mptapton 0:6b0b61d411ad 227 case 8:
mptapton 0:6b0b61d411ad 228 note = 65;
mptapton 0:6b0b61d411ad 229 key= "C2";
mptapton 0:6b0b61d411ad 230 //send C chord white LED pattern
mptapton 0:6b0b61d411ad 231 break;
mptapton 0:6b0b61d411ad 232 case 9:
mptapton 0:6b0b61d411ad 233 note = 87;
mptapton 0:6b0b61d411ad 234 key= "F2";
mptapton 0:6b0b61d411ad 235 //send F chord white LED pattern
mptapton 0:6b0b61d411ad 236 break;
mptapton 0:6b0b61d411ad 237 }
mptapton 0:6b0b61d411ad 238
mptapton 0:6b0b61d411ad 239 //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford
mptapton 0:6b0b61d411ad 240 adc.append(sample_audio);
mptapton 0:6b0b61d411ad 241 adc.startmode(0,0);
mptapton 0:6b0b61d411ad 242 adc.burst(1);
mptapton 0:6b0b61d411ad 243 adc.setup(p20,1);
mptapton 0:6b0b61d411ad 244
mptapton 0:6b0b61d411ad 245 //start the interrupt and wait for about 4096 samples
mptapton 0:6b0b61d411ad 246 adc.interrupt_state(p20,1);
mptapton 0:6b0b61d411ad 247 wait(.2);
mptapton 0:6b0b61d411ad 248
mptapton 0:6b0b61d411ad 249 //Finsh up - Unset pin 20
mptapton 0:6b0b61d411ad 250 adc.interrupt_state(p20,0);
mptapton 0:6b0b61d411ad 251 adc.setup(p20,0);
mptapton 0:6b0b61d411ad 252 int actual_rate = adc.actual_sample_rate();
mptapton 0:6b0b61d411ad 253
mptapton 0:6b0b61d411ad 254 //for debugging tell the terminal sample rate and how many samples we took
mptapton 0:6b0b61d411ad 255 printf("Requested max sample rate is %u, actual max sample rate is %u.\n",
mptapton 0:6b0b61d411ad 256 SAMPLE_RATE, actual_rate);
mptapton 0:6b0b61d411ad 257 printf("We did %i samples\n",Counter);
mptapton 0:6b0b61d411ad 258
mptapton 0:6b0b61d411ad 259 high = 0;
mptapton 0:6b0b61d411ad 260 low = 0;
mptapton 0:6b0b61d411ad 261 for (int i=3; i<46; i+=3) {
mptapton 0:6b0b61d411ad 262 high1 = goertzelFilter(Buffer, (note + i ), Counter);
mptapton 0:6b0b61d411ad 263 if (high1 > high) high=high1;
mptapton 0:6b0b61d411ad 264 }
mptapton 0:6b0b61d411ad 265 for (int i=3; i<46; i+=3) {
mptapton 0:6b0b61d411ad 266 low1 = goertzelFilter(Buffer, (note - i ), Counter);
mptapton 0:6b0b61d411ad 267 if (low1 > low) low=low1;
mptapton 0:6b0b61d411ad 268 }
mptapton 0:6b0b61d411ad 269 in_tune1 = goertzelFilter(Buffer, (note+1), Counter);
mptapton 0:6b0b61d411ad 270 in_tune2 = goertzelFilter(Buffer, note, Counter);
mptapton 0:6b0b61d411ad 271 in_tune3 = goertzelFilter(Buffer, (note-1), Counter);
mptapton 0:6b0b61d411ad 272
mptapton 0:6b0b61d411ad 273 if ((in_tune1 > in_tune2) && (in_tune1 > in_tune3)) in_tune = in_tune1;
mptapton 0:6b0b61d411ad 274 else if ((in_tune2 > in_tune1) && (in_tune2 > in_tune3)) in_tune = in_tune2;
mptapton 0:6b0b61d411ad 275 else in_tune = in_tune3;
mptapton 0:6b0b61d411ad 276 if ((in_tune > high) && (in_tune > low)) {
mptapton 0:6b0b61d411ad 277 led_high = 0;
mptapton 0:6b0b61d411ad 278 led_ok = 1;
mptapton 0:6b0b61d411ad 279 led_low = 0;
mptapton 0:6b0b61d411ad 280 } else if (high > in_tune) {
mptapton 0:6b0b61d411ad 281 led_high = 1;
mptapton 0:6b0b61d411ad 282 led_ok = 0;
mptapton 0:6b0b61d411ad 283 led_low = 0;
mptapton 0:6b0b61d411ad 284 } else if (low > in_tune) {
mptapton 0:6b0b61d411ad 285 led_high = 0;
mptapton 0:6b0b61d411ad 286 led_ok = 0;
mptapton 0:6b0b61d411ad 287 led_low = 1;
mptapton 0:6b0b61d411ad 288 } else {
mptapton 0:6b0b61d411ad 289 led_high = 0;
mptapton 0:6b0b61d411ad 290 led_ok = 0;
mptapton 0:6b0b61d411ad 291 led_low = 0;
mptapton 0:6b0b61d411ad 292 }
mptapton 0:6b0b61d411ad 293
mptapton 0:6b0b61d411ad 294 int pintwenty = adc.read(p20); //read pin 20
mptapton 0:6b0b61d411ad 295 lcd.locate(0,1);
mptapton 0:6b0b61d411ad 296 lcd.printf("%s ",key);
mptapton 0:6b0b61d411ad 297 lcd.locate(4,1);// need to deal with lcd screen changes to length of frequencies
mptapton 0:6b0b61d411ad 298 lcd.printf(" ");
mptapton 0:6b0b61d411ad 299 lcd.locate(4,1);
mptapton 0:6b0b61d411ad 300 lcd.printf("%iHz",(int) note);
mptapton 0:6b0b61d411ad 301 lcd.locate(11,1);
mptapton 0:6b0b61d411ad 302 lcd.printf("%4d\n",pintwenty); //need to deal with lcd screen changes to restrict input decimal range to 4sf
mptapton 0:6b0b61d411ad 303 if (led_ok) lcd.printf("Play %s->In Tune",key); //if statement here for send green LED pattern for selected chord
mptapton 0:6b0b61d411ad 304 else if (led_low) lcd.printf("Play %s -> 2Low ",key);//if statement here for send red LED pattern for selected chord
mptapton 0:6b0b61d411ad 305 else if (led_high) lcd.printf("Play %s -> 2High",key);//if statement here for send red LED pattern for selected chord
mptapton 0:6b0b61d411ad 306 else lcd.printf("~~~~~~~~");
mptapton 0:6b0b61d411ad 307
mptapton 0:6b0b61d411ad 308 Counter = 0;
mptapton 0:6b0b61d411ad 309 }
mptapton 0:6b0b61d411ad 310 }
mptapton 0:6b0b61d411ad 311
mptapton 0:6b0b61d411ad 312
mptapton 0:6b0b61d411ad 313 }
mptapton 0:6b0b61d411ad 314 }