NAudio fft result gives intensity at all C # frequencies

I have a working implementation of NAudio Wasapi audio recording and FFT data. Most of the data that I get is the same as it should be, but every time in the interval (from 10 seconds to minutes) it shows the amplitude at almost all frequencies.

Error image

Basically, the image moves from right to left with time and frequencies running on a logarithmic scale from the lowest frequencies at the bottom. Lines are errors. As far as I can tell, they should not be there.

I get a sound buffer and send samples to the aggregator (using the Hamming window), which implements NAudio FFT. I checked the data (the FFT result) before I changed it in any way (the image is not from the original output FFT, but the desibel scale), confirming that the FFT result gives these lines. I could also indicate that the image is modified by LockBits, so I thought I was having something wrong with the logic, but why did I check the FFT output that shows the same problem.

Well, I could be wrong, and the problem may be somewhere I said that this is not so, but it seems that this comes from the FFT OR data of the buffer (the data itself or the collection of samples). Somehow I doubt that the buffer itself is damaged.

If anyone knows what might cause this, I would really appreciate it!

UPDATE

So I decided to draw the whole range of FFT results, not half. It showed something strange. I'm not sure about the FFT, but I thought the Fourier transform should produce a result that is reflected around the middle. This, of course, is not so.

The image is on a linear scale, so the exact middle of the image is the midpoint of the FFT result. The bottom is the first, and the top is the last.

wholefft

I played a 10 kHz sine wave, which gives two horizontal lines, but the upper part is beyond me. It also seems that the lines are reflected around the bottom quarter of the picture, so it seems strange to me.

UPDATE 2

So, I increased the FFT size from 4096 to 8192 and tried again. This is the result when I fight with the sine frequency.

picture3

It would seem that the result is mirrored twice. Once in the middle, and then again in the upper and lower half. And now the huge lines have disappeared. And it would seem that lines appear only at the bottom.

After some additional testing with different FFT lengths, it seems that the strings are completely random in this account.

UPDATE 3

I did some testing with many things. The last thing I added is match patterns, so I reuse the last half of the pattern array at the beginning of the next FFT. On the windows of Hamming and Hann, this gives me tremendous intensity (as in the second picture I posted), but not with Blackman Harris. Disabling overlap removes the biggest errors for each window function. Smaller errors, as in the upper image, remain even with the BH window. I still don't know why these lines appear.

My current form allows me to control which window function to use (of the three previously mentioned), overlap (on / off), and several different drawing options. This allows me to compare all effects of the affected parties when changing.

I will investigate further (I'm sure I was mistaken at some point), but good suggestions are more than welcome!

+6
source share
1 answer

The problem was how I handled the data arrays. Now we work like a charm.

Code (remote excess and possibly added errors):

// Other inputs are also usable. Just look through the NAudio library. private IWaveIn waveIn; private static int fftLength = 8192; // NAudio fft wants powers of two! // There might be a sample aggregator in NAudio somewhere but I made a variation for my needs private SampleAggregator sampleAggregator = new SampleAggregator(fftLength); public Main() { sampleAggregator.FftCalculated += new EventHandler<FftEventArgs>(FftCalculated); sampleAggregator.PerformFFT = true; // Here you decide what you want to use as the waveIn. // There are many options in NAudio and you can use other streams/files. // Note that the code varies for each different source. waveIn = new WasapiLoopbackCapture(); waveIn.DataAvailable += OnDataAvailable; waveIn.StartRecording(); } void OnDataAvailable(object sender, WaveInEventArgs e) { if (this.InvokeRequired) { this.BeginInvoke(new EventHandler<WaveInEventArgs>(OnDataAvailable), sender, e); } else { byte[] buffer = e.Buffer; int bytesRecorded = e.BytesRecorded; int bufferIncrement = waveIn.WaveFormat.BlockAlign; for (int index = 0; index < bytesRecorded; index += bufferIncrement) { float sample32 = BitConverter.ToSingle(buffer, index); sampleAggregator.Add(sample32); } } } void FftCalculated(object sender, FftEventArgs e) { // Do something with e.result! } 

And the sample aggregator class:

 using NAudio.Dsp; // The Complex and FFT are here! class SampleAggregator { // FFT public event EventHandler<FftEventArgs> FftCalculated; public bool PerformFFT { get; set; } // This Complex is NAudio own! private Complex[] fftBuffer; private FftEventArgs fftArgs; private int fftPos; private int fftLength; private int m; public SampleAggregator(int fftLength) { if (!IsPowerOfTwo(fftLength)) { throw new ArgumentException("FFT Length must be a power of two"); } this.m = (int)Math.Log(fftLength, 2.0); this.fftLength = fftLength; this.fftBuffer = new Complex[fftLength]; this.fftArgs = new FftEventArgs(fftBuffer); } bool IsPowerOfTwo(int x) { return (x & (x - 1)) == 0; } public void Add(float value) { if (PerformFFT && FftCalculated != null) { // Remember the window function! There are many others as well. fftBuffer[fftPos].X = (float)(value * FastFourierTransform.HammingWindow(fftPos, fftLength)); fftBuffer[fftPos].Y = 0; // This is always zero with audio. fftPos++; if (fftPos >= fftLength) { fftPos = 0; FastFourierTransform.FFT(true, m, fftBuffer); FftCalculated(this, fftArgs); } } } } public class FftEventArgs : EventArgs { [DebuggerStepThrough] public FftEventArgs(Complex[] result) { this.Result = result; } public Complex[] Result { get; private set; } } 

And I think. Maybe I missed something. Hope this helps!

+10
source

Source: https://habr.com/ru/post/953862/


All Articles