diff --git a/core/src/core.cpp b/core/src/core.cpp index 4796ed65..bb601b5d 100644 --- a/core/src/core.cpp +++ b/core/src/core.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/core/src/gui/gui.h b/core/src/gui/gui.h index 1e371638..e6a2ee5a 100644 --- a/core/src/gui/gui.h +++ b/core/src/gui/gui.h @@ -1,7 +1,7 @@ #pragma once -#include -#include -#include +#include +#include +#include #include #include diff --git a/core/src/gui/main_window.cpp b/core/src/gui/main_window.cpp index 0e200aa2..e1645a45 100644 --- a/core/src/gui/main_window.cpp +++ b/core/src/gui/main_window.cpp @@ -9,12 +9,12 @@ #include #include #include -#include -#include +#include +#include #include #include #include -#include +#include #include #include #include @@ -122,12 +122,13 @@ void windowInit() { displaymenu::init(); // TODO for 0.2.5 - // Add a loading screen - // Add "select folder" option for the recorder module - // Add squelsh - // CW and RAW modes; - // Bring VFO to a visible place when changing sample rate if it's smaller - // Use DUK_USE_DATE_NOW_WINDOWS for windows 7 support + // Add "select folder" option for the file source + // Fix SSB demod + // FIX AUDIO ISSUE ON BOTH LINUX AND SOMETIMES WINDOWS (probly the ring buffer, though double buffering could help) + // Rewrite radio module with CW and RAW modes + // Add default main config to avoid having to ship one + // Have a good directory system on both linux and windows + // Switch to double buffering // TODO for 0.2.6 // And a module add/remove/change order menu diff --git a/core/src/gui/menus/bandplan.cpp b/core/src/gui/menus/bandplan.cpp index 8588b78e..7cb8664a 100644 --- a/core/src/gui/menus/bandplan.cpp +++ b/core/src/gui/menus/bandplan.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include diff --git a/core/src/gui/bandplan.cpp b/core/src/gui/widgets/bandplan.cpp similarity index 99% rename from core/src/gui/bandplan.cpp rename to core/src/gui/widgets/bandplan.cpp index af585b12..28bb4fcd 100644 --- a/core/src/gui/bandplan.cpp +++ b/core/src/gui/widgets/bandplan.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include diff --git a/core/src/gui/bandplan.h b/core/src/gui/widgets/bandplan.h similarity index 100% rename from core/src/gui/bandplan.h rename to core/src/gui/widgets/bandplan.h diff --git a/core/src/gui/frequency_select.cpp b/core/src/gui/widgets/frequency_select.cpp similarity index 99% rename from core/src/gui/frequency_select.cpp rename to core/src/gui/widgets/frequency_select.cpp index d0f96363..be0d2110 100644 --- a/core/src/gui/frequency_select.cpp +++ b/core/src/gui/widgets/frequency_select.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/core/src/gui/frequency_select.h b/core/src/gui/widgets/frequency_select.h similarity index 100% rename from core/src/gui/frequency_select.h rename to core/src/gui/widgets/frequency_select.h diff --git a/core/src/gui/menu.cpp b/core/src/gui/widgets/menu.cpp similarity index 96% rename from core/src/gui/menu.cpp rename to core/src/gui/widgets/menu.cpp index 74feb7e2..3bd06ed8 100644 --- a/core/src/gui/menu.cpp +++ b/core/src/gui/widgets/menu.cpp @@ -1,4 +1,4 @@ -#include +#include #include Menu::Menu() { diff --git a/core/src/gui/menu.h b/core/src/gui/widgets/menu.h similarity index 100% rename from core/src/gui/menu.h rename to core/src/gui/widgets/menu.h diff --git a/core/src/gui/waterfall.cpp b/core/src/gui/widgets/waterfall.cpp similarity index 98% rename from core/src/gui/waterfall.cpp rename to core/src/gui/widgets/waterfall.cpp index de25afe7..f211e939 100644 --- a/core/src/gui/waterfall.cpp +++ b/core/src/gui/widgets/waterfall.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -564,6 +564,14 @@ namespace ImGui { double currentRatio = viewBandwidth / wholeBandwidth; wholeBandwidth = bandWidth; setViewBandwidth(bandWidth * currentRatio); + for (auto const& [name, vfo] : vfos) { + if (vfo->lowerOffset < -(bandWidth / 2)) { + vfo->setCenterOffset(-(bandWidth / 2)); + } + if (vfo->upperOffset > (bandWidth / 2)) { + vfo->setCenterOffset(bandWidth / 2); + } + } updateAllVFOs(); } diff --git a/core/src/gui/waterfall.h b/core/src/gui/widgets/waterfall.h similarity index 99% rename from core/src/gui/waterfall.h rename to core/src/gui/widgets/waterfall.h index 20cdf588..f31a2a92 100644 --- a/core/src/gui/waterfall.h +++ b/core/src/gui/widgets/waterfall.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include +#include #include #include #include diff --git a/core/src/signal_path/vfo_manager.h b/core/src/signal_path/vfo_manager.h index 29bb8922..194c9ef8 100644 --- a/core/src/signal_path/vfo_manager.h +++ b/core/src/signal_path/vfo_manager.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include class VFOManager { diff --git a/recorder/src/main.cpp b/recorder/src/main.cpp index 2d7cc1be..aa16aea9 100644 --- a/recorder/src/main.cpp +++ b/recorder/src/main.cpp @@ -7,8 +7,11 @@ #include #include #include +#include #include #include +#include +#include #define CONCAT(a, b) ((std::string(a) + b).c_str()) @@ -30,6 +33,11 @@ void sampleRateChanged(void* ctx, double sampleRate, int blockSize) { } +std::string expandString(std::string input) { + input = std::regex_replace(input, std::regex("%ROOT%"), ROOT_DIR); + return std::regex_replace(input, std::regex("//"), "/"); +} + class RecorderModule { public: RecorderModule(std::string name) { @@ -38,6 +46,7 @@ public: selectedStreamName = ""; selectedStreamId = 0; lastNameList = ""; + strcpy(path, "%ROOT%/recordings"); gui::menu.registerEntry(name, menuHandler, this); } @@ -77,6 +86,27 @@ private: } ImGui::BeginGroup(); + if (_this->recording) { style::beginDisabled(); } + ImGui::SetNextItemWidth(menuColumnWidth); + bool lastPathValid = _this->pathValid; + if (!lastPathValid) { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); + } + if (ImGui::InputText(CONCAT("##_recorder_path_", _this->name), _this->path, 4095)) { + std::string expandedPath = expandString(_this->path); + if (!std::filesystem::exists(expandedPath)) { + _this->pathValid = false; + } + else if (!std::filesystem::is_directory(expandedPath)) { + _this->pathValid = false; + } + else { + _this->pathValid = true; + } + } + if (!lastPathValid) { + ImGui::PopStyleColor(); + } // TODO: Change VFO ref in signal path // TODO: Add VFO record @@ -88,6 +118,7 @@ private: if (ImGui::RadioButton(CONCAT("Audio##_", _this->name), _this->recMode == 1) && _this->recMode != 1) { _this->recMode = 1; } + if (_this->recording) { style::endDisabled(); } ImGui::Columns(1, CONCAT("EndRecordModeColumns##_", _this->name), false); ImGui::EndGroup(); @@ -95,16 +126,19 @@ private: if (_this->recMode == 0) { ImGui::PushItemWidth(menuColumnWidth); if (!_this->recording) { + if (!_this->pathValid) { style::beginDisabled(); } if (ImGui::Button("Record", ImVec2(menuColumnWidth, 0))) { + std::string expandedPath = expandString(std::string(_this->path) + genFileName("/baseband_")); _this->samplesWritten = 0; _this->sampleRate = sigpath::signalPath.getSampleRate(); - _this->writer = new WavWriter(ROOT_DIR "/recordings/" + genFileName("baseband_"), 16, 2, _this->sampleRate); + _this->writer = new WavWriter(expandedPath, 16, 2, _this->sampleRate); _this->iqStream = new dsp::stream; sigpath::signalPath.bindIQStream(_this->iqStream); _this->workerThread = std::thread(_iqWriteWorker, _this); _this->recording = true; _this->startTime = time(0); } + if (!_this->pathValid) { style::endDisabled(); } ImGui::TextColored(ImGui::GetStyleColorVec4(ImGuiCol_Text), "Idle --:--:--"); } else { @@ -140,15 +174,18 @@ private: ImGui::PopStyleColor(3); } if (!_this->recording) { + if (!_this->pathValid) { style::beginDisabled(); } if (ImGui::Button("Record", ImVec2(menuColumnWidth, 0))) { + std::string expandedPath = expandString(std::string(_this->path) + genFileName("/audio_")); _this->samplesWritten = 0; _this->sampleRate = sigpath::sinkManager.getStreamSampleRate(_this->selectedStreamName); - _this->writer = new WavWriter(ROOT_DIR "/recordings/" + genFileName("audio_"), 16, 2, _this->sampleRate); + _this->writer = new WavWriter(expandedPath, 16, 2, _this->sampleRate); _this->audioStream = sigpath::sinkManager.bindStream(_this->selectedStreamName); _this->workerThread = std::thread(_audioWriteWorker, _this); _this->recording = true; _this->startTime = time(0); } + if (!_this->pathValid) { style::endDisabled(); } ImGui::TextColored(ImGui::GetStyleColorVec4(ImGuiCol_Text), "Idle --:--:--"); } else { @@ -202,6 +239,8 @@ private: } std::string name; + char path[4096]; + bool pathValid = true; dsp::stream* audioStream; dsp::stream* iqStream; WavWriter* writer; diff --git a/root_dev/config.json b/root_dev/config.json index 66c796dd..88c611be 100644 --- a/root_dev/config.json +++ b/root_dev/config.json @@ -21,11 +21,10 @@ "fftHeight": 296, "frequency": 99000000, "max": 0.0, - "maximized": true, + "maximized": false, "menuOrder": [ "Source", - "Radio 1", - "Radio 2", + "Radio", "Recorder", "Sinks", "Audio", @@ -34,10 +33,10 @@ "Display" ], "menuWidth": 300, - "min": -53.676475524902344, + "min": -72.05882263183594, "offset": 0.0, "showWaterfall": true, - "source": "SoapySDR", + "source": "PlutoSDR", "sourceSettings": {}, "streams": { "Radio": { diff --git a/root_dev/module_list.json b/root_dev/module_list.json index a96849e7..5187e16c 100644 --- a/root_dev/module_list.json +++ b/root_dev/module_list.json @@ -1,6 +1,5 @@ { - "Radio 1": "./radio/Release/radio.dll", - "Radio 2": "./radio/Release/radio.dll", + "Radio": "./radio/Release/radio.dll", "Recorder": "./recorder/Release/recorder.dll", "Soapy": "./soapy/Release/soapy.dll", "RTLTCPSource": "./rtl_tcp_source/Release/rtl_tcp_source.dll", diff --git a/root_dev/plutosdr_source_config.json b/root_dev/plutosdr_source_config.json index cf337e35..96baa2e5 100644 --- a/root_dev/plutosdr_source_config.json +++ b/root_dev/plutosdr_source_config.json @@ -2,5 +2,5 @@ "IP": "192.168.2.1", "gain": 0.0, "gainMode": 2, - "sampleRate": 4000000.0 + "sampleRate": 2000000.0 } \ No newline at end of file