mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-26 01:39:05 -05:00
SSB demod: better algorithm for AGC limitation. For #1918
This commit is contained in:
parent
f98800702c
commit
68601d6947
@ -143,7 +143,7 @@ This AGC is based on the calculated magnitude (square root of power of the filte
|
|||||||
|
|
||||||
<h4>13.3: AGC clamping</h4>
|
<h4>13.3: AGC clamping</h4>
|
||||||
|
|
||||||
When on this clamps signal at the maximum amplitude. Normally this is not needed for most signals as the AGC amplitude order is quite conservative at 10% of the maximum. You may switch it on if you notice a loud click when a transmission starts.
|
This limits AGC gain when signal rises up sharply avoiding peak audio overload. You may switch it on if you notice a loud click on strong signals after silences.
|
||||||
|
|
||||||
<h4>13.4: Noise Reduction</h4>
|
<h4>13.4: Noise Reduction</h4>
|
||||||
|
|
||||||
|
@ -73,8 +73,6 @@ SSBDemodSink::SSBDemodSink() :
|
|||||||
m_magsqSum = 0.0;
|
m_magsqSum = 0.0;
|
||||||
m_magsqPeak = 0.0;
|
m_magsqPeak = 0.0;
|
||||||
m_magsqCount = 0;
|
m_magsqCount = 0;
|
||||||
m_magsqCur = 0.0;
|
|
||||||
m_magsqPrev = 0.0;
|
|
||||||
|
|
||||||
SSBFilter = new fftfilt(m_LowCutoff / m_audioSampleRate, m_Bandwidth / m_audioSampleRate, m_ssbFftLen);
|
SSBFilter = new fftfilt(m_LowCutoff / m_audioSampleRate, m_Bandwidth / m_audioSampleRate, m_ssbFftLen);
|
||||||
DSBFilter = new fftfilt((2.0f * m_Bandwidth) / m_audioSampleRate, 2 * m_ssbFftLen);
|
DSBFilter = new fftfilt((2.0f * m_Bandwidth) / m_audioSampleRate, 2 * m_ssbFftLen);
|
||||||
@ -175,24 +173,20 @@ void SSBDemodSink::processOneSample(Complex &ci)
|
|||||||
float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 1.0;
|
float agcVal = m_agcActive ? m_agc.feedAndGetValue(sideband[i]) : 1.0;
|
||||||
fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay());
|
fftfilt::cmplx& delayedSample = m_squelchDelayLine.readBack(m_agc.getStepDownDelay());
|
||||||
m_audioActive = delayedSample.real() != 0.0;
|
m_audioActive = delayedSample.real() != 0.0;
|
||||||
m_magsqCur = std::norm(sideband[i]*agcVal);
|
|
||||||
|
|
||||||
// Prevent overload based on squared magnitude variation
|
// Prevent overload based on squared magnitude variation
|
||||||
// Only if AGC is active
|
// Only if AGC is active
|
||||||
if (m_agcActive && m_agcClamping && (std::abs(m_magsqCur - m_magsqPrev) > m_agcTarget*m_agcTarget*5.0) & (agcVal > 100.0))
|
if (m_agcActive && m_agcClamping && agcVal > 100.0)
|
||||||
{
|
{
|
||||||
float target = m_agcTarget*sqrt(agcVal); // Quench AGC depending on previous value
|
qDebug("SSBDemodSink::processOneSample: %f", agcVal);
|
||||||
m_agc.reset(target);
|
m_agc.reset(m_agcTarget*m_agcTarget);
|
||||||
m_squelchDelayLine.write(fftfilt::cmplx{target, 0.0});
|
m_squelchDelayLine.write(fftfilt::cmplx{0.0, 0.0});
|
||||||
m_magsqCur = target*target;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_squelchDelayLine.write(sideband[i]*agcVal);
|
m_squelchDelayLine.write(sideband[i]*agcVal);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_magsqPrev = m_magsqCur;
|
|
||||||
|
|
||||||
if (m_audioMute)
|
if (m_audioMute)
|
||||||
{
|
{
|
||||||
m_audioBuffer[m_audioBufferFill].r = 0;
|
m_audioBuffer[m_audioBufferFill].r = 0;
|
||||||
@ -200,7 +194,6 @@ void SSBDemodSink::processOneSample(Complex &ci)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// fftfilt::cmplx z = m_agcActive ? delayedSample * m_agc.getStepValue() : delayedSample;
|
|
||||||
fftfilt::cmplx z = (m_agcActive && m_agcClamping) ?
|
fftfilt::cmplx z = (m_agcActive && m_agcClamping) ?
|
||||||
fftfilt::cmplx{m_lowpassI.filter(delayedSample.real()), m_lowpassQ.filter(delayedSample.imag())}
|
fftfilt::cmplx{m_lowpassI.filter(delayedSample.real()), m_lowpassQ.filter(delayedSample.imag())}
|
||||||
: delayedSample;
|
: delayedSample;
|
||||||
|
@ -102,8 +102,6 @@ private:
|
|||||||
double m_magsqSum;
|
double m_magsqSum;
|
||||||
double m_magsqPeak;
|
double m_magsqPeak;
|
||||||
int m_magsqCount;
|
int m_magsqCount;
|
||||||
double m_magsqCur;
|
|
||||||
double m_magsqPrev;
|
|
||||||
MagSqLevelsStore m_magSqLevelStore;
|
MagSqLevelsStore m_magSqLevelStore;
|
||||||
MagAGC m_agc;
|
MagAGC m_agc;
|
||||||
bool m_agcActive;
|
bool m_agcActive;
|
||||||
|
Loading…
Reference in New Issue
Block a user