#include "spyserver.h" #include "imgui/imgui_stdlib.h" #include "common/widgets/stepped_slider.h" SpyServerStreamFormat depth_to_format(int depth) { if (depth == 4) return SpyServerStreamFormat::SPYSERVER_STREAM_FORMAT_DINT4; else if (depth == 8) return SpyServerStreamFormat::SPYSERVER_STREAM_FORMAT_UINT8; else if (depth == 16) return SpyServerStreamFormat::SPYSERVER_STREAM_FORMAT_INT16; else if (depth == 24) return SpyServerStreamFormat::SPYSERVER_STREAM_FORMAT_INT24; else if (depth == 32) return SpyServerStreamFormat::SPYSERVER_STREAM_FORMAT_FLOAT; else return SpyServerStreamFormat::SPYSERVER_STREAM_FORMAT_INVALID; } void SpyServerSource::set_gains() { client->setSetting(SPYSERVER_SETTING_GAIN, gain); if (digital_gain == 0) digital_gain = client->computeDigitalGain(depth_to_format(bit_depth), gain, stage_to_use); client->setSetting(SPYSERVER_SETTING_IQ_DIGITAL_GAIN, digital_gain); logger->debug("Set SpyServer gain (device) to %d", gain); logger->debug("Set SpyServer gain (digital) to %d", digital_gain); } void SpyServerSource::set_settings(nlohmann::json settings) { d_settings = settings; ip_address = getValueOrDefault(d_settings["ip_address"], ip_address); port = getValueOrDefault(d_settings["port"], port); bit_depth = getValueOrDefault(d_settings["bit_depth"], bit_depth); gain = getValueOrDefault(d_settings["gain"], gain); digital_gain = getValueOrDefault(d_settings["digital_gain"], digital_gain); if (is_open && is_connected) { set_gains(); } } nlohmann::json SpyServerSource::get_settings() { d_settings["ip_address"] = ip_address; d_settings["port"] = port; d_settings["bit_depth"] = bit_depth; d_settings["gain"] = gain; d_settings["digital_gain"] = digital_gain; return d_settings; } void SpyServerSource::open() { // Nothing to do is_open = true; } void SpyServerSource::start() { if (is_connected) disconnect(); if (!is_connected) try_connect(); // DSPSampleSource::start(); // Do NOT reset the stream client->setSetting(SPYSERVER_SETTING_IQ_FORMAT, depth_to_format(bit_depth)); client->setSetting(SPYSERVER_SETTING_STREAMING_MODE, SPYSERVER_STREAM_MODE_IQ_ONLY); logger->debug("Set SpyServer samplerate to " + std::to_string(current_samplerate)); client->setSetting(SPYSERVER_SETTING_IQ_DECIMATION, stage_to_use); set_frequency(d_frequency); set_gains(); client->startStream(); is_started = true; } void SpyServerSource::stop() { if (is_started) client->stopStream(); is_started = false; } void SpyServerSource::close() { if (is_open && is_started) client->close(); is_open = false; } void SpyServerSource::set_frequency(uint64_t frequency) { if (is_open && is_connected) { client->setSetting(SPYSERVER_SETTING_IQ_FREQUENCY, frequency); logger->debug("Set SpyServer frequency to %d", frequency); } DSPSampleSource::set_frequency(frequency); } void SpyServerSource::drawControlUI() { if (is_connected) { if (is_started) style::beginDisabled(); ImGui::Combo("Samplerate", &selected_samplerate, samplerate_option_str.c_str()); current_samplerate = available_samplerates[selected_samplerate]; stage_to_use = selected_samplerate; if (is_started) style::endDisabled(); } if (is_started) style::beginDisabled(); if (is_connected) style::beginDisabled(); ImGui::InputText("Address", &ip_address); ImGui::InputInt("Port", &port); if (is_connected) style::endDisabled(); if (!is_connected) { if (ImGui::Button("Connect")) { try { try_connect(); } catch (std::exception &e) { logger->error("Error connecting to SpyServer %s", e.what()); error.set_message(style::theme.red, e.what()); } } } else { if (ImGui::Button("Disconnect")) { disconnect(); return; } } error.draw(); if (ImGui::Combo("Depth", &selected_bit_depth, "32\0" "16\0" "8\0")) { if (selected_bit_depth == 0) bit_depth = 32; else if (selected_bit_depth == 1) bit_depth = 16; else if (selected_bit_depth == 2) bit_depth = 8; } if (is_started) style::endDisabled(); if (is_connected) { bool gain_changed = false; gain_changed |= widgets::SteppedSliderInt("Gain", &gain, 0, client->devInfo.MaximumGainIndex); gain_changed |= widgets::SteppedSliderInt("Digital Gain", &digital_gain, 0, client->devInfo.MaximumGainIndex); if (gain_changed) set_gains(); } } void SpyServerSource::set_samplerate(uint64_t samplerate) { if (!is_connected) { buffer_samplerate = samplerate; } else { for (int i = 0; i < (int)available_samplerates.size(); i++) { if (samplerate == available_samplerates[i]) { selected_samplerate = i; current_samplerate = samplerate; stage_to_use = i; buffer_samplerate = 0; return; } } if (buffer_samplerate == 0) throw std::runtime_error("Unsupported samplerate : " + std::to_string(samplerate) + "!"); buffer_samplerate = 0; } } uint64_t SpyServerSource::get_samplerate() { if (is_connected) return current_samplerate; else return buffer_samplerate; } std::vector SpyServerSource::getAvailableSources() { std::vector results; results.push_back({"spyserver", "SpyServer", "0", false}); return results; }