From 5b4a3483063d61ac54b1639a5208fd0dfb5c805e Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 26 Jul 2016 19:25:39 -0400 Subject: [PATCH 1/5] Add FM Stereo De-emphasis setting --- src/modules/modem/analog/ModemFMStereo.cpp | 43 ++++++++++++++++++++++ src/modules/modem/analog/ModemFMStereo.h | 6 +++ 2 files changed, 49 insertions(+) diff --git a/src/modules/modem/analog/ModemFMStereo.cpp b/src/modules/modem/analog/ModemFMStereo.cpp index acc7078..7997553 100644 --- a/src/modules/modem/analog/ModemFMStereo.cpp +++ b/src/modules/modem/analog/ModemFMStereo.cpp @@ -2,6 +2,7 @@ ModemFMStereo::ModemFMStereo() { demodFM = freqdem_create(0.5); + _demph = 75; } ModemFMStereo::~ModemFMStereo() { @@ -34,6 +35,48 @@ int ModemFMStereo::getDefaultSampleRate() { return 200000; } +ModemArgInfoList ModemFMStereo::getSettings() { + ModemArgInfoList args; + + ModemArgInfo demphArg; + demphArg.key = "demph"; + demphArg.name = "De-emphasis"; + demphArg.value = std::to_string(_demph); + demphArg.description = "FM Stereo De-Emphasis, typically 75us in US/Canada, 50us elsewhere."; + + demphArg.type = ModemArgInfo::STRING; + + std::vector demphOptNames; + demphOptNames.push_back("None"); + demphOptNames.push_back("50μs"); + demphOptNames.push_back("75μs"); + demphArg.optionNames = demphOptNames; + + std::vector demphOpts; + demphOpts.push_back("0"); + demphOpts.push_back("50"); + demphOpts.push_back("75"); + demphArg.options = demphOpts; + + args.push_back(demphArg); + + return args; +} + +void ModemFMStereo::writeSetting(std::string setting, std::string value) { + if (setting == "demph") { + _demph = std::stoi(value); + rebuildKit(); + } +} + +std::string ModemFMStereo::readSetting(std::string setting) { + if (setting == "demph") { + return std::to_string(_demph); + } + return ""; +} + ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) { ModemKitFMStereo *kit = new ModemKitFMStereo; diff --git a/src/modules/modem/analog/ModemFMStereo.h b/src/modules/modem/analog/ModemFMStereo.h index 6cf9768..a198424 100644 --- a/src/modules/modem/analog/ModemFMStereo.h +++ b/src/modules/modem/analog/ModemFMStereo.h @@ -34,6 +34,10 @@ public: int checkSampleRate(long long sampleRate, int audioSampleRate); int getDefaultSampleRate(); + ModemArgInfoList getSettings(); + void writeSetting(std::string setting, std::string value); + std::string readSetting(std::string setting); + ModemKit *buildKit(long long sampleRate, int audioSampleRate); void disposeKit(ModemKit *kit); @@ -45,4 +49,6 @@ private: std::vector resampledOutputData; std::vector resampledStereoData; freqdem demodFM; + + int _demph; }; \ No newline at end of file From 604ce8cdf90cb49a0fbd592bcdd1e0ce86653040 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 26 Jul 2016 23:34:49 -0400 Subject: [PATCH 2/5] Experimental de-emphasis option for FM-Stereo --- src/modules/modem/analog/ModemFMStereo.cpp | 48 ++++++++++++++++++---- src/modules/modem/analog/ModemFMStereo.h | 6 ++- 2 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/modules/modem/analog/ModemFMStereo.cpp b/src/modules/modem/analog/ModemFMStereo.cpp index 7997553..c169c9d 100644 --- a/src/modules/modem/analog/ModemFMStereo.cpp +++ b/src/modules/modem/analog/ModemFMStereo.cpp @@ -48,8 +48,8 @@ ModemArgInfoList ModemFMStereo::getSettings() { std::vector demphOptNames; demphOptNames.push_back("None"); - demphOptNames.push_back("50μs"); - demphOptNames.push_back("75μs"); + demphOptNames.push_back("50us"); + demphOptNames.push_back("75us"); demphArg.optionNames = demphOptNames; std::vector demphOpts; @@ -130,6 +130,24 @@ ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) { nco_crcf_reset(kit->stereoPilot); nco_crcf_pll_set_bandwidth(kit->stereoPilot, 0.25f); + kit->demph = _demph; + + if (_demph) { + float f = (1.0 / (2.0 * M_PI * double(_demph) * 1e-6)); + float t = 1/(2* M_PI * f); + t = 1.0 / (2.0 * float(audioSampleRate) * tan(1.0 / (2.0 * float(audioSampleRate) * t))); + + float tb = (1.0f + 2.0f * t * float(audioSampleRate)); + float b_demph[2] = { 1.0f / tb, 1.0f / tb }; + float a_demph[2] = { 1.0f, (1.0f - 2.0f * t * float(audioSampleRate)) / tb }; + + kit->iirDemphL = iirfilt_rrrf_create(b_demph, 2, a_demph, 2); + kit->iirDemphR = iirfilt_rrrf_create(b_demph, 2, a_demph, 2); + } else { + kit->iirDemphL = nullptr; + kit->iirDemphR = nullptr; + kit->demph = 0; + } return kit; } @@ -143,6 +161,8 @@ void ModemFMStereo::disposeKit(ModemKit *kit) { firhilbf_destroy(fmkit->firStereoR2C); firhilbf_destroy(fmkit->firStereoC2R); nco_crcf_destroy(fmkit->stereoPilot); + if (fmkit->iirDemphR) { iirfilt_rrrf_destroy(fmkit->iirDemphR); } + if (fmkit->iirDemphL) { iirfilt_rrrf_destroy(fmkit->iirDemphL); } } @@ -232,12 +252,24 @@ void ModemFMStereo::demodulate(ModemKit *kit, ModemIQData *input, AudioThreadInp audioOut->data.resize(numAudioWritten * 2); for (size_t i = 0; i < numAudioWritten; i++) { float l, r; - - firfilt_rrrf_push(fmkit->firStereoLeft, 0.568f * (resampledOutputData[i] - (resampledStereoData[i]))); - firfilt_rrrf_execute(fmkit->firStereoLeft, &l); - - firfilt_rrrf_push(fmkit->firStereoRight, 0.568f * (resampledOutputData[i] + (resampledStereoData[i]))); - firfilt_rrrf_execute(fmkit->firStereoRight, &r); + float ld, rd; + + if (fmkit->demph) { + iirfilt_rrrf_execute(fmkit->iirDemphL, 0.568f * (resampledOutputData[i] - (resampledStereoData[i])), &ld); + iirfilt_rrrf_execute(fmkit->iirDemphR, 0.568f * (resampledOutputData[i] + (resampledStereoData[i])), &rd); + + firfilt_rrrf_push(fmkit->firStereoLeft, ld); + firfilt_rrrf_execute(fmkit->firStereoLeft, &l); + + firfilt_rrrf_push(fmkit->firStereoRight, rd); + firfilt_rrrf_execute(fmkit->firStereoRight, &r); + } else { + firfilt_rrrf_push(fmkit->firStereoLeft, 0.568f * (resampledOutputData[i] - (resampledStereoData[i]))); + firfilt_rrrf_execute(fmkit->firStereoLeft, &l); + + firfilt_rrrf_push(fmkit->firStereoRight, 0.568f * (resampledOutputData[i] + (resampledStereoData[i]))); + firfilt_rrrf_execute(fmkit->firStereoRight, &r); + } audioOut->data[i * 2] = l; audioOut->data[i * 2 + 1] = r; diff --git a/src/modules/modem/analog/ModemFMStereo.h b/src/modules/modem/analog/ModemFMStereo.h index a198424..ccba7dd 100644 --- a/src/modules/modem/analog/ModemFMStereo.h +++ b/src/modules/modem/analog/ModemFMStereo.h @@ -13,7 +13,11 @@ public: firfilt_rrrf firStereoLeft; firfilt_rrrf firStereoRight; iirfilt_crcf iirStereoPilot; - + + int demph; + iirfilt_rrrf iirDemphR; + iirfilt_rrrf iirDemphL; + firhilbf firStereoR2C; firhilbf firStereoC2R; From 0a80feece96656a16297611a4c116cc9aade8ab3 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 26 Jul 2016 23:47:31 -0400 Subject: [PATCH 3/5] Add some reasonable sounding intermediate steps betwen 50 and None --- src/modules/modem/analog/ModemFMStereo.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/modules/modem/analog/ModemFMStereo.cpp b/src/modules/modem/analog/ModemFMStereo.cpp index c169c9d..10bf567 100644 --- a/src/modules/modem/analog/ModemFMStereo.cpp +++ b/src/modules/modem/analog/ModemFMStereo.cpp @@ -48,12 +48,18 @@ ModemArgInfoList ModemFMStereo::getSettings() { std::vector demphOptNames; demphOptNames.push_back("None"); + demphOptNames.push_back("10us"); + demphOptNames.push_back("25us"); + demphOptNames.push_back("32us"); demphOptNames.push_back("50us"); demphOptNames.push_back("75us"); demphArg.optionNames = demphOptNames; std::vector demphOpts; demphOpts.push_back("0"); + demphOpts.push_back("10"); + demphOpts.push_back("25"); + demphOpts.push_back("32"); demphOpts.push_back("50"); demphOpts.push_back("75"); demphArg.options = demphOpts; From 91547475e532f8837d8841beae2a189bd2c5a520 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 27 Jul 2016 19:56:43 -0400 Subject: [PATCH 4/5] Make modem properties collapsable and add theme colors --- src/AppFrame.cpp | 14 +++++++++ src/ModemProperties.cpp | 66 ++++++++++++++++++++++++++++++++++++++--- src/ModemProperties.h | 10 +++++-- 3 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index c07a95e..02d2c5e 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -1003,6 +1003,7 @@ void AppFrame::OnMenu(wxCommandEvent& event) { waterfallSpeedMeter->Refresh(); spectrumAvgMeter->Refresh(); gainCanvas->setThemeColors(); + modemProps->updateTheme(); } switch (event.GetId()) { @@ -1498,6 +1499,7 @@ void AppFrame::OnIdle(wxIdleEvent& event) { modemProps->initProperties(demod->getModemArgs()); modemPropertiesUpdated.store(false); demodTray->Layout(); + modemProps->fitColumns(); #if ENABLE_DIGITAL_LAB if (demod->getModemType() == "digital") { ModemDigitalOutputConsole *outp = (ModemDigitalOutputConsole *)demod->getOutput(); @@ -1510,6 +1512,18 @@ void AppFrame::OnIdle(wxIdleEvent& event) { #endif } + if (modemProps->isCollapsed() && modemProps->GetMinWidth() > 22) { + modemProps->SetMinSize(wxSize(22,-1)); + modemProps->SetMaxSize(wxSize(22,-1)); + demodTray->Layout(); + modemProps->fitColumns(); + } else if (!modemProps->isCollapsed() && modemProps->GetMinWidth() < 200) { + modemProps->SetMinSize(wxSize(200,-1)); + modemProps->SetMaxSize(wxSize(200,-1)); + demodTray->Layout(); + modemProps->fitColumns(); + } + int peakHoldMode = peakHoldButton->getSelection(); if (peakHoldButton->modeChanged()) { wxGetApp().getSpectrumProcessor()->setPeakHold(peakHoldMode == 1); diff --git a/src/ModemProperties.cpp b/src/ModemProperties.cpp index bd0901b..981f479 100644 --- a/src/ModemProperties.cpp +++ b/src/ModemProperties.cpp @@ -4,24 +4,62 @@ 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); - + m_propertyGrid = new wxPropertyGrid(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxPG_DEFAULT_STYLE | wxPG_NO_INTERNAL_BORDER); + bSizer = new wxBoxSizer( wxVERTICAL ); - bSizer->Add(m_propertyGrid, 1, wxEXPAND, 5); + bSizer->Add(m_propertyGrid, 1, wxEXPAND, 0); this->SetSizer(bSizer); + m_propertyGrid->Connect( wxEVT_PG_ITEM_COLLAPSED, wxPropertyGridEventHandler( ModemProperties::OnCollapse ), NULL, this ); + m_propertyGrid->Connect( wxEVT_PG_ITEM_EXPANDED, wxPropertyGridEventHandler( ModemProperties::OnExpand ), NULL, this ); m_propertyGrid->Connect( wxEVT_PG_CHANGED, wxPropertyGridEventHandler( ModemProperties::OnChange ), NULL, this ); this->Connect( wxEVT_SHOW, wxShowEventHandler( ModemProperties::OnShow ), NULL, this ); this->Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( ModemProperties::OnMouseEnter ), NULL, this); this->Connect( wxEVT_LEAVE_WINDOW, wxMouseEventHandler( ModemProperties::OnMouseLeave ), NULL, this); - + + updateTheme(); + mouseInView = false; + collapsed = false; } void ModemProperties::OnShow(wxShowEvent & /* event */) { + updateTheme(); +} + +void ModemProperties::updateTheme() { + wxColour bgColor( + (unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.r * 255.0), + (unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.g * 255.0), + (unsigned char) (ThemeMgr::mgr.currentTheme->generalBackground.b * 255.0)); + + wxColour textColor( + (unsigned char) (ThemeMgr::mgr.currentTheme->text.r * 255.0), + (unsigned char) (ThemeMgr::mgr.currentTheme->text.g * 255.0), + (unsigned char) (ThemeMgr::mgr.currentTheme->text.b * 255.0)); + + wxColour btn( + (unsigned char) (ThemeMgr::mgr.currentTheme->button.r * 255.0), + (unsigned char) (ThemeMgr::mgr.currentTheme->button.g * 255.0), + (unsigned char) (ThemeMgr::mgr.currentTheme->button.b * 255.0)); + + wxColour btnHl( + (unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.r * 255.0), + (unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.g * 255.0), + (unsigned char) (ThemeMgr::mgr.currentTheme->buttonHighlight.b * 255.0)); + + + m_propertyGrid->SetEmptySpaceColour(bgColor); + m_propertyGrid->SetCellBackgroundColour(bgColor); + m_propertyGrid->SetCellTextColour(textColor); + m_propertyGrid->SetSelectionTextColour(bgColor); + m_propertyGrid->SetSelectionBackgroundColour(btnHl); + m_propertyGrid->SetCaptionTextColour(bgColor); + m_propertyGrid->SetCaptionBackgroundColour(btn); + m_propertyGrid->SetLineColour(btn); } ModemProperties::~ModemProperties() { @@ -51,6 +89,10 @@ void ModemProperties::initProperties(ModemArgInfoList newArgs) { } m_propertyGrid->FitColumns(); + + if (collapsed) { + m_propertyGrid->CollapseAll(); + } } wxPGProperty *ModemProperties::addArgInfoProperty(wxPropertyGrid *pg, ModemArgInfo arg) { @@ -166,6 +208,14 @@ void ModemProperties::OnChange(wxPropertyGridEvent &event) { } } +void ModemProperties::OnCollapse(wxPropertyGridEvent &event) { + collapsed = true; +} + +void ModemProperties::OnExpand(wxPropertyGridEvent &event) { + collapsed = false; +} + void ModemProperties::OnMouseEnter(wxMouseEvent & /* event */) { mouseInView = true; } @@ -177,3 +227,11 @@ void ModemProperties::OnMouseLeave(wxMouseEvent & /* event */) { bool ModemProperties::isMouseInView() { return mouseInView || (m_propertyGrid && m_propertyGrid->IsEditorFocused()); } + +bool ModemProperties::isCollapsed() { + return collapsed; +} + +void ModemProperties::fitColumns() { + m_propertyGrid->FitColumns(); +} diff --git a/src/ModemProperties.h b/src/ModemProperties.h index 326c947..2f1efc9 100644 --- a/src/ModemProperties.h +++ b/src/ModemProperties.h @@ -21,12 +21,18 @@ public: void initProperties(ModemArgInfoList newArgs); bool isMouseInView(); - + bool isCollapsed(); + void fitColumns(); + + void updateTheme(); + private: wxPGProperty *addArgInfoProperty(wxPropertyGrid *pg, ModemArgInfo arg); std::string readProperty(std::string); void OnChange(wxPropertyGridEvent &event); void OnShow(wxShowEvent &event); + void OnCollapse(wxPropertyGridEvent &event); + void OnExpand(wxPropertyGridEvent &event); void OnMouseEnter(wxMouseEvent &event); void OnMouseLeave(wxMouseEvent &event); @@ -35,5 +41,5 @@ private: wxPropertyGrid* m_propertyGrid; ModemArgInfoList args; std::map props; - bool mouseInView; + bool mouseInView, collapsed; }; \ No newline at end of file From 0fdb970d2c528f615884de878653491e4225db56 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Wed, 27 Jul 2016 20:01:37 -0400 Subject: [PATCH 5/5] Cleanup --- src/modules/modem/analog/ModemFMStereo.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/modem/analog/ModemFMStereo.cpp b/src/modules/modem/analog/ModemFMStereo.cpp index 10bf567..f98fa21 100644 --- a/src/modules/modem/analog/ModemFMStereo.cpp +++ b/src/modules/modem/analog/ModemFMStereo.cpp @@ -139,9 +139,9 @@ ModemKit *ModemFMStereo::buildKit(long long sampleRate, int audioSampleRate) { kit->demph = _demph; if (_demph) { - float f = (1.0 / (2.0 * M_PI * double(_demph) * 1e-6)); - float t = 1/(2* M_PI * f); - t = 1.0 / (2.0 * float(audioSampleRate) * tan(1.0 / (2.0 * float(audioSampleRate) * t))); + float f = (1.0f / (2.0f * M_PI * double(_demph) * 1e-6)); + float t = 1.0f / (2.0f * M_PI * f); + t = 1.0f / (2.0f * float(audioSampleRate) * tan(1.0f / (2.0f * float(audioSampleRate) * t))); float tb = (1.0f + 2.0f * t * float(audioSampleRate)); float b_demph[2] = { 1.0f / tb, 1.0f / tb };