AudioAnalyzeFFT256 does not work like FFT1024 ? (works only once)

Status
Not open for further replies.

JBeale

Well-known member
I'm sure i'm missing something simple. Using Teensy 3.2 / Arduino 1.8.3 / Teensyduino 1.38-beta2.
The code below using AudioAnalyzeFFT256 prints only one number and then freezes, meaning myFFT.available() went true only one time. If I exchange the three lines commented out so I am using FFT1024 instead, I get all 100 lines as expected and the runtime in msec at the end. In this case I am using the Serial1 UART, but the same behavior occurs if I use the USB port. Any suggestions?

Code:
#include <Audio.h>  # Test Teensy 3.2 Audio Library FFT1024 and FFT256

AudioInputAnalog         adc1;       
// AudioAnalyzeFFT1024      myFFT;
AudioAnalyzeFFT256      myFFT;

AudioConnection  patchCord1(adc1, myFFT);

// #define FBINS 512    // full length of frequency data from 1024-point FFT
 #define FBINS 128    // full length of frequency data from 256-point FFT

#define SERPORT Serial1

void setup() {
float fv;      // sum of FFT values

  AudioMemory(12);
  SERPORT.begin(57600);
  delay(2000);
    
//  SERPORT.println("FFT Test Start 1024");
  SERPORT.println("FFT Test Start 256");
  int tstart = millis();
  for (int i=0; i<100; i++) {  // do a few rounds
    do {} while (!myFFT.available());
    fv = 0;
    for (int j=0; j<FBINS; j++) {
      fv += myFFT.read(i);
    }
    SERPORT.println(fv);
  }
  int delta = millis()-tstart;
  SERPORT.println(delta);
}

void loop() {}
 
Last edited:
Hi Frank,

Yes, I had a silly mistake on the index i instead of j. This is just example code anyway, but I fixed that (see below). The behavior the same: it prints out only 1 line with FFT256. I think the code structure is basically correct, because with the FFT1024 version it prints out all 100 lines as intended.

What should I change or add in the 256 version to make it not freeze after the first read, and work like the 1024 version works? What do you mean by "need a output" ?

FFT256 Code:
Code:
#include <Audio.h>  # Test Teensy 3.2 Audio Library FFT1024 and FFT256

AudioInputAnalog         adc1;       
// AudioAnalyzeFFT1024      myFFT;
AudioAnalyzeFFT256      myFFT;

AudioConnection  patchCord1(adc1, myFFT);

// #define FBINS 512    // full length of frequency data from 1024-point FFT
#define FBINS 128    // full length of frequency data from 256-point FFT

#define SERPORT Serial1

void setup() {
float fv;      // sum of FFT values

  AudioMemory(12);
  SERPORT.begin(57600);
  delay(2000);
    
  // SERPORT.println("FFT Test Start 1024");
  SERPORT.println("FFT Test Start 256");
  int tstart = millis();
  for (int i=0; i<100; i++) {  // do a few rounds
    do {} while (!myFFT.available());
    fv = 0;
    for (int j=0; j<FBINS; j++) {
      fv += myFFT.read(j);
    }
    SERPORT.println(fv);
  }
  int delta = millis()-tstart;
  SERPORT.println(delta);
}

void loop() {}

FFT256 Output:
Code:
FFT Test Start 256
0.01

FFT1024 code:
Code:
#include <Audio.h>  # Test Teensy 3.2 Audio Library FFT1024 and FFT256

AudioInputAnalog         adc1;       
AudioAnalyzeFFT1024      myFFT;
// AudioAnalyzeFFT256      myFFT;

AudioConnection  patchCord1(adc1, myFFT);

#define FBINS 512    // full length of frequency data from 1024-point FFT
// #define FBINS 128    // full length of frequency data from 256-point FFT

#define SERPORT Serial1

void setup() {
float fv;      // sum of FFT values

  AudioMemory(12);
  SERPORT.begin(57600);
  delay(2000);
    
  SERPORT.println("FFT Test Start 1024");
  // SERPORT.println("FFT Test Start 256");
  int tstart = millis();
  for (int i=0; i<100; i++) {  // do a few rounds
    do {} while (!myFFT.available());
    fv = 0;
    for (int j=0; j<FBINS; j++) {
      fv += myFFT.read(j);
    }
    SERPORT.println(fv);
  }
  int delta = millis()-tstart;
  SERPORT.println(delta);
}

void loop() {}

FFT1024 Output:
Code:
FFT Test Start 1024
0.07
0.08
0.08
0.08
0.07
0.07
0.07
0.06
0.07
0.10
0.09
0.07
0.06
0.05
0.07
0.06
0.05
0.06
0.05
0.06
0.08
0.07
0.05
0.08
0.06
0.05
0.07
0.06
0.05
0.08
0.06
0.05
0.06
0.05
0.06
0.05
0.05
0.06
0.05
0.07
0.07
0.05
0.06
0.05
0.05
0.06
0.06
0.05
0.07
0.07
0.06
0.08
0.06
0.07
0.06
0.05
0.08
0.07
0.07
0.06
0.07
0.05
0.05
0.05
0.05
0.05
0.04
0.05
0.04
0.05
0.04
0.04
0.05
0.04
0.04
0.04
0.04
0.04
0.04
0.05
0.04
0.05
0.04
0.05
0.04
0.04
0.04
0.04
0.05
0.04
0.04
0.04
0.04
0.04
0.04
0.04
0.04
0.04
0.04
0.05
1150
 
Last edited:
That was a lightning fast code fix! And I see Paul has already pulled it in. Thanks for the quick work. -john
 
Speed of FFT256? Expected 4x faster, but actually 2x slower than FFT1024

I manually added the "volatile" fix to the Audio library analyze_fft256.h file. Now the 256 element FFT works.

BUT I am puzzled by the fact that 100 cycles of the loop (code in my earlier post) takes 2277 msec, meaning each FFT256 takes 22.77 milliseconds. By contrast, the FFT1024 takes 1149 msec for 100 cycles, meaning each FFT1024 takes 11.49 msec, very nearly twice as fast. I did not change the audio sample rate, so I would have expected 256 audio samples to be acquired 4x faster than 1024 samples, and not 2x slower. Does this mean that the FFT256 has a built in x8 decimation, or what else is happening?

(Note, this is true whether or not the println() is commented out, so it's unrelated to serial comm times.)
 
Check for this code in the FFT256:
Code:
#if AUDIO_BLOCK_SAMPLES == 128
		prevblock = NULL;
		naverage = 8;

When picking the fft256 it defaults to 8 times averaging. So it takes twice as long for one quarter of the samples because each is read and averaged 8 times before use.

Is this the function to call to adjust that? : averageTogether()
 
Thanks for that info. I can confirm when I changed that in the library to naverage = 2, I did get back FFT256 results 2x faster than I did with the FFT1024 case, so it works as expected.
 
Last edited:
Status
Not open for further replies.
Back
Top