mirror of https://github.com/f4exb/sdrangel.git
Rework decimation.
This commit is contained in:
parent
aaef1678ad
commit
444e8ed857
|
@ -45,7 +45,6 @@ public:
|
||||||
|
|
||||||
virtual const QString& getDeviceDescription() const = 0;
|
virtual const QString& getDeviceDescription() const = 0;
|
||||||
virtual int getSampleRate() const = 0;
|
virtual int getSampleRate() const = 0;
|
||||||
virtual int wfdecimation() const = 0;
|
|
||||||
virtual quint64 getCenterFrequency() const = 0;
|
virtual quint64 getCenterFrequency() const = 0;
|
||||||
|
|
||||||
virtual bool handleMessage(Message* message) = 0;
|
virtual bool handleMessage(Message* message) = 0;
|
||||||
|
|
|
@ -56,10 +56,12 @@ void NFMDemod::configure(MessageQueue* messageQueue, Real rfBandwidth, Real afBa
|
||||||
cmd->submit(messageQueue, this);
|
cmd->submit(messageQueue, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int framedrop = 0;
|
||||||
void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst)
|
void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iterator end, bool firstOfBurst)
|
||||||
{
|
{
|
||||||
Complex ci;
|
Complex ci;
|
||||||
bool consumed;
|
bool consumed;
|
||||||
|
qint16 sample;
|
||||||
|
|
||||||
for(SampleVector::const_iterator it = begin; it < end; ++it) {
|
for(SampleVector::const_iterator it = begin; it < end; ++it) {
|
||||||
Complex c(it->real() / 32768.0, it->imag() / 32768.0);
|
Complex c(it->real() / 32768.0, it->imag() / 32768.0);
|
||||||
|
@ -67,22 +69,25 @@ void NFMDemod::feed(SampleVector::const_iterator begin, SampleVector::const_iter
|
||||||
|
|
||||||
consumed = false;
|
consumed = false;
|
||||||
if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &consumed, &ci)) {
|
if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &consumed, &ci)) {
|
||||||
m_sampleBuffer.push_back(Sample(ci.real() * 32768.0, ci.imag() * 32768.0));
|
if (++framedrop & 1) {
|
||||||
|
m_movingAverage.feed(ci.real() * ci.real() + ci.imag() * ci.imag());
|
||||||
|
if(m_movingAverage.average() >= m_squelchLevel)
|
||||||
|
m_squelchState = m_sampleRate / 50;
|
||||||
|
}
|
||||||
|
Complex d = ci * conj(m_lastSample);
|
||||||
|
m_lastSample = ci;
|
||||||
|
Real demod = atan2(d.imag(), d.real()) / M_PI;
|
||||||
|
demod = m_volume * m_lowpass.filter(demod);
|
||||||
|
sample = demod * 32767;
|
||||||
|
|
||||||
m_movingAverage.feed(ci.real() * ci.real() + ci.imag() * ci.imag());
|
if (!(framedrop & 3))
|
||||||
|
m_sampleBuffer.push_back(Sample(sample, sample));
|
||||||
|
|
||||||
if(m_movingAverage.average() >= m_squelchLevel)
|
if(m_squelchState > 0)
|
||||||
m_squelchState = m_sampleRate / 50;
|
|
||||||
|
|
||||||
if(m_squelchState > 0) {
|
|
||||||
m_squelchState--;
|
m_squelchState--;
|
||||||
Complex d = ci * conj(m_lastSample);
|
else
|
||||||
m_lastSample = ci;
|
sample = 0;
|
||||||
Real demod = atan2(d.imag(), d.real()) / M_PI;
|
{
|
||||||
demod = m_lowpass.filter(demod);
|
|
||||||
demod *= m_volume;
|
|
||||||
qint16 sample = demod * 32767;
|
|
||||||
|
|
||||||
m_audioBuffer[m_audioBufferFill].l = sample;
|
m_audioBuffer[m_audioBufferFill].l = sample;
|
||||||
m_audioBuffer[m_audioBufferFill].r = sample;
|
m_audioBuffer[m_audioBufferFill].r = sample;
|
||||||
++m_audioBufferFill;
|
++m_audioBufferFill;
|
||||||
|
|
|
@ -164,7 +164,7 @@ NFMDemodGUI::NFMDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
|
||||||
m_pluginAPI->addSampleSink(m_threadedSampleSink);
|
m_pluginAPI->addSampleSink(m_threadedSampleSink);
|
||||||
|
|
||||||
ui->glSpectrum->setCenterFrequency(0);
|
ui->glSpectrum->setCenterFrequency(0);
|
||||||
ui->glSpectrum->setSampleRate(48000);
|
ui->glSpectrum->setSampleRate(12000);
|
||||||
ui->glSpectrum->setDisplayWaterfall(true);
|
ui->glSpectrum->setDisplayWaterfall(true);
|
||||||
ui->glSpectrum->setDisplayMaxHold(true);
|
ui->glSpectrum->setDisplayMaxHold(true);
|
||||||
m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
|
m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
|
||||||
|
|
|
@ -140,7 +140,7 @@ SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, QWidget* parent) :
|
||||||
ui->glSpectrum->setCenterFrequency(0);
|
ui->glSpectrum->setCenterFrequency(0);
|
||||||
ui->glSpectrum->setSampleRate(12000);
|
ui->glSpectrum->setSampleRate(12000);
|
||||||
ui->glSpectrum->setDisplayWaterfall(true);
|
ui->glSpectrum->setDisplayWaterfall(true);
|
||||||
ui->glSpectrum->setDisplayMaxHold(false);
|
ui->glSpectrum->setDisplayMaxHold(true);
|
||||||
m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
|
m_spectrumVis->configure(m_threadedSampleSink->getMessageQueue(), 64, 10, FFTWindow::BlackmanHarris);
|
||||||
|
|
||||||
m_channelMarker = new ChannelMarker(this);
|
m_channelMarker = new ChannelMarker(this);
|
||||||
|
|
|
@ -185,12 +185,6 @@ int RTLSDRInput::getSampleRate() const
|
||||||
return 1536000 / (1 << m_settings.m_decimation);
|
return 1536000 / (1 << m_settings.m_decimation);
|
||||||
}
|
}
|
||||||
|
|
||||||
int RTLSDRInput::wfdecimation() const
|
|
||||||
{
|
|
||||||
// decimate waterfall more when downsampling less
|
|
||||||
return (1 << (4 - m_settings.m_decimation) ) -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
quint64 RTLSDRInput::getCenterFrequency() const
|
quint64 RTLSDRInput::getCenterFrequency() const
|
||||||
{
|
{
|
||||||
return m_generalSettings.m_centerFrequency;
|
return m_generalSettings.m_centerFrequency;
|
||||||
|
|
|
@ -87,7 +87,6 @@ public:
|
||||||
|
|
||||||
const QString& getDeviceDescription() const;
|
const QString& getDeviceDescription() const;
|
||||||
int getSampleRate() const;
|
int getSampleRate() const;
|
||||||
int wfdecimation() const;
|
|
||||||
quint64 getCenterFrequency() const;
|
quint64 getCenterFrequency() const;
|
||||||
|
|
||||||
bool handleMessage(Message* message);
|
bool handleMessage(Message* message);
|
||||||
|
|
|
@ -74,66 +74,6 @@ void RTLSDRThread::run()
|
||||||
m_running = false;
|
m_running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
void RTLSDRThread::decimate2(SampleVector::iterator* it, const quint8* buf, qint32 len)
|
|
||||||
{
|
|
||||||
for(int pos = 0; pos < len; pos += 2) {
|
|
||||||
Sample s((((qint8)buf[pos]) - 128) << 8, (((qint8)buf[pos + 1]) - 128) << 8);
|
|
||||||
if(m_decimator2.workDecimateCenter(&s)) {
|
|
||||||
**it = s;
|
|
||||||
++(*it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTLSDRThread::decimate4(SampleVector::iterator* it, const quint8* buf, qint32 len)
|
|
||||||
{
|
|
||||||
for(int pos = 0; pos < len; pos += 2) {
|
|
||||||
Sample s((((qint8)buf[pos]) - 128) << 8, (((qint8)buf[pos + 1]) - 128) << 8);
|
|
||||||
if(m_decimator2.workDecimateCenter(&s)) {
|
|
||||||
if(m_decimator4.workDecimateCenter(&s)) {
|
|
||||||
**it = s;
|
|
||||||
++(*it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTLSDRThread::decimate8(SampleVector::iterator* it, const quint8* buf, qint32 len)
|
|
||||||
{
|
|
||||||
for(int pos = 0; pos < len; pos += 2) {
|
|
||||||
Sample s((((qint8)buf[pos]) - 128) << 8, (((qint8)buf[pos + 1]) - 128) << 8);
|
|
||||||
if(m_decimator2.workDecimateCenter(&s)) {
|
|
||||||
if(m_decimator4.workDecimateCenter(&s)) {
|
|
||||||
if(m_decimator8.workDecimateCenter(&s)) {
|
|
||||||
**it = s;
|
|
||||||
++(*it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void RTLSDRThread::decimate16(SampleVector::iterator* it, const quint8* buf, qint32 len)
|
|
||||||
{
|
|
||||||
for(int pos = 0; pos < len; pos += 2) {
|
|
||||||
Sample s((((qint8)buf[pos]) - 128) << 8, (((qint8)buf[pos + 1]) - 128) << 8);
|
|
||||||
if(m_decimator2.workDecimateCenter(&s)) {
|
|
||||||
if(m_decimator4.workDecimateCenter(&s)) {
|
|
||||||
if(m_decimator8.workDecimateCenter(&s)) {
|
|
||||||
if(m_decimator16.workDecimateCenter(&s)) {
|
|
||||||
**it = s;
|
|
||||||
++(*it);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void RTLSDRThread::decimate2(SampleVector::iterator* it, const quint8* buf, qint32 len)
|
void RTLSDRThread::decimate2(SampleVector::iterator* it, const quint8* buf, qint32 len)
|
||||||
{
|
{
|
||||||
qint16 xreal, yimag;
|
qint16 xreal, yimag;
|
||||||
|
@ -194,13 +134,16 @@ void RTLSDRThread::decimate16(SampleVector::iterator* it, const quint8* buf, qin
|
||||||
(*it)++;
|
(*it)++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
int localdecimation = 0;
|
||||||
void RTLSDRThread::callback(const quint8* buf, qint32 len)
|
void RTLSDRThread::callback(const quint8* buf, qint32 len)
|
||||||
{
|
{
|
||||||
qint16 xreal, yimag, phase;
|
qint16 xreal, yimag, phase;
|
||||||
SampleVector::iterator it = m_convertBuffer.begin();
|
SampleVector::iterator it = m_convertBuffer.begin();
|
||||||
|
|
||||||
|
if (++localdecimation < (1 << (4 - m_decimation))) return;
|
||||||
|
localdecimation = 0;
|
||||||
|
|
||||||
switch(m_decimation) {
|
switch(m_decimation) {
|
||||||
case 0: // 1:1 = no decimation
|
case 0: // 1:1 = no decimation
|
||||||
// just rotation
|
// just rotation
|
||||||
|
@ -210,7 +153,7 @@ void RTLSDRThread::callback(const quint8* buf, qint32 len)
|
||||||
xreal = phase * (buf[pos+0] - 127);
|
xreal = phase * (buf[pos+0] - 127);
|
||||||
yimag = phase * (buf[pos+1] - 127);
|
yimag = phase * (buf[pos+1] - 127);
|
||||||
*it++ = Sample( xreal<<7,yimag<<7);
|
*it++ = Sample( xreal<<7,yimag<<7);
|
||||||
xreal = phase * (128 - buf[pos+3]);
|
xreal = phase * (127 - buf[pos+3]);
|
||||||
yimag = phase * (buf[pos+2] - 127);
|
yimag = phase * (buf[pos+2] - 127);
|
||||||
*it++ = Sample( xreal<<7,yimag<<7);
|
*it++ = Sample( xreal<<7,yimag<<7);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,11 +48,6 @@ private:
|
||||||
|
|
||||||
int m_decimation;
|
int m_decimation;
|
||||||
|
|
||||||
IntHalfbandFilter m_decimator2;
|
|
||||||
IntHalfbandFilter m_decimator4;
|
|
||||||
IntHalfbandFilter m_decimator8;
|
|
||||||
IntHalfbandFilter m_decimator16;
|
|
||||||
|
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
void decimate2(SampleVector::iterator* it, const quint8* buf, qint32 len);
|
void decimate2(SampleVector::iterator* it, const quint8* buf, qint32 len);
|
||||||
|
|
|
@ -196,7 +196,6 @@ void DSPEngine::imbalance(SampleVector::iterator begin, SampleVector::iterator e
|
||||||
it->m_imag = (it->m_imag * m_imbalance) >> 16;
|
it->m_imag = (it->m_imag * m_imbalance) >> 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
int drop_frame = 0;
|
|
||||||
void DSPEngine::work()
|
void DSPEngine::work()
|
||||||
{
|
{
|
||||||
SampleFifo* sampleFifo = m_sampleSource->getSampleFifo();
|
SampleFifo* sampleFifo = m_sampleSource->getSampleFifo();
|
||||||
|
@ -211,12 +210,6 @@ void DSPEngine::work()
|
||||||
|
|
||||||
size_t count = sampleFifo->readBegin(sampleFifo->fill(), &part1begin, &part1end, &part2begin, &part2end);
|
size_t count = sampleFifo->readBegin(sampleFifo->fill(), &part1begin, &part1end, &part2begin, &part2end);
|
||||||
|
|
||||||
if (m_sampleSource->wfdecimation() & drop_frame++) {
|
|
||||||
sampleFifo->readCommit(count);
|
|
||||||
samplesDone += count;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// first part of FIFO data
|
// first part of FIFO data
|
||||||
if(part1begin != part1end) {
|
if(part1begin != part1end) {
|
||||||
// correct stuff
|
// correct stuff
|
||||||
|
|
Loading…
Reference in New Issue