-1

I'm using the vDSP framework for a real-time audio application based on FFT computation.

After having lots of problems trying to figure out why the algorithm was producing incorrect results, I found out the following comment on the official vDSP FFT help code (DemonstrateFFT.c, lines 242, 416, 548)

/*  Zero the signal before timing because repeated FFTs on non-zero
    data can cause abnormalities such as infinities, NaNs, and
    subnormal numbers.
*/

In order to reproduce the error, just comment line 247 (no zero the signal) and add something similar to the following line at line 273 (just after the vDSP_fft_zrip method)

if (isnan(Observed.realp[0])) printf("Iteration %lu: NaN\n",i); // it would work with any of the components of Observed

It is interesting to observe that reducing N (i.e. increasing the amount of FFTs per time unit) makes the zrip algorithm to fail before, which kinds of makes sense since the comment advices about performing repeated FFTs.

The behavior is also observed with the vDSP_fft_zrop algorithm.

I'm really wondering what's the point about performing FFTs of "zero data" as advised on the comment. Either I'm missing something important, or definitely the vDSP framework is not suited at all for real-time audio processing.

1 Answers1

1

Normal 16 and 24-bit "real time" audio samples will not see this issue.

But benchmarks can create bigger and smaller numbers that can exceed the range of double precision floats when iterated enough times, and when using many functions, not just FFTs. Try iterating exp() fed back to itself, that will blow up even faster. It's a problem one encounters using any finite precision computer arithmetic (not just the ARM and x86 CPUs that vDSP uses).

hotpaw2
  • 70,107
  • 14
  • 90
  • 153
  • Thank you hotpaw2 for the answer. I can understand the issue that you describe but, in fact, the first time I faced this issue was not on a benchmark, but in a real-time application (several dozens of Double Frequency Delay Line convolutions with 16384 tab filters each audio callback). That would mean that, in such cases, the target performance is faster than the upper vDSP limit for my CPU. For instance, I'm not experiencing this issue with KissFFT, maybe partly because KissFFT is in general terms slower than vDSP for FFTs. – Andres Perez-Lopez Jul 27 '17 at 16:23
  • The difference might be that you are using the double precision form of KissFFT and the single precision float version of vDSP. There are also vDSP calls that use double. – hotpaw2 Jul 27 '17 at 16:28
  • 1
    hotpaw2 is correct. I am the author of the comment quoted in the question, and it is referring to the fact that if you do an FFT on some non-zero data, and then do an FFT on the results, and another FFT on the results of that, then the magnitudes involved continue increasing (because the vDSP FFT is not normalized; it effectively multiplies the data by N each time you call it, where N is the number of elements). Normally, you do not repeat an FFT on the output data that way. It is a loop done only to measure execution time, which is a very special use case. – Eric Postpischil Aug 08 '17 at 23:49
  • The speed with which FFTs are performed has nothing directly to do with whether or not NaNs are produced. If changing some of the parameters of your FFT causes NaNs, then likely your data was already near the limit of finite floating-point numbers or there is some other bug in your program that is getting stirred up by the changes. – Eric Postpischil Aug 08 '17 at 23:51
  • Depending on the processor, FFTs handling or producing NaNs or tiny denorms can run far slower. This is because those numbers can cause hardware pipeline bubbles that can add lots of clock cycles to each arithmetic op. – hotpaw2 Aug 09 '17 at 00:03
  • I understood Andres Perez-Lopez to be saying that doing FFTs at a faster rate (doing more per unit of time) could cause NaNs to be produced, and that is what I was addressing. – Eric Postpischil Aug 12 '17 at 16:29
  • Dear hotpaw2 and Eric. Thank you very much for your answers and excuse my late arrival to the discussion. You are right in your comments: computing on a loop FFTs of FFTs will cause NaNs because of scaling. I was wrong because I didn't realized there was no IFFT involved, just because I had another (unrelated) bug causing the same NaN problem (incorrect buffer memory allocation) under certain "demanding" circumstances. Now I enjoy again nice, accurate and fast vDSP computations. Thanks. – Andres Perez-Lopez Sep 06 '17 at 10:59