Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add monitor volume adjustment #733

Merged
merged 11 commits into from
Jul 14, 2024
1 change: 1 addition & 0 deletions USER_MANUAL.md
Original file line number Diff line number Diff line change
Expand Up @@ -896,6 +896,7 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
2. Enhancements:
* Show green line indicating RX frequency. (PR #725)
* Update configuration of the Voice Keyer feature based on user feedback. (PR #730)
* Add monitor volume adjustment. (PR #733)
3. Build system:
* Allow overrriding the version tag when building. (PR #727)
* Update wxWidgets to 3.2.5. (PR #731)
Expand Down
6 changes: 6 additions & 0 deletions src/config/FreeDVConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ FreeDVConfiguration::FreeDVConfiguration()
, tabLayout("/MainFrame/TabLayout", _(""))

, monitorVoiceKeyerAudio("/Monitor/VoiceKeyerAudio", false)
, monitorVoiceKeyerAudioVol("/Monitor/VoiceKeyerAudioVol", 0)
, monitorTxAudio("/Monitor/TransmitAudio", false)
, monitorTxAudioVol("/Monitor/TransmitAudioVol", 0)

, txRxDelayMilliseconds("/Audio/TxRxDelayMilliseconds", 0)

Expand Down Expand Up @@ -220,6 +222,8 @@ void FreeDVConfiguration::load(wxConfigBase* config)

load_(config, monitorVoiceKeyerAudio);
load_(config, monitorTxAudio);
load_(config, monitorVoiceKeyerAudioVol);
load_(config, monitorTxAudioVol);

quickRecordPath.setDefaultVal(documentsDir);
load_(config, quickRecordPath);
Expand Down Expand Up @@ -312,6 +316,8 @@ void FreeDVConfiguration::save(wxConfigBase* config)

save_(config, monitorVoiceKeyerAudio);
save_(config, monitorTxAudio);
save_(config, monitorVoiceKeyerAudioVol);
save_(config, monitorTxAudioVol);

save_(config, txRxDelayMilliseconds);

Expand Down
2 changes: 2 additions & 0 deletions src/config/FreeDVConfiguration.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ class FreeDVConfiguration : public WxWidgetsConfigStore
ConfigurationDataElement<wxString> tabLayout;

ConfigurationDataElement<bool> monitorVoiceKeyerAudio;
ConfigurationDataElement<float> monitorVoiceKeyerAudioVol;
ConfigurationDataElement<bool> monitorTxAudio;
ConfigurationDataElement<float> monitorTxAudioVol;

ConfigurationDataElement<int> txRxDelayMilliseconds;

Expand Down
3 changes: 2 additions & 1 deletion src/gui/dialogs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ add_library(fdv_gui_dialogs STATIC
dlg_filter.cpp
dlg_options.cpp
dlg_ptt.cpp
freedv_reporter.cpp)
freedv_reporter.cpp
monitor_volume_adj.cpp)

target_include_directories(fdv_gui_dialogs PRIVATE ${CODEC2_INCLUDE_DIRS} ${CMAKE_CURRENT_SOURCE_DIR}/../.. ${CMAKE_CURRENT_BINARY_DIR}/../..)

Expand Down
59 changes: 59 additions & 0 deletions src/gui/dialogs/monitor_volume_adj.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//==========================================================================
// Name: monitor_volume_adj.cpp
// Purpose: Popup to allow adjustment of monitor volume
// Created: Jul 12, 2024
// Authors: Mooneer Salem
//
// License:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.1,
// as published by the Free Software Foundation. This program is
// distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//
//==========================================================================

#include <wx/stattext.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/statbox.h>

#include "monitor_volume_adj.h"

MonitorVolumeAdjPopup::MonitorVolumeAdjPopup( wxWindow* parent, ConfigurationDataElement<float>& configVal )
: wxPopupTransientWindow(parent)
, configVal_(configVal)
{
wxStaticBoxSizer* mainSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Monitor volume (dB)"));

volumeSlider_ = new wxSlider(mainSizer->GetStaticBox(), wxID_ANY, configVal, -40, 0, wxDefaultPosition, wxSize(250, -1), wxSL_AUTOTICKS | wxSL_LABELS);
mainSizer->Add(volumeSlider_, 0, wxALL | wxEXPAND, 2);

SetSizerAndFit(mainSizer);
Layout();

// Link event handlers
volumeSlider_->Connect(wxEVT_SLIDER, wxCommandEventHandler(MonitorVolumeAdjPopup::OnSliderAdjusted), NULL, this);

// Make popup show up to the left of (and above) mouse cursor position
wxPoint pt = wxGetMousePosition();
wxSize sz = GetSize();
pt -= wxPoint(sz.GetWidth(), sz.GetHeight());
SetPosition( pt );
}

MonitorVolumeAdjPopup::~MonitorVolumeAdjPopup()
{
volumeSlider_->Disconnect(wxEVT_SLIDER, wxCommandEventHandler(MonitorVolumeAdjPopup::OnSliderAdjusted), NULL, this);
}

void MonitorVolumeAdjPopup::OnSliderAdjusted(wxCommandEvent& event)
{
configVal_ = volumeSlider_->GetValue();
}
47 changes: 47 additions & 0 deletions src/gui/dialogs/monitor_volume_adj.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//==========================================================================
// Name: monitor_volume_adj.h
// Purpose: Popup to allow adjustment of monitor volume
// Created: Jul 12, 2024
// Authors: Mooneer Salem
//
// License:
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2.1,
// as published by the Free Software Foundation. This program is
// distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, see <http://www.gnu.org/licenses/>.
//
//==========================================================================

#ifndef __MONITOR_VOLUME_ADJ__
#define __MONITOR_VOLUME_ADJ__

#include <wx/popupwin.h>
#include <wx/slider.h>

#include "config/ConfigurationDataElement.h"

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
// Class MonitorVolumeAdjPopup
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
class MonitorVolumeAdjPopup : public wxPopupTransientWindow
{
public:
MonitorVolumeAdjPopup( wxWindow* parent, ConfigurationDataElement<float>& configVal );
~MonitorVolumeAdjPopup();

protected:
void OnSliderAdjusted(wxCommandEvent& event);

private:
wxSlider* volumeSlider_;
ConfigurationDataElement<float>& configVal_;
};

#endif // __MONITOR_VOLUME_ADJ__
26 changes: 22 additions & 4 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,16 +760,16 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent, wxID_ANY, _("FreeDV ")
voiceKeyerPopupMenu_ = new wxMenu();
assert(voiceKeyerPopupMenu_ != nullptr);

auto chooseVKFileMenuItem = voiceKeyerPopupMenu_->Append(wxID_ANY, _("&Use another voice keyer file..."));
chooseVKFileMenuItem_ = voiceKeyerPopupMenu_->Append(wxID_ANY, _("&Use another voice keyer file..."));
voiceKeyerPopupMenu_->Connect(
chooseVKFileMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED,
chooseVKFileMenuItem_->GetId(), wxEVT_COMMAND_MENU_SELECTED,
wxCommandEventHandler(MainFrame::OnChooseAlternateVoiceKeyerFile),
NULL,
this);

auto recordNewVoiceKeyerFileMenuItem = voiceKeyerPopupMenu_->Append(wxID_ANY, _("&Record new voice keyer file..."));
recordNewVoiceKeyerFileMenuItem_ = voiceKeyerPopupMenu_->Append(wxID_ANY, _("&Record new voice keyer file..."));
voiceKeyerPopupMenu_->Connect(
recordNewVoiceKeyerFileMenuItem->GetId(), wxEVT_COMMAND_MENU_SELECTED,
recordNewVoiceKeyerFileMenuItem_->GetId(), wxEVT_COMMAND_MENU_SELECTED,
wxCommandEventHandler(MainFrame::OnRecordNewVoiceKeyerFile),
NULL,
this);
Expand All @@ -784,6 +784,15 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent, wxID_ANY, _("FreeDV ")
NULL,
this);

adjustMonitorVKVolMenuItem_ = voiceKeyerPopupMenu_->Append(wxID_ANY, _("Adjust Monitor Volume..."));
adjustMonitorVKVolMenuItem_->Enable(wxGetApp().appConfiguration.monitorVoiceKeyerAudio);
voiceKeyerPopupMenu_->Connect(
adjustMonitorVKVolMenuItem_->GetId(), wxEVT_COMMAND_MENU_SELECTED,
wxCommandEventHandler(MainFrame::OnSetMonitorVKAudioVol),
NULL,
this
);

// Create PTT popup menu
pttPopupMenu_ = new wxMenu();
assert(pttPopupMenu_ != nullptr);
Expand All @@ -795,6 +804,15 @@ MainFrame::MainFrame(wxWindow *parent) : TopFrame(parent, wxID_ANY, _("FreeDV ")
wxCommandEventHandler(MainFrame::OnSetMonitorTxAudio),
NULL,
this);

adjustMonitorPttVolMenuItem_ = pttPopupMenu_->Append(wxID_ANY, _("Adjust Monitor Volume..."));
adjustMonitorPttVolMenuItem_->Enable(wxGetApp().appConfiguration.monitorTxAudio);
pttPopupMenu_->Connect(
adjustMonitorPttVolMenuItem_->GetId(), wxEVT_COMMAND_MENU_SELECTED,
wxCommandEventHandler(MainFrame::OnSetMonitorTxAudioVol),
NULL,
this
);

m_RxRunning = false;

Expand Down
7 changes: 7 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,9 @@ class MainFrame : public TopFrame
void OnSetMonitorVKAudio( wxCommandEvent& event );
void OnSetMonitorTxAudio( wxCommandEvent& event );

void OnSetMonitorVKAudioVol( wxCommandEvent& event );
void OnSetMonitorTxAudioVol( wxCommandEvent& event );

private:
std::shared_ptr<IAudioDevice> rxInSoundDevice;
std::shared_ptr<IAudioDevice> rxOutSoundDevice;
Expand Down Expand Up @@ -480,6 +483,10 @@ class MainFrame : public TopFrame

wxMenu* voiceKeyerPopupMenu_;
wxMenu* pttPopupMenu_;
wxMenuItem* adjustMonitorPttVolMenuItem_;
wxMenuItem* adjustMonitorVKVolMenuItem_;
wxMenuItem* chooseVKFileMenuItem_;
wxMenuItem* recordNewVoiceKeyerFileMenuItem_;

int getSoundCardIDFromName(wxString& name, bool input);
bool validateSoundCardSetup();
Expand Down
8 changes: 8 additions & 0 deletions src/ongui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "gui/dialogs/dlg_options.h"
#include "gui/dialogs/dlg_ptt.h"
#include "gui/dialogs/freedv_reporter.h"
#include "gui/dialogs/monitor_volume_adj.h"

#if defined(WIN32)
#include "rig_control/omnirig/OmniRigController.h"
Expand Down Expand Up @@ -836,6 +837,13 @@ int MainApp::FilterEvent(wxEvent& event)
void MainFrame::OnSetMonitorTxAudio( wxCommandEvent& event )
{
wxGetApp().appConfiguration.monitorTxAudio = event.IsChecked();
adjustMonitorPttVolMenuItem_->Enable(wxGetApp().appConfiguration.monitorTxAudio);
}

void MainFrame::OnSetMonitorTxAudioVol( wxCommandEvent& event )
{
auto popup = new MonitorVolumeAdjPopup(this, wxGetApp().appConfiguration.monitorTxAudioVol);
popup->Popup();
}

//-------------------------------------------------------------------------
Expand Down
15 changes: 15 additions & 0 deletions src/pipeline/TxRxThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,21 @@ void TxRxThread::initializePipeline_()

auto monitorPipeline = new AudioPipeline(inputSampleRate_, outputSampleRate_);
monitorPipeline->appendPipelineStep(equalizedMicAudioLink_->getOutputPipelineStep());

auto monitorLevelStep = std::make_shared<LevelAdjustStep>(outputSampleRate_, [&]() {
double volInDb = 0;
if (g_voice_keyer_tx && wxGetApp().appConfiguration.monitorVoiceKeyerAudio)
{
volInDb = wxGetApp().appConfiguration.monitorVoiceKeyerAudioVol;
}
else
{
volInDb = wxGetApp().appConfiguration.monitorTxAudioVol;
}

return std::exp(volInDb/20.0f * std::log(10.0f));
});
monitorPipeline->appendPipelineStep(monitorLevelStep);

auto muteStep = new MuteStep(outputSampleRate_);

Expand Down
24 changes: 18 additions & 6 deletions src/voicekeyer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

#include "main.h"
#include "gui/dialogs/monitor_volume_adj.h"

extern SNDFILE *g_sfRecMicFile;
bool g_recVoiceKeyerFile;
Expand Down Expand Up @@ -157,17 +158,28 @@ void MainFrame::OnChooseAlternateVoiceKeyerFile( wxCommandEvent& event )

void MainFrame::OnTogBtnVoiceKeyerRightClick( wxContextMenuEvent& event )
{
// Only handle right-click if idle
if (vk_state == VK_IDLE && !m_btnTogPTT->GetValue())
{
auto sz = m_togBtnVoiceKeyer->GetSize();
m_togBtnVoiceKeyer->PopupMenu(voiceKeyerPopupMenu_, wxPoint(-sz.GetWidth() - 25, 0));
}
// Only enable VK file selection on idle
bool enabled = vk_state == VK_IDLE && !m_btnTogPTT->GetValue();
chooseVKFileMenuItem_->Enable(enabled);
recordNewVoiceKeyerFileMenuItem_->Enable(enabled);

// Trigger right-click menu popup in a location that will prevent it from
// ending up off the screen.
auto sz = m_togBtnVoiceKeyer->GetSize();
m_togBtnVoiceKeyer->PopupMenu(voiceKeyerPopupMenu_, wxPoint(-sz.GetWidth() - 25, 0));
}

void MainFrame::OnSetMonitorVKAudio( wxCommandEvent& event )
{
wxGetApp().appConfiguration.monitorVoiceKeyerAudio = event.IsChecked();
adjustMonitorVKVolMenuItem_->Enable(wxGetApp().appConfiguration.monitorVoiceKeyerAudio);

}

void MainFrame::OnSetMonitorVKAudioVol( wxCommandEvent& event )
{
auto popup = new MonitorVolumeAdjPopup(this, wxGetApp().appConfiguration.monitorVoiceKeyerAudioVol);
popup->Popup();
}

extern SNDFILE *g_sfPlayFile;
Expand Down
Loading