mirror of
				https://github.com/AlexandreRouma/SDRPlusPlus.git
				synced 2025-10-31 00:48:11 +01:00 
			
		
		
		
	noise reduction work
This commit is contained in:
		| @@ -9,7 +9,7 @@ namespace dsp::convert { | ||||
|  | ||||
|         StereoToMono(stream<stereo_t>* in) { base_type::init(in); } | ||||
|          | ||||
|         inline int process(int count, const stereo_t* in, float* out) { | ||||
|         static inline int process(int count, const stereo_t* in, float* out) { | ||||
|             for (int i = 0; i < count; i++) { | ||||
|                 out[i] = (in[i].l + in[i].r) / 2.0f; | ||||
|             } | ||||
|   | ||||
| @@ -37,21 +37,17 @@ namespace dsp::noise_reduction { | ||||
|  | ||||
|         inline int process(int count, complex_t* in, complex_t* out) { | ||||
|             for (int i = 0; i < count; i++) { | ||||
|                 // Get signal amplitude | ||||
|                 // Get signal amplitude and pass value if null | ||||
|                 float inAmp = in[i].amplitude(); | ||||
|  | ||||
|                 // Update average amplitude | ||||
|                 float gain = 1.0f; | ||||
|                 if (inAmp != 0.0f) { | ||||
|                     amp = (amp * _invRate) + (inAmp * _rate); | ||||
|                     float excess = inAmp / amp; | ||||
|                     if (excess > _level) { | ||||
|                         gain = 1.0f / excess; | ||||
|                     } | ||||
|                 if (!inAmp) { | ||||
|                     out[i] = in[i]; | ||||
|                 } | ||||
|                  | ||||
|                 // Scale output by gain | ||||
|                 out[i] = in[i] * gain; | ||||
|  | ||||
|                 // Update running average of amplitude | ||||
|                 amp = (_rate*inAmp) + (_invRate*amp); | ||||
|  | ||||
|                 // Null out if spike (Note: ideally, it should try to guess the real data) | ||||
|                 out[i] = (inAmp > _level*amp) ? complex_t{0.0f,0.0f} : in[i]; | ||||
|             } | ||||
|             return count; | ||||
|         } | ||||
|   | ||||
| @@ -45,6 +45,7 @@ namespace demod { | ||||
|         virtual int getDefaultDeemphasisMode() = 0; | ||||
|         virtual bool getFMIFNRAllowed() = 0; | ||||
|         virtual bool getNBAllowed() = 0; | ||||
|         virtual bool getAFNRAllowed() = 0; | ||||
|         virtual dsp::stream<dsp::stereo_t>* getOutput() = 0; | ||||
|     }; | ||||
| } | ||||
|   | ||||
| @@ -86,6 +86,7 @@ namespace demod { | ||||
|         int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; } | ||||
|         bool getFMIFNRAllowed() { return false; } | ||||
|         bool getNBAllowed() { return false; } | ||||
|         bool getAFNRAllowed() { return false; } | ||||
|         dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -92,6 +92,7 @@ namespace demod { | ||||
|         int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; } | ||||
|         bool getFMIFNRAllowed() { return false; } | ||||
|         bool getNBAllowed() { return false; } | ||||
|         bool getAFNRAllowed() { return false; } | ||||
|         dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -79,6 +79,7 @@ namespace demod { | ||||
|         int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; } | ||||
|         bool getFMIFNRAllowed() { return false; } | ||||
|         bool getNBAllowed() { return true; } | ||||
|         bool getAFNRAllowed() { return false; } | ||||
|         dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -79,6 +79,7 @@ namespace demod { | ||||
|         int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; } | ||||
|         bool getFMIFNRAllowed() { return false; } | ||||
|         bool getNBAllowed() { return true; } | ||||
|         bool getAFNRAllowed() { return false; } | ||||
|         dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -75,6 +75,7 @@ namespace demod { | ||||
|         int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; } | ||||
|         bool getFMIFNRAllowed() { return true; } | ||||
|         bool getNBAllowed() { return false; } | ||||
|         bool getAFNRAllowed() { return false; } | ||||
|         dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -59,6 +59,7 @@ namespace demod { | ||||
|         int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; } | ||||
|         bool getFMIFNRAllowed() { return false; } | ||||
|         bool getNBAllowed() { return true; } | ||||
|         bool getAFNRAllowed() { return false; } | ||||
|         dsp::stream<dsp::stereo_t>* getOutput() { return &c2s.out; } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -80,6 +80,7 @@ namespace demod { | ||||
|         int getDefaultDeemphasisMode() { return DEEMP_MODE_NONE; } | ||||
|         bool getFMIFNRAllowed() { return false; } | ||||
|         bool getNBAllowed() { return true; } | ||||
|         bool getAFNRAllowed() { return true; } | ||||
|         dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -130,6 +130,7 @@ namespace demod { | ||||
|         int getDefaultDeemphasisMode() { return DEEMP_MODE_50US; } | ||||
|         bool getFMIFNRAllowed() { return true; } | ||||
|         bool getNBAllowed() { return false; } | ||||
|         bool getAFNRAllowed() { return false; } | ||||
|         dsp::stream<dsp::stereo_t>* getOutput() { return &demod.out; } | ||||
|  | ||||
|         // ============= DEDICATED FUNCTIONS ============= | ||||
|   | ||||
| @@ -9,6 +9,7 @@ | ||||
| #include <dsp/noise_reduction/noise_blanker.h> | ||||
| #include <dsp/noise_reduction/fm_if.h> | ||||
| #include <dsp/noise_reduction/squelch.h> | ||||
| #include <dsp/noise_reduction/audio.h> | ||||
| #include <dsp/multirate/rational_resampler.h> | ||||
| #include <dsp/filter/deephasis.h> | ||||
| #include <core.h> | ||||
| @@ -83,9 +84,11 @@ public: | ||||
|  | ||||
|         resamp.init(NULL, 250000.0, 48000.0); | ||||
|         deemp.init(NULL, 50e-6, 48000.0); | ||||
|         afNR.init(NULL, 1024); | ||||
|  | ||||
|         afChain.addBlock(&resamp, true); | ||||
|         afChain.addBlock(&deemp, false); | ||||
|         afChain.addBlock(&afNR, false); | ||||
|  | ||||
|         // Initialize the sink | ||||
|         srChangeHandler.ctx = this; | ||||
| @@ -247,6 +250,12 @@ private: | ||||
|             if (!_this->nbEnabled && _this->enabled) { style::endDisabled(); } | ||||
|         } | ||||
|          | ||||
|         // Noise reduction | ||||
|         if (_this->afNRAllowed) { | ||||
|             if (ImGui::Checkbox(("Audio Noise Reduction##_radio_afnr_ena_" + _this->name).c_str(), &_this->afNREnabled)) { | ||||
|                 _this->setAFNREnabled(_this->afNREnabled); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Squelch | ||||
|         if (ImGui::Checkbox(("Squelch##_radio_sqelch_ena_" + _this->name).c_str(), &_this->squelchEnabled)) { | ||||
| @@ -370,6 +379,8 @@ private: | ||||
|         fmIFPresetId = ifnrPresets.valueId(IFNR_PRESET_VOICE); | ||||
|         nbAllowed = selectedDemod->getNBAllowed(); | ||||
|         nbEnabled = false; | ||||
|         afNRAllowed = selectedDemod->getAFNRAllowed(); | ||||
|         afNREnabled = false; | ||||
|         nbLevel = 0.0f; | ||||
|         double ifSamplerate = selectedDemod->getIFSampleRate(); | ||||
|         config.acquire(); | ||||
| @@ -411,6 +422,9 @@ private: | ||||
|         if (config.conf[name][selectedDemod->getName()].contains("noiseBlankerLevel")) { | ||||
|             nbLevel = config.conf[name][selectedDemod->getName()]["noiseBlankerLevel"]; | ||||
|         } | ||||
|         if (config.conf[name][selectedDemod->getName()].contains("audioNoiseReductionEnabled")) { | ||||
|             nbEnabled = config.conf[name][selectedDemod->getName()]["audioNoiseReductionEnabled"]; | ||||
|         } | ||||
|         config.release(); | ||||
|  | ||||
|         // Configure VFO | ||||
| @@ -446,7 +460,10 @@ private: | ||||
|             afChain.enableBlock(&resamp, [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); }); | ||||
|  | ||||
|             // Configure deemphasis | ||||
|             setDeemphasisMode(deempModes[deempId]); | ||||
|             setDeemphasisMode(deempAllowed ? deempModes[deempId] : DEEMP_MODE_NONE); | ||||
|  | ||||
|             // Configure AF NR | ||||
|             setAFNREnabled(afNRAllowed && afNREnabled); | ||||
|         } | ||||
|         else { | ||||
|             // Disable everything if post processing is disabled | ||||
| @@ -508,6 +525,17 @@ private: | ||||
|         config.release(true); | ||||
|     } | ||||
|  | ||||
|     void setAFNREnabled(bool enable) { | ||||
|         afNREnabled = enable; | ||||
|         if (!postProcEnabled || !selectedDemod) { return; } | ||||
|         afChain.setBlockEnabled(&afNR, afNREnabled, [=](dsp::stream<dsp::stereo_t>* out){ stream.setInput(out); }); | ||||
|  | ||||
|         // Save config | ||||
|         config.acquire(); | ||||
|         config.conf[name][selectedDemod->getName()]["audioNoiseReductionEnabled"] = nbEnabled; | ||||
|         config.release(true); | ||||
|     } | ||||
|  | ||||
|     void setNBEnabled(bool enable) { | ||||
|         nbEnabled = enable; | ||||
|         if (!selectedDemod) { return; } | ||||
| @@ -660,6 +688,7 @@ private: | ||||
|     dsp::chain<dsp::stereo_t> afChain; | ||||
|     dsp::multirate::RationalResampler<dsp::stereo_t> resamp; | ||||
|     dsp::filter::Deemphasis<dsp::stereo_t> deemp; | ||||
|     dsp::noise_reduction::Audio afNR; | ||||
|  | ||||
|     SinkManager::Stream stream; | ||||
|  | ||||
| @@ -683,6 +712,9 @@ private: | ||||
|     int deempId = 0; | ||||
|     bool deempAllowed; | ||||
|  | ||||
|     bool afNREnabled = false; | ||||
|     bool afNRAllowed; | ||||
|  | ||||
|     bool FMIFNRAllowed; | ||||
|     bool FMIFNREnabled = false; | ||||
|     int fmIFPresetId; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user