SDRPlusPlus/core/src/gui/main_window.cpp

495 lines
17 KiB
C++
Raw Normal View History

2020-09-20 00:19:39 +02:00
#include <gui/main_window.h>
#include <gui/gui.h>
#include "imgui.h"
#include "imgui_impl_glfw.h"
#include "imgui_impl_opengl3.h"
#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <imgui_plot.h>
#include <dsp/resampling.h>
#include <dsp/demodulator.h>
#include <dsp/filter.h>
#include <thread>
#include <complex>
#include <dsp/source.h>
#include <dsp/math.h>
#include <gui/waterfall.h>
#include <gui/frequency_select.h>
#include <fftw3.h>
#include <signal_path/dsp.h>
#include <gui/icons.h>
#include <gui/bandplan.h>
#include <watcher.h>
#include <module.h>
#include <signal_path/vfo_manager.h>
#include <signal_path/audio.h>
#include <gui/style.h>
#include <config.h>
#include <signal_path/signal_path.h>
#include <core.h>
#include <gui/menus/source.h>
#include <gui/menus/display.h>
#include <gui/menus/bandplan.h>
#include <gui/menus/audio.h>
#include <gui/menus/scripting.h>
#include <gui/dialogs/credits.h>
#include <signal_path/source.h>
2020-06-10 04:13:56 +02:00
std::thread worker;
std::mutex fft_mtx;
2020-06-10 18:52:07 +02:00
fftwf_complex *fft_in, *fft_out;
fftwf_plan p;
2020-06-15 15:53:45 +02:00
float* tempData;
2020-07-19 21:26:37 +02:00
char buf[1024];
2020-06-10 18:52:07 +02:00
2020-06-15 15:53:45 +02:00
int fftSize = 8192 * 8;
2020-06-10 04:13:56 +02:00
2020-06-15 15:53:45 +02:00
std::vector<float> _data;
std::vector<float> fftTaps;
2020-06-22 16:45:57 +02:00
void fftHandler(dsp::complex_t* samples) {
2020-06-15 15:53:45 +02:00
fftwf_execute(p);
int half = fftSize / 2;
2020-06-10 04:13:56 +02:00
2020-06-15 15:53:45 +02:00
for (int i = 0; i < half; i++) {
_data.push_back(log10(std::abs(std::complex<float>(fft_out[half + i][0], fft_out[half + i][1])) / (float)fftSize) * 10.0);
2020-06-15 15:53:45 +02:00
}
for (int i = 0; i < half; i++) {
_data.push_back(log10(std::abs(std::complex<float>(fft_out[i][0], fft_out[i][1])) / (float)fftSize) * 10.0);
2020-06-15 15:53:45 +02:00
}
2020-06-10 04:13:56 +02:00
2020-06-15 15:53:45 +02:00
for (int i = 5; i < fftSize; i++) {
_data[i] = (_data[i - 4] + _data[i - 3] + _data[i - 2] + _data[i - 1] + _data[i]) / 5.0;
2020-06-15 15:53:45 +02:00
}
2020-06-10 04:13:56 +02:00
2020-09-20 00:19:39 +02:00
gui::waterfall.pushFFT(_data, fftSize);
2020-06-15 15:53:45 +02:00
_data.clear();
}
2020-06-10 04:13:56 +02:00
2020-08-11 18:33:42 +02:00
dsp::NullSink sink;
2020-08-21 15:38:27 +02:00
watcher<uint64_t> freq((uint64_t)90500000);
watcher<double> vfoFreq(92000000.0);
float dummyVolume = 1.0;
2020-08-16 03:39:05 +02:00
float* volume = &dummyVolume;
float fftMin = -70.0;
float fftMax = 0.0;
watcher<double> offset(0.0, true);
watcher<float> bw(8000000.0, true);
2020-08-16 03:39:05 +02:00
bool playing = false;
watcher<bool> dcbias(false, false);
bool showCredits = false;
std::string audioStreamName = "";
std::string sourceName = "";
2020-08-20 18:29:23 +02:00
int menuWidth = 300;
bool grabbingMenu = false;
int newWidth = 300;
int fftHeight = 300;
2020-08-21 15:34:50 +02:00
bool showMenu = true;
2020-10-01 01:21:15 +02:00
dsp::stream<dsp::complex_t> dummyStream;
2020-09-24 19:36:57 +02:00
2020-08-16 03:39:05 +02:00
void windowInit() {
2020-09-19 12:48:34 +02:00
spdlog::info("Initializing SoapySDR");
2020-09-24 19:36:57 +02:00
credits::init();
2020-10-20 00:32:17 +02:00
core::configManager.aquire();
gui::menu.order = core::configManager.conf["menuOrder"].get<std::vector<std::string>>();
core::configManager.release();
2020-10-01 01:21:15 +02:00
gui::menu.registerEntry("Source", sourecmenu::draw, NULL);
gui::menu.registerEntry("Audio", audiomenu::draw, NULL);
2020-10-07 14:44:39 +02:00
gui::menu.registerEntry("Scripting", scriptingmenu::draw, NULL);
gui::menu.registerEntry("Band Plan", bandplanmenu::draw, NULL);
gui::menu.registerEntry("Display", displaymenu::draw, NULL);
2020-09-19 12:48:34 +02:00
2020-09-20 00:19:39 +02:00
gui::freqSelect.init();
2020-06-15 15:53:45 +02:00
2020-07-20 15:26:59 +02:00
fft_in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
fft_out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize);
2020-06-15 15:53:45 +02:00
p = fftwf_plan_dft_1d(fftSize, fft_in, fft_out, FFTW_FORWARD, FFTW_ESTIMATE);
2020-06-10 04:13:56 +02:00
2020-10-01 01:21:15 +02:00
sigpath::signalPath.init(8000000, 20, fftSize, &dummyStream, (dsp::complex_t*)fft_in, fftHandler);
2020-09-20 00:19:39 +02:00
sigpath::signalPath.start();
2020-08-11 18:33:42 +02:00
2020-08-12 16:43:44 +02:00
spdlog::info("Loading modules");
2020-09-24 19:36:57 +02:00
mod::loadFromList(ROOT_DIR "/module_list.json");
2020-06-10 04:13:56 +02:00
2020-10-01 01:21:15 +02:00
sourecmenu::init();
audiomenu::init();
2020-10-07 14:44:39 +02:00
scriptingmenu::init();
2020-10-01 01:21:15 +02:00
bandplanmenu::init();
displaymenu::init();
2020-08-16 03:39:05 +02:00
// Load last source configuration
2020-08-16 14:26:22 +02:00
// Also add a loading screen
2020-08-20 18:29:23 +02:00
// Adjustable "snap to grid" for each VFO
// Finish the recorder module
2020-08-16 14:26:22 +02:00
// Add squelsh
// Bandwidth ajustment
2020-09-06 15:39:09 +02:00
// CW and RAW modes;
2020-08-18 00:56:51 +02:00
// Bring VFO to a visible place when changing sample rate if it's smaller
2020-09-18 00:23:03 +02:00
// Add save config for modules
// Do VFO in two steps: First sample rate conversion, then filtering
2020-08-21 17:11:12 +02:00
2020-08-20 18:29:23 +02:00
// And a module add/remove/change order menu
2020-08-16 03:39:05 +02:00
// Update UI settings
2020-10-20 00:32:17 +02:00
core::configManager.aquire();
2020-09-24 19:36:57 +02:00
fftMin = core::configManager.conf["min"];
fftMax = core::configManager.conf["max"];
2020-09-20 00:19:39 +02:00
gui::waterfall.setFFTMin(fftMin);
gui::waterfall.setWaterfallMin(fftMin);
gui::waterfall.setFFTMax(fftMax);
gui::waterfall.setWaterfallMax(fftMax);
2020-10-01 01:21:15 +02:00
double frequency = core::configManager.conf["frequency"];
2020-08-16 03:39:05 +02:00
2020-09-20 00:19:39 +02:00
gui::freqSelect.setFrequency(frequency);
gui::freqSelect.frequencyChanged = false;
2020-10-01 01:21:15 +02:00
sigpath::sourceManager.tune(frequency);
2020-09-20 00:19:39 +02:00
gui::waterfall.setCenterFrequency(frequency);
2020-10-01 01:21:15 +02:00
gui::waterfall.setBandwidth(8000000);
gui::waterfall.setViewBandwidth(8000000);
bw.val = 8000000;
2020-09-20 00:19:39 +02:00
gui::waterfall.vfoFreqChanged = false;
gui::waterfall.centerFreqMoved = false;
gui::waterfall.selectFirstVFO();
2020-08-16 03:39:05 +02:00
2020-09-24 19:36:57 +02:00
menuWidth = core::configManager.conf["menuWidth"];
2020-08-20 18:29:23 +02:00
newWidth = menuWidth;
2020-09-24 19:36:57 +02:00
fftHeight = core::configManager.conf["fftHeight"];
2020-09-20 00:19:39 +02:00
gui::waterfall.setFFTHeight(fftHeight);
2020-09-24 19:36:57 +02:00
core::configManager.release();
2020-08-16 03:39:05 +02:00
}
2020-07-19 18:23:00 +02:00
void setVFO(double freq) {
2020-09-20 00:19:39 +02:00
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO];
2020-08-10 02:30:25 +02:00
double currentOff = vfo->centerOffset;
double currentTune = gui::waterfall.getCenterFrequency() + vfo->generalOffset;
double delta = freq - currentTune;
2020-07-19 15:59:44 +02:00
double newVFO = currentOff + delta;
double vfoBW = vfo->bandwidth;
double vfoBottom = newVFO - (vfoBW / 2.0);
double vfoTop = newVFO + (vfoBW / 2.0);
2020-07-19 15:59:44 +02:00
double view = gui::waterfall.getViewOffset();
double viewBW = gui::waterfall.getViewBandwidth();
double viewBottom = view - (viewBW / 2.0);
double viewTop = view + (viewBW / 2.0);
2020-07-19 15:59:44 +02:00
double wholeFreq = gui::waterfall.getCenterFrequency();
double BW = gui::waterfall.getBandwidth();
double bottom = -(BW / 2.0);
double top = (BW / 2.0);
2020-07-19 15:59:44 +02:00
// VFO still fints in the view
if (vfoBottom > viewBottom && vfoTop < viewTop) {
2020-09-20 00:19:39 +02:00
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO);
2020-07-19 15:59:44 +02:00
return;
}
// VFO too low for current SDR tuning
if (vfoBottom < bottom) {
gui::waterfall.setViewOffset((BW / 2.0) - (viewBW / 2.0));
double newVFOOffset = (BW / 2.0) - (vfoBW / 2.0) - (viewBW / 10.0);
2020-09-20 00:19:39 +02:00
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset);
gui::waterfall.setCenterFrequency(freq - newVFOOffset);
2020-10-01 01:21:15 +02:00
sigpath::sourceManager.tune(freq - newVFOOffset);
2020-07-19 15:59:44 +02:00
return;
}
// VFO too high for current SDR tuning
if (vfoTop > top) {
gui::waterfall.setViewOffset((viewBW / 2.0) - (BW / 2.0));
double newVFOOffset = (vfoBW / 2.0) - (BW / 2.0) + (viewBW / 10.0);
2020-09-20 00:19:39 +02:00
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset);
gui::waterfall.setCenterFrequency(freq - newVFOOffset);
2020-10-01 01:21:15 +02:00
sigpath::sourceManager.tune(freq - newVFOOffset);
2020-07-19 15:59:44 +02:00
return;
}
// VFO is still without the SDR's bandwidth
if (delta < 0) {
double newViewOff = vfoTop - (viewBW / 2.0) + (viewBW / 10.0);
double newViewBottom = newViewOff - (viewBW / 2.0);
double newViewTop = newViewOff + (viewBW / 2.0);
2020-07-19 15:59:44 +02:00
if (newViewBottom > bottom) {
2020-09-20 00:19:39 +02:00
gui::waterfall.setViewOffset(newViewOff);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO);
2020-07-19 15:59:44 +02:00
return;
}
gui::waterfall.setViewOffset((BW / 2.0) - (viewBW / 2.0));
double newVFOOffset = (BW / 2.0) - (vfoBW / 2.0) - (viewBW / 10.0);
2020-09-20 00:19:39 +02:00
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset);
gui::waterfall.setCenterFrequency(freq - newVFOOffset);
2020-10-01 01:21:15 +02:00
sigpath::sourceManager.tune(freq - newVFOOffset);
2020-07-19 15:59:44 +02:00
}
else {
double newViewOff = vfoBottom + (viewBW / 2.0) - (viewBW / 10.0);
double newViewBottom = newViewOff - (viewBW / 2.0);
double newViewTop = newViewOff + (viewBW / 2.0);
2020-07-19 15:59:44 +02:00
if (newViewTop < top) {
2020-09-20 00:19:39 +02:00
gui::waterfall.setViewOffset(newViewOff);
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFO);
2020-07-19 15:59:44 +02:00
return;
}
gui::waterfall.setViewOffset((viewBW / 2.0) - (BW / 2.0));
double newVFOOffset = (vfoBW / 2.0) - (BW / 2.0) + (viewBW / 10.0);
2020-09-20 00:19:39 +02:00
sigpath::vfoManager.setCenterOffset(gui::waterfall.selectedVFO, newVFOOffset);
gui::waterfall.setCenterFrequency(freq - newVFOOffset);
2020-10-01 01:21:15 +02:00
sigpath::sourceManager.tune(freq - newVFOOffset);
2020-07-19 15:59:44 +02:00
}
}
2020-07-11 21:15:10 +02:00
2020-06-10 04:13:56 +02:00
void drawWindow() {
2020-08-16 03:39:05 +02:00
ImGui::Begin("Main", NULL, WINDOW_FLAGS);
2020-08-11 18:33:42 +02:00
2020-09-20 00:19:39 +02:00
ImGui::WaterfallVFO* vfo = gui::waterfall.vfos[gui::waterfall.selectedVFO];
2020-08-10 02:30:25 +02:00
2020-08-11 18:33:42 +02:00
if (vfo->centerOffsetChanged) {
2020-09-20 00:19:39 +02:00
gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset);
gui::freqSelect.frequencyChanged = false;
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
core::configManager.conf["frequency"] = gui::freqSelect.frequency;
core::configManager.release(true);
2020-08-11 18:33:42 +02:00
}
2020-09-20 00:19:39 +02:00
sigpath::vfoManager.updateFromWaterfall(&gui::waterfall);
2020-08-11 18:33:42 +02:00
2020-09-20 00:19:39 +02:00
if (gui::waterfall.selectedVFOChanged) {
gui::waterfall.selectedVFOChanged = false;
gui::freqSelect.setFrequency(vfo->generalOffset + gui::waterfall.getCenterFrequency());
gui::freqSelect.frequencyChanged = false;
audioStreamName = audio::getNameFromVFO(gui::waterfall.selectedVFO);
2020-08-16 03:39:05 +02:00
if (audioStreamName != "") {
volume = &audio::streams[audioStreamName]->volume;
}
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
core::configManager.conf["frequency"] = gui::freqSelect.frequency;
core::configManager.release(true);
2020-08-10 02:30:25 +02:00
}
2020-09-20 00:19:39 +02:00
if (gui::freqSelect.frequencyChanged) {
gui::freqSelect.frequencyChanged = false;
setVFO(gui::freqSelect.frequency);
2020-08-11 18:33:42 +02:00
vfo->centerOffsetChanged = false;
vfo->lowerOffsetChanged = false;
vfo->upperOffsetChanged = false;
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
core::configManager.conf["frequency"] = gui::freqSelect.frequency;
core::configManager.release(true);
2020-06-10 04:13:56 +02:00
}
2020-09-20 00:19:39 +02:00
if (gui::waterfall.centerFreqMoved) {
gui::waterfall.centerFreqMoved = false;
2020-10-01 01:21:15 +02:00
sigpath::sourceManager.tune(gui::waterfall.getCenterFrequency());
2020-09-20 00:19:39 +02:00
gui::freqSelect.setFrequency(gui::waterfall.getCenterFrequency() + vfo->generalOffset);
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
core::configManager.conf["frequency"] = gui::freqSelect.frequency;
core::configManager.release(true);
2020-08-04 21:34:56 +02:00
}
2020-09-20 00:19:39 +02:00
int _fftHeight = gui::waterfall.getFFTHeight();
2020-08-20 18:29:23 +02:00
if (fftHeight != _fftHeight) {
fftHeight = _fftHeight;
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
core::configManager.conf["fftHeight"] = fftHeight;
core::configManager.release(true);
2020-08-20 18:29:23 +02:00
}
2020-06-10 04:13:56 +02:00
ImVec2 vMin = ImGui::GetWindowContentRegionMin();
ImVec2 vMax = ImGui::GetWindowContentRegionMax();
int width = vMax.x - vMin.x;
int height = vMax.y - vMin.y;
2020-07-19 15:59:44 +02:00
// To Bar
2020-08-21 15:34:50 +02:00
if (ImGui::ImageButton(icons::MENU, ImVec2(40, 40), ImVec2(0, 0), ImVec2(1, 1), 0)) {
showMenu = !showMenu;
}
ImGui::SameLine();
2020-07-19 15:59:44 +02:00
if (playing) {
2020-08-16 03:39:05 +02:00
if (ImGui::ImageButton(icons::STOP, ImVec2(40, 40), ImVec2(0, 0), ImVec2(1, 1), 0)) {
2020-10-01 01:21:15 +02:00
sigpath::sourceManager.stop();
2020-07-19 15:59:44 +02:00
playing = false;
}
}
2020-10-01 01:21:15 +02:00
else { // TODO: Might need to check if there even is a device
if (ImGui::ImageButton(icons::PLAY, ImVec2(40, 40), ImVec2(0, 0), ImVec2(1, 1), 0)) {
sigpath::sourceManager.start();
// TODO: tune in module instead
sigpath::sourceManager.tune(gui::waterfall.getCenterFrequency());
2020-07-19 15:59:44 +02:00
playing = true;
}
}
ImGui::SameLine();
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 8);
ImGui::SetNextItemWidth(200);
if (ImGui::SliderFloat("##_2_", volume, 0.0, 1.0, "")) {
2020-08-16 03:39:05 +02:00
if (audioStreamName != "") {
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
if (!core::configManager.conf["audio"].contains(audioStreamName)) {
//saveAudioConfig(audioStreamName);
// TODO: FIX THIS SHIT
2020-08-21 17:11:12 +02:00
}
2020-08-16 03:39:05 +02:00
audio::streams[audioStreamName]->audio->setVolume(*volume);
2020-09-24 19:36:57 +02:00
core::configManager.conf["audio"][audioStreamName]["volume"] = *volume;
core::configManager.release(true);
2020-08-16 03:39:05 +02:00
}
}
2020-07-19 15:59:44 +02:00
ImGui::SameLine();
2020-09-20 00:19:39 +02:00
gui::freqSelect.draw();
2020-07-19 15:59:44 +02:00
2020-08-16 03:39:05 +02:00
ImGui::SameLine();
// Logo button
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - 48);
ImGui::SetCursorPosY(10);
if (ImGui::ImageButton(icons::LOGO, ImVec2(32, 32), ImVec2(0, 0), ImVec2(1, 1), 0)) {
showCredits = true;
}
if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
showCredits = false;
}
if (ImGui::IsKeyPressed(GLFW_KEY_ESCAPE)) {
showCredits = false;
}
2020-08-20 18:29:23 +02:00
// Handle menu resize
float curY = ImGui::GetCursorPosY();
2020-07-19 15:59:44 +02:00
ImVec2 winSize = ImGui::GetWindowSize();
2020-08-20 18:29:23 +02:00
ImVec2 mousePos = ImGui::GetMousePos();
bool click = ImGui::IsMouseClicked(ImGuiMouseButton_Left);
bool down = ImGui::IsMouseDown(ImGuiMouseButton_Left);
if (grabbingMenu) {
newWidth = mousePos.x;
newWidth = std::clamp<float>(newWidth, 250, winSize.x - 250);
ImGui::GetForegroundDrawList()->AddLine(ImVec2(newWidth, curY), ImVec2(newWidth, winSize.y - 10), ImGui::GetColorU32(ImGuiCol_SeparatorActive));
}
if (mousePos.x >= newWidth - 2 && mousePos.x <= newWidth + 2 && mousePos.y > curY) {
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
if (click) {
grabbingMenu = true;
}
}
else {
ImGui::SetMouseCursor(ImGuiMouseCursor_Arrow);
}
if(!down && grabbingMenu) {
grabbingMenu = false;
menuWidth = newWidth;
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
core::configManager.conf["menuWidth"] = menuWidth;
core::configManager.release(true);
2020-08-20 18:29:23 +02:00
}
2020-06-10 04:13:56 +02:00
// Left Column
2020-08-16 03:39:05 +02:00
2020-08-21 15:34:50 +02:00
if (showMenu) {
ImGui::Columns(3, "WindowColumns", false);
ImGui::SetColumnWidth(0, menuWidth);
ImGui::SetColumnWidth(1, winSize.x - menuWidth - 60);
ImGui::SetColumnWidth(2, 60);
ImGui::BeginChild("Left Column");
float menuColumnWidth = ImGui::GetContentRegionAvailWidth();
2020-08-16 03:39:05 +02:00
2020-09-24 19:36:57 +02:00
gui::menu.draw();
2020-06-10 04:13:56 +02:00
2020-08-21 15:34:50 +02:00
if(ImGui::CollapsingHeader("Debug")) {
ImGui::Text("Frame time: %.3f ms/frame", 1000.0 / ImGui::GetIO().Framerate);
2020-08-21 15:34:50 +02:00
ImGui::Text("Framerate: %.1f FPS", ImGui::GetIO().Framerate);
2020-10-22 02:47:10 +02:00
ImGui::Text("Center Frequency: %.0f Hz", gui::waterfall.getCenterFrequency());
2020-08-21 17:11:12 +02:00
ImGui::Text("Source name: %s", sourceName.c_str());
2020-10-20 00:32:17 +02:00
if (ImGui::Checkbox("Test technique", &dcbias.val)) {
sigpath::signalPath.setDCBiasCorrection(dcbias.val);
}
2020-08-21 15:34:50 +02:00
ImGui::Spacing();
}
2020-06-10 04:13:56 +02:00
2020-08-21 15:34:50 +02:00
ImGui::EndChild();
}
else {
// When hiding the menu bar
ImGui::Columns(3, "WindowColumns", false);
ImGui::SetColumnWidth(0, 8);
ImGui::SetColumnWidth(1, winSize.x - 8 - 60);
ImGui::SetColumnWidth(2, 60);
}
2020-06-10 04:13:56 +02:00
// Right Column
2020-08-16 03:39:05 +02:00
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
2020-06-10 04:13:56 +02:00
ImGui::NextColumn();
2020-08-17 02:39:56 +02:00
ImGui::PopStyleVar();
2020-06-10 04:13:56 +02:00
ImGui::BeginChild("Waterfall");
2020-08-16 03:39:05 +02:00
2020-09-20 00:19:39 +02:00
gui::waterfall.draw();
2020-08-16 03:39:05 +02:00
2020-06-10 04:13:56 +02:00
ImGui::EndChild();
2020-07-19 15:59:44 +02:00
2020-08-20 18:29:23 +02:00
2020-07-19 15:59:44 +02:00
ImGui::NextColumn();
2020-08-16 03:39:05 +02:00
ImGui::BeginChild("WaterfallControls");
2020-07-19 15:59:44 +02:00
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Zoom").x / 2.0));
2020-07-19 15:59:44 +02:00
ImGui::Text("Zoom");
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10);
ImGui::VSliderFloat("##_7_", ImVec2(20.0, 150.0), &bw.val, gui::waterfall.getBandwidth(), 1000.0, "");
2020-07-19 15:59:44 +02:00
ImGui::NewLine();
2020-07-19 18:09:59 +02:00
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Max").x / 2.0));
2020-07-19 18:09:59 +02:00
ImGui::Text("Max");
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10);
if (ImGui::VSliderFloat("##_8_", ImVec2(20.0, 150.0), &fftMax, 0.0, -100.0, "")) {
2020-08-17 02:39:56 +02:00
fftMax = std::max<float>(fftMax, fftMin + 10);
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
core::configManager.conf["max"] = fftMax;
core::configManager.release(true);
2020-08-16 03:39:05 +02:00
}
2020-07-19 15:59:44 +02:00
ImGui::NewLine();
2020-07-19 18:09:59 +02:00
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Min").x / 2.0));
2020-07-19 18:09:59 +02:00
ImGui::Text("Min");
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10);
if (ImGui::VSliderFloat("##_9_", ImVec2(20.0, 150.0), &fftMin, 0.0, -100.0, "")) {
2020-08-17 02:39:56 +02:00
fftMin = std::min<float>(fftMax - 10, fftMin);
2020-09-24 19:36:57 +02:00
core::configManager.aquire();
core::configManager.conf["min"] = fftMin;
core::configManager.release(true);
2020-08-16 03:39:05 +02:00
}
ImGui::EndChild();
2020-07-19 15:59:44 +02:00
2020-08-04 21:34:56 +02:00
if (bw.changed()) {
2020-09-20 00:19:39 +02:00
gui::waterfall.setViewBandwidth(bw.val);
gui::waterfall.setViewOffset(vfo->centerOffset);
2020-07-19 15:59:44 +02:00
}
2020-09-20 00:19:39 +02:00
gui::waterfall.setFFTMin(fftMin);
gui::waterfall.setFFTMax(fftMax);
gui::waterfall.setWaterfallMin(fftMin);
gui::waterfall.setWaterfallMax(fftMax);
2020-08-16 03:39:05 +02:00
2020-08-20 18:29:23 +02:00
2020-08-16 03:39:05 +02:00
ImGui::End();
if (showCredits) {
credits::show();
2020-08-16 03:39:05 +02:00
}
2020-06-10 04:13:56 +02:00
}