diff --git a/plugins/channeltx/modam/ammod.cpp b/plugins/channeltx/modam/ammod.cpp index 793389dee..e7dbf3655 100644 --- a/plugins/channeltx/modam/ammod.cpp +++ b/plugins/channeltx/modam/ammod.cpp @@ -26,6 +26,8 @@ #include "dsp/pidcontroller.h" MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureAMMod, Message) +MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureChannelizer, Message) +MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureAMModPrivate, Message) MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureFileSourceName, Message) MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureFileSourceSeek, Message) MESSAGE_CLASS_DEFINITION(AMMod::MsgConfigureAFInput, Message) @@ -89,13 +91,13 @@ void AMMod::configure(MessageQueue* messageQueue, bool audioMute, bool playLoop) { - Message* cmd = MsgConfigureAMMod::create(rfBandwidth, modFactor, toneFrequency, volumeFactor, audioMute, playLoop); + Message* cmd = MsgConfigureAMModPrivate::create(rfBandwidth, modFactor, toneFrequency, volumeFactor, audioMute, playLoop); messageQueue->push(cmd); } void AMMod::pull(Sample& sample) { - if (m_running.m_channelMute) + if (m_settings.m_channelMute) { sample.m_real = 0.0f; sample.m_imag = 0.0f; @@ -160,7 +162,7 @@ void AMMod::modulateSample() calculateLevel(t); m_audioBufferFill++; - m_modSample.real((t*m_running.m_modFactor + 1.0f) * 16384.0f); // modulate and scale zero frequency carrier + m_modSample.real((t*m_settings.m_modFactor + 1.0f) * 16384.0f); // modulate and scale zero frequency carrier m_modSample.imag(0.0f); } @@ -178,7 +180,7 @@ void AMMod::pullAF(Real& sample) { if (m_ifstream.eof()) { - if (m_running.m_playLoop) + if (m_settings.m_playLoop) { m_ifstream.clear(); m_ifstream.seekg(0, std::ios::beg); @@ -192,7 +194,7 @@ void AMMod::pullAF(Real& sample) else { m_ifstream.read(reinterpret_cast(&sample), sizeof(Real)); - sample *= m_running.m_volumeFactor; + sample *= m_settings.m_volumeFactor; } } else @@ -201,7 +203,7 @@ void AMMod::pullAF(Real& sample) } break; case AMModInputAudio: - sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_running.m_volumeFactor; + sample = ((m_audioBuffer[m_audioBufferFill].l + m_audioBuffer[m_audioBufferFill].r) / 65536.0f) * m_settings.m_volumeFactor; break; case AMModInputCWTone: Real fadeFactor; @@ -272,6 +274,9 @@ bool AMMod::handleMessage(const Message& cmd) m_config.m_outputSampleRate = notif.getSampleRate(); m_config.m_inputFrequencyOffset = notif.getFrequencyOffset(); + m_settings.m_outputSampleRate = notif.getSampleRate(); + m_settings.m_inputFrequencyOffset = notif.getFrequencyOffset(); + apply(); qDebug() << "AMMod::handleMessage: MsgChannelizerNotification:" @@ -281,9 +286,31 @@ bool AMMod::handleMessage(const Message& cmd) return true; } - else if (MsgConfigureAMMod::match(cmd)) + else if (MsgConfigureAMMod::match(cmd)) + { + MsgConfigureAMMod& cfg = (MsgConfigureAMMod&) cmd; + + AMModSettings settings = cfg.getSettings(); + + // These settings are set with DownChannelizer::MsgChannelizerNotification + settings.m_outputSampleRate = m_settings.m_outputSampleRate; + settings.m_inputFrequencyOffset = m_settings.m_inputFrequencyOffset; + + applySettings(settings, cfg.getForce()); + + qDebug() << "AMMod::handleMessage: MsgConfigureAMMod:" + << " m_rfBandwidth: " << settings.m_rfBandwidth + << " m_modFactor: " << settings.m_modFactor + << " m_toneFrequency: " << settings.m_toneFrequency + << " m_volumeFactor: " << settings.m_volumeFactor + << " m_audioMute: " << settings.m_channelMute + << " m_playLoop: " << settings.m_playLoop; + + return true; + } + else if (MsgConfigureAMModPrivate::match(cmd)) { - MsgConfigureAMMod& cfg = (MsgConfigureAMMod&) cmd; + MsgConfigureAMModPrivate& cfg = (MsgConfigureAMModPrivate&) cmd; m_config.m_rfBandwidth = cfg.getRFBandwidth(); m_config.m_modFactor = cfg.getModFactor(); @@ -294,7 +321,7 @@ bool AMMod::handleMessage(const Message& cmd) apply(); - qDebug() << "AMMod::handleMessage: MsgConfigureAMMod:" + qDebug() << "AMMod::handleMessage: MsgConfigureAMModPrivate:" << " m_rfBandwidth: " << m_config.m_rfBandwidth << " m_modFactor: " << m_config.m_modFactor << " m_toneFrequency: " << m_config.m_toneFrequency @@ -394,6 +421,16 @@ void AMMod::apply() m_running.m_audioSampleRate = m_config.m_audioSampleRate; m_running.m_channelMute = m_config.m_channelMute; m_running.m_playLoop = m_config.m_playLoop; + + m_settings.m_outputSampleRate = m_config.m_outputSampleRate; + m_settings.m_inputFrequencyOffset = m_config.m_inputFrequencyOffset; + m_settings.m_rfBandwidth = m_config.m_rfBandwidth; + m_settings.m_modFactor = m_config.m_modFactor; + m_settings.m_toneFrequency = m_config.m_toneFrequency; + m_settings.m_volumeFactor = m_config.m_volumeFactor; + m_settings.m_audioSampleRate = m_config.m_audioSampleRate; + m_settings.m_channelMute = m_config.m_channelMute; + m_settings.m_playLoop = m_config.m_playLoop; } void AMMod::openFileStream() @@ -430,3 +467,40 @@ void AMMod::seekFileStream(int seekPercentage) m_ifstream.seekg(seekPoint, std::ios::beg); } } + +void AMMod::applySettings(const AMModSettings& settings, bool force) +{ + if ((settings.m_inputFrequencyOffset != m_settings.m_inputFrequencyOffset) || + (settings.m_outputSampleRate != m_settings.m_outputSampleRate) || force) + { + m_settingsMutex.lock(); + m_carrierNco.setFreq(settings.m_inputFrequencyOffset, settings.m_outputSampleRate); + m_settingsMutex.unlock(); + } + + if((settings.m_outputSampleRate != m_settings.m_outputSampleRate) || + (settings.m_rfBandwidth != m_settings.m_rfBandwidth) || + (settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force) + { + m_settingsMutex.lock(); + m_interpolatorDistanceRemain = 0; + m_interpolatorConsumed = false; + m_interpolatorDistance = (Real) settings.m_audioSampleRate / (Real) settings.m_outputSampleRate; + m_interpolator.create(48, settings.m_audioSampleRate, settings.m_rfBandwidth / 2.2, 3.0); + m_settingsMutex.unlock(); + } + + if ((settings.m_toneFrequency != m_settings.m_toneFrequency) || + (settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force) + { + m_settingsMutex.lock(); + m_toneNco.setFreq(settings.m_toneFrequency, settings.m_audioSampleRate); + m_settingsMutex.unlock(); + } + + if ((settings.m_audioSampleRate != m_settings.m_audioSampleRate) || force) + { + m_cwKeyer.setSampleRate(settings.m_audioSampleRate); + m_cwSmoother.setNbFadeSamples(settings.m_audioSampleRate / 250); // 4 ms + } +} diff --git a/plugins/channeltx/modam/ammod.h b/plugins/channeltx/modam/ammod.h index 67fed36b0..4b5cb673f 100644 --- a/plugins/channeltx/modam/ammod.h +++ b/plugins/channeltx/modam/ammod.h @@ -32,10 +32,58 @@ #include "audio/audiofifo.h" #include "util/message.h" +#include "ammodsettings.h" + class AMMod : public BasebandSampleSource { Q_OBJECT public: + class MsgConfigureAMMod : public Message { + MESSAGE_CLASS_DECLARATION + + public: + const AMModSettings& getSettings() const { return m_settings; } + bool getForce() const { return m_force; } + + static MsgConfigureAMMod* create(const AMModSettings& settings, bool force) + { + return new MsgConfigureAMMod(settings, force); + } + + private: + AMModSettings m_settings; + bool m_force; + + MsgConfigureAMMod(const AMModSettings& settings, bool force) : + Message(), + m_settings(settings), + m_force(force) + { } + }; + + class MsgConfigureChannelizer : public Message { + MESSAGE_CLASS_DECLARATION + + public: + int getSampleRate() const { return m_sampleRate; } + int getCenterFrequency() const { return m_centerFrequency; } + + static MsgConfigureChannelizer* create(int sampleRate, int centerFrequency) + { + return new MsgConfigureChannelizer(sampleRate, centerFrequency); + } + + private: + int m_sampleRate; + int m_centerFrequency; + + MsgConfigureChannelizer(int sampleRate, int centerFrequency) : + Message(), + m_sampleRate(sampleRate), + m_centerFrequency(centerFrequency) + { } + }; + typedef enum { AMModInputNone, @@ -205,7 +253,7 @@ signals: private: - class MsgConfigureAMMod : public Message + class MsgConfigureAMModPrivate : public Message { MESSAGE_CLASS_DECLARATION @@ -217,9 +265,9 @@ private: bool getChannelMute() const { return m_channelMute; } bool getPlayLoop() const { return m_playLoop; } - static MsgConfigureAMMod* create(Real rfBandwidth, float modFactor, float toneFreqeuncy, float volumeFactor, bool channelMute, bool playLoop) + static MsgConfigureAMModPrivate* create(Real rfBandwidth, float modFactor, float toneFreqeuncy, float volumeFactor, bool channelMute, bool playLoop) { - return new MsgConfigureAMMod(rfBandwidth, modFactor, toneFreqeuncy, volumeFactor, channelMute, playLoop); + return new MsgConfigureAMModPrivate(rfBandwidth, modFactor, toneFreqeuncy, volumeFactor, channelMute, playLoop); } private: @@ -230,7 +278,7 @@ private: bool m_channelMute; bool m_playLoop; - MsgConfigureAMMod(Real rfBandwidth, float modFactor, float toneFrequency, float volumeFactor, bool channelMute, bool playLoop) : + MsgConfigureAMModPrivate(Real rfBandwidth, float modFactor, float toneFrequency, float volumeFactor, bool channelMute, bool playLoop) : Message(), m_rfBandwidth(rfBandwidth), m_modFactor(modFactor), @@ -278,6 +326,7 @@ private: Config m_config; Config m_running; + AMModSettings m_settings; NCO m_carrierNco; NCOF m_toneNco; @@ -314,6 +363,7 @@ private: static const int m_levelNbSamples; void apply(); + void applySettings(const AMModSettings& settings, bool force = false); void pullAF(Real& sample); void calculateLevel(Real& sample); void modulateSample(); diff --git a/plugins/channeltx/modam/ammodgui.cpp b/plugins/channeltx/modam/ammodgui.cpp index 4dad78de2..988415a26 100644 --- a/plugins/channeltx/modam/ammodgui.cpp +++ b/plugins/channeltx/modam/ammodgui.cpp @@ -409,6 +409,9 @@ void AMModGUI::applySettings(bool force __attribute((unused))) ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency()); +// AMMod::MsgConfigureAMMod* message = AMMod::MsgConfigureAMMod::create( m_settings, force); +// m_amMod->getInputMessageQueue()->push(message); + m_amMod->configure(m_amMod->getInputMessageQueue(), m_settings.m_rfBandwidth, m_settings.m_modFactor,