From 9de585190f9a608973e3c7245c7b9645e6f1160e Mon Sep 17 00:00:00 2001 From: Ryzerth Date: Sun, 20 Sep 2020 00:19:39 +0200 Subject: [PATCH] Fixed issues with new module system --- .gitignore | 3 +- core/CMakeLists.txt | 5 +- core/src/core.cpp | 36 ++-- core/src/{ => gui}/bandplan.cpp | 2 +- core/src/{ => gui}/bandplan.h | 0 core/src/{ => gui}/frequency_select.cpp | 2 +- core/src/{ => gui}/frequency_select.h | 0 core/src/gui/gui.cpp | 6 + core/src/gui/gui.h | 9 + core/src/{ => gui}/icons.cpp | 2 +- core/src/{ => gui}/icons.h | 0 core/src/{ => gui}/main_window.cpp | 191 +++++++++--------- core/src/{ => gui}/main_window.h | 17 +- core/src/gui/menu.cpp | 24 +++ core/src/gui/menu.h | 23 +++ core/src/{ => gui}/style.cpp | 2 +- core/src/{ => gui}/style.h | 0 core/src/{ => gui}/waterfall.cpp | 3 +- core/src/{ => gui}/waterfall.h | 2 +- core/src/module.cpp | 16 +- core/src/module.h | 17 +- core/src/{ => signal_path}/audio.cpp | 2 +- core/src/{ => signal_path}/audio.h | 0 .../{signal_path.cpp => signal_path/dsp.cpp} | 2 +- core/src/{signal_path.h => signal_path/dsp.h} | 0 core/src/signal_path/signal_path.cpp | 6 + core/src/signal_path/signal_path.h | 9 + core/src/signal_path/vfo_manager.cpp | 128 ++++++++++++ core/src/signal_path/vfo_manager.h | 47 +++++ core/src/vfo_manager.cpp | 99 --------- core/src/vfo_manager.h | 24 --- demo/CMakeLists.txt | 7 + demo/src/main.cpp | 2 +- radio/CMakeLists.txt | 49 +---- radio/src/main.cpp | 9 +- radio/src/path.cpp | 65 +++--- radio/src/path.h | 5 +- root_dev/config.json | 4 +- 38 files changed, 460 insertions(+), 358 deletions(-) rename core/src/{ => gui}/bandplan.cpp (99%) rename core/src/{ => gui}/bandplan.h (100%) rename core/src/{ => gui}/frequency_select.cpp (99%) rename core/src/{ => gui}/frequency_select.h (100%) create mode 100644 core/src/gui/gui.cpp create mode 100644 core/src/gui/gui.h rename core/src/{ => gui}/icons.cpp (97%) rename core/src/{ => gui}/icons.h (100%) rename core/src/{ => gui}/main_window.cpp (83%) rename core/src/{ => gui}/main_window.h (71%) create mode 100644 core/src/gui/menu.cpp create mode 100644 core/src/gui/menu.h rename core/src/{ => gui}/style.cpp (99%) rename core/src/{ => gui}/style.h (100%) rename core/src/{ => gui}/waterfall.cpp (99%) rename core/src/{ => gui}/waterfall.h (99%) rename core/src/{ => signal_path}/audio.cpp (99%) rename core/src/{ => signal_path}/audio.h (100%) rename core/src/{signal_path.cpp => signal_path/dsp.cpp} (98%) rename core/src/{signal_path.h => signal_path/dsp.h} (100%) create mode 100644 core/src/signal_path/signal_path.cpp create mode 100644 core/src/signal_path/signal_path.h create mode 100644 core/src/signal_path/vfo_manager.cpp create mode 100644 core/src/signal_path/vfo_manager.h delete mode 100644 core/src/vfo_manager.cpp delete mode 100644 core/src/vfo_manager.h diff --git a/.gitignore b/.gitignore index 12cbce30..357301de 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ build/ .vscode/ *.old *.dll -*.exe \ No newline at end of file +*.exe +*.zip \ No newline at end of file diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d08495d7..065841c5 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -9,13 +9,16 @@ else() set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive -fsanitize=address -g") # set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive") endif (MSVC) +add_definitions(-DSDRPP_IS_CORE) # Main code file(GLOB SRC "src/*.cpp") +file(GLOB GUI "src/gui/*.cpp") +file(GLOB SIGPATH "src/signal_path/*.cpp") file(GLOB IMGUI "src/imgui/*.cpp") # Add code to dyn lib -add_library(sdrpp_core SHARED ${SRC} ${IMGUI}) +add_library(sdrpp_core SHARED ${SRC} ${GUI} ${SIGPATH} ${IMGUI}) # Include core headers target_include_directories(sdrpp_core PUBLIC "src/") diff --git a/core/src/core.cpp b/core/src/core.cpp index 4df80c94..d77835a8 100644 --- a/core/src/core.cpp +++ b/core/src/core.cpp @@ -4,12 +4,12 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include -#include +#include #include #include #include @@ -139,23 +139,23 @@ int sdrpp_main() { // ==================================================== - // glfwPollEvents(); - ImGui_ImplOpenGL3_NewFrame(); - // ImGui_ImplGlfw_NewFrame(); - // ImGui::NewFrame(); + // // glfwPollEvents(); + // ImGui_ImplOpenGL3_NewFrame(); + // // ImGui_ImplGlfw_NewFrame(); + // // ImGui::NewFrame(); - // ImGui::ShowDemoWindow(); + // // ImGui::ShowDemoWindow(); - // ImGui::Render(); - int display_w, display_h; - glfwGetFramebufferSize(window, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(0.0666f, 0.0666f, 0.0666f, 1.0f); - //glClearColor(0.9f, 0.9f, 0.9f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - // ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + // // ImGui::Render(); + // int display_w, display_h; + // glfwGetFramebufferSize(window, &display_w, &display_h); + // glViewport(0, 0, display_w, display_h); + // glClearColor(0.0666f, 0.0666f, 0.0666f, 1.0f); + // //glClearColor(0.9f, 0.9f, 0.9f, 1.0f); + // glClear(GL_COLOR_BUFFER_BIT); + // // ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - glfwSwapBuffers(window); + // glfwSwapBuffers(window); // ==================================================== spdlog::info("Loading icons"); diff --git a/core/src/bandplan.cpp b/core/src/gui/bandplan.cpp similarity index 99% rename from core/src/bandplan.cpp rename to core/src/gui/bandplan.cpp index 47cb5591..a0e6de91 100644 --- a/core/src/bandplan.cpp +++ b/core/src/gui/bandplan.cpp @@ -1,4 +1,4 @@ -#include +#include namespace bandplan { std::map bandplans; diff --git a/core/src/bandplan.h b/core/src/gui/bandplan.h similarity index 100% rename from core/src/bandplan.h rename to core/src/gui/bandplan.h diff --git a/core/src/frequency_select.cpp b/core/src/gui/frequency_select.cpp similarity index 99% rename from core/src/frequency_select.cpp rename to core/src/gui/frequency_select.cpp index fe750ff0..b40aabad 100644 --- a/core/src/frequency_select.cpp +++ b/core/src/gui/frequency_select.cpp @@ -1,4 +1,4 @@ -#include +#include bool isInArea(ImVec2 val, ImVec2 min, ImVec2 max) { return val.x >= min.x && val.x < max.x && val.y >= min.y && val.y < max.y; diff --git a/core/src/frequency_select.h b/core/src/gui/frequency_select.h similarity index 100% rename from core/src/frequency_select.h rename to core/src/gui/frequency_select.h diff --git a/core/src/gui/gui.cpp b/core/src/gui/gui.cpp new file mode 100644 index 00000000..59c8b375 --- /dev/null +++ b/core/src/gui/gui.cpp @@ -0,0 +1,6 @@ +#include + +namespace gui { + ImGui::WaterFall waterfall; + FrequencySelect freqSelect; +}; \ No newline at end of file diff --git a/core/src/gui/gui.h b/core/src/gui/gui.h new file mode 100644 index 00000000..c65833c2 --- /dev/null +++ b/core/src/gui/gui.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include +#include + +namespace gui { + SDRPP_EXPORT ImGui::WaterFall waterfall; + SDRPP_EXPORT FrequencySelect freqSelect; +}; \ No newline at end of file diff --git a/core/src/icons.cpp b/core/src/gui/icons.cpp similarity index 97% rename from core/src/icons.cpp rename to core/src/gui/icons.cpp index f80ff61b..54c6f451 100644 --- a/core/src/icons.cpp +++ b/core/src/gui/icons.cpp @@ -1,4 +1,4 @@ -#include +#include #define STB_IMAGE_IMPLEMENTATION #include diff --git a/core/src/icons.h b/core/src/gui/icons.h similarity index 100% rename from core/src/icons.h rename to core/src/gui/icons.h diff --git a/core/src/main_window.cpp b/core/src/gui/main_window.cpp similarity index 83% rename from core/src/main_window.cpp rename to core/src/gui/main_window.cpp index bd196ffc..b47a6034 100644 --- a/core/src/main_window.cpp +++ b/core/src/gui/main_window.cpp @@ -1,9 +1,8 @@ -#include +#include +#include std::thread worker; std::mutex fft_mtx; -ImGui::WaterFall wtf; -FrequencySelect fSel; fftwf_complex *fft_in, *fft_out; fftwf_plan p; float* tempData; @@ -14,8 +13,6 @@ ImFont* bigFont; int fftSize = 8192 * 8; io::SoapyWrapper soapy; - -SignalPath sigPath; std::vector _data; std::vector fftTaps; void fftHandler(dsp::complex_t* samples) { @@ -33,7 +30,7 @@ void fftHandler(dsp::complex_t* samples) { _data[i] = (_data[i - 4] + _data[i - 3] + _data[i - 2] + _data[i - 1] + _data[i]) / 5.0f; } - wtf.pushFFT(_data, fftSize); + gui::waterfall.pushFFT(_data, fftSize); _data.clear(); } @@ -87,7 +84,7 @@ void loadSourceConfig(std::string name) { else { srId = std::distance(soapy.sampleRates.begin(), _srIt); } - sigPath.setSampleRate(sampleRate); + sigpath::signalPath.setSampleRate(sampleRate); soapy.setSampleRate(sampleRate); // Set gains @@ -107,8 +104,8 @@ void loadSourceConfig(std::string name) { } // Update GUI - wtf.setBandwidth(sampleRate); - wtf.setViewBandwidth(sampleRate); + gui::waterfall.setBandwidth(sampleRate); + gui::waterfall.setViewBandwidth(sampleRate); bw.val = sampleRate; } @@ -158,21 +155,19 @@ void windowInit() { spdlog::info("Initializing SoapySDR"); soapy.init(); - fSel.init(); + gui::freqSelect.init(); fft_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize); fft_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize); p = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE); - sigPath.init(sampleRate, 20, fftSize, &soapy.output, (dsp::complex_t*)fft_in, fftHandler); - sigPath.start(); - - vfoman::init(&wtf, &sigPath); + sigpath::signalPath.init(sampleRate, 20, fftSize, &soapy.output, (dsp::complex_t*)fft_in, fftHandler); + sigpath::signalPath.start(); uiGains = new float[soapy.gainList.size()]; spdlog::info("Loading modules"); - mod::initAPI(&wtf); + mod::initAPI(&gui::waterfall); mod::loadFromList(config::getRootDirectory() + "/module_list.json"); bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF((config::getRootDirectory() + "/res/fonts/Roboto-Medium.ttf").c_str(), 128.0f); @@ -206,7 +201,7 @@ void windowInit() { sourceName = soapy.devNameList[0]; } sampleRate = soapy.getSampleRate(); - sigPath.setSampleRate(sampleRate); + sigpath::signalPath.setSampleRate(sampleRate); } // Search for the first source in the list to have a config // If no pre-defined source, selected default device @@ -229,10 +224,10 @@ void windowInit() { // Update UI settings fftMin = config::config["min"]; fftMax = config::config["max"]; - wtf.setFFTMin(fftMin); - wtf.setWaterfallMin(fftMin); - wtf.setFFTMax(fftMax); - wtf.setWaterfallMax(fftMax); + gui::waterfall.setFFTMin(fftMin); + gui::waterfall.setWaterfallMin(fftMin); + gui::waterfall.setFFTMax(fftMax); + gui::waterfall.setWaterfallMax(fftMax); bandPlanEnabled.val = config::config["bandPlanEnabled"]; bandPlanEnabled.markAsChanged(); @@ -243,10 +238,10 @@ void windowInit() { bandplanId.val = std::distance(bandplan::bandplans.begin(), bandplan::bandplans.find(bandPlanName)); if (bandPlanEnabled.val) { - wtf.bandplan = &bandplan::bandplans[bandPlanName]; + gui::waterfall.bandplan = &bandplan::bandplans[bandPlanName]; } else { - wtf.bandplan = NULL; + gui::waterfall.bandplan = NULL; } } else { @@ -255,16 +250,16 @@ void windowInit() { bandplanId.markAsChanged(); - fSel.setFrequency(frequency); - fSel.frequencyChanged = false; + gui::freqSelect.setFrequency(frequency); + gui::freqSelect.frequencyChanged = false; soapy.setFrequency(frequency); - wtf.setCenterFrequency(frequency); - wtf.setBandwidth(sampleRate); - wtf.setViewBandwidth(sampleRate); + gui::waterfall.setCenterFrequency(frequency); + gui::waterfall.setBandwidth(sampleRate); + gui::waterfall.setViewBandwidth(sampleRate); bw.val = sampleRate; - wtf.vfoFreqChanged = false; - wtf.centerFreqMoved = false; - wtf.selectFirstVFO(); + gui::waterfall.vfoFreqChanged = false; + gui::waterfall.centerFreqMoved = false; + gui::waterfall.selectFirstVFO(); for (auto [name, stream] : audio::streams) { if (config::config["audio"].contains(name)) { @@ -277,7 +272,7 @@ void windowInit() { } } - audioStreamName = audio::getNameFromVFO(wtf.selectedVFO); + audioStreamName = audio::getNameFromVFO(gui::waterfall.selectedVFO); if (audioStreamName != "") { volume = &audio::streams[audioStreamName]->volume; } @@ -287,18 +282,18 @@ void windowInit() { showWaterfall = config::config["showWaterfall"]; if (!showWaterfall) { - wtf.hideWaterfall(); + gui::waterfall.hideWaterfall(); } fftHeight = config::config["fftHeight"]; - wtf.setFFTHeight(fftHeight); + gui::waterfall.setFFTHeight(fftHeight); } void setVFO(float freq) { - ImGui::WaterfallVFO* vfo = wtf.vfos[wtf.selectedVFO]; + ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO]; float currentOff = vfo->centerOffset; - float currentTune = wtf.getCenterFrequency() + vfo->generalOffset; + float currentTune = gui::waterfall.getCenterFrequency() + vfo->generalOffset; float delta = freq - currentTune; float newVFO = currentOff + delta; @@ -306,38 +301,38 @@ void setVFO(float freq) { float vfoBottom = newVFO - (vfoBW / 2.0f); float vfoTop = newVFO + (vfoBW / 2.0f); - float view = wtf.getViewOffset(); - float viewBW = wtf.getViewBandwidth(); + float view = gui::waterfall.getViewOffset(); + float viewBW = gui::waterfall.getViewBandwidth(); float viewBottom = view - (viewBW / 2.0f); float viewTop = view + (viewBW / 2.0f); - float wholeFreq = wtf.getCenterFrequency(); - float BW = wtf.getBandwidth(); + float wholeFreq = gui::waterfall.getCenterFrequency(); + float BW = gui::waterfall.getBandwidth(); float bottom = -(BW / 2.0f); float top = (BW / 2.0f); // VFO still fints in the view if (vfoBottom > viewBottom && vfoTop < viewTop) { - vfoman::setCenterOffset(wtf.selectedVFO, newVFO); + sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO); return; } // VFO too low for current SDR tuning if (vfoBottom < bottom) { - wtf.setViewOffset((BW / 2.0f) - (viewBW / 2.0f)); + gui::waterfall.setViewOffset((BW / 2.0f) - (viewBW / 2.0f)); float newVFOOffset = (BW / 2.0f) - (vfoBW / 2.0f) - (viewBW / 10.0f); - vfoman::setCenterOffset(wtf.selectedVFO, newVFOOffset); - wtf.setCenterFrequency(freq - newVFOOffset); + sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset); + gui::waterfall.setCenterFrequency(freq - newVFOOffset); soapy.setFrequency(freq - newVFOOffset); return; } // VFO too high for current SDR tuning if (vfoTop > top) { - wtf.setViewOffset((viewBW / 2.0f) - (BW / 2.0f)); + gui::waterfall.setViewOffset((viewBW / 2.0f) - (BW / 2.0f)); float newVFOOffset = (vfoBW / 2.0f) - (BW / 2.0f) + (viewBW / 10.0f); - vfoman::setCenterOffset(wtf.selectedVFO, newVFOOffset); - wtf.setCenterFrequency(freq - newVFOOffset); + sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset); + gui::waterfall.setCenterFrequency(freq - newVFOOffset); soapy.setFrequency(freq - newVFOOffset); return; } @@ -349,15 +344,15 @@ void setVFO(float freq) { float newViewTop = newViewOff + (viewBW / 2.0f); if (newViewBottom > bottom) { - wtf.setViewOffset(newViewOff); - vfoman::setCenterOffset(wtf.selectedVFO, newVFO); + gui::waterfall.setViewOffset(newViewOff); + sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO); return; } - wtf.setViewOffset((BW / 2.0f) - (viewBW / 2.0f)); + gui::waterfall.setViewOffset((BW / 2.0f) - (viewBW / 2.0f)); float newVFOOffset = (BW / 2.0f) - (vfoBW / 2.0f) - (viewBW / 10.0f); - vfoman::setCenterOffset(wtf.selectedVFO, newVFOOffset); - wtf.setCenterFrequency(freq - newVFOOffset); + sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset); + gui::waterfall.setCenterFrequency(freq - newVFOOffset); soapy.setFrequency(freq - newVFOOffset); } else { @@ -366,15 +361,15 @@ void setVFO(float freq) { float newViewTop = newViewOff + (viewBW / 2.0f); if (newViewTop < top) { - wtf.setViewOffset(newViewOff); - vfoman::setCenterOffset(wtf.selectedVFO, newVFO); + gui::waterfall.setViewOffset(newViewOff); + sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO); return; } - wtf.setViewOffset((viewBW / 2.0f) - (BW / 2.0f)); + gui::waterfall.setViewOffset((viewBW / 2.0f) - (BW / 2.0f)); float newVFOOffset = (vfoBW / 2.0f) - (BW / 2.0f) + (viewBW / 10.0f); - vfoman::setCenterOffset(wtf.selectedVFO, newVFOOffset); - wtf.setCenterFrequency(freq - newVFOOffset); + sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset); + gui::waterfall.setCenterFrequency(freq - newVFOOffset); soapy.setFrequency(freq - newVFOOffset); } } @@ -382,61 +377,61 @@ void setVFO(float freq) { void drawWindow() { ImGui::Begin("Main", NULL, WINDOW_FLAGS); - ImGui::WaterfallVFO* vfo = wtf.vfos[wtf.selectedVFO]; + ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO]; if (vfo->centerOffsetChanged) { - fSel.setFrequency(wtf.getCenterFrequency() + vfo->generalOffset); - fSel.frequencyChanged = false; - config::config["frequency"] = fSel.frequency; + gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset); + gui::freqSelect.frequencyChanged = false; + config::config["frequency"] = gui::freqSelect.frequency; config::configModified = true; } - vfoman::updateFromWaterfall(); + sigpath::vfoManager.updateFromWaterfall(&gui::waterfall); - if (wtf.selectedVFOChanged) { - wtf.selectedVFOChanged = false; - fSel.setFrequency(vfo->generalOffset + wtf.getCenterFrequency()); - fSel.frequencyChanged = false; + if (gui::waterfall.selectedVFOChanged) { + gui::waterfall.selectedVFOChanged = false; + gui::freqSelect.setFrequency(vfo->generalOffset + gui::waterfall.getCenterFrequency()); + gui::freqSelect.frequencyChanged = false; mod::broadcastEvent(mod::EVENT_SELECTED_VFO_CHANGED); - audioStreamName = audio::getNameFromVFO(wtf.selectedVFO); + audioStreamName = audio::getNameFromVFO(gui::waterfall.selectedVFO); if (audioStreamName != "") { volume = &audio::streams[audioStreamName]->volume; } - config::config["frequency"] = fSel.frequency; + config::config["frequency"] = gui::freqSelect.frequency; config::configModified = true; } - if (fSel.frequencyChanged) { - fSel.frequencyChanged = false; - setVFO(fSel.frequency); + if (gui::freqSelect.frequencyChanged) { + gui::freqSelect.frequencyChanged = false; + setVFO(gui::freqSelect.frequency); vfo->centerOffsetChanged = false; vfo->lowerOffsetChanged = false; vfo->upperOffsetChanged = false; - config::config["frequency"] = fSel.frequency; + config::config["frequency"] = gui::freqSelect.frequency; config::configModified = true; } - if (wtf.centerFreqMoved) { - wtf.centerFreqMoved = false; - soapy.setFrequency(wtf.getCenterFrequency()); - fSel.setFrequency(wtf.getCenterFrequency() + vfo->generalOffset); - config::config["frequency"] = fSel.frequency; + if (gui::waterfall.centerFreqMoved) { + gui::waterfall.centerFreqMoved = false; + soapy.setFrequency(gui::waterfall.getCenterFrequency()); + gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset); + config::config["frequency"] = gui::freqSelect.frequency; config::configModified = true; } if (dcbias.changed()) { - sigPath.setDCBiasCorrection(dcbias.val); + sigpath::signalPath.setDCBiasCorrection(dcbias.val); } if (bandplanId.changed() && bandPlanEnabled.val) { - wtf.bandplan = &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]]; + gui::waterfall.bandplan = &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]]; } if (bandPlanEnabled.changed()) { - wtf.bandplan = bandPlanEnabled.val ? &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]] : NULL; + gui::waterfall.bandplan = bandPlanEnabled.val ? &bandplan::bandplans[bandplan::bandplanNames[bandplanId.val]] : NULL; } - int _fftHeight = wtf.getFFTHeight(); + int _fftHeight = gui::waterfall.getFFTHeight(); if (fftHeight != _fftHeight) { fftHeight = _fftHeight; config::config["fftHeight"] = fftHeight; @@ -472,7 +467,7 @@ void drawWindow() { else { if (ImGui::ImageButton(icons::PLAY, ImVec2(40, 40), ImVec2(0, 0), ImVec2(1, 1), 0) && soapy.devList.size() > 0) { soapy.start(); - soapy.setFrequency(wtf.getCenterFrequency()); + soapy.setFrequency(gui::waterfall.getCenterFrequency()); playing = true; } } @@ -494,7 +489,7 @@ void drawWindow() { ImGui::SameLine(); - fSel.draw(); + gui::freqSelect.draw(); ImGui::SameLine(); @@ -564,9 +559,9 @@ void drawWindow() { srId = 0; sampleRate = soapy.getSampleRate(); bw.val = sampleRate; - wtf.setBandwidth(sampleRate); - wtf.setViewBandwidth(sampleRate); - sigPath.setSampleRate(sampleRate); + gui::waterfall.setBandwidth(sampleRate); + gui::waterfall.setViewBandwidth(sampleRate); + sigpath::signalPath.setSampleRate(sampleRate); if (soapy.gainList.size() >= 0) { delete[] uiGains; @@ -576,7 +571,7 @@ void drawWindow() { } } } - setVFO(fSel.frequency); + setVFO(gui::freqSelect.frequency); config::config["source"] = sourceName; config::configModified = true; } @@ -586,9 +581,9 @@ void drawWindow() { spdlog::info("Changed sample rate: {0}", srId); sampleRate = soapy.sampleRates[srId]; soapy.setSampleRate(sampleRate); - wtf.setBandwidth(sampleRate); - wtf.setViewBandwidth(sampleRate); - sigPath.setSampleRate(sampleRate); + gui::waterfall.setBandwidth(sampleRate); + gui::waterfall.setViewBandwidth(sampleRate); + sigpath::signalPath.setSampleRate(sampleRate); bw.val = sampleRate; if (!config::config["sourceSettings"].contains(sourceName)) { @@ -739,7 +734,7 @@ void drawWindow() { if (ImGui::CollapsingHeader("Display", ImGuiTreeNodeFlags_DefaultOpen)) { if (ImGui::Checkbox("Show waterfall", &showWaterfall)) { - showWaterfall ? wtf.showWaterfall() : wtf.hideWaterfall(); + showWaterfall ? gui::waterfall.showWaterfall() : gui::waterfall.hideWaterfall(); } ImGui::Spacing(); } @@ -747,7 +742,7 @@ void drawWindow() { if(ImGui::CollapsingHeader("Debug")) { ImGui::Text("Frame time: %.3f ms/frame", 1000.0f / ImGui::GetIO().Framerate); ImGui::Text("Framerate: %.1f FPS", ImGui::GetIO().Framerate); - ImGui::Text("Center Frequency: %.0f Hz", wtf.getCenterFrequency()); + ImGui::Text("Center Frequency: %.0f Hz", gui::waterfall.getCenterFrequency()); ImGui::Text("Source name: %s", sourceName.c_str()); ImGui::Spacing(); } @@ -769,7 +764,7 @@ void drawWindow() { ImGui::BeginChild("Waterfall"); - wtf.draw(); + gui::waterfall.draw(); ImGui::EndChild(); @@ -807,14 +802,14 @@ void drawWindow() { ImGui::EndChild(); if (bw.changed()) { - wtf.setViewBandwidth(bw.val); - wtf.setViewOffset(vfo->centerOffset); + gui::waterfall.setViewBandwidth(bw.val); + gui::waterfall.setViewOffset(vfo->centerOffset); } - wtf.setFFTMin(fftMin); - wtf.setFFTMax(fftMax); - wtf.setWaterfallMin(fftMin); - wtf.setWaterfallMax(fftMax); + gui::waterfall.setFFTMin(fftMin); + gui::waterfall.setFFTMax(fftMax); + gui::waterfall.setWaterfallMin(fftMin); + gui::waterfall.setWaterfallMax(fftMax); ImGui::End(); diff --git a/core/src/main_window.h b/core/src/gui/main_window.h similarity index 71% rename from core/src/main_window.h rename to core/src/gui/main_window.h index 2b7fe923..265717fb 100644 --- a/core/src/main_window.h +++ b/core/src/gui/main_window.h @@ -13,19 +13,20 @@ #include #include #include -#include -#include +#include +#include #include -#include +#include #include -#include -#include +#include +#include #include #include -#include -#include -#include +#include +#include +#include #include +#include #define WINDOW_FLAGS ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBackground diff --git a/core/src/gui/menu.cpp b/core/src/gui/menu.cpp new file mode 100644 index 00000000..b967698b --- /dev/null +++ b/core/src/gui/menu.cpp @@ -0,0 +1,24 @@ +#include + +Menu::Menu() { + +} + +void Menu::registerEntry(std::string name, void (*drawHandler)(void* ctx), void* ctx) { + MenuItem_t item; + item.drawHandler = drawHandler; + item.ctx = ctx; + items[name] = item; +} + +void Menu::removeEntry(std::string name) { + items.erase(name); +} + +void Menu::draw() { + MenuItem_t item; + for (std::string name : order) { + item = items[name]; + item.drawHandler(item.ctx); + } +} diff --git a/core/src/gui/menu.h b/core/src/gui/menu.h new file mode 100644 index 00000000..e7f21f5d --- /dev/null +++ b/core/src/gui/menu.h @@ -0,0 +1,23 @@ +#pragma once +#include +#include +#include + +class Menu { +public: + Menu(); + + struct MenuItem_t { + void (*drawHandler)(void* ctx); + void* ctx; + }; + + void registerEntry(std::string name, void (*drawHandler)(void* ctx), void* ctx = NULL); + void removeEntry(std::string name); + void draw(); + + std::vector order; + +private: + std::map items; +}; \ No newline at end of file diff --git a/core/src/style.cpp b/core/src/gui/style.cpp similarity index 99% rename from core/src/style.cpp rename to core/src/gui/style.cpp index 9f2a5b15..e55df3d7 100644 --- a/core/src/style.cpp +++ b/core/src/gui/style.cpp @@ -1,4 +1,4 @@ -#include +#include namespace style { void setDefaultStyle() { diff --git a/core/src/style.h b/core/src/gui/style.h similarity index 100% rename from core/src/style.h rename to core/src/gui/style.h diff --git a/core/src/waterfall.cpp b/core/src/gui/waterfall.cpp similarity index 99% rename from core/src/waterfall.cpp rename to core/src/gui/waterfall.cpp index d590f780..6a17381c 100644 --- a/core/src/waterfall.cpp +++ b/core/src/gui/waterfall.cpp @@ -1,4 +1,4 @@ -#include +#include float COLOR_MAP[][3] = { {0x00, 0x00, 0x20}, @@ -650,6 +650,7 @@ namespace ImGui { } void WaterfallVFO::setOffset(float offset) { + printf("WaterfallVFO::SetOffset: %p\n", this); generalOffset = offset; if (reference == REF_CENTER) { centerOffset = offset; diff --git a/core/src/waterfall.h b/core/src/gui/waterfall.h similarity index 99% rename from core/src/waterfall.h rename to core/src/gui/waterfall.h index e7d21aad..1ce08a3d 100644 --- a/core/src/waterfall.h +++ b/core/src/gui/waterfall.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #define WATERFALL_RESOLUTION 1000000 diff --git a/core/src/module.cpp b/core/src/module.cpp index 2ea8be18..4df08517 100644 --- a/core/src/module.cpp +++ b/core/src/module.cpp @@ -1,7 +1,7 @@ #include -#include -#include -#include +#include +#include +#include namespace mod { API_t API; @@ -16,16 +16,6 @@ namespace mod { void initAPI(ImGui::WaterFall* wtf) { _wtf = wtf; - // VFO Manager - API.registerVFO = vfoman::create; - API.setVFOOffset = vfoman::setOffset; - API.setVFOCenterOffset = vfoman::setCenterOffset; - API.setVFOBandwidth = vfoman::setBandwidth; - API.setVFOSampleRate = vfoman::setSampleRate; - API.getVFOOutputBlockSize = vfoman::getOutputBlockSize; - API.setVFOReference = vfoman::setReference; - API.removeVFO = vfoman::remove; - // GUI API.getSelectedVFOName = api_getSelectedVFOName; API.bindVolumeVariable = bindVolumeVariable; diff --git a/core/src/module.h b/core/src/module.h index d5b16193..f98384d3 100644 --- a/core/src/module.h +++ b/core/src/module.h @@ -7,16 +7,25 @@ #include #include #include -#include +#include #include +#ifdef _WIN32 +#ifdef SDRPP_IS_CORE +#define SDRPP_EXPORT extern "C" __declspec(dllexport) +#else +#define SDRPP_EXPORT extern "C" __declspec(dllimport) +#endif +#else +#define SDRPP_EXPORT /**/ +#endif + #ifdef _WIN32 #include -#define MOD_EXPORT extern "C" \ - __declspec(dllexport) +#define MOD_EXPORT extern "C" __declspec(dllexport) #else #include -#define MOD_EXPORT extern "C" +#define MOD_EXPORT extern "C" #endif namespace mod { diff --git a/core/src/audio.cpp b/core/src/signal_path/audio.cpp similarity index 99% rename from core/src/audio.cpp rename to core/src/signal_path/audio.cpp index 18acf105..363ef7a1 100644 --- a/core/src/audio.cpp +++ b/core/src/signal_path/audio.cpp @@ -1,4 +1,4 @@ -#include +#include namespace audio { std::map streams; diff --git a/core/src/audio.h b/core/src/signal_path/audio.h similarity index 100% rename from core/src/audio.h rename to core/src/signal_path/audio.h diff --git a/core/src/signal_path.cpp b/core/src/signal_path/dsp.cpp similarity index 98% rename from core/src/signal_path.cpp rename to core/src/signal_path/dsp.cpp index 777dcb3a..f2f50333 100644 --- a/core/src/signal_path.cpp +++ b/core/src/signal_path/dsp.cpp @@ -1,4 +1,4 @@ -#include +#include SignalPath::SignalPath() { diff --git a/core/src/signal_path.h b/core/src/signal_path/dsp.h similarity index 100% rename from core/src/signal_path.h rename to core/src/signal_path/dsp.h diff --git a/core/src/signal_path/signal_path.cpp b/core/src/signal_path/signal_path.cpp new file mode 100644 index 00000000..13188e15 --- /dev/null +++ b/core/src/signal_path/signal_path.cpp @@ -0,0 +1,6 @@ +#include + +namespace sigpath { + SignalPath signalPath; + VFOManager vfoManager; +}; \ No newline at end of file diff --git a/core/src/signal_path/signal_path.h b/core/src/signal_path/signal_path.h new file mode 100644 index 00000000..c0d10a73 --- /dev/null +++ b/core/src/signal_path/signal_path.h @@ -0,0 +1,9 @@ +#pragma once +#include +#include +#include + +namespace sigpath { + SDRPP_EXPORT SignalPath signalPath; + SDRPP_EXPORT VFOManager vfoManager; +}; \ No newline at end of file diff --git a/core/src/signal_path/vfo_manager.cpp b/core/src/signal_path/vfo_manager.cpp new file mode 100644 index 00000000..bf356996 --- /dev/null +++ b/core/src/signal_path/vfo_manager.cpp @@ -0,0 +1,128 @@ +#include +#include + +VFOManager::VFO::VFO(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize) { + this->name = name; + dspVFO = sigpath::signalPath.addVFO(name, sampleRate, bandwidth, offset); + wtfVFO = new ImGui::WaterfallVFO; + wtfVFO->setReference(reference); + wtfVFO->setBandwidth(bandwidth); + wtfVFO->setOffset(offset); + output = dspVFO->output; + printf("Created VFO: %p", wtfVFO); + gui::waterfall.vfos[name] = wtfVFO; +} + +VFOManager::VFO::~VFO() { + gui::waterfall.vfos.erase(name); + sigpath::signalPath.removeVFO(name); + delete wtfVFO; +} + +void VFOManager::VFO::setOffset(float offset) { + wtfVFO->setOffset(offset); + dspVFO->setOffset(wtfVFO->centerOffset); +} + +void VFOManager::VFO::setCenterOffset(float offset) { + wtfVFO->setCenterOffset(offset); + dspVFO->setOffset(offset); +} + +void VFOManager::VFO::setBandwidth(float bandwidth) { + wtfVFO->setBandwidth(bandwidth); + dspVFO->setBandwidth(bandwidth); +} + +void VFOManager::VFO::setSampleRate(float sampleRate, float bandwidth) { + dspVFO->setOutputSampleRate(sampleRate, bandwidth); + wtfVFO->setBandwidth(bandwidth); +} + +void VFOManager::VFO::setReference(int ref) { + wtfVFO->setReference(ref); +} + +int VFOManager::VFO::getOutputBlockSize() { + return dspVFO->getOutputBlockSize(); +} + + +VFOManager::VFOManager() { + +} + +VFOManager::VFO* VFOManager::createVFO(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize) { + if (vfos.find(name) != vfos.end() || name == "") { + return NULL; + } + VFOManager::VFO* vfo = new VFO(name, reference, offset, bandwidth, sampleRate, blockSize); + vfos[name] = vfo; + return vfo; +} + +void VFOManager::deleteVFO(VFOManager::VFO* vfo) { + std::string name = ""; + for (auto const& [_name, _vfo] : vfos) { + if (_vfo == vfo) { + name == _name; + break; + } + } + if (name == "") { + return; + } + vfos.erase(name); +} + +void VFOManager::setOffset(std::string name, float offset) { + if (vfos.find(name) == vfos.end()) { + return; + } + vfos[name]->setOffset(offset); +} + +void VFOManager::setCenterOffset(std::string name, float offset) { + if (vfos.find(name) == vfos.end()) { + return; + } + vfos[name]->setCenterOffset(offset); +} + +void VFOManager::setBandwidth(std::string name, float bandwidth) { + if (vfos.find(name) == vfos.end()) { + return; + } + vfos[name]->setBandwidth(bandwidth); +} + +void VFOManager::setSampleRate(std::string name, float sampleRate, float bandwidth) { + if (vfos.find(name) == vfos.end()) { + return; + } + vfos[name]->setSampleRate(sampleRate, bandwidth); +} + +void VFOManager::setReference(std::string name, int ref) { + if (vfos.find(name) == vfos.end()) { + return; + } + vfos[name]->setReference(ref); +} + +int VFOManager::getOutputBlockSize(std::string name) { + if (vfos.find(name) == vfos.end()) { + return -1; + } + return vfos[name]->getOutputBlockSize(); +} + +void VFOManager::updateFromWaterfall(ImGui::WaterFall* wtf) { + for (auto const& [name, vfo] : vfos) { + if (vfo->wtfVFO->centerOffsetChanged) { + spdlog::info("UH OH: Change!"); + vfo->wtfVFO->centerOffsetChanged = false; + vfo->dspVFO->setOffset(vfo->wtfVFO->centerOffset); + } + } +} diff --git a/core/src/signal_path/vfo_manager.h b/core/src/signal_path/vfo_manager.h new file mode 100644 index 00000000..c61ae865 --- /dev/null +++ b/core/src/signal_path/vfo_manager.h @@ -0,0 +1,47 @@ +#pragma once +#include +#include +#include + +class VFOManager { +public: + VFOManager(); + + class VFO { + public: + VFO(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize); + ~VFO(); + + void setOffset(float offset); + void setCenterOffset(float offset); + void setBandwidth(float bandwidth); + void setSampleRate(float sampleRate, float bandwidth); + void setReference(int ref); + int getOutputBlockSize(); + + dsp::stream* output; + + friend class VFOManager; + + private: + std::string name; + dsp::VFO* dspVFO; + ImGui::WaterfallVFO* wtfVFO; + + }; + + VFOManager::VFO* createVFO(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize); + void deleteVFO(VFOManager::VFO* vfo); + + void setOffset(std::string name, float offset); + void setCenterOffset(std::string name, float offset); + void setBandwidth(std::string name, float bandwidth); + void setSampleRate(std::string name, float sampleRate, float bandwidth); + void setReference(std::string name, int ref); + int getOutputBlockSize(std::string name); + + void updateFromWaterfall(ImGui::WaterFall* wtf); + +private: + std::map vfos; +}; \ No newline at end of file diff --git a/core/src/vfo_manager.cpp b/core/src/vfo_manager.cpp deleted file mode 100644 index fc23a34a..00000000 --- a/core/src/vfo_manager.cpp +++ /dev/null @@ -1,99 +0,0 @@ -#include - -namespace vfoman { - std::map vfos; - ImGui::WaterFall* _wtf; - SignalPath* _sigPath; - - void init(ImGui::WaterFall* wtf, SignalPath* sigPath) { - _wtf = wtf; - _sigPath = sigPath; - } - - dsp::stream* create(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize) { - if (vfos.find(name) != vfos.end()) { - spdlog::warn("Tried to add VFO with an already existing name: {0}", name); - return NULL; - } - spdlog::info("Creating new VFO '{0}'", name); - VFO_t vfo; - vfo.dspVFO = _sigPath->addVFO(name, sampleRate, bandwidth, offset); - vfo.wtfVFO = new ImGui::WaterfallVFO; - vfo.wtfVFO->setReference(reference); - vfo.wtfVFO->setBandwidth(bandwidth); - vfo.wtfVFO->setOffset(offset); - _wtf->vfos[name] = vfo.wtfVFO; - vfos[name] = vfo; - return vfo.dspVFO->output; - } - - void setOffset(std::string name, float offset) { - if (vfos.find(name) == vfos.end()) { - return; - } - VFO_t vfo = vfos[name]; - vfo.wtfVFO->setOffset(offset); - vfo.dspVFO->setOffset(vfo.wtfVFO->centerOffset); - } - - void setCenterOffset(std::string name, float offset) { - if (vfos.find(name) == vfos.end()) { - return; - } - VFO_t vfo = vfos[name]; - vfo.wtfVFO->setCenterOffset(offset); - vfo.dspVFO->setOffset(offset); - } - - void setBandwidth(std::string name, float bandwidth) { - if (vfos.find(name) == vfos.end()) { - return; - } - VFO_t vfo = vfos[name]; - vfo.wtfVFO->setBandwidth(bandwidth); - vfo.dspVFO->setBandwidth(bandwidth); - } - - void setSampleRate(std::string name, float sampleRate, float bandwidth) { - if (vfos.find(name) == vfos.end()) { - return; - } - VFO_t vfo = vfos[name]; - vfo.dspVFO->setOutputSampleRate(sampleRate, bandwidth); - vfo.wtfVFO->setBandwidth(bandwidth); - } - - void setReference(std::string name, int ref){ - if (vfos.find(name) == vfos.end()) { - return; - } - vfos[name].wtfVFO->setReference(ref); - } - - int getOutputBlockSize(std::string name) { - if (vfos.find(name) == vfos.end()) { - return -1; - } - return vfos[name].dspVFO->getOutputBlockSize(); - } - - void remove(std::string name) { - if (vfos.find(name) == vfos.end()) { - return; - } - VFO_t vfo = vfos[name]; - _wtf->vfos.erase(name); - _sigPath->removeVFO(name); - delete vfo.wtfVFO; - vfos.erase(name); - } - - void updateFromWaterfall() { - for (auto const& [name, vfo] : vfos) { - if (vfo.wtfVFO->centerOffsetChanged) { - vfo.wtfVFO->centerOffsetChanged = false; - vfo.dspVFO->setOffset(vfo.wtfVFO->centerOffset); - } - } - } -}; \ No newline at end of file diff --git a/core/src/vfo_manager.h b/core/src/vfo_manager.h deleted file mode 100644 index 6656db84..00000000 --- a/core/src/vfo_manager.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include -#include -#include - -namespace vfoman { - struct VFO_t { - dsp::VFO* dspVFO; - ImGui::WaterfallVFO* wtfVFO; - }; - - void init(ImGui::WaterFall* wtf, SignalPath* sigPath); - - dsp::stream* create(std::string name, int reference, float offset, float bandwidth, float sampleRate, int blockSize); - void setOffset(std::string name, float offset); - void setCenterOffset(std::string name, float offset); - void setBandwidth(std::string name, float bandwidth); - void setSampleRate(std::string name, float sampleRate, float bandwidth); - void setReference(std::string name, int ref); - int getOutputBlockSize(std::string name); - void remove(std::string name); - - void updateFromWaterfall(); -}; \ No newline at end of file diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt index 9fe9176a..7354f36e 100644 --- a/demo/CMakeLists.txt +++ b/demo/CMakeLists.txt @@ -1,6 +1,13 @@ cmake_minimum_required(VERSION 3.13) project(demo) +if (MSVC) + set(CMAKE_CXX_FLAGS "-O2 /std:c++17") +else() + set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive -fsanitize=address -g") + # set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive") +endif (MSVC) + file(GLOB SRC "src/*.cpp") add_library(demo SHARED ${SRC}) diff --git a/demo/src/main.cpp b/demo/src/main.cpp index 8abd3cf3..0201e70d 100644 --- a/demo/src/main.cpp +++ b/demo/src/main.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #define CONCAT(a, b) ((std::string(a) + b).c_str()) diff --git a/radio/CMakeLists.txt b/radio/CMakeLists.txt index 2ac85c54..b6cfe995 100644 --- a/radio/CMakeLists.txt +++ b/radio/CMakeLists.txt @@ -3,53 +3,14 @@ project(radio) if (MSVC) set(CMAKE_CXX_FLAGS "-O2 /std:c++17") - link_directories(radio "C:/Program Files/PothosSDR/lib/") - include_directories(radio "C:/Program Files/PothosSDR/include/volk/") - include_directories(radio "C:/Program Files/PothosSDR/include/") else() - set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fsanitize=address -g") - include_directories(radio "/usr/include/volk") - link_libraries(pthread) - link_libraries(GL) - link_libraries(GLEW) - link_libraries(glfw) - link_libraries(fftw3) - link_libraries(fftw3f) - link_libraries(portaudio) - link_libraries(X11) - link_libraries(Xxf86vm) + set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive -fsanitize=address -g") + # set(CMAKE_CXX_FLAGS "-O3 -std=c++17 -fpermissive") endif (MSVC) -link_libraries(volk) -link_libraries(SoapySDR) - -# Main code -include_directories(radio "src/") -include_directories(radio "../core/src/") -include_directories(radio "../core/src/imgui") file(GLOB SRC "src/*.cpp") -file(GLOB IMGUI "../core/src/imgui/*.cpp") -add_library(radio SHARED ${SRC} ${IMGUI}) -set_target_properties(radio PROPERTIES PREFIX "") -if (MSVC) - # Glew - find_package(GLEW REQUIRED) - target_link_libraries(radio PRIVATE GLEW::GLEW) +include_directories("src/") - # GLFW3 - find_package(glfw3 CONFIG REQUIRED) - target_link_libraries(radio PRIVATE glfw) - - # FFTW3 - find_package(FFTW3 CONFIG REQUIRED) - target_link_libraries(radio PRIVATE FFTW3::fftw3) - find_package(FFTW3f CONFIG REQUIRED) - target_link_libraries(radio PRIVATE FFTW3::fftw3f) - - # PortAudio - find_package(portaudio CONFIG REQUIRED) - target_link_libraries(radio PRIVATE portaudio portaudio_static) -endif (MSVC) - -# cmake .. "-DCMAKE_TOOLCHAIN_FILE=C:/Users/Alex/vcpkg/scripts/buildsystems/vcpkg.cmake" -G "Visual Studio 15 2017 Win64" \ No newline at end of file +add_library(radio SHARED ${SRC}) +target_link_libraries(radio PRIVATE sdrpp_core) \ No newline at end of file diff --git a/radio/src/main.cpp b/radio/src/main.cpp index 7a365f8c..c007df3d 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -25,7 +25,7 @@ MOD_EXPORT void* _INIT_(mod::API_t* _API, ImGuiContext* imctx, std::string _name ctx->bandWidth = 200000; ctx->bandWidthMin = 100000; ctx->bandWidthMax = 200000; - ctx->sigPath.init(_name, 200000, 1000, API->registerVFO(_name, mod::API_t::REF_CENTER, 0, 200000, 200000, 1000)); + ctx->sigPath.init(_name, 200000, 1000); ctx->sigPath.start(); ImGui::SetCurrentContext(imctx); return ctx; @@ -49,7 +49,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) { ctx->bandWidthMin = 8000; ctx->bandWidthMax = 16000; ctx->sigPath.setDemodulator(SigPath::DEMOD_NFM, ctx->bandWidth); - API->setVFOReference(ctx->name, mod::API_t::REF_CENTER); } if (ImGui::RadioButton(CONCAT("WFM##_", ctx->name), ctx->demod == 1) && ctx->demod != 1) { ctx->demod = 1; @@ -57,7 +56,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) { ctx->bandWidthMin = 100000; ctx->bandWidthMax = 200000; ctx->sigPath.setDemodulator(SigPath::DEMOD_FM, ctx->bandWidth); - API->setVFOReference(ctx->name, mod::API_t::REF_CENTER); } ImGui::NextColumn(); if (ImGui::RadioButton(CONCAT("AM##_", ctx->name), ctx->demod == 2) && ctx->demod != 2) { @@ -66,7 +64,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) { ctx->bandWidthMin = 6250; ctx->bandWidthMax = 12500; ctx->sigPath.setDemodulator(SigPath::DEMOD_AM, ctx->bandWidth); - API->setVFOReference(ctx->name, mod::API_t::REF_CENTER); } if (ImGui::RadioButton(CONCAT("DSB##_", ctx->name), ctx->demod == 3) && ctx->demod != 3) { ctx->demod = 3; @@ -74,7 +71,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) { ctx->bandWidthMin = 3000; ctx->bandWidthMax = 6000; ctx->sigPath.setDemodulator(SigPath::DEMOD_DSB, ctx->bandWidth); - API->setVFOReference(ctx->name, mod::API_t::REF_CENTER); } ImGui::NextColumn(); if (ImGui::RadioButton(CONCAT("USB##_", ctx->name), ctx->demod == 4) && ctx->demod != 4) { @@ -83,7 +79,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) { ctx->bandWidthMin = 1500; ctx->bandWidthMax = 3000; ctx->sigPath.setDemodulator(SigPath::DEMOD_USB, ctx->bandWidth); - API->setVFOReference(ctx->name, mod::API_t::REF_LOWER); } if (ImGui::RadioButton(CONCAT("CW##_", ctx->name), ctx->demod == 5) && ctx->demod != 5) { ctx->demod = 5; }; ImGui::NextColumn(); @@ -93,7 +88,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) { ctx->bandWidthMin = 1500; ctx->bandWidthMax = 3000; ctx->sigPath.setDemodulator(SigPath::DEMOD_LSB, ctx->bandWidth); - API->setVFOReference(ctx->name, mod::API_t::REF_UPPER); } if (ImGui::RadioButton(CONCAT("RAW##_", ctx->name), ctx->demod == 7) && ctx->demod != 7) { ctx->demod = 7; @@ -101,7 +95,6 @@ MOD_EXPORT void _DRAW_MENU_(RadioContext_t* ctx) { ctx->bandWidthMin = 3000; ctx->bandWidthMax = 10000; ctx->sigPath.setDemodulator(SigPath::DEMOD_RAW, ctx->bandWidth); - API->setVFOReference(ctx->name, mod::API_t::REF_CENTER); }; ImGui::Columns(1, CONCAT("EndRadioModeColumns##_", ctx->name), false); diff --git a/radio/src/path.cpp b/radio/src/path.cpp index 5fd332cf..f0547757 100644 --- a/radio/src/path.cpp +++ b/radio/src/path.cpp @@ -18,11 +18,13 @@ int SigPath::sampleRateChangeHandler(void* ctx, float sampleRate) { return _this->audioResamp.getOutputBlockSize(); } -void SigPath::init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp::stream* input) { +void SigPath::init(std::string vfoName, uint64_t sampleRate, int blockSize) { this->sampleRate = sampleRate; this->blockSize = blockSize; this->vfoName = vfoName; + vfo = sigpath::vfoManager.createVFO(vfoName, mod::API_t::REF_CENTER, 0, 200000, 200000, 1000); + _demod = DEMOD_FM; _deemp = DEEMP_50US; bandwidth = 200000; @@ -31,10 +33,10 @@ void SigPath::init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp: // TODO: ajust deemphasis for different output sample rates // TODO: Add a mono to stereo for different modes - demod.init(input, 100000, 200000, 800); - amDemod.init(input, 50); - ssbDemod.init(input, 6000, 3000, 22); - cpx2stereo.init(input, 22); + demod.init(vfo->output, 100000, 200000, 800); + amDemod.init(vfo->output, 50); + ssbDemod.init(vfo->output, 6000, 3000, 22); + cpx2stereo.init(vfo->output, 22); audioResamp.init(&demod.output, 200000, 48000, 800); deemp.init(&audioResamp.output, 800, 50e-6, 48000); @@ -91,72 +93,79 @@ void SigPath::setDemodulator(int demId, float bandWidth) { // Set input of the audio resampler // TODO: Set bandwidth from argument if (demId == DEMOD_FM) { - API->setVFOSampleRate(vfoName, 200000, bandwidth); - demod.setBlockSize(API->getVFOOutputBlockSize(vfoName)); + vfo->setSampleRate(200000, bandwidth); + demod.setBlockSize(vfo->getOutputBlockSize()); demod.setSampleRate(200000); demod.setDeviation(bandwidth / 2.0f); audioResamp.setInput(&demod.output); audioBw = std::min(bandwidth, outputSampleRate / 2.0f); - audioResamp.setInputSampleRate(200000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw); + audioResamp.setInputSampleRate(200000, vfo->getOutputBlockSize(), audioBw, audioBw); deemp.bypass = (_deemp == DEEMP_NONE); + vfo->setReference(mod::API_t::REF_CENTER); demod.start(); } else if (demId == DEMOD_NFM) { - API->setVFOSampleRate(vfoName, 16000, bandwidth); - demod.setBlockSize(API->getVFOOutputBlockSize(vfoName)); + vfo->setSampleRate(16000, bandwidth); + demod.setBlockSize(vfo->getOutputBlockSize()); demod.setSampleRate(16000); demod.setDeviation(bandwidth / 2.0f); audioResamp.setInput(&demod.output); audioBw = std::min(bandwidth, outputSampleRate / 2.0f); - audioResamp.setInputSampleRate(16000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw); + audioResamp.setInputSampleRate(16000, vfo->getOutputBlockSize(), audioBw, audioBw); deemp.bypass = true; + vfo->setReference(mod::API_t::REF_CENTER); demod.start(); } else if (demId == DEMOD_AM) { - API->setVFOSampleRate(vfoName, 12500, bandwidth); - amDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName)); + vfo->setSampleRate(12500, bandwidth); + amDemod.setBlockSize(vfo->getOutputBlockSize()); audioResamp.setInput(&amDemod.output); audioBw = std::min(bandwidth, outputSampleRate / 2.0f); - audioResamp.setInputSampleRate(12500, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw); + audioResamp.setInputSampleRate(12500, vfo->getOutputBlockSize(), audioBw, audioBw); deemp.bypass = true; + vfo->setReference(mod::API_t::REF_CENTER); amDemod.start(); } else if (demId == DEMOD_USB) { - API->setVFOSampleRate(vfoName, 6000, bandwidth); - ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName)); + vfo->setSampleRate(6000, bandwidth); + ssbDemod.setBlockSize(vfo->getOutputBlockSize()); ssbDemod.setMode(dsp::SSBDemod::MODE_USB); audioResamp.setInput(&ssbDemod.output); audioBw = std::min(bandwidth, outputSampleRate / 2.0f); - audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw); + audioResamp.setInputSampleRate(6000, vfo->getOutputBlockSize(), audioBw, audioBw); deemp.bypass = true; + vfo->setReference(mod::API_t::REF_LOWER); ssbDemod.start(); } else if (demId == DEMOD_LSB) { - API->setVFOSampleRate(vfoName, 6000, bandwidth); - ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName)); + vfo->setSampleRate(6000, bandwidth); + ssbDemod.setBlockSize(vfo->getOutputBlockSize()); ssbDemod.setMode(dsp::SSBDemod::MODE_LSB); audioResamp.setInput(&ssbDemod.output); audioBw = std::min(bandwidth, outputSampleRate / 2.0f); - audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw); + audioResamp.setInputSampleRate(6000, vfo->getOutputBlockSize(), audioBw, audioBw); deemp.bypass = true; + vfo->setReference(mod::API_t::REF_UPPER); ssbDemod.start(); } else if (demId == DEMOD_DSB) { - API->setVFOSampleRate(vfoName, 6000, bandwidth); - ssbDemod.setBlockSize(API->getVFOOutputBlockSize(vfoName)); + vfo->setSampleRate(6000, bandwidth); + ssbDemod.setBlockSize(vfo->getOutputBlockSize()); ssbDemod.setMode(dsp::SSBDemod::MODE_DSB); audioResamp.setInput(&ssbDemod.output); audioBw = std::min(bandwidth, outputSampleRate / 2.0f); - audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw); + audioResamp.setInputSampleRate(6000, vfo->getOutputBlockSize(), audioBw, audioBw); deemp.bypass = true; + vfo->setReference(mod::API_t::REF_CENTER); ssbDemod.start(); } else if (demId == DEMOD_RAW) { - API->setVFOSampleRate(vfoName, 10000, bandwidth); - cpx2stereo.setBlockSize(API->getVFOOutputBlockSize(vfoName)); + vfo->setSampleRate(10000, bandwidth); + cpx2stereo.setBlockSize(vfo->getOutputBlockSize()); //audioResamp.setInput(&cpx2stereo.output); audioBw = std::min(bandwidth, outputSampleRate / 2.0f); - audioResamp.setInputSampleRate(10000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw); + audioResamp.setInputSampleRate(10000, vfo->getOutputBlockSize(), audioBw, audioBw); + vfo->setReference(mod::API_t::REF_LOWER); cpx2stereo.start(); } else { @@ -192,7 +201,7 @@ void SigPath::setDeemphasis(int deemph) { void SigPath::setBandwidth(float bandWidth) { bandwidth = bandWidth; - API->setVFOBandwidth(vfoName, bandwidth); + vfo->setBandwidth(bandwidth); if (_demod == DEMOD_FM) { demod.stop(); demod.setDeviation(bandwidth / 2.0f); @@ -231,7 +240,7 @@ void SigPath::setBandwidth(float bandWidth) { if (audioBw != _audioBw) { audioBw = _audioBw; audioResamp.stop(); - audioResamp.setInputSampleRate(6000, API->getVFOOutputBlockSize(vfoName), audioBw, audioBw); + audioResamp.setInputSampleRate(6000, vfo->getOutputBlockSize(), audioBw, audioBw); audioResamp.start(); } } diff --git a/radio/src/path.h b/radio/src/path.h index 63cee571..f3f6b822 100644 --- a/radio/src/path.h +++ b/radio/src/path.h @@ -10,11 +10,12 @@ #include #include #include +#include class SigPath { public: SigPath(); - void init(std::string vfoName, uint64_t sampleRate, int blockSize, dsp::stream* input); + void init(std::string vfoName, uint64_t sampleRate, int blockSize); void start(); void setSampleRate(float sampleRate); void setVFOFrequency(uint64_t frequency); @@ -46,6 +47,8 @@ public: private: static int sampleRateChangeHandler(void* ctx, float sampleRate); + + VFOManager::VFO* vfo; dsp::stream input; diff --git a/root_dev/config.json b/root_dev/config.json index 14d71bf2..95be2664 100644 --- a/root_dev/config.json +++ b/root_dev/config.json @@ -3,13 +3,13 @@ "Radio": { "device": "Speakers (Realtek High Definiti", "sampleRate": 48000.0, - "volume": 0.4032258093357086 + "volume": 0.6666666865348816 } }, "bandPlan": "General", "bandPlanEnabled": true, "fftHeight": 300, - "frequency": 99000000, + "frequency": 103200000, "max": 0.0, "maximized": false, "menuWidth": 300,