mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-06-25 12:07:49 +02:00
lots o shit
This commit is contained in:
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "../demod.h"
|
||||
#include <dsp/demodulator.h>
|
||||
#include <dsp/filter.h>
|
||||
#include <dsp/demod/am.h>
|
||||
#include <dsp/convert/mono_to_stereo.h>
|
||||
|
||||
namespace demod {
|
||||
class AM : public Demodulator {
|
||||
@ -20,20 +20,17 @@ namespace demod {
|
||||
this->name = name;
|
||||
|
||||
// Define structure
|
||||
demod.init(input);
|
||||
agc.init(&demod.out, 20.0f, getIFSampleRate());
|
||||
m2s.init(&agc.out);
|
||||
demod.init(input, dsp::demod::AM::AGCMode::CARRIER, 200000.0 / getIFSampleRate());
|
||||
m2s.init(&demod.out);
|
||||
}
|
||||
|
||||
void start() {
|
||||
demod.start();
|
||||
agc.start();
|
||||
m2s.start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
demod.stop();
|
||||
agc.stop();
|
||||
m2s.stop();
|
||||
}
|
||||
|
||||
@ -71,9 +68,8 @@ namespace demod {
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
dsp::AMDemod demod;
|
||||
dsp::AGC agc;
|
||||
dsp::MonoToStereo m2s;
|
||||
dsp::demod::AM demod;
|
||||
dsp::convert::MonoToStereo m2s;
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
#include "../demod.h"
|
||||
#include <dsp/demodulator.h>
|
||||
#include <dsp/filter.h>
|
||||
#include <dsp/channel/frequency_xlator.h>
|
||||
#include <dsp/convert/complex_to_real.h>
|
||||
#include <dsp/convert/mono_to_stereo.h>
|
||||
#include <dsp/loop/agc.h>
|
||||
|
||||
namespace demod {
|
||||
class CW : public Demodulator {
|
||||
@ -30,9 +32,9 @@ namespace demod {
|
||||
config->release();
|
||||
|
||||
// Define structure
|
||||
xlator.init(input, getIFSampleRate(), tone);
|
||||
xlator.init(input, tone, getIFSampleRate());
|
||||
c2r.init(&xlator.out);
|
||||
agc.init(&c2r.out, 20.0f, getIFSampleRate());
|
||||
agc.init(&c2r.out, 1.0, 200000.0 / getIFSampleRate());
|
||||
m2s.init(&agc.out);
|
||||
}
|
||||
|
||||
@ -55,7 +57,7 @@ namespace demod {
|
||||
ImGui::FillWidth();
|
||||
if (ImGui::InputInt(("Stereo##_radio_cw_tone_" + name).c_str(), &tone, 10, 100)) {
|
||||
tone = std::clamp<int>(tone, 250, 1250);
|
||||
xlator.setFrequency(tone);
|
||||
xlator.setOffset(tone, getIFSampleRate());
|
||||
afbwChangeHandler.handler(getAFBandwidth(_bandwidth), afbwChangeHandler.ctx);
|
||||
_config->acquire();
|
||||
_config->conf[name][getName()]["tone"] = tone;
|
||||
@ -94,10 +96,10 @@ namespace demod {
|
||||
|
||||
private:
|
||||
ConfigManager* _config = NULL;
|
||||
dsp::FrequencyXlator<dsp::complex_t> xlator;
|
||||
dsp::ComplexToReal c2r;
|
||||
dsp::AGC agc;
|
||||
dsp::MonoToStereo m2s;
|
||||
dsp::channel::FrequencyXlator xlator;
|
||||
dsp::convert::ComplexToReal c2r;
|
||||
dsp::loop::AGC<float> agc;
|
||||
dsp::convert::MonoToStereo m2s;
|
||||
|
||||
std::string name;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "../demod.h"
|
||||
#include <dsp/demodulator.h>
|
||||
#include <dsp/filter.h>
|
||||
#include <dsp/demod/ssb.h>
|
||||
#include <dsp/convert/mono_to_stereo.h>
|
||||
|
||||
namespace demod {
|
||||
class DSB : public Demodulator {
|
||||
@ -20,20 +20,17 @@ namespace demod {
|
||||
this->name = name;
|
||||
|
||||
// Define structure
|
||||
demod.init(input, getIFSampleRate(), bandwidth, dsp::SSBDemod::MODE_DSB);
|
||||
agc.init(&demod.out, 20.0f, getIFSampleRate());
|
||||
m2s.init(&agc.out);
|
||||
demod.init(input, dsp::demod::SSB::Mode::DSB, bandwidth, getIFSampleRate(), 200000.0 / getIFSampleRate());
|
||||
m2s.init(&demod.out);
|
||||
}
|
||||
|
||||
void start() {
|
||||
demod.start();
|
||||
agc.start();
|
||||
m2s.start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
demod.stop();
|
||||
agc.stop();
|
||||
m2s.stop();
|
||||
}
|
||||
|
||||
@ -42,7 +39,7 @@ namespace demod {
|
||||
}
|
||||
|
||||
void setBandwidth(double bandwidth) {
|
||||
demod.setBandWidth(bandwidth);
|
||||
demod.setBandwidth(bandwidth);
|
||||
}
|
||||
|
||||
void setInput(dsp::stream<dsp::complex_t>* input) {
|
||||
@ -73,9 +70,8 @@ namespace demod {
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
dsp::SSBDemod demod;
|
||||
dsp::AGC agc;
|
||||
dsp::MonoToStereo m2s;
|
||||
dsp::demod::SSB demod;
|
||||
dsp::convert::MonoToStereo m2s;
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "../demod.h"
|
||||
#include <dsp/demodulator.h>
|
||||
#include <dsp/filter.h>
|
||||
#include <dsp/demod/ssb.h>
|
||||
#include <dsp/convert/mono_to_stereo.h>
|
||||
|
||||
namespace demod {
|
||||
class LSB : public Demodulator {
|
||||
@ -20,20 +20,17 @@ namespace demod {
|
||||
this->name = name;
|
||||
|
||||
// Define structure
|
||||
demod.init(input, getIFSampleRate(), bandwidth, dsp::SSBDemod::MODE_LSB);
|
||||
agc.init(&demod.out, 20.0f, getIFSampleRate());
|
||||
m2s.init(&agc.out);
|
||||
demod.init(input, dsp::demod::SSB::Mode::LSB, bandwidth, getIFSampleRate(), 200000.0 / getIFSampleRate());
|
||||
m2s.init(&demod.out);
|
||||
}
|
||||
|
||||
void start() {
|
||||
demod.start();
|
||||
agc.start();
|
||||
m2s.start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
demod.stop();
|
||||
agc.stop();
|
||||
m2s.stop();
|
||||
}
|
||||
|
||||
@ -42,7 +39,7 @@ namespace demod {
|
||||
}
|
||||
|
||||
void setBandwidth(double bandwidth) {
|
||||
demod.setBandWidth(bandwidth);
|
||||
demod.setBandwidth(bandwidth);
|
||||
}
|
||||
|
||||
void setInput(dsp::stream<dsp::complex_t>* input) {
|
||||
@ -73,9 +70,8 @@ namespace demod {
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
dsp::SSBDemod demod;
|
||||
dsp::AGC agc;
|
||||
dsp::MonoToStereo m2s;
|
||||
dsp::demod::SSB demod;
|
||||
dsp::convert::MonoToStereo m2s;
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "../demod.h"
|
||||
#include <dsp/demodulator.h>
|
||||
#include <dsp/filter.h>
|
||||
#include <dsp/demod/fm.h>
|
||||
#include <dsp/convert/mono_to_stereo.h>
|
||||
|
||||
namespace demod {
|
||||
class NFM : public Demodulator {
|
||||
@ -20,21 +20,24 @@ namespace demod {
|
||||
this->name = name;
|
||||
|
||||
// Define structure
|
||||
demod.init(input, getIFSampleRate(), bandwidth / 2.0f);
|
||||
demod.init(input, bandwidth / 2.0, getIFSampleRate());
|
||||
m2s.init(&demod.out);
|
||||
}
|
||||
|
||||
void start() {
|
||||
demod.start();
|
||||
m2s.start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
demod.stop();
|
||||
m2s.stop();
|
||||
}
|
||||
|
||||
void showMenu() {}
|
||||
|
||||
void setBandwidth(double bandwidth) {
|
||||
demod.setDeviation(bandwidth / 2.0f);
|
||||
demod.setDeviation(bandwidth / 2.0, getIFSampleRate());
|
||||
}
|
||||
|
||||
void setInput(dsp::stream<dsp::complex_t>* input) {
|
||||
@ -62,10 +65,11 @@ namespace demod {
|
||||
bool getDynamicAFBandwidth() { return true; }
|
||||
bool getFMIFNRAllowed() { return true; }
|
||||
bool getNBAllowed() { return false; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
dsp::FMDemod demod;
|
||||
dsp::demod::FM demod;
|
||||
dsp::convert::MonoToStereo m2s;
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "../demod.h"
|
||||
#include <dsp/demodulator.h>
|
||||
#include <dsp/filter.h>
|
||||
#include <dsp/convert/complex_to_stereo.h>
|
||||
|
||||
namespace demod {
|
||||
class RAW : public Demodulator {
|
||||
@ -67,7 +66,7 @@ namespace demod {
|
||||
|
||||
private:
|
||||
double audioSampleRate;
|
||||
dsp::ComplexToStereo c2s;
|
||||
dsp::convert::ComplexToStereo c2s;
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include "../demod.h"
|
||||
#include <dsp/demodulator.h>
|
||||
#include <dsp/filter.h>
|
||||
#include <dsp/demod/ssb.h>
|
||||
#include <dsp/convert/mono_to_stereo.h>
|
||||
|
||||
namespace demod {
|
||||
class USB : public Demodulator {
|
||||
@ -20,20 +20,17 @@ namespace demod {
|
||||
this->name = name;
|
||||
|
||||
// Define structure
|
||||
demod.init(input, getIFSampleRate(), bandwidth, dsp::SSBDemod::MODE_USB);
|
||||
agc.init(&demod.out, 20.0f, getIFSampleRate());
|
||||
m2s.init(&agc.out);
|
||||
demod.init(input, dsp::demod::SSB::Mode::USB, bandwidth, getIFSampleRate(), 200000.0 / getIFSampleRate());
|
||||
m2s.init(&demod.out);
|
||||
}
|
||||
|
||||
void start() {
|
||||
demod.start();
|
||||
agc.start();
|
||||
m2s.start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
demod.stop();
|
||||
agc.stop();
|
||||
m2s.stop();
|
||||
}
|
||||
|
||||
@ -42,7 +39,7 @@ namespace demod {
|
||||
}
|
||||
|
||||
void setBandwidth(double bandwidth) {
|
||||
demod.setBandWidth(bandwidth);
|
||||
demod.setBandwidth(bandwidth);
|
||||
}
|
||||
|
||||
void setInput(dsp::stream<dsp::complex_t>* input) {
|
||||
@ -73,9 +70,8 @@ namespace demod {
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
dsp::SSBDemod demod;
|
||||
dsp::AGC agc;
|
||||
dsp::MonoToStereo m2s;
|
||||
dsp::demod::SSB demod;
|
||||
dsp::convert::MonoToStereo m2s;
|
||||
|
||||
std::string name;
|
||||
};
|
||||
|
@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
#include "../demod.h"
|
||||
#include <dsp/demodulator.h>
|
||||
#include <dsp/filter.h>
|
||||
#include <dsp/demod/broadcast_fm.h>
|
||||
|
||||
namespace demod {
|
||||
class WFM : public Demodulator {
|
||||
@ -25,41 +24,37 @@ namespace demod {
|
||||
_config->acquire();
|
||||
bool modified = false;
|
||||
if (config->conf[name][getName()].contains("stereo")) {
|
||||
stereo = config->conf[name][getName()]["stereo"];
|
||||
_stereo = config->conf[name][getName()]["stereo"];
|
||||
}
|
||||
_config->release(modified);
|
||||
|
||||
// Define structure
|
||||
demod.init(input, getIFSampleRate(), bandwidth / 2.0f);
|
||||
demodStereo.init(input, getIFSampleRate(), bandwidth / 2.0f);
|
||||
demod.init(input, bandwidth / 2.0f, getIFSampleRate(), _stereo);
|
||||
}
|
||||
|
||||
void start() {
|
||||
stereo ? demodStereo.start() : demod.start();
|
||||
demod.start();
|
||||
}
|
||||
|
||||
void stop() {
|
||||
demod.stop();
|
||||
demodStereo.stop();
|
||||
}
|
||||
|
||||
void showMenu() {
|
||||
if (ImGui::Checkbox(("Stereo##_radio_wfm_stereo_" + name).c_str(), &stereo)) {
|
||||
setStereo(stereo);
|
||||
if (ImGui::Checkbox(("Stereo##_radio_wfm_stereo_" + name).c_str(), &_stereo)) {
|
||||
setStereo(_stereo);
|
||||
_config->acquire();
|
||||
_config->conf[name][getName()]["stereo"] = stereo;
|
||||
_config->conf[name][getName()]["stereo"] = _stereo;
|
||||
_config->release(true);
|
||||
}
|
||||
}
|
||||
|
||||
void setBandwidth(double bandwidth) {
|
||||
demod.setDeviation(bandwidth / 2.0f);
|
||||
demodStereo.setDeviation(bandwidth / 2.0f);
|
||||
}
|
||||
|
||||
void setInput(dsp::stream<dsp::complex_t>* input) {
|
||||
demod.setInput(input);
|
||||
demodStereo.setInput(input);
|
||||
}
|
||||
|
||||
void AFSampRateChanged(double newSR) {}
|
||||
@ -83,31 +78,21 @@ namespace demod {
|
||||
bool getDynamicAFBandwidth() { return false; }
|
||||
bool getFMIFNRAllowed() { return true; }
|
||||
bool getNBAllowed() { return false; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return stereo ? demodStereo.out : &demod.out; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; }
|
||||
|
||||
// ============= DEDICATED FUNCTIONS =============
|
||||
|
||||
void setStereo(bool _stereo) {
|
||||
stereo = _stereo;
|
||||
if (stereo) {
|
||||
demod.stop();
|
||||
outputChangeHandler.handler(demodStereo.out, outputChangeHandler.ctx);
|
||||
demodStereo.start();
|
||||
}
|
||||
else {
|
||||
demodStereo.stop();
|
||||
outputChangeHandler.handler(&demod.out, outputChangeHandler.ctx);
|
||||
demod.start();
|
||||
}
|
||||
void setStereo(bool stereo) {
|
||||
_stereo = stereo;
|
||||
demod.setStereo(_stereo);
|
||||
}
|
||||
|
||||
private:
|
||||
dsp::FMDemod demod;
|
||||
dsp::StereoFMDemod demodStereo;
|
||||
dsp::demod::BroadcastFM demod;
|
||||
|
||||
ConfigManager* _config = NULL;
|
||||
|
||||
bool stereo = false;
|
||||
bool _stereo = false;
|
||||
|
||||
std::string name;
|
||||
EventHandler<dsp::stream<dsp::stereo_t>*> outputChangeHandler;
|
||||
|
@ -6,7 +6,10 @@
|
||||
#include <signal_path/signal_path.h>
|
||||
#include <config.h>
|
||||
#include <dsp/chain.h>
|
||||
#include <dsp/noise_reduction.h>
|
||||
#include <dsp/noise_reduction/fm_if.h>
|
||||
#include <dsp/noise_reduction/squelch.h>
|
||||
#include <dsp/multirate/rational_resampler.h>
|
||||
#include <dsp/filter/deephasis.h>
|
||||
#include <core.h>
|
||||
#include <utils/optionlist.h>
|
||||
#include "radio_interface.h"
|
||||
@ -74,17 +77,13 @@ public:
|
||||
// Initialize IF DSP chain
|
||||
ifChainOutputChanged.ctx = this;
|
||||
ifChainOutputChanged.handler = ifChainOutputChangeHandler;
|
||||
ifChain.init(vfo->output, &ifChainOutputChanged);
|
||||
ifChain.init(vfo->output);
|
||||
|
||||
fmnr.block.init(NULL, 32);
|
||||
notch.block.init(NULL, 0.5, 0, 250000); // TODO: The rate has to depend on IF sample rate so the width is always the same
|
||||
squelch.block.init(NULL, MIN_SQUELCH);
|
||||
nb.block.init(NULL, -100.0f);
|
||||
fmnr.init(NULL, 32);
|
||||
squelch.init(NULL, MIN_SQUELCH);
|
||||
|
||||
ifChain.add(¬ch);
|
||||
ifChain.add(&squelch);
|
||||
ifChain.add(&fmnr);
|
||||
ifChain.add(&nb);
|
||||
ifChain.addBlock(&squelch, false);
|
||||
ifChain.addBlock(&fmnr, false);
|
||||
|
||||
// Load configuration for and enabled all demodulators
|
||||
EventHandler<dsp::stream<dsp::stereo_t>*> _demodOutputChangeHandler;
|
||||
@ -107,26 +106,22 @@ public:
|
||||
bw = std::clamp<double>(bw, demod->getMinBandwidth(), demod->getMaxBandwidth());
|
||||
|
||||
// Initialize
|
||||
demod->init(name, &config, ifChain.getOutput(), bw, _demodOutputChangeHandler, _demodAfbwChangedHandler, stream.getSampleRate());
|
||||
demod->init(name, &config, ifChain.out, bw, _demodOutputChangeHandler, _demodAfbwChangedHandler, stream.getSampleRate());
|
||||
}
|
||||
|
||||
// Initialize audio DSP chain
|
||||
afChainOutputChanged.ctx = this;
|
||||
afChainOutputChanged.handler = afChainOutputChangeHandler;
|
||||
afChain.init(&dummyAudioStream, &afChainOutputChanged);
|
||||
afChain.init(&dummyAudioStream);
|
||||
|
||||
win.init(24000, 24000, 48000);
|
||||
resamp.block.init(NULL, &win, 250000, 48000);
|
||||
deemp.block.init(NULL, 48000, 50e-6);
|
||||
deemp.block.bypass = false;
|
||||
resamp.init(NULL, 250000.0, 48000.0);
|
||||
deemp.init(NULL, 50e-6, 48000.0);
|
||||
|
||||
afChain.add(&resamp);
|
||||
afChain.add(&deemp);
|
||||
afChain.addBlock(&resamp, true);
|
||||
afChain.addBlock(&deemp, false);
|
||||
|
||||
// Initialize the sink
|
||||
srChangeHandler.ctx = this;
|
||||
srChangeHandler.handler = sampleRateChangeHandler;
|
||||
stream.init(afChain.getOutput(), &srChangeHandler, audioSampleRate);
|
||||
stream.init(afChain.out, &srChangeHandler, audioSampleRate);
|
||||
sigpath::sinkManager.registerStream(name, &stream);
|
||||
|
||||
// Select the demodulator
|
||||
@ -165,7 +160,7 @@ public:
|
||||
vfo = sigpath::vfoManager.createVFO(name, ImGui::WaterfallVFO::REF_CENTER, 0, 200000, 200000, 50000, 200000, false);
|
||||
vfo->wtfVFO->onUserChangedBandwidth.bindHandler(&onUserChangedBandwidthHandler);
|
||||
}
|
||||
ifChain.setInput(vfo->output);
|
||||
ifChain.setInput(vfo->output, [=](dsp::stream<dsp::complex_t>* out){ ifChainOutputChangeHandler(out, this); });
|
||||
ifChain.start();
|
||||
selectDemodByID((DemodID)selectedDemodID);
|
||||
afChain.start();
|
||||
@ -280,32 +275,6 @@ private:
|
||||
}
|
||||
if (!_this->squelchEnabled && _this->enabled) { style::endDisabled(); }
|
||||
|
||||
// Noise blanker
|
||||
if (_this->nbAllowed) {
|
||||
if (ImGui::Checkbox(("Noise Blanker##_radio_nb_ena_" + _this->name).c_str(), &_this->nbEnabled)) {
|
||||
_this->setNoiseBlankerEnabled(_this->nbEnabled);
|
||||
}
|
||||
if (!_this->nbEnabled && _this->enabled) { style::beginDisabled(); }
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||
if (ImGui::SliderFloat(("##_radio_nb_lvl_" + _this->name).c_str(), &_this->nbLevel, 0.0f, -100.0f, "%.3fdB")) {
|
||||
_this->setNoiseBlankerLevel(_this->nbLevel);
|
||||
}
|
||||
if (!_this->nbEnabled && _this->enabled) { style::endDisabled(); }
|
||||
}
|
||||
|
||||
|
||||
// // Notch filter
|
||||
// if (ImGui::Checkbox("Notch##_radio_notch_ena_", &_this->notchEnabled)) {
|
||||
// _this->ifChain.setState(&_this->notch, _this->notchEnabled);
|
||||
// }
|
||||
// if (ImGui::SliderFloat(("NF##_radio_notch_freq_" + _this->name).c_str(), &_this->notchPos, -7500, 7500)) {
|
||||
// _this->notch.block.setOffset(_this->notchPos);
|
||||
// }
|
||||
// if (ImGui::SliderFloat(("NW##_radio_notch_width_" + _this->name).c_str(), &_this->notchWidth, 0, 1000)) {
|
||||
// // TODO: Implement
|
||||
// }
|
||||
|
||||
// FM IF Noise Reduction
|
||||
if (_this->FMIFNRAllowed) {
|
||||
if (ImGui::Checkbox(("IF Noise Reduction##_radio_fmifnr_ena_" + _this->name).c_str(), &_this->FMIFNREnabled)) {
|
||||
@ -352,10 +321,10 @@ private:
|
||||
selectedDemod->AFSampRateChanged(audioSampleRate);
|
||||
|
||||
// Set the demodulator's input
|
||||
selectedDemod->setInput(ifChain.getOutput());
|
||||
selectedDemod->setInput(ifChain.out);
|
||||
|
||||
// Set AF chain's input
|
||||
afChain.setInput(selectedDemod->getOutput());
|
||||
afChain.setInput(selectedDemod->getOutput(), [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
||||
|
||||
// Load config
|
||||
bandwidth = selectedDemod->getDefaultBandwidth();
|
||||
@ -433,31 +402,24 @@ private:
|
||||
setIFNRPreset((selectedDemodID == RADIO_DEMOD_NFM) ? ifnrPresets[fmIFPresetId] : IFNR_PRESET_BROADCAST);
|
||||
setFMIFNREnabled(FMIFNRAllowed ? FMIFNREnabled : false);
|
||||
|
||||
// Configure notch
|
||||
notch.block.setSampleRate(selectedDemod->getIFSampleRate());
|
||||
|
||||
// Configure squelch
|
||||
squelch.block.setLevel(squelchLevel);
|
||||
squelch.setLevel(squelchLevel);
|
||||
setSquelchEnabled(squelchEnabled);
|
||||
|
||||
// Configure noise blanker
|
||||
nb.block.setLevel(nbLevel);
|
||||
setNoiseBlankerEnabled(nbEnabled);
|
||||
|
||||
// Configure AF chain
|
||||
if (postProcEnabled) {
|
||||
// Configure resampler
|
||||
afChain.stop();
|
||||
resamp.block.setInSampleRate(selectedDemod->getAFSampleRate());
|
||||
resamp.setInSamplerate(selectedDemod->getAFSampleRate());
|
||||
setAudioSampleRate(audioSampleRate);
|
||||
afChain.enable(&resamp);
|
||||
afChain.enableBlock(&resamp, [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
||||
|
||||
// Configure deemphasis
|
||||
setDeemphasisMode(deempModes[deempId]);
|
||||
}
|
||||
else {
|
||||
// Disable everything if post processing is disabled
|
||||
afChain.disableAll();
|
||||
afChain.disableAllBlocks([=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
||||
}
|
||||
|
||||
// Start new demodulator
|
||||
@ -474,12 +436,12 @@ private:
|
||||
vfo->setBandwidth(bandwidth);
|
||||
selectedDemod->setBandwidth(bandwidth);
|
||||
|
||||
// Only bother with setting the resampling setting if we're actually post processing and dynamic bw is enabled
|
||||
if (selectedDemod->getDynamicAFBandwidth() && postProcEnabled) {
|
||||
win.setCutoff(audioBW);
|
||||
win.setTransWidth(audioBW);
|
||||
resamp.block.updateWindow(&win);
|
||||
}
|
||||
// // Only bother with setting the resampling setting if we're actually post processing and dynamic bw is enabled
|
||||
// if (selectedDemod->getDynamicAFBandwidth() && postProcEnabled) {
|
||||
// win.setCutoff(audioBW);
|
||||
// win.setTransWidth(audioBW);
|
||||
// resamp.block.updateWindow(&win);
|
||||
// }
|
||||
|
||||
config.acquire();
|
||||
config.conf[name][selectedDemod->getName()]["bandwidth"] = bandwidth;
|
||||
@ -504,15 +466,16 @@ private:
|
||||
|
||||
afChain.stop();
|
||||
|
||||
// Configure resampler
|
||||
resamp.block.setOutSampleRate(audioSampleRate);
|
||||
win.setSampleRate(selectedDemod->getAFSampleRate() * resamp.block.getInterpolation());
|
||||
win.setCutoff(audioBW);
|
||||
win.setTransWidth(audioBW);
|
||||
resamp.block.updateWindow(&win);
|
||||
// // Configure resampler
|
||||
// resamp.block.setOutSampleRate(audioSampleRate);
|
||||
// win.setSampleRate(selectedDemod->getAFSampleRate() * resamp.block.getInterpolation());
|
||||
// win.setCutoff(audioBW);
|
||||
// win.setTransWidth(audioBW);
|
||||
// resamp.block.updateWindow(&win);
|
||||
resamp.setOutSamplerate(audioSampleRate);
|
||||
|
||||
// Configure deemphasis sample rate
|
||||
deemp.block.setSampleRate(audioSampleRate);
|
||||
deemp.setSamplerate(audioSampleRate);
|
||||
|
||||
afChain.start();
|
||||
}
|
||||
@ -521,8 +484,8 @@ private:
|
||||
deempId = deempModes.valueId(mode);
|
||||
if (!postProcEnabled || !selectedDemod) { return; }
|
||||
bool deempEnabled = (mode != DEEMP_MODE_NONE);
|
||||
if (deempEnabled) { deemp.block.setTau(deempTaus[mode]); }
|
||||
afChain.setState(&deemp, deempEnabled);
|
||||
if (deempEnabled) { deemp.setTau(deempTaus[mode]); }
|
||||
afChain.setBlockEnabled(&deemp, deempEnabled, [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); });
|
||||
|
||||
// Save config
|
||||
config.acquire();
|
||||
@ -533,7 +496,7 @@ private:
|
||||
void setSquelchEnabled(bool enable) {
|
||||
squelchEnabled = enable;
|
||||
if (!selectedDemod) { return; }
|
||||
ifChain.setState(&squelch, squelchEnabled);
|
||||
ifChain.setBlockEnabled(&squelch, squelchEnabled, [=](dsp::stream<dsp::complex_t>* out){ selectedDemod->setInput(out); });
|
||||
|
||||
// Save config
|
||||
config.acquire();
|
||||
@ -543,7 +506,7 @@ private:
|
||||
|
||||
void setSquelchLevel(float level) {
|
||||
squelchLevel = std::clamp<float>(level, MIN_SQUELCH, MAX_SQUELCH);
|
||||
squelch.block.setLevel(squelchLevel);
|
||||
squelch.setLevel(squelchLevel);
|
||||
|
||||
// Save config
|
||||
config.acquire();
|
||||
@ -554,7 +517,7 @@ private:
|
||||
void setFMIFNREnabled(bool enabled) {
|
||||
FMIFNREnabled = enabled;
|
||||
if (!selectedDemod) { return; }
|
||||
ifChain.setState(&fmnr, FMIFNREnabled);
|
||||
ifChain.setBlockEnabled(&fmnr, FMIFNREnabled, [=](dsp::stream<dsp::complex_t>* out){ selectedDemod->setInput(out); });
|
||||
|
||||
// Save config
|
||||
config.acquire();
|
||||
@ -562,39 +525,17 @@ private:
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
void setNoiseBlankerEnabled(bool enabled) {
|
||||
nbEnabled = enabled;
|
||||
if (!selectedDemod) { return; }
|
||||
ifChain.setState(&nb, nbEnabled);
|
||||
|
||||
// Save config
|
||||
config.acquire();
|
||||
config.conf[name][selectedDemod->getName()]["noiseBlankerEnabled"] = nbEnabled;
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
void setNoiseBlankerLevel(float level) {
|
||||
nbLevel = level;
|
||||
if (!selectedDemod) { return; }
|
||||
nb.block.setLevel(nbLevel);
|
||||
|
||||
// Save config
|
||||
config.acquire();
|
||||
config.conf[name][selectedDemod->getName()]["noiseBlankerLevel"] = nbLevel;
|
||||
config.release(true);
|
||||
}
|
||||
|
||||
void setIFNRPreset(IFNRPreset preset) {
|
||||
// Don't save if in broadcast mode
|
||||
if (preset == IFNR_PRESET_BROADCAST) {
|
||||
if (!selectedDemod) { return; }
|
||||
fmnr.block.setTapCount(ifnrTaps[preset]);
|
||||
fmnr.setBins(ifnrTaps[preset]);
|
||||
return;
|
||||
}
|
||||
|
||||
fmIFPresetId = ifnrPresets.valueId(preset);
|
||||
if (!selectedDemod) { return; }
|
||||
fmnr.block.setTapCount(ifnrTaps[preset]);
|
||||
fmnr.setBins(ifnrTaps[preset]);
|
||||
|
||||
// Save config
|
||||
config.acquire();
|
||||
@ -614,7 +555,7 @@ private:
|
||||
|
||||
static void demodOutputChangeHandler(dsp::stream<dsp::stereo_t>* output, void* ctx) {
|
||||
RadioModule* _this = (RadioModule*)ctx;
|
||||
_this->afChain.setInput(output);
|
||||
_this->afChain.setInput(output, [=](dsp::stream<dsp::stereo_t>* out){ _this->stream.setInput(out); });
|
||||
}
|
||||
|
||||
static void demodAfbwChangedHandler(float output, void* ctx) {
|
||||
@ -623,9 +564,9 @@ private:
|
||||
float audioBW = std::min<float>(_this->selectedDemod->getMaxAFBandwidth(), _this->selectedDemod->getAFBandwidth(_this->bandwidth));
|
||||
audioBW = std::min<float>(audioBW, _this->audioSampleRate / 2.0);
|
||||
|
||||
_this->win.setCutoff(audioBW);
|
||||
_this->win.setTransWidth(audioBW);
|
||||
_this->resamp.block.updateWindow(&_this->win);
|
||||
// _this->win.setCutoff(audioBW);
|
||||
// _this->win.setTransWidth(audioBW);
|
||||
// _this->resamp.block.updateWindow(&_this->win);
|
||||
}
|
||||
|
||||
static void ifChainOutputChangeHandler(dsp::stream<dsp::complex_t>* output, void* ctx) {
|
||||
@ -634,11 +575,6 @@ private:
|
||||
_this->selectedDemod->setInput(output);
|
||||
}
|
||||
|
||||
static void afChainOutputChangeHandler(dsp::stream<dsp::stereo_t>* output, void* ctx) {
|
||||
RadioModule* _this = (RadioModule*)ctx;
|
||||
_this->stream.setInput(output);
|
||||
}
|
||||
|
||||
static void moduleInterfaceHandler(int code, void* in, void* out, void* ctx) {
|
||||
RadioModule* _this = (RadioModule*)ctx;
|
||||
if (!_this->enabled || !_this->selectedDemod) { return; }
|
||||
@ -694,18 +630,15 @@ private:
|
||||
VFOManager::VFO* vfo = NULL;
|
||||
|
||||
// IF chain
|
||||
dsp::Chain<dsp::complex_t> ifChain;
|
||||
dsp::ChainLink<dsp::FMIFNoiseReduction, dsp::complex_t> fmnr;
|
||||
dsp::ChainLink<dsp::NotchFilter, dsp::complex_t> notch;
|
||||
dsp::ChainLink<dsp::Squelch, dsp::complex_t> squelch;
|
||||
dsp::ChainLink<dsp::NoiseBlanker, dsp::complex_t> nb;
|
||||
dsp::chain<dsp::complex_t> ifChain;
|
||||
dsp::noise_reduction::FMIF fmnr;
|
||||
dsp::noise_reduction::Squelch squelch;
|
||||
|
||||
// Audio chain
|
||||
dsp::stream<dsp::stereo_t> dummyAudioStream;
|
||||
dsp::Chain<dsp::stereo_t> afChain;
|
||||
dsp::filter_window::BlackmanWindow win;
|
||||
dsp::ChainLink<dsp::PolyphaseResampler<dsp::stereo_t>, dsp::stereo_t> resamp;
|
||||
dsp::ChainLink<dsp::BFMDeemp, dsp::stereo_t> deemp;
|
||||
dsp::chain<dsp::stereo_t> afChain;
|
||||
dsp::multirate::RationalResampler<dsp::stereo_t> resamp;
|
||||
dsp::filter::Deemphasis<dsp::stereo_t> deemp;
|
||||
|
||||
SinkManager::Stream stream;
|
||||
|
||||
|
Reference in New Issue
Block a user