mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-01-30 19:34:45 +01:00
more work
This commit is contained in:
parent
2a741932e0
commit
4c584847de
@ -35,6 +35,9 @@ namespace streamsmenu {
|
|||||||
|
|
||||||
sink->showMenu();
|
sink->showMenu();
|
||||||
|
|
||||||
|
// Volume slider + mute button
|
||||||
|
|
||||||
|
|
||||||
ImGui::FillWidth();
|
ImGui::FillWidth();
|
||||||
if (ImGui::Button(CONCAT("Remove##sdrpp_streams_remove_type_", name))) {
|
if (ImGui::Button(CONCAT("Remove##sdrpp_streams_remove_type_", name))) {
|
||||||
sinksToBeRemoved.push_back(id);
|
sinksToBeRemoved.push_back(id);
|
||||||
@ -50,7 +53,7 @@ namespace streamsmenu {
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::FillWidth();
|
ImGui::FillWidth();
|
||||||
if (ImGui::Button(CONCAT("Add##sdrpp_streams_add_btn_", name))) {
|
if (ImGui::Button(CONCAT("Add##sdrpp_streams_add_btn_", name))) {
|
||||||
stream->addSink("Sink 2");
|
stream->addSink("Audio");
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
|
@ -144,7 +144,6 @@ AudioStream::AudioStream(StreamManager* manager, const std::string& name, dsp::s
|
|||||||
|
|
||||||
// Initialize DSP
|
// Initialize DSP
|
||||||
split.init(stream);
|
split.init(stream);
|
||||||
split.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioStream::~AudioStream() {
|
AudioStream::~AudioStream() {
|
||||||
@ -173,10 +172,13 @@ void AudioStream::setInput(dsp::stream<dsp::stereo_t>* stream, double samplerate
|
|||||||
this->samplerate = samplerate;
|
this->samplerate = samplerate;
|
||||||
|
|
||||||
// Stop DSP
|
// Stop DSP
|
||||||
|
if (running) {
|
||||||
split.stop();
|
split.stop();
|
||||||
for (auto& [id, sink] : sinks) {
|
for (auto& [id, sink] : sinks) {
|
||||||
sink->stopDSP();
|
sink->stopDSP();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Set input and samplerate
|
// Set input and samplerate
|
||||||
split.setInput(stream);
|
split.setInput(stream);
|
||||||
@ -185,10 +187,12 @@ void AudioStream::setInput(dsp::stream<dsp::stereo_t>* stream, double samplerate
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start DSP
|
// Start DSP
|
||||||
|
if (running) {
|
||||||
for (auto& [id, sink] : sinks) {
|
for (auto& [id, sink] : sinks) {
|
||||||
sink->startDSP();
|
sink->startDSP();
|
||||||
}
|
}
|
||||||
split.start();
|
split.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioStream::setSamplerate(double samplerate) {
|
void AudioStream::setSamplerate(double samplerate) {
|
||||||
@ -198,10 +202,12 @@ void AudioStream::setSamplerate(double samplerate) {
|
|||||||
this->samplerate = samplerate;
|
this->samplerate = samplerate;
|
||||||
|
|
||||||
// Stop DSP
|
// Stop DSP
|
||||||
|
if (running) {
|
||||||
split.stop();
|
split.stop();
|
||||||
for (auto& [id, sink] : sinks) {
|
for (auto& [id, sink] : sinks) {
|
||||||
sink->stopDSP();
|
sink->stopDSP();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set samplerate
|
// Set samplerate
|
||||||
for (auto& [id, sink] : sinks) {
|
for (auto& [id, sink] : sinks) {
|
||||||
@ -209,10 +215,12 @@ void AudioStream::setSamplerate(double samplerate) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start DSP
|
// Start DSP
|
||||||
|
if (running) {
|
||||||
for (auto& [id, sink] : sinks) {
|
for (auto& [id, sink] : sinks) {
|
||||||
sink->startDSP();
|
sink->startDSP();
|
||||||
}
|
}
|
||||||
split.start();
|
split.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& AudioStream::getName() const {
|
const std::string& AudioStream::getName() const {
|
||||||
@ -246,7 +254,7 @@ SinkID AudioStream::addSink(const std::string& type, SinkID id) {
|
|||||||
|
|
||||||
// Start the sink and DSP
|
// Start the sink and DSP
|
||||||
sink->startSink();
|
sink->startSink();
|
||||||
sink->startDSP();
|
if (running) { sink->startDSP(); }
|
||||||
|
|
||||||
// Bind the sinks's input
|
// Bind the sinks's input
|
||||||
split.bindStream(&sink->input);
|
split.bindStream(&sink->input);
|
||||||
@ -313,6 +321,36 @@ const std::map<SinkID, std::shared_ptr<SinkEntry>>& AudioStream::getSinks() cons
|
|||||||
return sinks;
|
return sinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioStream::startDSP() {
|
||||||
|
// TODO: Maybe add a different mutex for the stream?
|
||||||
|
std::unique_lock<std::shared_mutex> 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<std::shared_mutex> 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<AudioStream> StreamManager::createStream(const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) {
|
std::shared_ptr<AudioStream> StreamManager::createStream(const std::string& name, dsp::stream<dsp::stereo_t>* stream, double samplerate) {
|
||||||
std::unique_lock<std::shared_mutex> lck(streamsMtx);
|
std::unique_lock<std::shared_mutex> lck(streamsMtx);
|
||||||
|
|
||||||
|
@ -146,7 +146,6 @@ private:
|
|||||||
dsp::multirate::RationalResampler<dsp::stereo_t> resamp;
|
dsp::multirate::RationalResampler<dsp::stereo_t> resamp;
|
||||||
dsp::audio::Volume volumeAdjust;
|
dsp::audio::Volume volumeAdjust;
|
||||||
|
|
||||||
|
|
||||||
SinkProvider* provider = NULL;
|
SinkProvider* provider = NULL;
|
||||||
std::unique_ptr<Sink> sink;
|
std::unique_ptr<Sink> sink;
|
||||||
std::string type;
|
std::string type;
|
||||||
@ -216,6 +215,18 @@ public:
|
|||||||
*/
|
*/
|
||||||
const std::map<SinkID, std::shared_ptr<SinkEntry>>& getSinks() const;
|
const std::map<SinkID, std::shared_ptr<SinkEntry>>& 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
|
// Emitted when the samplerate of the stream was changed
|
||||||
NewEvent<double> onSamplerateChanged;
|
NewEvent<double> onSamplerateChanged;
|
||||||
// Emitted when a sink was added
|
// Emitted when a sink was added
|
||||||
@ -228,6 +239,7 @@ private:
|
|||||||
const std::string name;
|
const std::string name;
|
||||||
double samplerate;
|
double samplerate;
|
||||||
dsp::routing::Splitter<dsp::stereo_t> split;
|
dsp::routing::Splitter<dsp::stereo_t> split;
|
||||||
|
bool running = false;
|
||||||
|
|
||||||
std::map<SinkID, std::shared_ptr<SinkEntry>> sinks;
|
std::map<SinkID, std::shared_ptr<SinkEntry>> sinks;
|
||||||
std::shared_mutex sinksMtx;
|
std::shared_mutex sinksMtx;
|
||||||
|
@ -24,13 +24,12 @@ namespace demod {
|
|||||||
class Demodulator {
|
class Demodulator {
|
||||||
public:
|
public:
|
||||||
virtual ~Demodulator() {}
|
virtual ~Demodulator() {}
|
||||||
virtual void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) = 0;
|
virtual void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) = 0;
|
||||||
virtual void start() = 0;
|
virtual void start() = 0;
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
virtual void showMenu() = 0;
|
virtual void showMenu() = 0;
|
||||||
virtual void setBandwidth(double bandwidth) = 0;
|
virtual void setBandwidth(double bandwidth) = 0;
|
||||||
virtual void setInput(dsp::stream<dsp::complex_t>* input) = 0;
|
virtual void setInput(dsp::stream<dsp::complex_t>* input) = 0;
|
||||||
virtual void AFSampRateChanged(double newSR) = 0;
|
|
||||||
virtual const char* getName() = 0;
|
virtual const char* getName() = 0;
|
||||||
virtual double getIFSampleRate() = 0;
|
virtual double getIFSampleRate() = 0;
|
||||||
virtual double getAFSampleRate() = 0;
|
virtual double getAFSampleRate() = 0;
|
||||||
|
@ -7,13 +7,13 @@ namespace demod {
|
|||||||
public:
|
public:
|
||||||
AM() {}
|
AM() {}
|
||||||
|
|
||||||
AM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
AM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
init(name, config, input, bandwidth, audioSR);
|
init(name, config, input, bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~AM() { stop(); }
|
~AM() { stop(); }
|
||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
@ -68,8 +68,6 @@ namespace demod {
|
|||||||
|
|
||||||
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
||||||
|
|
||||||
void AFSampRateChanged(double newSR) {}
|
|
||||||
|
|
||||||
// ============= INFO =============
|
// ============= INFO =============
|
||||||
|
|
||||||
const char* getName() { return "AM"; }
|
const char* getName() { return "AM"; }
|
||||||
|
@ -7,15 +7,15 @@ namespace demod {
|
|||||||
public:
|
public:
|
||||||
CW() {}
|
CW() {}
|
||||||
|
|
||||||
CW(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
CW(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
init(name, config, input, bandwidth, audioSR);
|
init(name, config, input, bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~CW() {
|
~CW() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
this->_config = config;
|
this->_config = config;
|
||||||
this->afbwChangeHandler = afbwChangeHandler;
|
this->afbwChangeHandler = afbwChangeHandler;
|
||||||
@ -74,8 +74,6 @@ namespace demod {
|
|||||||
|
|
||||||
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
||||||
|
|
||||||
void AFSampRateChanged(double newSR) {}
|
|
||||||
|
|
||||||
// ============= INFO =============
|
// ============= INFO =============
|
||||||
|
|
||||||
const char* getName() { return "CW"; }
|
const char* getName() { return "CW"; }
|
||||||
|
@ -7,15 +7,15 @@ namespace demod {
|
|||||||
public:
|
public:
|
||||||
DSB() {}
|
DSB() {}
|
||||||
|
|
||||||
DSB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
DSB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
init(name, config, input, bandwidth, audioSR);
|
init(name, config, input, bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~DSB() {
|
~DSB() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
@ -61,8 +61,6 @@ namespace demod {
|
|||||||
|
|
||||||
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
||||||
|
|
||||||
void AFSampRateChanged(double newSR) {}
|
|
||||||
|
|
||||||
// ============= INFO =============
|
// ============= INFO =============
|
||||||
|
|
||||||
const char* getName() { return "DSB"; }
|
const char* getName() { return "DSB"; }
|
||||||
|
@ -7,15 +7,15 @@ namespace demod {
|
|||||||
public:
|
public:
|
||||||
LSB() {}
|
LSB() {}
|
||||||
|
|
||||||
LSB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
LSB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
init(name, config, input, bandwidth, audioSR);
|
init(name, config, input, bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~LSB() {
|
~LSB() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
@ -61,8 +61,6 @@ namespace demod {
|
|||||||
|
|
||||||
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
||||||
|
|
||||||
void AFSampRateChanged(double newSR) {}
|
|
||||||
|
|
||||||
// ============= INFO =============
|
// ============= INFO =============
|
||||||
|
|
||||||
const char* getName() { return "LSB"; }
|
const char* getName() { return "LSB"; }
|
||||||
|
@ -7,13 +7,13 @@ namespace demod {
|
|||||||
public:
|
public:
|
||||||
NFM() {}
|
NFM() {}
|
||||||
|
|
||||||
NFM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
NFM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
init(name, config, input, bandwidth, audioSR);
|
init(name, config, input, bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~NFM() { stop(); }
|
~NFM() { stop(); }
|
||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
this->_config = config;
|
this->_config = config;
|
||||||
|
|
||||||
@ -57,8 +57,6 @@ namespace demod {
|
|||||||
|
|
||||||
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
||||||
|
|
||||||
void AFSampRateChanged(double newSR) {}
|
|
||||||
|
|
||||||
// ============= INFO =============
|
// ============= INFO =============
|
||||||
|
|
||||||
const char* getName() { return "FM"; }
|
const char* getName() { return "FM"; }
|
||||||
|
@ -7,17 +7,18 @@ namespace demod {
|
|||||||
public:
|
public:
|
||||||
RAW() {}
|
RAW() {}
|
||||||
|
|
||||||
RAW(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
RAW(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
init(name, config, input, bandwidth, audioSR);
|
init(name, config, input, bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~RAW() {
|
~RAW() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
audioSampleRate = audioSR;
|
audioSampleRate = 48000;
|
||||||
|
// TODO: This needs to be selectable
|
||||||
|
|
||||||
// Define structure
|
// Define structure
|
||||||
c2s.init(input);
|
c2s.init(input);
|
||||||
@ -39,10 +40,6 @@ namespace demod {
|
|||||||
c2s.setInput(input);
|
c2s.setInput(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AFSampRateChanged(double newSR) {
|
|
||||||
audioSampleRate = newSR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============= INFO =============
|
// ============= INFO =============
|
||||||
|
|
||||||
const char* getName() { return "RAW"; }
|
const char* getName() { return "RAW"; }
|
||||||
|
@ -8,15 +8,15 @@ namespace demod {
|
|||||||
public:
|
public:
|
||||||
USB() {}
|
USB() {}
|
||||||
|
|
||||||
USB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
USB(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
init(name, config, input, bandwidth, audioSR);
|
init(name, config, input, bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~USB() {
|
~USB() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
@ -62,8 +62,6 @@ namespace demod {
|
|||||||
|
|
||||||
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
void setInput(dsp::stream<dsp::complex_t>* input) { demod.setInput(input); }
|
||||||
|
|
||||||
void AFSampRateChanged(double newSR) {}
|
|
||||||
|
|
||||||
// ============= INFO =============
|
// ============= INFO =============
|
||||||
|
|
||||||
const char* getName() { return "USB"; }
|
const char* getName() { return "USB"; }
|
||||||
|
@ -16,8 +16,8 @@ namespace demod {
|
|||||||
public:
|
public:
|
||||||
WFM() {}
|
WFM() {}
|
||||||
|
|
||||||
WFM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
WFM(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
init(name, config, input, bandwidth, audioSR);
|
init(name, config, input, bandwidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
~WFM() {
|
~WFM() {
|
||||||
@ -25,7 +25,7 @@ namespace demod {
|
|||||||
gui::waterfall.onFFTRedraw.unbindHandler(&fftRedrawHandler);
|
gui::waterfall.onFFTRedraw.unbindHandler(&fftRedrawHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth, double audioSR) {
|
void init(std::string name, ConfigManager* config, dsp::stream<dsp::complex_t>* input, double bandwidth) {
|
||||||
this->name = name;
|
this->name = name;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
|
||||||
@ -112,8 +112,6 @@ namespace demod {
|
|||||||
demod.setInput(input);
|
demod.setInput(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AFSampRateChanged(double newSR) {}
|
|
||||||
|
|
||||||
// ============= INFO =============
|
// ============= INFO =============
|
||||||
|
|
||||||
const char* getName() { return "WFM"; }
|
const char* getName() { return "WFM"; }
|
||||||
|
@ -81,30 +81,16 @@ public:
|
|||||||
// Initialize audio DSP chain
|
// Initialize audio DSP chain
|
||||||
afChain.init(&dummyAudioStream);
|
afChain.init(&dummyAudioStream);
|
||||||
|
|
||||||
resamp.init(NULL, 250000.0, 48000.0);
|
|
||||||
deemp.init(NULL, 50e-6, 48000.0);
|
deemp.init(NULL, 50e-6, 48000.0);
|
||||||
|
|
||||||
afChain.addBlock(&resamp, true);
|
|
||||||
afChain.addBlock(&deemp, false);
|
afChain.addBlock(&deemp, false);
|
||||||
|
|
||||||
// Initialize the sink
|
// Initialize the sink
|
||||||
srChangeHandler.ctx = this;
|
stream = sigpath::streamManager.createStream(name, afChain.out, 48000);
|
||||||
srChangeHandler.handler = sampleRateChangeHandler;
|
|
||||||
stream.init(afChain.out, &srChangeHandler, audioSampleRate);
|
|
||||||
sigpath::sinkManager.registerStream(name, &stream);
|
|
||||||
|
|
||||||
// Select the demodulator
|
// Select the demodulator
|
||||||
selectDemodByID((DemodID)selectedDemodID);
|
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
|
// Register the menu
|
||||||
gui::menu.registerEntry(name, menuHandler, this, this);
|
gui::menu.registerEntry(name, menuHandler, this, this);
|
||||||
|
|
||||||
@ -115,11 +101,10 @@ public:
|
|||||||
~RadioModule() {
|
~RadioModule() {
|
||||||
core::modComManager.unregisterInterface(name);
|
core::modComManager.unregisterInterface(name);
|
||||||
gui::menu.removeEntry(name);
|
gui::menu.removeEntry(name);
|
||||||
stream.stop();
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
disable();
|
disable();
|
||||||
}
|
}
|
||||||
sigpath::sinkManager.unregisterStream(name);
|
sigpath::streamManager.destroyStream(stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
void postInit() {}
|
void postInit() {}
|
||||||
@ -131,9 +116,7 @@ public:
|
|||||||
vfo->wtfVFO->onUserChangedBandwidth.bindHandler(&onUserChangedBandwidthHandler);
|
vfo->wtfVFO->onUserChangedBandwidth.bindHandler(&onUserChangedBandwidthHandler);
|
||||||
}
|
}
|
||||||
ifChain.setInput(vfo->output, [=](dsp::stream<dsp::complex_t>* out){ ifChainOutputChangeHandler(out, this); });
|
ifChain.setInput(vfo->output, [=](dsp::stream<dsp::complex_t>* out){ ifChainOutputChangeHandler(out, this); });
|
||||||
ifChain.start();
|
|
||||||
selectDemodByID((DemodID)selectedDemodID);
|
selectDemodByID((DemodID)selectedDemodID);
|
||||||
afChain.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable() {
|
void disable() {
|
||||||
@ -141,6 +124,7 @@ public:
|
|||||||
ifChain.stop();
|
ifChain.stop();
|
||||||
if (selectedDemod) { selectedDemod->stop(); }
|
if (selectedDemod) { selectedDemod->stop(); }
|
||||||
afChain.stop();
|
afChain.stop();
|
||||||
|
stream->stopDSP();
|
||||||
if (vfo) { sigpath::vfoManager.deleteVFO(vfo); }
|
if (vfo) { sigpath::vfoManager.deleteVFO(vfo); }
|
||||||
vfo = NULL;
|
vfo = NULL;
|
||||||
}
|
}
|
||||||
@ -313,7 +297,7 @@ private:
|
|||||||
bw = std::clamp<double>(bw, demod->getMinBandwidth(), demod->getMaxBandwidth());
|
bw = std::clamp<double>(bw, demod->getMinBandwidth(), demod->getMaxBandwidth());
|
||||||
|
|
||||||
// Initialize
|
// Initialize
|
||||||
demod->init(name, &config, ifChain.out, bw, stream.getSampleRate());
|
demod->init(name, &config, ifChain.out, bw);
|
||||||
|
|
||||||
return demod;
|
return demod;
|
||||||
}
|
}
|
||||||
@ -337,22 +321,34 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void selectDemod(demod::Demodulator* demod) {
|
void selectDemod(demod::Demodulator* demod) {
|
||||||
// Stopcurrently selected demodulator and select new
|
// Stop the IF chain
|
||||||
afChain.setInput(&dummyAudioStream, [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
ifChain.stop();
|
||||||
|
|
||||||
|
// Stop the current demodulator
|
||||||
if (selectedDemod) {
|
if (selectedDemod) {
|
||||||
selectedDemod->stop();
|
selectedDemod->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop AF chain
|
||||||
|
afChain.stop();
|
||||||
|
|
||||||
|
// Stop audio stream's DSP
|
||||||
|
stream->stopDSP();
|
||||||
|
|
||||||
|
// Destroy the old demodulator
|
||||||
|
afChain.setInput(&dummyAudioStream, [=](dsp::stream<dsp::stereo_t>* out){ stream->setInput(out); });
|
||||||
|
if (selectedDemod) {
|
||||||
delete selectedDemod;
|
delete selectedDemod;
|
||||||
}
|
}
|
||||||
selectedDemod = demod;
|
|
||||||
|
|
||||||
// Give the demodulator the most recent audio SR
|
// Select the new demodulator
|
||||||
selectedDemod->AFSampRateChanged(audioSampleRate);
|
selectedDemod = demod;
|
||||||
|
|
||||||
// Set the demodulator's input
|
// Set the demodulator's input
|
||||||
selectedDemod->setInput(ifChain.out);
|
selectedDemod->setInput(ifChain.out);
|
||||||
|
|
||||||
// Set AF chain's input
|
// Set AF chain's input
|
||||||
afChain.setInput(selectedDemod->getOutput(), [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
afChain.setInput(selectedDemod->getOutput(), [=](dsp::stream<dsp::stereo_t>* out){ stream->setInput(out); });
|
||||||
|
|
||||||
// Load config
|
// Load config
|
||||||
bandwidth = selectedDemod->getDefaultBandwidth();
|
bandwidth = selectedDemod->getDefaultBandwidth();
|
||||||
@ -440,21 +436,27 @@ private:
|
|||||||
// Configure AF chain
|
// Configure AF chain
|
||||||
if (postProcEnabled) {
|
if (postProcEnabled) {
|
||||||
// Configure resampler
|
// Configure resampler
|
||||||
afChain.stop();
|
deemp.setSamplerate(selectedDemod->getAFSampleRate());
|
||||||
resamp.setInSamplerate(selectedDemod->getAFSampleRate());
|
|
||||||
setAudioSampleRate(audioSampleRate);
|
|
||||||
afChain.enableBlock(&resamp, [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
|
||||||
|
|
||||||
// Configure deemphasis
|
// Configure deemphasis
|
||||||
setDeemphasisMode(deempModes[deempId]);
|
setDeemphasisMode(deempModes[deempId]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Disable everything if post processing is disabled
|
// Disable everything if post processing is disabled
|
||||||
afChain.disableAllBlocks([=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
afChain.disableAllBlocks([=](dsp::stream<dsp::stereo_t>* out){ stream->setInput(out); });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start the IF chain
|
||||||
|
ifChain.start();
|
||||||
|
|
||||||
// Start new demodulator
|
// Start new demodulator
|
||||||
selectedDemod->start();
|
selectedDemod->start();
|
||||||
|
|
||||||
|
// Start the AF chain
|
||||||
|
afChain.start();
|
||||||
|
|
||||||
|
// Start the audio stream
|
||||||
|
stream->startDSP();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -470,37 +472,12 @@ private:
|
|||||||
config.release(true);
|
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) {
|
void setDeemphasisMode(DeemphasisMode mode) {
|
||||||
deempId = deempModes.valueId(mode);
|
deempId = deempModes.valueId(mode);
|
||||||
if (!postProcEnabled || !selectedDemod) { return; }
|
if (!postProcEnabled || !selectedDemod) { return; }
|
||||||
bool deempEnabled = (mode != DEEMP_MODE_NONE);
|
bool deempEnabled = (mode != DEEMP_MODE_NONE);
|
||||||
if (deempEnabled) { deemp.setTau(deempTaus[mode]); }
|
if (deempEnabled) { deemp.setTau(deempTaus[mode]); }
|
||||||
afChain.setBlockEnabled(&deemp, deempEnabled, [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
afChain.setBlockEnabled(&deemp, deempEnabled, [=](dsp::stream<dsp::stereo_t>* out){ stream->setInput(out); });
|
||||||
|
|
||||||
// Save config
|
// Save config
|
||||||
config.acquire();
|
config.acquire();
|
||||||
@ -584,11 +561,6 @@ private:
|
|||||||
_this->setBandwidth(newBw);
|
_this->setBandwidth(newBw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sampleRateChangeHandler(float sampleRate, void* ctx) {
|
|
||||||
RadioModule* _this = (RadioModule*)ctx;
|
|
||||||
_this->setAudioSampleRate(sampleRate);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ifChainOutputChangeHandler(dsp::stream<dsp::complex_t>* output, void* ctx) {
|
static void ifChainOutputChangeHandler(dsp::stream<dsp::complex_t>* output, void* ctx) {
|
||||||
RadioModule* _this = (RadioModule*)ctx;
|
RadioModule* _this = (RadioModule*)ctx;
|
||||||
if (!_this->selectedDemod) { return; }
|
if (!_this->selectedDemod) { return; }
|
||||||
@ -643,7 +615,6 @@ private:
|
|||||||
|
|
||||||
// Handlers
|
// Handlers
|
||||||
EventHandler<double> onUserChangedBandwidthHandler;
|
EventHandler<double> onUserChangedBandwidthHandler;
|
||||||
EventHandler<float> srChangeHandler;
|
|
||||||
EventHandler<dsp::stream<dsp::complex_t>*> ifChainOutputChanged;
|
EventHandler<dsp::stream<dsp::complex_t>*> ifChainOutputChanged;
|
||||||
EventHandler<dsp::stream<dsp::stereo_t>*> afChainOutputChanged;
|
EventHandler<dsp::stream<dsp::stereo_t>*> afChainOutputChanged;
|
||||||
|
|
||||||
@ -658,10 +629,9 @@ private:
|
|||||||
// Audio chain
|
// Audio chain
|
||||||
dsp::stream<dsp::stereo_t> dummyAudioStream;
|
dsp::stream<dsp::stereo_t> dummyAudioStream;
|
||||||
dsp::chain<dsp::stereo_t> afChain;
|
dsp::chain<dsp::stereo_t> afChain;
|
||||||
dsp::multirate::RationalResampler<dsp::stereo_t> resamp;
|
|
||||||
dsp::filter::Deemphasis<dsp::stereo_t> deemp;
|
dsp::filter::Deemphasis<dsp::stereo_t> deemp;
|
||||||
|
|
||||||
SinkManager::Stream stream;
|
std::shared_ptr<AudioStream> stream;
|
||||||
|
|
||||||
demod::Demodulator* selectedDemod = NULL;
|
demod::Demodulator* selectedDemod = NULL;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user