mirror of
				https://github.com/AlexandreRouma/SDRPlusPlus.git
				synced 2025-10-31 00:48:11 +01:00 
			
		
		
		
	more work
This commit is contained in:
		| @@ -117,6 +117,8 @@ int sdrpp_main(int argc, char* argv[]) { | ||||
|     defConfig["colorMap"] = "Classic"; | ||||
|     defConfig["fftHold"] = false; | ||||
|     defConfig["fftHoldSpeed"] = 60; | ||||
|     defConfig["fftSmoothing"] = false; | ||||
|     defConfig["fftSmoothingSpeed"] = 100; | ||||
|     defConfig["fastFFT"] = false; | ||||
|     defConfig["fftHeight"] = 300; | ||||
|     defConfig["fftRate"] = 20; | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
| #include <signal_path/signal_path.h> | ||||
| #include <gui/style.h> | ||||
| #include <utils/optionlist.h> | ||||
| #include <algorithm> | ||||
|  | ||||
| namespace displaymenu { | ||||
|     bool showWaterfall; | ||||
| @@ -22,6 +23,8 @@ namespace displaymenu { | ||||
|     bool restartRequired = false; | ||||
|     bool fftHold = false; | ||||
|     int fftHoldSpeed = 60; | ||||
|     bool fftSmoothing = false; | ||||
|     int fftSmoothingSpeed = 100; | ||||
|  | ||||
|     OptionList<float, float> uiScales; | ||||
|  | ||||
| @@ -57,8 +60,9 @@ namespace displaymenu { | ||||
|         IQFrontEnd::FFTWindow::NUTTALL | ||||
|     }; | ||||
|  | ||||
|     void updateFFTHoldSpeed() { | ||||
|         gui::waterfall.setFFTHoldSpeed(fftHoldSpeed / (fftRate * 10.0f)); | ||||
|     void updateFFTSpeeds() { | ||||
|         gui::waterfall.setFFTHoldSpeed((float)fftHoldSpeed / ((float)fftRate * 10.0f)); | ||||
|         gui::waterfall.setFFTSmoothingSpeed(std::min<float>((float)fftSmoothingSpeed / (float)(fftRate * 10.0f), 1.0f)); | ||||
|     } | ||||
|  | ||||
|     void init() { | ||||
| @@ -104,7 +108,9 @@ namespace displaymenu { | ||||
|         fftHold = core::configManager.conf["fftHold"]; | ||||
|         fftHoldSpeed = core::configManager.conf["fftHoldSpeed"]; | ||||
|         gui::waterfall.setFFTHold(fftHold); | ||||
|         updateFFTHoldSpeed(); | ||||
|         fftSmoothing = core::configManager.conf["fftSmoothing"]; | ||||
|         fftSmoothingSpeed = core::configManager.conf["fftSmoothingSpeed"]; | ||||
|         updateFFTSpeeds(); | ||||
|  | ||||
|         // Define and load UI scales | ||||
|         uiScales.define(1.0f, "100%", 1.0f); | ||||
| @@ -145,15 +151,32 @@ namespace displaymenu { | ||||
|             core::configManager.release(true); | ||||
|         } | ||||
|  | ||||
|         if (ImGui::Checkbox("FFT Smoothing##_sdrpp", &fftSmoothing)) { | ||||
|             gui::waterfall.setFFTSmoothing(fftSmoothing); | ||||
|             core::configManager.acquire(); | ||||
|             core::configManager.conf["fftSmoothing"] = fftSmoothing; | ||||
|             core::configManager.release(true); | ||||
|         } | ||||
|  | ||||
|         ImGui::LeftLabel("FFT Hold Speed"); | ||||
|         ImGui::FillWidth(); | ||||
|         if (ImGui::InputInt("##sdrpp_fft_hold_speed", &fftHoldSpeed)) { | ||||
|             updateFFTHoldSpeed(); | ||||
|             updateFFTSpeeds(); | ||||
|             core::configManager.acquire(); | ||||
|             core::configManager.conf["fftHoldSpeed"] = fftHoldSpeed; | ||||
|             core::configManager.release(true); | ||||
|         } | ||||
|  | ||||
|         ImGui::LeftLabel("FFT Smoothing Speed"); | ||||
|         ImGui::FillWidth(); | ||||
|         if (ImGui::InputInt("##sdrpp_fft_smoothing_speed", &fftSmoothingSpeed)) { | ||||
|             fftSmoothingSpeed = std::max<int>(fftSmoothingSpeed, 1); | ||||
|             updateFFTSpeeds(); | ||||
|             core::configManager.acquire(); | ||||
|             core::configManager.conf["fftSmoothingSpeed"] = fftSmoothingSpeed; | ||||
|             core::configManager.release(true); | ||||
|         } | ||||
|  | ||||
|         ImGui::LeftLabel("High-DPI Scaling"); | ||||
|         ImGui::FillWidth(); | ||||
|         if (ImGui::Combo("##sdrpp_ui_scale", &uiScaleId, uiScales.txt)) { | ||||
| @@ -168,7 +191,7 @@ namespace displaymenu { | ||||
|         if (ImGui::InputInt("##sdrpp_fft_rate", &fftRate, 1, 10)) { | ||||
|             fftRate = std::max<int>(1, fftRate); | ||||
|             sigpath::iqFrontEnd.setFFTRate(fftRate); | ||||
|             updateFFTHoldSpeed(); | ||||
|             updateFFTSpeeds(); | ||||
|             core::configManager.acquire(); | ||||
|             core::configManager.conf["fftRate"] = fftRate; | ||||
|             core::configManager.release(true); | ||||
|   | ||||
| @@ -689,6 +689,7 @@ namespace ImGui { | ||||
|  | ||||
|     void WaterFall::onResize() { | ||||
|         std::lock_guard<std::recursive_mutex> lck(latestFFTMtx); | ||||
|         std::lock_guard<std::mutex> lck2(smoothingBufMtx); | ||||
|         // return if widget is too small | ||||
|         if (widgetSize.x < 100 || widgetSize.y < 100) { | ||||
|             return; | ||||
| @@ -740,14 +741,23 @@ namespace ImGui { | ||||
|         } | ||||
|         latestFFTHold = new float[dataWidth]; | ||||
|  | ||||
|         // Reallocate smoothing buffer | ||||
|         if (fftSmoothing) { | ||||
|             if (smoothingBuf) { delete[] smoothingBuf; } | ||||
|             smoothingBuf = new float[dataWidth]; | ||||
|             for (int i = 0; i < dataWidth; i++) { | ||||
|                 smoothingBuf[i] = -1000.0f;  | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (waterfallVisible) { | ||||
|             delete[] waterfallFb; | ||||
|             waterfallFb = new uint32_t[dataWidth * waterfallHeight]; | ||||
|             memset(waterfallFb, 0, dataWidth * waterfallHeight * sizeof(uint32_t)); | ||||
|         } | ||||
|         for (int i = 0; i < dataWidth; i++) { | ||||
|             latestFFT[i] = -1000.0; // Hide everything | ||||
|             latestFFTHold[i] = -1000.0; | ||||
|             latestFFT[i] = -1000.0f; // Hide everything | ||||
|             latestFFTHold[i] = -1000.0f; | ||||
|         } | ||||
|  | ||||
|         fftAreaMin = ImVec2(widgetPos.x + (50.0f * style::uiScale), widgetPos.y + (9.0f * style::uiScale)); | ||||
| @@ -873,6 +883,15 @@ namespace ImGui { | ||||
|             fftLines = 1; | ||||
|         } | ||||
|  | ||||
|         // Apply smoothing if enabled | ||||
|         if (fftSmoothing && latestFFT != NULL && smoothingBuf != NULL && fftLines != 0) { | ||||
|             std::lock_guard<std::mutex> lck2(smoothingBufMtx); | ||||
|             volk_32f_s32f_multiply_32f(latestFFT, latestFFT, smoothingAlpha, dataWidth); | ||||
|             volk_32f_s32f_multiply_32f(smoothingBuf, smoothingBuf, smoothingBeta, dataWidth); | ||||
|             volk_32f_x2_add_32f(smoothingBuf, latestFFT, smoothingBuf, dataWidth); | ||||
|             memcpy(latestFFT, smoothingBuf, dataWidth * sizeof(float)); | ||||
|         } | ||||
|  | ||||
|         if (selectedVFO != "" && vfos.size() > 0) { | ||||
|             float dummy; | ||||
|             calculateVFOSignalInfo(waterfallVisible ? &rawFFTs[currentFFTLine * rawFFTSize] : rawFFTs, vfos[selectedVFO], dummy, selectedVFOSNR); | ||||
| @@ -1110,6 +1129,36 @@ namespace ImGui { | ||||
|         fftHoldSpeed = speed; | ||||
|     } | ||||
|  | ||||
|     void WaterFall::setFFTSmoothing(bool enabled) { | ||||
|         std::lock_guard<std::mutex> lck(smoothingBufMtx); | ||||
|         fftSmoothing = enabled; | ||||
|  | ||||
|         // Free buffer if not null | ||||
|         if (smoothingBuf) {delete[] smoothingBuf; } | ||||
|  | ||||
|         // If disabled, stop here | ||||
|         if (!enabled) { | ||||
|             smoothingBuf = NULL; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Allocate and copy existing FFT into it | ||||
|         smoothingBuf = new float[dataWidth]; | ||||
|         if (latestFFT) { | ||||
|             std::lock_guard<std::recursive_mutex> lck2(latestFFTMtx); | ||||
|             memcpy(smoothingBuf, latestFFT, dataWidth * sizeof(float)); | ||||
|         } | ||||
|         else { | ||||
|             memset(smoothingBuf, 0, dataWidth * sizeof(float)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void WaterFall::setFFTSmoothingSpeed(float speed) { | ||||
|         std::lock_guard<std::mutex> lck(smoothingBufMtx); | ||||
|         smoothingAlpha = speed; | ||||
|         smoothingBeta = 1.0f - speed; | ||||
|     } | ||||
|  | ||||
|     float* WaterFall::acquireLatestFFT(int& width) { | ||||
|         latestFFTMtx.lock(); | ||||
|         if (!latestFFT) { | ||||
|   | ||||
| @@ -169,6 +169,9 @@ namespace ImGui { | ||||
|         void setFFTHold(bool hold); | ||||
|         void setFFTHoldSpeed(float speed); | ||||
|  | ||||
|         void setFFTSmoothing(bool enabled); | ||||
|         void setFFTSmoothingSpeed(float speed); | ||||
|  | ||||
|         float* acquireLatestFFT(int& width); | ||||
|         void releaseLatestFFT(); | ||||
|  | ||||
| @@ -270,6 +273,7 @@ namespace ImGui { | ||||
|         std::recursive_mutex buf_mtx; | ||||
|         std::recursive_mutex latestFFTMtx; | ||||
|         std::mutex texMtx; | ||||
|         std::mutex smoothingBufMtx; | ||||
|  | ||||
|         float vRange; | ||||
|  | ||||
| @@ -304,8 +308,9 @@ namespace ImGui { | ||||
|         //std::vector<std::vector<float>> rawFFTs; | ||||
|         int rawFFTSize; | ||||
|         float* rawFFTs = NULL; | ||||
|         float* latestFFT; | ||||
|         float* latestFFTHold; | ||||
|         float* latestFFT = NULL; | ||||
|         float* latestFFTHold = NULL; | ||||
|         float* smoothingBuf = NULL; | ||||
|         int currentFFTLine = 0; | ||||
|         int fftLines = 0; | ||||
|  | ||||
| @@ -325,6 +330,10 @@ namespace ImGui { | ||||
|         bool fftHold = false; | ||||
|         float fftHoldSpeed = 0.3f; | ||||
|  | ||||
|         bool fftSmoothing = false; | ||||
|         float smoothingAlpha = 0.5; | ||||
|         float smoothingBeta = 0.5; | ||||
|  | ||||
|         // UI Select elements | ||||
|         bool fftResizeSelect = false; | ||||
|         bool freqScaleSelect = false; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user