Skip to content

Commit

Permalink
AMMod: revised thread processing
Browse files Browse the repository at this point in the history
  • Loading branch information
f4exb committed Aug 27, 2024
1 parent 2219fcd commit 2b26f15
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 46 deletions.
117 changes: 84 additions & 33 deletions plugins/channeltx/modam/ammod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,18 +56,13 @@ const char* const AMMod::m_channelId ="AMMod";
AMMod::AMMod(DeviceAPI *deviceAPI) :
ChannelAPI(m_channelIdURI, ChannelAPI::StreamSingleSource),
m_deviceAPI(deviceAPI),
m_running(false),
m_fileSize(0),
m_recordLength(0),
m_sampleRate(48000)
m_sampleRate(48000),
m_levelMeter(nullptr)
{
setObjectName(m_channelId);

m_thread = new QThread(this);
m_basebandSource = new AMModBaseband();
m_basebandSource->setInputFileStream(&m_ifstream);
m_basebandSource->setChannel(this);
m_basebandSource->moveToThread(m_thread);

applySettings(m_settings, true);

m_deviceAPI->addChannelSource(this);
Expand All @@ -93,8 +88,8 @@ AMMod::~AMMod()
delete m_networkManager;
m_deviceAPI->removeChannelSourceAPI(this);
m_deviceAPI->removeChannelSource(this);
delete m_basebandSource;
delete m_thread;

stop();
}

void AMMod::setDeviceAPI(DeviceAPI *deviceAPI)
Expand All @@ -116,21 +111,61 @@ uint32_t AMMod::getNumberOfDeviceStreams() const

void AMMod::start()
{
if (m_running) {
return;
}

qDebug("AMMod::start");
m_thread = new QThread(this);
m_basebandSource = new AMModBaseband();
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();

AMModBaseband::MsgConfigureAMModBaseband *msg = AMModBaseband::MsgConfigureAMModBaseband::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 AMMod::stop()
{
if (!m_running) {
return;
}

qDebug("AMMod::stop");
m_running = false;
m_thread->exit();
m_thread->wait();
}

void AMMod::pull(SampleVector::iterator& begin, unsigned int nbSamples)
{
m_basebandSource->pull(begin, nbSamples);
if (m_running) {
m_basebandSource->pull(begin, nbSamples);
}
}

void AMMod::setCenterFrequency(qint64 frequency)
Expand Down Expand Up @@ -203,11 +238,13 @@ bool AMMod::handleMessage(const Message& cmd)
}
else if (DSPSignalNotification::match(cmd))
{
qDebug() << "AMMod::handleMessage: DSPSignalNotification";
// Forward to the source
DSPSignalNotification& notif = (DSPSignalNotification&) cmd;
DSPSignalNotification* rep = new DSPSignalNotification(notif); // make a copy
qDebug() << "AMMod::handleMessage: DSPSignalNotification";
m_basebandSource->getInputMessageQueue()->push(rep);

if (m_running) {
m_basebandSource->getInputMessageQueue()->push(new DSPSignalNotification(notif));
}
// Forward to GUI if any
if (getMessageQueueToGUI()) {
getMessageQueueToGUI()->push(new DSPSignalNotification(notif));
Expand Down Expand Up @@ -338,8 +375,11 @@ void AMMod::applySettings(const AMModSettings& settings, bool force)
reverseAPIKeys.append("streamIndex");
}

AMModBaseband::MsgConfigureAMModBaseband *msg = AMModBaseband::MsgConfigureAMModBaseband::create(settings, force);
m_basebandSource->getInputMessageQueue()->push(msg);
if (m_running)
{
AMModBaseband::MsgConfigureAMModBaseband *msg = AMModBaseband::MsgConfigureAMModBaseband::create(settings, force);
m_basebandSource->getInputMessageQueue()->push(msg);
}

if (settings.m_useReverseAPI)
{
Expand Down Expand Up @@ -412,7 +452,7 @@ int AMMod::webapiSettingsGet(
webapiFormatChannelSettings(response, m_settings);

SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getAmModSettings()->getCwKeyer();
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = getCWKeyer()->getSettings();
CWKeyer::webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);

return 200;
Expand Down Expand Up @@ -440,11 +480,11 @@ int AMMod::webapiSettingsPutPatch(
if (channelSettingsKeys.contains("cwKeyer"))
{
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = response.getAmModSettings()->getCwKeyer();
CWKeyerSettings cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
CWKeyerSettings cwKeyerSettings = getCWKeyer()->getSettings();
CWKeyer::webapiSettingsPutPatch(channelSettingsKeys, cwKeyerSettings, apiCwKeyerSettings);

CWKeyer::MsgConfigureCWKeyer *msgCwKeyer = CWKeyer::MsgConfigureCWKeyer::create(cwKeyerSettings, force);
m_basebandSource->getCWKeyer().getInputMessageQueue()->push(msgCwKeyer);
getCWKeyer()->getInputMessageQueue()->push(msgCwKeyer);

if (m_guiMessageQueue) // forward to GUI if any
{
Expand Down Expand Up @@ -615,8 +655,12 @@ void AMMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respons
void AMMod::webapiFormatChannelReport(SWGSDRangel::SWGChannelReport& response)
{
response.getAmModReport()->setChannelPowerDb(CalcDb::dbPower(getMagSq()));
response.getAmModReport()->setAudioSampleRate(m_basebandSource->getAudioSampleRate());
response.getAmModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate());

if (m_running)
{
response.getAmModReport()->setAudioSampleRate(m_basebandSource->getAudioSampleRate());
response.getAmModReport()->setChannelSampleRate(m_basebandSource->getChannelSampleRate());
}
}

void AMMod::webapiReverseSendSettings(QList<QString>& channelSettingsKeys, const AMModSettings& settings, bool force)
Expand Down Expand Up @@ -654,7 +698,7 @@ void AMMod::webapiReverseSendCWSettings(const CWKeyerSettings& cwKeyerSettings)

swgAMModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgAMModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
getCWKeyer()->webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);

QString channelSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/channel/%4/settings")
.arg(m_settings.m_reverseAPIAddress)
Expand Down Expand Up @@ -756,10 +800,10 @@ void AMMod::webapiFormatChannelSettings(

if (force)
{
const CWKeyerSettings& cwKeyerSettings = m_basebandSource->getCWKeyer().getSettings();
const CWKeyerSettings& cwKeyerSettings = getCWKeyer()->getSettings();
swgAMModSettings->setCwKeyer(new SWGSDRangel::SWGCWKeyerSettings());
SWGSDRangel::SWGCWKeyerSettings *apiCwKeyerSettings = swgAMModSettings->getCwKeyer();
m_basebandSource->getCWKeyer().webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
getCWKeyer()->webapiFormatChannelSettings(apiCwKeyerSettings, cwKeyerSettings);
}

if (settings.m_channelMarker && (channelSettingsKeys.contains("channelMarker") || force))
Expand Down Expand Up @@ -800,25 +844,32 @@ void AMMod::networkManagerFinished(QNetworkReply *reply)

double AMMod::getMagSq() const
{
return m_basebandSource->getMagSq();
}
if (m_running) {
return m_basebandSource->getMagSq();
}

CWKeyer *AMMod::getCWKeyer()
{
return &m_basebandSource->getCWKeyer();
return 0;
}

void AMMod::setLevelMeter(QObject *levelMeter)
CWKeyer *AMMod::getCWKeyer()
{
connect(m_basebandSource, SIGNAL(levelChanged(qreal, qreal, int)), levelMeter, SLOT(levelChanged(qreal, qreal, int)));
return &m_cwKeyer;
}

int AMMod::getAudioSampleRate() const
{
return m_basebandSource->getAudioSampleRate();
if (m_running) {
return m_basebandSource->getAudioSampleRate();
}

return 0;
}

int AMMod::getFeedbackAudioSampleRate() const
{
return m_basebandSource->getFeedbackAudioSampleRate();
if (m_running) {
return m_basebandSource->getFeedbackAudioSampleRate();
}

return 0;
}
6 changes: 5 additions & 1 deletion plugins/channeltx/modam/ammod.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <QNetworkRequest>

#include "dsp/basebandsamplesource.h"
#include "dsp/cwkeyer.h"
#include "channel/channelapi.h"
#include "util/message.h"

Expand Down Expand Up @@ -235,7 +236,7 @@ class AMMod : public BasebandSampleSource, public ChannelAPI {
uint32_t getNumberOfDeviceStreams() const;
double getMagSq() const;
CWKeyer *getCWKeyer();
void setLevelMeter(QObject *levelMeter);
void setLevelMeter(QObject *levelMeter) { m_levelMeter = levelMeter; }
int getAudioSampleRate() const;
int getFeedbackAudioSampleRate() const;

Expand All @@ -250,6 +251,7 @@ class AMMod : public BasebandSampleSource, public ChannelAPI {

DeviceAPI* m_deviceAPI;
QThread *m_thread;
bool m_running;
AMModBaseband* m_basebandSource;
AMModSettings m_settings;

Expand All @@ -264,6 +266,8 @@ class AMMod : public BasebandSampleSource, public ChannelAPI {

QNetworkAccessManager *m_networkManager;
QNetworkRequest m_networkRequest;
CWKeyer m_cwKeyer;
QObject *m_levelMeter;

virtual bool handleMessage(const Message& cmd);
void applySettings(const AMModSettings& settings, bool force = false);
Expand Down
5 changes: 3 additions & 2 deletions plugins/channeltx/modam/ammodbaseband.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "dsp/upchannelizer.h"
#include "dsp/dspengine.h"
#include "dsp/dspcommands.h"
#include "dsp/cwkeyer.h"

#include "ammodbaseband.h"

Expand Down Expand Up @@ -171,8 +172,8 @@ bool AMModBaseband::handleMessage(const Message& cmd)
qDebug() << "AMModBaseband::handleMessage: MsgConfigureCWKeyer";
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;
}
Expand Down
2 changes: 1 addition & 1 deletion plugins/channeltx/modam/ammodbaseband.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class AMModBaseband : public QObject
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(); }
Expand Down
22 changes: 16 additions & 6 deletions plugins/channeltx/modam/ammodsource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <QDebug>

#include "dsp/datafifo.h"
#include "dsp/cwkeyer.h"
#include "util/messagequeue.h"
#include "maincore.h"

Expand All @@ -35,7 +36,8 @@ AMModSource::AMModSource() :
m_levelCalcCount(0),
m_peakLevel(0.0f),
m_levelSum(0.0f),
m_ifstream(nullptr)
m_ifstream(nullptr),
m_cwKeyer(nullptr)
{
m_audioFifo.setLabel("AMModSource.m_audioFifo");
m_feedbackAudioFifo.setLabel("AMModSource.m_feedbackAudioFifo");
Expand Down Expand Up @@ -218,14 +220,18 @@ void AMModSource::pullAF(Real& sample)
case AMModSettings::AMModInputCWTone:
Real fadeFactor;

if (m_cwKeyer.getSample())
if (!m_cwKeyer) {
break;
}

if (m_cwKeyer->getSample())
{
m_cwKeyer.getCWSmoother().getFadeSample(true, fadeFactor);
m_cwKeyer->getCWSmoother().getFadeSample(true, fadeFactor);
sample = m_toneNco.next() * fadeFactor;
}
else
{
if (m_cwKeyer.getCWSmoother().getFadeSample(false, fadeFactor))
if (m_cwKeyer->getCWSmoother().getFadeSample(false, fadeFactor))
{
sample = m_toneNco.next() * fadeFactor;
}
Expand Down Expand Up @@ -320,8 +326,12 @@ void AMModSource::applyAudioSampleRate(int sampleRate)
m_interpolatorDistance = (Real) sampleRate / (Real) m_channelSampleRate;
m_interpolator.create(48, sampleRate, m_settings.m_rfBandwidth / 2.2, 3.0);
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();
}

QList<ObjectPipe*> pipes;
MainCore::instance()->getMessagePipes().getMessagePipes(m_channel, "reportdemod", pipes);
Expand Down
7 changes: 4 additions & 3 deletions plugins/channeltx/modam/ammodsource.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@
#include "dsp/ncof.h"
#include "dsp/interpolator.h"
#include "util/movingaverage.h"
#include "dsp/cwkeyer.h"
#include "audio/audiofifo.h"

#include "ammodsettings.h"

class ChannelAPI;
class CWKeyer;

class AMModSource : public QObject, public ChannelSampleSource
{
Expand All @@ -57,7 +57,8 @@ class AMModSource : public QObject, public ChannelSampleSource
void applyFeedbackAudioSampleRate(int sampleRate);
int getAudioSampleRate() const { return m_audioSampleRate; }
int getFeedbackAudioSampleRate() const { return m_feedbackAudioSampleRate; }
CWKeyer& getCWKeyer() { return m_cwKeyer; }
void setCWKeyer(CWKeyer *cwKeyer) { m_cwKeyer = cwKeyer; }
CWKeyer* getCWKeyer() { return m_cwKeyer; }
double getMagSq() const { return m_magsq; }
void getLevels(qreal& rmsLevel, qreal& peakLevel, int& numSamples) const
{
Expand Down Expand Up @@ -112,7 +113,7 @@ class AMModSource : public QObject, public ChannelSampleSource
Real m_levelSum;

std::ifstream *m_ifstream;
CWKeyer m_cwKeyer;
CWKeyer *m_cwKeyer;

QRecursiveMutex m_mutex;

Expand Down

0 comments on commit 2b26f15

Please sign in to comment.