private void ProcessMono(float *baseBand, float *interleavedStereo, int length) { #region Prepare buffer if (_channelABuffer == null || _channelABuffer.Length != length) { _channelABuffer = UnsafeBuffer.Create(length, sizeof(float)); _channelAPtr = (float *)_channelABuffer; } #endregion #region Decimate L+R Utils.Memcpy(_channelAPtr, baseBand, length * sizeof(float)); _channelADecimator.Process(_channelAPtr, length); #endregion #region Filter L+R length /= _audioDecimationFactor; _channelAFilter.Process(_channelAPtr, length); #endregion #region Process deemphasis for (var i = 0; i < length; i++) { _deemphasisAvgL += _deemphasisAlpha * (_channelAPtr[i] - _deemphasisAvgL); _channelAPtr[i] = _deemphasisAvgL; } #endregion #region Fill output buffer for (var i = 0; i < length; i++) { var sample = _channelAPtr[i] * AudioGain; interleavedStereo[i * 2] = sample; interleavedStereo[i * 2 + 1] = sample; } #endregion }
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 }