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

Dependencies:   mbed

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