Guest User

Guitar Tuner Autocorrelation

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