Exemple #1
0
        public override void ReadFrame(float[] fftResult)
        {
            // Check output array size
            switch (outputFormat)
            {
            case OutputFormat.Decibel:
            case OutputFormat.Magnitudes:
            case OutputFormat.MagnitudesSquared:
                if (fftResult.Length != fft.Size / 2)
                {
                    throw new ArgumentException("the provided FFT result array has an invalid size");
                }
                break;

            default:
                if (fftResult.Length != fft.Size)
                {
                    throw new ArgumentException("the provided FFT result array has an invalid size");
                }
                break;
            }

            base.ReadFrame(frameBuffer);

            // do fourier transform
            fft.Forward(frameBuffer, fftBuffer);

            // normalize fourier results
            switch (outputFormat)
            {
            case OutputFormat.Decibel:
                // TODO check if calculation corresponds to Haitsma & Kalker paper
                FFTUtil.Results(fftBuffer, fftResult);
                break;

            case OutputFormat.Magnitudes:
                FFTUtil.CalculateMagnitudes(fftBuffer, fftResult);
                break;

            case OutputFormat.MagnitudesSquared:
                // TODO check if consumers of this mode really want it or if they want unsquared magnitudes instead
                // (e.g. OLTW; this code path returns CalculateMagnitudesSquared for some time, as a temp test for OLTW,
                // but originally returned CalculateMagnitudes)
                FFTUtil.CalculateMagnitudesSquared(fftBuffer, fftResult);
                break;

            case OutputFormat.MagnitudesAndPhases:
                FFTUtil.CalculateMagnitudes(fftBuffer, fftResult, 0);
                FFTUtil.CalculatePhases(fftBuffer, fftResult, fft.Size / 2);
                break;

            case OutputFormat.Raw:
                // Nothing to do here, result is already in raw format, just copy it to output buffer
                Buffer.BlockCopy(fftBuffer, 0, fftResult, 0, fft.Size * 4);
                break;
            }

            OnFrameReadSTFT(fftResult);
        }
Exemple #2
0
        /// <summary>
        /// Calculates a normalization offset for the current window function. Every window function leads to
        /// a different FFT result peak value, and since the peak value of each windowed FFT means 0dB, this
        /// offset can be used to adjust the calculated dB values.
        /// </summary>
        private void CalculateWindowFunctionNormalizationOffset()
        {
            if (windowFunction == null)
            {
                windowFunctionNormalizationDecibelOffset = 0;
            }
            else
            {
                SineGeneratorStream sine   = new SineGeneratorStream(1024, 16, new TimeSpan(0, 0, 1));
                float[]             input  = new float[WindowSize];
                float[]             output = new float[input.Length / 2];
                WindowFunction      wf     = WindowUtil.GetFunction(windowFunction.Type, input.Length);

                sine.Read(input, 0, input.Length);
                wf.Apply(input);
                fft.Forward(input);
                int   maxIndex = FFTUtil.Results(input, output);
                float maxValue = output[maxIndex];
                windowFunctionNormalizationDecibelOffset = 1f - maxValue;
            }
        }
 private static void FrequencyDistributionBlockProcess(float[] buffer, double[] target, IFFT fft)
 {
     windowFunction.Apply(buffer);
     fft.Forward(buffer);
     for (int i = 0; i < buffer.Length; i += 2)
     {
         buffer[i / 2] = FFTUtil.CalculateMagnitude(buffer[i], buffer[i + 1]) / buffer.Length * 2;
     }
     for (int i = 0; i < target.Length; i++)
     {
         target[i] += buffer[i];
     }
 }