Go Down

Topic: Audio input analyzed w/ Arduino FFT (Read 13886 times) previous topic - next topic

rexhex

Hello Arduino audio forum members,

I am working on an audio project and have reached the part where I need to do some audio processing. I have been spending some time getting the audio into the arduino with an op amp. I have it so that my audio signal going into the arduino oscilates around 2.5v and does not exceed 0 - 5v. I am working on improving the circuit for my needs but it is working and I am going to post a schematic of what I have below. Here are some resources for those that are interested.

Amanda's Instructable was a good start but she uses dual supply for her op amp and single supply makes more sense for real applications.
 http://www.instructables.com/id/Arduino-Audio-Input/

So this circuit comes into play for single supply op amp with the chip she uses.
http://www.rason.org/Projects/opamps/opamps.htm

and here is some good info on op amps
http://www.ti.com/lit/ml/sloa076/sloa076.pdf

Now for some reason I thought this project would be slightly easier than it is proving to be but Im happy with the learning experience and that I have a good audio signal going to A0.

After 5 hours of research I have decided that the arduino library FFT is my best best to get real time analysis of the audios frequencies. http://wiki.openmusiclabs.com/wiki/ArduinoFFT

I would like to input the audio going into A0 through the FFT functions to output real time frequencies so that I can do work with that data. Looking at functions Im not really sure where to put A0. I figured I would post this to see if anyone has any ideas on how to do this or any better places to look for an arduino to analyze audio.

Thank you for your time,

Rex


rexhex

This is the schematic. It did not let me upload the image.

also, not being able to post until after waiting 10min is  frustrating.


rexhex

Looks like ADC0 is how we are talking about A0 in this code. Maybe a register? Anyways, I can see that the code is set up for ADC0 data to go into fft_input[].

When I try to upload example code I get "fft_input" was not declared in this scope.

I found this problem has happened before and was mentioned in arduino forum space.
http://forum.arduino.cc/index.php?topic=175219.0

I unzipped the library in the arduino library folder. This was suggested on the other forum post.

I am using mac 10.6 --> wishing I could use my chrome book even if I had to put it in Ubuntu or Mint for it to work...

The IDE I am using is Aruino 1.0.6. I believe this is the newest IDE that works on my mac.

adamatcooranbong, who posted this issue without a solution, said he used IDE Arduino 1.0, 1.0.5 and 1.5.2

Any ideas?




tmd3


rexhex

Here is open music labs example code for their fft library. This is where I get an error on fft_input

Code: [Select]

   1 /*
   2 fft_adc.pde
   3 guest openmusiclabs.com 8.18.12
   4 example sketch for testing the fft library.
   5 it takes in data on ADC0 (Analog0) and processes them
   6 with the fft. the data is sent out over the serial
   7 port at 115.2kb.  there is a pure data patch for
   8 visualizing the data.
   9 */
  10
  11 // do #defines BEFORE #includes
  12 #define LOG_OUT 1 // use the log output function
  13 #define FFT_N 256 // set to 256 point fft
  14
  15 #include <FFT.h> // include the library
  16
  17 void setup() {
  18   Serial.begin(115200); // use the serial port
  19   TIMSK0 = 0; // turn off timer0 for lower jitter - delay() and millis() killed
  20   ADCSRA = 0xe5; // set the adc to free running mode
  21   ADMUX = 0x40; // use adc0
  22   DIDR0 = 0x01; // turn off the digital input for adc0
  23 }
  24
  25 void loop() {
  26   while(1) { // reduces jitter
  27     cli();  // UDRE interrupt slows this way down on arduino1.0
  28     for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
  29       while(!(ADCSRA & 0x10)); // wait for adc to be ready
  30       ADCSRA = 0xf5; // restart adc
  31       byte m = ADCL; // fetch adc data
  32       byte j = ADCH;
  33       int k = (j << 8) | m; // form into an int
  34       k -= 0x0200; // form into a signed int
  35       k <<= 6; // form into a 16b signed int
  36       fft_input[i] = k; // put real data into even bins
  37       fft_input[i+1] = 0; // set odd bins to 0
  38     }
  39     // window data, then reorder, then run, then take output
  40     fft_window(); // window the data for better frequency response
  41     fft_reorder(); // reorder the data before doing the fft
  42     fft_run(); // process the data in the fft
  43     fft_mag_log(); // take the output of the fft
  44     sei(); // turn interrupts back on
  45     Serial.write(255); // send a start byte
  46     Serial.write(fft_log_out, 128); // send out the data
  47   }
  48 }
  49


tmd3

I think that this isn't really your code.  The posted code has line numbers.  The compiler would balk at that before it ever looked at fft_input.

I think that either the library isn't properly installed, or the order of the #define and #include lines has been changed.  You can see how to install libraries here:  https://www.arduino.cc/en/Guide/Libraries.  If we can see your actual code - not the code from somebody's website, but the code that you are actually compileing to get the error you mention - we might be able to figure out which it is, or whether it's something else. 

rexhex

I am away from my computer with the arduino IDE on it. That is the code that I copied and pasted into my arduino IDE. After pasting it I went through and got ride of the line numbers. I can paste the code without the line numbers if you think that would help.

2trillion

The open music labs code has to be modified to execute properly.  It should only be used as a guide.

rexhex

That's good to know. I was thinking that if it compiled it would serial write frequency values. It looks like people tend to use processing to see the frequencies but that is not my intent. I would like to get values of the frequencies and their amplitude. 

rexhex

I was going through the FFT.h and I think tmd3 is right in saying that the #define is not working. The issue now I guess is why is this not working. I went through the steps suggested by arduino after already unzipping the folder in the libraries folder. While going through the fft.h i found that the other defined pieces (log_out and fft_n) are in this .h, I was thinking maybe they were the missing link.

Being that the library shows up in my arduino IDE its hard to believe that its not able to see and use this .h file.

rexhex

Blue eyes posted the solution to this compiling issue on the originally few year old forum post (http://forum.arduino.cc/index.php?topic=175219.new#new). What a guy. or girl?

Anyways the solution to anyone experiencing compiling issues with the FFT library is to remove the FFT folder inside the ArduinoFFT2 folder. I now have both the FFT and ArduinoFF2 folders in the library folder and it compiled just fine. So it must be that the arduino IDE does not look farther than one folder in the main library folder.

rexhex

Ok so now that the FFT examples have compiled I am not sure what is going on with the output. I have my audio so nicely entering the arduino A0 pin at a 2.5 middle not exceeding 0 or 5v.

here is the code straight from the FFT library example
Code: [Select]
/*
fft_adc.pde
guest openmusiclabs.com 8.18.12
example sketch for testing the fft library.
it takes in data on ADC0 (Analog0) and processes them
with the fft. the data is sent out over the serial
port at 115.2kb.  there is a pure data patch for
visualizing the data.
*/

#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft

#include <FFT.h> // include the library

void setup() {
  Serial.begin(115200); // use the serial port
  TIMSK0 = 0; // turn off timer0 for lower jitter
  ADCSRA = 0xe5; // set the adc to free running mode
  ADMUX = 0x40; // use adc0
  DIDR0 = 0x01; // turn off the digital input for adc0
}

void loop() {
  while(1) { // reduces jitter
    cli();  // UDRE interrupt slows this way down on arduino1.0
    for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
      while(!(ADCSRA & 0x10)); // wait for adc to be ready
      ADCSRA = 0xf5; // restart adc
      byte m = ADCL; // fetch adc data
      byte j = ADCH;
      int k = (j << 8) | m; // form into an int
      k -= 0x0200; // form into a signed int
      k <<= 6; // form into a 16b signed int
      fft_input[i] = k; // put real data into even bins
      fft_input[i+1] = 0; // set odd bins to 0
    }
    fft_window(); // window the data for better frequency response
    fft_reorder(); // reorder the data before doing the fft
    fft_run(); // process the data in the fft
    fft_mag_log(); // take the output of the fft
    sei();
    Serial.write(255); // send a start byte
    Serial.write(fft_log_out, 128); // send out the data
  }
}


and here is the serial print data... WOW weird symbols. Its like a printer gone mad.   

µ! ?ähòLy‚K ;™k´Ímªˆ œiv`'þ p ¢ üJ / ØìŸ?=Ÿnéýeéÿc
€xâ1Ëôÿ €Š ®PN~ ÇK- "þ F ©:$³Ã© $ QØ£R $"2´,}C     À¤Ì '    EŸá² ÿŠ€ À-Ÿ²"ù×k €òáš× -ð à
… &D mÃ'0ÿ Â A & ÿ$ › Ö-ãMl¤ …ýh Ô ¬ % B@- z [¤*ˆ=`¼ þ
á ½ß"¤Jrû)$ mR&ÿGAÓ Ã-ŠQ¸Ž•` [=Û™-ÿ 8p @Ðh Ï°Ê<‹"iš,BžT.    "{(
ð Æz0-FÃ8øcÛ¢(€‹Oþ ï < -'5BP; f§Â-6 " rƒ®ŒšE6š„x+8 ÐZÃ:$°†m¸ è¤ï+;p; Hý£C !˜‹6ÂúÒË C‰zÎß'N ÑR Àʯ9H˜ÿ# 0 ©w‰ k p   -.MÏ$š›*… ÊC°Kÿš !›<š þ…! €2Ò $Z ¹@ HŸI 9øß" ˜G¸áó ‚ k>m ÓA D)SïK ± Ë
Ò´à ÍŽZbd @ € W-É ãì E@/ -ÿ)¥ D@ƒli-ªýi €$÷ ÇN$) €N8„'Ó" Ds{•Ùžûla)0ìÝ*(@à
åûOܬ , (>lM ÿÖ B ›³É %D ©Ö" H" -k T= ü¥ˆ°Ê0€N €/ š¬(þbB €B I'"î"€@ $u§-- ÿ\<‚„(h¶ Á:    É­´ €þ '@ß ­õV‚ € ¨WX €ÿÖ$ A ÌAPÅ ã ãÁÿ† ý  X ã 9 Pþ)ñ @ JœmÈ‚€" jO·"--ü @ µ†Kˆ´ÿP   d šLg% T ! Ÿ"eü „t 6 Ô4@ D ¢ HW$@ÿ/' H WÛš!Aþ„ M9 …ÿ¦ `--O5 ùÆ!Fçž V ÿ D$¥ ¤XÄÿ`    A`Ë ð` !¥ b æ @ {OÁ é Ïì @ t£ ÖÒ"'    …qz q2ü4 Oâ*Ù ýPHŠ)=--È1ûa
  ¸ŽÂ°¤ 4 kò5"Èò i ¿Ÿ"ÌÊIF'€ Ô Ñ‰«Þ¢ ;Èm$e$ 9 n' ó DB°4NhJ$ |ã(Z‚þ`A áÁ' 1     Ï7 ½l" i     „S '$@Z
'áãÿ¤‹ Рܹÿ È:¶ù«ˆ×=ÿRšK €O[ [¼ŒH a "åÅQkÿ
SóxJÉ€ MC2
®$ ¼çÒu¸Í „¸\-- N3 ÅSŸëJþÁò€ @Ÿ¨bóN…$ l--ÊCÔ y€€âÉM mÍA " zp,^ p Ò Ê° ,@ ³ È,S™€ $C¶ žš
    `˜=Æèûi X …%#dÒ Ï0 ž1¼ ÿ €° /BXíÞ Üy‚ ÄôO‚ Íw5-ÿ²DŠD Û´Ò7 ø(7‚e ‹ ý‰ Ú Ûþ"
"æçÿ'-ÿÉ 8 %ÛJ!"ýŸ6à @•--h²ùZV) AžY x"k
{‰ŒX€ÿ ‚ § €`I6     ¤ LF` # !ÂöRZ7í7Ø Ó> ,[ÿËä‚"À ƒøúêÏaj tiç
yˆ $J¥ÛÐ:äu
¢Oä)öI^Dž"í- "EüÚ € íÙ 3ã @‰ -x¶'ZLl D[¼" Ú - €z{-‚@;¤ l
MŒýK 1   , òÅÆ D>MÛòU r M /Èø¼ & V % '± ÀØ„ºuèî
@+ $ZWxÿ!
~ÀQ R-`v $xŠ" òj D Þ ¯1„Ò @€yÄšÄöiC $ÈPbÂÿz¥KÛ X $ M å„•€ @0`Ð)€ Nh {Hà, ( EÒ üT'" Ä ¾rF±e ²<ª²ÀÂ@Ð!z \„P@D    ¹òÜh ü @Ú
ÿP œ …` Ò"€ §Î(,šˆkH„ yQƒ ©T R ­CB þC‚‚ `hP4 ÿ2J € á¨#Yˆ D º
¦$ ÿV€ ã>v ²IR% @Aà' ÞðH ƒã ÿ @ ‚†I *°0 µ=CB‰þÖ0L€€­6z/Ûþ% êe ›{ô< ' ¢JžU.¤˜ ¶ à Û! ÚN2É @¶ <þ Yæx À î 9Èh
D ¬à ä! @ Á†q-Ë) € I äœvÿ e3< @ÿ, ,¥Ðû œ ˆ
‰Y™ T " Ä ¼‚ÛM     A±   -   úà…@ Í è(øY ¿Øt éF0 € 'P ÊÞ '@¶
ÿR 2 ¡(HB‚þa$"K€è…!ø) @%ŸLò ÿik1 Büi- c…F »
ÕL«þÞ ¨ M>K ´þ®) 2 _ÑÂÏ" !"
i¾`±Ël … --' ¥È ÈøúÔ[4ÿV3 ©Ùm'C k€ä ¶ Œ K @j»J ò ¸4¢ $ú
F€ H nWB
a2
ܼ¥X(ˆ P¯ y!h- €„D ž RßÆ)€Zn Ÿï HP‚žH=rõB Û` C™ÿ A €@ î bà
Hl3„"d¬ â4 ¥[M
iËy›ð# @$À7 5¡‹Ñ*$@€ ›œ µþJ
D0 š @ ã' ägŠiþ¶ €JúŠ0ôÿk| ` ¶ ÿŽI€ "­ núT$ Ý'ž    ž DëX"qÊüi; b%d •ÿo) V ƒE#ÿÞ, 5Ñ Ê þᎠ€œVž`€ÿ¯¤ B L­š/ù @ À
ˆ€@ÿM # A¶N °HbM b kây Cóƒ DY a Jÿ  „à­¤ÿ'Å# €8…%lÈ * $\f` D@ùs ãÿ]
ÙIÎ'þŒ* ­'@ Èa@ ô¼ÈiêX    ä    : þ D mX²¬ŸüK B" Î…¥Ù€ ƒ65@(ÿ'@! rÍ¢x Ir€ ù mÿ¥ J ã< ºZE O6ȼނ0PHÇ$ ²*N #¤Ó% W I 'a¤ ƒ€ >­IÒ2 „ * X(H ý @'âAâ ÿ 8   ‚-† Р   M 0`ÿ 1„ÈWõ FÖ K ×Ø-ÿiR Jÿm¬4¤ý.(
ƒØ ¤5%@ ¯ÛL%õ9 Mg [i)€   Á
ñ: Þ<B b   `A(S2'×ý‚0! ó'
1¤*J B‡ƒ ˆ 9JI $ÿL T†›E ñ @ |ˆ ¤Óÿ (   #G    Jü" #Z¼@$ÿ* Å‚I'„F „åijX" @
Ê¥²   ÿ l€F€ 9hÖš# 5Q:H @ Ú Ç²¹a \" ÎôZ ø"¼†À € ¸Z°ySÿa‚     -øt õ ƒ àAÃKJ{A!0 ,7 êR ‡'r~Ä -    Jß BÐJ   @€p %2 ÿ† € r=jÒyž    kz {Xÿ6 €xkSëÓ, )<O HÇÿò D‚ È&1J ‡€€¬I"|˜ ,J(K×7šˆD 0 hX`s4þh‚L €k‚Ô‚éa Øô ú ø d@¶g`À‡þÞD {"D Ïýø ( Hè(‰èþ( `B ~ŠMÓ° 4@õQ÷äÐþL " ši]ù‹ " Õq ™' KþO³,‰ €"2 "Ha}%F Â(X¡"
LMÑ Vÿb K œEÿ¶ h |€Ä € C =È)SR xº   ¤ þx €[eš šZI ìKd)ÆÚ!€Hz" d‚I )š „ C†£@ !9^XjŽ V€DI ÏÁIl B-@%NA+f    Êx)! ðÀi[$ø ˆ
§kÆ
ÿN0 € XHt €{­²) þ
hÀIŒ !ÒV" €8‹… × K à› ,¥´dt éb aý‚ @D I þ 3 @¼Y8Á<ÿ    Ý(z¬½ûÅ ¢ µ-lÑ°    K %Ó¢üŒTp7 ž ú¶ $@Ù͇­È
[& -ÚY i @ ‡S    „KIy‚!y € yJ‚ÆKð‚ ! NX AÿR „ ¤ƒ<‚ òl ©OJ
  B „ z Þl € Ò[‡yC € ÐŒ©Ïzñª € b,¥¤Íb!6iËÑÉZ € ÓHRWTþÏ© €ÙµÂ ÷²@ HŸ,+ r
†n†ÿö' ¤ !LKñ` iª, О" Ä

tmd3

#12
Nov 10, 2015, 06:59 am Last Edit: Nov 12, 2015, 04:03 am by tmd3
Seril.write() isn't the same as Serial.print().  Check the difference in the Reference pages.  Serial.write() sends unmodified data; Serial.print() sends an ASCII representation of the value, generally human-readable.

To see the output, you'll have to replace the two Serial.write()'s with a loop that Serial.print()s those values.

[Edit: grammar]

rexhex

Serial.print(255) and Serial.print(fft_log_out,128) gives an error of "call of overloaded 'print(uin8_t[128])' ambiguous.

tmd3

#14
Nov 10, 2015, 02:32 pm Last Edit: Nov 10, 2015, 02:33 pm by tmd3
Check the Reference page(s) for how to use Serial print().  Replace the Serial.write() instructions with this:
Code: [Select]
   for (uint8_t j = 0; j < FFT_N/2; j++) {
      Serial.print(j);
      Serial.print(" ");
      Serial.println(fft_log_out[j]);
    }

Note that it'll print a lot of data, quite fast.

Go Up