private unsafe float Utility(float phase, float gain) { byte * ptr = stackalloc byte[(int)(uint)(1024 * sizeof(Complex) + 16)]; Complex *ptr2 = (Complex *)((long)ptr + 15 & -16); byte * ptr3 = stackalloc byte[4112]; float * ptr4 = (float *)((long)ptr3 + 15 & -16); Utils.Memcpy(ptr2, this._iqPtr, 1024 * sizeof(Complex)); IQBalancer.Adjust(ptr2, 1024, phase, gain); Fourier.ApplyFFTWindow(ptr2, this._windowPtr, 1024); Fourier.ForwardTransform(ptr2, 1024, true); Fourier.SpectrumPower(ptr2, ptr4, 1024, 0f, false); float num = 0f; for (int i = 0; i < 512; i++) { int num2 = 512 - i; if ((float)num2 > 25.6f && (float)num2 < 486.4f) { int num3 = 1022 - i; if (ptr4[i] - this._averagePower > 20f || ptr4[num3] - this._averagePower > 20f) { float num4 = ptr4[i] - ptr4[num3]; num += num4 * num4; } } } return(num); }
private float Utility(float phase, float gain) { var rawFFTPtr = stackalloc byte[FFTBins * sizeof(Complex) + 16]; var fftPtr = (Complex *)(((long)rawFFTPtr + 15) & ~15); var rawSpectrumPtr = stackalloc byte[FFTBins * sizeof(float) + 16]; var spectrumPtr = (float *)(((long)rawSpectrumPtr + 15) & ~15); Utils.Memcpy(fftPtr, _iqPtr, FFTBins * sizeof(Complex)); Adjust(fftPtr, FFTBins, phase, gain); Fourier.ApplyFFTWindow(fftPtr, _windowPtr, FFTBins); Fourier.ForwardTransform(fftPtr, FFTBins); Fourier.SpectrumPower(fftPtr, spectrumPtr, FFTBins); var result = 0.0f; const int halfBins = FFTBins / 2; for (var i = 0; i < halfBins; i++) { var distanceFromCenter = halfBins - i; if (distanceFromCenter > 0.05f * halfBins && distanceFromCenter < 0.95f * halfBins) { var j = FFTBins - 2 - i; if (spectrumPtr[i] - _averagePower > PowerThreshold || spectrumPtr[j] - _averagePower > PowerThreshold) { var distance = spectrumPtr[i] - spectrumPtr[j]; result += distance * distance; } } } return(result); }
public unsafe static void GetFilterSpecs(float[] kernel, double passband, double stopband, out double ripple, out double attenuation) { int num = 0; int num2 = 0; int num3 = 2; while (true) { if (num3 >= kernel.Length * 2 && num >= 4) { break; } num = (int)Math.Round((double)num3 * passband); num2 = (int)Math.Ceiling((double)num3 * stopband); num3 *= 2; } Complex[] obj = new Complex[num3]; float[] array = new float[num3 / 2]; Complex[] array2 = obj; fixed(Complex *ptr = array2) { float[] array3 = array; fixed(float *ptr2 = array3) { for (int i = 0; i < kernel.Length; i++) { ptr[i] = kernel[i]; } Fourier.ForwardTransform(ptr, num3, false); Fourier.SpectrumPower(ptr, ptr2, array.Length, 0f); float num4 = float.PositiveInfinity; float num5 = float.NegativeInfinity; for (int j = 0; j <= num; j++) { if (num4 > ptr2[j]) { num4 = ptr2[j]; } if (num5 < ptr2[j]) { num5 = ptr2[j]; } } ripple = (double)(num5 - num4); float num6 = float.NegativeInfinity; for (int k = num2; k < array.Length; k++) { if (num6 < ptr2[k]) { num6 = ptr2[k]; } } attenuation = Math.Max(0.0, (double)(num4 + num5) * 0.5 - (double)num6); } } }
private unsafe void OverlapSave() { Utils.Memcpy(this._fftPtr, this._queuePtr, this._fftSize * sizeof(Complex)); Fourier.ForwardTransform(this._fftPtr, this._fftSize, false); this.ProcessFft(this._fftPtr, this._fftSize); Fourier.InverseTransform(this._fftPtr, this._fftSize); Utils.Memcpy(this._outputPtr, this._fftPtr + this._halfSize, this._halfSize * sizeof(Complex)); Utils.Memcpy(this._queuePtr, this._queuePtr + this._halfSize, this._halfSize * sizeof(Complex)); }
public unsafe static void BackwardTransform(Complex *buffer, int length) { for (int i = 0; i < length; i++) { buffer[i].Imag = 0f - buffer[i].Imag; } Fourier.ForwardTransform(buffer, length, false); float num = 1f / (float)length; for (int j = 0; j < length; j++) { buffer[j].Real *= num; buffer[j].Imag = (0f - buffer[j].Imag) * num; } }
public unsafe static void InverseTransform(Complex *samples, int length) { for (int i = 0; i < length; i++) { samples[i].Imag = 0f - samples[i].Imag; } Fourier.ForwardTransform(samples, length, false); float num = 1f / (float)length; for (int j = 0; j < length; j++) { samples[j].Real *= num; samples[j].Imag = (0f - samples[j].Imag) * num; } }
private unsafe void OverlapAdd() { for (int i = 0; i < this._fftSize; i++) { this._fftPtr[i] = this._queuePtr[i] * this._windowPtr[i]; } Fourier.ForwardTransform(this._fftPtr, this._fftSize, false); this.ProcessFft(this._fftPtr, this._fftSize); Fourier.InverseTransform(this._fftPtr, this._fftSize); for (int j = 0; j < this._halfSize; j++) { this._outputPtr[j] = this._overlapPtr[j] * this._windowPtr[this._halfSize + j] + this._fftPtr[j] * this._windowPtr[j]; } Utils.Memcpy(this._overlapPtr, this._fftPtr + this._halfSize, this._halfSize * sizeof(Complex)); Utils.Memcpy(this._queuePtr, this._queuePtr + this._halfSize, this._halfSize * sizeof(Complex)); }
private unsafe void OverlapAdd() { Utils.Memcpy(this._fftPtr, this._queuePtr, this._fftSize * sizeof(Complex)); Fourier.ForwardTransform(this._fftPtr, this._fftSize, false); this.ProcessFft(this._fftPtr, this._fftSize); Fourier.InverseTransform(this._fftPtr, this._fftSize); Complex *ptr = this._fftPtr + this._fftSize / 2; float num = 1f / (float)(this._outputSize - 1); for (int i = 0; i < this._outputSize; i++) { float num2 = num * (float)i; this._outputPtr[i] = this._overlapPtr[i] * (1f - num2) + ptr[i] * num2; } Utils.Memmove(this._overlapPtr, ptr + this._outputSize, this._outputSize * sizeof(Complex)); Utils.Memmove(this._queuePtr, this._queuePtr + this._outputSize, (this._fftSize - this._outputSize) * sizeof(Complex)); }
private void EstimatePower() { var rawFFTPtr = stackalloc byte[FFTBins * sizeof(Complex) + 16]; var fftPtr = (Complex *)(((long)rawFFTPtr + 15) & ~15); var rawSpectrumPtr = stackalloc byte[FFTBins * sizeof(float) + 16]; var spectrumPtr = (float *)(((long)rawSpectrumPtr + 15) & ~15); Utils.Memcpy(fftPtr, _iqPtr, FFTBins * sizeof(Complex)); Fourier.ApplyFFTWindow(fftPtr, _windowPtr, FFTBins); Fourier.ForwardTransform(fftPtr, FFTBins); Fourier.SpectrumPower(fftPtr, spectrumPtr, FFTBins); const int halfBins = FFTBins / 2; var max = float.NegativeInfinity; var avg = 0f; var count = 0; for (var i = 0; i < halfBins; i++) { var distanceFromCenter = halfBins - i; if (distanceFromCenter > 0.05f * halfBins && distanceFromCenter < 0.95f * halfBins) { var j = FFTBins - 2 - i; if (spectrumPtr[i] > max) { max = spectrumPtr[i]; } if (spectrumPtr[j] > max) { max = spectrumPtr[j]; } avg += spectrumPtr[i] + spectrumPtr[j]; count += 2; } } avg /= count; _powerRange = max - avg; _averagePower = avg; }
private unsafe void OverlapCrossfade() { Utils.Memcpy(this._fftPtr, this._queuePtr, this._fftSize * sizeof(Complex)); Fourier.ForwardTransform(this._fftPtr, this._fftSize, false); this.ProcessFft(this._fftPtr, this._fftSize); Fourier.InverseTransform(this._fftPtr, this._fftSize); int num = 0; int num2 = this._crossFadingSize - 1; int num3 = this._halfSize; while (num < this._crossFadingSize) { this._outputPtr[num] = this._fftPtr[num3] * this._windowPtr[num] + this._crossFadingPtr[num] * this._windowPtr[num2]; num++; num2--; num3++; } Utils.Memcpy(this._outputPtr + this._crossFadingSize, this._fftPtr + this._halfSize + this._crossFadingSize, (this._outputSize - this._crossFadingSize) * sizeof(Complex)); Utils.Memcpy(this._crossFadingPtr, this._fftPtr + this._halfSize + this._outputSize, this._crossFadingSize * sizeof(Complex)); Utils.Memcpy(this._queuePtr, this._queuePtr + this._outputSize, (this._fftSize - this._outputSize) * sizeof(Complex)); }
private unsafe float Utility(Complex *iq, float phase) { Complex *ptr = stackalloc Complex[128 * sizeof(Complex)]; Utils.Memcpy(ptr, iq, 128 * sizeof(Complex)); this.AdjustPhase(ptr, phase); Fourier.ApplyFFTWindow(ptr, IQBalancer._windowPtr, 128); Fourier.ForwardTransform(ptr, 128, false); float num = 0f; int num2 = 1; int num3 = 127; while (num2 < 64) { float num4 = Math.Abs(ptr[num2].Real) + Math.Abs(ptr[num2].Imag); float num5 = Math.Abs(ptr[num3].Real) + Math.Abs(ptr[num3].Imag); num += Math.Abs(num4 - num5); num2++; num3--; } return(num); }
private unsafe void EstimatePower() { byte * ptr = stackalloc byte[(int)(uint)(1024 * sizeof(Complex) + 16)]; Complex *ptr2 = (Complex *)((long)ptr + 15 & -16); byte * ptr3 = stackalloc byte[4112]; float * ptr4 = (float *)((long)ptr3 + 15 & -16); Utils.Memcpy(ptr2, this._iqPtr, 1024 * sizeof(Complex)); Fourier.ApplyFFTWindow(ptr2, this._windowPtr, 1024); Fourier.ForwardTransform(ptr2, 1024, true); Fourier.SpectrumPower(ptr2, ptr4, 1024, 0f, false); float num = float.NegativeInfinity; float num2 = 0f; int num3 = 0; for (int i = 0; i < 512; i++) { int num4 = 512 - i; if ((float)num4 > 25.6f && (float)num4 < 486.4f) { int num5 = 1022 - i; if (ptr4[i] > num) { num = ptr4[i]; } if (ptr4[num5] > num) { num = ptr4[num5]; } num2 += ptr4[i] + ptr4[num5]; num3 += 2; } } num2 /= (float)num3; this._powerRange = num - num2; this._averagePower = num2; }
public unsafe void Process(Complex *buffer, int length) { int i = 0; int j = 0; for (; i < length; i++) { this._fftBufferPtr[this._fftBufferPos++] = buffer[i]; if (this._fftBufferPos == this._fftSize) { int num = this._halfSize; int num2 = 0; while (num < this._fftSize) { this._overlapBufferPtr[num2] = this._fftBufferPtr[num]; num++; num2++; } for (; j < length; j++) { if (this._sampleBufferHead == this._sampleBufferTail) { break; } buffer[j] = this._sampleBufferPtr[this._sampleBufferTail]; this._sampleBufferTail = (this._sampleBufferTail + 1 & this._fftSize - 1); } Fourier.ForwardTransform(this._fftBufferPtr, this._fftSize, false); this.ProcessFft(this._fftBufferPtr, this._fftSize); Fourier.BackwardTransform(this._fftBufferPtr, this._fftSize); int num3 = 0; int num4 = this._halfSize - this._overlapSize; while (num3 < this._halfSize) { if (num3 < this._overlapSize) { float num5 = (float)num3 * this._blendFactor; Complex.Mul(ref this._sampleBufferPtr[this._sampleBufferHead], this._fftBufferPtr[num4], num5); Complex.Mul(ref this._tmp, this._outOverlapPtr[num3], 1f - num5); Complex.Add(ref this._sampleBufferPtr[this._sampleBufferHead], this._tmp); } else { this._sampleBufferPtr[this._sampleBufferHead] = this._fftBufferPtr[num4]; } this._sampleBufferHead = (this._sampleBufferHead + 1 & this._fftSize - 1); num3++; num4++; } int num6 = 0; int num7 = this._fftSize - this._overlapSize; while (num6 < this._overlapSize) { this._outOverlapPtr[num6] = this._fftBufferPtr[num7]; num6++; num7++; } for (int k = 0; k < this._halfSize; k++) { this._fftBufferPtr[k] = this._overlapBufferPtr[k]; } this._fftBufferPos = this._halfSize; } } for (; j < length; j++) { if (this._sampleBufferHead == this._sampleBufferTail) { break; } buffer[j] = this._sampleBufferPtr[this._sampleBufferTail]; this._sampleBufferTail = (this._sampleBufferTail + 1 & this._fftSize - 1); } }
public void Process(Complex *buffer, int length) { var inOffset = 0; var outOffset = 0; while (inOffset < length) { _fftBufferPtr[_fftBufferPos++] = buffer[inOffset]; if (_fftBufferPos == _fftSize) { for (int i = _halfSize, j = 0; i < _fftSize; i++, j++) { _overlapBufferPtr[j] = _fftBufferPtr[i]; } while (outOffset < length && _sampleBufferHead != _sampleBufferTail) { buffer[outOffset] = _sampleBufferPtr[_sampleBufferTail]; _sampleBufferTail = (_sampleBufferTail + 1) & (_fftSize - 1); outOffset++; } Fourier.ForwardTransform(_fftBufferPtr, _fftSize, false); ProcessFft(_fftBufferPtr, _fftSize); Fourier.InverseTransform(_fftBufferPtr, _fftSize); for (int i = 0, j = _halfSize - _overlapSize; i < _halfSize; i++, j++) { if (i < _overlapSize) { var alpha = i * _blendFactor; _sampleBufferPtr[_sampleBufferHead] = alpha * _fftBufferPtr[j] + (1.0f - alpha) * _outOverlapPtr[i]; } else { _sampleBufferPtr[_sampleBufferHead] = _fftBufferPtr[j]; } _sampleBufferHead = (_sampleBufferHead + 1) & (_fftSize - 1); } for (int i = 0, j = _fftSize - _overlapSize; i < _overlapSize; i++, j++) { _outOverlapPtr[i] = _fftBufferPtr[j]; } for (var i = 0; i < _halfSize; i++) { _fftBufferPtr[i] = _overlapBufferPtr[i]; } _fftBufferPos = _halfSize; } inOffset++; } while (outOffset < length && _sampleBufferHead != _sampleBufferTail) { buffer[outOffset] = _sampleBufferPtr[_sampleBufferTail]; _sampleBufferTail = (_sampleBufferTail + 1) & (_fftSize - 1); outOffset++; } }
public unsafe void SetCoefficients(Complex[] coefficients) { this._isFast = false; if (coefficients != null) { if (this._coeffBuffer == null || coefficients.Length != this._queueSize) { this._queueSize = coefficients.Length; this._offset = this._queueSize * 3; this._coeffBuffer = UnsafeBuffer.Create(this._queueSize, sizeof(Complex)); this._coeffPtr = (Complex *)(void *)this._coeffBuffer; this._queueBuffer = UnsafeBuffer.Create(this._queueSize * 4, sizeof(Complex)); this._queuePtr = (Complex *)(void *)this._queueBuffer; } for (int i = 0; i < this._queueSize; i++) { this._coeffPtr[i] = coefficients[i]; } this._isSymmetric = true; this._isSparse = true; if (this._queueSize % 2 != 0) { int num = this._queueSize / 2; for (int j = 0; j < num; j++) { int num2 = this._queueSize - 1 - j; Complex.Sub(ref this._dif, this._coeffPtr[j], this._coeffPtr[num2]); if ((double)this._dif.Modulus() > 1E-06) { this._isSymmetric = false; this._isSparse = false; break; } if (j % 2 != 0) { this._isSparse = (this._coeffPtr[j].Real == 0f && this._coeffPtr[j].Imag == 0f && this._coeffPtr[num2].Real == 0f && this._coeffPtr[num2].Imag == 0f); } } } if (this._segment == null || this._segment.Length != this._fftSize) { this._segment = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); this._segPtr = (Complex *)(void *)this._segment; this._kernel = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); this._kerPtr = (Complex *)(void *)this._kernel; this._overlap = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); this._olaPtr = (Complex *)(void *)this._overlap; this._temp = UnsafeBuffer.Create(this._fftSize, sizeof(Complex)); this._tmpPtr = (Complex *)(void *)this._temp; } if (this._queueSize < 64) { this._fftLen = 128; goto IL_033c; } if (this._queueSize < 128) { this._fftLen = 256; goto IL_033c; } if (this._queueSize < 256) { this._fftLen = 512; goto IL_033c; } if (this._queueSize < 512) { this._fftLen = 1024; goto IL_033c; } if (this._queueSize < 1024) { this._fftLen = 2048; goto IL_033c; } if (this._queueSize < 2048) { this._fftLen = 4096; goto IL_033c; } throw new Exception("kernel too long"); } return; IL_033c: CpxFirFilter.FillFft(this._kerPtr, this._fftLen, this._coeffPtr, this._queueSize); Fourier.ForwardTransform(this._kerPtr, this._fftLen, false); this._isFast = true; }