SSB Modulator: implemented hard limiter on compressor to prevent overload

This commit is contained in:
f4exb 2019-05-07 02:50:05 +02:00
parent a9a149ec4b
commit a69d8a6422
3 changed files with 20 additions and 5 deletions

View File

@ -110,6 +110,7 @@ SSBMod::SSBMod(DeviceSinkAPI *deviceAPI) :
m_inAGC.setGate(m_settings.m_agcThresholdGate);
m_inAGC.setStepDownDelay(m_settings.m_agcThresholdDelay);
m_inAGC.setClamping(true);
m_inAGC.setHardLimiting(true);
applyChannelSettings(m_basebandSampleRate, m_outputSampleRate, m_inputFrequencyOffset, true);
applySettings(m_settings, true);

View File

@ -55,7 +55,8 @@ MagAGC::MagAGC(int historySize, double R, double threshold) :
m_stepDownDelay(historySize),
m_clamping(false),
m_R2(R*R),
m_clampMax(1.0)
m_clampMax(1.0),
m_hardLimiting(false)
{}
MagAGC::~MagAGC()
@ -95,6 +96,15 @@ void MagAGC::feed(Complex& ci)
ci *= feedAndGetValue(ci);
}
double MagAGC::hardLimiter(double multiplier, double magsq)
{
if ((m_hardLimiting) && (multiplier*multiplier*magsq > 1.0)) {
return 1.0 / (multiplier*sqrt(magsq));
} else {
return multiplier;
}
}
double MagAGC::feedAndGetValue(const Complex& ci)
{
m_magsq = ci.real()*ci.real() + ci.imag()*ci.imag();
@ -153,11 +163,11 @@ double MagAGC::feedAndGetValue(const Complex& ci)
if (m_stepUpCounter < m_stepLength)
{
m_stepUpCounter++;
return m_u0 * StepFunctions::smootherstep(m_stepUpCounter * m_stepDelta);
return hardLimiter(m_u0 * StepFunctions::smootherstep(m_stepUpCounter * m_stepDelta), m_magsq);
}
else
{
return m_u0;
return hardLimiter(m_u0, m_magsq);
}
}
else
@ -167,7 +177,7 @@ double MagAGC::feedAndGetValue(const Complex& ci)
if (m_stepDownCounter > 0)
{
m_stepDownCounter--;
return m_u0 * StepFunctions::smootherstep(m_stepDownCounter * m_stepDelta);
return hardLimiter(m_u0 * StepFunctions::smootherstep(m_stepDownCounter * m_stepDelta), m_magsq);
}
else
{
@ -177,7 +187,7 @@ double MagAGC::feedAndGetValue(const Complex& ci)
}
else
{
return m_u0;
return hardLimiter(m_u0, m_magsq);
}
}

View File

@ -53,6 +53,7 @@ public:
int getStepDownDelay() const { return m_stepDownDelay; }
float getStepDownValue() const;
float getStepValue() const;
void setHardLimiting(bool hardLimiting) { m_hardLimiting = hardLimiting; }
private:
bool m_squared; //!< use squared magnitude (power) to compute AGC value
@ -69,6 +70,9 @@ private:
bool m_clamping; //!< clamping active
double m_R2; //!< square of ordered magnitude
double m_clampMax; //!< maximum to clamp to as power value
bool m_hardLimiting; //!< hard limit multiplier so that resulting sample magnitude does not exceed 1.0
double hardLimiter(double multiplier, double magsq);
};
template<uint32_t AvgSize>