public WaveCapture(IWaveIn capture, int fftSize, double moveSpeed, DSP.Window window = null) { this.capture = capture; capture.DataAvailable += (sender, e) => { observer?.Write(MemoryMarshal.Cast <byte, float>(e.Buffer.AsSpan(0, e.BytesRecorded))); }; Reset(fftSize, moveSpeed, window); }
public SharedStreamObserver(IWaveIn capture, int fftSize, double moveSpeed, DSP.Window fftWindow) { this.capture = capture; this.fftWindow = fftWindow; fft = FFT.CreateFFT(fftSize); leftFFTData = new Complex[fft.FFTComplexCount]; rightFFTData = new Complex[fft.FFTComplexCount]; streamObserver = new StreamObserver <float>(fftSize, (int)(fftSize / moveSpeed), 2, true); streamObserver.Completed += StreamObserver_Completed; capture.DataAvailable += Capture_DataAvailable; }
public void Reset(int fftSize, double moveSpeed, DSP.Window window) { lock (@lock) { this.fftSize = fftSize; fftComplexCount = fftSize / 2 + 1; this.moveSpeed = moveSpeed; fftWindow = window; if (fft != null) { fft = FFT.CreateFFT(fftSize); CreateObserver(); } } }
/// <summary> /// FFT结果取模 /// </summary> /// <param name="fftSize">fft大小</param> /// <param name="src">输入缓冲区</param> /// <param name="dst">输出缓冲区</param> /// <param name="sqrt">true则进行sqrt运算</param> public static void Abs(int fftSize, ReadOnlySpan <Complex> src, Span <double> dst, bool sqrt = true, DSP.Window window = null) { src.Handle(dst, GetComplexCount(fftSize), (@in, @out, length) => { double scale0 = window != null ? window.Scale : 1.0 / fftSize; double scale = window != null ? 2 * window.Scale : 2.0 / fftSize; if (sqrt) { @out[0] = @in[0].Magnitude * scale0; for (int i = 1; i < length; i++) { @out[i] = @in[i].Magnitude * scale; } } else { @out[0] = (@in[0].Real * @in[0].Real + @in[0].Imaginary * @in[0].Imaginary) * scale0; for (int i = 1; i < length; i++) { @out[i] = (@in[i].Real * @in[i].Real + @in[i].Imaginary * @in[i].Imaginary) * scale; } } }); }