コード例 #1
0
ファイル: Fourier.cs プロジェクト: yi520520/SDRSharp-1
        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;
            }
        }
コード例 #2
0
ファイル: Fourier.cs プロジェクト: jamezleedz/SDRSharper
        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;
            }
        }
コード例 #3
0
 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));
 }
コード例 #4
0
        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));
        }
コード例 #5
0
ファイル: IQBalancer.cs プロジェクト: Radiomix2000/sdrsharp-1
        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;
        }
コード例 #6
0
        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));
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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;
        }
コード例 #9
0
ファイル: FftProcessor.cs プロジェクト: jamezleedz/SDRSharper
        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);
            }
        }
コード例 #10
0
        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++;
            }
        }
コード例 #11
0
        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;
        }