mirror of
https://github.com/AlexandreRouma/SDRPlusPlus.git
synced 2024-11-06 02:37:32 +01:00
Backend abstraction + added android support + partial high DPI scaling
This commit is contained in:
parent
9969ce018b
commit
e5f3d1672c
4
.gitignore
vendored
4
.gitignore
vendored
@ -14,4 +14,6 @@ Folder.DotSettings.user
|
||||
CMakeSettings.json
|
||||
poggers_decoder
|
||||
m17_decoder/libcorrect
|
||||
SDR++.app
|
||||
SDR++.app
|
||||
android/deps
|
||||
android/app/assets
|
@ -7,8 +7,19 @@ else()
|
||||
set(CMAKE_INSTALL_PREFIX "/usr")
|
||||
endif()
|
||||
|
||||
# Configure toolchain for android
|
||||
if (ANDROID)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS
|
||||
"${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate"
|
||||
)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX14_EXTENSION_COMPILE_OPTION "-std=c++17")
|
||||
endif (ANDROID)
|
||||
|
||||
# Backends
|
||||
option(OPT_BACKEND_GLFW "Use the GLFW backend" ON)
|
||||
option(OPT_BACKEND_ANDROID "Use the Android backend" OFF)
|
||||
|
||||
# Compatibility Options
|
||||
option(OPT_OVERRIDE_STD_FILESYSTEM "Use a local version of std::filesystem on systems that don't have it yet" OFF)
|
||||
@ -31,6 +42,7 @@ option(OPT_BUILD_SPYSERVER_SOURCE "Build SpyServer Source Module (no dependencie
|
||||
option(OPT_BUILD_PLUTOSDR_SOURCE "Build PlutoSDR Source Module (Dependencies: libiio, libad9361)" ON)
|
||||
|
||||
# Sinks
|
||||
option(OPT_BUILD_ANDROID_AUDIO_SINK "Build Android Audio Sink Module (Dependencies: AAudio, only for android)" OFF)
|
||||
option(OPT_BUILD_AUDIO_SINK "Build Audio Sink Module (Dependencies: rtaudio)" ON)
|
||||
option(OPT_BUILD_PORTAUDIO_SINK "Build PortAudio Sink Module (Dependencies: portaudio)" OFF)
|
||||
option(OPT_BUILD_NETWORK_SINK "Build Audio Sink Module (no dependencies required)" ON)
|
||||
@ -121,6 +133,10 @@ endif (OPT_BUILD_PLUTOSDR_SOURCE)
|
||||
|
||||
|
||||
# Sink modules
|
||||
if (OPT_BUILD_ANDROID_AUDIO_SINK)
|
||||
add_subdirectory("sink_modules/android_audio_sink")
|
||||
endif (OPT_BUILD_ANDROID_AUDIO_SINK)
|
||||
|
||||
if (OPT_BUILD_AUDIO_SINK)
|
||||
add_subdirectory("sink_modules/audio_sink")
|
||||
endif (OPT_BUILD_AUDIO_SINK)
|
||||
|
@ -21,6 +21,10 @@ endif ()
|
||||
if (OPT_BACKEND_GLFW)
|
||||
file(GLOB_RECURSE BACKEND_SRC "backends/glfw/*.cpp" "backends/glfw/*.c")
|
||||
endif (OPT_BACKEND_GLFW)
|
||||
if (OPT_BACKEND_ANDROID)
|
||||
file(GLOB_RECURSE BACKEND_SRC "backends/android/*.cpp" "backends/android/*.c")
|
||||
set(BACKEND_SRC ${BACKEND_SRC} ${ANDROID_NDK}/sources/android/native_app_glue/android_native_app_glue.c)
|
||||
endif (OPT_BACKEND_ANDROID)
|
||||
|
||||
# Add code to dyn lib
|
||||
add_library(sdrpp_core SHARED ${SRC} ${BACKEND_SRC})
|
||||
@ -59,6 +63,10 @@ if (OPT_BACKEND_GLFW)
|
||||
target_link_libraries(sdrpp_core PUBLIC ${GLFW3_LIBRARIES})
|
||||
endif()
|
||||
endif (OPT_BACKEND_GLFW)
|
||||
if (OPT_BACKEND_ANDROID)
|
||||
target_include_directories(sdrpp_core PUBLIC "backends/android")
|
||||
target_include_directories(sdrpp_core PUBLIC "backends/android/imgui")
|
||||
endif (OPT_BACKEND_ANDROID)
|
||||
|
||||
# Link to libcorrect
|
||||
if (USE_INTERNAL_LIBCORRECT)
|
||||
@ -98,7 +106,24 @@ if (MSVC)
|
||||
# ZSTD
|
||||
find_package(zstd CONFIG REQUIRED)
|
||||
target_link_libraries(sdrpp_core PUBLIC zstd::libzstd_shared)
|
||||
elseif (ANDROID)
|
||||
target_include_directories(sdrpp_core PUBLIC
|
||||
../android/deps/volk/jni
|
||||
../android/deps/fftw3/jni
|
||||
/mnt/android_sdr/zstd/lib
|
||||
${ANDROID_NDK}/sources/android/native_app_glue
|
||||
)
|
||||
|
||||
target_link_libraries(sdrpp_core PUBLIC
|
||||
${PROJECT_SOURCE_DIR}/../android/deps/volk/${ANDROID_ABI}/libcpu_features.a
|
||||
${PROJECT_SOURCE_DIR}/../android/deps/volk/${ANDROID_ABI}/libvolk.so
|
||||
${PROJECT_SOURCE_DIR}/../android/deps/fftw3/${ANDROID_ABI}/libfftw3f.a
|
||||
/mnt/android_sdr/output/zstd/${ANDROID_ABI}/libzstd.so
|
||||
android
|
||||
EGL
|
||||
GLESv3
|
||||
log
|
||||
)
|
||||
else()
|
||||
find_package(PkgConfig)
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
@ -21,4 +21,7 @@
|
||||
#define KB_KEY_LCTRL GLFW_KEY_LEFT_CONTROL
|
||||
#define KB_KEY_RCTRL GLFW_KEY_RIGHT_CONTROL
|
||||
#define KB_KEY_LSHIFT GLFW_KEY_LEFT_SHIFT
|
||||
#define KB_KEY_RSHIFT GLFW_KEY_RIGHT_SHIFT
|
||||
#define KB_KEY_RSHIFT GLFW_KEY_RIGHT_SHIFT
|
||||
|
||||
#define KB_KEY_A GLFW_KEY_A
|
||||
#define KB_KEY_R GLFW_KEY_R
|
@ -2,7 +2,7 @@
|
||||
#include <string>
|
||||
|
||||
namespace backend {
|
||||
int init(std::string resDir);
|
||||
int init(std::string resDir = "");
|
||||
void beginFrame();
|
||||
void render(bool vsync = true);
|
||||
void getMouseScreenPos(double& x, double& y);
|
||||
|
@ -1,7 +1,5 @@
|
||||
#include <server.h>
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <stdio.h>
|
||||
#include <gui/main_window.h>
|
||||
#include <gui/style.h>
|
||||
@ -188,6 +186,7 @@ int sdrpp_main(int argc, char* argv[]) {
|
||||
defConfig["theme"] = "Dark";
|
||||
|
||||
defConfig["modules"] = json::array();
|
||||
|
||||
defConfig["offsetMode"] = (int)0; // Off
|
||||
defConfig["offset"] = 0.0;
|
||||
defConfig["showMenu"] = true;
|
||||
@ -213,6 +212,9 @@ int sdrpp_main(int argc, char* argv[]) {
|
||||
#elif defined(IS_MACOS_BUNDLE)
|
||||
defConfig["modulesDirectory"] = "../Plugins";
|
||||
defConfig["resourcesDirectory"] = "../Resources";
|
||||
#elif defined(__ANDROID__)
|
||||
defConfig["modulesDirectory"] = options::opts.root + "/modules";
|
||||
defConfig["resourcesDirectory"] = options::opts.root + "/res";
|
||||
#else
|
||||
defConfig["modulesDirectory"] = INSTALL_PREFIX "/lib/sdrpp/plugins";
|
||||
defConfig["resourcesDirectory"] = INSTALL_PREFIX "/share/sdrpp";
|
||||
@ -223,8 +225,33 @@ int sdrpp_main(int argc, char* argv[]) {
|
||||
core::configManager.setPath(options::opts.root + "/config.json");
|
||||
core::configManager.load(defConfig);
|
||||
core::configManager.enableAutoSave();
|
||||
|
||||
core::configManager.acquire();
|
||||
|
||||
// Android can't load just any .so file. This means we have to hardcode the name of the modules
|
||||
#ifdef __ANDROID__
|
||||
int modCount = 0;
|
||||
core::configManager.conf["modules"] = json::array();
|
||||
|
||||
core::configManager.conf["modules"][modCount++] = "airspy_source.so";
|
||||
core::configManager.conf["modules"][modCount++] = "airspyhf_source.so";
|
||||
core::configManager.conf["modules"][modCount++] = "hackrf_source.so";
|
||||
core::configManager.conf["modules"][modCount++] = "plutosdr_source.so";
|
||||
core::configManager.conf["modules"][modCount++] = "sdrpp_server_source.so";
|
||||
core::configManager.conf["modules"][modCount++] = "rfspace_source.so";
|
||||
core::configManager.conf["modules"][modCount++] = "rtl_sdr_source.so";
|
||||
core::configManager.conf["modules"][modCount++] = "rtl_tcp_source.so";
|
||||
core::configManager.conf["modules"][modCount++] = "spyserver_source.so";
|
||||
|
||||
core::configManager.conf["modules"][modCount++] = "network_sink.so";
|
||||
core::configManager.conf["modules"][modCount++] = "audio_sink.so";
|
||||
|
||||
core::configManager.conf["modules"][modCount++] = "radio.so";
|
||||
|
||||
core::configManager.conf["modules"][modCount++] = "frequency_manager.so";
|
||||
core::configManager.conf["modules"][modCount++] = "recorder.so";
|
||||
core::configManager.conf["modules"][modCount++] = "rigctl_server.so";
|
||||
#endif
|
||||
|
||||
// Fix missing elements in config
|
||||
for (auto const& item : defConfig.items()) {
|
||||
if (!core::configManager.conf.contains(item.key())) {
|
||||
@ -274,6 +301,7 @@ int sdrpp_main(int argc, char* argv[]) {
|
||||
|
||||
if (!style::loadFonts(resDir)) { return -1; }
|
||||
thememenu::init(resDir);
|
||||
LoadingScreen::init();
|
||||
|
||||
LoadingScreen::show("Loading icons");
|
||||
spdlog::info("Loading icons");
|
||||
@ -294,6 +322,8 @@ int sdrpp_main(int argc, char* argv[]) {
|
||||
// Run render loop (TODO: CHECK RETURN VALUE)
|
||||
backend::renderLoop();
|
||||
|
||||
// On android, none of this shutdown should happen due to the way the UI works
|
||||
#ifndef __ANDROID__
|
||||
// Shut down all modules
|
||||
for (auto& [name, mod] : core::moduleManager.modules) {
|
||||
mod.end();
|
||||
@ -306,6 +336,7 @@ int sdrpp_main(int argc, char* argv[]) {
|
||||
|
||||
core::configManager.disableAutoSave();
|
||||
core::configManager.save();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -8,8 +8,10 @@
|
||||
|
||||
namespace credits {
|
||||
ImFont* bigFont;
|
||||
ImVec2 imageSize(128.0f, 128.0f);
|
||||
|
||||
void init() {
|
||||
imageSize = ImVec2(128.0f * style::uiScale, 128.0f * style::uiScale);
|
||||
}
|
||||
|
||||
void show() {
|
||||
@ -25,7 +27,7 @@ namespace credits {
|
||||
ImGui::TextUnformatted("SDR++ ");
|
||||
ImGui::PopFont();
|
||||
ImGui::SameLine();
|
||||
ImGui::Image(icons::LOGO, ImVec2(128, 128));
|
||||
ImGui::Image(icons::LOGO, imageSize);
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
ImGui::Spacing();
|
||||
|
@ -1,8 +1,6 @@
|
||||
#include <gui/dialogs/loading_screen.h>
|
||||
#include <gui/main_window.h>
|
||||
#include <imgui.h>
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include <gui/icons.h>
|
||||
#include <gui/style.h>
|
||||
#include <credits.h>
|
||||
@ -10,6 +8,11 @@
|
||||
#include <backend.h>
|
||||
|
||||
namespace LoadingScreen {
|
||||
ImVec2 imageSize(128.0f, 128.0f);
|
||||
|
||||
void init() {
|
||||
imageSize = ImVec2(128.0f * style::uiScale, 128.0f * style::uiScale);
|
||||
}
|
||||
|
||||
void show(std::string msg) {
|
||||
backend::beginFrame();
|
||||
@ -26,7 +29,7 @@ namespace LoadingScreen {
|
||||
ImGui::TextUnformatted("SDR++ ");
|
||||
ImGui::PopFont();
|
||||
ImGui::SameLine();
|
||||
ImGui::Image(icons::LOGO, ImVec2(128, 128));
|
||||
ImGui::Image(icons::LOGO, imageSize);
|
||||
|
||||
ImVec2 origPos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPosY(origPos.y + 50);
|
||||
|
@ -4,5 +4,6 @@
|
||||
#include <mutex>
|
||||
|
||||
namespace LoadingScreen {
|
||||
void init();
|
||||
void show(std::string msg);
|
||||
};
|
@ -1,8 +1,6 @@
|
||||
#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 <thread>
|
||||
#include <complex>
|
||||
@ -126,10 +124,14 @@ void MainWindow::init() {
|
||||
|
||||
// Load additional modules specified through config
|
||||
for (auto const& path : modules) {
|
||||
#ifndef __ANDROID__
|
||||
std::string apath = std::filesystem::absolute(path).string();
|
||||
spdlog::info("Loading {0}", apath);
|
||||
LoadingScreen::show("Loading " + std::filesystem::path(path).filename().string());
|
||||
core::moduleManager.loadModule(apath);
|
||||
#else
|
||||
core::moduleManager.loadModule(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create module instances
|
||||
@ -354,8 +356,9 @@ void MainWindow::draw() {
|
||||
}
|
||||
|
||||
// To Bar
|
||||
ImVec2 btnSize(30 * style::uiScale, 30 * style::uiScale);
|
||||
ImGui::PushID(ImGui::GetID("sdrpp_menu_btn"));
|
||||
if (ImGui::ImageButton(icons::MENU, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(KB_KEY_MENU, false)) {
|
||||
if (ImGui::ImageButton(icons::MENU, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(KB_KEY_MENU, false)) {
|
||||
showMenu = !showMenu;
|
||||
core::configManager.acquire();
|
||||
core::configManager.conf["showMenu"] = showMenu;
|
||||
@ -369,14 +372,14 @@ void MainWindow::draw() {
|
||||
if (playButtonLocked && !tmpPlaySate) { style::beginDisabled(); }
|
||||
if (playing) {
|
||||
ImGui::PushID(ImGui::GetID("sdrpp_stop_btn"));
|
||||
if (ImGui::ImageButton(icons::STOP, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(KB_KEY_END, false)) {
|
||||
if (ImGui::ImageButton(icons::STOP, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(KB_KEY_END, false)) {
|
||||
setPlayState(false);
|
||||
}
|
||||
ImGui::PopID();
|
||||
}
|
||||
else { // TODO: Might need to check if there even is a device
|
||||
ImGui::PushID(ImGui::GetID("sdrpp_play_btn"));
|
||||
if (ImGui::ImageButton(icons::PLAY, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(KB_KEY_END, false)) {
|
||||
if (ImGui::ImageButton(icons::PLAY, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5) || ImGui::IsKeyPressed(KB_KEY_END, false)) {
|
||||
setPlayState(true);
|
||||
}
|
||||
ImGui::PopID();
|
||||
@ -384,20 +387,21 @@ void MainWindow::draw() {
|
||||
if (playButtonLocked && !tmpPlaySate) { style::endDisabled(); }
|
||||
|
||||
ImGui::SameLine();
|
||||
float origY = ImGui::GetCursorPosY();
|
||||
|
||||
//ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 8);
|
||||
sigpath::sinkManager.showVolumeSlider(gui::waterfall.selectedVFO, "##_sdrpp_main_volume_", 248, 30, 5, true);
|
||||
sigpath::sinkManager.showVolumeSlider(gui::waterfall.selectedVFO, "##_sdrpp_main_volume_", 248 * style::uiScale, btnSize.x, 5, true);
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SetCursorPosY(origY);
|
||||
gui::freqSelect.draw();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() - 9);
|
||||
ImGui::SetCursorPosY(origY);
|
||||
if (tuningMode == tuner::TUNER_MODE_CENTER) {
|
||||
ImGui::PushID(ImGui::GetID("sdrpp_ena_st_btn"));
|
||||
if (ImGui::ImageButton(icons::CENTER_TUNING, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5)) {
|
||||
if (ImGui::ImageButton(icons::CENTER_TUNING, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5)) {
|
||||
tuningMode = tuner::TUNER_MODE_NORMAL;
|
||||
gui::waterfall.VFOMoveSingleClick = false;
|
||||
core::configManager.acquire();
|
||||
@ -408,7 +412,7 @@ void MainWindow::draw() {
|
||||
}
|
||||
else { // TODO: Might need to check if there even is a device
|
||||
ImGui::PushID(ImGui::GetID("sdrpp_dis_st_btn"));
|
||||
if (ImGui::ImageButton(icons::NORMAL_TUNING, ImVec2(30, 30), ImVec2(0, 0), ImVec2(1, 1), 5)) {
|
||||
if (ImGui::ImageButton(icons::NORMAL_TUNING, btnSize, ImVec2(0, 0), ImVec2(1, 1), 5)) {
|
||||
tuningMode = tuner::TUNER_MODE_CENTER;
|
||||
gui::waterfall.VFOMoveSingleClick = true;
|
||||
tuner::tune(tuner::TUNER_MODE_CENTER, gui::waterfall.selectedVFO, gui::freqSelect.frequency);
|
||||
@ -421,19 +425,20 @@ void MainWindow::draw() {
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
int snrWidth = std::min<int>(300, ImGui::GetWindowSize().x - ImGui::GetCursorPosX() - 87);
|
||||
int snrOffset = 87.0f * style::uiScale;
|
||||
int snrWidth = std::min<int>(300.0f * style::uiScale, ImGui::GetWindowSize().x - ImGui::GetCursorPosX() - snrOffset);
|
||||
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - (snrWidth + 87));
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5);
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - (snrWidth + snrOffset));
|
||||
ImGui::SetCursorPosY(origY + (5.0f * style::uiScale));
|
||||
ImGui::SetNextItemWidth(snrWidth);
|
||||
ImGui::SNRMeter((vfo != NULL) ? gui::waterfall.selectedVFOSNR : 0);
|
||||
|
||||
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)) {
|
||||
ImGui::SetCursorPosX(ImGui::GetWindowSize().x - (48 * style::uiScale));
|
||||
ImGui::SetCursorPosY(10 * style::uiScale);
|
||||
if (ImGui::ImageButton(icons::LOGO, ImVec2(32 * style::uiScale, 32 * style::uiScale), ImVec2(0, 0), ImVec2(1, 1), 0)) {
|
||||
showCredits = true;
|
||||
}
|
||||
if (ImGui::IsMouseDown(ImGuiMouseButton_Left)) {
|
||||
@ -455,7 +460,7 @@ void MainWindow::draw() {
|
||||
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) {
|
||||
if (mousePos.x >= newWidth - (2.0f * style::uiScale) && mousePos.x <= newWidth + (2.0f * style::uiScale) && mousePos.y > curY) {
|
||||
ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
|
||||
if (click) {
|
||||
grabbingMenu = true;
|
||||
@ -479,8 +484,8 @@ void MainWindow::draw() {
|
||||
if (showMenu) {
|
||||
ImGui::Columns(3, "WindowColumns", false);
|
||||
ImGui::SetColumnWidth(0, menuWidth);
|
||||
ImGui::SetColumnWidth(1, winSize.x - menuWidth - 60);
|
||||
ImGui::SetColumnWidth(2, 60);
|
||||
ImGui::SetColumnWidth(1, winSize.x - menuWidth - (60.0f * style::uiScale));
|
||||
ImGui::SetColumnWidth(2, 60.0f * style::uiScale);
|
||||
ImGui::BeginChild("Left Column");
|
||||
|
||||
if (gui::menu.draw(firstMenuRender)) {
|
||||
@ -513,7 +518,7 @@ void MainWindow::draw() {
|
||||
ImGui::Text("Center Frequency: %.0f Hz", gui::waterfall.getCenterFrequency());
|
||||
ImGui::Text("Source name: %s", sourceName.c_str());
|
||||
ImGui::Checkbox("Show demo window", &demoWindow);
|
||||
ImGui::Text("ImGui version: %s", ImGui::GetVersion());
|
||||
ImGui::Text("ImGui version: %s_feb_2022", ImGui::GetVersion());
|
||||
|
||||
ImGui::Checkbox("Bypass buffering", &sigpath::signalPath.inputBuffer.bypass);
|
||||
|
||||
@ -538,9 +543,9 @@ void MainWindow::draw() {
|
||||
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);
|
||||
ImGui::SetColumnWidth(0, 8 * style::uiScale);
|
||||
ImGui::SetColumnWidth(1, winSize.x - ((8 + 60) * style::uiScale));
|
||||
ImGui::SetColumnWidth(2, 60.0f * style::uiScale);
|
||||
}
|
||||
|
||||
// Right Column
|
||||
@ -602,8 +607,9 @@ void MainWindow::draw() {
|
||||
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Zoom").x / 2.0));
|
||||
ImGui::TextUnformatted("Zoom");
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10);
|
||||
if (ImGui::VSliderFloat("##_7_", ImVec2(20.0, 150.0), &bw, 1.0, 0.0, "")) {
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10 * style::uiScale);
|
||||
ImVec2 wfSliderSize(20.0 * style::uiScale, 150.0 * style::uiScale);
|
||||
if (ImGui::VSliderFloat("##_7_", wfSliderSize, &bw, 1.0, 0.0, "")) {
|
||||
double factor = (double)bw * (double)bw;
|
||||
|
||||
// Map 0.0 -> 1.0 to 1000.0 -> bandwidth
|
||||
@ -621,8 +627,8 @@ void MainWindow::draw() {
|
||||
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Max").x / 2.0));
|
||||
ImGui::TextUnformatted("Max");
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10);
|
||||
if (ImGui::VSliderFloat("##_8_", ImVec2(20.0, 150.0), &fftMax, 0.0, -160.0f, "")) {
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10 * style::uiScale);
|
||||
if (ImGui::VSliderFloat("##_8_", wfSliderSize, &fftMax, 0.0, -160.0f, "")) {
|
||||
fftMax = std::max<float>(fftMax, fftMin + 10);
|
||||
core::configManager.acquire();
|
||||
core::configManager.conf["max"] = fftMax;
|
||||
@ -633,8 +639,8 @@ void MainWindow::draw() {
|
||||
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - (ImGui::CalcTextSize("Min").x / 2.0));
|
||||
ImGui::TextUnformatted("Min");
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10);
|
||||
if (ImGui::VSliderFloat("##_9_", ImVec2(20.0, 150.0), &fftMin, 0.0, -160.0f, "")) {
|
||||
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2.0) - 10 * style::uiScale);
|
||||
if (ImGui::VSliderFloat("##_9_", wfSliderSize, &fftMin, 0.0, -160.0f, "")) {
|
||||
fftMin = std::min<float>(fftMax - 10, fftMin);
|
||||
core::configManager.acquire();
|
||||
core::configManager.conf["min"] = fftMin;
|
||||
@ -707,4 +713,8 @@ void MainWindow::setFFTWindow(int win) {
|
||||
|
||||
bool MainWindow::isPlaying() {
|
||||
return playing;
|
||||
}
|
||||
|
||||
void MainWindow::setFirstMenuRender() {
|
||||
firstMenuRender = true;
|
||||
}
|
@ -19,6 +19,7 @@ public:
|
||||
bool sdrIsRunning();
|
||||
void setFFTSize(int size);
|
||||
void setFFTWindow(int win);
|
||||
void setFirstMenuRender();
|
||||
|
||||
// TODO: Replace with it's own class
|
||||
void setVFO(double freq);
|
||||
|
@ -23,8 +23,11 @@ namespace thememenu {
|
||||
it = std::find(themeNames.begin(), themeNames.end(), "Dark");
|
||||
selectedThemeName = "Dark";
|
||||
}
|
||||
gui::themeManager.applyTheme(selectedThemeName);
|
||||
themeId = std::distance(themeNames.begin(), it);
|
||||
applyTheme();
|
||||
|
||||
// Apply scaling
|
||||
ImGui::GetStyle().ScaleAllSizes(style::uiScale);
|
||||
|
||||
themeNamesTxt = "";
|
||||
for (auto name : themeNames) {
|
||||
@ -33,12 +36,16 @@ namespace thememenu {
|
||||
}
|
||||
}
|
||||
|
||||
void applyTheme() {
|
||||
gui::themeManager.applyTheme(themeNames[themeId]);
|
||||
}
|
||||
|
||||
void draw(void* ctx) {
|
||||
float menuWidth = ImGui::GetContentRegionAvailWidth();
|
||||
ImGui::LeftLabel("Theme");
|
||||
ImGui::SetNextItemWidth(menuWidth - ImGui::GetCursorPosX());
|
||||
if (ImGui::Combo("##theme_select_combo", &themeId, themeNamesTxt.c_str())) {
|
||||
gui::themeManager.applyTheme(themeNames[themeId]);
|
||||
applyTheme();
|
||||
core::configManager.acquire();
|
||||
core::configManager.conf["theme"] = themeNames[themeId];
|
||||
core::configManager.release(true);
|
||||
|
@ -3,5 +3,6 @@
|
||||
|
||||
namespace thememenu {
|
||||
void init(std::string resDir);
|
||||
void applyTheme();
|
||||
void draw(void* ctx);
|
||||
}
|
@ -11,15 +11,21 @@ namespace style {
|
||||
ImFont* bigFont;
|
||||
ImFont* hugeFont;
|
||||
|
||||
#ifndef __ANDROID__
|
||||
float uiScale = 1.0f;
|
||||
#else
|
||||
float uiScale = 3.0f;
|
||||
#endif
|
||||
|
||||
bool loadFonts(std::string resDir) {
|
||||
if (!std::filesystem::is_directory(resDir)) {
|
||||
spdlog::error("Invalid resource directory: {0}", resDir);
|
||||
return false;
|
||||
}
|
||||
|
||||
baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 16.0f);
|
||||
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 45.0f);
|
||||
hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 128.0f);
|
||||
baseFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 16.0f * uiScale);
|
||||
bigFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 45.0f * uiScale);
|
||||
hugeFont = ImGui::GetIO().Fonts->AddFontFromFileTTF(((std::string)(resDir + "/fonts/Roboto-Medium.ttf")).c_str(), 128.0f * uiScale);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ namespace style {
|
||||
extern ImFont* bigFont;
|
||||
extern ImFont* hugeFont;
|
||||
|
||||
extern float uiScale;
|
||||
|
||||
bool setDefaultStyle(std::string resDir);
|
||||
bool loadFonts(std::string resDir);
|
||||
void beginDisabled();
|
||||
|
@ -42,9 +42,6 @@ void FrequencySelect::onPosChange() {
|
||||
}
|
||||
}
|
||||
|
||||
void FrequencySelect::onResize() {
|
||||
}
|
||||
|
||||
void FrequencySelect::incrementDigit(int i) {
|
||||
if (i < 0) {
|
||||
return;
|
||||
@ -93,34 +90,27 @@ void FrequencySelect::moveCursorToDigit(int i) {
|
||||
}
|
||||
|
||||
void FrequencySelect::draw() {
|
||||
window = ImGui::GetCurrentWindow();
|
||||
auto window = ImGui::GetCurrentWindow();
|
||||
widgetPos = ImGui::GetWindowContentRegionMin();
|
||||
widgetEndPos = ImGui::GetWindowContentRegionMax();
|
||||
ImVec2 cursorPos = ImGui::GetCursorPos();
|
||||
widgetPos.x += window->Pos.x + cursorPos.x;
|
||||
widgetPos.y += window->Pos.y - 3;
|
||||
widgetEndPos.x += window->Pos.x + cursorPos.x;
|
||||
widgetEndPos.y += window->Pos.y - 3;
|
||||
widgetSize = ImVec2(widgetEndPos.x - widgetPos.x, widgetEndPos.y - widgetPos.y);
|
||||
|
||||
ImGui::PushFont(style::bigFont);
|
||||
ImVec2 digitSz = ImGui::CalcTextSize("0");
|
||||
ImVec2 commaSz = ImGui::CalcTextSize(".");
|
||||
widgetPos.y = cursorPos.y - ((digitSz.y / 2.0f) - ceilf(15 * style::uiScale) - 5);
|
||||
|
||||
if (widgetPos.x != lastWidgetPos.x || widgetPos.y != lastWidgetPos.y) {
|
||||
lastWidgetPos = widgetPos;
|
||||
onPosChange();
|
||||
}
|
||||
if (widgetSize.x != lastWidgetSize.x || widgetSize.y != lastWidgetSize.y) {
|
||||
lastWidgetSize = widgetSize;
|
||||
onResize();
|
||||
}
|
||||
|
||||
ImU32 disabledColor = ImGui::GetColorU32(ImGuiCol_Text, 0.3f);
|
||||
ImU32 textColor = ImGui::GetColorU32(ImGuiCol_Text);
|
||||
|
||||
ImVec2 digitSz = ImGui::CalcTextSize("0");
|
||||
ImVec2 commaSz = ImGui::CalcTextSize(".");
|
||||
|
||||
int digitWidth = digitSz.x;
|
||||
int commaOffset = 0;
|
||||
float textOffset = 11.0f * style::uiScale;
|
||||
bool zeros = true;
|
||||
|
||||
ImGui::ItemSize(ImRect(digitTopMins[0], ImVec2(digitBottomMaxs[11].x + 15, digitBottomMaxs[11].y)));
|
||||
@ -134,7 +124,7 @@ void FrequencySelect::draw() {
|
||||
zeros ? disabledColor : textColor, buf);
|
||||
if ((i + 1) % 3 == 0 && i < 11) {
|
||||
commaOffset += commaSz.x;
|
||||
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + 11, widgetPos.y),
|
||||
window->DrawList->AddText(ImVec2(widgetPos.x + (i * digitWidth) + commaOffset + textOffset, widgetPos.y),
|
||||
zeros ? disabledColor : textColor, ".");
|
||||
}
|
||||
}
|
||||
@ -223,9 +213,7 @@ void FrequencySelect::draw() {
|
||||
|
||||
ImGui::PopFont();
|
||||
|
||||
ImGui::SetCursorPosX(digitBottomMaxs[11].x + 17);
|
||||
|
||||
//ImGui::NewLine();
|
||||
ImGui::SetCursorPosX(digitBottomMaxs[11].x + (17.0f * style::uiScale));
|
||||
}
|
||||
|
||||
void FrequencySelect::setFrequency(int64_t freq) {
|
||||
|
@ -26,13 +26,7 @@ private:
|
||||
void moveCursorToDigit(int i);
|
||||
|
||||
ImVec2 widgetPos;
|
||||
ImVec2 widgetEndPos;
|
||||
ImVec2 widgetSize;
|
||||
|
||||
ImVec2 lastWidgetPos;
|
||||
ImVec2 lastWidgetSize;
|
||||
|
||||
ImGuiWindow* window;
|
||||
|
||||
int digits[12];
|
||||
ImVec2 digitBottomMins[12];
|
||||
|
@ -28,6 +28,7 @@ bool Menu::draw(bool updateStates) {
|
||||
bool changed = false;
|
||||
float menuWidth = ImGui::GetContentRegionAvailWidth();
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
ImVec2 checkboxOffset = ImVec2(menuWidth - ImGui::GetTextLineHeight() - (6.0f * style::uiScale), - ImGui::GetTextLineHeight() - (10.0f * style::uiScale));
|
||||
|
||||
int displayedCount = 0;
|
||||
int rawId = 0;
|
||||
@ -46,6 +47,7 @@ bool Menu::draw(bool updateStates) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Draw dragged menu item
|
||||
if (displayedCount == insertBefore && !draggedMenuName.empty()) {
|
||||
if (updateStates) { ImGui::SetNextItemOpen(false); }
|
||||
ImVec2 posMin = ImGui::GetCursorScreenPos();
|
||||
@ -56,14 +58,14 @@ bool Menu::draw(bool updateStates) {
|
||||
if (items[draggedOpt.name].inst != NULL) {
|
||||
window->WorkRect = orignalRect;
|
||||
ImVec2 pos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPosX(pos.x + menuWidth - ImGui::GetTextLineHeight() - 6);
|
||||
ImGui::SetCursorPosY(pos.y - 10 - ImGui::GetTextLineHeight());
|
||||
ImGui::SetCursorPosX(pos.x + checkboxOffset.x);
|
||||
ImGui::SetCursorPosY(pos.y + checkboxOffset.y);
|
||||
bool enabled = items[draggedOpt.name].inst->isEnabled();
|
||||
ImGui::Checkbox(("##_menu_checkbox_" + draggedOpt.name).c_str(), &enabled);
|
||||
ImGui::SetCursorPos(pos);
|
||||
}
|
||||
style::endDisabled();
|
||||
window->DrawList->AddRect(posMin, posMax, textColor);
|
||||
window->DrawList->AddRect(posMin, posMax, textColor, 0.0f, 0, style::uiScale);
|
||||
}
|
||||
displayedCount++;
|
||||
|
||||
@ -72,7 +74,7 @@ bool Menu::draw(bool updateStates) {
|
||||
|
||||
ImRect orginalRect = window->WorkRect;
|
||||
if (item.inst != NULL) {
|
||||
window->WorkRect = ImRect(orginalRect.Min, ImVec2(orginalRect.Max.x - ImGui::GetTextLineHeight() - 6, orginalRect.Max.y));
|
||||
window->WorkRect = ImRect(orginalRect.Min, ImVec2(orginalRect.Max.x - ImGui::GetTextLineHeight() - (6.0f * style::uiScale), orginalRect.Max.y));
|
||||
}
|
||||
|
||||
ImVec2 posMin = ImGui::GetCursorScreenPos();
|
||||
@ -93,13 +95,14 @@ bool Menu::draw(bool updateStates) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Draw menu header and menu content. There is a lot of boilerplate because the checkbox has to be drawn before the menu, TODO: fix
|
||||
if (updateStates) { ImGui::SetNextItemOpen(opt.open); }
|
||||
if (ImGui::CollapsingHeader((opt.name + "##sdrpp_main_menu").c_str())) {
|
||||
if (item.inst != NULL) {
|
||||
window->WorkRect = orginalRect;
|
||||
ImVec2 pos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPosX(pos.x + menuWidth - ImGui::GetTextLineHeight() - 6);
|
||||
ImGui::SetCursorPosY(pos.y - 10 - ImGui::GetTextLineHeight());
|
||||
ImGui::SetCursorPosX(pos.x + checkboxOffset.x);
|
||||
ImGui::SetCursorPosY(pos.y + checkboxOffset.y);
|
||||
bool enabled = item.inst->isEnabled();
|
||||
if (ImGui::Checkbox(("##_menu_checkbox_" + opt.name).c_str(), &enabled)) {
|
||||
enabled ? item.inst->enable() : item.inst->disable();
|
||||
@ -120,8 +123,8 @@ bool Menu::draw(bool updateStates) {
|
||||
else if (item.inst != NULL) {
|
||||
window->WorkRect = orginalRect;
|
||||
ImVec2 pos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPosX(pos.x + menuWidth - ImGui::GetTextLineHeight() - 6);
|
||||
ImGui::SetCursorPosY(pos.y - 10 - ImGui::GetTextLineHeight());
|
||||
ImGui::SetCursorPosX(pos.x + checkboxOffset.x);
|
||||
ImGui::SetCursorPosY(pos.y + checkboxOffset.y);
|
||||
bool enabled = item.inst->isEnabled();
|
||||
if (ImGui::Checkbox(("##_menu_checkbox_" + opt.name).c_str(), &enabled)) {
|
||||
enabled ? item.inst->enable() : item.inst->disable();
|
||||
@ -168,7 +171,7 @@ bool Menu::draw(bool updateStates) {
|
||||
insertBefore = -1;
|
||||
}
|
||||
|
||||
|
||||
// TODO: Figure out why the hell this is needed
|
||||
if (insertBefore == displayedCount && !draggedMenuName.empty()) {
|
||||
if (updateStates) { ImGui::SetNextItemOpen(false); }
|
||||
ImVec2 posMin = ImGui::GetCursorScreenPos();
|
||||
@ -179,14 +182,14 @@ bool Menu::draw(bool updateStates) {
|
||||
if (items[draggedOpt.name].inst != NULL) {
|
||||
window->WorkRect = orignalRect;
|
||||
ImVec2 pos = ImGui::GetCursorPos();
|
||||
ImGui::SetCursorPosX(pos.x + menuWidth - ImGui::GetTextLineHeight() - 6);
|
||||
ImGui::SetCursorPosY(pos.y - 10 - ImGui::GetTextLineHeight());
|
||||
ImGui::SetCursorPosX(pos.x + checkboxOffset.x);
|
||||
ImGui::SetCursorPosY(pos.y + checkboxOffset.y);
|
||||
bool enabled = items[draggedOpt.name].inst->isEnabled();
|
||||
ImGui::Checkbox(("##_menu_checkbox_" + draggedOpt.name).c_str(), &enabled);
|
||||
ImGui::SetCursorPos(pos);
|
||||
}
|
||||
style::endDisabled();
|
||||
window->DrawList->AddRect(posMin, posMax, textColor);
|
||||
window->DrawList->AddRect(posMin, posMax, textColor, 0.0f, 0, style::uiScale);
|
||||
}
|
||||
|
||||
if (!draggedMenuName.empty()) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <gui/widgets/volume_meter.h>
|
||||
#include <algorithm>
|
||||
#include <gui/style.h>
|
||||
|
||||
#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
@ -27,15 +28,15 @@ namespace ImGui {
|
||||
float it = size.x / 9;
|
||||
char buf[32];
|
||||
|
||||
window->DrawList->AddRectFilled(min + ImVec2(0, 1), min + ImVec2(roundf((float)val * ratio), 10), IM_COL32(0, 136, 255, 255));
|
||||
window->DrawList->AddLine(min, min + ImVec2(0, 9), text);
|
||||
window->DrawList->AddLine(min + ImVec2(0, 9), min + ImVec2(size.x + 1, 9), text);
|
||||
window->DrawList->AddRectFilled(min + ImVec2(0, 1), min + ImVec2(roundf((float)val * ratio), 10 * style::uiScale), IM_COL32(0, 136, 255, 255));
|
||||
window->DrawList->AddLine(min, min + ImVec2(0, (10.0f * style::uiScale) - 1), text, style::uiScale);
|
||||
window->DrawList->AddLine(min + ImVec2(0, (10.0f * style::uiScale) - 1), min + ImVec2(size.x + 1, (10.0f * style::uiScale) - 1), text, style::uiScale);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), 9), min + ImVec2(roundf((float)i * it), 14), text);
|
||||
window->DrawList->AddLine(min + ImVec2(roundf((float)i * it), (10.0f * style::uiScale) - 1), min + ImVec2(roundf((float)i * it), (15.0f * style::uiScale) - 1), text, style::uiScale);
|
||||
sprintf(buf, "%d", i * 10);
|
||||
ImVec2 sz = ImGui::CalcTextSize(buf);
|
||||
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x / 2.0)) + 1, 16), text, buf);
|
||||
window->DrawList->AddText(min + ImVec2(roundf(((float)i * it) - (sz.x / 2.0)) + 1, 16.0f * style::uiScale), text, buf);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
#include <volk/volk.h>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <gui/gui.h>
|
||||
#include <gui/style.h>
|
||||
#include <keybinds.h>
|
||||
|
||||
float DEFAULT_COLOR_MAP[][3] = {
|
||||
@ -99,51 +100,53 @@ namespace ImGui {
|
||||
ImU32 trace = ImGui::GetColorU32(ImGuiCol_PlotLines);
|
||||
ImU32 shadow = ImGui::GetColorU32(ImGuiCol_PlotLines, 0.2);
|
||||
ImU32 text = ImGui::GetColorU32(ImGuiCol_Text);
|
||||
float textVOffset = 10.0f * style::uiScale;
|
||||
|
||||
// Vertical scale
|
||||
for (float line = startLine; line > fftMin; line -= vRange) {
|
||||
float yPos = widgetPos.y + fftHeight + 10 - ((line - fftMin) * scaleFactor);
|
||||
window->DrawList->AddLine(ImVec2(roundf(widgetPos.x + 50), roundf(yPos)),
|
||||
ImVec2(roundf(widgetPos.x + dataWidth + 50), roundf(yPos)),
|
||||
IM_COL32(50, 50, 50, 255), 1.0);
|
||||
float yPos = fftAreaMax.y - ((line - fftMin) * scaleFactor);
|
||||
window->DrawList->AddLine(ImVec2(fftAreaMin.x, roundf(yPos)),
|
||||
ImVec2(fftAreaMax.x, roundf(yPos)),
|
||||
IM_COL32(50, 50, 50, 255), style::uiScale);
|
||||
sprintf(buf, "%d", (int)line);
|
||||
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
||||
window->DrawList->AddText(ImVec2(widgetPos.x + 40 - txtSz.x, roundf(yPos - (txtSz.y / 2.0))), text, buf);
|
||||
window->DrawList->AddText(ImVec2(fftAreaMin.x - txtSz.x - textVOffset, roundf(yPos - (txtSz.y / 2.0))), text, buf);
|
||||
}
|
||||
|
||||
// Horizontal scale
|
||||
double startFreq = ceilf(lowerFreq / range) * range;
|
||||
double horizScale = (double)dataWidth / viewBandwidth;
|
||||
float scaleVOfsset = 7 * style::uiScale;
|
||||
for (double freq = startFreq; freq < upperFreq; freq += range) {
|
||||
double xPos = widgetPos.x + 50 + ((freq - lowerFreq) * horizScale);
|
||||
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + 10),
|
||||
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
|
||||
IM_COL32(50, 50, 50, 255), 1.0);
|
||||
window->DrawList->AddLine(ImVec2(roundf(xPos), widgetPos.y + fftHeight + 10),
|
||||
ImVec2(roundf(xPos), widgetPos.y + fftHeight + 17),
|
||||
text, 1.0);
|
||||
double xPos = fftAreaMin.x + ((freq - lowerFreq) * horizScale);
|
||||
window->DrawList->AddLine(ImVec2(roundf(xPos), fftAreaMin.y + 1),
|
||||
ImVec2(roundf(xPos), fftAreaMax.y),
|
||||
IM_COL32(50, 50, 50, 255), style::uiScale);
|
||||
window->DrawList->AddLine(ImVec2(roundf(xPos), fftAreaMax.y),
|
||||
ImVec2(roundf(xPos), fftAreaMax.y + scaleVOfsset),
|
||||
text, style::uiScale);
|
||||
printAndScale(freq, buf);
|
||||
ImVec2 txtSz = ImGui::CalcTextSize(buf);
|
||||
window->DrawList->AddText(ImVec2(roundf(xPos - (txtSz.x / 2.0)), widgetPos.y + fftHeight + 10 + txtSz.y), text, buf);
|
||||
window->DrawList->AddText(ImVec2(roundf(xPos - (txtSz.x / 2.0)), fftAreaMax.y + txtSz.y), text, buf);
|
||||
}
|
||||
|
||||
// Data
|
||||
if (latestFFT != NULL && fftLines != 0) {
|
||||
for (int i = 1; i < dataWidth; i++) {
|
||||
double aPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i - 1] - fftMin) * scaleFactor);
|
||||
double bPos = widgetPos.y + fftHeight + 10 - ((latestFFT[i] - fftMin) * scaleFactor);
|
||||
aPos = std::clamp<double>(aPos, widgetPos.y + 10, widgetPos.y + fftHeight + 10);
|
||||
bPos = std::clamp<double>(bPos, widgetPos.y + 10, widgetPos.y + fftHeight + 10);
|
||||
window->DrawList->AddLine(ImVec2(widgetPos.x + 49 + i, roundf(aPos)),
|
||||
ImVec2(widgetPos.x + 50 + i, roundf(bPos)), trace, 1.0);
|
||||
window->DrawList->AddLine(ImVec2(widgetPos.x + 50 + i, roundf(bPos)),
|
||||
ImVec2(widgetPos.x + 50 + i, widgetPos.y + fftHeight + 10), shadow, 1.0);
|
||||
double aPos = fftAreaMax.y - ((latestFFT[i - 1] - fftMin) * scaleFactor);
|
||||
double bPos = fftAreaMax.y - ((latestFFT[i] - fftMin) * scaleFactor);
|
||||
aPos = std::clamp<double>(aPos, fftAreaMin.y + 1, fftAreaMax.y);
|
||||
bPos = std::clamp<double>(bPos, fftAreaMin.y + 1, fftAreaMax.y);
|
||||
window->DrawList->AddLine(ImVec2(fftAreaMin.x + i - 1, roundf(aPos)),
|
||||
ImVec2(fftAreaMin.x + i, roundf(bPos)), trace, 1.0);
|
||||
window->DrawList->AddLine(ImVec2(fftAreaMin.x + i, roundf(bPos)),
|
||||
ImVec2(fftAreaMin.x + i, fftAreaMax.y), shadow, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
FFTRedrawArgs args;
|
||||
args.min = ImVec2(widgetPos.x + 50, widgetPos.y + 9);
|
||||
args.max = ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10);
|
||||
args.min = fftAreaMin;
|
||||
args.max = fftAreaMax;
|
||||
args.lowFreq = lowerFreq;
|
||||
args.highFreq = upperFreq;
|
||||
args.freqToPixelRatio = horizScale;
|
||||
@ -152,13 +155,13 @@ namespace ImGui {
|
||||
onFFTRedraw.emit(args);
|
||||
|
||||
// X Axis
|
||||
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 10),
|
||||
ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10),
|
||||
text, 1.0);
|
||||
window->DrawList->AddLine(ImVec2(fftAreaMin.x, fftAreaMax.y),
|
||||
ImVec2(fftAreaMax.x, fftAreaMax.y),
|
||||
text, style::uiScale);
|
||||
// Y Axis
|
||||
window->DrawList->AddLine(ImVec2(widgetPos.x + 50, widgetPos.y + 9),
|
||||
ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 9),
|
||||
text, 1.0);
|
||||
window->DrawList->AddLine(ImVec2(fftAreaMin.x, fftAreaMin.y),
|
||||
ImVec2(fftAreaMin.x, fftAreaMax.y - 1),
|
||||
text, style::uiScale);
|
||||
}
|
||||
|
||||
void WaterFall::drawWaterfall() {
|
||||
@ -173,7 +176,7 @@ namespace ImGui {
|
||||
for (auto const& [name, vfo] : vfos) {
|
||||
window->DrawList->AddRectFilled(vfo->wfRectMin, vfo->wfRectMax, vfo->color);
|
||||
if (!vfo->lineVisible) { continue; }
|
||||
window->DrawList->AddLine(vfo->wfLineMin, vfo->wfLineMax, (name == selectedVFO) ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
|
||||
window->DrawList->AddLine(vfo->wfLineMin, vfo->wfLineMax, (name == selectedVFO) ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255), style::uiScale);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -212,7 +215,7 @@ namespace ImGui {
|
||||
bool mouseClicked = ImGui::ButtonBehavior(ImRect(fftAreaMin, wfMax), GetID("WaterfallID"), &mouseHovered, &mouseHeld,
|
||||
ImGuiButtonFlags_MouseButtonLeft | ImGuiButtonFlags_PressedOnClick);
|
||||
|
||||
mouseInFFTResize = (dragOrigin.x > widgetPos.x && dragOrigin.x < widgetPos.x + widgetSize.x && dragOrigin.y >= widgetPos.y + newFFTAreaHeight - 2 && dragOrigin.y <= widgetPos.y + newFFTAreaHeight + 2);
|
||||
mouseInFFTResize = (dragOrigin.x > widgetPos.x && dragOrigin.x < widgetPos.x + widgetSize.x && dragOrigin.y >= widgetPos.y + newFFTAreaHeight - (2.0f * style::uiScale) && dragOrigin.y <= widgetPos.y + newFFTAreaHeight + (2.0f * style::uiScale));
|
||||
mouseInFreq = IS_IN_AREA(dragOrigin, freqAreaMin, freqAreaMax);
|
||||
mouseInFFT = IS_IN_AREA(dragOrigin, fftAreaMin, fftAreaMax);
|
||||
mouseInWaterfall = IS_IN_AREA(dragOrigin, wfMin, wfMax);
|
||||
@ -304,7 +307,7 @@ namespace ImGui {
|
||||
newFFTAreaHeight = mousePos.y - widgetPos.y;
|
||||
newFFTAreaHeight = std::clamp<float>(newFFTAreaHeight, 150, widgetSize.y - 50);
|
||||
ImGui::GetForegroundDrawList()->AddLine(ImVec2(widgetPos.x, newFFTAreaHeight + widgetPos.y), ImVec2(widgetEndPos.x, newFFTAreaHeight + widgetPos.y),
|
||||
ImGui::GetColorU32(ImGuiCol_SeparatorActive));
|
||||
ImGui::GetColorU32(ImGuiCol_SeparatorActive), style::uiScale);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -417,7 +420,7 @@ namespace ImGui {
|
||||
// Finally, if nothing else was selected, just move the VFO
|
||||
if ((VFOMoveSingleClick ? ImGui::IsMouseClicked(ImGuiMouseButton_Left) : ImGui::IsMouseDown(ImGuiMouseButton_Left)) && (mouseInFFT | mouseInWaterfall) && (mouseMoved || hoveredVFOName == "")) {
|
||||
if (selVfo != NULL) {
|
||||
int refCenter = mousePos.x - (widgetPos.x + 50);
|
||||
int refCenter = mousePos.x - fftAreaMin.x;
|
||||
if (refCenter >= 0 && refCenter < dataWidth) {
|
||||
double off = ((((double)refCenter / ((double)dataWidth / 2.0)) - 1.0) * (viewBandwidth / 2.0)) + viewOffset;
|
||||
off += centerFreq;
|
||||
@ -599,10 +602,10 @@ namespace ImGui {
|
||||
float bpBottom;
|
||||
|
||||
if (bandPlanPos == BANDPLAN_POS_BOTTOM) {
|
||||
bpBottom = widgetPos.y + fftHeight + 10;
|
||||
bpBottom = fftAreaMax.y;
|
||||
}
|
||||
else {
|
||||
bpBottom = widgetPos.y + height + 10;
|
||||
bpBottom = fftAreaMin.y + height + 1;
|
||||
}
|
||||
|
||||
|
||||
@ -620,9 +623,9 @@ namespace ImGui {
|
||||
start = std::clamp<double>(start, lowerFreq, upperFreq);
|
||||
end = std::clamp<double>(end, lowerFreq, upperFreq);
|
||||
center = (start + end) / 2.0;
|
||||
aPos = widgetPos.x + 50 + ((start - lowerFreq) * horizScale);
|
||||
bPos = widgetPos.x + 50 + ((end - lowerFreq) * horizScale);
|
||||
cPos = widgetPos.x + 50 + ((center - lowerFreq) * horizScale);
|
||||
aPos = fftAreaMin.x + ((start - lowerFreq) * horizScale);
|
||||
bPos = fftAreaMin.x + ((end - lowerFreq) * horizScale);
|
||||
cPos = fftAreaMin.x + ((center - lowerFreq) * horizScale);
|
||||
width = bPos - aPos;
|
||||
txtSz = ImGui::CalcTextSize(bandplan->bands[i].name.c_str());
|
||||
if (bandplan::colorTable.find(bandplan->bands[i].type.c_str()) != bandplan::colorTable.end()) {
|
||||
@ -633,22 +636,22 @@ namespace ImGui {
|
||||
color = IM_COL32(255, 255, 255, 255);
|
||||
colorTrans = IM_COL32(255, 255, 255, 100);
|
||||
}
|
||||
if (aPos <= widgetPos.x + 50) {
|
||||
aPos = widgetPos.x + 51;
|
||||
if (aPos <= fftAreaMin.x) {
|
||||
aPos = fftAreaMin.x + 1;
|
||||
}
|
||||
if (bPos <= widgetPos.x + 50) {
|
||||
bPos = widgetPos.x + 51;
|
||||
if (bPos <= fftAreaMin.x) {
|
||||
bPos = fftAreaMin.x + 1;
|
||||
}
|
||||
if (width >= 1.0) {
|
||||
window->DrawList->AddRectFilled(ImVec2(roundf(aPos), bpBottom - height),
|
||||
ImVec2(roundf(bPos), bpBottom), colorTrans);
|
||||
if (startVis) {
|
||||
window->DrawList->AddLine(ImVec2(roundf(aPos), bpBottom - height - 1),
|
||||
ImVec2(roundf(aPos), bpBottom - 1), color);
|
||||
ImVec2(roundf(aPos), bpBottom - 1), color, style::uiScale);
|
||||
}
|
||||
if (endVis) {
|
||||
window->DrawList->AddLine(ImVec2(roundf(bPos), bpBottom - height - 1),
|
||||
ImVec2(roundf(bPos), bpBottom - 1), color);
|
||||
ImVec2(roundf(bPos), bpBottom - 1), color, style::uiScale);
|
||||
}
|
||||
}
|
||||
if (txtSz.x <= width) {
|
||||
@ -679,15 +682,15 @@ namespace ImGui {
|
||||
int lastWaterfallHeight = waterfallHeight;
|
||||
|
||||
if (waterfallVisible) {
|
||||
FFTAreaHeight = std::min<int>(FFTAreaHeight, widgetSize.y - 50);
|
||||
FFTAreaHeight = std::min<int>(FFTAreaHeight, widgetSize.y - (50.0f * style::uiScale));
|
||||
newFFTAreaHeight = FFTAreaHeight;
|
||||
fftHeight = FFTAreaHeight - 50;
|
||||
waterfallHeight = widgetSize.y - fftHeight - 52;
|
||||
fftHeight = FFTAreaHeight - (50.0f * style::uiScale);
|
||||
waterfallHeight = widgetSize.y - fftHeight - (50.0f * style::uiScale) - 2;
|
||||
}
|
||||
else {
|
||||
fftHeight = widgetSize.y - 50;
|
||||
fftHeight = widgetSize.y - (50.0f * style::uiScale);
|
||||
}
|
||||
dataWidth = widgetSize.x - 60.0;
|
||||
dataWidth = widgetSize.x - (60.0f * style::uiScale);
|
||||
|
||||
if (waterfallVisible) {
|
||||
// Raw FFT resize
|
||||
@ -724,12 +727,14 @@ namespace ImGui {
|
||||
latestFFT[i] = -1000.0; // Hide everything
|
||||
}
|
||||
|
||||
fftAreaMin = ImVec2(widgetPos.x + 50, widgetPos.y + 9);
|
||||
fftAreaMax = ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 10);
|
||||
freqAreaMin = ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 11);
|
||||
freqAreaMax = ImVec2(widgetPos.x + dataWidth + 50, widgetPos.y + fftHeight + 50);
|
||||
wfMin = ImVec2(widgetPos.x + 50, widgetPos.y + fftHeight + 51);
|
||||
wfMax = ImVec2(widgetPos.x + 50 + dataWidth, widgetPos.y + fftHeight + 51 + waterfallHeight);
|
||||
fftAreaMin = ImVec2(widgetPos.x + (50.0f * style::uiScale), widgetPos.y + (9.0f * style::uiScale));
|
||||
fftAreaMax = ImVec2(fftAreaMin.x + dataWidth, fftAreaMin.y + fftHeight + 1);
|
||||
|
||||
freqAreaMin = ImVec2(fftAreaMin.x, fftAreaMax.y + 1);
|
||||
freqAreaMax = ImVec2(fftAreaMax.x, fftAreaMax.y + (40.0f * style::uiScale));
|
||||
|
||||
wfMin = ImVec2(fftAreaMin.x, freqAreaMax.y + 1);
|
||||
wfMax = ImVec2(fftAreaMin.x + dataWidth, wfMin.y + waterfallHeight);
|
||||
|
||||
maxHSteps = dataWidth / (ImGui::CalcTextSize("000.000").x + 10);
|
||||
maxVSteps = fftHeight / (ImGui::CalcTextSize("000.000").y);
|
||||
@ -769,8 +774,8 @@ namespace ImGui {
|
||||
//window->DrawList->AddRectFilled(widgetPos, widgetEndPos, IM_COL32( 0, 0, 0, 255 ));
|
||||
ImU32 bg = ImGui::ColorConvertFloat4ToU32(gui::themeManager.waterfallBg);
|
||||
window->DrawList->AddRectFilled(widgetPos, widgetEndPos, bg);
|
||||
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32(50, 50, 50, 255));
|
||||
window->DrawList->AddLine(ImVec2(widgetPos.x, widgetPos.y + fftHeight + 50), ImVec2(widgetPos.x + widgetSize.x, widgetPos.y + fftHeight + 50), IM_COL32(50, 50, 50, 255), 1.0);
|
||||
window->DrawList->AddRect(widgetPos, widgetEndPos, IM_COL32(50, 50, 50, 255), 0.0, 0, style::uiScale);
|
||||
window->DrawList->AddLine(ImVec2(widgetPos.x, freqAreaMax.y), ImVec2(widgetPos.x + widgetSize.x, freqAreaMax.y), IM_COL32(50, 50, 50, 255), style::uiScale);
|
||||
|
||||
if (!gui::mainWindow.lockWaterfallControls) {
|
||||
inputHandled = false;
|
||||
@ -1041,8 +1046,8 @@ namespace ImGui {
|
||||
vfo->updateDrawingVars(viewBandwidth, dataWidth, viewOffset, widgetPos, fftHeight);
|
||||
vfo->wfRectMin = ImVec2(vfo->rectMin.x, wfMin.y);
|
||||
vfo->wfRectMax = ImVec2(vfo->rectMax.x, wfMax.y);
|
||||
vfo->wfLineMin = ImVec2(vfo->lineMin.x, wfMin.y);
|
||||
vfo->wfLineMax = ImVec2(vfo->lineMax.x, wfMax.y);
|
||||
vfo->wfLineMin = ImVec2(vfo->lineMin.x, wfMin.y - 1);
|
||||
vfo->wfLineMax = ImVec2(vfo->lineMax.x, wfMax.y - 1);
|
||||
vfo->wfLbwSelMin = ImVec2(vfo->wfRectMin.x - 2, vfo->wfRectMin.y);
|
||||
vfo->wfLbwSelMax = ImVec2(vfo->wfRectMin.x + 2, vfo->wfRectMax.y);
|
||||
vfo->wfRbwSelMin = ImVec2(vfo->wfRectMax.x - 2, vfo->wfRectMin.y);
|
||||
@ -1175,16 +1180,16 @@ namespace ImGui {
|
||||
|
||||
// Calculate the position of the line
|
||||
if (reference == REF_LOWER) {
|
||||
lineMin = ImVec2(widgetPos.x + 50 + left, widgetPos.y + 9);
|
||||
lineMax = ImVec2(widgetPos.x + 50 + left, widgetPos.y + fftHeight + 9);
|
||||
lineMin = ImVec2(gui::waterfall.fftAreaMin.x + left, gui::waterfall.fftAreaMin.y);
|
||||
lineMax = ImVec2(gui::waterfall.fftAreaMin.x + left, gui::waterfall.fftAreaMax.y - 1);
|
||||
}
|
||||
else if (reference == REF_CENTER) {
|
||||
lineMin = ImVec2(widgetPos.x + 50 + center, widgetPos.y + 9);
|
||||
lineMax = ImVec2(widgetPos.x + 50 + center, widgetPos.y + fftHeight + 9);
|
||||
lineMin = ImVec2(gui::waterfall.fftAreaMin.x + center, gui::waterfall.fftAreaMin.y);
|
||||
lineMax = ImVec2(gui::waterfall.fftAreaMin.x + center, gui::waterfall.fftAreaMax.y - 1);
|
||||
}
|
||||
else if (reference == REF_UPPER) {
|
||||
lineMin = ImVec2(widgetPos.x + 50 + right, widgetPos.y + 9);
|
||||
lineMax = ImVec2(widgetPos.x + 50 + right, widgetPos.y + fftHeight + 9);
|
||||
lineMin = ImVec2(gui::waterfall.fftAreaMin.x + right, gui::waterfall.fftAreaMin.y);
|
||||
lineMax = ImVec2(gui::waterfall.fftAreaMin.x + right, gui::waterfall.fftAreaMax.y - 1);
|
||||
}
|
||||
|
||||
int _left = left;
|
||||
@ -1194,22 +1199,23 @@ namespace ImGui {
|
||||
leftClamped = (left != _left);
|
||||
rightClamped = (right != _right);
|
||||
|
||||
rectMin = ImVec2(widgetPos.x + 50 + left, widgetPos.y + 10);
|
||||
rectMax = ImVec2(widgetPos.x + 51 + right, widgetPos.y + fftHeight + 10);
|
||||
rectMin = ImVec2(gui::waterfall.fftAreaMin.x + left, gui::waterfall.fftAreaMin.y + 1);
|
||||
rectMax = ImVec2(gui::waterfall.fftAreaMin.x + right + 1, gui::waterfall.fftAreaMax.y);
|
||||
|
||||
lbwSelMin = ImVec2(rectMin.x - 2, rectMin.y);
|
||||
lbwSelMax = ImVec2(rectMin.x + 2, rectMax.y);
|
||||
rbwSelMin = ImVec2(rectMax.x - 2, rectMin.y);
|
||||
rbwSelMax = ImVec2(rectMax.x + 2, rectMax.y);
|
||||
float gripSize = 2.0f * style::uiScale;
|
||||
lbwSelMin = ImVec2(rectMin.x - gripSize, rectMin.y);
|
||||
lbwSelMax = ImVec2(rectMin.x + gripSize, rectMax.y);
|
||||
rbwSelMin = ImVec2(rectMax.x - gripSize, rectMin.y);
|
||||
rbwSelMax = ImVec2(rectMax.x + gripSize, rectMax.y);
|
||||
|
||||
notchMin = ImVec2(widgetPos.x + 50 + notch - 2, widgetPos.y + 9);
|
||||
notchMax = ImVec2(widgetPos.x + 50 + notch + 2, widgetPos.y + fftHeight + 9);
|
||||
notchMin = ImVec2(gui::waterfall.fftAreaMin.x + notch - gripSize, gui::waterfall.fftAreaMin.y);
|
||||
notchMax = ImVec2(gui::waterfall.fftAreaMin.x + notch + gripSize, gui::waterfall.fftAreaMax.y - 1);
|
||||
}
|
||||
|
||||
void WaterfallVFO::draw(ImGuiWindow* window, bool selected) {
|
||||
window->DrawList->AddRectFilled(rectMin, rectMax, color);
|
||||
if (lineVisible) {
|
||||
window->DrawList->AddLine(lineMin, lineMax, selected ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255));
|
||||
window->DrawList->AddLine(lineMin, lineMax, selected ? IM_COL32(255, 0, 0, 255) : IM_COL32(255, 255, 0, 255), style::uiScale);
|
||||
}
|
||||
|
||||
if (notchVisible) {
|
||||
|
@ -236,6 +236,13 @@ namespace ImGui {
|
||||
_BANDPLAN_POS_COUNT
|
||||
};
|
||||
|
||||
ImVec2 fftAreaMin;
|
||||
ImVec2 fftAreaMax;
|
||||
ImVec2 freqAreaMin;
|
||||
ImVec2 freqAreaMax;
|
||||
ImVec2 wfMin;
|
||||
ImVec2 wfMax;
|
||||
|
||||
private:
|
||||
void drawWaterfall();
|
||||
void drawFFT();
|
||||
@ -260,13 +267,6 @@ namespace ImGui {
|
||||
ImVec2 lastWidgetPos;
|
||||
ImVec2 lastWidgetSize;
|
||||
|
||||
ImVec2 fftAreaMin;
|
||||
ImVec2 fftAreaMax;
|
||||
ImVec2 freqAreaMin;
|
||||
ImVec2 freqAreaMax;
|
||||
ImVec2 wfMin;
|
||||
ImVec2 wfMax;
|
||||
|
||||
ImGuiWindow* window;
|
||||
|
||||
GLuint textureId;
|
||||
|
@ -4,6 +4,9 @@
|
||||
|
||||
ModuleManager::Module_t ModuleManager::loadModule(std::string path) {
|
||||
Module_t mod;
|
||||
|
||||
// On android, the path has to be relative, don't make it absolute
|
||||
#ifndef __ANDROID__
|
||||
if (!std::filesystem::exists(path)) {
|
||||
spdlog::error("{0} does not exist", path);
|
||||
mod.handle = NULL;
|
||||
@ -14,6 +17,7 @@ ModuleManager::Module_t ModuleManager::loadModule(std::string path) {
|
||||
mod.handle = NULL;
|
||||
return mod;
|
||||
}
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
mod.handle = LoadLibraryA(path.c_str());
|
||||
if (mod.handle == NULL) {
|
||||
|
@ -13,6 +13,8 @@ namespace options {
|
||||
#elif defined(IS_MACOS_BUNDLE)
|
||||
std::string homedir = getenv("HOME");
|
||||
opts.root = homedir + "/Library/Application Support/sdrpp";
|
||||
#elif defined(__ANDROID__)
|
||||
opts.root = "/storage/self/primary/sdrpp";
|
||||
#else
|
||||
std::string homedir = getenv("HOME");
|
||||
opts.root = homedir + "/.config/sdrpp";
|
||||
|
@ -248,6 +248,7 @@ void SinkManager::showVolumeSlider(std::string name, std::string prefix, float w
|
||||
}
|
||||
|
||||
float ypos = ImGui::GetCursorPosY();
|
||||
float sliderOffset = 8.0f * style::uiScale;
|
||||
|
||||
if (streams.find(name) == streams.end() || name == "") {
|
||||
float dummy = 0.0f;
|
||||
@ -256,7 +257,7 @@ void SinkManager::showVolumeSlider(std::string name, std::string prefix, float w
|
||||
ImGui::ImageButton(icons::MUTED, ImVec2(height, height), ImVec2(0, 0), ImVec2(1, 1), btwBorder);
|
||||
ImGui::PopID();
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(width - height - 8);
|
||||
ImGui::SetNextItemWidth(width - height - sliderOffset);
|
||||
ImGui::SetCursorPosY(ypos + ((height - sliderHeight) / 2.0f) + btwBorder);
|
||||
ImGui::SliderFloat((prefix + name).c_str(), &dummy, 0.0f, 1.0f, "");
|
||||
style::endDisabled();
|
||||
@ -289,7 +290,7 @@ void SinkManager::showVolumeSlider(std::string name, std::string prefix, float w
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::SetNextItemWidth(width - height - 8);
|
||||
ImGui::SetNextItemWidth(width - height - sliderOffset);
|
||||
ImGui::SetCursorPosY(ypos + ((height - sliderHeight) / 2.0f) + btwBorder);
|
||||
if (ImGui::SliderFloat((prefix + name).c_str(), &stream->guiVolume, 0.0f, 1.0f, "")) {
|
||||
stream->setVolume(stream->guiVolume);
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include <GL/gl.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <OpenGL/gl.h>
|
||||
#elif defined(__ANDROID__)
|
||||
#include <EGL/egl.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_STR "1.0.5"
|
||||
#define VERSION_STR "1.0.6"
|
@ -3,7 +3,7 @@
|
||||
"country_name": "United Kingdom",
|
||||
"country_code": "UK",
|
||||
"author_name": "John Donkersley",
|
||||
"author_url": "--",
|
||||
"author_url": "",
|
||||
"bands": [
|
||||
{
|
||||
"name": "Long Wave",
|
||||
@ -29,18 +29,42 @@
|
||||
"start": 1810000,
|
||||
"end": 2000000
|
||||
},
|
||||
{
|
||||
"name": "Maritime",
|
||||
"type": "marine",
|
||||
"start": 2045000,
|
||||
"end": 2300000
|
||||
},
|
||||
{
|
||||
"name": "120m Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 2300000,
|
||||
"end": 2495000
|
||||
},
|
||||
{
|
||||
"name": "Maritime",
|
||||
"type": "marine",
|
||||
"start": 2500000,
|
||||
"end": 2850000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 2850000,
|
||||
"end": 3155000
|
||||
},
|
||||
{
|
||||
"name": "90m Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 3200000,
|
||||
"end": 3400000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 3400000,
|
||||
"end": 3500000
|
||||
},
|
||||
{
|
||||
"name": "80m Ham Band",
|
||||
"type": "amateur",
|
||||
@ -53,6 +77,18 @@
|
||||
"start": 3900000,
|
||||
"end": 4000000
|
||||
},
|
||||
{
|
||||
"name": "Maritime",
|
||||
"type": "marine",
|
||||
"start": 4063000,
|
||||
"end": 4438000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 4650000,
|
||||
"end": 4750000
|
||||
},
|
||||
{
|
||||
"name": "60m Broadcast",
|
||||
"type": "broadcast",
|
||||
@ -65,12 +101,30 @@
|
||||
"start": 5258500,
|
||||
"end": 5406500
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 5450000,
|
||||
"end": 5730000
|
||||
},
|
||||
{
|
||||
"name": "49m Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 5900000,
|
||||
"end": 6200000
|
||||
},
|
||||
{
|
||||
"name": "Maritime",
|
||||
"type": "marine",
|
||||
"start": 6200000,
|
||||
"end": 6525000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 6525000,
|
||||
"end": 6765000
|
||||
},
|
||||
{
|
||||
"name": "40m Ham Band",
|
||||
"type": "amateur",
|
||||
@ -83,23 +137,59 @@
|
||||
"start": 7200000,
|
||||
"end": 7450000
|
||||
},
|
||||
{
|
||||
"name": "Maritime",
|
||||
"type": "marine",
|
||||
"start": 8195000,
|
||||
"end": 8815000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 8815000,
|
||||
"end": 9040000
|
||||
},
|
||||
{
|
||||
"name": "31m Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 9400000,
|
||||
"end": 9900000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 10005000,
|
||||
"end": 10100000
|
||||
},
|
||||
{
|
||||
"name": "30m Ham Band",
|
||||
"type": "amateur",
|
||||
"start": 10100000,
|
||||
"end": 10150000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 11175000,
|
||||
"end": 11400000
|
||||
},
|
||||
{
|
||||
"name": "25m Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 11600000,
|
||||
"end": 12100000
|
||||
"end": 12230000
|
||||
},
|
||||
{
|
||||
"name": "Maritime",
|
||||
"type": "marine",
|
||||
"start": 12230000,
|
||||
"end": 13200000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 13200000,
|
||||
"end": 13360000
|
||||
},
|
||||
{
|
||||
"name": "22m Broadcast",
|
||||
@ -113,6 +203,18 @@
|
||||
"start": 14000000,
|
||||
"end": 14350000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 15010000,
|
||||
"end": 15100000
|
||||
},
|
||||
{
|
||||
"name": "Maritime",
|
||||
"type": "marine",
|
||||
"start": 16360000,
|
||||
"end": 17410000
|
||||
},
|
||||
{
|
||||
"name": "19m Broadcast",
|
||||
"type": "broadcast",
|
||||
@ -125,18 +227,36 @@
|
||||
"start": 17480000,
|
||||
"end": 17900000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 17900000,
|
||||
"end": 18030000
|
||||
},
|
||||
{
|
||||
"name": "17m Ham Band",
|
||||
"type": "amateur",
|
||||
"start": 18068000,
|
||||
"end": 18168000
|
||||
},
|
||||
{
|
||||
"name": "Maritime - ship tx",
|
||||
"type": "marine",
|
||||
"start": 18780000,
|
||||
"end": 18900000
|
||||
},
|
||||
{
|
||||
"name": "15m Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 18900000,
|
||||
"end": 19020000
|
||||
},
|
||||
{
|
||||
"name": "Maritime - coast tx",
|
||||
"type": "marine",
|
||||
"start": 19680000,
|
||||
"end": 19990000
|
||||
},
|
||||
{
|
||||
"name": "15m Ham Band",
|
||||
"type": "amateur",
|
||||
@ -149,6 +269,18 @@
|
||||
"start": 21450000,
|
||||
"end": 21850000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 21870000,
|
||||
"end": 22000000
|
||||
},
|
||||
{
|
||||
"name": "Aeronautical Mobile",
|
||||
"type": "aviation",
|
||||
"start": 23200000,
|
||||
"end": 23350000
|
||||
},
|
||||
{
|
||||
"name": "12m Ham Band",
|
||||
"type": "amateur",
|
||||
@ -179,6 +311,18 @@
|
||||
"start": 28000000,
|
||||
"end": 29700000
|
||||
},
|
||||
{
|
||||
"name": "Analogue Cordless Phones",
|
||||
"type": "amateur",
|
||||
"start": 31037500,
|
||||
"end": 40112500
|
||||
},
|
||||
{
|
||||
"name": "Low Power Devices",
|
||||
"type": "amateur",
|
||||
"start": 49820000,
|
||||
"end": 49987500
|
||||
},
|
||||
{
|
||||
"name": "6m Ham Band",
|
||||
"type": "amateur",
|
||||
@ -198,7 +342,7 @@
|
||||
"end": 108000000
|
||||
},
|
||||
{
|
||||
"name": "Air Band VOR/ILS",
|
||||
"name": "Air Band TACAN/ILS",
|
||||
"type": "aviation",
|
||||
"start": 108000000,
|
||||
"end": 118000000
|
||||
@ -206,7 +350,7 @@
|
||||
{
|
||||
"name": "Air Band Voice",
|
||||
"type": "aviation",
|
||||
"start": 118000000,
|
||||
"start": 117975000,
|
||||
"end": 137000000
|
||||
},
|
||||
{
|
||||
@ -222,11 +366,53 @@
|
||||
"end": 146000000
|
||||
},
|
||||
{
|
||||
"name": "Marine",
|
||||
"name": "Land/Mountain Rescue",
|
||||
"type": "PMR",
|
||||
"start": 147343750,
|
||||
"end": 147500000
|
||||
},
|
||||
{
|
||||
"name": "Pagers - Flex/POCSAG",
|
||||
"type": "PMR",
|
||||
"start": 153025000,
|
||||
"end": 153500000
|
||||
},
|
||||
{
|
||||
"name": "Land/Mountain Rescue DMR",
|
||||
"type": "PMR",
|
||||
"start": 155000000,
|
||||
"end": 156000000
|
||||
},
|
||||
{
|
||||
"name": "Marine - ship tx",
|
||||
"type": "marine",
|
||||
"start": 156000000,
|
||||
"end": 157850000
|
||||
},
|
||||
{
|
||||
"name": "Short Term Hire",
|
||||
"type": "PMR",
|
||||
"start": 158787500,
|
||||
"end": 159687500
|
||||
},
|
||||
{
|
||||
"name": "Marine - coast tx",
|
||||
"type": "marine",
|
||||
"start": 160650000,
|
||||
"end": 162025000
|
||||
},
|
||||
{
|
||||
"name": "Short Term Hire",
|
||||
"type": "PMR",
|
||||
"start": 163287500,
|
||||
"end": 164200000
|
||||
},
|
||||
{
|
||||
"name": "Business Radio",
|
||||
"type": "PMR",
|
||||
"start": 165000000,
|
||||
"end": 174000000
|
||||
},
|
||||
{
|
||||
"name": "DAB Radio",
|
||||
"type": "broadcast",
|
||||
@ -239,6 +425,12 @@
|
||||
"start": 230000000,
|
||||
"end": 400000000
|
||||
},
|
||||
{
|
||||
"name": "Private Mobile Radio inc trams",
|
||||
"type": "PMR",
|
||||
"start": 422000000,
|
||||
"end": 424000000
|
||||
},
|
||||
{
|
||||
"name": "70cm Ham Band",
|
||||
"type": "amateur",
|
||||
@ -247,16 +439,52 @@
|
||||
},
|
||||
{
|
||||
"name": "PMR446",
|
||||
"type": "amateur",
|
||||
"type": "PMR",
|
||||
"start": 446000000,
|
||||
"end": 446200000
|
||||
},
|
||||
{
|
||||
"name": "Outside Broadcast Talkback",
|
||||
"type": "PMR",
|
||||
"start": 446200000,
|
||||
"end": 447512500
|
||||
},
|
||||
{
|
||||
"name": "Private Mobile Radio",
|
||||
"type": "PMR",
|
||||
"start": 447600000,
|
||||
"end": 454000000
|
||||
},
|
||||
{
|
||||
"name": "Mosques",
|
||||
"type": "amateur",
|
||||
"start": 454000000,
|
||||
"end": 455000000
|
||||
},
|
||||
{
|
||||
"name": "Private Mobile Radio",
|
||||
"type": "PMR",
|
||||
"start": 455000000,
|
||||
"end": 467200000
|
||||
},
|
||||
{
|
||||
"name": "Outside Broadcast Talkback",
|
||||
"type": "PMR",
|
||||
"start": 467200000,
|
||||
"end": 468600000
|
||||
},
|
||||
{
|
||||
"name": "Digital TV Broadcast",
|
||||
"type": "broadcast",
|
||||
"start": 470000000,
|
||||
"end": 790000000
|
||||
},
|
||||
{
|
||||
"name": "Licence Exempt Short Range",
|
||||
"type": "amateur",
|
||||
"start": 862000000,
|
||||
"end": 875800000
|
||||
},
|
||||
{
|
||||
"name": "23cm Ham Band",
|
||||
"type": "amateur",
|
||||
|
@ -24,6 +24,16 @@ if (MSVC)
|
||||
target_include_directories(airspy_source PUBLIC "C:/Program Files/PothosSDR/include/libairspy/")
|
||||
|
||||
target_link_libraries(airspy_source PRIVATE airspy)
|
||||
elseif (ANDROID)
|
||||
target_include_directories(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/libusb/libusb
|
||||
/mnt/android_sdr/airspyone_host/libairspy/src
|
||||
)
|
||||
|
||||
target_link_libraries(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/output/libusb/${ANDROID_ABI}/libusb1.0.so
|
||||
/mnt/android_sdr/output/libairspy/${ANDROID_ABI}/libairspy.so
|
||||
)
|
||||
else (MSVC)
|
||||
find_package(PkgConfig)
|
||||
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include <gui/smgui.h>
|
||||
#include <airspy.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android_backend.h>
|
||||
#endif
|
||||
|
||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
||||
|
||||
SDRPP_MOD_INFO{
|
||||
@ -75,6 +79,7 @@ public:
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
#ifndef __ANDROID__
|
||||
devList.clear();
|
||||
devListTxt = "";
|
||||
|
||||
@ -88,6 +93,18 @@ public:
|
||||
devListTxt += buf;
|
||||
devListTxt += '\0';
|
||||
}
|
||||
#else
|
||||
// Check for device presence
|
||||
int vid, pid;
|
||||
devFd = backend::getDeviceFD(vid, pid, backend::AIRSPY_VIDPIDS);
|
||||
if (devFd < 0) { return; }
|
||||
|
||||
// Get device info
|
||||
std::string fakeName = "Airspy USB";
|
||||
devList.push_back(0xDEADBEEF);
|
||||
devListTxt += fakeName;
|
||||
devListTxt += '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
void selectFirst() {
|
||||
@ -112,7 +129,11 @@ public:
|
||||
void selectBySerial(uint64_t serial) {
|
||||
airspy_device* dev;
|
||||
try {
|
||||
#ifndef __ANDROID__
|
||||
int err = airspy_open_sn(&dev, serial);
|
||||
#else
|
||||
int err = airspy_open_sn(&dev, devFd);
|
||||
#endif
|
||||
if (err != 0) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%016" PRIX64, serial);
|
||||
@ -245,7 +266,11 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
int err = airspy_open_sn(&_this->openDev, _this->selectedSerial);
|
||||
#else
|
||||
int err = airspy_open_sn(&_this->openDev, _this->devFd);
|
||||
#endif
|
||||
if (err != 0) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%016" PRIX64, _this->selectedSerial);
|
||||
@ -571,6 +596,10 @@ private:
|
||||
bool lnaAgc = false;
|
||||
bool mixerAgc = false;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
int devFd = 0;
|
||||
#endif
|
||||
|
||||
std::vector<uint64_t> devList;
|
||||
std::string devListTxt;
|
||||
std::vector<uint32_t> sampleRateList;
|
||||
|
@ -24,6 +24,16 @@ if (MSVC)
|
||||
target_include_directories(airspyhf_source PUBLIC "C:/Program Files/PothosSDR/include/libairspyhf/")
|
||||
|
||||
target_link_libraries(airspyhf_source PRIVATE airspyhf)
|
||||
elseif (ANDROID)
|
||||
target_include_directories(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/libusb/libusb
|
||||
/mnt/android_sdr/airspyhf/libairspyhf/src
|
||||
)
|
||||
|
||||
target_link_libraries(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/output/libusb/${ANDROID_ABI}/libusb1.0.so
|
||||
/mnt/android_sdr/output/libairspyhf/${ANDROID_ABI}/libairspyhf.so
|
||||
)
|
||||
else (MSVC)
|
||||
find_package(PkgConfig)
|
||||
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include <airspyhf.h>
|
||||
#include <gui/widgets/stepped_slider.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android_backend.h>
|
||||
#endif
|
||||
|
||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
||||
|
||||
SDRPP_MOD_INFO{
|
||||
@ -79,6 +83,7 @@ public:
|
||||
devList.clear();
|
||||
devListTxt = "";
|
||||
|
||||
#ifndef __ANDROID__
|
||||
uint64_t serials[256];
|
||||
int n = airspyhf_list_devices(serials, 256);
|
||||
|
||||
@ -89,6 +94,18 @@ public:
|
||||
devListTxt += buf;
|
||||
devListTxt += '\0';
|
||||
}
|
||||
#else
|
||||
// Check for device presence
|
||||
int vid, pid;
|
||||
devFd = backend::getDeviceFD(vid, pid, backend::AIRSPYHF_VIDPIDS);
|
||||
if (devFd < 0) { return; }
|
||||
|
||||
// Get device info
|
||||
std::string fakeName = "Airspy HF+ USB";
|
||||
devList.push_back(0xDEADBEEF);
|
||||
devListTxt += fakeName;
|
||||
devListTxt += '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
void selectFirst() {
|
||||
@ -113,10 +130,14 @@ public:
|
||||
void selectBySerial(uint64_t serial) {
|
||||
airspyhf_device_t* dev;
|
||||
try {
|
||||
int err = airspyhf_open_sn(&dev, selectedSerial);
|
||||
#ifndef __ANDROID__
|
||||
int err = airspyhf_open_sn(&dev, serial);
|
||||
#else
|
||||
int err = airspyhf_open_sn(&dev, devFd);
|
||||
#endif
|
||||
if (err != 0) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%016" PRIX64, selectedSerial);
|
||||
sprintf(buf, "%016" PRIX64, serial);
|
||||
spdlog::error("Could not open Airspy HF+ {0}", buf);
|
||||
selectedSerial = 0;
|
||||
return;
|
||||
@ -124,7 +145,7 @@ public:
|
||||
}
|
||||
catch (std::exception e) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%016" PRIX64, selectedSerial);
|
||||
sprintf(buf, "%016" PRIX64, serial);
|
||||
spdlog::error("Could not open Airspy HF+ {0}", buf);
|
||||
}
|
||||
|
||||
@ -221,7 +242,11 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
int err = airspyhf_open_sn(&_this->openDev, _this->selectedSerial);
|
||||
#ifndef __ANDROID__
|
||||
int err = airspyhf_open_sn(&_this->openDev, _this->selectedSerial);
|
||||
#else
|
||||
int err = airspyhf_open_sn(&_this->openDev, _this->devFd);
|
||||
#endif
|
||||
if (err != 0) {
|
||||
char buf[1024];
|
||||
sprintf(buf, "%016" PRIX64, _this->selectedSerial);
|
||||
@ -368,6 +393,10 @@ private:
|
||||
float atten = 0.0f;
|
||||
std::string selectedSerStr = "";
|
||||
|
||||
#ifdef __ANDROID__
|
||||
int devFd = 0;
|
||||
#endif
|
||||
|
||||
std::vector<uint64_t> devList;
|
||||
std::string devListTxt;
|
||||
std::vector<uint32_t> sampleRateList;
|
||||
|
@ -22,6 +22,16 @@ if (MSVC)
|
||||
target_link_directories(hackrf_source PRIVATE "C:/Program Files/PothosSDR/bin/")
|
||||
|
||||
target_link_libraries(hackrf_source PRIVATE hackrf)
|
||||
elseif (ANDROID)
|
||||
target_include_directories(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/libusb/libusb
|
||||
/mnt/android_sdr/hackrf/host/libhackrf/src
|
||||
)
|
||||
|
||||
target_link_libraries(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/output/libusb/${ANDROID_ABI}/libusb1.0.so
|
||||
/mnt/android_sdr/output/libhackrf/${ANDROID_ABI}/libhackrf.so
|
||||
)
|
||||
else (MSVC)
|
||||
find_package(PkgConfig)
|
||||
|
||||
|
@ -5,11 +5,18 @@
|
||||
#include <core.h>
|
||||
#include <gui/style.h>
|
||||
#include <config.h>
|
||||
#include <libhackrf/hackrf.h>
|
||||
#include <gui/widgets/stepped_slider.h>
|
||||
#include <options.h>
|
||||
#include <gui/smgui.h>
|
||||
|
||||
#ifndef __ANDROID__
|
||||
#include <libhackrf/hackrf.h>
|
||||
#else
|
||||
#include <android_backend.h>
|
||||
#include <spdlog/sinks/android_sink.h>
|
||||
#include <hackrf.h>
|
||||
#endif
|
||||
|
||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
||||
|
||||
SDRPP_MOD_INFO{
|
||||
@ -127,6 +134,7 @@ public:
|
||||
devList.clear();
|
||||
devListTxt = "";
|
||||
|
||||
#ifndef __ANDROID__
|
||||
uint64_t serials[256];
|
||||
hackrf_device_list_t* _devList = hackrf_device_list();
|
||||
|
||||
@ -137,6 +145,15 @@ public:
|
||||
}
|
||||
|
||||
hackrf_device_list_free(_devList);
|
||||
#else
|
||||
int vid, pid;
|
||||
devFd = backend::getDeviceFD(vid, pid, backend::HACKRF_VIDPIDS);
|
||||
if (devFd < 0) { return; }
|
||||
std::string fakeName = "HackRF USB";
|
||||
devList.push_back("fake_serial");
|
||||
devListTxt += fakeName;
|
||||
devListTxt += '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
void selectFirst() {
|
||||
@ -229,7 +246,11 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
hackrf_error err = (hackrf_error)hackrf_open_by_serial(_this->selectedSerial.c_str(), &_this->openDev);
|
||||
#else
|
||||
hackrf_error err = (hackrf_error)hackrf_open_by_fd(&_this->openDev, _this->devFd);
|
||||
#endif
|
||||
if (err != HACKRF_SUCCESS) {
|
||||
spdlog::error("Could not open HackRF {0}: {1}", _this->selectedSerial, hackrf_error_name(err));
|
||||
return;
|
||||
@ -383,6 +404,10 @@ private:
|
||||
float lna = 0;
|
||||
float vga = 0;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
int devFd = -1;
|
||||
#endif
|
||||
|
||||
std::vector<std::string> devList;
|
||||
std::string devListTxt;
|
||||
};
|
||||
|
@ -24,6 +24,17 @@ if (MSVC)
|
||||
|
||||
target_link_libraries(plutosdr_source PRIVATE libiio)
|
||||
target_link_libraries(plutosdr_source PRIVATE libad9361)
|
||||
elseif (ANDROID)
|
||||
target_include_directories(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/libiio
|
||||
/mnt/android_sdr/libad9361-iio
|
||||
)
|
||||
|
||||
target_link_libraries(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/output/libxml2/${ANDROID_ABI}/libxml2.so
|
||||
/mnt/android_sdr/output/libiio/${ANDROID_ABI}/libiio.so
|
||||
/mnt/android_sdr/output/libad9361/${ANDROID_ABI}/libad9361.so
|
||||
)
|
||||
else (MSVC)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
target_include_directories(plutosdr_source PRIVATE "/Library/Frameworks/iio.framework/Headers")
|
||||
|
@ -22,6 +22,16 @@ if (MSVC)
|
||||
target_link_directories(rtl_sdr_source PRIVATE "C:/Program Files/PothosSDR/bin/")
|
||||
|
||||
target_link_libraries(rtl_sdr_source PRIVATE rtlsdr)
|
||||
elseif (ANDROID)
|
||||
target_include_directories(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/libusb/libusb
|
||||
/mnt/android_sdr/librtlsdr/include
|
||||
)
|
||||
|
||||
target_link_libraries(sdrpp_core PUBLIC
|
||||
/mnt/android_sdr/output/libusb/${ANDROID_ABI}/libusb1.0.so
|
||||
/mnt/android_sdr/output/librtlsdr/${ANDROID_ABI}/librtlsdr.so
|
||||
)
|
||||
else (MSVC)
|
||||
find_package(PkgConfig)
|
||||
|
||||
|
@ -9,6 +9,9 @@
|
||||
#include <gui/smgui.h>
|
||||
#include <rtl-sdr.h>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android_backend.h>
|
||||
#endif
|
||||
|
||||
#define CONCAT(a, b) ((std::string(a) + b).c_str())
|
||||
|
||||
@ -114,6 +117,7 @@ public:
|
||||
devNames.clear();
|
||||
devListTxt = "";
|
||||
|
||||
#ifndef __ANDROID__
|
||||
devCount = rtlsdr_get_device_count();
|
||||
char buf[1024];
|
||||
for (int i = 0; i < devCount; i++) {
|
||||
@ -123,6 +127,20 @@ public:
|
||||
devListTxt += buf;
|
||||
devListTxt += '\0';
|
||||
}
|
||||
#else
|
||||
// Check for device connection
|
||||
devCount = 0;
|
||||
int vid, pid;
|
||||
devFd = backend::getDeviceFD(vid, pid, backend::RTL_SDR_VIDPIDS);
|
||||
if (devFd < 0) { return; }
|
||||
|
||||
// Generate fake device info
|
||||
devCount = 1;
|
||||
std::string fakeName = "RTL-SDR Dongle USB";
|
||||
devNames.push_back(fakeName);
|
||||
devListTxt += fakeName;
|
||||
devListTxt += '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
void selectFirst() {
|
||||
@ -144,9 +162,15 @@ public:
|
||||
void selectById(int id) {
|
||||
selectedDevName = devNames[id];
|
||||
|
||||
if (rtlsdr_open(&openDev, id) < 0) {
|
||||
#ifndef __ANDROID__
|
||||
int oret = rtlsdr_open(&openDev, id);
|
||||
#else
|
||||
int oret = rtlsdr_open(&openDev, devFd);
|
||||
#endif
|
||||
|
||||
if (oret < 0) {
|
||||
selectedDevName = "";
|
||||
spdlog::error("Could not open RTL-SDR");
|
||||
spdlog::error("Could not open RTL-SDR: {0}", oret);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -252,7 +276,13 @@ private:
|
||||
return;
|
||||
}
|
||||
|
||||
if (rtlsdr_open(&_this->openDev, _this->devId) < 0) {
|
||||
#ifndef __ANDROID__
|
||||
int oret = rtlsdr_open(&_this->openDev, _this->devId);
|
||||
#else
|
||||
int oret = rtlsdr_open(&_this->openDev, _this->devFd);
|
||||
#endif
|
||||
|
||||
if (oret < 0) {
|
||||
spdlog::error("Could not open RTL-SDR");
|
||||
return;
|
||||
}
|
||||
@ -510,6 +540,10 @@ private:
|
||||
int devCount = 0;
|
||||
std::thread workerThread;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
int devFd = -1;
|
||||
#endif
|
||||
|
||||
int ppm = 0;
|
||||
|
||||
bool biasT = false;
|
||||
|
Loading…
Reference in New Issue
Block a user