![](/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.
Diff: main.cpp
- Revision:
- 0:6b0b61d411ad
- Child:
- 1:c8ec50d75f80
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jan 03 13:46:19 2017 +0000 @@ -0,0 +1,314 @@ +// 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; + } + } + + + } +} \ No newline at end of file