From 7e4d173996e123f0f96805deacff5bad4e29a1c9 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Sat, 28 Nov 2015 23:03:07 -0500 Subject: [PATCH] Basic console window for digital output - Probably end up making this a single tabbed dialog but this works for the moment --- CMakeLists.txt | 10 +- src/AppFrame.cpp | 27 +- src/CubicSDR.cpp | 52 +- src/ModemProperties.cpp | 4 +- src/demod/DemodulatorInstance.cpp | 76 ++- src/demod/DemodulatorInstance.h | 19 +- src/demod/DemodulatorPreThread.cpp | 7 + src/forms/DigitalConsole/DigitalConsole.cpp | 138 +++++ src/forms/DigitalConsole/DigitalConsole.fbp | 474 ++++++++++++++++++ src/forms/DigitalConsole/DigitalConsole.h | 61 +++ .../DigitalConsole/DigitalConsoleFrame.cpp | 67 +++ .../DigitalConsole/DigitalConsoleFrame.h | 57 +++ src/modules/modem/ModemDigital.cpp | 29 +- src/modules/modem/ModemDigital.h | 31 +- src/modules/modem/analog/ModemAM.cpp | 2 +- src/modules/modem/analog/ModemDSB.cpp | 2 +- src/modules/modem/analog/ModemFM.cpp | 2 +- src/modules/modem/analog/ModemLSB.cpp | 2 +- src/modules/modem/analog/ModemUSB.cpp | 2 +- src/modules/modem/digital/ModemAPSK.cpp | 2 +- src/modules/modem/digital/ModemASK.cpp | 2 +- src/modules/modem/digital/ModemBPSK.cpp | 2 +- src/modules/modem/digital/ModemDPSK.cpp | 2 +- src/modules/modem/digital/ModemFSK.cpp | 14 +- src/modules/modem/digital/ModemFSK.h | 1 + src/modules/modem/digital/ModemOOK.cpp | 2 +- src/modules/modem/digital/ModemPSK.cpp | 2 +- src/modules/modem/digital/ModemQAM.cpp | 2 +- src/modules/modem/digital/ModemQPSK.cpp | 2 +- src/modules/modem/digital/ModemSQAM.cpp | 2 +- src/modules/modem/digital/ModemST.cpp | 2 +- 31 files changed, 1030 insertions(+), 67 deletions(-) create mode 100644 src/forms/DigitalConsole/DigitalConsole.cpp create mode 100644 src/forms/DigitalConsole/DigitalConsole.fbp create mode 100644 src/forms/DigitalConsole/DigitalConsole.h create mode 100644 src/forms/DigitalConsole/DigitalConsoleFrame.cpp create mode 100644 src/forms/DigitalConsole/DigitalConsoleFrame.h diff --git a/CMakeLists.txt b/CMakeLists.txt index e4bf852..1f07098 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -290,6 +290,8 @@ SET (cubicsdr_sources IF(ENABLE_DIGITAL_LAB) SET (cubicsdr_sources ${cubicsdr_sources} + src/forms/DigitalConsole/DigitalConsole.cpp + src/forms/DigitalConsole/DigitalConsoleFrame.cpp src/modules/modem/digital/ModemASK.cpp src/modules/modem/digital/ModemAPSK.cpp src/modules/modem/digital/ModemBPSK.cpp @@ -393,6 +395,8 @@ SET (cubicsdr_headers IF(ENABLE_DIGITAL_LAB) SET (cubicsdr_headers ${cubicsdr_headers} + src/forms/DigitalConsole/DigitalConsole.h + src/forms/DigitalConsole/DigitalConsoleFrame.h src/modules/modem/digital/ModemASK.h src/modules/modem/digital/ModemAPSK.h src/modules/modem/digital/ModemBPSK.h @@ -429,9 +433,10 @@ SOURCE_GROUP("Forms\\SDRDevices" REGULAR_EXPRESSION "src/forms/SDRDevices/${REG_ SOURCE_GROUP("SDR" REGULAR_EXPRESSION "src/sdr/${REG_EXT}") SOURCE_GROUP("Demodulator" REGULAR_EXPRESSION "src/demod/${REG_EXT}") SOURCE_GROUP("Modem" REGULAR_EXPRESSION "src/modules/modem/${REG_EXT}") -SOURCE_GROUP("Modem-Analog" REGULAR_EXPRESSION "src/modules/modem/analog/${REG_EXT}") +SOURCE_GROUP("Modem\\Analog" REGULAR_EXPRESSION "src/modules/modem/analog/${REG_EXT}") IF(ENABLE_DIGITAL_LAB) -SOURCE_GROUP("Modem-Digital" REGULAR_EXPRESSION "src/modules/modem/digital/${REG_EXT}") +SOURCE_GROUP("Modem\\Digital" REGULAR_EXPRESSION "src/modules/modem/digital/${REG_EXT}") +SOURCE_GROUP("Forms\\DigitalConsole" REGULAR_EXPRESSION "src/forms/DigitalConsole/${REG_EXT}") ENDIF() SOURCE_GROUP("Audio" REGULAR_EXPRESSION "src/audio/${REG_EXT}") SOURCE_GROUP("Utility" REGULAR_EXPRESSION "src/util/${REG_EXT}") @@ -446,6 +451,7 @@ SOURCE_GROUP("_ext-CubicVR2" REGULAR_EXPRESSION "external/cubicvr2/.*${REG_EXT}" include_directories ( ${PROJECT_SOURCE_DIR}/src/forms/SDRDevices + ${PROJECT_SOURCE_DIR}/src/forms/DigitalConsole ${PROJECT_SOURCE_DIR}/src/sdr ${PROJECT_SOURCE_DIR}/src/demod ${PROJECT_SOURCE_DIR}/src/modules diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index b1a8711..7cc5339 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -76,6 +76,8 @@ AppFrame::AppFrame() : demodModeSelector->addChoice(6, "I/Q"); demodModeSelector->setSelection("FM"); demodModeSelector->setHelpTip("Choose modulation type: Frequency Modulation, Amplitude Modulation and Lower, Upper or Double Side-Band."); + demodModeSelector->SetMinSize(wxSize(40,-1)); + demodModeSelector->SetMaxSize(wxSize(40,-1)); demodTray->Add(demodModeSelector, 2, wxEXPAND | wxALL, 0); #ifdef ENABLE_DIGITAL_LAB @@ -92,11 +94,16 @@ AppFrame::AppFrame() : demodModeSelectorAdv->addChoice(9, "QAM"); demodModeSelectorAdv->addChoice(10, "QPSK"); demodModeSelectorAdv->setHelpTip("Choose advanced modulation types."); + demodModeSelectorAdv->SetMinSize(wxSize(40,-1)); + demodModeSelectorAdv->SetMaxSize(wxSize(40,-1)); demodTray->Add(demodModeSelectorAdv, 3, wxEXPAND | wxALL, 0); #endif modemPropertiesUpdated.store(false); modemProps = new ModemProperties(demodPanel, wxID_ANY); + modemProps->SetMinSize(wxSize(200,-1)); + modemProps->SetMaxSize(wxSize(200,-1)); + modemProps->Hide(); demodTray->Add(modemProps, 15, wxEXPAND | wxALL, 0); @@ -117,6 +124,8 @@ AppFrame::AppFrame() : wxGetApp().getDemodSpectrumProcessor()->attachOutput(demodWaterfallCanvas->getVisualDataQueue()); demodWaterfallCanvas->getVisualDataQueue()->set_max_num_items(3); + demodVisuals->SetMinSize(wxSize(128,-1)); + demodTray->Add(demodVisuals, 30, wxEXPAND | wxALL, 0); demodTray->AddSpacer(1); @@ -135,6 +144,7 @@ AppFrame::AppFrame() : scopeCanvas = new ScopeCanvas(demodPanel, attribList); scopeCanvas->setHelpTip("Audio Visuals, drag left/right to toggle Scope or Spectrum."); + scopeCanvas->SetMinSize(wxSize(128,-1)); demodScopeTray->Add(scopeCanvas, 8, wxEXPAND | wxALL, 0); wxGetApp().getScopeProcessor()->setup(2048); wxGetApp().getScopeProcessor()->attachOutput(scopeCanvas->getInputQueue()); @@ -1021,7 +1031,6 @@ void AppFrame::OnIdle(wxIdleEvent& event) { wxGetApp().getAudioVisualQueue()->set_max_num_items((scopeCanvas->scopeVisible()?1:0) + (scopeCanvas->spectrumVisible()?1:0)); wxGetApp().getScopeProcessor()->run(); -// wxGetApp().getSpectrumDistributor()->run(); SpectrumVisualProcessor *proc = wxGetApp().getSpectrumProcessor(); @@ -1070,12 +1079,18 @@ void AppFrame::OnIdle(wxIdleEvent& event) { modemProps->initProperties(demod->getModemArgs()); modemPropertiesUpdated.store(false); demodTray->Layout(); +#if ENABLE_DIGITAL_LAB + if (demod->getModemType() == "digital") { + ModemDigitalOutputConsole *outp = (ModemDigitalOutputConsole *)demod->getOutput(); + if (!outp->getDialog()) { + outp->setTitle(demod->getDemodulatorType() + ": " + frequencyToStr(demod->getFrequency())); + outp->setDialog(new DigitalConsole(this, outp)); + } + demod->showOutput(); + } +#endif } -// waterfallCanvas->processInputQueue(); -// waterfallCanvas->Refresh(); -// demodWaterfallCanvas->processInputQueue(); -// demodWaterfallCanvas->Refresh(); - + if (!this->IsActive()) { std::this_thread::sleep_for(std::chrono::milliseconds(25)); } diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 5084294..2e917e6 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -20,20 +20,20 @@ IMPLEMENT_APP(CubicSDR) -#ifdef ENABLE_DIGITAL_LAB -// console output buffer for windows -#ifdef _WINDOWS -class outbuf : public std::streambuf { - public: - outbuf() { - setp(0, 0); - } - virtual int_type overflow(int_type c = traits_type::eof()) { - return fputc(c, stdout) == EOF ? traits_type::eof() : c; - } -}; -#endif -#endif +//#ifdef ENABLE_DIGITAL_LAB +//// console output buffer for windows +//#ifdef _WINDOWS +//class outbuf : public std::streambuf { +// public: +// outbuf() { +// setp(0, 0); +// } +// virtual int_type overflow(int_type c = traits_type::eof()) { +// return fputc(c, stdout) == EOF ? traits_type::eof() : c; +// } +//}; +//#endif +//#endif #ifdef MINGW_PATCH FILE _iob[] = { *stdin, *stdout, *stderr }; @@ -149,18 +149,18 @@ bool CubicSDR::OnInit() { return false; } -#ifdef ENABLE_DIGITAL_LAB - // console output for windows - #ifdef _WINDOWS - if (AllocConsole()) { - freopen("CONOUT$", "w", stdout); - SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED); - } - outbuf ob; - std::streambuf *sb = std::cout.rdbuf(&ob); - std::cout.rdbuf(sb); - #endif -#endif +//#ifdef ENABLE_DIGITAL_LAB +// // console output for windows +// #ifdef _WINDOWS +// if (AllocConsole()) { +// freopen("CONOUT$", "w", stdout); +// SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED); +// } +// outbuf ob; +// std::streambuf *sb = std::cout.rdbuf(&ob); +// std::cout.rdbuf(sb); +// #endif +//#endif wxApp::SetAppName("CubicSDR"); diff --git a/src/ModemProperties.cpp b/src/ModemProperties.cpp index c679e3d..d8c2546 100644 --- a/src/ModemProperties.cpp +++ b/src/ModemProperties.cpp @@ -5,10 +5,10 @@ ModemProperties::ModemProperties(wxWindow *parent, wxWindowID winid, const wxPoint& pos, const wxSize& size, long style, const wxString& name) : wxPanel(parent, winid, pos, size, style, name) { m_propertyGrid = new wxPropertyGrid(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxPG_DEFAULT_STYLE); - + bSizer = new wxBoxSizer( wxVERTICAL ); - bSizer->Add(m_propertyGrid, 1, wxEXPAND | wxALL, 5); + bSizer->Add(m_propertyGrid, 1, wxEXPAND, 5); this->SetSizer(bSizer); diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index a326ea3..5ba905a 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -2,8 +2,11 @@ #include "CubicSDR.h" DemodulatorInstance::DemodulatorInstance() : - t_PreDemod(NULL), t_Demod(NULL), t_Audio(NULL) { + t_PreDemod(nullptr), t_Demod(nullptr), t_Audio(nullptr) { +#if ENABLE_DIGITAL_LAB + activeOutput = nullptr; +#endif terminated.store(true); audioTerminated.store(true); demodTerminated.store(true); @@ -42,6 +45,9 @@ DemodulatorInstance::DemodulatorInstance() : } DemodulatorInstance::~DemodulatorInstance() { +#if ENABLE_DIGITAL_LAB + delete activeOutput; +#endif delete audioThread; delete demodulatorThread; delete demodulatorPreThread; @@ -137,6 +143,11 @@ bool DemodulatorInstance::isTerminated() { #else t_Demod->join(); delete t_Demod; +#endif +#if ENABLE_DIGITAL_LAB + if (activeOutput) { + closeOutput(); + } #endif demodTerminated = true; break; @@ -165,8 +176,18 @@ bool DemodulatorInstance::isActive() { void DemodulatorInstance::setActive(bool state) { if (active && !state) { +#if ENABLE_DIGITAL_LAB + if (activeOutput && !isTerminated()) { + activeOutput->Hide(); + } +#endif audioThread->setActive(state); } else if (!active && state) { +#if ENABLE_DIGITAL_LAB + if (activeOutput) { + activeOutput->Show(); + } +#endif audioThread->setActive(state); } if (!state) { @@ -244,6 +265,11 @@ void DemodulatorInstance::setDemodulatorType(std::string demod_type_in) { if ((currentDemodType != "") && (currentDemodType != demod_type_in)) { lastModemSettings[currentDemodType] = demodulatorPreThread->readModemSettings(); } +#if ENABLE_DIGITAL_LAB + if (activeOutput) { + activeOutput->Hide(); + } +#endif demodulatorPreThread->setDemodType(demod_type_in); } } @@ -284,6 +310,14 @@ void DemodulatorInstance::setFrequency(long long freq) { } demodulatorPreThread->setFrequency(freq); +#if ENABLE_DIGITAL_LAB + if (activeOutput) { + if (isModemInitialized() && getModemType() == "digital") { + ModemDigitalOutputConsole *outp = (ModemDigitalOutputConsole *)getOutput(); + outp->setTitle(getDemodulatorType() + ": " + frequencyToStr(getFrequency())); + } + } +#endif } long long DemodulatorInstance::getFrequency() { @@ -375,6 +409,13 @@ bool DemodulatorInstance::isModemInitialized() { return demodulatorPreThread->isInitialized(); } +std::string DemodulatorInstance::getModemType() { + if (isModemInitialized()) { + return demodulatorPreThread->getModem()->getType(); + } + return ""; +} + ModemSettings DemodulatorInstance::getLastModemSettings(std::string demodType) { if (lastModemSettings.find(demodType) != lastModemSettings.end()) { return lastModemSettings[demodType]; @@ -383,3 +424,36 @@ ModemSettings DemodulatorInstance::getLastModemSettings(std::string demodType) { return mods; } } + +#if ENABLE_DIGITAL_LAB +ModemDigitalOutput *DemodulatorInstance::getOutput() { + if (activeOutput == nullptr) { + activeOutput = new ModemDigitalOutputConsole(); + } + return activeOutput; +} + +void DemodulatorInstance::showOutput() { + if (activeOutput != nullptr) { + activeOutput->Show(); + } +} + +void DemodulatorInstance::hideOutput() { + if (activeOutput != nullptr) { + activeOutput->Hide(); + } +} + +void DemodulatorInstance::closeOutput() { + if (isModemInitialized()) { + if (getModemType() == "digital") { + ModemDigital *dModem = (ModemDigital *)demodulatorPreThread->getModem(); + dModem->setOutput(nullptr); + } + } + if (activeOutput) { + activeOutput->Close(); + } +} +#endif \ No newline at end of file diff --git a/src/demod/DemodulatorInstance.h b/src/demod/DemodulatorInstance.h index 84a91e0..d3d3671 100644 --- a/src/demod/DemodulatorInstance.h +++ b/src/demod/DemodulatorInstance.h @@ -10,6 +10,10 @@ #include "ModemDigital.h" #include "ModemAnalog.h" +#if ENABLE_DIGITAL_LAB +#include "DigitalConsole.h" +#endif + class DemodulatorInstance { public: @@ -89,8 +93,16 @@ public: void writeModemSettings(ModemSettings settings); bool isModemInitialized(); + std::string getModemType(); ModemSettings getLastModemSettings(std::string demodType); - + +#if ENABLE_DIGITAL_LAB + ModemDigitalOutput *getOutput(); + void showOutput(); + void hideOutput(); + void closeOutput(); +#endif + protected: DemodulatorThreadInputQueue* pipeIQInputData; DemodulatorThreadPostInputQueue* pipeIQDemodData; @@ -115,4 +127,7 @@ private: std::atomic currentAudioGain; std::atomic_bool follow, tracking; std::map lastModemSettings; - }; +#if ENABLE_DIGITAL_LAB + ModemDigitalOutput *activeOutput; +#endif +}; diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 277b6c9..98716fd 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -120,6 +120,7 @@ void DemodulatorPreThread::run() { cModem = nullptr; cModemKit = nullptr; demodTypeChanged.store(false); + initialized.store(false); } else if ( cModemKit && cModem && @@ -226,6 +227,12 @@ void DemodulatorPreThread::run() { if (result.modem != nullptr) { cModem = result.modem; +#if ENABLE_DIGITAL_LAB + if (cModem->getType() == "digital") { + ModemDigital *mDigi = (ModemDigital *)cModem; + mDigi->setOutput(parent->getOutput()); + } +#endif } if (result.modemKit != nullptr) { diff --git a/src/forms/DigitalConsole/DigitalConsole.cpp b/src/forms/DigitalConsole/DigitalConsole.cpp new file mode 100644 index 0000000..f472ca1 --- /dev/null +++ b/src/forms/DigitalConsole/DigitalConsole.cpp @@ -0,0 +1,138 @@ +#include "DigitalConsole.h" +#include "CubicSDR.h" +#include + +DigitalConsole::DigitalConsole( wxWindow* parent, ModemDigitalOutputConsole *doParent ): DigitalConsoleFrame( parent ), doParent(doParent) { + streamWritten.store(false); + streamPaused.store(false); +} + +DigitalConsole::~DigitalConsole() { + doParent->setDialog(nullptr); +} + +void DigitalConsole::OnClose( wxCloseEvent& event ) { + doParent->setDialog(nullptr); +} + +void DigitalConsole::OnCopy( wxCommandEvent& event ) { + m_dataView->SelectAll(); + m_dataView->Copy(); +} + +void DigitalConsole::OnPause( wxCommandEvent& event ) { + if (streamPaused.load()) { + m_pauseButton->SetLabel("Stop"); + streamPaused.store(false); + } else { + m_pauseButton->SetLabel("Run"); + streamPaused.store(true); + } +} + +void DoRefresh( wxTimerEvent& event ) { + event.Skip(); +} + +void DigitalConsole::DoRefresh( wxTimerEvent& event ) { + if (streamWritten.load()) { + stream_busy.lock(); + m_dataView->AppendText(streamBuf.str()); + streamBuf.str(""); + streamWritten.store(false); + stream_busy.unlock(); + } +} + +void DigitalConsole::OnClear( wxCommandEvent& event ) { + m_dataView->Clear(); +} + +void DigitalConsole::write(std::string outp) { + if (streamPaused.load()) { + return; + } + stream_busy.lock(); + streamBuf << outp; + streamWritten.store(true); + stream_busy.unlock(); +} + +void DigitalConsole::write(char outc) { + if (streamPaused.load()) { + return; + } + stream_busy.lock(); + streamBuf << outc; + streamWritten.store(true); + stream_busy.unlock(); +} + + +ModemDigitalOutputConsole::ModemDigitalOutputConsole(): ModemDigitalOutput(), dialog(nullptr) { + streamWritten.store(false); +} + +ModemDigitalOutputConsole::~ModemDigitalOutputConsole() { + +} + +void ModemDigitalOutputConsole::setDialog(DigitalConsole *dialog_in) { + dialog = dialog_in; + if (dialog && dialogTitle != "") { + dialog->SetTitle(dialogTitle); + } +} + +DigitalConsole *ModemDigitalOutputConsole::getDialog() { + return dialog; +} + +void ModemDigitalOutputConsole::Show() { + if (!dialog) { + return; + } + if (!dialog->IsShown()) { + dialog->Show(); + } +} + + +void ModemDigitalOutputConsole::Hide() { + if (!dialog) { + return; + } + if (dialog->IsShown()) { + dialog->Hide(); + } +} + +void ModemDigitalOutputConsole::Close() { + if (!dialog) { + return; + } + dialog->Hide(); + dialog->Close(); + dialog = nullptr; +} + +void ModemDigitalOutputConsole::setTitle(std::string title) { + if (dialog) { + dialog->SetTitle(title); + } + dialogTitle = title; +} + +void ModemDigitalOutputConsole::write(std::string outp) { + if (!dialog) { + return; + } + dialog->write(outp); +} + +void ModemDigitalOutputConsole::write(char outc) { + if (!dialog) { + return; + } + dialog->write(outc); +} diff --git a/src/forms/DigitalConsole/DigitalConsole.fbp b/src/forms/DigitalConsole/DigitalConsole.fbp new file mode 100644 index 0000000..cd41a92 --- /dev/null +++ b/src/forms/DigitalConsole/DigitalConsole.fbp @@ -0,0 +1,474 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + DigitalConsoleFrame + 1000 + none + 0 + DigitalConsole + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DigitalConsoleFrame + + 441,394 + wxCAPTION|wxFRAME_FLOAT_ON_PARENT|wxMAXIMIZE|wxMAXIMIZE_BOX|wxMINIMIZE|wxMINIMIZE_BOX|wxRESIZE_BORDER + ; + Digital Output + + wxWS_EX_PROCESS_UI_UPDATES + + wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL + 1 + + + + + + + + + + OnClose + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer + wxVERTICAL + none + + 5 + wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + ,90,90,-1,76,0 + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_dataView + 1 + + + protected + 1 + + Resizable + 1 + + wxTE_CHARWRAP|wxTE_MULTILINE|wxTE_NOHIDESEL|wxTE_READONLY|wxTE_WORDWRAP + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + wxWS_EX_PROCESS_UI_UPDATES + + wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE|wxNO_BORDER|wxSIMPLE_BORDER|wxVSCROLL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer2 + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Clear + + 0 + + + 0 + + 1 + m_clearButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnClear + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Copy + + 0 + + + 0 + + 1 + m_copyButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnCopy + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Stop + + 0 + + + 0 + + 1 + m_pauseButton + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnPause + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + wxID_ANY + m_refreshTimer + 0 + 250 + protected + DoRefresh + + + + diff --git a/src/forms/DigitalConsole/DigitalConsole.h b/src/forms/DigitalConsole/DigitalConsole.h new file mode 100644 index 0000000..5d5321d --- /dev/null +++ b/src/forms/DigitalConsole/DigitalConsole.h @@ -0,0 +1,61 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "DigitalConsoleFrame.h" +#include "ModemDigital.h" + +class ModemDigitalOutputConsole; +class DigitalConsole: public DigitalConsoleFrame { +public: + DigitalConsole( wxWindow* parent, ModemDigitalOutputConsole *doParent ); + ~DigitalConsole(); + + + void write(std::string outp); + void write(char outc); + +private: + void DoRefresh( wxTimerEvent& event ); + void OnClose( wxCloseEvent& event ); + void OnClear( wxCommandEvent& event ); + + void OnCopy( wxCommandEvent& event ); + void OnPause( wxCommandEvent& event ); + + std::stringstream streamBuf; + std::mutex stream_busy; + std::atomic streamWritten; + std::atomic streamPaused; + ModemDigitalOutputConsole *doParent; +}; + +class ModemDigitalOutputConsole: public ModemDigitalOutput { +public: + ModemDigitalOutputConsole(); + ~ModemDigitalOutputConsole(); + + void setDialog(DigitalConsole *dialog_in); + DigitalConsole *getDialog(); + + void setTitle(std::string title); + + void write(std::string outp); + void write(char outc); + + void Show(); + void Hide(); + void Close(); + +private: + DigitalConsole *dialog; + std::stringstream streamBuf; + std::mutex stream_busy; + std::atomic streamWritten; + std::string dialogTitle; +}; + diff --git a/src/forms/DigitalConsole/DigitalConsoleFrame.cpp b/src/forms/DigitalConsole/DigitalConsoleFrame.cpp new file mode 100644 index 0000000..565a054 --- /dev/null +++ b/src/forms/DigitalConsole/DigitalConsoleFrame.cpp @@ -0,0 +1,67 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Aug 23 2015) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "DigitalConsoleFrame.h" + +/////////////////////////////////////////////////////////////////////////// + +DigitalConsoleFrame::DigitalConsoleFrame( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : wxFrame( parent, id, title, pos, size, style ) +{ + this->SetSizeHints( wxDefaultSize, wxDefaultSize ); + this->SetExtraStyle( wxWS_EX_PROCESS_UI_UPDATES ); + + wxBoxSizer* bSizer; + bSizer = new wxBoxSizer( wxVERTICAL ); + + m_dataView = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CHARWRAP|wxTE_MULTILINE|wxTE_NOHIDESEL|wxTE_READONLY|wxTE_WORDWRAP|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE|wxNO_BORDER|wxSIMPLE_BORDER|wxVSCROLL ); + m_dataView->SetExtraStyle( wxWS_EX_PROCESS_UI_UPDATES ); + m_dataView->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 76, 90, 90, false, wxEmptyString ) ); + + bSizer->Add( m_dataView, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizer2; + bSizer2 = new wxBoxSizer( wxHORIZONTAL ); + + m_clearButton = new wxButton( this, wxID_ANY, wxT("Clear"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer2->Add( m_clearButton, 0, wxALL, 5 ); + + m_copyButton = new wxButton( this, wxID_ANY, wxT("Copy"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer2->Add( m_copyButton, 0, wxALL, 5 ); + + m_pauseButton = new wxButton( this, wxID_ANY, wxT("Stop"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer2->Add( m_pauseButton, 0, wxEXPAND, 5 ); + + + bSizer->Add( bSizer2, 0, wxEXPAND, 5 ); + + + this->SetSizer( bSizer ); + this->Layout(); + m_refreshTimer.SetOwner( this, wxID_ANY ); + m_refreshTimer.Start( 250 ); + + + this->Centre( wxBOTH ); + + // Connect Events + this->Connect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DigitalConsoleFrame::OnClose ) ); + m_clearButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DigitalConsoleFrame::OnClear ), NULL, this ); + m_copyButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DigitalConsoleFrame::OnCopy ), NULL, this ); + m_pauseButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DigitalConsoleFrame::OnPause ), NULL, this ); + this->Connect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( DigitalConsoleFrame::DoRefresh ) ); +} + +DigitalConsoleFrame::~DigitalConsoleFrame() +{ + // Disconnect Events + this->Disconnect( wxEVT_CLOSE_WINDOW, wxCloseEventHandler( DigitalConsoleFrame::OnClose ) ); + m_clearButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DigitalConsoleFrame::OnClear ), NULL, this ); + m_copyButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DigitalConsoleFrame::OnCopy ), NULL, this ); + m_pauseButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DigitalConsoleFrame::OnPause ), NULL, this ); + this->Disconnect( wxID_ANY, wxEVT_TIMER, wxTimerEventHandler( DigitalConsoleFrame::DoRefresh ) ); + +} diff --git a/src/forms/DigitalConsole/DigitalConsoleFrame.h b/src/forms/DigitalConsole/DigitalConsoleFrame.h new file mode 100644 index 0000000..05fdd9f --- /dev/null +++ b/src/forms/DigitalConsole/DigitalConsoleFrame.h @@ -0,0 +1,57 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Aug 23 2015) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __DIGITALCONSOLEFRAME_H__ +#define __DIGITALCONSOLEFRAME_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class DigitalConsoleFrame +/////////////////////////////////////////////////////////////////////////////// +class DigitalConsoleFrame : public wxFrame +{ + private: + + protected: + wxTextCtrl* m_dataView; + wxButton* m_clearButton; + wxButton* m_copyButton; + wxButton* m_pauseButton; + wxTimer m_refreshTimer; + + // Virtual event handlers, overide them in your derived class + virtual void OnClose( wxCloseEvent& event ) { event.Skip(); } + virtual void OnClear( wxCommandEvent& event ) { event.Skip(); } + virtual void OnCopy( wxCommandEvent& event ) { event.Skip(); } + virtual void OnPause( wxCommandEvent& event ) { event.Skip(); } + virtual void DoRefresh( wxTimerEvent& event ) { event.Skip(); } + + + public: + + DigitalConsoleFrame( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = wxT("Digital Output"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 441,394 ), long style = wxCAPTION|wxFRAME_FLOAT_ON_PARENT|wxMAXIMIZE|wxMAXIMIZE_BOX|wxMINIMIZE|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL ); + + ~DigitalConsoleFrame(); + +}; + +#endif //__DIGITALCONSOLEFRAME_H__ diff --git a/src/modules/modem/ModemDigital.cpp b/src/modules/modem/ModemDigital.cpp index c8c09f6..aa8e123 100644 --- a/src/modules/modem/ModemDigital.cpp +++ b/src/modules/modem/ModemDigital.cpp @@ -1,7 +1,18 @@ #include "ModemDigital.h" -ModemDigital::ModemDigital() { +ModemDigitalOutput::ModemDigitalOutput() { + +} + +ModemDigital::ModemDigital() { +#if ENABLE_DIGITAL_LAB + digitalOut = nullptr; +#endif +} + +ModemDigitalOutput::~ModemDigitalOutput() { + } std::string ModemDigital::getType() { @@ -54,6 +65,18 @@ void ModemDigital::digitalStart(ModemKitDigital *kit, modem mod, ModemIQData *in } void ModemDigital::digitalFinish(ModemKitDigital *kit, modem mod) { - demodOutputDataDigital.empty(); +#if ENABLE_DIGITAL_LAB + if (digitalOut && outStream.str().length()) { + digitalOut->write(outStream.str()); + outStream.str(""); + } else { + outStream.str(""); + } +#endif } - \ No newline at end of file + +#if ENABLE_DIGITAL_LAB +void ModemDigital::setOutput(ModemDigitalOutput *modemDigitalOutput) { + digitalOut = modemDigitalOutput; +} +#endif \ No newline at end of file diff --git a/src/modules/modem/ModemDigital.h b/src/modules/modem/ModemDigital.h index 3c0e1be..e1991c1 100644 --- a/src/modules/modem/ModemDigital.h +++ b/src/modules/modem/ModemDigital.h @@ -1,5 +1,10 @@ #pragma once #include "Modem.h" +#include +#include +#include +#include +#include class ModemKitDigital : public ModemKit { public: @@ -8,6 +13,20 @@ public: }; }; +class ModemDigitalOutput { +public: + ModemDigitalOutput(); + virtual ~ModemDigitalOutput(); + + virtual void write(std::string outp) = 0; + virtual void write(char outc) = 0; + + virtual void Show() = 0; + virtual void Hide() = 0; + virtual void Close() = 0; + +private: +}; class ModemDigital : public Modem { public: @@ -28,11 +47,15 @@ public: virtual void updateDemodulatorLock(modem mod, float sensitivity); +#if ENABLE_DIGITAL_LAB + void setOutput(ModemDigitalOutput *digitalOutput); +#endif + protected: std::vector demodOutputDataDigital; std::atomic_bool currentDemodLock; - -// std::vector demodOutputDataDigitalTest; -// std::vector demodOutputSoftbits; -// std::vector demodOutputSoftbitsTest; +#if ENABLE_DIGITAL_LAB + ModemDigitalOutput *digitalOut; + std::stringstream outStream; +#endif }; \ No newline at end of file diff --git a/src/modules/modem/analog/ModemAM.cpp b/src/modules/modem/analog/ModemAM.cpp index 678832e..114d81b 100644 --- a/src/modules/modem/analog/ModemAM.cpp +++ b/src/modules/modem/analog/ModemAM.cpp @@ -1,6 +1,6 @@ #include "ModemAM.h" -ModemAM::ModemAM() { +ModemAM::ModemAM() : ModemAnalog() { demodAM = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 0); } diff --git a/src/modules/modem/analog/ModemDSB.cpp b/src/modules/modem/analog/ModemDSB.cpp index c343425..b40b11f 100644 --- a/src/modules/modem/analog/ModemDSB.cpp +++ b/src/modules/modem/analog/ModemDSB.cpp @@ -1,6 +1,6 @@ #include "ModemDSB.h" -ModemDSB::ModemDSB() { +ModemDSB::ModemDSB() : ModemAnalog() { demodAM_DSB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_DSB, 1); } diff --git a/src/modules/modem/analog/ModemFM.cpp b/src/modules/modem/analog/ModemFM.cpp index 259fcfd..1e90ea4 100644 --- a/src/modules/modem/analog/ModemFM.cpp +++ b/src/modules/modem/analog/ModemFM.cpp @@ -1,6 +1,6 @@ #include "ModemFM.h" -ModemFM::ModemFM() { +ModemFM::ModemFM() : ModemAnalog() { demodFM = freqdem_create(0.5); } diff --git a/src/modules/modem/analog/ModemLSB.cpp b/src/modules/modem/analog/ModemLSB.cpp index d4d6ce8..3838f1d 100644 --- a/src/modules/modem/analog/ModemLSB.cpp +++ b/src/modules/modem/analog/ModemLSB.cpp @@ -1,6 +1,6 @@ #include "ModemLSB.h" -ModemLSB::ModemLSB() { +ModemLSB::ModemLSB() : ModemAnalog() { // half band filter used for side-band elimination ssbFilt = resamp2_crcf_create(12,-0.25f,60.0f); demodAM_LSB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_LSB, 1); diff --git a/src/modules/modem/analog/ModemUSB.cpp b/src/modules/modem/analog/ModemUSB.cpp index 780d44a..17392c5 100644 --- a/src/modules/modem/analog/ModemUSB.cpp +++ b/src/modules/modem/analog/ModemUSB.cpp @@ -1,6 +1,6 @@ #include "ModemUSB.h" -ModemUSB::ModemUSB() { +ModemUSB::ModemUSB() : ModemAnalog() { // half band filter used for side-band elimination ssbFilt = resamp2_crcf_create(12,-0.25f,60.0f); demodAM_USB = ampmodem_create(0.5, 0.0, LIQUID_AMPMODEM_USB, 1); diff --git a/src/modules/modem/digital/ModemAPSK.cpp b/src/modules/modem/digital/ModemAPSK.cpp index febd4fe..8d4ffc6 100644 --- a/src/modules/modem/digital/ModemAPSK.cpp +++ b/src/modules/modem/digital/ModemAPSK.cpp @@ -1,6 +1,6 @@ #include "ModemAPSK.h" -ModemAPSK::ModemAPSK() { +ModemAPSK::ModemAPSK() : ModemDigital() { demodAPSK4 = modem_create(LIQUID_MODEM_APSK4); demodAPSK8 = modem_create(LIQUID_MODEM_APSK8); demodAPSK16 = modem_create(LIQUID_MODEM_APSK16); diff --git a/src/modules/modem/digital/ModemASK.cpp b/src/modules/modem/digital/ModemASK.cpp index fb9adf4..f952a55 100644 --- a/src/modules/modem/digital/ModemASK.cpp +++ b/src/modules/modem/digital/ModemASK.cpp @@ -1,6 +1,6 @@ #include "ModemASK.h" -ModemASK::ModemASK() { +ModemASK::ModemASK() : ModemDigital() { demodASK2 = modem_create(LIQUID_MODEM_ASK2); demodASK4 = modem_create(LIQUID_MODEM_ASK4); demodASK8 = modem_create(LIQUID_MODEM_ASK8); diff --git a/src/modules/modem/digital/ModemBPSK.cpp b/src/modules/modem/digital/ModemBPSK.cpp index 6e2b3a1..bd82d88 100644 --- a/src/modules/modem/digital/ModemBPSK.cpp +++ b/src/modules/modem/digital/ModemBPSK.cpp @@ -1,6 +1,6 @@ #include "ModemBPSK.h" -ModemBPSK::ModemBPSK() { +ModemBPSK::ModemBPSK() : ModemDigital() { demodBPSK = modem_create(LIQUID_MODEM_BPSK); } diff --git a/src/modules/modem/digital/ModemDPSK.cpp b/src/modules/modem/digital/ModemDPSK.cpp index 9698e8c..13f5083 100644 --- a/src/modules/modem/digital/ModemDPSK.cpp +++ b/src/modules/modem/digital/ModemDPSK.cpp @@ -1,6 +1,6 @@ #include "ModemDPSK.h" -ModemDPSK::ModemDPSK() { +ModemDPSK::ModemDPSK() : ModemDigital() { demodDPSK2 = modem_create(LIQUID_MODEM_DPSK2); demodDPSK4 = modem_create(LIQUID_MODEM_DPSK4); demodDPSK8 = modem_create(LIQUID_MODEM_DPSK8); diff --git a/src/modules/modem/digital/ModemFSK.cpp b/src/modules/modem/digital/ModemFSK.cpp index f5b08fa..43b8180 100644 --- a/src/modules/modem/digital/ModemFSK.cpp +++ b/src/modules/modem/digital/ModemFSK.cpp @@ -1,9 +1,11 @@ #include "ModemFSK.h" +#include -ModemFSK::ModemFSK() { +ModemFSK::ModemFSK() : ModemDigital() { // DMR defaults? bps = 1; sps = 9600; + outStream << std::hex; } Modem *ModemFSK::factory() { @@ -35,6 +37,7 @@ ModemArgInfoList ModemFSK::getSettings() { bpsOpts.push_back("2"); bpsOpts.push_back("4"); bpsOpts.push_back("8"); + bpsOpts.push_back("16"); bpsArg.options = bpsOpts; args.push_back(bpsArg); @@ -48,6 +51,8 @@ ModemArgInfoList ModemFSK::getSettings() { std::vector spsOpts; // some common modem rates ..? + spsOpts.push_back("300"); + spsOpts.push_back("600"); spsOpts.push_back("1200"); spsOpts.push_back("2400"); spsOpts.push_back("4800"); @@ -117,12 +122,9 @@ void ModemFSK::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInput *a dkit->inputBuffer.insert(dkit->inputBuffer.end(),input->data.begin(),input->data.end()); while (dkit->inputBuffer.size() >= dkit->k) { - unsigned int sym_out; - - sym_out = fskdem_demodulate(dkit->demodFSK, &dkit->inputBuffer[0]); + outStream << fskdem_demodulate(dkit->demodFSK, &dkit->inputBuffer[0]); + // float err = fskdem_get_frequency_error(dkit->demodFSK); -// std::cout << "ferror: " << err << std::endl; - printf("%01X", sym_out); dkit->inputBuffer.erase(dkit->inputBuffer.begin(),dkit->inputBuffer.begin()+dkit->k); } diff --git a/src/modules/modem/digital/ModemFSK.h b/src/modules/modem/digital/ModemFSK.h index 2eab813..8f2e00b 100644 --- a/src/modules/modem/digital/ModemFSK.h +++ b/src/modules/modem/digital/ModemFSK.h @@ -1,5 +1,6 @@ #pragma once #include "ModemDigital.h" +#include class ModemKitFSK : public ModemKitDigital { public: diff --git a/src/modules/modem/digital/ModemOOK.cpp b/src/modules/modem/digital/ModemOOK.cpp index d0e92f9..7b5d54f 100644 --- a/src/modules/modem/digital/ModemOOK.cpp +++ b/src/modules/modem/digital/ModemOOK.cpp @@ -1,6 +1,6 @@ #include "ModemOOK.h" -ModemOOK::ModemOOK() { +ModemOOK::ModemOOK() : ModemDigital() { demodOOK = modem_create(LIQUID_MODEM_OOK); } diff --git a/src/modules/modem/digital/ModemPSK.cpp b/src/modules/modem/digital/ModemPSK.cpp index 1f33ff3..8789435 100644 --- a/src/modules/modem/digital/ModemPSK.cpp +++ b/src/modules/modem/digital/ModemPSK.cpp @@ -1,6 +1,6 @@ #include "ModemPSK.h" -ModemPSK::ModemPSK() { +ModemPSK::ModemPSK() : ModemDigital() { demodPSK2 = modem_create(LIQUID_MODEM_PSK2); demodPSK4 = modem_create(LIQUID_MODEM_PSK4); demodPSK8 = modem_create(LIQUID_MODEM_PSK8); diff --git a/src/modules/modem/digital/ModemQAM.cpp b/src/modules/modem/digital/ModemQAM.cpp index 63659a3..c593357 100644 --- a/src/modules/modem/digital/ModemQAM.cpp +++ b/src/modules/modem/digital/ModemQAM.cpp @@ -1,6 +1,6 @@ #include "ModemQAM.h" -ModemQAM::ModemQAM() { +ModemQAM::ModemQAM() : ModemDigital() { demodQAM4 = modem_create(LIQUID_MODEM_QAM4); demodQAM8 = modem_create(LIQUID_MODEM_QAM8); demodQAM16 = modem_create(LIQUID_MODEM_QAM16); diff --git a/src/modules/modem/digital/ModemQPSK.cpp b/src/modules/modem/digital/ModemQPSK.cpp index 98dfb7f..4754e78 100644 --- a/src/modules/modem/digital/ModemQPSK.cpp +++ b/src/modules/modem/digital/ModemQPSK.cpp @@ -1,6 +1,6 @@ #include "ModemQPSK.h" -ModemQPSK::ModemQPSK() { +ModemQPSK::ModemQPSK() : ModemDigital() { demodQPSK = modem_create(LIQUID_MODEM_QPSK); } diff --git a/src/modules/modem/digital/ModemSQAM.cpp b/src/modules/modem/digital/ModemSQAM.cpp index fbb8f47..f2ef57f 100644 --- a/src/modules/modem/digital/ModemSQAM.cpp +++ b/src/modules/modem/digital/ModemSQAM.cpp @@ -1,6 +1,6 @@ #include "ModemSQAM.h" -ModemSQAM::ModemSQAM() { +ModemSQAM::ModemSQAM() : ModemDigital() { demodSQAM32 = modem_create(LIQUID_MODEM_SQAM32); demodSQAM128 = modem_create(LIQUID_MODEM_SQAM128); demodSQAM = demodSQAM32; diff --git a/src/modules/modem/digital/ModemST.cpp b/src/modules/modem/digital/ModemST.cpp index 7adbe71..b827fc2 100644 --- a/src/modules/modem/digital/ModemST.cpp +++ b/src/modules/modem/digital/ModemST.cpp @@ -1,6 +1,6 @@ #include "ModemST.h" -ModemST::ModemST() { +ModemST::ModemST() : ModemDigital() { demodST = modem_create(LIQUID_MODEM_V29); }