mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2025-06-25 12:07:49 +02:00
Added a noise blanker for SSB and DSB
This commit is contained in:
@ -38,6 +38,7 @@ namespace demod {
|
||||
virtual int getDefaultDeemphasisMode() = 0;
|
||||
virtual double getAFBandwidth(double bandwidth) = 0;
|
||||
virtual bool getFMIFNRAllowed() = 0;
|
||||
virtual bool getNBAllowed() = 0;
|
||||
|
||||
virtual bool getDynamicAFBandwidth() = 0;
|
||||
virtual dsp::stream<dsp::stereo_t>* getOutput() = 0;
|
||||
|
@ -68,6 +68,7 @@ namespace demod {
|
||||
double getAFBandwidth(double bandwidth) { return bandwidth / 2.0; }
|
||||
bool getDynamicAFBandwidth() { return true; }
|
||||
bool getFMIFNRAllowed() { return false; }
|
||||
bool getNBAllowed() { return false; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
|
@ -69,6 +69,7 @@ namespace demod {
|
||||
double getAFBandwidth(double bandwidth) { return (bandwidth / 2.0) + 1000.0; }
|
||||
bool getDynamicAFBandwidth() { return true; }
|
||||
bool getFMIFNRAllowed() { return false; }
|
||||
bool getNBAllowed() { return false; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
|
@ -70,6 +70,7 @@ namespace demod {
|
||||
double getAFBandwidth(double bandwidth) { return bandwidth / 2.0; }
|
||||
bool getDynamicAFBandwidth() { return true; }
|
||||
bool getFMIFNRAllowed() { return false; }
|
||||
bool getNBAllowed() { return true; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
|
@ -70,6 +70,7 @@ namespace demod {
|
||||
double getAFBandwidth(double bandwidth) { return bandwidth; }
|
||||
bool getDynamicAFBandwidth() { return true; }
|
||||
bool getFMIFNRAllowed() { return false; }
|
||||
bool getNBAllowed() { return true; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
|
@ -62,6 +62,7 @@ namespace demod {
|
||||
double getAFBandwidth(double bandwidth) { return bandwidth / 2.0; }
|
||||
bool getDynamicAFBandwidth() { return true; }
|
||||
bool getFMIFNRAllowed() { return true; }
|
||||
bool getNBAllowed() { return false; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; }
|
||||
|
||||
private:
|
||||
|
@ -63,6 +63,7 @@ namespace demod {
|
||||
double getAFBandwidth(double bandwidth) { return bandwidth; }
|
||||
bool getDynamicAFBandwidth() { return false; }
|
||||
bool getFMIFNRAllowed() { return false; }
|
||||
bool getNBAllowed() { return true; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &c2s.out; }
|
||||
|
||||
private:
|
||||
|
@ -70,6 +70,7 @@ namespace demod {
|
||||
double getAFBandwidth(double bandwidth) { return bandwidth; }
|
||||
bool getDynamicAFBandwidth() { return true; }
|
||||
bool getFMIFNRAllowed() { return false; }
|
||||
bool getNBAllowed() { return true; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return &m2s.out; }
|
||||
|
||||
private:
|
||||
|
@ -86,6 +86,7 @@ namespace demod {
|
||||
double getAFBandwidth(double bandwidth) { return 16000.0; }
|
||||
bool getDynamicAFBandwidth() { return false; }
|
||||
bool getFMIFNRAllowed() { return true; }
|
||||
bool getNBAllowed() { return false; }
|
||||
dsp::stream<dsp::stereo_t>* getOutput() { return stereo ? demodStereo.out : &demod.out; }
|
||||
|
||||
// ============= DEDICATED FUNCTIONS =============
|
||||
|
@ -62,10 +62,12 @@ public:
|
||||
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);
|
||||
|
||||
ifChain.add(¬ch);
|
||||
ifChain.add(&squelch);
|
||||
ifChain.add(&fmnr);
|
||||
ifChain.add(&nb);
|
||||
|
||||
// Load configuration for and enabled all demodulators
|
||||
EventHandler<dsp::stream<dsp::stereo_t>*> _demodOutputChangeHandler;
|
||||
@ -258,6 +260,21 @@ 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);
|
||||
@ -324,6 +341,10 @@ private:
|
||||
postProcEnabled = selectedDemod->getPostProcEnabled();
|
||||
FMIFNRAllowed = selectedDemod->getFMIFNRAllowed();
|
||||
FMIFNREnabled = false;
|
||||
nbAllowed = selectedDemod->getNBAllowed();
|
||||
nbEnabled = false;
|
||||
nbLevel = 0.0f;
|
||||
config.acquire();
|
||||
if (config.conf[name][selectedDemod->getName()].contains("bandwidth")) {
|
||||
bandwidth = config.conf[name][selectedDemod->getName()]["bandwidth"];
|
||||
bandwidth = std::clamp<double>(bandwidth, minBandwidth, maxBandwidth);
|
||||
@ -343,6 +364,16 @@ private:
|
||||
if (config.conf[name][selectedDemod->getName()].contains("FMIFNREnabled")) {
|
||||
FMIFNREnabled = config.conf[name][selectedDemod->getName()]["FMIFNREnabled"];
|
||||
}
|
||||
if (config.conf[name][selectedDemod->getName()].contains("noiseBlankerEnabled")) {
|
||||
nbEnabled = config.conf[name][selectedDemod->getName()]["noiseBlankerEnabled"];
|
||||
}
|
||||
if (config.conf[name][selectedDemod->getName()].contains("noiseBlankerEnabled")) {
|
||||
nbEnabled = config.conf[name][selectedDemod->getName()]["noiseBlankerEnabled"];
|
||||
}
|
||||
if (config.conf[name][selectedDemod->getName()].contains("noiseBlankerLevel")) {
|
||||
nbLevel = config.conf[name][selectedDemod->getName()]["noiseBlankerLevel"];
|
||||
}
|
||||
config.release();
|
||||
deempMode = std::clamp<int>(deempMode, 0, _DEEMP_MODE_COUNT-1);
|
||||
|
||||
// Configure VFO
|
||||
@ -363,6 +394,10 @@ private:
|
||||
squelch.block.setLevel(squelchLevel);
|
||||
setSquelchEnabled(squelchEnabled);
|
||||
|
||||
// Configure noise blanker
|
||||
nb.block.setLevel(nbLevel);
|
||||
setNoiseBlankerEnabled(nbEnabled);
|
||||
|
||||
// Configure AF chain
|
||||
if (postProcEnabled) {
|
||||
// Configure resampler
|
||||
@ -483,6 +518,28 @@ 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);
|
||||
}
|
||||
|
||||
static void vfoUserChangedBandwidthHandler(double newBw, void* ctx) {
|
||||
RadioModule* _this = (RadioModule*)ctx;
|
||||
_this->setBandwidth(newBw);
|
||||
@ -568,6 +625,7 @@ private:
|
||||
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;
|
||||
|
||||
// Audio chain
|
||||
dsp::stream<dsp::stereo_t> dummyAudioStream;
|
||||
@ -587,12 +645,15 @@ private:
|
||||
float bandwidth;
|
||||
bool bandwidthLocked;
|
||||
int snapInterval;
|
||||
int selectedDemodID = 1;
|
||||
bool postProcEnabled;
|
||||
|
||||
bool squelchEnabled = false;
|
||||
float squelchLevel;
|
||||
int selectedDemodID = 1;
|
||||
|
||||
int deempMode = DEEMP_MODE_NONE;
|
||||
bool deempAllowed;
|
||||
bool postProcEnabled;
|
||||
|
||||
bool FMIFNRAllowed;
|
||||
bool FMIFNREnabled = false;
|
||||
|
||||
@ -600,6 +661,10 @@ private:
|
||||
float notchPos = 0;
|
||||
float notchWidth = 500;
|
||||
|
||||
bool nbAllowed;
|
||||
bool nbEnabled;
|
||||
float nbLevel = -100.0f;
|
||||
|
||||
const double MIN_SQUELCH = -100.0;
|
||||
const double MAX_SQUELCH = 0.0;
|
||||
|
||||
|
Reference in New Issue
Block a user