Is it possible to do an FFT on the Teensy 4? I was reading that the audio library wiring doesn't work to connect ADC(A0) to the fft1024_1.
Is it possible to do an FFT on the Teensy 4? I was reading that the audio library wiring doesn't work to connect ADC(A0) to the fft1024_1.
Yes, it should. Not sure what was at hand when reading about the issues and how it affects desired use?
I get this when I try to compile this:
I'm not using the audio board. Am I doing something wrong?Code:#include <Audio.h> #include <Wire.h> #include <SPI.h> #include <SD.h> #include <SerialFlash.h> // GUItool: begin automatically generated code AudioInputAnalog adc1; //xy=193,57 AudioAnalyzeFFT1024 fft1024_1; //xy=461,75 AudioConnection patchCord1(adc1, fft1024_1); // GUItool: end automatically generated code void setup(){ } void loop(){ }
Perhaps look at the Audio Tutorial FFT examples on the PJRC site. It seems that is missing some things.
I just watched the relevant portion of the audio tutorial again, and scoured the prjc site for more info on the FFT direct from the ADC, and I don't see anything wrong with my code. The error makes it look like something can't be found in the .h file.
Put an Audio board Rev D onto a T_4.0 - and seeing streaming FFT data going by on USB display.
Using :: ...\hardware\teensy\avr\libraries\Audio\examples\T utorial\Part_3_02_Fourier_Transform\Part_3_02_Four ier_Transform.ino
That isn't feeding from ADC data - but FFT on T_4.0 works - in this sample using the PJRC audio board as the auto driver for output. The Tutorial focuses on the Audio board - not sure if that is in use - assumed not as it is not in the posted code?
Info on ADC usage is showing examples: pjrc.com/teensy/gui/?info=AudioInputAnalog
> that shows 'AudioInputAnalog adc1(A3);' differs from the above where no pin is given - so "Audio input needs to connect to pin 16 (A2). The signal range is 0 to 1.2V." - according to that GUI Tool text.Code:Examples File > Examples > Audio > HardwareTesting > PassThroughMono File > Examples > Audio > Analysis > PeakMeterMono File > Examples > Audio > Analysis > DialTone_7segment File > Examples > OctoWS2811 > SpectrumAnalyzer Notes analogRead() must not be used, because AudioInputAnalog is regularly accessing the ADC hardware. If both access the hardware at the same moment, analogRead() can end up waiting forever, which effectively crashes your program. A different pin may be used, but adding it as an parameter to the AudioInputAnalog object definition. For example, to use pin A3: AudioInputAnalog adc1(A3);
A provided example close to post #3 looks to be :: ...\hardware\teensy\avr\libraries\Audio\examples\A nalysis\PeakMeterMono\PeakMeterMono.ino
> Perhaps seeing that work with these notes will help as it does not use the PJRC Audio Board. After seeing the 'Peak' work it should easily evolve into FFT usage from one of the other examples.
And as indicated in the following there is no "AudioMemory( ## )" from :: ...\hardware\teensy\avr\libraries\Audio\examples\A nalysis\SpectrumAnalyzerBasic\SpectrumAnalyzerBasic.ino
To run the above sketch "Part_3_02_Fourier_Transform.ino" these lines needed to be added - a SD card on the audio board with PJRC file "SDTEST1.WAV" present:Code:void setup() { // Audio requires memory to work. AudioMemory(12);
Code:#include <Audio.h> #include <Wire.h> #include <SPI.h> #include <SD.h> #include <SerialFlash.h> /////////////////////////////////// // copy the Design Tool code here /////////////////////////////////// // GUItool: begin automatically generated code AudioPlaySdWav playSdWav1; //xy=90,44 AudioPlayMemory playMem1; //xy=94,113 AudioSynthWaveform waveform1; //xy=104,170 AudioMixer4 mixer1; //xy=290,91 AudioAnalyzeFFT1024 fft1024_1; //xy=461,132 AudioOutputI2S i2s1; //xy=465,58 AudioConnection patchCord1(playSdWav1, 0, mixer1, 0); AudioConnection patchCord2(playSdWav1, 1, mixer1, 1); AudioConnection patchCord3(playMem1, 0, mixer1, 2); AudioConnection patchCord4(waveform1, 0, mixer1, 3); AudioConnection patchCord5(mixer1, 0, i2s1, 0); AudioConnection patchCord6(mixer1, 0, i2s1, 1); AudioConnection patchCord7(mixer1, fft1024_1); AudioControlSGTL5000 sgtl5000_1; //xy=352,195 // GUItool: end automatically generated code
No error details were provided. Cut and paste of text from the console would show what that was.
Perhaps it is the error showing here compiling the suggested : ...\hardware\teensy\avr\libraries\Audio\examples\A nalysis\PeakMeterMono\PeakMeterMono.ino
Just posted a question about that on the TD 1.52 B3 thread - as that may in fact be not yet supported - but FFT's are working.
Indeed it is there once clicked … I thought that was an audio wave form of some sort ( scope or LA ) proving it wasn't working somehow since the code has no loop() there would be no SerMon output.
Anyhow the answer is - indeed T_4.0 lacks ADC1 support at this time:
Well I have about 24 hours to code my own FFT then. Hmmm...
Any updates on this thread? Is FFT really not working on teensy 4.0 + the audio board?
FFT was working on T_4 - what wasn't working was getting the data from :: AudioInputAnalog adc1;
That it seems was fixed to work in the TD 1.52 B4 release today. Please try and update.
Teensyduino-1-52-Beta-4
"fixed" might be a strong word to use. "experimental" or "alpha" is probably better.
ADC input does work now, but still has many caveats. Among them, it requires another input or output because it does not yet cause the audio library to update.
Well the COMPILE error was fixed … and provided the link to notes about the need for RunTime caveats …
Here is a program which will run on Teensy 4.0 using 1.52-beta4 and gives you FFT of an audio signal on analog pin A2.
This will work without the audio shield present, but I2S output (or any other I/O object that causes the library to update) is currently required. Future versions will remove this requirement. Please understand this ADC audio code is very new and still has many minor issues. But at least you can see we're making progress towards ADC input for audio.Code:#include <Audio.h> // GUItool: begin automatically generated code AudioInputAnalog adc1; //xy=197,73 AudioAnalyzeFFT1024 fft1024_1; //xy=361,47 AudioOutputI2S i2s1; //xy=378,99 AudioConnection patchCord1(adc1, 0, i2s1, 0); AudioConnection patchCord2(adc1, 0, i2s1, 1); AudioConnection patchCord3(adc1, fft1024_1); AudioControlSGTL5000 sgtl5000_1; //xy=265,161 // GUItool: end automatically generated code void setup() { AudioMemory(30); sgtl5000_1.enable(); sgtl5000_1.volume(0.5); while (!Serial) ; // wait for Arduino Serial Monitor Serial.println("FFT test"); } void loop() { if (fft1024_1.available()) { for (int i=0; i < 20; i++) { // print the first 20 bins Serial.print(fft1024_1.read(i), 3); Serial.print(" "); } Serial.println(); } }
One of those many minor issues is the level. A full scale waveform on the ADC pin does not yet map to a full scale signal coming into the audio library. Removal of DC offset also isn't working well yet.
Paul - this code works on T_4.0 and 4.1 - but as noted elsewhere FAILS on T_3.6 [ using IDE 1.8.12 and TD 1.52 B4 ]::
Code:"T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SD\\fat_t3.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SD\\file_t3.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SD\\init_t3.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SD\\utility\\NXP_SDHC.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SD\\utility\\Sd2Card.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SD\\utility\\SdFile.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SD\\utility\\SdVolume.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SerialFlash\\SerialFlashChip.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\SerialFlash\\SerialFlashDirectory.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\Wire\\Wire.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\Wire\\WireIMXRT.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\Wire\\WireKinetis.cpp.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino\\libraries\\Wire\\utility\\twi.c.o" "T:\\TEMP\\arduino_build_AnalogFFT.ino/core\\core.a" "-LT:\\TEMP\\arduino_build_AnalogFFT.ino" -larm_cortexM4lf_math -lm T:\TEMP\arduino_build_AnalogFFT.ino\sketch\AnalogFFT.ino.cpp.o: In function `AudioInputAnalog::AudioInputAnalog(unsigned char)': T:\arduino-1.8.12\hardware\teensy\avr\libraries\Audio/input_adc.h:38: undefined reference to `AudioInputAnalog::init(unsigned char)' T:\TEMP\arduino_build_AnalogFFT.ino\sketch\AnalogFFT.ino.cpp.o: In function `AudioStream::AudioStream(unsigned char, audio_block_struct**)': T:\arduino-1.8.12\hardware\teensy\avr\cores\teensy3/AudioStream.h:138: undefined reference to `vtable for AudioInputAnalog' collect2.exe: error: ld returned 1 exit status
Hello dear defragster / dear forum members,
I have a few questions regarding the FFT Example:
Above you said that audio input needs to be connected to pin 16...so does that mean that if I'm connecting a device like e.g. a little Synthesizer to pin 16 the serial monitor / plotter will show me the spectrum of that signal?
Why do i need the file "SDTEST1.WAV" on my SD card? In the "Part_3_02_Fourier_Transform" example there is a sample of a guitar "AudioSampleGuitar.cpp / .h"... I thought the Fourier analysis was taken from that sample rather than the .WAV file? Or am I seeing the spectrum of "SDTEST1.WAV" right now?
So are different data types possible then? What I mean: Can I only get the FFT of an wav2sketch sampled .WAV signal? Or also as an analog signal like a synth coming into pin16? Or could I directly send an .WAV into the code without converting it before? What format(s) is / are needed for the FFT?
Furthermore: Does somebody know on how to find the highest peak in the resulting spectrum? So e.g. if I'm playing an A (440Hz) on my piano, the fundamental of f = 440 Hz should be the loudest in that signal - but how loud is it? Everything coming from the "Part_3_02_Fourier_Transform" - Code is very numerical, I can't really translate those values / LED-pictures to an actual dB-value...any ideas how to transform the values coming out of that "Part_3_02_Fourier_Transform" - Code into some more audio-relatable data like decibel?
Thanks a lot for this thread and your help guys
With kind regards,
Mala
So long as the signal is in the correct voltage range, 0..Vcc (otherwise you'll risk frying the chip - the suggested interface circuit in the
docs for adc input doesn't seem to feature any protection alas - at the very least its wise to use series resistor and schottky clamps if
the voltage source is from an external piece of equipment)
Any signal you can get into the audio lib system can be processed however you like with any object. Internally its 44.1kSPS and 16 bit signed
So are different data types possible then? What I mean: Can I only get the FFT of an wav2sketch sampled .WAV signal? Or also as an analog signal like a synth coming into pin16? Or could I directly send an .WAV into the code without converting it before? What format(s) is / are needed for the FFT?
throughout.
That's up to your coding I think - scan the fft bins and find the greatest... BTW its not necessarily true that the fundamental has the
Furthermore: Does somebody know on how to find the highest peak in the resulting spectrum? So e.g. if I'm playing an A (440Hz) on my piano, the fundamental of f = 440 Hz should be the loudest in that signal - but how loud is it? Everything coming from the "Part_3_02_Fourier_Transform" - Code is very numerical, I can't really translate those values / LED-pictures to an actual dB-value...any ideas how to transform the values coming out of that "Part_3_02_Fourier_Transform" - Code into some more audio-relatable data like decibel?
highest amplitude in a musical note, though often the case. To pick the dominant tone there are much better algorithms than picking
the highest peak in the FFT, for instance cepstrum analysis is used for speech decoding as its more reliable. For this sort of task
I'd recommend looking around for existing libraries and projects.
Thanks a lot for this thread and your help guys
With kind regards,
Mala
Thanks for the advice, i will try that out! Did you ever connect a microphone to one of your teensys / audio boards? Would be interested if you got any tips for a good little MIC and what to bear in mind when connecting it
Since you've posted in the thread i've started last week (https://forum.pjrc.com/threads/66288...ation-with-FFT) I can tell you why I'm interested in the FFT algorithm:
I've analyzed the spectrum of my voice inside a DAW. It has a nearly constant fundamental and a very unique overtone series. I actually do not need THE lowest frequency of the signal, it just has to be one of the lowest overtones f. Then I would search for 2f, 3f, 4f and so on. If I could measure the values / loudness of the different frequencies I could actually create my own "voice fingerprint" with that. Taking a second recording I could then evaluate if the person talking into the microphone creates a different spectrum or not.
To realize this approach I'll need to have access to the different peaks of the spectrum and that's the current issue I'm trying to solve.
I've never heard of Cepstrum Analysis, thanks for sharing that with me! I googled it and researched a bit on how the transformation works and it is a really powerful tool if you want to evaluate the periodicity of a signal. However I wouldn't see a benefit in using this transformation in my case, since I think the DFT/FFT approach would be way easier to program.
Thanks for reading this and thanks for any advice / help!
With kind regards,
Mala
Voice spectra contain both the signature of the harmonics, related to the waveform from the vocal chords,
and the filtering envelope imposed by the throat/mouth cavity, which doesn't change in frequency with the
note, but can change in character with mouth/tongue/soft-palette position (vowel sounds are principally due to this part).
Yes exactly, there isn't really one unique recording of your voice which will always sound the same - there will be filtering-effects due to different recording sessions. I thought of something like a "frequency tolerance" for this issue. Something like this:
If (f0_new >= f0_old + 5 || f0_new <= f0_old - 5)
return 0; // Authentification failed
I know it all looks a bit improvised at this point. But i don't think one wouldn't be able to realize an algorithm like that. But first of all I need to get concrete values for the frequencies and their levels. That's why i was asking here in this thread on how to translate the FFT1024 values.
(I also would still be interested why you'd need the "SDTEST1.WAV" for this example code? Is the spectrum I'm seeing taken of "AudioSampleGuitar" or of "SDTEST1.WAV"?)
With kind regards, Mala
You need to install the three buttons to use the complete example code. By default it uses SDTEST1.WAV as the audio input to the FFT. Each of the three buttons selects a different input.
Code:// Left button starts playing a new song . . // Middle button plays Guitar sample . . // Right button plays a pure sine wave tone
and BTW.
This:
would always be true. It should be this:Code:If (f0_new >= f0_old + 5 || f0_new <= f0_old - 5)
PeteCode:if (f0_new >= f0_old + 5 && f0_new <= f0_old - 5)
Thanks a lot Pete, I'll try to install the buttons and analyze the FFTs of the other Signals!
I'm not sure about that, because with && the value f0_new would need to be 5Hz higher than f0_old and 5 Hz lower than f0_old at the same time which would then always be false I think?
Code:If (f0_new >= f0_old + 5 || f0_new <= f0_old - 5)
Assuming f0_old is 200 Hz, then with this or conjunction f0_new would need to be between 195 Hz and 205 Hz (if I'm not overseeing something)
Thanks for your help guys!
With kind regards,
Mala
You're absolutely right. I misread it. Sorry.I'm not sure about that
If you just want to see the spectrum of the guitar sample, There's a variable that is set to 0, 1 or 2 when you push the buttons. It is initially zero. If you initialize it to 1, you'll get the guitar spectrum without needing any extra hardware - although the buttons could just be jumper wires and you ground one of them.
Pete