diff --git a/plugins/channel/ssb/ssbdemod.cpp b/plugins/channel/ssb/ssbdemod.cpp index 7cadf0086..9abff79bd 100644 --- a/plugins/channel/ssb/ssbdemod.cpp +++ b/plugins/channel/ssb/ssbdemod.cpp @@ -50,20 +50,20 @@ SSBDemod::SSBDemod(SampleSink* sampleSink) : m_audioBuffer.resize(1<<9); m_audioBufferFill = 0; m_undersampleCount = 0; + m_sum = 0; m_usb = true; m_magsq = 0.0f; SSBFilter = new fftfilt(m_LowCutoff / m_audioSampleRate, m_Bandwidth / m_audioSampleRate, ssbFftLen); + DSBFilter = new fftfilt((2*m_Bandwidth) / m_sampleRate, 2*ssbFftLen); DSPEngine::instance()->addAudioSink(&m_audioFifo); } SSBDemod::~SSBDemod() { - if (SSBFilter) - { - delete SSBFilter; - } + if (SSBFilter) delete SSBFilter; + if (DSBFilter) delete DSBFilter; DSPEngine::instance()->removeAudioSink(&m_audioFifo); } @@ -84,7 +84,7 @@ void SSBDemod::configure(MessageQueue* messageQueue, void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly) { Complex ci; - fftfilt::cmplx *sideband, sum; + fftfilt::cmplx *sideband; Real avg; int n_out; @@ -101,68 +101,81 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto if(m_interpolator.interpolate(&m_sampleDistanceRemain, c, &ci)) { - n_out = SSBFilter->runSSB(ci, &sideband, m_usb); + if (m_dsb) + { + n_out = DSBFilter->runDSB(ci, &sideband); + } + else + { + n_out = SSBFilter->runSSB(ci, &sideband, m_usb); + } + + for (int i = 0; i < n_out; i++) + { + // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display + // smart decimation with bit gain using float arithmetic (23 bits significand) + + m_sum += sideband[i]; + + if (!(m_undersampleCount++ & decim_mask)) + { + m_sum /= decim; + m_magsq = (m_sum.real() * m_sum.real() + m_sum.imag() * m_sum.imag())/ (1<<30); + + if (!m_dsb & !m_usb) + { // invert spectrum for LSB + m_sampleBuffer.push_back(Sample(m_sum.imag(), m_sum.real())); + } + else + { + m_sampleBuffer.push_back(Sample(m_sum.real(), m_sum.imag())); + } + + m_sum = 0; + } + + if (m_audioBinaual) + { + if (m_audioFlipChannels) + { + m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].imag() * m_volume * 100); + m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].real() * m_volume * 100); + } + else + { + m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].real() * m_volume * 100); + m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].imag() * m_volume * 100); + } + } + else + { + Real demod = (sideband[i].real() + sideband[i].imag()) * 0.7; + qint16 sample = (qint16)(demod * m_volume * 100); + m_audioBuffer[m_audioBufferFill].l = sample; + m_audioBuffer[m_audioBufferFill].r = sample; + } + + ++m_audioBufferFill; + + if (m_audioBufferFill >= m_audioBuffer.size()) + { + uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); + + if (res != m_audioBufferFill) + { + qDebug("lost %u samples", m_audioBufferFill - res); + } + + m_audioBufferFill = 0; + } + } + m_sampleDistanceRemain += (Real)m_sampleRate / m_audioSampleRate; } else { n_out = 0; } - - for (int i = 0; i < n_out; i++) - { - // Downsample by 2^(m_scaleLog2 - 1) for SSB band spectrum display - // smart decimation with bit gain using float arithmetic (23 bits significand) - - sum += sideband[i]; - - if (!(m_undersampleCount++ & decim_mask)) - { - Real avgr = sum.real() / decim; - Real avgi = sum.imag() / decim; - m_magsq = (avgr * avgr + avgi * avgi) / (1<<30); - //avg = (sum.real() + sum.imag()) * 0.7 * 32768.0 / decim; - avg = (avgr + avgi) * 0.7; - m_sampleBuffer.push_back(Sample(avg, 0.0)); - sum.real() = 0.0; - sum.imag() = 0.0; - } - - if (m_audioBinaual) - { - if (m_audioFlipChannels) - { - m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].imag() * m_volume * 100); - m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].real() * m_volume * 100); - } - else - { - m_audioBuffer[m_audioBufferFill].r = (qint16)(sideband[i].real() * m_volume * 100); - m_audioBuffer[m_audioBufferFill].l = (qint16)(sideband[i].imag() * m_volume * 100); - } - } - else - { - Real demod = (sideband[i].real() + sideband[i].imag()) * 0.7; - qint16 sample = (qint16)(demod * m_volume * 100); - m_audioBuffer[m_audioBufferFill].l = sample; - m_audioBuffer[m_audioBufferFill].r = sample; - } - - ++m_audioBufferFill; - - if (m_audioBufferFill >= m_audioBuffer.size()) - { - uint res = m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 1); - - if (res != m_audioBufferFill) - { - qDebug("lost %u samples", m_audioBufferFill - res); - } - - m_audioBufferFill = 0; - } - } } if (m_audioFifo.write((const quint8*)&m_audioBuffer[0], m_audioBufferFill, 0) != m_audioBufferFill) @@ -173,7 +186,7 @@ void SSBDemod::feed(const SampleVector::const_iterator& begin, const SampleVecto if(m_sampleSink != 0) { - m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), true); + m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), !m_dsb); } m_sampleBuffer.clear(); @@ -239,6 +252,7 @@ bool SSBDemod::handleMessage(const Message& cmd) m_interpolator.create(16, m_sampleRate, band * 2.0f); SSBFilter->create_filter(m_LowCutoff / (float) m_audioSampleRate, m_Bandwidth / (float) m_audioSampleRate); + DSBFilter->create_dsb_filter((2*m_Bandwidth) / m_sampleRate); m_volume = cfg.getVolume(); m_volume *= m_volume * 0.1; diff --git a/plugins/channel/ssb/ssbdemod.h b/plugins/channel/ssb/ssbdemod.h index c2215fd08..749ab406d 100644 --- a/plugins/channel/ssb/ssbdemod.h +++ b/plugins/channel/ssb/ssbdemod.h @@ -43,6 +43,7 @@ public: bool audioFlipChannels, bool dsb); + int getSampleRate() const { return m_sampleRate; } virtual void feed(const SampleVector::const_iterator& begin, const SampleVector::const_iterator& end, bool positiveOnly); virtual void start(); virtual void stop(); @@ -112,6 +113,7 @@ private: Real m_LowCutoff; Real m_volume; int m_spanLog2; + fftfilt::cmplx m_sum; int m_undersampleCount; int m_sampleRate; int m_frequency; @@ -125,6 +127,7 @@ private: Interpolator m_interpolator; Real m_sampleDistanceRemain; fftfilt* SSBFilter; + fftfilt* DSBFilter; SampleSink* m_sampleSink; SampleVector m_sampleBuffer; diff --git a/plugins/channel/ssb/ssbdemodgui.cpp b/plugins/channel/ssb/ssbdemodgui.cpp index f82291702..556f9c68a 100644 --- a/plugins/channel/ssb/ssbdemodgui.cpp +++ b/plugins/channel/ssb/ssbdemodgui.cpp @@ -167,7 +167,31 @@ void SSBDemodGUI::on_audioFlipChannels_toggled(bool flip) void SSBDemodGUI::on_dsb_toggled(bool dsb) { m_dsb = dsb; - applySettings(); + + if (!m_dsb) + { + if (ui->BW->value() < 0) { + m_channelMarker.setSidebands(ChannelMarker::lsb); + } else { + m_channelMarker.setSidebands(ChannelMarker::usb); + } + + ui->glSpectrum->setCenterFrequency(m_rate/4); + ui->glSpectrum->setSampleRate(m_rate/2); + ui->glSpectrum->setSsbSpectrum(true); + + on_lowCut_valueChanged(m_channelMarker.getLowCutoff()/100); + } + else + { + m_channelMarker.setSidebands(ChannelMarker::dsb); + + ui->glSpectrum->setCenterFrequency(0); + ui->glSpectrum->setSampleRate(m_rate); + ui->glSpectrum->setSsbSpectrum(false); + + applySettings(); + } } void SSBDemodGUI::on_deltaFrequency_changed(quint64 value) @@ -188,13 +212,17 @@ void SSBDemodGUI::on_BW_valueChanged(int value) ui->BWText->setText(tr("%1k").arg(s)); m_channelMarker.setBandwidth(value * 100 * 2); - if (value < 0) + if (!m_dsb) { - m_channelMarker.setSidebands(ChannelMarker::lsb); + if (value < 0) { + m_channelMarker.setSidebands(ChannelMarker::lsb); + } else { + m_channelMarker.setSidebands(ChannelMarker::usb); + } } else { - m_channelMarker.setSidebands(ChannelMarker::usb); + m_channelMarker.setSidebands(ChannelMarker::dsb); } on_lowCut_valueChanged(m_channelMarker.getLowCutoff()/100); @@ -206,25 +234,18 @@ int SSBDemodGUI::getEffectiveLowCutoff(int lowCutoff) int effectiveLowCutoff = lowCutoff; const int guard = 100; - if (ssbBW < 0) - { - if (effectiveLowCutoff < ssbBW + guard) - { + if (ssbBW < 0) { + if (effectiveLowCutoff < ssbBW + guard) { effectiveLowCutoff = ssbBW + guard; } - if (effectiveLowCutoff > 0) - { + if (effectiveLowCutoff > 0) { effectiveLowCutoff = 0; } - } - else - { - if (effectiveLowCutoff > ssbBW - guard) - { + } else { + if (effectiveLowCutoff > ssbBW - guard) { effectiveLowCutoff = ssbBW - guard; } - if (effectiveLowCutoff < 0) - { + if (effectiveLowCutoff < 0) { effectiveLowCutoff = 0; } } @@ -323,6 +344,7 @@ SSBDemodGUI::SSBDemodGUI(PluginAPI* pluginAPI, QWidget* parent) : ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum); applySettings(); + setNewRate(m_spanLog2); } SSBDemodGUI::~SSBDemodGUI() @@ -339,32 +361,26 @@ SSBDemodGUI::~SSBDemodGUI() bool SSBDemodGUI::setNewRate(int spanLog2) { - if ((spanLog2 < 1) || (spanLog2 > 5)) - { + if ((spanLog2 < 0) || (spanLog2 > 6)) { return false; } m_spanLog2 = spanLog2; - m_rate = 48000 / (1<getSampleRate() / (1<BW->value() < -m_rate/100) - { + if (ui->BW->value() < -m_rate/100) { ui->BW->setValue(-m_rate/100); m_channelMarker.setBandwidth(-m_rate*2); - } - else if (ui->BW->value() > m_rate/100) - { + } else if (ui->BW->value() > m_rate/100) { ui->BW->setValue(m_rate/100); m_channelMarker.setBandwidth(m_rate*2); } - if (ui->lowCut->value() < -m_rate/100) - { + if (ui->lowCut->value() < -m_rate/100) { ui->lowCut->setValue(-m_rate/100); m_channelMarker.setLowCutoff(-m_rate); - } - else if (ui->lowCut->value() > m_rate/100) - { + } else if (ui->lowCut->value() > m_rate/100) { ui->lowCut->setValue(m_rate/100); m_channelMarker.setLowCutoff(m_rate); } @@ -377,8 +393,26 @@ bool SSBDemodGUI::setNewRate(int spanLog2) QString s = QString::number(m_rate/1000.0, 'f', 1); ui->spanText->setText(tr("%1k").arg(s)); - ui->glSpectrum->setCenterFrequency(m_rate/2); - ui->glSpectrum->setSampleRate(m_rate); + if (!m_dsb) + { + if (ui->BW->value() < 0) { + m_channelMarker.setSidebands(ChannelMarker::lsb); + } else { + m_channelMarker.setSidebands(ChannelMarker::usb); + } + + ui->glSpectrum->setCenterFrequency(m_rate/4); + ui->glSpectrum->setSampleRate(m_rate/2); + ui->glSpectrum->setSsbSpectrum(true); + } + else + { + m_channelMarker.setSidebands(ChannelMarker::dsb); + + ui->glSpectrum->setCenterFrequency(0); + ui->glSpectrum->setSampleRate(m_rate); + ui->glSpectrum->setSsbSpectrum(false); + } return true; } diff --git a/plugins/channel/ssb/ssbdemodgui.ui b/plugins/channel/ssb/ssbdemodgui.ui index eeaa90c47..d0bdcbfb4 100644 --- a/plugins/channel/ssb/ssbdemodgui.ui +++ b/plugins/channel/ssb/ssbdemodgui.ui @@ -201,6 +201,9 @@ true + + false +