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 volume controls for mic in/speaker out #208

Merged
merged 26 commits into from
Feb 5, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
d5718ab
Import vol effect from parent sox library.
tmiw Jan 21, 2022
dc5f084
Tie in vol effect to main processing loop.
tmiw Jan 21, 2022
0cc2444
Add initial GUI for volume effect.
tmiw Jan 21, 2022
1d01908
Update sox library to latest.
tmiw Jan 21, 2022
4bdabc7
sox 'vol' effect can be a no-op, unlike the others FreeDV uses.
tmiw Jan 21, 2022
0c446df
Fix typo preventing volumes from loading properly.
tmiw Jan 21, 2022
6c64967
Avoid crash due to vol using a different flow function.
tmiw Jan 21, 2022
18a909c
Allow gain values < 1 for the 'vol' effect.
tmiw Jan 21, 2022
b78e0db
Reenable use of vol as part of filter graphs.
tmiw Jan 22, 2022
1d8de82
Place EQ controls inside auiNotebook.
tmiw Jan 23, 2022
fe8381b
Use vertical sliders for equalizer controls to ensure visual consiste…
tmiw Jan 23, 2022
41c1934
Additional cleanup of beta/gamma controls to save horizontal space.
tmiw Jan 23, 2022
973cbe0
Invert slider direction
tmiw Jan 23, 2022
b70d54a
Adjust text label alignment.
tmiw Jan 23, 2022
120ffa4
Adjust font and spacing for equalizer controls.
tmiw Jan 25, 2022
cd6e4b6
Allow EQ plots to resize when window is resized.
tmiw Jan 26, 2022
2e6b8f7
Each EQ box should take equal space.
tmiw Jan 26, 2022
ab505dd
Fix assertions with wxWidgets 3.1.
tmiw Jan 26, 2022
401479d
Consolidate OK/Cancel into single Close button.
tmiw Jan 26, 2022
7aaaca2
Make filter dialog non-modal.
tmiw Jan 26, 2022
e173130
Avoid showing more than one FilterDlg at a time.
tmiw Jan 26, 2022
892d666
Expand EQ boxes on window resize.
tmiw Jan 26, 2022
8944f46
fix signed-unsigned warning
drowe67 Jan 26, 2022
bfb67a1
Use default font for tabs.
tmiw Jan 27, 2022
22b204d
Move Enable/Default UI for EQ to the left.
tmiw Jan 29, 2022
4f2ff35
Merge branch 'master' into ms-filter-volume
tmiw Feb 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,17 @@ set(FREEDV_SOURCES
sox/effects.c
sox/effects.h
sox/effects_i.c
sox/effects_i_dsp.c
sox/fft4g.c
sox/formats.c
sox/formats_i.c
sox/libsox.c
sox/sox.h
sox/sox_i.h
sox/soxomp.h
sox/util.c
sox/util.h
sox/vol.c
sox/xmalloc.h
sox/xmalloc.c
topFrame.h
Expand Down
362 changes: 227 additions & 135 deletions src/dlg_filter.cpp

Large diffs are not rendered by default.

43 changes: 15 additions & 28 deletions src/dlg_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@

#include "main.h"

enum {disableQ = false, enableQ = true};
enum {disableQ = false, enableQ = true, disableFreq = false, enableFreq = true};

typedef struct {
wxStaticBox *eqBox;
wxSlider *sliderFreq;
wxStaticText *valueFreq;
wxSlider *sliderGain;
Expand All @@ -45,24 +46,6 @@ typedef struct {
float maxFreqHz;
} EQ;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
// Class AuiNotebookNoKbd
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
class AuiNotebookNoKbd : public wxNotebook
{
// This class inherits from wxNotebook, and the only difference between
// it and the wx notebook is functionality to ignore tabbing to it. This
// is a control with no user input, thus blind hams have no reason to tab
// to it.
public:

AuiNotebookNoKbd(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition,
const wxSize &size=wxDefaultSize, long style=0) :
wxNotebook(parent, id, pos, size, style) {;}

bool AcceptsFocusFromKeyboard() const { return false; }
};

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
// Class FilterDlg
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
Expand All @@ -72,14 +55,13 @@ class FilterDlg : public wxDialog
FilterDlg( wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
wxWindowID id = wxID_ANY, const wxString& title = _("Filter"),
const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
long style = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER );
~FilterDlg();

void ExchangeData(int inout, bool storePersistent);
void ExchangeData(int inout);

protected:
// Handlers for events.
void OnCancel(wxCommandEvent& event);
void OnOK(wxCommandEvent& event);
void OnClose(wxCloseEvent& event);
void OnInitDialog(wxInitDialogEvent& event);
Expand All @@ -100,6 +82,8 @@ class FilterDlg : public wxDialog
void OnMicInMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_MicInMid, true); }
void OnMicInMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInMid, true); }
void OnMicInMidQScroll(wxScrollEvent& event) { sliderToQ(&m_MicInMid, true); }
void OnMicInVolGainScroll(wxScrollEvent& event) { sliderToGain(&m_MicInVol, true); }

void OnMicInEnable(wxScrollEvent& event);
void OnMicInDefault(wxCommandEvent& event);

Expand All @@ -110,6 +94,8 @@ class FilterDlg : public wxDialog
void OnSpkOutMidFreqScroll(wxScrollEvent& event) { sliderToFreq(&m_SpkOutMid, false); }
void OnSpkOutMidGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutMid, false); }
void OnSpkOutMidQScroll(wxScrollEvent& event) { sliderToQ(&m_SpkOutMid, false); }
void OnSpkOutVolGainScroll(wxScrollEvent& event) { sliderToGain(&m_SpkOutVol, false); }

void OnSpkOutEnable(wxScrollEvent& event);
void OnSpkOutDefault(wxCommandEvent& event);

Expand All @@ -130,7 +116,6 @@ class FilterDlg : public wxDialog

wxStdDialogButtonSizer* m_sdbSizer5;
wxButton* m_sdbSizer5OK;
wxButton* m_sdbSizer5Cancel;
PlotSpectrum* m_MicInFreqRespPlot;
PlotSpectrum* m_SpkOutFreqRespPlot;

Expand All @@ -151,17 +136,17 @@ class FilterDlg : public wxDialog
void setGamma(void); // sets slider and static text from m_gamma
void setCodec2(void);

void newEQControl(wxSlider** slider, wxStaticText** value, wxStaticBoxSizer *bs, wxString controlName);
EQ newEQ(wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ);
void newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxSizer *sbs, wxString controlName);
AuiNotebookNoKbd *m_auiNotebook;
void newEQControl(wxWindow* parent, wxSlider** slider, wxStaticText** value, wxSizer *sizer, wxString controlName);
EQ newEQ(wxWindow* parent, wxSizer *bs, wxString eqName, float maxFreqHz, bool enableQ, bool enableFreq);
void newLPCPFControl(wxSlider **slider, wxStaticText **stValue, wxWindow* parent, wxSizer *sbs, wxString controlName);
wxNotebook *m_auiNotebook;
void setFreq(EQ *eq);
void setGain(EQ *eq);
void setQ(EQ *eq);
void sliderToFreq(EQ *eq, bool micIn);
void sliderToGain(EQ *eq, bool micIn);
void sliderToQ(EQ *eq, bool micIn);
void plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ* eqTreble, PlotSpectrum* freqRespPlot, float *magdB);
void plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ* eqTreble, EQ* eqVol, PlotSpectrum* freqRespPlot, float *magdB);
void calcFilterSpectrum(float magdB[], int arc, char *argv[]);
void plotMicInFilterSpectrum(void);
void plotSpkOutFilterSpectrum(void);
Expand All @@ -171,10 +156,12 @@ class FilterDlg : public wxDialog
EQ m_MicInBass;
EQ m_MicInMid;
EQ m_MicInTreble;
EQ m_MicInVol;

EQ m_SpkOutBass;
EQ m_SpkOutMid;
EQ m_SpkOutTreble;
EQ m_SpkOutVol;

float limit(float value, float min, float max);

Expand Down
32 changes: 26 additions & 6 deletions src/eq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ void *MainFrame::designAnEQFilter(const char filterType[], float freqHz, float g
{
char *arg[SBQ_MAX_ARGS];
char argstorage[SBQ_MAX_ARGS][80];
void *sbq;
int i, argc;

assert((strcmp(filterType, "bass") == 0) ||
(strcmp(filterType, "treble") == 0) ||
(strcmp(filterType, "equalizer") == 0));
(strcmp(filterType, "equalizer") == 0) ||
(strcmp(filterType, "vol") == 0));

for(i=0; i<SBQ_MAX_ARGS; i++) {
arg[i] = &argstorage[i][0];
Expand All @@ -39,13 +39,19 @@ void *MainFrame::designAnEQFilter(const char filterType[], float freqHz, float g
sprintf(arg[argc++], "%f", gaindB+1E-6);
sprintf(arg[argc++], "%d", sampleRate);
}

if (strcmp(filterType, "vol") == 0)
{
sprintf(arg[argc++], "%s", filterType);
sprintf(arg[argc++], "%f", gaindB);
sprintf(arg[argc++], "%s", "dB");
sprintf(arg[argc++], "%f", 0.05); // to prevent clipping
sprintf(arg[argc++], "%d", sampleRate);
}

assert(argc <= SBQ_MAX_ARGS);
// Note - the argc count doesn't include the command!
sbq = sox_biquad_create(argc-1, (const char **)arg);
assert(sbq != NULL);

return sbq;
return sox_biquad_create(argc-1, (const char **)arg);
}

void MainFrame::designEQFilters(paCallBackData *cb, int rxSampleRate, int txSampleRate)
Expand All @@ -57,6 +63,10 @@ void MainFrame::designEQFilters(paCallBackData *cb, int rxSampleRate, int txSam
cb->sbqMicInBass = designAnEQFilter("bass", wxGetApp().m_MicInBassFreqHz, wxGetApp().m_MicInBassGaindB, txSampleRate);
cb->sbqMicInTreble = designAnEQFilter("treble", wxGetApp().m_MicInTrebleFreqHz, wxGetApp().m_MicInTrebleGaindB, txSampleRate);
cb->sbqMicInMid = designAnEQFilter("equalizer", wxGetApp().m_MicInMidFreqHz, wxGetApp().m_MicInMidGaindB, wxGetApp().m_MicInMidQ, txSampleRate);
cb->sbqMicInVol = designAnEQFilter("vol", 0, wxGetApp().m_MicInVolInDB, 0, txSampleRate);

// Note: vol can be a no-op!
assert(cb->sbqMicInBass != nullptr && cb->sbqMicInTreble != nullptr && cb->sbqMicInMid != nullptr);
}

// init Spk Out Equaliser Filters
Expand All @@ -68,6 +78,10 @@ void MainFrame::designEQFilters(paCallBackData *cb, int rxSampleRate, int txSam
cb->sbqSpkOutBass = designAnEQFilter("bass", wxGetApp().m_SpkOutBassFreqHz, wxGetApp().m_SpkOutBassGaindB, rxSampleRate);
cb->sbqSpkOutTreble = designAnEQFilter("treble", wxGetApp().m_SpkOutTrebleFreqHz, wxGetApp().m_SpkOutTrebleGaindB, rxSampleRate);
cb->sbqSpkOutMid = designAnEQFilter("equalizer", wxGetApp().m_SpkOutMidFreqHz, wxGetApp().m_SpkOutMidGaindB, wxGetApp().m_SpkOutMidQ, rxSampleRate);
cb->sbqSpkOutVol = designAnEQFilter("vol", 0, wxGetApp().m_SpkOutVolInDB, 0, txSampleRate);

// Note: vol can be a no-op!
assert(cb->sbqSpkOutBass != nullptr && cb->sbqSpkOutTreble != nullptr && cb->sbqSpkOutMid != nullptr);
}

m_newMicInFilter = false;
Expand All @@ -84,9 +98,12 @@ void MainFrame::deleteEQFilters(paCallBackData *cb)
sox_biquad_destroy(cb->sbqMicInTreble);
sox_biquad_destroy(cb->sbqMicInMid);

if (cb->sbqMicInVol) sox_biquad_destroy(cb->sbqMicInVol);

cb->sbqMicInBass = nullptr;
cb->sbqMicInTreble = nullptr;
cb->sbqMicInMid = nullptr;
cb->sbqMicInVol = nullptr;
}

if (m_newSpkOutFilter)
Expand All @@ -96,10 +113,13 @@ void MainFrame::deleteEQFilters(paCallBackData *cb)
sox_biquad_destroy(cb->sbqSpkOutBass);
sox_biquad_destroy(cb->sbqSpkOutTreble);
sox_biquad_destroy(cb->sbqSpkOutMid);

if (cb->sbqSpkOutVol) sox_biquad_destroy(cb->sbqSpkOutVol);

cb->sbqSpkOutBass = nullptr;
cb->sbqSpkOutTreble = nullptr;
cb->sbqSpkOutMid = nullptr;
cb->sbqSpkOutVol = nullptr;
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ void MainFrame::loadConfiguration_()
wxGetApp().m_MicInMidFreqHz = (float)pConfig->Read(wxT("/Filter/MicInMidFreqHz"), 1);
wxGetApp().m_MicInMidGaindB = (float)pConfig->Read(wxT("/Filter/MicInMidGaindB"), (long)0)/10.0;
wxGetApp().m_MicInMidQ = (float)pConfig->Read(wxT("/Filter/MicInMidQ"), (long)100)/100.0;
wxGetApp().m_MicInVolInDB = (float)pConfig->Read(wxT("/Filter/MicInVolInDB"), (long)0)/10.0;

bool f = false;
wxGetApp().m_MicInEQEnable = (float)pConfig->Read(wxT("/Filter/MicInEQEnable"), f);
Expand All @@ -383,6 +384,7 @@ void MainFrame::loadConfiguration_()
wxGetApp().m_SpkOutMidFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutMidFreqHz"), 1);
wxGetApp().m_SpkOutMidGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutMidGaindB"), (long)0)/10.0;
wxGetApp().m_SpkOutMidQ = (float)pConfig->Read(wxT("/Filter/SpkOutMidQ"), (long)100)/100.0;
wxGetApp().m_SpkOutVolInDB = (float)pConfig->Read(wxT("/Filter/SpkOutVolInDB"), (long)0)/10.0;

wxGetApp().m_SpkOutEQEnable = (float)pConfig->Read(wxT("/Filter/SpkOutEQEnable"), f);

Expand Down Expand Up @@ -650,6 +652,11 @@ MainFrame::~MainFrame()
int w;
int h;

if (m_filterDialog != nullptr)
{
m_filterDialog->Close();
}

//fprintf(stderr, "MainFrame::~MainFrame()\n");
#ifdef FTEST
fclose(ftest);
Expand Down Expand Up @@ -2645,6 +2652,7 @@ void txRxProcessing()
sox_biquad_filter(cbData->sbqSpkOutBass, outfreedv, outfreedv, speechOutbufferSize);
sox_biquad_filter(cbData->sbqSpkOutTreble, outfreedv, outfreedv, speechOutbufferSize);
sox_biquad_filter(cbData->sbqSpkOutMid, outfreedv, outfreedv, speechOutbufferSize);
if (cbData->sbqSpkOutVol) sox_biquad_filter(cbData->sbqSpkOutVol, outfreedv, outfreedv, speechOutbufferSize);
}
g_mutexProtectingCallbackData.Unlock();

Expand Down Expand Up @@ -2749,6 +2757,7 @@ void txRxProcessing()
sox_biquad_filter(cbData->sbqMicInBass, infreedv, infreedv, nout);
sox_biquad_filter(cbData->sbqMicInTreble, infreedv, infreedv, nout);
sox_biquad_filter(cbData->sbqMicInMid, infreedv, infreedv, nout);
if (cbData->sbqMicInVol) sox_biquad_filter(cbData->sbqMicInVol, infreedv, infreedv, nout);
}
g_mutexProtectingCallbackData.Unlock();

Expand Down
8 changes: 8 additions & 0 deletions src/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ extern int g_soundCard2SampleRate;
#define DS_SYNC_WAIT_TIME 5.0

class MainFrame;
class FilterDlg;

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
// Class MainApp
Expand Down Expand Up @@ -254,6 +255,7 @@ class MainApp : public wxApp
float m_MicInMidGaindB;
float m_MicInMidQ;
bool m_MicInEQEnable;
float m_MicInVolInDB;

// Spk Out Equaliser
float m_SpkOutBassFreqHz;
Expand All @@ -264,6 +266,7 @@ class MainApp : public wxApp
float m_SpkOutMidGaindB;
float m_SpkOutMidQ;
bool m_SpkOutEQEnable;
float m_SpkOutVolInDB;

// optional vox trigger tone
bool m_leftChannelVoxTone;
Expand Down Expand Up @@ -371,9 +374,11 @@ typedef struct paCallBackData
, sbqMicInBass(nullptr)
, sbqMicInTreble(nullptr)
, sbqMicInMid(nullptr)
, sbqMicInVol(nullptr)
, sbqSpkOutBass(nullptr)
, sbqSpkOutTreble(nullptr)
, sbqSpkOutMid(nullptr)
, sbqSpkOutVol(nullptr)
, micInEQEnable(false)
, spkOutEQEnable(false)
, leftChannelVoxTone(false)
Expand Down Expand Up @@ -411,9 +416,11 @@ typedef struct paCallBackData
void *sbqMicInBass;
void *sbqMicInTreble;
void *sbqMicInMid;
void *sbqMicInVol;
void *sbqSpkOutBass;
void *sbqSpkOutTreble;
void *sbqSpkOutMid;
void *sbqSpkOutVol;

bool micInEQEnable;
bool spkOutEQEnable;
Expand Down Expand Up @@ -477,6 +484,7 @@ class MainFrame : public TopFrame
MainFrame(wxWindow *parent);
virtual ~MainFrame();

FilterDlg* m_filterDialog;
PlotSpectrum* m_panelSpectrum;
PlotWaterfall* m_panelWaterfall;
PlotScatter* m_panelScatter;
Expand Down
16 changes: 13 additions & 3 deletions src/ongui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,19 @@ void MainFrame::OnToolsAudioUI(wxUpdateUIEvent& event)
void MainFrame::OnToolsFilter(wxCommandEvent& event)
{
wxUnusedVar(event);
FilterDlg *dlg = new FilterDlg(NULL, m_RxRunning, &m_newMicInFilter, &m_newSpkOutFilter);
dlg->ShowModal();
delete dlg;

if (m_filterDialog == nullptr)
{
m_filterDialog = new FilterDlg(NULL, m_RxRunning, &m_newMicInFilter, &m_newSpkOutFilter);
}
else
{
m_filterDialog->Iconize(false);
m_filterDialog->SetFocus();
m_filterDialog->Raise();
}

m_filterDialog->Show();
}

//-------------------------------------------------------------------------
Expand Down