Skip to content

Commit e910e44

Browse files
authored
Merge pull request #631 from drowe67/ms-null-filters
Prevent creation of filters if not enabled.
2 parents c9c2b00 + 73349f3 commit e910e44

File tree

6 files changed

+115
-44
lines changed

6 files changed

+115
-44
lines changed

USER_MANUAL.md

+1
Original file line numberDiff line numberDiff line change
@@ -919,6 +919,7 @@ LDPC | Low Density Parity Check Codes - a family of powerful FEC codes
919919
* Improve validation of frequencies in Options dialog. (PR #628)
920920
* Fix typo resulting in TX device sample rate being used for filter initialization. (PR #630)
921921
* Fix intermittent crash resulting from object thread starting before object is fully initialized. (PR #630)
922+
* Prevent creation of filters if not enabled. (PR #631)
922923
2. Enhancements:
923924
* Allow user to refresh status message even if it hasn't been changed. (PR #632)
924925
* Increase priority of status message highlight. (PR #632)

src/dlg_filter.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151

5252
extern FreeDVInterface freedvInterface;
5353
extern wxConfigBase *pConfig;
54+
extern wxMutex g_mutexProtectingCallbackData;
5455

5556
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
5657
// Class FilterDlg
@@ -743,14 +744,10 @@ void FilterDlg::updateControlState()
743744
}
744745

745746
void FilterDlg::OnMicInEnable(wxScrollEvent& event) {
746-
wxGetApp().appConfiguration.filterConfiguration.micInChannel.eqEnable = m_MicInEnable->GetValue();
747-
updateControlState();
748747
adjRunTimeMicInFilter();
749748
}
750749

751750
void FilterDlg::OnSpkOutEnable(wxScrollEvent& event) {
752-
wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.eqEnable = m_SpkOutEnable->GetValue();
753-
updateControlState();
754751
adjRunTimeSpkOutFilter();
755752
}
756753

@@ -847,19 +844,29 @@ void FilterDlg::plotSpkOutFilterSpectrum(void) {
847844
void FilterDlg::adjRunTimeMicInFilter(void) {
848845
// signal an adjustment in running filter coeffs
849846

847+
g_mutexProtectingCallbackData.Lock();
850848
ExchangeData(EXCHANGE_DATA_OUT);
851849
if (m_running) {
852850
*m_newMicInFilter = true;
853851
}
852+
wxGetApp().appConfiguration.filterConfiguration.micInChannel.eqEnable = m_MicInEnable->GetValue();
853+
g_mutexProtectingCallbackData.Unlock();
854+
855+
updateControlState();
854856
}
855857

856858
void FilterDlg::adjRunTimeSpkOutFilter(void) {
857859
// signal an adjustment in running filter coeffs
858860

861+
g_mutexProtectingCallbackData.Lock();
859862
ExchangeData(EXCHANGE_DATA_OUT);
860863
if (m_running) {
861864
*m_newSpkOutFilter = true;
862865
}
866+
wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.eqEnable = m_SpkOutEnable->GetValue();
867+
g_mutexProtectingCallbackData.Unlock();
868+
869+
updateControlState();
863870
}
864871

865872

src/eq.cpp

+38-14
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void *MainFrame::designAnEQFilter(const char filterType[], float freqHz, float g
5959
void MainFrame::designEQFilters(paCallBackData *cb, int rxSampleRate, int txSampleRate)
6060
{
6161
// init Mic In Equaliser Filters
62-
if (m_newMicInFilter) {
62+
if (cb->micInEQEnable) {
6363
assert(cb->sbqMicInBass == nullptr && cb->sbqMicInTreble == nullptr && cb->sbqMicInMid == nullptr);
6464
//printf("designing new Min In filters\n");
6565
cb->sbqMicInBass = designAnEQFilter("bass", wxGetApp().appConfiguration.filterConfiguration.micInChannel.bassFreqHz, wxGetApp().appConfiguration.filterConfiguration.micInChannel.bassGaindB, txSampleRate);
@@ -73,7 +73,7 @@ void MainFrame::designEQFilters(paCallBackData *cb, int rxSampleRate, int txSam
7373

7474
// init Spk Out Equaliser Filters
7575

76-
if (m_newSpkOutFilter) {
76+
if (cb->spkOutEQEnable) {
7777
assert(cb->sbqSpkOutBass == nullptr && cb->sbqSpkOutTreble == nullptr && cb->sbqSpkOutMid == nullptr);
7878
//printf("designing new Spk Out filters\n");
7979
//printf("designEQFilters: wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.bassFreqHz: %f\n",wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.bassFreqHz);
@@ -94,13 +94,25 @@ void MainFrame::deleteEQFilters(paCallBackData *cb)
9494
{
9595
if (m_newMicInFilter)
9696
{
97-
assert(cb->sbqMicInBass != nullptr && cb->sbqMicInTreble != nullptr && cb->sbqMicInMid != nullptr);
97+
if (cb->sbqMicInBass != nullptr)
98+
{
99+
sox_biquad_destroy(cb->sbqMicInBass);
100+
}
101+
102+
if (cb->sbqMicInTreble != nullptr)
103+
{
104+
sox_biquad_destroy(cb->sbqMicInTreble);
105+
}
98106

99-
sox_biquad_destroy(cb->sbqMicInBass);
100-
sox_biquad_destroy(cb->sbqMicInTreble);
101-
sox_biquad_destroy(cb->sbqMicInMid);
107+
if (cb->sbqMicInMid != nullptr)
108+
{
109+
sox_biquad_destroy(cb->sbqMicInMid);
110+
}
102111

103-
if (cb->sbqMicInVol) sox_biquad_destroy(cb->sbqMicInVol);
112+
if (cb->sbqMicInVol != nullptr)
113+
{
114+
sox_biquad_destroy(cb->sbqMicInVol);
115+
}
104116

105117
cb->sbqMicInBass = nullptr;
106118
cb->sbqMicInTreble = nullptr;
@@ -109,14 +121,26 @@ void MainFrame::deleteEQFilters(paCallBackData *cb)
109121
}
110122

111123
if (m_newSpkOutFilter)
112-
{
113-
assert(cb->sbqSpkOutBass != nullptr && cb->sbqSpkOutTreble != nullptr && cb->sbqSpkOutMid != nullptr);
114-
115-
sox_biquad_destroy(cb->sbqSpkOutBass);
116-
sox_biquad_destroy(cb->sbqSpkOutTreble);
117-
sox_biquad_destroy(cb->sbqSpkOutMid);
124+
{
125+
if (cb->sbqSpkOutBass != nullptr)
126+
{
127+
sox_biquad_destroy(cb->sbqSpkOutBass);
128+
}
129+
130+
if (cb->sbqSpkOutTreble != nullptr)
131+
{
132+
sox_biquad_destroy(cb->sbqSpkOutTreble);
133+
}
134+
135+
if (cb->sbqSpkOutMid != nullptr)
136+
{
137+
sox_biquad_destroy(cb->sbqSpkOutMid);
138+
}
118139

119-
if (cb->sbqSpkOutVol) sox_biquad_destroy(cb->sbqSpkOutVol);
140+
if (cb->sbqSpkOutVol != nullptr)
141+
{
142+
sox_biquad_destroy(cb->sbqSpkOutVol);
143+
}
120144

121145
cb->sbqSpkOutBass = nullptr;
122146
cb->sbqSpkOutTreble = nullptr;

src/main.cpp

+48-14
Original file line numberDiff line numberDiff line change
@@ -1493,26 +1493,39 @@ void MainFrame::OnTimer(wxTimerEvent &evt)
14931493

14941494
// Run time update of EQ filters -----------------------------------
14951495

1496-
if (m_newMicInFilter || m_newSpkOutFilter) {
1497-
g_mutexProtectingCallbackData.Lock();
1496+
g_mutexProtectingCallbackData.Lock();
1497+
1498+
bool micEqEnableOld = g_rxUserdata->micInEQEnable;
1499+
bool spkrEqEnableOld = g_rxUserdata->spkOutEQEnable;
1500+
1501+
if (m_newMicInFilter || m_newSpkOutFilter ||
1502+
micEqEnableOld != wxGetApp().appConfiguration.filterConfiguration.micInChannel.eqEnable ||
1503+
spkrEqEnableOld != wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.eqEnable) {
1504+
14981505
deleteEQFilters(g_rxUserdata);
14991506

1500-
if (g_nSoundCards == 1)
1507+
g_rxUserdata->micInEQEnable = wxGetApp().appConfiguration.filterConfiguration.micInChannel.eqEnable;
1508+
g_rxUserdata->spkOutEQEnable = wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.eqEnable;
1509+
1510+
if (
1511+
wxGetApp().appConfiguration.filterConfiguration.micInChannel.eqEnable ||
1512+
wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.eqEnable)
15011513
{
1502-
// RX In isn't used here but we need to provide it anyway.
1503-
designEQFilters(g_rxUserdata, wxGetApp().appConfiguration.audioConfiguration.soundCard1Out.sampleRate, wxGetApp().appConfiguration.audioConfiguration.soundCard1In.sampleRate);
1504-
}
1505-
else
1506-
{
1507-
designEQFilters(g_rxUserdata, wxGetApp().appConfiguration.audioConfiguration.soundCard2Out.sampleRate, wxGetApp().appConfiguration.audioConfiguration.soundCard2In.sampleRate);
1514+
if (g_nSoundCards == 1)
1515+
{
1516+
// RX In isn't used here but we need to provide it anyway.
1517+
designEQFilters(g_rxUserdata, wxGetApp().appConfiguration.audioConfiguration.soundCard1Out.sampleRate, wxGetApp().appConfiguration.audioConfiguration.soundCard1In.sampleRate);
1518+
}
1519+
else
1520+
{
1521+
designEQFilters(g_rxUserdata, wxGetApp().appConfiguration.audioConfiguration.soundCard2Out.sampleRate, wxGetApp().appConfiguration.audioConfiguration.soundCard2In.sampleRate);
1522+
}
15081523
}
1509-
g_mutexProtectingCallbackData.Unlock();
1524+
15101525
m_newMicInFilter = m_newSpkOutFilter = false;
15111526
}
1527+
g_mutexProtectingCallbackData.Unlock();
15121528

1513-
g_rxUserdata->micInEQEnable = wxGetApp().appConfiguration.filterConfiguration.micInChannel.eqEnable;
1514-
g_rxUserdata->spkOutEQEnable = wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.eqEnable;
1515-
15161529
// set some run time options (if applicable)
15171530
freedvInterface.setRunTimeOptions(
15181531
(int)wxGetApp().appConfiguration.freedv700Clip,
@@ -2639,9 +2652,20 @@ void MainFrame::startRxStream()
26392652

26402653
m_newMicInFilter = m_newSpkOutFilter = true;
26412654
g_mutexProtectingCallbackData.Lock();
2642-
designEQFilters(g_rxUserdata, wxGetApp().appConfiguration.audioConfiguration.soundCard2Out.sampleRate, wxGetApp().appConfiguration.audioConfiguration.soundCard2In.sampleRate);
2655+
26432656
g_rxUserdata->micInEQEnable = wxGetApp().appConfiguration.filterConfiguration.micInChannel.eqEnable;
26442657
g_rxUserdata->spkOutEQEnable = wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.eqEnable;
2658+
2659+
if (
2660+
wxGetApp().appConfiguration.filterConfiguration.micInChannel.eqEnable ||
2661+
wxGetApp().appConfiguration.filterConfiguration.spkOutChannel.eqEnable)
2662+
{
2663+
designEQFilters(
2664+
g_rxUserdata,
2665+
wxGetApp().appConfiguration.audioConfiguration.soundCard2Out.sampleRate,
2666+
wxGetApp().appConfiguration.audioConfiguration.soundCard2In.sampleRate);
2667+
}
2668+
26452669
m_newMicInFilter = m_newSpkOutFilter = false;
26462670
g_mutexProtectingCallbackData.Unlock();
26472671

@@ -2884,6 +2908,16 @@ void MainFrame::startRxStream()
28842908
}
28852909

28862910
if (g_verbose) fprintf(stderr, "starting tx/rx processing thread\n");
2911+
2912+
// Work around an issue where the buttons stay disabled even if there
2913+
// is an error opening one or more audio device(s).
2914+
bool txDevicesRunning =
2915+
(!txInSoundDevice || txInSoundDevice->isRunning()) &&
2916+
(!txOutSoundDevice || txOutSoundDevice->isRunning());
2917+
bool rxDevicesRunning =
2918+
(rxInSoundDevice && rxInSoundDevice->isRunning()) &&
2919+
(rxOutSoundDevice && rxOutSoundDevice->isRunning());
2920+
m_RxRunning = txDevicesRunning && rxDevicesRunning;
28872921
}
28882922
}
28892923

src/pipeline/EqualizerStep.cpp

+13-10
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,12 @@
2020
//
2121
//=========================================================================
2222

23-
2423
#include "EqualizerStep.h"
2524

25+
#include <cstring>
2626
#include "../sox_biquad.h"
2727
#include <assert.h>
2828

29-
// TBD -- use std::mutex instead of wxMutex to remove wxWidgets dependency.
30-
#include <wx/wx.h>
31-
extern wxMutex g_mutexProtectingCallbackData;
32-
3329
EqualizerStep::EqualizerStep(int sampleRate, bool* enableFilter, void** bassFilter, void** midFilter, void** trebleFilter, void** volFilter)
3430
: sampleRate_(sampleRate)
3531
, enableFilter_(enableFilter)
@@ -63,18 +59,25 @@ std::shared_ptr<short> EqualizerStep::execute(std::shared_ptr<short> inputSample
6359

6460
memcpy(outputSamples, inputSamples.get(), sizeof(short)*numInputSamples);
6561

66-
g_mutexProtectingCallbackData.Lock();
6762
if (*enableFilter_)
6863
{
69-
sox_biquad_filter(*bassFilter_, outputSamples, outputSamples, numInputSamples);
70-
sox_biquad_filter(*trebleFilter_, outputSamples, outputSamples, numInputSamples);
71-
sox_biquad_filter(*midFilter_, outputSamples, outputSamples, numInputSamples);
64+
if (*bassFilter_)
65+
{
66+
sox_biquad_filter(*bassFilter_, outputSamples, outputSamples, numInputSamples);
67+
}
68+
if (*trebleFilter_)
69+
{
70+
sox_biquad_filter(*trebleFilter_, outputSamples, outputSamples, numInputSamples);
71+
}
72+
if (*midFilter_)
73+
{
74+
sox_biquad_filter(*midFilter_, outputSamples, outputSamples, numInputSamples);
75+
}
7276
if (*volFilter_)
7377
{
7478
sox_biquad_filter(*volFilter_, outputSamples, outputSamples, numInputSamples);
7579
}
7680
}
77-
g_mutexProtectingCallbackData.Unlock();
7881

7982
*numOutputSamples = numInputSamples;
8083
return std::shared_ptr<short>(outputSamples, std::default_delete<short[]>());

src/pipeline/TxRxThread.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,8 @@ void TxRxThread::initializePipeline_()
201201
&g_rxUserdata->sbqMicInMid,
202202
&g_rxUserdata->sbqMicInTreble,
203203
&g_rxUserdata->sbqMicInVol);
204-
pipeline_->appendPipelineStep(std::shared_ptr<IPipelineStep>(equalizerStep));
204+
auto equalizerLockStep = new ExclusiveAccessStep(equalizerStep, callbackLockFn, callbackUnlockFn);
205+
pipeline_->appendPipelineStep(std::shared_ptr<IPipelineStep>(equalizerLockStep));
205206

206207
// Take TX audio post-equalizer and send it to RX for possible monitoring use.
207208
if (equalizedMicAudioLink_ != nullptr)
@@ -426,7 +427,8 @@ void TxRxThread::initializePipeline_()
426427
&g_rxUserdata->sbqSpkOutMid,
427428
&g_rxUserdata->sbqSpkOutTreble,
428429
&g_rxUserdata->sbqSpkOutVol);
429-
pipeline_->appendPipelineStep(std::shared_ptr<IPipelineStep>(equalizerStep));
430+
auto equalizerLockStep = new ExclusiveAccessStep(equalizerStep, callbackLockFn, callbackUnlockFn);
431+
pipeline_->appendPipelineStep(std::shared_ptr<IPipelineStep>(equalizerLockStep));
430432

431433
// Resample for plot step (speech out)
432434
auto resampleForPlotOutStep = new ResampleForPlotStep(g_plotSpeechOutFifo);

0 commit comments

Comments
 (0)