示例#1
0
        private void DSPProc()
        {
            #region Prepare buffers

            if (_dspInBuffer == null || _dspInBuffer.Length != _inputBufferSize)
            {
                _dspInBuffer = UnsafeBuffer.Create(_inputBufferSize, sizeof(Complex));
                _dspInPtr    = (Complex *)_dspInBuffer;
            }

            if (_dspOutBuffer == null || _dspOutBuffer.Length != _outputBufferSize)
            {
                _dspOutBuffer = UnsafeBuffer.Create(_outputBufferSize, sizeof(float));
                _dspOutPtr    = (float *)_dspOutBuffer;
            }

            #endregion

            while (IsPlaying)
            {
                var total = 0;
                while (IsPlaying && total < _dspInBuffer.Length)
                {
                    var len = _dspInBuffer.Length - total;
                    total += _iqStream.Read(_dspInPtr, total, len); // Blocking read
                }

                ProcessIQHooks();

                ProcessIQ();

                ProcessAudioHooks();

                _audioStream.Write(_dspOutPtr, _dspOutBuffer.Length); // Blocking write
            }
        }
示例#2
0
        public unsafe OverlapAddProcessor(int fftSize)
        {
            this._fftSize       = fftSize;
            this._halfSize      = this._fftSize / 2;
            this._inputPos      = this._halfSize;
            this._queuepBuffer  = UnsafeBuffer.Create(this._fftSize, sizeof(Complex));
            this._queuePtr      = (Complex *)(void *)this._queuepBuffer;
            this._windowBuffer  = UnsafeBuffer.Create(this._fftSize, 4);
            this._windowPtr     = (float *)(void *)this._windowBuffer;
            this._fftBuffer     = UnsafeBuffer.Create(this._fftSize, sizeof(Complex));
            this._fftPtr        = (Complex *)(void *)this._fftBuffer;
            this._outputBuffer  = UnsafeBuffer.Create(this._halfSize, sizeof(Complex));
            this._outputPtr     = (Complex *)(void *)this._outputBuffer;
            this._overlapBuffer = UnsafeBuffer.Create(this._halfSize, sizeof(Complex));
            this._overlapPtr    = (Complex *)(void *)this._overlapBuffer;
            double num = 1.5707963267948966 / (double)(this._halfSize - 1);

            for (int i = 0; i < this._halfSize; i++)
            {
                double a = (double)i * num;
                this._windowPtr[i] = (float)Math.Sin(a);
                this._windowPtr[this._fftSize - 1 - i] = this._windowPtr[i];
            }
        }
示例#3
0
        public unsafe void ProcessBuffer(Complex *iqBuffer, float *audioBuffer, int length)
        {
            if (this._needConfigure)
            {
                this.Configure(true);
            }
            length = this._mainDownConverter.Process(iqBuffer, length);
            this._ifOffsetTranslator.Process(iqBuffer, length);
            if (this._lockCarrier && (this._actualDetectorType == DetectorType.LSB || this._actualDetectorType == DetectorType.USB))
            {
                this._carrierLocker.Process(iqBuffer, length);
            }
            this._iqFilter.Process(iqBuffer, length);
            if (this._hookManager != null && this._hooksEnabled)
            {
                this._hookManager.ProcessDecimatedAndFilteredIQ(iqBuffer, length);
            }
            if (this._lockCarrier && (this._actualDetectorType == DetectorType.DSB || this._actualDetectorType == DetectorType.AM))
            {
                this._carrierLocker.Process(iqBuffer, length);
            }
            if (this._lockCarrier && this._useAntiFading && this._carrierLocker.IsLocked && (this._actualDetectorType == DetectorType.DSB || this._actualDetectorType == DetectorType.AM))
            {
                this._amAntiFading.Process(iqBuffer, length);
            }
            if (this._actualDetectorType == DetectorType.RAW)
            {
                Utils.Memcpy(audioBuffer, iqBuffer, length * sizeof(Complex));
                if (this._hookManager != null && this._hooksEnabled)
                {
                    this._hookManager.ProcessFilteredAudioOutput(audioBuffer, length * 2);
                }
                if (this._muted)
                {
                    Vfo.MuteAudio(audioBuffer, length * 2);
                }
            }
            else
            {
                if (this._rawAudioBuffer == null || this._rawAudioBuffer.Length != length)
                {
                    this._rawAudioBuffer = UnsafeBuffer.Create(length, 4);
                    this._rawAudioPtr    = (float *)(void *)this._rawAudioBuffer;
                }
                if (this._actualDetectorType != DetectorType.WFM)
                {
                    Vfo.ScaleIQ(iqBuffer, length);
                }
                if (this._bypassDemodulation)
                {
                    if (this._actualDetectorType == DetectorType.WFM)
                    {
                        length >>= this._audioDecimationStageCount;
                    }
                    length <<= 1;
                    Vfo.MuteAudio(audioBuffer, length);
                }
                else
                {
                    this.Demodulate(iqBuffer, this._rawAudioPtr, length);
                    if (this._hookManager != null && this._hooksEnabled)
                    {
                        this._hookManager.ProcessDemodulatorOutput(this._rawAudioPtr, length);
                    }
                    switch (this._actualDetectorType)
                    {
                    case DetectorType.WFM:
                        if (this._filterAudio)
                        {
                            this._audioIIR.Process(this._rawAudioPtr, length);
                        }
                        if (this._hookManager != null && this._hooksEnabled)
                        {
                            this._hookManager.ProcessFMMPX(this._rawAudioPtr, length);
                        }
                        this._rdsDecoder.Process(this._rawAudioPtr, length);
                        this._stereoDecoder.Process(this._rawAudioPtr, audioBuffer, length);
                        length >>= this._audioDecimationStageCount;
                        break;

                    case DetectorType.NFM:
                        if (this._filterAudio)
                        {
                            this._audioIIR.Process(this._rawAudioPtr, length);
                            this._audioFIR.Process(this._rawAudioPtr, length, 1);
                            this.Deemphasis(this._rawAudioPtr, length);
                        }
                        if (this._useAgc)
                        {
                            this._agc.Process(this._rawAudioPtr, length);
                        }
                        Vfo.MonoToStereo(this._rawAudioPtr, audioBuffer, length);
                        break;

                    default:
                        if (this._useAgc)
                        {
                            this._agc.Process(this._rawAudioPtr, length);
                        }
                        if (this._filterAudio)
                        {
                            this._audioIIR.Process(this._rawAudioPtr, length);
                            this._audioFIR.Process(this._rawAudioPtr, length, 1);
                        }
                        Vfo.MonoToStereo(this._rawAudioPtr, audioBuffer, length);
                        break;
                    }
                    length <<= 1;
                    if (this._hookManager != null && this._hooksEnabled)
                    {
                        this._hookManager.ProcessFilteredAudioOutput(audioBuffer, length);
                    }
                    if (this._muted)
                    {
                        Vfo.MuteAudio(audioBuffer, length);
                    }
                }
            }
        }
示例#4
0
        public unsafe int ProcessBuffer(Complex *iqBuffer, float *audioBuffer, int iqLen, float *xBuf, float *yBuf, float *envelopBuf)
        {
            if (this._needConfigure)
            {
                this.configure();
                this._needConfigure = false;
            }
            if (this._demodX == DemodType.Envelope || this._demodY == DemodType.Envelope || envelopBuf != null)
            {
                if (this._envBuf == null || this._envBuf.Length != iqLen)
                {
                    if (this._envBuf != null)
                    {
                        this._envBuf.Dispose();
                    }
                    this._envBuf = UnsafeBuffer.Create(iqLen, sizeof(Complex));
                    this._envPtr = (Complex *)(void *)this._envBuf;
                }
                Utils.Memcpy(this._envPtr, iqBuffer, iqLen * sizeof(Complex));
                this._downConverter2.Process(this._envPtr, iqLen);
                int num = iqLen;
                if (this._envelopeDecimator.StageCount > 0)
                {
                    this._envelopeDecimator.Process(this._envPtr, iqLen);
                    num = iqLen >> this._envelopeDecimationStageCount;
                }
                this._envFilter.Process(this._envPtr, num);
                if (this._demodX == DemodType.Envelope)
                {
                    for (int i = 0; i < num; i++)
                    {
                        xBuf[i] = this._envPtr[i].Real * 0.005f;
                    }
                    this.doAgcAndGain(this._agcX, xBuf, num);
                    if (this._useAgc)
                    {
                        for (int j = 0; j < num; j++)
                        {
                            xBuf[j] *= 0.33f;
                        }
                    }
                }
                if (this._demodY == DemodType.Envelope)
                {
                    for (int k = 0; k < num; k++)
                    {
                        yBuf[k] = this._envPtr[k].Imag * 0.005f;
                    }
                    this.doAgcAndGain(this._agcY, yBuf, num);
                    if (this._useAgc)
                    {
                        for (int l = 0; l < num; l++)
                        {
                            yBuf[l] *= 0.33f;
                        }
                    }
                }
                if (envelopBuf != null)
                {
                    for (int m = 0; m < num; m++)
                    {
                        envelopBuf[m] = this._envPtr[m].Imag * 0.005f;
                    }
                    this.doAgcAndGain(this._agcEnv, envelopBuf, num);
                    if (this._useAgc)
                    {
                        for (int n = 0; n < num; n++)
                        {
                            envelopBuf[n] *= 0.33f;
                        }
                    }
                }
            }
            this._downConverter.Process(iqBuffer, iqLen);
            if (this._hookManager != null)
            {
                this._hookManager.ProcessFrequencyTranslatedIQ(iqBuffer, iqLen);
            }
            int num2 = iqLen;

            if (this._baseBandDecimator.StageCount > 0)
            {
                this._baseBandDecimator.Process(iqBuffer, iqLen);
                num2 = iqLen >> this._baseBandDecimationStageCount;
            }
            if (!Utils.FastConvolve)
            {
                this._realIqFilter.Process(iqBuffer, num2);
            }
            else
            {
                this._cpxIqFilter.Process(iqBuffer, num2);
            }
            if (this._hookManager != null)
            {
                this._hookManager.ProcessDecimatedAndFilteredIQ(iqBuffer, num2);
            }
            for (int num3 = 0; num3 <= 3; num3++)
            {
                if (this._notchFilter[num3] != null && this._notchFilter[num3].Width > 0)
                {
                    this._notchFilter[num3].Process(iqBuffer, num2);
                }
            }
            if (this._actualDetectorType == DetectorType.RAW)
            {
                Utils.Memcpy(audioBuffer, iqBuffer, num2 * sizeof(Complex));
            }
            else
            {
                if (this._rawAudioBuffer == null || this._rawAudioBuffer.Length != num2)
                {
                    if (this._rawAudioBuffer != null)
                    {
                        this._rawAudioBuffer.Dispose();
                    }
                    this._rawAudioBuffer = UnsafeBuffer.Create(num2, 4);
                    this._rawAudioPtr    = (float *)(void *)this._rawAudioBuffer;
                }
                if (this.DetectorType == DetectorType.SAM && (this._rBuf == null || this._rBuf.Length != num2))
                {
                    if (this._rBuf != null)
                    {
                        this._rBuf.Dispose();
                    }
                    if (this._lBuf != null)
                    {
                        this._lBuf.Dispose();
                    }
                    this._rBuf = UnsafeBuffer.Create(num2, 4);
                    this._lBuf = UnsafeBuffer.Create(num2, 4);
                    this._rPtr = (float *)(void *)this._rBuf;
                    this._lPtr = (float *)(void *)this._lBuf;
                }
                if (this._actualDetectorType != DetectorType.WFM)
                {
                    Vfo.scaleIQ(iqBuffer, num2);
                }
            }
            int num4 = num2 * 2;

            this.demodulate(iqBuffer, xBuf, yBuf, num2);
            if (this._demodX == DemodType.AM)
            {
                this.doAgcAndGain(this._agcX, xBuf, num2);
            }
            if (this._demodY == DemodType.AM)
            {
                this.doAgcAndGain(this._agcY, yBuf, num2);
            }
            if (this._actualDetectorType == DetectorType.RAW)
            {
                return(num2);
            }
            if (this._actualDetectorType == DetectorType.SAM && this._stereo)
            {
                if (Utils.Chk1)
                {
                    if (this._filterAudio)
                    {
                        this._rFilter.Process(this._rPtr, num2);
                    }
                    this.doAgcAndGain(this._agcX, this._rPtr, num2);
                    if (this._filterAudio)
                    {
                        this._lFilter.Process(this._lPtr, num2);
                    }
                    this.doAgcAndGain(this._agcY, this._lPtr, num2);
                }
                int num5 = 0;
                for (int num6 = 0; num6 < num2; num6++)
                {
                    audioBuffer[num5++] = this._rPtr[num6];
                    audioBuffer[num5++] = this._lPtr[num6];
                }
                if (!Utils.Chk1)
                {
                    if (this._filterAudio)
                    {
                        this._audioFilter.Process(audioBuffer, num2 * 2);
                    }
                    this.doAgcAndGain(this._agc, audioBuffer, num2 * 2);
                }
                return(num2);
            }
            if (this._hookManager != null)
            {
                this._hookManager.ProcessDemodulatorOutput(this._rawAudioPtr, num2);
            }
            if (this._actualDetectorType != DetectorType.WFM)
            {
                if (this._filterAudio)
                {
                    this._audioFilter.Process(this._rawAudioPtr, num2);
                }
                if (this._actualDetectorType != 0)
                {
                    this.doAgcOrGain(this._agc, this._rawAudioPtr, num2);
                }
            }
            if (this._actualDetectorType == DetectorType.AM)
            {
                this._dcRemover.Process(this._rawAudioPtr, num2);
            }
            if (this._actualDetectorType != DetectorType.WFM)
            {
                Vfo.monoToStereo(this._rawAudioPtr, audioBuffer, num2);
            }
            else
            {
                this._rdsDecoder.Process(this._rawAudioPtr, num2);
                this._stereoDecoder.Process(this._rawAudioPtr, audioBuffer, num2);
                num4 >>= this._audioDecimationStageCount;
            }
            if (this._hookManager != null)
            {
                this._hookManager.ProcessFilteredAudioOutput(audioBuffer, num4);
            }
            return(num2);
        }
示例#5
0
        public void Process(float *baseBand, int length)
        {
            #region Initialize buffers

            if (_rawBuffer == null || _rawBuffer.Length != length)
            {
                _rawBuffer = UnsafeBuffer.Create(length, sizeof(Complex));
                _rawPtr    = (Complex *)_rawBuffer;
            }

            if (_magBuffer == null || _magBuffer.Length != length)
            {
                _magBuffer = UnsafeBuffer.Create(length, sizeof(float));
                _magPtr    = (float *)_magBuffer;
            }

            if (_dataBuffer == null || _dataBuffer.Length != length)
            {
                _dataBuffer = UnsafeBuffer.Create(length, sizeof(float));
                _dataPtr    = (float *)_dataBuffer;
            }

            #endregion

            // Downconvert
            for (var i = 0; i < length; i++)
            {
                _osc->Tick();
                _rawPtr[i] = _osc->Phase * baseBand[i];
            }

            // Decimate
            _decimator.Process(_rawPtr, length);
            length /= _decimationFactor;

            // Filter
            _baseBandFilter.Process(_rawPtr, length);

            // PLL
            for (var i = 0; i < length; i++)
            {
                _dataPtr[i] = _pll->Process(_rawPtr[i]).Imag;
            }

            //if (!_pll->IsLocked)
            //{
            //    _bitDecoder.Reset();
            //    return;
            //}

            // Matched filter
            _matchedFilter.Process(_dataPtr, length);

            // Recover signal energy to sustain the oscillation in the IIR
            for (var i = 0; i < length; i++)
            {
                _magPtr[i] = Math.Abs(_dataPtr[i]);
            }

            // Synchronize to RDS bitrate
            _syncFilter->Process(_magPtr, length);

            // Detect RDS bits
            for (int i = 0; i < length; i++)
            {
                var data    = _dataPtr[i];
                var syncVal = _magPtr[i];
                var slope   = syncVal - _lastSync;
                _lastSync = syncVal;
                if (slope < 0.0f && _lastSyncSlope * slope < 0.0f)
                {
                    bool bit = _lastData > 0;
                    _bitDecoder.Process(bit ^ _lastBit);
                    _lastBit = bit;
                }
                _lastData      = data;
                _lastSyncSlope = slope;
            }
        }
示例#6
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;
        }
        public void ProcessBuffer(Complex *iqBuffer, float *audioBuffer, int length)
        {
            if (_needConfigure)
            {
                Configure();
                _needConfigure = false;
            }

            if (_hookManager != null)
            {
                _hookManager.ProcessRawIQ(iqBuffer, length);
            }

            _downConverter.Process(iqBuffer, length);

            if (_hookManager != null)
            {
                _hookManager.ProcessFrequencyTranslatedIQ(iqBuffer, length);
            }

            if (_baseBandDecimator.StageCount > 0)
            {
                _baseBandDecimator.Process(iqBuffer, length);
                length /= (int)Math.Pow(2.0, _baseBandDecimator.StageCount);
            }

            _iqFilter.Process(iqBuffer, length);

            if (_hookManager != null)
            {
                _hookManager.ProcessDecimatedAndFilteredIQ(iqBuffer, length);
            }

            if (_actualDetectorType == DetectorType.RAW)
            {
                Utils.Memcpy(audioBuffer, iqBuffer, length * sizeof(Complex));
                return;
            }

            if (_rawAudioBuffer == null || _rawAudioBuffer.Length != length)
            {
                _rawAudioBuffer = UnsafeBuffer.Create(length, sizeof(float));
                _rawAudioPtr    = (float *)_rawAudioBuffer;
            }

            if (_actualDetectorType != DetectorType.WFM)
            {
                ScaleIQ(iqBuffer, length);
            }

            Demodulate(iqBuffer, _rawAudioPtr, length);

            if (_hookManager != null)
            {
                _hookManager.ProcessDemodulatorOutput(_rawAudioPtr, length);
            }

            if (_actualDetectorType != DetectorType.WFM)
            {
                if (_filterAudio)
                {
                    _audioFilter.Process(_rawAudioPtr, length);
                }

                if (_actualDetectorType != DetectorType.NFM && _useAgc)
                {
                    _agc.Process(_rawAudioPtr, length);
                }
            }

            if (_filterAudio)
            {
                _dcRemover.Process(_rawAudioPtr, length);
            }

            if (_actualDetectorType == DetectorType.WFM)
            {
                _rdsDecoder.Process(_rawAudioPtr, length);
                _stereoDecoder.Process(_rawAudioPtr, audioBuffer, length);
                length >>= _audioDecimationStageCount;
            }
            else
            {
                MonoToStereo(_rawAudioPtr, audioBuffer, length);
            }

            if (_hookManager != null)
            {
                length <<= 1;
                _hookManager.ProcessFilteredAudioOutput(audioBuffer, length);
            }
        }
示例#8
0
        private void ProcessStereo(float *baseBand, float *interleavedStereo, int length)
        {
            #region Prepare L+R buffer

            if (_channelABuffer == null || _channelABuffer.Length != length)
            {
                _channelABuffer = UnsafeBuffer.Create(length, sizeof(float));
                _channelAPtr    = (float *)_channelABuffer;
            }

            #endregion

            #region Prepare L-R buffer

            if (_channelBBuffer == null || _channelBBuffer.Length != length)
            {
                _channelBBuffer = UnsafeBuffer.Create(length, sizeof(float));
                _channelBPtr    = (float *)_channelBBuffer;
            }

            #endregion

            #region Decimate and filter L+R

            var audioLength = length / _audioDecimationFactor;

            if (_isMultiThreaded)
            {
                DSPThreadPool.QueueUserWorkItem(
                    delegate
                {
                    Utils.Memcpy(_channelAPtr, baseBand, length * sizeof(float));
                    _channelADecimator.Process(_channelAPtr, length);
                    _channelAFilter.Process(_channelAPtr, audioLength);
                    _event.Set();
                });
            }
            else
            {
                Utils.Memcpy(_channelAPtr, baseBand, length * sizeof(float));
                _channelADecimator.Process(_channelAPtr, length);
                _channelAFilter.Process(_channelAPtr, audioLength);
            }

            #endregion

            #region Demodulate L-R

            for (var i = 0; i < length; i++)
            {
                var pilot = _pilotFilter->Process(baseBand[i]);
                _pll->Process(pilot);
                _channelBPtr[i] = baseBand[i] * Trig.Sin((float)(_pll->AdjustedPhase * 2.0));
            }

            if (!_pll->IsLocked)
            {
                if (_isMultiThreaded)
                {
                    _event.WaitOne();
                }

                #region Process mono deemphasis

                for (var i = 0; i < audioLength; i++)
                {
                    _deemphasisAvgL += _deemphasisAlpha * (_channelAPtr[i] - _deemphasisAvgL);
                    _channelAPtr[i]  = _deemphasisAvgL;
                }

                #endregion

                #region Fill output buffer with mono

                for (var i = 0; i < audioLength; i++)
                {
                    var sample = _channelAPtr[i] * AudioGain;
                    interleavedStereo[i * 2]     = sample;
                    interleavedStereo[i * 2 + 1] = sample;
                }

                #endregion

                return;
            }

            #endregion

            #region Decimate and filter L-R

            _channelBDecimator.Process(_channelBPtr, length);
            _channelBFilter.Process(_channelBPtr, audioLength);

            #endregion

            #region Recover L and R audio channels

            if (_isMultiThreaded)
            {
                _event.WaitOne();
            }

            for (var i = 0; i < audioLength; i++)
            {
                var a = _channelAPtr[i];
                var b = 2f * _channelBPtr[i];
                interleavedStereo[i * 2]     = (a + b) * AudioGain;
                interleavedStereo[i * 2 + 1] = (a - b) * AudioGain;
            }

            #endregion

            #region Process deemphasis

            for (var i = 0; i < audioLength; i++)
            {
                _deemphasisAvgL         += _deemphasisAlpha * (interleavedStereo[i * 2] - _deemphasisAvgL);
                interleavedStereo[i * 2] = _deemphasisAvgL;

                _deemphasisAvgR += _deemphasisAlpha * (interleavedStereo[i * 2 + 1] - _deemphasisAvgR);
                interleavedStereo[i * 2 + 1] = _deemphasisAvgR;
            }

            #endregion
        }
示例#9
0
 public void Stop()
 {
     if (_inputType == InputType.Plugin && _frontend != null)
     {
         _frontend.Stop();
         _frontend = null;
     }
     if (_wavePlayer != null)
     {
         _wavePlayer.Dispose();
         _wavePlayer = null;
     }
     if (_waveRecorder != null)
     {
         _waveRecorder.Dispose();
         _waveRecorder = null;
     }
     if (_waveDuplex != null)
     {
         _waveDuplex.Dispose();
         _waveDuplex = null;
     }
     _inputSampleRate = 0;
     if (_waveReadThread != null)
     {
         _waveReadThread.Join();
         _waveReadThread = null;
     }
     if (_iqStream != null)
     {
         _iqStream.Close();
     }
     if (_audioStream != null)
     {
         _audioStream.Close();
     }
     if (_streamHookManager != null)
     {
         _streamHookManager.CloseStreams();
         _streamHookManager.Stop();
     }
     if (_dspThread != null)
     {
         _dspThread.Join();
         _dspThread = null;
     }
     if (_streamHookManager != null)
     {
         _streamHookManager.StopIQObserverThread();
     }
     if (_waveFile != null)
     {
         _waveFile.Dispose();
         _waveFile = null;
     }
     if (_iqStream != null)
     {
         _iqStream.Dispose();
         _iqStream = null;
     }
     if (_streamHookManager != null)
     {
         _streamHookManager.DisposeStreams();
     }
     _audioStream  = null;
     _dspOutBuffer = null;
     _iqInBuffer   = null;
 }
示例#10
0
 public static UnsafeBuffer Create(int length, int sizeOfElement)
 {
     return(UnsafeBuffer.Create(length, sizeOfElement, true));
 }
示例#11
0
 public static UnsafeBuffer Create(int size)
 {
     return(UnsafeBuffer.Create(size, 1, true));
 }
示例#12
0
 public DownConverter(int phaseCount)
 {
     _phaseCount        = phaseCount;
     _oscillatorsBuffer = UnsafeBuffer.Create(sizeof(Oscillator) * phaseCount);
     _oscillators       = (Oscillator *)_oscillatorsBuffer;
 }
示例#13
0
 public unsafe StereoDecoder()
 {
     this._pllBuffer       = UnsafeBuffer.Create(sizeof(Pll));
     this._pll             = (Pll *)(void *)this._pllBuffer;
     this._isMultiThreaded = (Utils.ProcessorCount > 1);
 }
示例#14
0
        private unsafe void ProcessStereo(float *baseBand, float *interleavedStereo, int length)
        {
            if (this._channelABuffer == null || this._channelABuffer.Length != length)
            {
                this._channelABuffer = UnsafeBuffer.Create(length, 4);
                this._channelAPtr    = (float *)(void *)this._channelABuffer;
            }
            if (this._channelBBuffer == null || this._channelBBuffer.Length != length)
            {
                this._channelBBuffer = UnsafeBuffer.Create(length, 4);
                this._channelBPtr    = (float *)(void *)this._channelBBuffer;
            }
            int audioLength = length / this._audioDecimationFactor;

            if (this._isMultiThreaded)
            {
                DSPThreadPool.QueueUserWorkItem(delegate
                {
                    Utils.Memcpy(this._channelAPtr, baseBand, length * 4);
                    this._channelADecimator.Process(this._channelAPtr, length);
                    if (this._useFilter)
                    {
                        this._channelAFilter.Process(this._channelAPtr, audioLength);
                    }
                    this._event.Set();
                });
            }
            else
            {
                Utils.Memcpy(this._channelAPtr, baseBand, length * 4);
                this._channelADecimator.Process(this._channelAPtr, length);
                if (this._useFilter)
                {
                    this._channelAFilter.Process(this._channelAPtr, audioLength);
                }
            }
            for (int i = 0; i < length; i++)
            {
                float sample = this._pilotFilter->Process(baseBand[i]);
                this._pll->Process(sample);
                this._channelBPtr[i] = baseBand[i] * Trig.Sin((float)((double)this._pll->AdjustedPhase * 2.0));
            }
            if (!this._pll->IsLocked)
            {
                if (this._isMultiThreaded)
                {
                    this._event.WaitOne();
                }
                if (this._useFilter)
                {
                    for (int j = 0; j < audioLength; j++)
                    {
                        this._deemphasisAvgL += this._deemphasisAlpha * (this._channelAPtr[j] - this._deemphasisAvgL);
                        this._channelAPtr[j]  = this._deemphasisAvgL;
                    }
                }
                for (int k = 0; k < audioLength; k++)
                {
                    interleavedStereo[k * 2 + 1] = (interleavedStereo[k * 2] = this._channelAPtr[k] * 0.2f);
                }
            }
            else
            {
                this._channelBDecimator.Process(this._channelBPtr, length);
                if (this._useFilter)
                {
                    this._channelBFilter.Process(this._channelBPtr, audioLength);
                }
                if (this._isMultiThreaded)
                {
                    this._event.WaitOne();
                }
                for (int l = 0; l < audioLength; l++)
                {
                    float num  = this._channelAPtr[l];
                    float num2 = 2f * this._channelBPtr[l];
                    interleavedStereo[l * 2]     = (num + num2) * 0.2f;
                    interleavedStereo[l * 2 + 1] = (num - num2) * 0.2f;
                }
                if (this._useFilter)
                {
                    for (int m = 0; m < audioLength; m++)
                    {
                        this._deemphasisAvgL        += this._deemphasisAlpha * (interleavedStereo[m * 2] - this._deemphasisAvgL);
                        interleavedStereo[m * 2]     = this._deemphasisAvgL;
                        this._deemphasisAvgR        += this._deemphasisAlpha * (interleavedStereo[m * 2 + 1] - this._deemphasisAvgR);
                        interleavedStereo[m * 2 + 1] = this._deemphasisAvgR;
                    }
                }
            }
        }
示例#15
0
 public StereoDecoder()
 {
     _pllBuffer = UnsafeBuffer.Create(sizeof(Pll));
     _pll       = (Pll *)_pllBuffer;
 }
示例#16
0
 unsafe static IQBalancer()
 {
     IQBalancer._windowBuffer = UnsafeBuffer.Create(FilterBuilder.MakeWindow(WindowType.BlackmanHarris7, 128));
     IQBalancer._windowPtr    = (float *)(void *)IQBalancer._windowBuffer;
 }
示例#17
0
        private UnsafeBuffer AllocBlock()
        {
            var result = _usedBlocks.Count > 0 ? _usedBlocks.Pop() : UnsafeBuffer.Create(BlockSize, sizeof(Complex));

            return(result);
        }
示例#18
0
        public void StartIQObserverThread(int bufferSize)
        {
            if (_iqObserverBuffer == null || _iqObserverBuffer.Length != bufferSize)
            {

                if (_iqObserverBuffer != null)
                {
                    _iqObserverBuffer.Dispose();
                    _iqObserverBuffer = null;
                }

                _iqObserverBuffer = UnsafeBuffer.Create(bufferSize, sizeof(Complex));
                _iqObserverBufferPtr = (Complex*)_iqObserverBuffer;
            }
                
            _iqObserverThread = new Thread(IQObserverThread);
            _iqObserverThread.Priority = ThreadPriority.BelowNormal;
            _iqObserverThread.Name = "IQObserverThread";

            _iqObserverThreadRunning = true;
            _iqObserverThread.Start();            
        }
示例#19
0
 public unsafe StereoDecoder()
 {
     this._pllBuffer = UnsafeBuffer.Create(sizeof(Pll));
     this._pll       = (Pll *)(void *)this._pllBuffer;
 }
示例#20
0
 private UnsafeBuffer AllocBlock()
 {
     return((this._usedBlocks.Count > 0) ? this._usedBlocks.Pop() : UnsafeBuffer.Create(16384, 4));
 }