#include #include #include #include #include #include #define CONCAT(a, b) ((std::string(a) + b).c_str()) #define DEEMP_LIST "50µS\00075µS\000none\000" MOD_INFO { /* Name: */ "radio", /* Description: */ "Radio module for SDR++", /* Author: */ "Ryzerth", /* Version: */ "0.2.5" }; class RadioModule { public: RadioModule(std::string name) { this->name = name; demod = 1; bandWidth = 200000; bandWidthMin = 100000; bandWidthMax = 200000; sigPath.init(name, 200000, 1000); sigPath.start(); sigPath.setDemodulator(SigPath::DEMOD_FM, bandWidth); gui::menu.registerEntry(name, menuHandler, this); ScriptManager::ScriptRunHandler_t handler; handler.ctx = this; handler.handler = scriptCreateHandler; core::scriptManager.bindScriptRunHandler(name, handler); } ~RadioModule() { // TODO: Implement destructor } private: static void menuHandler(void* ctx) { RadioModule* _this = (RadioModule*)ctx; float menuColumnWidth = ImGui::GetContentRegionAvailWidth(); ImGui::BeginGroup(); // TODO: Change VFO ref in signal path ImGui::Columns(4, CONCAT("RadioModeColumns##_", _this->name), false); if (ImGui::RadioButton(CONCAT("NFM##_", _this->name), _this->demod == 0) && _this->demod != 0) { _this->demod = 0; _this->bandWidth = 16000; _this->bandWidthMin = 8000; _this->bandWidthMax = 16000; _this->sigPath.setDemodulator(SigPath::DEMOD_NFM, _this->bandWidth); } if (ImGui::RadioButton(CONCAT("WFM##_", _this->name), _this->demod == 1) && _this->demod != 1) { _this->demod = 1; _this->bandWidth = 200000; _this->bandWidthMin = 100000; _this->bandWidthMax = 200000; _this->sigPath.setDemodulator(SigPath::DEMOD_FM, _this->bandWidth); } ImGui::NextColumn(); if (ImGui::RadioButton(CONCAT("AM##_", _this->name), _this->demod == 2) && _this->demod != 2) { _this->demod = 2; _this->bandWidth = 12500; _this->bandWidthMin = 6250; _this->bandWidthMax = 12500; _this->sigPath.setDemodulator(SigPath::DEMOD_AM, _this->bandWidth); } if (ImGui::RadioButton(CONCAT("DSB##_", _this->name), _this->demod == 3) && _this->demod != 3) { _this->demod = 3; _this->bandWidth = 6000; _this->bandWidthMin = 3000; _this->bandWidthMax = 6000; _this->sigPath.setDemodulator(SigPath::DEMOD_DSB, _this->bandWidth); } ImGui::NextColumn(); if (ImGui::RadioButton(CONCAT("USB##_", _this->name), _this->demod == 4) && _this->demod != 4) { _this->demod = 4; _this->bandWidth = 3000; _this->bandWidthMin = 1500; _this->bandWidthMax = 3000; _this->sigPath.setDemodulator(SigPath::DEMOD_USB, _this->bandWidth); } if (ImGui::RadioButton(CONCAT("CW##_", _this->name), _this->demod == 5) && _this->demod != 5) { _this->demod = 5; }; ImGui::NextColumn(); if (ImGui::RadioButton(CONCAT("LSB##_", _this->name), _this->demod == 6) && _this->demod != 6) { _this->demod = 6; _this->bandWidth = 3000; _this->bandWidthMin = 1500; _this->bandWidthMax = 3000; _this->sigPath.setDemodulator(SigPath::DEMOD_LSB, _this->bandWidth); } if (ImGui::RadioButton(CONCAT("RAW##_", _this->name), _this->demod == 7) && _this->demod != 7) { _this->demod = 7; _this->bandWidth = 10000; _this->bandWidthMin = 3000; _this->bandWidthMax = 10000; _this->sigPath.setDemodulator(SigPath::DEMOD_RAW, _this->bandWidth); }; ImGui::Columns(1, CONCAT("EndRadioModeColumns##_", _this->name), false); ImGui::EndGroup(); ImGui::Text("WFM Deemphasis"); ImGui::SameLine(); ImGui::PushItemWidth(menuColumnWidth - ImGui::GetCursorPosX()); if (ImGui::Combo(CONCAT("##_deemp_select_", _this->name), &_this->deemp, DEEMP_LIST)) { _this->sigPath.setDeemphasis(_this->deemp); } ImGui::PopItemWidth(); ImGui::Text("Bandwidth"); ImGui::SameLine(); ImGui::PushItemWidth(menuColumnWidth - ImGui::GetCursorPosX()); if (ImGui::InputInt(CONCAT("##_bw_select_", _this->name), &_this->bandWidth, 100, 1000)) { _this->bandWidth = std::clamp(_this->bandWidth, _this->bandWidthMin, _this->bandWidthMax); _this->sigPath.setBandwidth(_this->bandWidth); } ImGui::PopItemWidth(); } static void scriptCreateHandler(void* ctx, duk_context* dukCtx, duk_idx_t objId) { duk_push_string(dukCtx, "Hello from modules ;)"); duk_put_prop_string(dukCtx, objId, "test"); duk_push_c_function(dukCtx, duk_setDemodulator, 1); duk_put_prop_string(dukCtx, objId, "setDemodulator"); duk_push_pointer(dukCtx, ctx); duk_put_prop_string(dukCtx, objId, DUK_HIDDEN_SYMBOL("radio_ctx")); } static duk_ret_t duk_setDemodulator(duk_context* dukCtx) { const char* str = duk_require_string(dukCtx, -1); std::string modName = str; if (modName == "USB") { _this->demod = 4; _this->bandWidth = 3000; _this->bandWidthMin = 1500; _this->bandWidthMax = 3000; _this->sigPath.setDemodulator(SigPath::DEMOD_USB, _this->bandWidth); } return 0; } std::string name; int demod = 1; int deemp = 0; int bandWidth; int bandWidthMin; int bandWidthMax; SigPath sigPath; }; MOD_EXPORT void _INIT_() { // Do your one time init here } MOD_EXPORT void* _CREATE_INSTANCE_(std::string name) { return new RadioModule(name); } MOD_EXPORT void _DELETE_INSTANCE_(void* instance) { delete (RadioModule*)instance; } MOD_EXPORT void _STOP_() { // Do your one shutdown here }