From 4c584847de4c59623ddfaf53bb04f7664fd5a8cf Mon Sep 17 00:00:00 2001 From: AlexandreRouma Date: Sun, 9 Jul 2023 18:34:52 +0200 Subject: [PATCH] more work --- core/src/gui/menus/streams.cpp | 5 +- core/src/signal_path/stream.cpp | 66 +++++++++--- core/src/signal_path/stream.h | 14 ++- decoder_modules/radio/src/demod.h | 3 +- decoder_modules/radio/src/demodulators/am.h | 8 +- decoder_modules/radio/src/demodulators/cw.h | 8 +- decoder_modules/radio/src/demodulators/dsb.h | 8 +- decoder_modules/radio/src/demodulators/lsb.h | 8 +- decoder_modules/radio/src/demodulators/nfm.h | 8 +- decoder_modules/radio/src/demodulators/raw.h | 13 +-- decoder_modules/radio/src/demodulators/usb.h | 8 +- decoder_modules/radio/src/demodulators/wfm.h | 8 +- decoder_modules/radio/src/radio_module.h | 100 +++++++------------ 13 files changed, 131 insertions(+), 126 deletions(-) diff --git a/core/src/gui/menus/streams.cpp b/core/src/gui/menus/streams.cpp index 4cea3bf3..3e0eedf2 100644 --- a/core/src/gui/menus/streams.cpp +++ b/core/src/gui/menus/streams.cpp @@ -35,6 +35,9 @@ namespace streamsmenu { sink->showMenu(); + // Volume slider + mute button + + ImGui::FillWidth(); if (ImGui::Button(CONCAT("Remove##sdrpp_streams_remove_type_", name))) { sinksToBeRemoved.push_back(id); @@ -50,7 +53,7 @@ namespace streamsmenu { ImGui::SameLine(); ImGui::FillWidth(); if (ImGui::Button(CONCAT("Add##sdrpp_streams_add_btn_", name))) { - stream->addSink("Sink 2"); + stream->addSink("Audio"); } ImGui::EndTable(); diff --git a/core/src/signal_path/stream.cpp b/core/src/signal_path/stream.cpp index 9601154c..e6e64735 100644 --- a/core/src/signal_path/stream.cpp +++ b/core/src/signal_path/stream.cpp @@ -144,7 +144,6 @@ AudioStream::AudioStream(StreamManager* manager, const std::string& name, dsp::s // Initialize DSP split.init(stream); - split.start(); } AudioStream::~AudioStream() { @@ -173,11 +172,14 @@ void AudioStream::setInput(dsp::stream* stream, double samplerate this->samplerate = samplerate; // Stop DSP - split.stop(); - for (auto& [id, sink] : sinks) { - sink->stopDSP(); + if (running) { + split.stop(); + for (auto& [id, sink] : sinks) { + sink->stopDSP(); + } } + // Set input and samplerate split.setInput(stream); for (auto& [id, sink] : sinks) { @@ -185,10 +187,12 @@ void AudioStream::setInput(dsp::stream* stream, double samplerate } // Start DSP - for (auto& [id, sink] : sinks) { - sink->startDSP(); + if (running) { + for (auto& [id, sink] : sinks) { + sink->startDSP(); + } + split.start(); } - split.start(); } void AudioStream::setSamplerate(double samplerate) { @@ -198,9 +202,11 @@ void AudioStream::setSamplerate(double samplerate) { this->samplerate = samplerate; // Stop DSP - split.stop(); - for (auto& [id, sink] : sinks) { - sink->stopDSP(); + if (running) { + split.stop(); + for (auto& [id, sink] : sinks) { + sink->stopDSP(); + } } // Set samplerate @@ -209,10 +215,12 @@ void AudioStream::setSamplerate(double samplerate) { } // Start DSP - for (auto& [id, sink] : sinks) { - sink->startDSP(); + if (running) { + for (auto& [id, sink] : sinks) { + sink->startDSP(); + } + split.start(); } - split.start(); } const std::string& AudioStream::getName() const { @@ -246,7 +254,7 @@ SinkID AudioStream::addSink(const std::string& type, SinkID id) { // Start the sink and DSP sink->startSink(); - sink->startDSP(); + if (running) { sink->startDSP(); } // Bind the sinks's input split.bindStream(&sink->input); @@ -313,6 +321,36 @@ const std::map>& AudioStream::getSinks() cons return sinks; } +void AudioStream::startDSP() { + // TODO: Maybe add a different mutex for the stream? + std::unique_lock lck(sinksMtx); + + // Check if already running + if (running) { return; } + + // Start all DSP + split.start(); + for (auto& [id, sink] : sinks) { + sink->startDSP(); + } + running = true; +} + +void AudioStream::stopDSP() { + // TODO: Maybe add a different mutex for the stream? + std::unique_lock lck(sinksMtx); + + // Check if already running + if (!running) { return; } + + // Start all DSP + split.stop(); + for (auto& [id, sink] : sinks) { + sink->stopDSP(); + } + running = false; +} + std::shared_ptr StreamManager::createStream(const std::string& name, dsp::stream* stream, double samplerate) { std::unique_lock lck(streamsMtx); diff --git a/core/src/signal_path/stream.h b/core/src/signal_path/stream.h index 54d86f91..44fd7fca 100644 --- a/core/src/signal_path/stream.h +++ b/core/src/signal_path/stream.h @@ -146,7 +146,6 @@ private: dsp::multirate::RationalResampler resamp; dsp::audio::Volume volumeAdjust; - SinkProvider* provider = NULL; std::unique_ptr sink; std::string type; @@ -216,6 +215,18 @@ public: */ const std::map>& getSinks() const; + // TODO: This should only be callable by the module that created the stream + + /** + * Start the DSP. + */ + void startDSP(); + + /** + * Stop the DSP. + */ + void stopDSP(); + // Emitted when the samplerate of the stream was changed NewEvent onSamplerateChanged; // Emitted when a sink was added @@ -228,6 +239,7 @@ private: const std::string name; double samplerate; dsp::routing::Splitter split; + bool running = false; std::map> sinks; std::shared_mutex sinksMtx; diff --git a/decoder_modules/radio/src/demod.h b/decoder_modules/radio/src/demod.h index b250aefa..bc6ea061 100644 --- a/decoder_modules/radio/src/demod.h +++ b/decoder_modules/radio/src/demod.h @@ -24,13 +24,12 @@ namespace demod { class Demodulator { public: virtual ~Demodulator() {} - virtual void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) = 0; + virtual void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) = 0; virtual void start() = 0; virtual void stop() = 0; virtual void showMenu() = 0; virtual void setBandwidth(double bandwidth) = 0; virtual void setInput(dsp::stream* input) = 0; - virtual void AFSampRateChanged(double newSR) = 0; virtual const char* getName() = 0; virtual double getIFSampleRate() = 0; virtual double getAFSampleRate() = 0; diff --git a/decoder_modules/radio/src/demodulators/am.h b/decoder_modules/radio/src/demodulators/am.h index 81d71806..35bffdf7 100644 --- a/decoder_modules/radio/src/demodulators/am.h +++ b/decoder_modules/radio/src/demodulators/am.h @@ -7,13 +7,13 @@ namespace demod { public: AM() {} - AM(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { - init(name, config, input, bandwidth, audioSR); + AM(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { + init(name, config, input, bandwidth); } ~AM() { stop(); } - void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { + void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { this->name = name; _config = config; @@ -68,8 +68,6 @@ namespace demod { void setInput(dsp::stream* input) { demod.setInput(input); } - void AFSampRateChanged(double newSR) {} - // ============= INFO ============= const char* getName() { return "AM"; } diff --git a/decoder_modules/radio/src/demodulators/cw.h b/decoder_modules/radio/src/demodulators/cw.h index df2bdcfb..800e9ed6 100644 --- a/decoder_modules/radio/src/demodulators/cw.h +++ b/decoder_modules/radio/src/demodulators/cw.h @@ -7,15 +7,15 @@ namespace demod { public: CW() {} - CW(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { - init(name, config, input, bandwidth, audioSR); + CW(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { + init(name, config, input, bandwidth); } ~CW() { stop(); } - void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { + void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { this->name = name; this->_config = config; this->afbwChangeHandler = afbwChangeHandler; @@ -74,8 +74,6 @@ namespace demod { void setInput(dsp::stream* input) { demod.setInput(input); } - void AFSampRateChanged(double newSR) {} - // ============= INFO ============= const char* getName() { return "CW"; } diff --git a/decoder_modules/radio/src/demodulators/dsb.h b/decoder_modules/radio/src/demodulators/dsb.h index 2c56565e..81016a5a 100644 --- a/decoder_modules/radio/src/demodulators/dsb.h +++ b/decoder_modules/radio/src/demodulators/dsb.h @@ -7,15 +7,15 @@ namespace demod { public: DSB() {} - DSB(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { - init(name, config, input, bandwidth, audioSR); + DSB(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { + init(name, config, input, bandwidth); } ~DSB() { stop(); } - void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { + void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { this->name = name; _config = config; @@ -61,8 +61,6 @@ namespace demod { void setInput(dsp::stream* input) { demod.setInput(input); } - void AFSampRateChanged(double newSR) {} - // ============= INFO ============= const char* getName() { return "DSB"; } diff --git a/decoder_modules/radio/src/demodulators/lsb.h b/decoder_modules/radio/src/demodulators/lsb.h index e442a87f..91dc7b14 100644 --- a/decoder_modules/radio/src/demodulators/lsb.h +++ b/decoder_modules/radio/src/demodulators/lsb.h @@ -7,15 +7,15 @@ namespace demod { public: LSB() {} - LSB(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { - init(name, config, input, bandwidth, audioSR); + LSB(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { + init(name, config, input, bandwidth); } ~LSB() { stop(); } - void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { + void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { this->name = name; _config = config; @@ -61,8 +61,6 @@ namespace demod { void setInput(dsp::stream* input) { demod.setInput(input); } - void AFSampRateChanged(double newSR) {} - // ============= INFO ============= const char* getName() { return "LSB"; } diff --git a/decoder_modules/radio/src/demodulators/nfm.h b/decoder_modules/radio/src/demodulators/nfm.h index c631c6b1..66f27127 100644 --- a/decoder_modules/radio/src/demodulators/nfm.h +++ b/decoder_modules/radio/src/demodulators/nfm.h @@ -7,13 +7,13 @@ namespace demod { public: NFM() {} - NFM(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { - init(name, config, input, bandwidth, audioSR); + NFM(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { + init(name, config, input, bandwidth); } ~NFM() { stop(); } - void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { + void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { this->name = name; this->_config = config; @@ -57,8 +57,6 @@ namespace demod { void setInput(dsp::stream* input) { demod.setInput(input); } - void AFSampRateChanged(double newSR) {} - // ============= INFO ============= const char* getName() { return "FM"; } diff --git a/decoder_modules/radio/src/demodulators/raw.h b/decoder_modules/radio/src/demodulators/raw.h index 094494de..07296198 100644 --- a/decoder_modules/radio/src/demodulators/raw.h +++ b/decoder_modules/radio/src/demodulators/raw.h @@ -7,17 +7,18 @@ namespace demod { public: RAW() {} - RAW(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { - init(name, config, input, bandwidth, audioSR); + RAW(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { + init(name, config, input, bandwidth); } ~RAW() { stop(); } - void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { + void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { this->name = name; - audioSampleRate = audioSR; + audioSampleRate = 48000; + // TODO: This needs to be selectable // Define structure c2s.init(input); @@ -39,10 +40,6 @@ namespace demod { c2s.setInput(input); } - void AFSampRateChanged(double newSR) { - audioSampleRate = newSR; - } - // ============= INFO ============= const char* getName() { return "RAW"; } diff --git a/decoder_modules/radio/src/demodulators/usb.h b/decoder_modules/radio/src/demodulators/usb.h index 41195ba6..6da501a9 100644 --- a/decoder_modules/radio/src/demodulators/usb.h +++ b/decoder_modules/radio/src/demodulators/usb.h @@ -8,15 +8,15 @@ namespace demod { public: USB() {} - USB(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { - init(name, config, input, bandwidth, audioSR); + USB(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { + init(name, config, input, bandwidth); } ~USB() { stop(); } - void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { + void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { this->name = name; _config = config; @@ -62,8 +62,6 @@ namespace demod { void setInput(dsp::stream* input) { demod.setInput(input); } - void AFSampRateChanged(double newSR) {} - // ============= INFO ============= const char* getName() { return "USB"; } diff --git a/decoder_modules/radio/src/demodulators/wfm.h b/decoder_modules/radio/src/demodulators/wfm.h index 2761b28e..a225a2f6 100644 --- a/decoder_modules/radio/src/demodulators/wfm.h +++ b/decoder_modules/radio/src/demodulators/wfm.h @@ -16,8 +16,8 @@ namespace demod { public: WFM() {} - WFM(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { - init(name, config, input, bandwidth, audioSR); + WFM(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { + init(name, config, input, bandwidth); } ~WFM() { @@ -25,7 +25,7 @@ namespace demod { gui::waterfall.onFFTRedraw.unbindHandler(&fftRedrawHandler); } - void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth, double audioSR) { + void init(std::string name, ConfigManager* config, dsp::stream* input, double bandwidth) { this->name = name; _config = config; @@ -112,8 +112,6 @@ namespace demod { demod.setInput(input); } - void AFSampRateChanged(double newSR) {} - // ============= INFO ============= const char* getName() { return "WFM"; } diff --git a/decoder_modules/radio/src/radio_module.h b/decoder_modules/radio/src/radio_module.h index c0605fd5..057e4e55 100644 --- a/decoder_modules/radio/src/radio_module.h +++ b/decoder_modules/radio/src/radio_module.h @@ -81,30 +81,16 @@ public: // Initialize audio DSP chain afChain.init(&dummyAudioStream); - resamp.init(NULL, 250000.0, 48000.0); deemp.init(NULL, 50e-6, 48000.0); - afChain.addBlock(&resamp, true); afChain.addBlock(&deemp, false); // Initialize the sink - srChangeHandler.ctx = this; - srChangeHandler.handler = sampleRateChangeHandler; - stream.init(afChain.out, &srChangeHandler, audioSampleRate); - sigpath::sinkManager.registerStream(name, &stream); + stream = sigpath::streamManager.createStream(name, afChain.out, 48000); // Select the demodulator selectDemodByID((DemodID)selectedDemodID); - // Start IF chain - ifChain.start(); - - // Start AF chain - afChain.start(); - - // Start stream, the rest was started when selecting the demodulator - stream.start(); - // Register the menu gui::menu.registerEntry(name, menuHandler, this, this); @@ -115,11 +101,10 @@ public: ~RadioModule() { core::modComManager.unregisterInterface(name); gui::menu.removeEntry(name); - stream.stop(); if (enabled) { disable(); } - sigpath::sinkManager.unregisterStream(name); + sigpath::streamManager.destroyStream(stream); } void postInit() {} @@ -131,9 +116,7 @@ public: vfo->wtfVFO->onUserChangedBandwidth.bindHandler(&onUserChangedBandwidthHandler); } ifChain.setInput(vfo->output, [=](dsp::stream* out){ ifChainOutputChangeHandler(out, this); }); - ifChain.start(); selectDemodByID((DemodID)selectedDemodID); - afChain.start(); } void disable() { @@ -141,6 +124,7 @@ public: ifChain.stop(); if (selectedDemod) { selectedDemod->stop(); } afChain.stop(); + stream->stopDSP(); if (vfo) { sigpath::vfoManager.deleteVFO(vfo); } vfo = NULL; } @@ -313,7 +297,7 @@ private: bw = std::clamp(bw, demod->getMinBandwidth(), demod->getMaxBandwidth()); // Initialize - demod->init(name, &config, ifChain.out, bw, stream.getSampleRate()); + demod->init(name, &config, ifChain.out, bw); return demod; } @@ -337,22 +321,34 @@ private: } void selectDemod(demod::Demodulator* demod) { - // Stopcurrently selected demodulator and select new - afChain.setInput(&dummyAudioStream, [=](dsp::stream* out){ stream.setInput(out); }); + // Stop the IF chain + ifChain.stop(); + + // Stop the current demodulator if (selectedDemod) { selectedDemod->stop(); + } + + // Stop AF chain + afChain.stop(); + + // Stop audio stream's DSP + stream->stopDSP(); + + // Destroy the old demodulator + afChain.setInput(&dummyAudioStream, [=](dsp::stream* out){ stream->setInput(out); }); + if (selectedDemod) { delete selectedDemod; } - selectedDemod = demod; - // Give the demodulator the most recent audio SR - selectedDemod->AFSampRateChanged(audioSampleRate); + // Select the new demodulator + selectedDemod = demod; // Set the demodulator's input selectedDemod->setInput(ifChain.out); // Set AF chain's input - afChain.setInput(selectedDemod->getOutput(), [=](dsp::stream* out){ stream.setInput(out); }); + afChain.setInput(selectedDemod->getOutput(), [=](dsp::stream* out){ stream->setInput(out); }); // Load config bandwidth = selectedDemod->getDefaultBandwidth(); @@ -440,21 +436,27 @@ private: // Configure AF chain if (postProcEnabled) { // Configure resampler - afChain.stop(); - resamp.setInSamplerate(selectedDemod->getAFSampleRate()); - setAudioSampleRate(audioSampleRate); - afChain.enableBlock(&resamp, [=](dsp::stream* out){ stream.setInput(out); }); + deemp.setSamplerate(selectedDemod->getAFSampleRate()); // Configure deemphasis setDeemphasisMode(deempModes[deempId]); } else { // Disable everything if post processing is disabled - afChain.disableAllBlocks([=](dsp::stream* out){ stream.setInput(out); }); + afChain.disableAllBlocks([=](dsp::stream* out){ stream->setInput(out); }); } + // Start the IF chain + ifChain.start(); + // Start new demodulator selectedDemod->start(); + + // Start the AF chain + afChain.start(); + + // Start the audio stream + stream->startDSP(); } @@ -470,37 +472,12 @@ private: config.release(true); } - void setAudioSampleRate(double sr) { - audioSampleRate = sr; - if (!selectedDemod) { return; } - selectedDemod->AFSampRateChanged(audioSampleRate); - if (!postProcEnabled && vfo) { - // If postproc is disabled, IF SR = AF SR - minBandwidth = selectedDemod->getMinBandwidth(); - maxBandwidth = selectedDemod->getMaxBandwidth(); - bandwidth = selectedDemod->getIFSampleRate(); - vfo->setBandwidthLimits(minBandwidth, maxBandwidth, selectedDemod->getBandwidthLocked()); - vfo->setSampleRate(selectedDemod->getIFSampleRate(), bandwidth); - return; - } - - afChain.stop(); - - // Configure resampler - resamp.setOutSamplerate(audioSampleRate); - - // Configure deemphasis sample rate - deemp.setSamplerate(audioSampleRate); - - afChain.start(); - } - void setDeemphasisMode(DeemphasisMode mode) { deempId = deempModes.valueId(mode); if (!postProcEnabled || !selectedDemod) { return; } bool deempEnabled = (mode != DEEMP_MODE_NONE); if (deempEnabled) { deemp.setTau(deempTaus[mode]); } - afChain.setBlockEnabled(&deemp, deempEnabled, [=](dsp::stream* out){ stream.setInput(out); }); + afChain.setBlockEnabled(&deemp, deempEnabled, [=](dsp::stream* out){ stream->setInput(out); }); // Save config config.acquire(); @@ -584,11 +561,6 @@ private: _this->setBandwidth(newBw); } - static void sampleRateChangeHandler(float sampleRate, void* ctx) { - RadioModule* _this = (RadioModule*)ctx; - _this->setAudioSampleRate(sampleRate); - } - static void ifChainOutputChangeHandler(dsp::stream* output, void* ctx) { RadioModule* _this = (RadioModule*)ctx; if (!_this->selectedDemod) { return; } @@ -643,7 +615,6 @@ private: // Handlers EventHandler onUserChangedBandwidthHandler; - EventHandler srChangeHandler; EventHandler*> ifChainOutputChanged; EventHandler*> afChainOutputChanged; @@ -658,10 +629,9 @@ private: // Audio chain dsp::stream dummyAudioStream; dsp::chain afChain; - dsp::multirate::RationalResampler resamp; dsp::filter::Deemphasis deemp; - SinkManager::Stream stream; + std::shared_ptr stream; demod::Demodulator* selectedDemod = NULL;