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

SSBMod: revised thread processing

This commit is contained in:
f4exb 2024-08-18 13:36:30 +02:00 committed by Edouard Griffiths
parent d553834adf
commit 75d40c8b68
6 changed files with 112 additions and 49 deletions

View File

@ -57,20 +57,13 @@ const char* const SSBMod::m_channelId = "SSBMod";
SSBMod::SSBMod(DeviceAPI *deviceAPI) :
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSource),
m_deviceAPI(deviceAPI),
m_running(false),
m_spectrumVis(SDR_TX_SCALEF),
m_fileSize(0),
m_recordLength(0),
m_sampleRate(48000)
{
setObjectName(m_channelId);
m_thread = new QThread(this);
m_basebandSource = new SSBModBaseband();
m_basebandSource->setSpectrumSink(&m_spectrumVis);
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->moveToThread(m_thread);
applySettings(m_settings, true);
m_deviceAPI->addChannelSource(this);
@ -96,8 +89,8 @@ SSBMod::~SSBMod()
delete m_networkManager;
m_deviceAPI->removeChannelSourceAPI(this);
m_deviceAPI->removeChannelSource(this);
delete m_basebandSource;
delete m_thread;
stop();
}
void SSBMod::setDeviceAPI(DeviceAPI *deviceAPI)
@ -114,21 +107,62 @@ void SSBMod::setDeviceAPI(DeviceAPI *deviceAPI)
void SSBMod::start()
{
if (m_running) {
return;
}
qDebug("SSBMod::start");
m_thread = new QThread(this);
m_basebandSource = new SSBModBaseband();
m_basebandSource->setSpectrumSink(&m_spectrumVis);
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->reset();
m_basebandSource->setCWKeyer(&m_cwKeyer);
m_basebandSource->moveToThread(m_thread);
QObject::connect(
m_thread,
&QThread::finished,
m_basebandSource,
&QObject::deleteLater
);
QObject::connect(
m_thread,
&QThread::finished,
m_thread,
&QThread::deleteLater
);
m_thread->start();
SSBModBaseband::MsgConfigureSSBModBaseband *msg = SSBModBaseband::MsgConfigureSSBModBaseband::create(m_settings, true);
m_basebandSource->getInputMessageQueue()->push(msg);
if (m_levelMeter) {
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), m_levelMeter, SLOT(levelChanged(qreal, qreal, int)));
}
m_running = true;
}
void SSBMod::stop()
{
if (!m_running) {
return;
}
qDebug("SSBMod::stop");
m_running = false;
m_thread->exit();
m_thread->wait();
}
void SSBMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
{
if (m_running) {
m_basebandSource->pull(begin, nbSamples);
}
}
void SSBMod::setCenterFrequency(qint64 frequency)
@ -201,11 +235,14 @@ bool SSBMod::handleMessage(const Message& cmd)
}
else if (DSPSignalNotification::match(cmd))
{
// Forward to the source
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
// Forward to the source
if (m_running)
{
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
qDebug() << "SSBMod::handleMessage: DSPSignalNotification";
m_basebandSource->getInputMessageQueue()->push(rep);
}
// Forward to GUI if any
if (getMessageQueueToGUI()) {
getMessageQueueToGUI()->push(new DSPSignalNotification(notif));
@ -360,8 +397,11 @@ void SSBMod::applySettings(const SSBModSettings& settings, bool force)
m_spectrumVis.getInputMessageQueue()->push(msg);
}
if (m_running)
{
SSBModBaseband::MsgConfigureSSBModBaseband *msg = SSBModBaseband::MsgConfigureSSBModBaseband::create(settings, force);
m_basebandSource->getInputMessageQueue()->push(msg);
}
if (settings.m_useReverseAPI)
{
@ -437,7 +477,7 @@ int SSBMod::webapiSettingsGet(
webapiFormatChannelSettings(response, m_settings);
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getSsbModSettings()->getCwKeyer();
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = m_cwKeyer.getSettings();
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
return 200;
@ -465,11 +505,11 @@ int SSBMod::webapiSettingsPutPatch(
if (channelSettingsKeys.contains("cwKeyer"))
{
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getSsbModSettings()->getCwKeyer();
CWKeyerSettings cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
CWKeyerSettings cwKeyerSettings = m_cwKeyer.getSettings();
CWKeyer::webapiSettingsPutPatch(channelSettingsKeys, cwKeyerSettings, apiCwKeyerSettings);
CWKeyer::MsgConfigureCWKeyer *msgCwKeyer = CWKeyer::MsgConfigureCWKeyer::create(cwKeyerSettings, force);
m_basebandSource->getCWKeyer().getInputMessageQueue()->push(msgCwKeyer);
m_cwKeyer.getInputMessageQueue()->push(msgCwKeyer);
if (m_guiMessageQueue) // forward to GUI if any
{
@ -689,8 +729,12 @@ void SSBMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
void SSBMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
{
response.getSsbModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq()));
if (m_running)
{
response.getSsbModReport()->setAudioSampleRate(m_basebandSource->getAudioSampleRate());
response.getSsbModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate());
}
}
void SSBMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const SSBModSettings& settings, bool force)
@ -728,7 +772,7 @@ void SSBMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)
swgSSBModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgSSBModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
m_cwKeyer.webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
.arg(m_settings.m_reverseAPIAddress)
@ -875,10 +919,10 @@ void SSBMod::webapiFormatChannelSettings(
if (force)
{
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = m_cwKeyer.getSettings();
swgSSBModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgSSBModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
m_cwKeyer.webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
}
}
@ -905,27 +949,34 @@ void SSBMod::networkManagerFinished(QNetworkReply *reply)
double SSBMod::getMagSq() const
{
if (m_running) {
return m_basebandSource->getMagSq();
}
return 0;
}
CWKeyer *SSBMod::getCWKeyer()
{
return &m_basebandSource->getCWKeyer();
}
void SSBMod::setLevelMeter(QObject *levelMeter)
{
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), levelMeter, SLOT(levelChanged(qreal, qreal, int)));
return &m_cwKeyer;
}
int SSBMod::getAudioSampleRate() const
{
if (m_running) {
return m_basebandSource->getAudioSampleRate();
}
return 0;
}
int SSBMod::getFeedbackAudioSampleRate() const
{
if (m_running) {
return m_basebandSource->getFeedbackAudioSampleRate();
}
return 0;
}
uint32_t SSBMod::getNumberOfDeviceStreams() const

View File

@ -29,6 +29,7 @@
#include "dsp/basebandsamplesource.h"
#include "dsp/spectrumvis.h"
#include "dsp/cwkeyer.h"
#include "channel/channelapi.h"
#include "util/message.h"
@ -236,7 +237,7 @@ public:
SpectrumVis *getSpectrumVis() { return &m_spectrumVis; }
double getMagSq() const;
CWKeyer *getCWKeyer();
void setLevelMeter(QObject *levelMeter);
void setLevelMeter(QObject *levelMeter) { m_levelMeter = levelMeter; }
int getAudioSampleRate() const;
int getFeedbackAudioSampleRate() const;
uint32_t getNumberOfDeviceStreams() const;
@ -252,6 +253,7 @@ private:
DeviceAPI* m_deviceAPI;
QThread *m_thread;
bool m_running;
SSBModBaseband* m_basebandSource;
SSBModSettings m_settings;
SpectrumVis m_spectrumVis;
@ -267,6 +269,8 @@ private:
QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
CWKeyer m_cwKeyer;
QObject *m_levelMeter;
virtual bool handleMessage(const Message& cmd);
void applySettings(const SSBModSettings& settings, bool force = false);

View File

@ -171,8 +171,8 @@ bool SSBModBaseband::handleMessage(const Message& cmd)
QMutexLocker mutexLocker(&m_mutex);
const CWKeyer::MsgConfigureCWKeyer& cfg = (CWKeyer::MsgConfigureCWKeyer&) cmd;
CWKeyer::MsgConfigureCWKeyer *notif = new CWKeyer::MsgConfigureCWKeyer(cfg);
CWKeyer& cwKeyer = m_source.getCWKeyer();
cwKeyer.getInputMessageQueue()->push(notif);
CWKeyer *cwKeyer = m_source.getCWKeyer();
cwKeyer->getInputMessageQueue()->push(notif);
return true;
}

View File

@ -65,7 +65,7 @@ public:
void reset();
void pull(const SampleVector::iterator& begin, unsigned int nbSamples);
MessageQueue *getInputMessageQueue() { return &m_inputMessageQueue; } //!< Get the queue for asynchronous inbound communication
CWKeyer& getCWKeyer() { return m_source.getCWKeyer(); }
void setCWKeyer(CWKeyer *cwKeyer) { m_source.setCWKeyer(cwKeyer); }
double getMagSq() const { return m_source.getMagSq(); }
int getAudioSampleRate() const { return m_source.getAudioSampleRate(); }
int getFeedbackAudioSampleRate() const { return m_source.getFeedbackAudioSampleRate(); }

View File

@ -39,7 +39,8 @@ SSBModSource::SSBModSource() :
m_levelCalcCount(0),
m_peakLevel(0.0f),
m_levelSum(0.0f),
m_ifstream(nullptr)
m_ifstream(nullptr),
m_cwKeyer(nullptr)
{
m_audioFifo.setLabel("SSBModSource.m_audioFifo");
m_feedbackAudioFifo.setLabel("SSBModSource.m_feedbackAudioFifo");
@ -69,9 +70,6 @@ SSBModSource::SSBModSource() :
m_magsq = 0.0;
m_toneNco.setFreq(1000.0, m_audioSampleRate);
m_cwKeyer.setSampleRate(m_audioSampleRate);
m_cwKeyer.reset();
m_audioCompressor.initSimple(
m_audioSampleRate,
m_settings.m_cmpPreGainDB, // pregain (dB)
@ -354,11 +352,15 @@ void SSBModSource::pullAF(Complex& sample)
break;
case SSBModSettings::SSBModInputCWTone:
if (!m_cwKeyer) {
break;
}
Real fadeFactor;
if (m_cwKeyer.getSample())
if (m_cwKeyer->getSample())
{
m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor);
m_cwKeyer->getCWSmoother().getFadeSample(true, fadeFactor);
if (m_settings.m_dsb)
{
@ -377,7 +379,7 @@ void SSBModSource::pullAF(Complex& sample)
}
else
{
if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor))
if (m_cwKeyer->getCWSmoother().getFadeSample(false, fadeFactor))
{
if (m_settings.m_dsb)
{
@ -623,8 +625,12 @@ void SSBModSource::applyAudioSampleRate(int sampleRate)
m_settings.m_usb = usb;
m_toneNco.setFreq(m_settings.m_toneFrequency, sampleRate);
m_cwKeyer.setSampleRate(sampleRate);
m_cwKeyer.reset();
if (m_cwKeyer)
{
m_cwKeyer->setSampleRate(sampleRate);
m_cwKeyer->reset();
}
m_audioCompressor.m_rate = sampleRate;
m_audioCompressor.initState();

View File

@ -39,6 +39,7 @@
class ChannelAPI;
class SpectrumVis;
class CWKeyer;
class SSBModSource : public QObject, public ChannelSampleSource
{
@ -59,7 +60,8 @@ public:
int getAudioSampleRate() const { return m_audioSampleRate; }
int getFeedbackAudioSampleRate() const { return m_feedbackAudioSampleRate; }
void setChannel(ChannelAPI *channel) { m_channel = channel; }
CWKeyer& getCWKeyer() { return m_cwKeyer; }
CWKeyer* getCWKeyer() { return m_cwKeyer; }
void setCWKeyer(CWKeyer *cwKeyer) { m_cwKeyer = cwKeyer; }
double getMagSq() const { return m_magsq; }
void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const
{
@ -131,7 +133,7 @@ private:
Real m_levelSum;
std::ifstream *m_ifstream;
CWKeyer m_cwKeyer;
CWKeyer *m_cwKeyer;
AudioCompressorSnd m_audioCompressor;
int m_agcStepLength;