Closed mhetrick closed 2 years ago
Also, this is occurring on both Mac and Windows.
With further investigation, MAG_FREQ format appears to be the suspect. Without that mode enabled, the above code isn't noisy.
After running a number of tests, I've figured out that this occurs when the internal phase accumulators aren't reset for a period of time.
This is generally missed when using something like the example pitch shifter code, which resets phases based on flux. However, that code still fails if the shifter works on a fairly constant drone for an extended period of time.
Our current workaround is to reset the phases manually every 20 minutes if they haven't been reset by flux.
Going to reopen this issue, as I think this should probably be fixed at the Gamma level instead of with our "every 20 minutes" hack.
The code in question is line 367 of DFT.cpp, in the STFT::inverse function:
for(unsigned k=1; k<numBins()-1; ++k){
double t = bin(k)[1]; // freq
t -= k*fund; // freq to freq deviation
t *= factor; // freq deviation to phase diff
t += k*expdp1; // add expected phase diff due to overlap
mAccums[k] += t; // accumulate phase diff
//bin(k)[1] = mAccums[k]; // copy accum phase for inverse xfm
bufInvFrq()[2*k] = bin(k)[0];
bufInvFrq()[2*k+1] = mAccums[k];
}
mAccums[k] += t;
should have a boundary check of some sort, or else each mAccum eventually overflows (leading to loud, dangerous spectral noise).
I agree this should be fixed upstream. I see artifacts forming in the upper spectrum after only around 8 min. I tried your suggestion of wrapping the phases and that seems to fix it. Pushed as 70ba31c92db6a.
Great, thanks! I'll close this. Looks like you could close issue #33 as well as a duplicate.
The STFT class is failing after approximately 20-30 minutes of use. I'm wondering if this is a similar rounding error as the CSine issue that I reported. Here's an example to test (just drop this into a file in the Examples folder).
Essentially, this example processes the first 7,000,000 samples offline before the audio callback turns on. I'm using SamplePlayer for the first 7,000,000, as it runs more quickly than the Sine oscillator.
`
include "../AudioApp.h"
include "Gamma/Oscillator.h"
include "Gamma/DFT.h"
include "Gamma/SamplePlayer.h"
using namespace gam;
class MyApp : public AudioApp{ public:
};
int main(){ MyApp().start(); } `