Page 4 of 7

Re: Stream FFT and iFFT

PostPosted: Fri Jun 21, 2013 10:44 pm
by TheAudiophileDutchman
MyCo wrote:Maybe it is just the graph display, that doesn't interpolate the plot points.

I don't think so: when directly comparing the two separate amplitude plots, there are also visible differences in the peak distribution between them that weren't there before (i.e. also when varying FFT sizes).

Re: Stream FFT and iFFT

PostPosted: Sat Jun 22, 2013 1:50 am
by MyCo
Found the reason for the display difference. The reason was just, that the de-serializer shifted the whole array 1 sample in the wrong direction. It was just a displaying bug, the FFT data itself is identical.

I've changed the counter to the new version. This outputs an additional counter, which is 180° shifted. All "length" inputs are now protected, so no matter what comes in, the value is always adjusted into the valid range.

I've also added 22 Window functions. They are plain unoptimized code. Most of them could be 4 times faster (because they use the sine table with all 4 channels) but I don't wanted to waste my time there. If someone wants to contribute: Optimize them! :mrgreen:

Re: Stream FFT and iFFT

PostPosted: Sat Jun 22, 2013 4:28 am
by MyCo
seems like the windowing and overlapping is not required at all. I've streamed an audio file through FFT/iFFT with rectangular window (=>no window), and the error between original and converted signal is max. 3e-07... that is -130dB!!!

Re: Stream FFT and iFFT

PostPosted: Sat Jun 22, 2013 1:34 pm
by trogluddite
MyCo wrote:seems like the windowing and overlapping is not required at all.

Yes, Martin made some comments about this on the SM forum thread. For the direct FFT->iFFT, each buffer will be perfectly re-created (to the limit of numerical precision).
The window/overlap/add is required in, for example, a phase vocoder system where the output frequencies are transformed, and so create phase shifts between buffers.
I found this really good article about that aspect...Phase Vocoder Thesis - I'm still making sense of it, but there are good MALAB code examples of the whole thing, so possibly a good start for some porting.

Re: Stream FFT and iFFT

PostPosted: Sat Jun 22, 2013 6:24 pm
by MyCo
Has someone got a good atan2 stream code? I've done one myself, but it isn't very accurate. When I convert FFT -> Mag/Phase -> iFFT the error rate is very high now. I use the taylor series approximation for atan with 10 degree or more, but the results aren't close enough and the CPU time is not that great, either.

Re: Stream FFT and iFFT

PostPosted: Sat Jun 22, 2013 6:45 pm
by tester
There was some talk on SM forum (registered area // filters), because I use some filters with very high resonances and there was a problem with that part too.

Atan related discussion starts somewhere here:
http://synthmaker.co.uk/forum/viewtopic ... =75#p90847

Meanwhile I check what I have here, but not sure if this one is what you look for.

//edit:
Actually better check it in original context. :-)

Re: Stream FFT and iFFT

PostPosted: Sat Jun 22, 2013 8:09 pm
by Tronic
MyCo wrote:Has someone got a good atan2 stream code? I've done one myself, but it isn't very accurate. When I convert FFT -> Mag/Phase -> iFFT the error rate is very high now. I use the taylor series approximation for atan with 10 degree or more, but the results aren't close enough and the CPU time is not that great, either.


atan aproximation http://www.ganssle.com/approx.htm

implemented here
http://www.synthmaker.co.uk/forum/viewt ... tan#p85063

Re: Stream FFT and iFFT

PostPosted: Sun Jun 23, 2013 8:56 am
by digitalwhitebyte
may suffice as a max error of 0.01 rads?

Code: Select all
# http://dspguru.com/dsp/tricks/fixed-point-atan2-with-self-normalization
# Fast arctan2
# max |error| > 0.01

def arctan2(y,x)

   oneQtrPI = Math::PI / 4.0;
   thrQtrPI = 3.0 * Math::PI / 4.0;

   abs_y = y.abs + 1e-10;      # kludge to prevent 0/0 condition
   
   if (x < 0.0)
   
      r = (x + abs_y) / (abs_y - x);
      angle = thrQtrPI;
   
   else
   
      r = (x - abs_y) / (x + abs_y);
      angle = oneQtrPI;
   end
   
      angle = angle + (0.1963 * r * r - 0.9817) * r;
      
   if (y < 0.0)
      return( -angle );     # negate if in quad III or IV
   else
      return( angle );
   end
end

arctan2(1,1)  # => 0.7853981634858032



!! Edit: updated code, corret my bad implementation. Now work.

Re: Stream FFT and iFFT

PostPosted: Sun Jun 23, 2013 12:31 pm
by MyCo
I've setup a comparison for the atan methods from the S|M Forum and my own. I've also compared DWBs atan2 with my own. As reference I use the FS/Rubys original.

I don't know what's wrong with my setup for DWBs atan2 but its results are completely off. Any hint?

The atan comparison is kind of a bad sign. My implementation delivers most of the time the highest accuracy. There is one exception: when the input is 1 or very close to 1, then my version goes nearly 3% off.

Would be nice if someone would join in experimenting with this. We need to find the best possible method to keep the FFT conversion in an acceptable range.

The best thing would be a atan / atan2 version that outputs a normalized range from 0..1, where 1 is 2*PI. This would be the fastest way, because when we convert that back we need sin1.

Re: Stream FFT and iFFT

PostPosted: Sun Jun 23, 2013 12:53 pm
by tester
I would ask Martin (on SM) for help, as far I can tell - he is good in this stuff.

On the web I see that people talk about atan with predefined look up table.
( like here? http://www.convict.lu/Jeunes/Math/arctan.htm )
Also found some talk here: http://www.dsprelated.com/showmessage/21872/2.php