![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Adapted code from original GT_Tuner code (by Andrew Durand) for a school project by Tapton School.
main.cpp
- Committer:
- mptapton
- Date:
- 2017-01-03
- Revision:
- 0:6b0b61d411ad
- Child:
- 1:c8ec50d75f80
File content as of revision 0:6b0b61d411ad:
// Guitar Tuner and Chord Learning Tool using Goertzel's Algorithm // // Based on original code created by: Andrew Durand // // Adjusted and modified by Tapton School EDS Project Team // #include "TextLCD.h" #include "mbed.h" #include "adc.h" #include <math.h> #define PI 3.1415 #define SAMPLE_RATE 24000 DigitalOut led_low(LED1); DigitalOut led_ok(LED2); DigitalOut led_high(LED4); InterruptIn button1(p6); //mosi DigitalIn myInputPin (p21); //select tuner or chord learning mode //LCD and Other Random Variables //NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type /* This code uses libraries created for 4-bit LCD's based on the HD44780. This program was designed for a similar product (Winstar's WH1602B 2x16 LC) working into an Mbed LPC1768. LCD pins: Pin 1(VSS) to Mbed Gnd, Pin 2(VDD) to Mbed 5v USB output, Pin 3(Vo- contrast) 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 MBed Gnd, Pins 4(RS),20(E) and the 4 data bits (DB4 [11] through to DB7 [14]) go to the Mbed pins described below: */ TextLCD lcd(p10, p12, p15, p16, p29, p30); // rs, e, d4-d7 int string_select = 0; int chord_select = 0; float high, high1, in_tune, in_tune1, in_tune2, in_tune3, low, low1, note, low_mod, high_mod; char* key; int Counter = 0; int Buffer[6000]; float goertzelFilter(int samples[], float freq, int N) { float s_prev = 0.0; float s_prev2 = 0.0; float coeff,normalizedfreq,power,s; int i; normalizedfreq = freq / SAMPLE_RATE; coeff = 2*cos(2*PI*normalizedfreq); for (i=0; i<N; i++) { s = samples[i] + coeff * s_prev - s_prev2; s_prev2 = s_prev; s_prev = s; } power = s_prev2*s_prev2+s_prev*s_prev-coeff*s_prev*s_prev2; return power; } ADC adc(SAMPLE_RATE, 1); void sample_audio(int chan, uint32_t value) { Buffer[Counter] = adc.read(p20); Counter += 1; } void button1_pressed() { string_select++; chord_select++; if (string_select > 5) string_select = 0; if (chord_select > 9) chord_select = 0;//change for number of chords supported } int main() { while (1) { myInputPin.mode(PullUp); //set the mbed to use a pullup resistor if (myInputPin) { //select guitar tuner or chord teaching lcd.cls (); // Guitar Tuner Section based on p21 being +3v //Interupt for Switching Strings button1.mode(PullDown); button1.rise(&button1_pressed); while (1) { switch (string_select) { case 0: note = 82; key= "E2"; break; case 1: note = 110; key= "A2"; break; case 2: note = 147; key= "D3"; break; case 3: note = 196; key= "G3"; break; case 4: note = 247; key= "B3"; break; case 5: note = 330; key= "E4"; break; } //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford adc.append(sample_audio); adc.startmode(0,0); adc.burst(1); adc.setup(p20,1); //start the interrupt and wait for about 4096 samples adc.interrupt_state(p20,1); wait(.2); //Finsh up - Unset pin 20 adc.interrupt_state(p20,0); adc.setup(p20,0); int actual_rate = adc.actual_sample_rate(); //for debugging tell the terminal sample rate and how many samples we took printf("Requested max sample rate is %u, actual max sample rate is %u.\n", SAMPLE_RATE, actual_rate); printf("We did %i samples\n",Counter); high = 0; low = 0; for (int i=3; i<46; i+=3) { high1 = goertzelFilter(Buffer, (note + i ), Counter); if (high1 > high) high=high1; } for (int i=3; i<46; i+=3) { low1 = goertzelFilter(Buffer, (note - i ), Counter); if (low1 > low) low=low1; } in_tune1 = goertzelFilter(Buffer, (note+1), Counter); in_tune2 = goertzelFilter(Buffer, note, Counter); in_tune3 = goertzelFilter(Buffer, (note-1), Counter); if ((in_tune1 > in_tune2) && (in_tune1 > in_tune3)) in_tune = in_tune1; else if ((in_tune2 > in_tune1) && (in_tune2 > in_tune3)) in_tune = in_tune2; else in_tune = in_tune3; if ((in_tune > high) && (in_tune > low)) { led_high = 0; led_ok = 1; led_low = 0; } else if (high > in_tune) { led_high = 1; led_ok = 0; led_low = 0; } else if (low > in_tune) { led_high = 0; led_ok = 0; led_low = 1; } else { led_high = 0; led_ok = 0; led_low = 0; } int pintwenty = adc.read(p20); //read pin 20 lcd.locate(0,1); lcd.printf("%s %iHz %d\n",key, (int) note, pintwenty); if (led_ok) lcd.printf("Tuner- In Tune"); else if (led_low) lcd.printf("Tuner- 2Low "); else if (led_high) lcd.printf("Tuner- 2High "); else lcd.printf("~~~~~~~~"); Counter = 0; } //inner while (1)loop } else { //if myinputpin lcd.cls (); //Chord Tutor Section based on p21 being 0v //Interupt for Switching chord selection button1.mode(PullDown); button1.rise(&button1_pressed); while (1) { switch (chord_select) { case 0: note = 82; key= "E2"; //send E chord white LED pattern break; case 1: note = 110; key= "A2"; //send A chord white LED pattern break; case 2: note = 147; key= "D3"; //send D chord white LED pattern break; case 3: note = 196; key= "G3"; //send G chord white LED pattern break; case 4: note = 247; key= "B3"; //send B chord white LED pattern break; case 5: note = 2349; key= "D7"; //send D7 chord white LED pattern break; case 6: note = 131; key= "C3"; //send C chord white LED pattern break; case 7: note = 174; key= "F3"; //send F chord white LED pattern break; case 8: note = 65; key= "C2"; //send C chord white LED pattern break; case 9: note = 87; key= "F2"; //send F chord white LED pattern break; } //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford adc.append(sample_audio); adc.startmode(0,0); adc.burst(1); adc.setup(p20,1); //start the interrupt and wait for about 4096 samples adc.interrupt_state(p20,1); wait(.2); //Finsh up - Unset pin 20 adc.interrupt_state(p20,0); adc.setup(p20,0); int actual_rate = adc.actual_sample_rate(); //for debugging tell the terminal sample rate and how many samples we took printf("Requested max sample rate is %u, actual max sample rate is %u.\n", SAMPLE_RATE, actual_rate); printf("We did %i samples\n",Counter); high = 0; low = 0; for (int i=3; i<46; i+=3) { high1 = goertzelFilter(Buffer, (note + i ), Counter); if (high1 > high) high=high1; } for (int i=3; i<46; i+=3) { low1 = goertzelFilter(Buffer, (note - i ), Counter); if (low1 > low) low=low1; } in_tune1 = goertzelFilter(Buffer, (note+1), Counter); in_tune2 = goertzelFilter(Buffer, note, Counter); in_tune3 = goertzelFilter(Buffer, (note-1), Counter); if ((in_tune1 > in_tune2) && (in_tune1 > in_tune3)) in_tune = in_tune1; else if ((in_tune2 > in_tune1) && (in_tune2 > in_tune3)) in_tune = in_tune2; else in_tune = in_tune3; if ((in_tune > high) && (in_tune > low)) { led_high = 0; led_ok = 1; led_low = 0; } else if (high > in_tune) { led_high = 1; led_ok = 0; led_low = 0; } else if (low > in_tune) { led_high = 0; led_ok = 0; led_low = 1; } else { led_high = 0; led_ok = 0; led_low = 0; } int pintwenty = adc.read(p20); //read pin 20 lcd.locate(0,1); lcd.printf("%s ",key); lcd.locate(4,1);// need to deal with lcd screen changes to length of frequencies lcd.printf(" "); lcd.locate(4,1); lcd.printf("%iHz",(int) note); lcd.locate(11,1); lcd.printf("%4d\n",pintwenty); //need to deal with lcd screen changes to restrict input decimal range to 4sf if (led_ok) lcd.printf("Play %s->In Tune",key); //if statement here for send green LED pattern for selected chord else if (led_low) lcd.printf("Play %s -> 2Low ",key);//if statement here for send red LED pattern for selected chord else if (led_high) lcd.printf("Play %s -> 2High",key);//if statement here for send red LED pattern for selected chord else lcd.printf("~~~~~~~~"); Counter = 0; } } } }