dsp.js icon indicating copy to clipboard operation
dsp.js copied to clipboard

Rfft inverse transform implemented

Open Spudd86 opened this issue 13 years ago • 2 comments

Spudd86 avatar Jan 29 '11 17:01 Spudd86

Almost 6 years after your pull request... in a galaxy far far away...

I'm learning dsp and since this library is now unmaintained, I writing my own dsp library in javascript (https://github.com/oramics/dsp-kit) taking parts from different projects. One of my goals is write a timestretch function using phase vocoder algorithm that works on realtime. For that I need the fastest fft implementation possible, and by the benchmarks I found to be this one. I've adapted the original code and your code into the library (https://github.com/oramics/dsp-kit/tree/master/packages/rfft) but I found several issues.

First of all, related to the dsp.js library itself. The problem is that the resulting spectrum from dsp.FFT and dsp.RFFT are different! :-o

  var dspjs = require('dsp.js')
  var { generate, round } = require('dsp-array')
  var signal = generate(1024, (n, N) => Math.sin(2 * Math.PI * n / (N - 1)))
  var rfft = new dspjs.RFFT(1024, 44100)
  var fft = new dspjs.FFT(1024, 44100)
  rfft.forward(signal)
  fft.forward(signal)
  assert.deepEqual(round(rfft.spectrum), round(fft.spectrum)) // throws and exception

And it's not a problem of number precision, because I've rounded the results. Anyway, this is not a problem with your code, but maybe you can give some light here.

The second problem is related to your code directly: as I understand, the inverse function you implemented uses the trans array that stores the real and imaginary parts mixed. For the phase-vocoder to work I need this values in polar notation (magnitudes and phases) and then perform the inverse FFT. So I would need a function to convert from magnitudes and phases to the trans array format.... or is any better alternative? Do you have any suggestion?

Sorry to bother you after so much time, and thanks in advance, Dani


UPDATE: It seems that the inverse of the forward does NOT return the signal. You can read the full test here: https://github.com/oramics/dsp-kit/blob/master/packages/rfft/test/test.js

danigb avatar Jan 14 '17 09:01 danigb

@danigb - I ran some of my own tests on this IRFFT and found that it's actually pretty accurate to within 0.0000005.

There were some typos in the PR and it didn't run properly without some massaging, however here's the calling code I used to generate the output below.

        let fft = new RFFT(bufferLength, 44100);
        fft.forward(aBuffer);
        fft.scale_trans();
        let inverse = fft.inverse(fft.trans);

Here's a small sample of my results, in each pair the top number is the original signal, and the bottom are the IRFFT result.

0.836010217666626
0.836010217666626

0.7999920845031738
0.7999920845031738

0.7608309984207153
0.7608309388160706

0.7186809182167053
0.7186809182167053

0.6737073659896851
0.6737073659896851

0.6260870099067688
0.6260870099067688

0.5760070085525513
0.5760070085525513

0.5236640572547913
0.5236639976501465

0.46926379203796387
0.4692637324333191

0.41301995515823364
0.41301995515823364

j-funk avatar May 08 '17 02:05 j-funk