From fa1c413e4f87ed84404f5a42949fe1e8f5479735 Mon Sep 17 00:00:00 2001 From: f4exb Date: Tue, 13 Dec 2016 23:00:09 +0100 Subject: [PATCH] SSB Modulator: interim state (5) --- plugins/channeltx/modssb/ssbmod.cpp | 21 ++++---- plugins/channeltx/modssb/ssbmodgui.cpp | 72 ++++++++++++++++++++++++++ plugins/channeltx/modssb/ssbmodgui.h | 3 ++ 3 files changed, 86 insertions(+), 10 deletions(-) diff --git a/plugins/channeltx/modssb/ssbmod.cpp b/plugins/channeltx/modssb/ssbmod.cpp index 6cdc32f07..30538df1f 100644 --- a/plugins/channeltx/modssb/ssbmod.cpp +++ b/plugins/channeltx/modssb/ssbmod.cpp @@ -55,14 +55,19 @@ SSBMod::SSBMod() : { setObjectName("SSBMod"); - m_config.m_outputSampleRate = 48000; + m_SSBFilter = new fftfilt(m_config.m_lowCutoff / m_config.m_audioSampleRate, m_config.m_bandwidth / m_config.m_audioSampleRate, m_ssbFftLen); + m_DSBFilter = new fftfilt((2.0f * m_config.m_bandwidth) / m_config.m_audioSampleRate, 2 * m_ssbFftLen); + m_SSBFilterBuffer = new Complex[m_ssbFftLen>>1]; // filter returns data exactly half of its size + m_DSBFilterBuffer = new Complex[m_ssbFftLen]; + memset(m_SSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen>>1)); + memset(m_DSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen)); + + m_config.m_outputSampleRate = 48000; m_config.m_inputFrequencyOffset = 0; m_config.m_bandwidth = 12500; m_config.m_toneFrequency = 1000.0f; m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate(); - apply(); - //m_audioBuffer.resize(1<<14); //m_audioBufferFill = 0; @@ -78,12 +83,7 @@ SSBMod::SSBMod() : m_cwKeyer.setWPM(13); m_cwKeyer.setMode(CWKeyer::CWNone); - m_SSBFilter = new fftfilt(m_config.m_lowCutoff / m_config.m_audioSampleRate, m_config.m_bandwidth / m_config.m_audioSampleRate, m_ssbFftLen); - m_DSBFilter = new fftfilt((2.0f * m_config.m_bandwidth) / m_config.m_audioSampleRate, 2 * m_ssbFftLen); - m_SSBFilterBuffer = new Complex[m_ssbFftLen>>1]; // filter returns data exactly half of its size - m_DSBFilterBuffer = new Complex[m_ssbFftLen]; - memset(m_SSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen>>1)); - memset(m_DSBFilterBuffer, 0, sizeof(Complex)*(m_ssbFftLen)); + apply(); } SSBMod::~SSBMod() @@ -157,7 +157,8 @@ void SSBMod::pull(Sample& sample) m_interpolatorDistanceRemain += m_interpolatorDistance; - ci *= m_carrierNco.nextIQ(); // shift to carrier frequency + ci *= 16368.0f; //scaling +// ci *= m_carrierNco.nextIQ(); // shift to carrier frequency m_settingsMutex.unlock(); diff --git a/plugins/channeltx/modssb/ssbmodgui.cpp b/plugins/channeltx/modssb/ssbmodgui.cpp index fafb87f78..934e87baf 100644 --- a/plugins/channeltx/modssb/ssbmodgui.cpp +++ b/plugins/channeltx/modssb/ssbmodgui.cpp @@ -233,6 +233,36 @@ void SSBModGUI::on_deltaFrequency_changed(quint64 value) } } +void SSBModGUI::on_dsb_toggled(bool checked) +{ + if (!checked) + { + 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(); + } + + setNewRate(m_spanLog2); +} + void SSBModGUI::on_BW_valueChanged(int value) { ui->BWText->setText(QString("%1 kHz").arg(value / 10.0, 0, 'f', 1)); @@ -240,6 +270,48 @@ void SSBModGUI::on_BW_valueChanged(int value) applySettings(); } +void SSBModGUI::on_lowCut_valueChanged(int value) +{ + int lowCutoff = getEffectiveLowCutoff(value * 100); + m_channelMarker.setLowCutoff(lowCutoff); + QString s = QString::number(lowCutoff/1000.0, 'f', 1); + ui->lowCutText->setText(tr("%1k").arg(s)); + ui->lowCut->setValue(lowCutoff/100); + applySettings(); +} + +int SSBModGUI::getEffectiveLowCutoff(int lowCutoff) +{ + int ssbBW = m_channelMarker.getBandwidth() / 2; + int effectiveLowCutoff = lowCutoff; + const int guard = 100; + + if (ssbBW < 0) + { + if (effectiveLowCutoff < ssbBW + guard) + { + effectiveLowCutoff = ssbBW + guard; + } + if (effectiveLowCutoff > 0) + { + effectiveLowCutoff = 0; + } + } + else + { + if (effectiveLowCutoff > ssbBW - guard) + { + effectiveLowCutoff = ssbBW - guard; + } + if (effectiveLowCutoff < 0) + { + effectiveLowCutoff = 0; + } + } + + return effectiveLowCutoff; +} + void SSBModGUI::on_toneFrequency_valueChanged(int value) { ui->toneFrequencyText->setText(QString("%1k").arg(value / 100.0, 0, 'f', 2)); diff --git a/plugins/channeltx/modssb/ssbmodgui.h b/plugins/channeltx/modssb/ssbmodgui.h index 418245ca6..44aa8f55c 100644 --- a/plugins/channeltx/modssb/ssbmodgui.h +++ b/plugins/channeltx/modssb/ssbmodgui.h @@ -60,7 +60,9 @@ private slots: void on_deltaFrequency_changed(quint64 value); void on_deltaMinus_toggled(bool minus); + void on_dsb_toggled(bool checked); void on_BW_valueChanged(int value); + void on_lowCut_valueChanged(int value); void on_volume_valueChanged(int value); void on_audioMute_toggled(bool checked); void on_tone_toggled(bool checked); @@ -105,6 +107,7 @@ private: explicit SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL); virtual ~SSBModGUI(); + int getEffectiveLowCutoff(int lowCutoff); bool setNewRate(int spanLog2); void blockApplySettings(bool block);