From dcd87b5ff8f0eb998d66a1eda246ac93ac76726c Mon Sep 17 00:00:00 2001 From: f4exb Date: Wed, 14 Dec 2016 00:14:52 +0100 Subject: [PATCH] SSB Modulator: interim state (6) --- plugins/channeltx/modssb/ssbmod.cpp | 113 ++++++++++++++++++++++++- plugins/channeltx/modssb/ssbmod.h | 15 +++- plugins/channeltx/modssb/ssbmodgui.cpp | 7 +- plugins/channeltx/modssb/ssbmodgui.h | 2 + 4 files changed, 129 insertions(+), 8 deletions(-) diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 30538df1f..7a8ff9ada 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -36,7 +36,8 @@ MESSAGE_CLASS_DEFINITION(SSBMod::MsgReportFileSourceStreamTiming, Message) const int SSBMod::m_levelNbSamples = 480; // every 10ms const int SSBMod::m_ssbFftLen = 1024; -SSBMod::SSBMod() : +SSBMod::SSBMod(BasebandSampleSink* sampleSink) : + m_sampleSink(sampleSink), m_SSBFilter(0), m_DSBFilter(0), m_SSBFilterBuffer(0), @@ -71,6 +72,15 @@ SSBMod::SSBMod() : //m_audioBuffer.resize(1<<14); //m_audioBufferFill = 0; +// m_magsqSpectrum = 0.0f; +// m_magsqSum = 0.0f; +// m_magsqPeak = 0.0f; +// m_magsqCount = 0; + m_sum.real(0.0f); + m_sum.imag(0.0f); + m_undersampleCount = 0; + m_sumCount = 0; + m_movingAverage.resize(16, 0); m_volumeAGC.resize(4096, 0.003, 0); m_magsq = 0.0; @@ -157,7 +167,7 @@ void SSBMod::pull(Sample& sample) m_interpolatorDistanceRemain += m_interpolatorDistance; - ci *= 16368.0f; //scaling + ci *= 29204.0f; //scaling at -1 dB to account for filter overshoot // ci *= m_carrierNco.nextIQ(); // shift to carrier frequency m_settingsMutex.unlock(); @@ -188,7 +198,10 @@ void SSBMod::pullAF(Complex& sample) int16_t audioSample[2]; Complex ci; fftfilt::cmplx *filtered; - int n_out; + int n_out = 0; + + int decim = 1<<(m_running.m_spanLog2 - 1); + unsigned char decim_mask = decim - 1; // counter LSB bit mask for decimation by 2^(m_scaleLog2 - 1) switch (m_afInput) { @@ -304,6 +317,98 @@ void SSBMod::pullAF(Complex& sample) sample = m_SSBFilterBuffer[m_SSBFilterBufferIndex]; m_SSBFilterBufferIndex++; } + + if (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) + + m_sum += filtered[i]; + + if (!(m_undersampleCount++ & decim_mask)) + { + Real avgr = m_sum.real() / decim; + Real avgi = m_sum.imag() / decim; +// m_magsqSpectrum = (avgr * avgr + avgi * avgi) / (1<<30); +// +// m_magsqSum += m_magsqSpectrum; +// +// if (m_magsqSpectrum > m_magsqPeak) +// { +// m_magsqPeak = m_magsqSpectrum; +// } +// +// m_magsqCount++; + + if (!m_running.m_dsb & !m_running.m_usb) + { // invert spectrum for LSB + m_sampleBuffer.push_back(Sample(avgi, avgr)); + } + else + { + m_sampleBuffer.push_back(Sample(avgr, avgi)); + } + + m_sum.real(0.0); + m_sum.imag(0.0); + } + } + } + } // Real audio + else if ((m_afInput == SSBModInputTone) || (m_afInput == SSBModInputCWTone)) // tone + { + m_sum += sample; + + if (!(m_undersampleCount++ & decim_mask)) + { + Real avgr = m_sum.real() / decim; + Real avgi = m_sum.imag() / decim; +// m_magsqSpectrum = (avgr * avgr + avgi * avgi) / (1<<30); +// +// m_magsqSum += m_magsqSpectrum; +// +// if (m_magsqSpectrum > m_magsqPeak) +// { +// m_magsqPeak = m_magsqSpectrum; +// } +// +// m_magsqCount++; + + if (!m_running.m_dsb & !m_running.m_usb) + { // invert spectrum for LSB + m_sampleBuffer.push_back(Sample(avgi, avgr)); + } + else + { + m_sampleBuffer.push_back(Sample(avgr, avgi)); + } + + m_sum.real(0.0); + m_sum.imag(0.0); + } + + if (m_sumCount < (m_running.m_dsb ? m_ssbFftLen : m_ssbFftLen>>1)) + { + n_out = 0; + m_sumCount++; + } + else + { + n_out = m_sumCount; + m_sumCount = 0; + } + } + + if (n_out > 0) + { + if (m_sampleSink != 0) + { + m_sampleSink->feed(m_sampleBuffer.begin(), m_sampleBuffer.end(), !m_running.m_dsb); + } + + m_sampleBuffer.clear(); } } @@ -544,7 +649,7 @@ void SSBMod::openFileStream() m_sampleRate = 48000; // fixed rate m_recordLength = m_fileSize / (sizeof(Real) * m_sampleRate); - qDebug() << "AMMod::openFileStream: " << m_fileName.toStdString().c_str() + qDebug() << "SSBMod::openFileStream: " << m_fileName.toStdString().c_str() << " fileSize: " << m_fileSize << "bytes" << " length: " << m_recordLength << " seconds"; diff --git a/plugins/channeltx/modssb/ssbmod.h b/plugins/channeltx/modssb/ssbmod.h index d0fda3250..cdf0c8386 100644 --- a/plugins/channeltx/modssb/ssbmod.h +++ b/plugins/channeltx/modssb/ssbmod.h @@ -23,6 +23,7 @@ #include #include "dsp/basebandsamplesource.h" +#include "dsp/basebandsamplesink.h" #include "dsp/nco.h" #include "dsp/interpolator.h" #include "dsp/movingaverage.h" @@ -173,7 +174,7 @@ public: //================================================================= - SSBMod(); + SSBMod(BasebandSampleSink* sampleSink); ~SSBMod(); void configure(MessageQueue* messageQueue, @@ -350,6 +351,17 @@ private: int m_DSBFilterBufferIndex; static const int m_ssbFftLen; + BasebandSampleSink* m_sampleSink; + SampleVector m_sampleBuffer; + +// Real m_magsqSpectrum; +// Real m_magsqSum; +// Real m_magsqPeak; +// int m_magsqCount; + fftfilt::cmplx m_sum; + int m_undersampleCount; + int m_sumCount; + Real m_magsq; MovingAverage m_movingAverage; SimpleAGC m_volumeAGC; @@ -358,7 +370,6 @@ private: //uint m_audioBufferFill; AudioFifo m_audioFifo; - SampleVector m_sampleBuffer; QMutex m_settingsMutex; std::ifstream m_ifstream; diff --git a/plugins/channeltx/modssb/ssbmodgui.cpp b/plugins/channeltx/modssb/ssbmodgui.cpp index 934e87baf..4dd06cb66 100644 --- a/plugins/channeltx/modssb/ssbmodgui.cpp +++ b/plugins/channeltx/modssb/ssbmodgui.cpp @@ -24,7 +24,7 @@ #include "device/devicesinkapi.h" #include "dsp/upchannelizer.h" - +#include "dsp/spectrumvis.h" #include "dsp/threadedbasebandsamplesource.h" #include "ui_ssbmodgui.h" #include "plugin/pluginapi.h" @@ -446,7 +446,8 @@ SSBModGUI::SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* pa connect(this, SIGNAL(widgetRolled(QWidget*,bool)), this, SLOT(onWidgetRolled(QWidget*,bool))); connect(this, SIGNAL(menuDoubleClickEvent()), this, SLOT(onMenuDoubleClicked())); - m_ssbMod = new SSBMod(); + m_spectrumVis = new SpectrumVis(ui->glSpectrum); + m_ssbMod = new SSBMod(m_spectrumVis); m_channelizer = new UpChannelizer(m_ssbMod); m_threadedChannelizer = new ThreadedBasebandSampleSource(m_channelizer, this); //m_pluginAPI->addThreadedSink(m_threadedChannelizer); @@ -479,6 +480,7 @@ SSBModGUI::SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* pa m_deviceAPI->addRollupWidget(this); ui->cwKeyerGUI->setBuddies(m_ssbMod->getInputMessageQueue(), m_ssbMod->getCWKeyer()); + ui->spectrumGUI->setBuddies(m_spectrumVis->getInputMessageQueue(), m_spectrumVis, ui->glSpectrum); applySettings(); setNewRate(m_spanLog2); @@ -494,6 +496,7 @@ SSBModGUI::~SSBModGUI() delete m_threadedChannelizer; delete m_channelizer; delete m_ssbMod; + delete m_spectrumVis; //delete m_channelMarker; delete ui; } diff --git a/plugins/channeltx/modssb/ssbmodgui.h b/plugins/channeltx/modssb/ssbmodgui.h index 44aa8f55c..4dc73e3f1 100644 --- a/plugins/channeltx/modssb/ssbmodgui.h +++ b/plugins/channeltx/modssb/ssbmodgui.h @@ -29,6 +29,7 @@ class DeviceSinkAPI; class ThreadedBasebandSampleSource; class UpChannelizer; class SSBMod; +class SpectrumVis; namespace Ui { class SSBModGUI; @@ -93,6 +94,7 @@ private: ThreadedBasebandSampleSource* m_threadedChannelizer; UpChannelizer* m_channelizer; + SpectrumVis* m_spectrumVis; SSBMod* m_ssbMod; MovingAverage m_channelPowerDbAvg;