mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-08-01 13:32:33 -04:00
WDSP Receiver: implemented spectrum handling and AGC
This commit is contained in:
parent
bc34a759c7
commit
dc626ea9bb
@ -211,7 +211,7 @@ void WDSPRxGUI::on_dnr_toggled(bool)
|
|||||||
|
|
||||||
void WDSPRxGUI::on_agcGain_valueChanged(int value)
|
void WDSPRxGUI::on_agcGain_valueChanged(int value)
|
||||||
{
|
{
|
||||||
QString s = QString::number((1<<value), 'f', 0);
|
QString s = QString::number(value, 'f', 0);
|
||||||
ui->agcGainText->setText(s);
|
ui->agcGainText->setText(s);
|
||||||
m_settings.m_agcGain = value;
|
m_settings.m_agcGain = value;
|
||||||
applySettings();
|
applySettings();
|
||||||
@ -769,11 +769,9 @@ void WDSPRxGUI::dnrSetup(int32_t iValueChanged)
|
|||||||
|
|
||||||
void WDSPRxGUI::tick()
|
void WDSPRxGUI::tick()
|
||||||
{
|
{
|
||||||
double magsqAvg, magsqPeak;
|
double powDbAvg, powDbPeak;
|
||||||
int nbMagsqSamples;
|
int nbMagsqSamples;
|
||||||
m_wdspRx->getMagSqLevels(magsqAvg, magsqPeak, nbMagsqSamples);
|
m_wdspRx->getMagSqLevels(powDbAvg, powDbPeak, nbMagsqSamples); // powers directly in dB
|
||||||
double powDbAvg = CalcDb::dbPower(magsqAvg);
|
|
||||||
double powDbPeak = CalcDb::dbPower(magsqPeak);
|
|
||||||
|
|
||||||
ui->channelPowerMeter->levelChanged(
|
ui->channelPowerMeter->levelChanged(
|
||||||
(WDSPRxSettings::m_mminPowerThresholdDBf + powDbAvg) / WDSPRxSettings::m_mminPowerThresholdDBf,
|
(WDSPRxSettings::m_mminPowerThresholdDBf + powDbAvg) / WDSPRxSettings::m_mminPowerThresholdDBf,
|
||||||
|
@ -34,31 +34,60 @@
|
|||||||
#include "wdsprxsink.h"
|
#include "wdsprxsink.h"
|
||||||
|
|
||||||
const int WDSPRxSink::m_ssbFftLen = 2048;
|
const int WDSPRxSink::m_ssbFftLen = 2048;
|
||||||
const int WDSPRxSink::m_agcTarget = 3276; // 32768/10 -10 dB amplitude => -20 dB power: center of normal signal
|
|
||||||
const int WDSPRxSink::m_wdspSampleRate = 48000;
|
const int WDSPRxSink::m_wdspSampleRate = 48000;
|
||||||
const int WDSPRxSink::m_wdspBufSize = 512;
|
const int WDSPRxSink::m_wdspBufSize = 512;
|
||||||
|
|
||||||
WDSPRxSink::SpectrumProbe::SpectrumProbe(SampleVector& sampleVector) :
|
WDSPRxSink::SpectrumProbe::SpectrumProbe(SampleVector& sampleVector) :
|
||||||
m_sampleVector(sampleVector)
|
m_sampleVector(sampleVector),
|
||||||
|
m_spanLog2(0),
|
||||||
|
m_dsb(false),
|
||||||
|
m_usb(true),
|
||||||
|
m_sum(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void WDSPRxSink::SpectrumProbe::proceed(const double *in, int nb_samples)
|
void WDSPRxSink::SpectrumProbe::setSpanLog2(int spanLog2)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < nb_samples; i++) {
|
m_spanLog2 = spanLog2;
|
||||||
m_sampleVector.push_back(Sample{static_cast<FixReal>(in[2*i]*SDR_RX_SCALED), static_cast<FixReal>(in[2*i+1]*SDR_RX_SCALED)});
|
}
|
||||||
|
|
||||||
|
void WDSPRxSink::SpectrumProbe::proceed(const float *in, int nb_samples)
|
||||||
|
{
|
||||||
|
int decim = 1<<(m_spanLog2 - 1);
|
||||||
|
unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1)
|
||||||
|
|
||||||
|
for (int i = 0; i < nb_samples; i++)
|
||||||
|
{
|
||||||
|
float cr = in[2*i+1];
|
||||||
|
float ci = in[2*i];
|
||||||
|
m_sum += std::complex<float>{cr, ci};
|
||||||
|
|
||||||
|
if (decim == 1)
|
||||||
|
{
|
||||||
|
m_sampleVector.push_back(Sample(cr*SDR_RX_SCALEF, ci*SDR_RX_SCALEF));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(m_undersampleCount++ & decim_mask))
|
||||||
|
{
|
||||||
|
float avgr = m_sum.real() / decim;
|
||||||
|
float avgi = m_sum.imag() / decim;
|
||||||
|
|
||||||
|
if (!m_dsb & !m_usb)
|
||||||
|
{ // invert spectrum for LSB
|
||||||
|
m_sampleVector.push_back(Sample(avgi*SDR_RX_SCALEF, avgr*SDR_RX_SCALEF));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sampleVector.push_back(Sample(avgr*SDR_RX_SCALEF, avgi*SDR_RX_SCALEF));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_sum = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WDSPRxSink::WDSPRxSink() :
|
WDSPRxSink::WDSPRxSink() :
|
||||||
m_audioBinaual(false),
|
|
||||||
m_dsb(false),
|
|
||||||
m_audioMute(false),
|
|
||||||
m_agc(12000, m_agcTarget, 1e-2),
|
|
||||||
m_agcActive(false),
|
|
||||||
m_agcClamping(false),
|
|
||||||
m_agcNbSamples(12000),
|
|
||||||
m_agcPowerThreshold(1e-2),
|
|
||||||
m_agcThresholdGate(0),
|
|
||||||
m_squelchDelayLine(2*48000),
|
m_squelchDelayLine(2*48000),
|
||||||
m_audioActive(false),
|
m_audioActive(false),
|
||||||
m_spectrumSink(nullptr),
|
m_spectrumSink(nullptr),
|
||||||
@ -75,12 +104,10 @@ WDSPRxSink::WDSPRxSink() :
|
|||||||
m_audioBuffer.resize(m_audioSampleRate / 10);
|
m_audioBuffer.resize(m_audioSampleRate / 10);
|
||||||
m_audioBufferFill = 0;
|
m_audioBufferFill = 0;
|
||||||
m_undersampleCount = 0;
|
m_undersampleCount = 0;
|
||||||
m_sum = 0;
|
|
||||||
|
|
||||||
m_demodBuffer.resize(1<<12);
|
m_demodBuffer.resize(1<<12);
|
||||||
m_demodBufferFill = 0;
|
m_demodBufferFill = 0;
|
||||||
|
|
||||||
m_usb = true;
|
|
||||||
m_sAvg = 0.0;
|
m_sAvg = 0.0;
|
||||||
m_sPeak = 0.0;
|
m_sPeak = 0.0;
|
||||||
m_sCount = 1;
|
m_sCount = 1;
|
||||||
@ -144,37 +171,34 @@ void WDSPRxSink::getMagSqLevels(double& avg, double& peak, int& nbSamples)
|
|||||||
|
|
||||||
void WDSPRxSink::processOneSample(Complex &ci)
|
void WDSPRxSink::processOneSample(Complex &ci)
|
||||||
{
|
{
|
||||||
m_rxa->get_inbuff()[2*m_inCount] = ci.real() / SDR_RX_SCALED;
|
m_rxa->get_inbuff()[2*m_inCount] = ci.imag() / SDR_RX_SCALEF;
|
||||||
m_rxa->get_inbuff()[2*m_inCount+1] = ci.imag() / SDR_RX_SCALED;
|
m_rxa->get_inbuff()[2*m_inCount+1] = ci.real() / SDR_RX_SCALEF;
|
||||||
|
|
||||||
if (++m_inCount == m_rxa->get_insize())
|
if (++m_inCount == m_rxa->get_insize())
|
||||||
{
|
{
|
||||||
WDSP::RXA::xrxa(m_rxa);
|
WDSP::RXA::xrxa(m_rxa);
|
||||||
|
|
||||||
|
m_sCount = m_wdspBufSize;
|
||||||
|
m_sAvg = WDSP::METER::GetMeter(*m_rxa, WDSP::RXA::RXA_S_AV);
|
||||||
|
m_sPeak = WDSP::METER::GetMeter(*m_rxa, WDSP::RXA::RXA_S_PK);
|
||||||
|
|
||||||
for (int i = 0; i < m_rxa->get_outsize(); i++)
|
for (int i = 0; i < m_rxa->get_outsize(); i++)
|
||||||
{
|
{
|
||||||
if (i == 0)
|
if (m_settings.m_audioMute)
|
||||||
{
|
|
||||||
m_sCount = m_wdspBufSize;
|
|
||||||
m_sAvg = WDSP::METER::GetMeter(*m_rxa, WDSP::RXA::RXA_S_AV);
|
|
||||||
m_sPeak = WDSP::METER::GetMeter(*m_rxa, WDSP::RXA::RXA_S_PK);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_audioMute)
|
|
||||||
{
|
{
|
||||||
m_audioBuffer[m_audioBufferFill].r = 0;
|
m_audioBuffer[m_audioBufferFill].r = 0;
|
||||||
m_audioBuffer[m_audioBufferFill].l = 0;
|
m_audioBuffer[m_audioBufferFill].l = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const double& cr = m_rxa->get_outbuff()[2*i];
|
const double& cr = m_rxa->get_outbuff()[2*i+1];
|
||||||
const double& ci = m_rxa->get_outbuff()[2*i+1];
|
const double& ci = m_rxa->get_outbuff()[2*i];
|
||||||
qint16 zr = cr * 32768.0;
|
qint16 zr = cr * 32768.0;
|
||||||
qint16 zi = ci * 32768.0;
|
qint16 zi = ci * 32768.0;
|
||||||
m_audioBuffer[m_audioBufferFill].r = zr * m_volume;
|
m_audioBuffer[m_audioBufferFill].r = zr * m_volume;
|
||||||
m_audioBuffer[m_audioBufferFill].l = zi * m_volume;
|
m_audioBuffer[m_audioBufferFill].l = zi * m_volume;
|
||||||
|
|
||||||
if (m_audioBinaual)
|
if (m_settings.m_audioBinaural)
|
||||||
{
|
{
|
||||||
m_demodBuffer[m_demodBufferFill++] = zr * m_volume;
|
m_demodBuffer[m_demodBufferFill++] = zr * m_volume;
|
||||||
m_demodBuffer[m_demodBufferFill++] = zi * m_volume;
|
m_demodBuffer[m_demodBufferFill++] = zi * m_volume;
|
||||||
@ -204,7 +228,7 @@ void WDSPRxSink::processOneSample(Complex &ci)
|
|||||||
fifo->write(
|
fifo->write(
|
||||||
(quint8*) &m_demodBuffer[0],
|
(quint8*) &m_demodBuffer[0],
|
||||||
m_demodBuffer.size() * sizeof(qint16),
|
m_demodBuffer.size() * sizeof(qint16),
|
||||||
m_audioBinaual ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
m_settings.m_audioBinaural ? DataFifo::DataTypeCI16 : DataFifo::DataTypeI16
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,7 +252,7 @@ void WDSPRxSink::processOneSample(Complex &ci)
|
|||||||
|
|
||||||
if (m_spectrumSink && (m_sampleBuffer.size() != 0))
|
if (m_spectrumSink && (m_sampleBuffer.size() != 0))
|
||||||
{
|
{
|
||||||
m_spectrumSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), false);
|
m_spectrumSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), !m_settings.m_dsb);
|
||||||
m_sampleBuffer.clear();
|
m_sampleBuffer.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +328,7 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
|
|||||||
<< " m_lowCutoff: " << settings.m_filterBank[settings.m_filterIndex].m_lowCutoff
|
<< " m_lowCutoff: " << settings.m_filterBank[settings.m_filterIndex].m_lowCutoff
|
||||||
<< " m_fftWindow: " << settings.m_filterBank[settings.m_filterIndex].m_fftWindow << "]"
|
<< " m_fftWindow: " << settings.m_filterBank[settings.m_filterIndex].m_fftWindow << "]"
|
||||||
<< " m_volume: " << settings.m_volume
|
<< " m_volume: " << settings.m_volume
|
||||||
<< " m_audioBinaual: " << settings.m_audioBinaural
|
<< " m_audioBinaural: " << settings.m_audioBinaural
|
||||||
<< " m_audioFlipChannels: " << settings.m_audioFlipChannels
|
<< " m_audioFlipChannels: " << settings.m_audioFlipChannels
|
||||||
<< " m_dsb: " << settings.m_dsb
|
<< " m_dsb: " << settings.m_dsb
|
||||||
<< " m_audioMute: " << settings.m_audioMute
|
<< " m_audioMute: " << settings.m_audioMute
|
||||||
@ -336,11 +360,11 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
|
|||||||
if (band < 0)
|
if (band < 0)
|
||||||
{
|
{
|
||||||
band = -band;
|
band = -band;
|
||||||
m_usb = false;
|
m_spectrumProbe.setUSB(false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_usb = true;
|
m_spectrumProbe.setUSB(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Bandwidth = band;
|
m_Bandwidth = band;
|
||||||
@ -351,11 +375,13 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
fLow = high;
|
fLow = high;
|
||||||
fHigh = -high;
|
fHigh = -high;
|
||||||
|
m_spectrumProbe.setDSB(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fLow = high;
|
fLow = high;
|
||||||
fHigh = low;
|
fHigh = low;
|
||||||
|
m_spectrumProbe.setDSB(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -364,11 +390,13 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
|
|||||||
{
|
{
|
||||||
fLow = -high;
|
fLow = -high;
|
||||||
fHigh = high;
|
fHigh = high;
|
||||||
|
m_spectrumProbe.setDSB(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fLow = low;
|
fLow = low;
|
||||||
fHigh = high;
|
fHigh = high;
|
||||||
|
m_spectrumProbe.setDSB(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -381,19 +409,55 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
|
|||||||
WDSP::NBP::NBPSetWindow(*m_rxa, m_settings.m_filterBank[m_settings.m_filterIndex].m_fftWindow);
|
WDSP::NBP::NBPSetWindow(*m_rxa, m_settings.m_filterBank[m_settings.m_filterIndex].m_fftWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((m_settings.m_filterBank[settings.m_filterIndex].m_spanLog2 != settings.m_filterBank[settings.m_filterIndex].m_spanLog2) || force) {
|
||||||
|
m_spectrumProbe.setSpanLog2(settings.m_filterBank[settings.m_filterIndex].m_spanLog2);
|
||||||
|
}
|
||||||
|
|
||||||
if ((m_settings.m_agc != settings.m_agc)
|
if ((m_settings.m_agc != settings.m_agc)
|
||||||
|| (m_settings.m_agcMode != settings.m_agcMode)
|
|| (m_settings.m_agcMode != settings.m_agcMode)
|
||||||
|
|| (m_settings.m_agcSlope != settings.m_agcSlope)
|
||||||
|
|| (m_settings.m_agcHangThreshold != settings.m_agcHangThreshold)
|
||||||
|| (m_settings.m_agcGain != settings.m_agcGain) || force)
|
|| (m_settings.m_agcGain != settings.m_agcGain) || force)
|
||||||
{
|
{
|
||||||
|
WDSP::WCPAGC::SetAGCMode(*m_rxa, settings.m_agc ? (int) settings.m_agcMode + 1 : 0); // SetRXAAGCMode(id, agc);
|
||||||
|
WDSP::WCPAGC::SetAGCSlope(*m_rxa, settings.m_agcSlope); // SetRXAAGCSlope(id, rx->agc_slope);
|
||||||
|
WDSP::WCPAGC::SetAGCTop(*m_rxa, (float) settings.m_agcGain); // SetRXAAGCTop(id, rx->agc_gain);
|
||||||
|
|
||||||
if (settings.m_agc)
|
if (settings.m_agc)
|
||||||
{
|
{
|
||||||
WDSP::WCPAGC::SetAGCMode(*m_rxa, (int) settings.m_agcMode + 1);
|
switch (settings.m_agcMode)
|
||||||
WDSP::WCPAGC::SetAGCFixed(*m_rxa, (double) settings.m_agcGain);
|
{
|
||||||
|
case WDSPRxSettings::AGCMode::AGCLong:
|
||||||
|
WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2);
|
||||||
|
WDSP::WCPAGC::SetAGCHang(*m_rxa, 2000); // SetRXAAGCHang(id, 2000);
|
||||||
|
WDSP::WCPAGC::SetAGCDecay(*m_rxa, 2000); // SetRXAAGCDecay(id, 2000);
|
||||||
|
WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold);
|
||||||
|
break;
|
||||||
|
case WDSPRxSettings::AGCMode::AGCSlow:
|
||||||
|
WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2);
|
||||||
|
WDSP::WCPAGC::SetAGCHang(*m_rxa, 1000); // SetRXAAGCHang(id, 1000);
|
||||||
|
WDSP::WCPAGC::SetAGCDecay(*m_rxa, 500); // SetRXAAGCDecay(id, 500);
|
||||||
|
WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, (int)rx->agc_hang_threshold);
|
||||||
|
break;
|
||||||
|
case WDSPRxSettings::AGCMode::AGCMedium:
|
||||||
|
WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2);
|
||||||
|
WDSP::WCPAGC::SetAGCHang(*m_rxa, 0); // SetRXAAGCHang(id, 0);
|
||||||
|
WDSP::WCPAGC::SetAGCDecay(*m_rxa, 250); // SetRXAAGCDecay(id, 250);
|
||||||
|
WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100);
|
||||||
|
break;
|
||||||
|
case WDSPRxSettings::AGCMode::AGCFast:
|
||||||
|
WDSP::WCPAGC::SetAGCAttack(*m_rxa, 2); // SetRXAAGCAttack(id, 2);
|
||||||
|
WDSP::WCPAGC::SetAGCHang(*m_rxa, 0); // SetRXAAGCHang(id, 0);
|
||||||
|
WDSP::WCPAGC::SetAGCDecay(*m_rxa, 50); // SetRXAAGCDecay(id, 50);
|
||||||
|
WDSP::WCPAGC::SetAGCHangThreshold(*m_rxa, settings.m_agcHangThreshold); // SetRXAAGCHangThreshold(id, 100);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
WDSP::WCPAGC::SetAGCFixed(*m_rxa, 60.0f); // default
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
WDSP::WCPAGC::SetAGCMode(*m_rxa, 0);
|
WDSP::WCPAGC::SetAGCFixed(*m_rxa, (float) settings.m_agcGain);
|
||||||
WDSP::WCPAGC::SetAGCTop(*m_rxa, (double) settings.m_agcGain);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,9 +475,5 @@ void WDSPRxSink::applySettings(const WDSPRxSettings& settings, bool force)
|
|||||||
WDSP::PANEL::SetPanelCopy(*m_rxa, settings.m_audioFlipChannels ? 3 : 0);
|
WDSP::PANEL::SetPanelCopy(*m_rxa, settings.m_audioFlipChannels ? 3 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_audioBinaual = settings.m_audioBinaural;
|
|
||||||
m_dsb = settings.m_dsb;
|
|
||||||
m_audioMute = settings.m_audioMute;
|
|
||||||
m_agcActive = settings.m_agc;
|
|
||||||
m_settings = settings;
|
m_settings = settings;
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "dsp/ncof.h"
|
#include "dsp/ncof.h"
|
||||||
#include "dsp/interpolator.h"
|
#include "dsp/interpolator.h"
|
||||||
#include "dsp/fftfilt.h"
|
#include "dsp/fftfilt.h"
|
||||||
#include "dsp/agc.h"
|
|
||||||
#include "dsp/firfilter.h"
|
#include "dsp/firfilter.h"
|
||||||
#include "audio/audiofifo.h"
|
#include "audio/audiofifo.h"
|
||||||
#include "util/doublebufferfifo.h"
|
#include "util/doublebufferfifo.h"
|
||||||
@ -63,9 +62,17 @@ private:
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpectrumProbe(SampleVector& sampleVector);
|
SpectrumProbe(SampleVector& sampleVector);
|
||||||
virtual void proceed(const double *in, int nbSamples);
|
virtual void proceed(const float *in, int nbSamples);
|
||||||
|
void setSpanLog2(int spanLog2);
|
||||||
|
void setDSB(bool dsb) { m_dsb = dsb; }
|
||||||
|
void setUSB(bool usb) { m_usb = usb; }
|
||||||
private:
|
private:
|
||||||
SampleVector& m_sampleVector;
|
SampleVector& m_sampleVector;
|
||||||
|
int m_spanLog2;
|
||||||
|
bool m_dsb;
|
||||||
|
bool m_usb;
|
||||||
|
uint32_t m_undersampleCount;
|
||||||
|
std::complex<float> m_sum;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MagSqLevelsStore
|
struct MagSqLevelsStore
|
||||||
@ -83,23 +90,12 @@ private:
|
|||||||
|
|
||||||
Real m_Bandwidth;
|
Real m_Bandwidth;
|
||||||
Real m_volume;
|
Real m_volume;
|
||||||
fftfilt::cmplx m_sum;
|
|
||||||
int m_undersampleCount;
|
int m_undersampleCount;
|
||||||
int m_channelSampleRate;
|
int m_channelSampleRate;
|
||||||
int m_channelFrequencyOffset;
|
int m_channelFrequencyOffset;
|
||||||
bool m_audioBinaual;
|
|
||||||
bool m_usb;
|
|
||||||
bool m_dsb;
|
|
||||||
bool m_audioMute;
|
|
||||||
double m_sAvg;
|
double m_sAvg;
|
||||||
double m_sPeak;
|
double m_sPeak;
|
||||||
int m_sCount;
|
int m_sCount;
|
||||||
MagAGC m_agc;
|
|
||||||
bool m_agcActive;
|
|
||||||
bool m_agcClamping;
|
|
||||||
int m_agcNbSamples; //!< number of audio (48 kHz) samples for AGC averaging
|
|
||||||
double m_agcPowerThreshold; //!< AGC power threshold (linear)
|
|
||||||
int m_agcThresholdGate; //!< Gate length in number of samples befor threshold triggers
|
|
||||||
DoubleBufferFIFO<fftfilt::cmplx> m_squelchDelayLine;
|
DoubleBufferFIFO<fftfilt::cmplx> m_squelchDelayLine;
|
||||||
bool m_audioActive; //!< True if an audio signal is produced (no AGC or AGC and above threshold)
|
bool m_audioActive; //!< True if an audio signal is produced (no AGC or AGC and above threshold)
|
||||||
|
|
||||||
@ -125,7 +121,6 @@ private:
|
|||||||
WDSP::RXA *m_rxa;
|
WDSP::RXA *m_rxa;
|
||||||
|
|
||||||
static const int m_ssbFftLen;
|
static const int m_ssbFftLen;
|
||||||
static const int m_agcTarget;
|
|
||||||
static const int m_wdspSampleRate;
|
static const int m_wdspSampleRate;
|
||||||
static const int m_wdspBufSize;
|
static const int m_wdspBufSize;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user