Advertisement
Guest User

Guitar Tuner Autocorrelation

a guest
May 3rd, 2013
442
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*********************************************************************************************************************
  2.     PESIT EEE 6th Sem Mini Project
  3.     May 2013
  4.    
  5.     ELECTRONIC GUITAR TUNER
  6.    
  7.     Tested on: Arduino Uno
  8.     Main Algorithm Used: Autocorrelation (for fundamental frequency)
  9.     Software version: 1.0.1
  10.    
  11.     Test Parameters:
  12.     INPUT: Emulated Acoustic guitar sound from Guitar Pro V5 (for windows)
  13.     SIGNAL FLOW: Computer Audio out->Operational Amplifier->Arduino Uno->7 Segment Display
  14.    
  15.     USNs:   1PI10EE009
  16.             1PI10EE026
  17.             1PI10EE019
  18. *********************************************************************************************************************/                     
  19.  
  20.  
  21. /*****************************************************************************
  22.                 DECLARATIONS
  23. ******************************************************************************/
  24.  
  25. #define N 200 //Buffer Size
  26. #define sampleF 38500//Hz
  27. #define display_time 5000//ms
  28.  
  29.  
  30. byte incomingAudio, bIndex=N-1;
  31. int buffer[N];
  32. long int corr[N], corrMin;
  33. long int t_old, t_new = millis();
  34. int i, j, minIndex,s;
  35. int Freq=0;
  36. boolean clipping = 0, flag = 0;
  37.  
  38.  
  39. const int A  = 110,     //These are the standard note frequencies
  40.       As = 116,         //At the lowest octave
  41.       B  = 123,
  42.       C  = 131,
  43.       Cs = 139,
  44.       D  = 147,
  45.       Ds = 156,
  46.       E  = 165,
  47.       F  = 171,
  48.       Fs = 185,
  49.       G  = 196,
  50.       Gs = 208;
  51. int note = A;
  52. int deviation = 0;
  53. bool dev;       //Higher or lower from the correct note
  54. bool correct;   //To show that the guitar is in tune
  55.  
  56. /*****************************************************************************
  57.         FUNCTION TO COMPUTE FUNDAMENTAL FREQUENCY
  58. ******************************************************************************/
  59.  
  60. void compute(void){
  61.   //Autocorrelate and find minimum point
  62.   minIndex=0;
  63.   for(i=0; i<=N-1; i++){
  64.     corr[i] = 0;
  65.     for(j=0; j<=N-1; j++){
  66.       s = j+i;
  67.       if((j+i)>(N-1))
  68.           s = (j+i) - (N-1);
  69.       corr[i] = corr[i] + (int)buffer[j]*buffer[s];
  70.     }  
  71.       if(corr[i]<corr[minIndex])
  72.         minIndex = i;
  73.    
  74.   }
  75.  
  76.   //Calculate Frequency
  77.   Freq = sampleF/(minIndex*2);    
  78. }
  79.  
  80.  
  81. /*****************************************************************************
  82.             PITCH DETECTION FUNCTION
  83. ******************************************************************************/
  84.  
  85. void pitch(void){
  86.     /*
  87.     This function is used to find the pitch after finding frequency and display the
  88.     outputs on the 7 segment display and the LEDs  
  89.     */
  90.    
  91.     const float t = 0.035; //tolerance band for note
  92.     const float t2 = 0.01; //tolerance band for correct note                
  93.     int octave = 1;
  94.      
  95.     //FIND OCTAVE
  96.     if(Freq > Gs*1)
  97.         octave = 2;
  98.     if(Freq > Gs*2)
  99.         octave =4;
  100.     if(Freq > Gs*4)
  101.         octave = 8;
  102.  
  103.     /*FIND PITCH
  104.       The following portion is equivalent to checking if 'Freq'
  105.       lies within a certain band around the given note.
  106.       The width of this band is set by 't' (a percentage value)
  107.       Check if:
  108.            (input_note) lies within required_note +/- (percentage*required_note)
  109.     */
  110.      
  111.       if( Freq > (A*octave)*(1-t) && Freq < (A*octave)*(1+t) ){
  112.         note = A;
  113.         //Signal the 7 seg display with the letter in each of these if statements.
  114.         seven_seg_A();
  115.         }
  116.       else  if( Freq > (As*octave)*(1-t) && Freq < (As*octave)*(1+t) ){
  117.         note = As;
  118.         seven_seg_As();
  119.         }
  120.       else  if( Freq > (B*octave)*(1-t) && Freq < (B*octave)*(1+t) ){
  121.         note = B;
  122.         seven_seg_B();
  123.         }
  124.       else  if( Freq > (C*octave)*(1-t) && Freq < (C*octave)*(1+t) ){
  125.         note = C;
  126.         seven_seg_C();
  127.         }
  128.       else  if( Freq > (Cs*octave)*(1-t) && Freq < (Cs*octave)*(1+t) ){
  129.         note = Cs;
  130.         seven_seg_Cs();
  131.         }
  132.       else  if( Freq > (D*octave)*(1-t) && Freq < (D*octave)*(1+t) ){
  133.         note = D;
  134.         seven_seg_D();
  135.         }
  136.       else  if( Freq > (Ds*octave)*(1-t) && Freq < (Ds*octave)*(1+t) ){
  137.         note = Ds;
  138.         seven_seg_Ds();
  139.         }
  140.       else  if( Freq > (E*octave)*(1-t) && Freq < (E*octave)*(1+t) ){
  141.         note = E;
  142.         seven_seg_E();
  143.         }
  144.       else  if( Freq > (F*octave)*(1-t) && Freq < (F*octave)*(1+t) ){
  145.         note = F;
  146.         seven_seg_F();
  147.         }
  148.       else  if( Freq > (Fs*octave)*(1-t) && Freq < (Fs*octave)*(1+t) ){
  149.         note = Fs;
  150.         seven_seg_Fs();
  151.         }
  152.       else  if( Freq > (G*octave)*(1-t) && Freq < (G*octave)*(1+t) ){
  153.         note = G;
  154.         seven_seg_G();
  155.         }
  156.       else  if( Freq > (Gs*octave)*(1-t) && Freq < (Gs*octave)*(1+t) ){
  157.         note = Gs;
  158.         seven_seg_Gs();
  159.         }
  160.      
  161.       //DISPLAY
  162.       deviation = Freq - note*octave;
  163.       if (abs(deviation) < t2*note){
  164.          correct = 1;      //in tune
  165.          //Serial.print(" ");
  166.          //Serial.println("Correct");
  167.          }
  168.       else{
  169.         correct = 0;      //not in tune
  170.         if((deviation)>0){
  171.           //Serial.print(" ");
  172.           //Serial.println("Note = deviated HIGH");
  173.           dev = HIGH;
  174.         }
  175.         else {
  176.             // Serial.print(" ");
  177.             //Serial.println("Deviated Low");
  178.             dev = LOW;
  179.         }
  180.     }
  181. }
  182. /***************END OF PITCH DETECTION FUNCTION****************/
  183.  
  184.  
  185. /******************************************************************************
  186.             FUNCTIONS FOR 7 SEGMENT DISPLAY
  187. *******************************************************************************/
  188.  
  189. //These are used to display the specific note on the 7 segment display
  190. void seven_seg_A(void){
  191.   digitalWrite(9, LOW);
  192.   digitalWrite(8, LOW);
  193.   digitalWrite(7, LOW);
  194.   digitalWrite(6, HIGH);
  195.   digitalWrite(5, LOW);
  196.   digitalWrite(4, LOW);
  197.   digitalWrite(3, LOW);
  198.   digitalWrite(2, HIGH);
  199.   if(correct == 1)
  200.   {
  201.     digitalWrite(12,LOW);
  202.     digitalWrite(11,HIGH);
  203.     digitalWrite(10,LOW);
  204.   }
  205.   else if(correct == 0)
  206.   {
  207.     if(dev == HIGH)
  208.     {
  209.       digitalWrite(12,LOW);
  210.       digitalWrite(11,LOW);
  211.       digitalWrite(10,HIGH);
  212.     }
  213.     else if(dev == LOW)
  214.     {
  215.       digitalWrite(12,HIGH);
  216.       digitalWrite(11,LOW);
  217.       digitalWrite(10,LOW);
  218.     }
  219.   }
  220. }
  221.  
  222. void seven_seg_As(void){
  223.     digitalWrite(9, LOW);
  224.     digitalWrite(8, LOW);
  225.     digitalWrite(7, LOW);
  226.     digitalWrite(6, HIGH);
  227.     digitalWrite(5, LOW);
  228.     digitalWrite(4, LOW);
  229.     digitalWrite(3, LOW);
  230.     digitalWrite(2, LOW);
  231.     if(correct == 1)
  232.       {
  233.         digitalWrite(12,LOW);
  234.         digitalWrite(11,HIGH);
  235.         digitalWrite(10,LOW);
  236.       }
  237.       else if(correct == 0)
  238.       {
  239.         if(dev == HIGH)
  240.         {
  241.           digitalWrite(12,LOW);
  242.           digitalWrite(11,LOW);
  243.           digitalWrite(10,HIGH);
  244.         }
  245.         else if(dev == LOW)
  246.         {
  247.           digitalWrite(12,HIGH);
  248.           digitalWrite(11,LOW);
  249.           digitalWrite(10,LOW);
  250.         }
  251.       }
  252.     }
  253.  
  254. void seven_seg_B(void){
  255.     digitalWrite(9, HIGH);
  256.     digitalWrite(8, HIGH);
  257.     digitalWrite(7, LOW);
  258.     digitalWrite(6, LOW);
  259.     digitalWrite(5, LOW);
  260.     digitalWrite(4, LOW);
  261.     digitalWrite(3, LOW);
  262.     digitalWrite(2, HIGH);
  263.     if(correct == 1)
  264.       {
  265.         digitalWrite(12,LOW);
  266.         digitalWrite(11,HIGH);
  267.         digitalWrite(10,LOW);
  268.       }
  269.       else if(correct == 0)
  270.       {
  271.         if(dev == HIGH)
  272.         {
  273.           digitalWrite(12,LOW);
  274.           digitalWrite(11,LOW);
  275.           digitalWrite(10,HIGH);
  276.         }
  277.         else if(dev == LOW)
  278.         {
  279.           digitalWrite(12,HIGH);
  280.           digitalWrite(11,LOW);
  281.           digitalWrite(10,LOW);
  282.         }
  283.       }
  284.     }
  285.  
  286. void seven_seg_C(void){
  287.     digitalWrite(9, HIGH);
  288.     digitalWrite(8, HIGH);
  289.     digitalWrite(7, HIGH);
  290.     digitalWrite(6, LOW);
  291.     digitalWrite(5, LOW);
  292.     digitalWrite(4, HIGH);
  293.     digitalWrite(3, LOW);
  294.     digitalWrite(2, HIGH);
  295.     if(correct == 1)
  296.       {
  297.         digitalWrite(12,LOW);
  298.         digitalWrite(11,HIGH);
  299.         digitalWrite(10,LOW);
  300.       }
  301.       else if(correct == 0)
  302.       {
  303.         if(dev == HIGH)
  304.         {
  305.           digitalWrite(12,LOW);
  306.           digitalWrite(11,LOW);
  307.           digitalWrite(10,HIGH);
  308.         }
  309.         else if(dev == LOW)
  310.         {
  311.           digitalWrite(12,HIGH);
  312.           digitalWrite(11,LOW);
  313.           digitalWrite(10,LOW);
  314.         }
  315.       }
  316.     }
  317.  
  318. void seven_seg_Cs(void){
  319.     digitalWrite(9, HIGH);
  320.     digitalWrite(8, HIGH);
  321.     digitalWrite(7, HIGH);
  322.     digitalWrite(6, LOW);
  323.     digitalWrite(5, LOW);
  324.     digitalWrite(4, HIGH);
  325.     digitalWrite(3, LOW);
  326.     digitalWrite(2, LOW);
  327.     if(correct == 1)
  328.       {
  329.         digitalWrite(12,LOW);
  330.         digitalWrite(11,HIGH);
  331.         digitalWrite(10,LOW);
  332.       }
  333.       else if(correct == 0)
  334.       {
  335.         if(dev == HIGH)
  336.         {
  337.           digitalWrite(12,LOW);
  338.           digitalWrite(11,LOW);
  339.           digitalWrite(10,HIGH);
  340.         }
  341.         else if(dev == LOW)
  342.         {
  343.           digitalWrite(12,HIGH);
  344.           digitalWrite(11,LOW);
  345.           digitalWrite(10,LOW);
  346.         }
  347.       }
  348.     }
  349.  
  350. void seven_seg_D(void){
  351.     digitalWrite(9, HIGH);
  352.     digitalWrite(8, LOW);
  353.     digitalWrite(7, LOW);
  354.     digitalWrite(6, LOW);
  355.     digitalWrite(5, LOW);
  356.     digitalWrite(4, HIGH);
  357.     digitalWrite(3, LOW);
  358.     digitalWrite(2, HIGH);
  359.     if(correct == 1)
  360.       {
  361.         digitalWrite(12,LOW);
  362.         digitalWrite(11,HIGH);
  363.         digitalWrite(10,LOW);
  364.       }
  365.       else if(correct == 0)
  366.       {
  367.         if(dev == HIGH)
  368.         {
  369.           digitalWrite(12,LOW);
  370.           digitalWrite(11,LOW);
  371.           digitalWrite(10,HIGH);
  372.         }
  373.         else if(dev == LOW)
  374.         {
  375.           digitalWrite(12,HIGH);
  376.           digitalWrite(11,LOW);
  377.           digitalWrite(10,LOW);
  378.         }
  379.       }
  380.     }
  381.  
  382. void seven_seg_Ds(void){
  383.     digitalWrite(9, HIGH);
  384.     digitalWrite(8, LOW);
  385.     digitalWrite(7, LOW);
  386.     digitalWrite(6, LOW);
  387.     digitalWrite(5, LOW);
  388.     digitalWrite(4, HIGH);
  389.     digitalWrite(3, LOW);
  390.     digitalWrite(2, LOW);
  391.     if(correct == 1)
  392.       {
  393.         digitalWrite(12,LOW);
  394.         digitalWrite(11,HIGH);
  395.         digitalWrite(10,LOW);
  396.       }
  397.       else if(correct == 0)
  398.       {
  399.         if(dev == HIGH)
  400.         {
  401.           digitalWrite(12,LOW);
  402.           digitalWrite(11,LOW);
  403.           digitalWrite(10,HIGH);
  404.         }
  405.         else if(dev == LOW)
  406.         {
  407.           digitalWrite(12,HIGH);
  408.           digitalWrite(11,LOW);
  409.           digitalWrite(10,LOW);
  410.         }
  411.       }
  412.     }
  413.  
  414. void seven_seg_E(void){
  415.     digitalWrite(9, LOW);
  416.     digitalWrite(8, HIGH);
  417.     digitalWrite(7, HIGH);
  418.     digitalWrite(6, LOW);
  419.     digitalWrite(5, LOW);
  420.     digitalWrite(4, LOW);
  421.     digitalWrite(3, LOW);
  422.     digitalWrite(2, HIGH);
  423.     if(correct == 1)
  424.       {
  425.         digitalWrite(12,LOW);
  426.         digitalWrite(11,HIGH);
  427.         digitalWrite(10,LOW);
  428.       }
  429.       else if(correct == 0)
  430.       {
  431.         if(dev == HIGH)
  432.         {
  433.           digitalWrite(12,LOW);
  434.           digitalWrite(11,LOW);
  435.           digitalWrite(10,HIGH);
  436.         }
  437.         else if(dev == LOW)
  438.         {
  439.           digitalWrite(12,HIGH);
  440.           digitalWrite(11,LOW);
  441.           digitalWrite(10,LOW);
  442.         }
  443.       }
  444.     }
  445.    
  446. void seven_seg_F(void){
  447.     digitalWrite(9, LOW);
  448.     digitalWrite(8, HIGH);
  449.     digitalWrite(7, HIGH);
  450.     digitalWrite(6, HIGH);
  451.     digitalWrite(5, LOW);
  452.     digitalWrite(4, LOW);
  453.     digitalWrite(3, LOW);
  454.     digitalWrite(2, HIGH);
  455.     if(correct == 1)
  456.       {
  457.         digitalWrite(12,LOW);
  458.         digitalWrite(11,HIGH);
  459.         digitalWrite(10,LOW);
  460.       }
  461.       else if(correct == 0)
  462.       {
  463.         if(dev == HIGH)
  464.         {
  465.           digitalWrite(12,LOW);
  466.           digitalWrite(11,LOW);
  467.           digitalWrite(10,HIGH);
  468.         }
  469.         else if(dev == LOW)
  470.         {
  471.           digitalWrite(12,HIGH);
  472.           digitalWrite(11,LOW);
  473.           digitalWrite(10,LOW);
  474.         }
  475.       }
  476.     }
  477.  
  478. void seven_seg_Fs(void){
  479.     digitalWrite(9, LOW);
  480.     digitalWrite(8, HIGH);
  481.     digitalWrite(7, HIGH);
  482.     digitalWrite(6, HIGH);
  483.     digitalWrite(5, LOW);
  484.     digitalWrite(4, LOW);
  485.     digitalWrite(3, LOW);
  486.     digitalWrite(2, LOW);
  487.     if(correct == 1)
  488.       {
  489.         digitalWrite(12,LOW);
  490.         digitalWrite(11,HIGH);
  491.         digitalWrite(10,LOW);
  492.       }
  493.       else if(correct == 0)
  494.       {
  495.         if(dev == HIGH)
  496.         {
  497.           digitalWrite(12,LOW);
  498.           digitalWrite(11,LOW);
  499.           digitalWrite(10,HIGH);
  500.         }
  501.         else if(dev == LOW)
  502.         {
  503.           digitalWrite(12,HIGH);
  504.           digitalWrite(11,LOW);
  505.           digitalWrite(10,LOW);
  506.         }
  507.       }
  508.     }
  509.  
  510. void seven_seg_G(void){
  511.     digitalWrite(9, LOW);
  512.     digitalWrite(8, LOW);
  513.     digitalWrite(7, LOW);
  514.     digitalWrite(6, LOW);
  515.     digitalWrite(5, HIGH);
  516.     digitalWrite(4, LOW);
  517.     digitalWrite(3, LOW);
  518.     digitalWrite(2, HIGH);
  519.     if(correct == 1)
  520.       {
  521.         digitalWrite(12,LOW);
  522.         digitalWrite(11,HIGH);
  523.         digitalWrite(10,LOW);
  524.       }
  525.       else if(correct == 0)
  526.       {
  527.         if(dev == HIGH)
  528.         {
  529.           digitalWrite(12,LOW);
  530.           digitalWrite(11,LOW);
  531.           digitalWrite(10,HIGH);
  532.         }
  533.         else if(dev == LOW)
  534.         {
  535.           digitalWrite(12,HIGH);
  536.           digitalWrite(11,LOW);
  537.           digitalWrite(10,LOW);
  538.         }
  539.       }
  540.     }
  541.  
  542. void seven_seg_Gs(void){
  543.     digitalWrite(9, LOW);
  544.     digitalWrite(8, LOW);
  545.     digitalWrite(7, LOW);
  546.     digitalWrite(6, LOW);
  547.     digitalWrite(5, HIGH);
  548.     digitalWrite(4, LOW);
  549.     digitalWrite(3, LOW);
  550.     digitalWrite(2, LOW);
  551.     if(correct == 1)
  552.       {
  553.         digitalWrite(12,LOW);
  554.         digitalWrite(11,HIGH);
  555.         digitalWrite(10,LOW);
  556.       }
  557.       else if(correct == 0)
  558.       {
  559.         if(dev == HIGH)
  560.         {
  561.           digitalWrite(12,LOW);
  562.           digitalWrite(11,LOW);
  563.           digitalWrite(10,HIGH);
  564.         }
  565.         else if(dev == LOW)
  566.         {
  567.           digitalWrite(12,HIGH);
  568.           digitalWrite(11,LOW);
  569.           digitalWrite(10,LOW);
  570.         }
  571.       }
  572.     }
  573.  
  574. void blank(void){
  575.     //Blanks out the 7 Segment display
  576.     digitalWrite(10, LOW);
  577.     digitalWrite(11, LOW);
  578.     digitalWrite(12, LOW);
  579.     digitalWrite(9, HIGH);
  580.     digitalWrite(8, HIGH);
  581.     digitalWrite(7, HIGH);
  582.     digitalWrite(6, HIGH);
  583.     digitalWrite(5, HIGH);
  584.     digitalWrite(4, HIGH);
  585.     digitalWrite(3, HIGH);
  586.     digitalWrite(2, HIGH);
  587.     }
  588.    
  589. void test(void){
  590.       //To test the 7 Segment display
  591.       seven_seg_A();
  592.       delay(500);
  593.       seven_seg_As();
  594.       delay(500);
  595.       seven_seg_B();
  596.       delay(500);
  597.       seven_seg_C();
  598.       delay(500);
  599.       seven_seg_Cs();
  600.       delay(500);
  601.       seven_seg_D();
  602.       delay(500);
  603.       seven_seg_Ds();
  604.       delay(500);
  605.       seven_seg_E();
  606.       delay(500);
  607.       seven_seg_F();
  608.       delay(500);
  609.       seven_seg_Fs();
  610.       delay(500);
  611.       seven_seg_G();
  612.       delay(500);
  613.       seven_seg_Gs();
  614.       delay(500);
  615.       blank();
  616.     }  
  617.    
  618. /***************END OF 7 SEG FUNCTIONS****************/
  619.  
  620. /*****************************************************************************
  621.                 SETUP
  622. ******************************************************************************/
  623.  
  624. void setup(){
  625.   pinMode(13,OUTPUT);//led clipping indicator pin
  626.   cli();    //disable interrupts
  627.  
  628.   //set up continuous sampling of analog pin 0
  629.   ADCSRA = 0;            //clear ADCSRA and ADCSRB registers
  630.   ADCSRB = 0;
  631.   ADMUX |= (1 << REFS0); //set reference voltage
  632.   ADMUX |= (1 << ADLAR); //left align the ADC value- so we can read highest 8 bits from ADCH register only
  633.   ADCSRA |= (1 << ADPS2) | (1 << ADPS0); //set ADC clock with 32 prescaler- 16mHz/32=500kHz
  634.   //ADCSRA |= (1 << ADPS2) | (0 << ADPS1) | (0 << ADPS0);
  635.   ADCSRA |= (1 << ADATE); //enabble auto trigger
  636.   ADCSRA |= (1 << ADIE); //enable interrupts when measurement complete
  637.   ADCSRA |= (1 << ADEN); //enable ADC
  638.   ADCSRA |= (1 << ADSC); //start ADC measurements
  639.   sei();//enable interrupts
  640.  
  641.  
  642.   Serial.begin(9600);
  643. }
  644.  
  645.  
  646. /*****************************************************************************
  647.             INTERRUPT SERVICE ROUTINE
  648. ******************************************************************************/
  649. ISR(ADC_vect) {//when new ADC value ready
  650.   incomingAudio = ADCH;//store 8 bit value from analog pin 0
  651.  
  652.   //t_new = millis();
  653.   if (incomingAudio == 0 || incomingAudio == 255){//if clipping
  654.     digitalWrite(13,HIGH);//set pin 13 high
  655.     clipping = 1;//currently clipping
  656.   }
  657.  
  658.   //Store in buffer                            //Works
  659.   if(bIndex!=N-1){
  660.     buffer[bIndex] = incomingAudio;
  661.     bIndex++;
  662.   }
  663.   else{
  664.     bIndex = 0;
  665.     //flag = 1;
  666.   }
  667. }
  668.  
  669. /***************END OF INTERRUPT SERVICE ROUTINE**************/
  670.  
  671. /*****************************************************************************
  672.                     LOOP
  673. ******************************************************************************/
  674.  
  675. void loop(){
  676.    
  677.     if (clipping){//if currently clipping
  678.       clipping = 0;//
  679.       digitalWrite(13,LOW);//turn off clipping led indicator (pin 13)
  680.       }
  681.  
  682.     cli();
  683.     compute();
  684.     //To print results on serial monitor
  685.     //Serial.print(Freq);
  686.     //Serial.println(" hz");
  687.     sei();
  688.  
  689.  
  690. }
  691.  
  692. /***************END OF LOOP**************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement