1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-23 00:18:37 -05:00

SSB Modulator: interim state (1)

This commit is contained in:
f4exb 2016-12-12 22:02:24 +01:00
parent d10209c223
commit 25e2a9877b
4 changed files with 178 additions and 50 deletions

View File

@ -50,7 +50,7 @@ SSBMod::SSBMod() :
m_config.m_outputSampleRate = 48000; m_config.m_outputSampleRate = 48000;
m_config.m_inputFrequencyOffset = 0; m_config.m_inputFrequencyOffset = 0;
m_config.m_rfBandwidth = 12500; m_config.m_bandwidth = 12500;
m_config.m_toneFrequency = 1000.0f; m_config.m_toneFrequency = 1000.0f;
m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate(); m_config.m_audioSampleRate = DSPEngine::instance()->getAudioSampleRate();
@ -78,13 +78,27 @@ SSBMod::~SSBMod()
} }
void SSBMod::configure(MessageQueue* messageQueue, void SSBMod::configure(MessageQueue* messageQueue,
Real rfBandwidth, Real bandwidth,
Real lowCutoff,
float toneFrequency, float toneFrequency,
float volumeFactor, float volumeFactor,
int spanLog2,
bool audioBinaural,
bool audioFlipChannels,
bool dsb,
bool audioMute, bool audioMute,
bool playLoop) bool playLoop)
{ {
Message* cmd = MsgConfigureSSBMod::create(rfBandwidth, toneFrequency, volumeFactor, audioMute, playLoop); Message* cmd = MsgConfigureSSBMod::create(bandwidth,
lowCutoff,
toneFrequency,
volumeFactor,
spanLog2,
audioBinaural,
audioFlipChannels,
dsb,
audioMute,
playLoop);
messageQueue->push(cmd); messageQueue->push(cmd);
} }
@ -247,20 +261,60 @@ bool SSBMod::handleMessage(const Message& cmd)
} }
else if (MsgConfigureSSBMod::match(cmd)) else if (MsgConfigureSSBMod::match(cmd))
{ {
MsgConfigureSSBMod& cfg = (MsgConfigureSSBMod&) cmd; float band, lowCutoff;
MsgConfigureSSBMod& cfg = (MsgConfigureSSBMod&) cmd;
m_settingsMutex.lock();
band = cfg.getBandwidth();
lowCutoff = cfg.getLoCutoff();
if (band < 0) // negative means LSB
{
band = -band; // turn to positive
lowCutoff = -lowCutoff;
m_config.m_usb = false; // and take note of side band
}
else
{
m_config.m_usb = true;
}
if (band < 100.0f) // at least 100 Hz
{
band = 100.0f;
lowCutoff = 0;
}
m_config.m_bandwidth = band;
m_config.m_lowCutoff = lowCutoff;
// TODO: move to apply
SSBFilter->create_filter(m_config.m_lowCutoff / (float) m_config.m_audioSampleRate, m_config.m_bandwidth / (float) m_config.m_audioSampleRate);
DSBFilter->create_dsb_filter((2.0f * m_config.m_bandwidth) / (float) m_config.m_audioSampleRate);
m_config.m_rfBandwidth = cfg.getRFBandwidth();
m_config.m_toneFrequency = cfg.getToneFrequency(); m_config.m_toneFrequency = cfg.getToneFrequency();
m_config.m_volumeFactor = cfg.getVolumeFactor(); m_config.m_volumeFactor = cfg.getVolumeFactor();
m_config.m_spanLog2 = cfg.getSpanLog2();
m_config.m_audioBinaural = cfg.getAudioBinaural();
m_config.m_audioFlipChannels = cfg.getAudioFlipChannels();
m_config.m_dsb = cfg.getDSB();
m_config.m_audioMute = cfg.getAudioMute(); m_config.m_audioMute = cfg.getAudioMute();
m_config.m_playLoop = cfg.getPlayLoop(); m_config.m_playLoop = cfg.getPlayLoop();
apply(); apply();
m_settingsMutex.unlock();
qDebug() << "SSBMod::handleMessage: MsgConfigureSSBMod:" qDebug() << "SSBMod::handleMessage: MsgConfigureSSBMod:"
<< " m_rfBandwidth: " << m_config.m_rfBandwidth << " m_bandwidth: " << m_config.m_bandwidth
<< " m_lowCutoff: " << m_config.m_lowCutoff
<< " m_toneFrequency: " << m_config.m_toneFrequency << " m_toneFrequency: " << m_config.m_toneFrequency
<< " m_volumeFactor: " << m_config.m_volumeFactor << " m_volumeFactor: " << m_config.m_volumeFactor
<< " m_spanLog2: " << m_config.m_spanLog2
<< " m_audioBinaural: " << m_config.m_audioBinaural
<< " m_audioFlipChannels: " << m_config.m_audioFlipChannels
<< " m_dsb: " << m_config.m_dsb
<< " m_audioMute: " << m_config.m_audioMute << " m_audioMute: " << m_config.m_audioMute
<< " m_playLoop: " << m_config.m_playLoop; << " m_playLoop: " << m_config.m_playLoop;
@ -322,14 +376,14 @@ void SSBMod::apply()
} }
if((m_config.m_outputSampleRate != m_running.m_outputSampleRate) || if((m_config.m_outputSampleRate != m_running.m_outputSampleRate) ||
(m_config.m_rfBandwidth != m_running.m_rfBandwidth) || (m_config.m_bandwidth != m_running.m_bandwidth) ||
(m_config.m_audioSampleRate != m_running.m_audioSampleRate)) (m_config.m_audioSampleRate != m_running.m_audioSampleRate))
{ {
m_settingsMutex.lock(); m_settingsMutex.lock();
m_interpolatorDistanceRemain = 0; m_interpolatorDistanceRemain = 0;
m_interpolatorConsumed = false; m_interpolatorConsumed = false;
m_interpolatorDistance = (Real) m_config.m_audioSampleRate / (Real) m_config.m_outputSampleRate; m_interpolatorDistance = (Real) m_config.m_audioSampleRate / (Real) m_config.m_outputSampleRate;
m_interpolator.create(48, m_config.m_audioSampleRate, m_config.m_rfBandwidth / 2.2, 3.0); m_interpolator.create(48, m_config.m_audioSampleRate, m_config.m_bandwidth / 2.2, 3.0);
m_settingsMutex.unlock(); m_settingsMutex.unlock();
} }
@ -348,10 +402,15 @@ void SSBMod::apply()
m_running.m_outputSampleRate = m_config.m_outputSampleRate; m_running.m_outputSampleRate = m_config.m_outputSampleRate;
m_running.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset; m_running.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset;
m_running.m_rfBandwidth = m_config.m_rfBandwidth; m_running.m_bandwidth = m_config.m_bandwidth;
m_running.m_lowCutoff = m_config.m_lowCutoff;
m_running.m_toneFrequency = m_config.m_toneFrequency; m_running.m_toneFrequency = m_config.m_toneFrequency;
m_running.m_volumeFactor = m_config.m_volumeFactor; m_running.m_volumeFactor = m_config.m_volumeFactor;
m_running.m_audioSampleRate = m_config.m_audioSampleRate; m_running.m_audioSampleRate = m_config.m_audioSampleRate;
m_running.m_spanLog2 = m_config.m_spanLog2;
m_running.m_audioBinaural = m_config.m_audioBinaural;
m_running.m_audioFlipChannels = m_config.m_audioFlipChannels;
m_running.m_dsb = m_config.m_dsb;
m_running.m_audioMute = m_config.m_audioMute; m_running.m_audioMute = m_config.m_audioMute;
m_running.m_playLoop = m_config.m_playLoop; m_running.m_playLoop = m_config.m_playLoop;
} }

View File

@ -27,6 +27,7 @@
#include "dsp/interpolator.h" #include "dsp/interpolator.h"
#include "dsp/movingaverage.h" #include "dsp/movingaverage.h"
#include "dsp/agc.h" #include "dsp/agc.h"
#include "dsp/fftfilt.h"
#include "dsp/cwkeyer.h" #include "dsp/cwkeyer.h"
#include "audio/audiofifo.h" #include "audio/audiofifo.h"
#include "util/message.h" #include "util/message.h"
@ -176,10 +177,15 @@ public:
~SSBMod(); ~SSBMod();
void configure(MessageQueue* messageQueue, void configure(MessageQueue* messageQueue,
Real rfBandwidth, Real bandwidth,
Real lowCutoff,
float toneFrequency, float toneFrequency,
float volumeFactor, float volumeFactor,
bool audioMute, int spanLog2,
bool audioBinaural,
bool audioFlipChannels,
bool dsb,
bool audioMute,
bool playLoop); bool playLoop);
virtual void pull(Sample& sample); virtual void pull(Sample& sample);
@ -207,29 +213,71 @@ private:
MESSAGE_CLASS_DECLARATION MESSAGE_CLASS_DECLARATION
public: public:
Real getRFBandwidth() const { return m_rfBandwidth; } Real getBandwidth() const { return m_bandwidth; }
Real getLowCutoff() const { return m_lowCutoff; }
float getToneFrequency() const { return m_toneFrequency; } float getToneFrequency() const { return m_toneFrequency; }
float getVolumeFactor() const { return m_volumeFactor; } float getVolumeFactor() const { return m_volumeFactor; }
int getSpanLog2() const { return m_spanLog2; }
bool getAudioBinaural() const { return m_audioBinaural; }
bool getAudioFlipChannels() const { return m_audioFlipChannels; }
bool getDSB() const { return m_dsb; }
bool getAudioMute() const { return m_audioMute; } bool getAudioMute() const { return m_audioMute; }
bool getPlayLoop() const { return m_playLoop; } bool getPlayLoop() const { return m_playLoop; }
static MsgConfigureSSBMod* create(Real rfBandwidth, float toneFreqeuncy, float volumeFactor, bool audioMute, bool playLoop) static MsgConfigureSSBMod* create(Real bandwidth,
Real lowCutoff,
float toneFrequency,
float volumeFactor,
int spanLog2,
bool audioBinaural,
bool audioFlipChannels,
bool dsb,
bool audioMute,
bool playLoop)
{ {
return new MsgConfigureSSBMod(rfBandwidth, toneFreqeuncy, volumeFactor, audioMute, playLoop); return new MsgConfigureSSBMod(bandwidth,
lowCutoff,
toneFrequency,
volumeFactor,
spanLog2,
audioBinaural,
audioFlipChannels,
dsb,
audioMute,
playLoop);
} }
private: private:
Real m_rfBandwidth; Real m_bandwidth;
Real m_lowCutoff;
float m_toneFrequency; float m_toneFrequency;
float m_volumeFactor; float m_volumeFactor;
int m_spanLog2;
bool m_audioBinaural;
bool m_audioFlipChannels;
bool m_dsb;
bool m_audioMute; bool m_audioMute;
bool m_playLoop; bool m_playLoop;
MsgConfigureSSBMod(Real rfBandwidth, float toneFrequency, float volumeFactor, bool audioMute, bool playLoop) : MsgConfigureSSBMod(Real bandwidth,
Real lowCutoff,
float toneFrequency,
float volumeFactor,
int spanLog2,
bool audioBinaural,
bool audioFlipChannels,
bool dsb,
bool audioMute,
bool playLoop) :
Message(), Message(),
m_rfBandwidth(rfBandwidth), m_bandwidth(bandwidth),
m_lowCutoff(lowCutoff),
m_toneFrequency(toneFrequency), m_toneFrequency(toneFrequency),
m_volumeFactor(volumeFactor), m_volumeFactor(volumeFactor),
m_spanLog2(spanLog2),
m_audioBinaural(audioBinaural),
m_audioFlipChannels(audioFlipChannels),
m_dsb(dsb),
m_audioMute(audioMute), m_audioMute(audioMute),
m_playLoop(playLoop) m_playLoop(playLoop)
{ } { }
@ -251,20 +299,32 @@ private:
struct Config { struct Config {
int m_outputSampleRate; int m_outputSampleRate;
qint64 m_inputFrequencyOffset; qint64 m_inputFrequencyOffset;
Real m_rfBandwidth; Real m_bandwidth;
Real m_lowCutoff;
bool m_usb;
float m_toneFrequency; float m_toneFrequency;
float m_volumeFactor; float m_volumeFactor;
quint32 m_audioSampleRate; quint32 m_audioSampleRate;
bool m_audioMute; int m_spanLog2;
bool m_audioBinaural;
bool m_audioFlipChannels;
bool m_dsb;
bool m_audioMute;
bool m_playLoop; bool m_playLoop;
Config() : Config() :
m_outputSampleRate(-1), m_outputSampleRate(0),
m_inputFrequencyOffset(0), m_inputFrequencyOffset(0),
m_rfBandwidth(-1), m_bandwidth(3000.0f),
m_toneFrequency(100), m_lowCutoff(300.0f),
m_usb(true),
m_toneFrequency(1000.0f),
m_volumeFactor(1.0f), m_volumeFactor(1.0f),
m_audioSampleRate(0), m_audioSampleRate(0),
m_spanLog2(3),
m_audioBinaural(false),
m_audioFlipChannels(false),
m_dsb(false),
m_audioMute(false), m_audioMute(false),
m_playLoop(false) m_playLoop(false)
{ } { }
@ -282,6 +342,8 @@ private:
Real m_interpolatorDistance; Real m_interpolatorDistance;
Real m_interpolatorDistanceRemain; Real m_interpolatorDistanceRemain;
bool m_interpolatorConsumed; bool m_interpolatorConsumed;
fftfilt* SSBFilter;
fftfilt* DSBFilter;
Real m_magsq; Real m_magsq;
MovingAverage<Real> m_movingAverage; MovingAverage<Real> m_movingAverage;

View File

@ -73,14 +73,21 @@ void SSBModGUI::resetToDefaults()
ui->BW->setValue(30); ui->BW->setValue(30);
ui->lowCut->setValue(3); ui->lowCut->setValue(3);
ui->spanLog2->setValue(3); ui->spanLog2->setValue(3);
m_spanLog2 = 3;
ui->toneFrequency->setValue(100); ui->toneFrequency->setValue(100);
ui->deltaFrequency->setValue(0); ui->deltaFrequency->setValue(0);
m_audioBinaural = false; ui->audioBinaural->setChecked(false);
m_audioFlipChannels = false; ui->audioFlipChannels->setChecked(false);
m_dsb = false; ui->dsb->setChecked(false);
ui->audioMute->setChecked(false);
ui->play->setEnabled(false);
ui->play->setChecked(false);
ui->tone->setChecked(false);
ui->morseKeyer->setChecked(false);
ui->mic->setChecked(false);
blockApplySettings(false); blockApplySettings(false);
applySettings();
} }
QByteArray SSBModGUI::serialize() const QByteArray SSBModGUI::serialize() const
@ -95,9 +102,9 @@ QByteArray SSBModGUI::serialize() const
s.writeBlob(6, ui->cwKeyerGUI->serialize()); s.writeBlob(6, ui->cwKeyerGUI->serialize());
s.writeS32(7, ui->lowCut->value()); s.writeS32(7, ui->lowCut->value());
s.writeS32(8, ui->spanLog2->value()); s.writeS32(8, ui->spanLog2->value());
s.writeBool(9, m_audioBinaural); s.writeBool(9, ui->audioBinaural->isChecked());
s.writeBool(10, m_audioFlipChannels); s.writeBool(10, ui->audioFlipChannels->isChecked());
s.writeBool(11, m_dsb); s.writeBool(11, ui->dsb->isChecked());
return s.final(); return s.final();
} }
@ -109,6 +116,7 @@ bool SSBModGUI::deserialize(const QByteArray& data)
if(!d.isValid()) if(!d.isValid())
{ {
resetToDefaults(); resetToDefaults();
applySettings();
return false; return false;
} }
@ -117,13 +125,14 @@ bool SSBModGUI::deserialize(const QByteArray& data)
QByteArray bytetmp; QByteArray bytetmp;
quint32 u32tmp; quint32 u32tmp;
qint32 tmp; qint32 tmp;
bool booltmp;
blockApplySettings(true); blockApplySettings(true);
m_channelMarker.blockSignals(true); m_channelMarker.blockSignals(true);
d.readS32(1, &tmp, 0); d.readS32(1, &tmp, 0);
m_channelMarker.setCenterFrequency(tmp); m_channelMarker.setCenterFrequency(tmp);
d.readS32(2, &tmp, 4); d.readS32(2, &tmp, 30);
ui->BW->setValue(tmp); ui->BW->setValue(tmp);
d.readS32(3, &tmp, 100); d.readS32(3, &tmp, 100);
ui->toneFrequency->setValue(tmp); ui->toneFrequency->setValue(tmp);
@ -140,15 +149,15 @@ bool SSBModGUI::deserialize(const QByteArray& data)
d.readS32(7, &tmp, 3); d.readS32(7, &tmp, 3);
ui->lowCut->setValue(tmp); ui->lowCut->setValue(tmp);
d.readS32(8, &tmp, 20); d.readS32(8, &tmp, 3);
ui->spanLog2->setValue(tmp); ui->spanLog2->setValue(tmp);
setNewRate(tmp); setNewRate(tmp);
d.readBool(9, &m_audioBinaural); d.readBool(9, &booltmp);
ui->audioBinaural->setChecked(m_audioBinaural); ui->audioBinaural->setChecked(booltmp);
d.readBool(10, &m_audioFlipChannels); d.readBool(10, &booltmp);
ui->audioFlipChannels->setChecked(m_audioFlipChannels); ui->audioFlipChannels->setChecked(booltmp);
d.readBool(11, &m_dsb); d.readBool(11, &booltmp);
ui->dsb->setChecked(m_dsb); ui->dsb->setChecked(booltmp);
blockApplySettings(false); blockApplySettings(false);
m_channelMarker.blockSignals(false); m_channelMarker.blockSignals(false);
@ -159,6 +168,7 @@ bool SSBModGUI::deserialize(const QByteArray& data)
else else
{ {
resetToDefaults(); resetToDefaults();
applySettings();
return false; return false;
} }
} }
@ -370,6 +380,8 @@ SSBModGUI::SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* pa
//m_pluginAPI->addThreadedSink(m_threadedChannelizer); //m_pluginAPI->addThreadedSink(m_threadedChannelizer);
m_deviceAPI->addThreadedSource(m_threadedChannelizer); m_deviceAPI->addThreadedSource(m_threadedChannelizer);
resetToDefaults();
ui->glSpectrum->setCenterFrequency(m_rate/2); ui->glSpectrum->setCenterFrequency(m_rate/2);
ui->glSpectrum->setSampleRate(m_rate); ui->glSpectrum->setSampleRate(m_rate);
ui->glSpectrum->setDisplayWaterfall(true); ui->glSpectrum->setDisplayWaterfall(true);
@ -394,12 +406,6 @@ SSBModGUI::SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* pa
m_deviceAPI->addChannelMarker(&m_channelMarker); m_deviceAPI->addChannelMarker(&m_channelMarker);
m_deviceAPI->addRollupWidget(this); m_deviceAPI->addRollupWidget(this);
ui->play->setEnabled(false);
ui->play->setChecked(false);
ui->tone->setChecked(false);
ui->morseKeyer->setChecked(false);
ui->mic->setChecked(false);
ui->cwKeyerGUI->setBuddies(m_ssbMod->getInputMessageQueue(), m_ssbMod->getCWKeyer()); ui->cwKeyerGUI->setBuddies(m_ssbMod->getInputMessageQueue(), m_ssbMod->getCWKeyer());
applySettings(); applySettings();
@ -462,7 +468,7 @@ bool SSBModGUI::setNewRate(int spanLog2)
//ui->glSpectrum->setCenterFrequency(m_rate/2); //ui->glSpectrum->setCenterFrequency(m_rate/2);
//ui->glSpectrum->setSampleRate(m_rate); //ui->glSpectrum->setSampleRate(m_rate);
if (!m_dsb) if (!ui->dsb->isChecked())
{ {
if (ui->BW->value() < 0) { if (ui->BW->value() < 0) {
m_channelMarker.setSidebands(ChannelMarker::lsb); m_channelMarker.setSidebands(ChannelMarker::lsb);
@ -505,9 +511,14 @@ void SSBModGUI::applySettings()
ui->deltaMinus->setChecked(m_channelMarker.getCenterFrequency() < 0); ui->deltaMinus->setChecked(m_channelMarker.getCenterFrequency() < 0);
m_ssbMod->configure(m_ssbMod->getInputMessageQueue(), m_ssbMod->configure(m_ssbMod->getInputMessageQueue(),
ui->BW->value() * 100.0, ui->BW->value() * 100.0f,
ui->lowCut->value() * 100.0f,
ui->toneFrequency->value() * 10.0f, ui->toneFrequency->value() * 10.0f,
ui->volume->value() / 10.0f , ui->volume->value() / 10.0f,
m_spanLog2,
ui->audioBinaural->isChecked(),
ui->audioFlipChannels->isChecked(),
ui->dsb->isChecked(),
ui->audioMute->isChecked(), ui->audioMute->isChecked(),
ui->playLoop->isChecked()); ui->playLoop->isChecked());
} }

View File

@ -102,10 +102,6 @@ private:
bool m_enableNavTime; bool m_enableNavTime;
SSBMod::SSBModInputAF m_modAFInput; SSBMod::SSBModInputAF m_modAFInput;
bool m_audioBinaural;
bool m_audioFlipChannels;
bool m_dsb;
explicit SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL); explicit SSBModGUI(PluginAPI* pluginAPI, DeviceSinkAPI *deviceAPI, QWidget* parent = NULL);
virtual ~SSBModGUI(); virtual ~SSBModGUI();