//
//==========================================================================
#include "dlg_filter.h"
-#include "sox_biquad.h"
#define SLIDER_MAX 100
#define SLIDER_LENGTH 155
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
// Class FilterDlg
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-=
-FilterDlg::FilterDlg(wxWindow* parent, bool running, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
+FilterDlg::FilterDlg(wxWindow* parent, bool running, bool *newMicInFilter, bool *newSpkOutFilter,
+ wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style) : wxDialog(parent, id, title, pos, size, style)
{
m_running = running;
+ m_newMicInFilter = newMicInFilter;
+ m_newSpkOutFilter = newSpkOutFilter;
this->SetSizeHints(wxDefaultSize, wxDefaultSize);
m_sdbSizer5Cancel->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnCancel), NULL, this);
m_sdbSizer5OK->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(FilterDlg::OnOK), NULL, this);
- sox_biquad_start();
}
//-------------------------------------------------------------------------
{
delete m_MicInMagdB;
delete m_SpkOutMagdB;
- sox_biquad_finish();
// Disconnect Events
//-------------------------------------------------------------------------
// ExchangeData()
//-------------------------------------------------------------------------
-void FilterDlg::ExchangeData(int inout)
+void FilterDlg::ExchangeData(int inout, bool storePersistent)
{
wxConfigBase *pConfig = wxConfigBase::Get();
if(inout == EXCHANGE_DATA_IN)
m_MicInMid.Q = wxGetApp().m_MicInMidQ; setQ(&m_MicInMid);
m_MicInMid.Q = limit(m_MicInMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
- m_MicInEnable->SetValue(wxGetApp().m_MicInEnable);
+ m_MicInEnable->SetValue(wxGetApp().m_MicInEQEnable);
setFreq(&m_MicInBass); setGain(&m_MicInBass); plotMicInFilterSpectrum();
m_SpkOutMid.Q = wxGetApp().m_SpkOutMidQ; setQ(&m_SpkOutMid);
m_SpkOutMid.Q = limit(m_SpkOutMid.Q, pow(10.0,MIN_LOG10_Q), pow(10.0, MAX_LOG10_Q));
- m_SpkOutEnable->SetValue(wxGetApp().m_SpkOutEnable);
+ m_SpkOutEnable->SetValue(wxGetApp().m_SpkOutEQEnable);
setFreq(&m_SpkOutBass); setGain(&m_SpkOutBass); plotSpkOutFilterSpectrum();
}
wxGetApp().m_codec2LPCPostFilterBeta = m_beta;
wxGetApp().m_codec2LPCPostFilterGamma = m_gamma;
- pConfig->Write(wxT("/Filter/codec2LPCPostFilterEnable"), wxGetApp().m_codec2LPCPostFilterEnable);
- pConfig->Write(wxT("/Filter/codec2LPCPostFilterBassBoost"), wxGetApp().m_codec2LPCPostFilterBassBoost);
- pConfig->Write(wxT("/Filter/codec2LPCPostFilterBeta"), (int)(m_beta*100.0));
- pConfig->Write(wxT("/Filter/codec2LPCPostFilterGamma"), (int)(m_gamma*100.0));
-
// Mic In Equaliser
wxGetApp().m_MicInBassFreqHz = m_MicInBass.freqHz;
- pConfig->Write(wxT("/Filter/MicInBassFreqHz"), (int)m_MicInBass.freqHz);
wxGetApp().m_MicInBassGaindB = m_MicInBass.gaindB;
- pConfig->Write(wxT("/Filter/MicInBassGaindB"), (int)(10.0*m_MicInBass.gaindB));
wxGetApp().m_MicInTrebleFreqHz = m_MicInTreble.freqHz;
- pConfig->Write(wxT("/Filter/MicInTrebleFreqHz"), (int)m_MicInTreble.freqHz);
wxGetApp().m_MicInTrebleGaindB = m_MicInTreble.gaindB;
- pConfig->Write(wxT("/Filter/MicInTrebleGaindB"), (int)(10.0*m_MicInTreble.gaindB));
wxGetApp().m_MicInMidFreqHz = m_MicInMid.freqHz;
- pConfig->Write(wxT("/Filter/MicInMidFreqHz"), (int)m_MicInMid.freqHz);
wxGetApp().m_MicInMidGaindB = m_MicInMid.gaindB;
- pConfig->Write(wxT("/Filter/MicInMidGaindB"), (int)(10.0*m_MicInMid.gaindB));
wxGetApp().m_MicInMidQ = m_MicInMid.Q;
- pConfig->Write(wxT("/Filter/MicInMidQ"), (int)(100.0*m_MicInMid.Q));
// Spk Out Equaliser
wxGetApp().m_SpkOutBassFreqHz = m_SpkOutBass.freqHz;
- pConfig->Write(wxT("/Filter/SpkOutBassFreqHz"), (int)m_SpkOutBass.freqHz);
wxGetApp().m_SpkOutBassGaindB = m_SpkOutBass.gaindB;
- pConfig->Write(wxT("/Filter/SpkOutBassGaindB"), (int)(10.0*m_SpkOutBass.gaindB));
wxGetApp().m_SpkOutTrebleFreqHz = m_SpkOutTreble.freqHz;
- pConfig->Write(wxT("/Filter/SpkOutTrebleFreqHz"), (int)m_SpkOutTreble.freqHz);
wxGetApp().m_SpkOutTrebleGaindB = m_SpkOutTreble.gaindB;
- pConfig->Write(wxT("/Filter/SpkOutTrebleGaindB"), (int)(10.0*m_SpkOutTreble.gaindB));
wxGetApp().m_SpkOutMidFreqHz = m_SpkOutMid.freqHz;
- pConfig->Write(wxT("/Filter/SpkOutMidFreqHz"), (int)m_SpkOutMid.freqHz);
wxGetApp().m_SpkOutMidGaindB = m_SpkOutMid.gaindB;
- pConfig->Write(wxT("/Filter/SpkOutMidGaindB"), (int)(10.0*m_SpkOutMid.gaindB));
wxGetApp().m_SpkOutMidQ = m_SpkOutMid.Q;
- pConfig->Write(wxT("/Filter/SpkOutMidQ"), (int)(100.0*m_SpkOutMid.Q));
- pConfig->Flush();
+ if (storePersistent) {
+ pConfig->Write(wxT("/Filter/codec2LPCPostFilterEnable"), wxGetApp().m_codec2LPCPostFilterEnable);
+ pConfig->Write(wxT("/Filter/codec2LPCPostFilterBassBoost"), wxGetApp().m_codec2LPCPostFilterBassBoost);
+ pConfig->Write(wxT("/Filter/codec2LPCPostFilterBeta"), (int)(m_beta*100.0));
+ pConfig->Write(wxT("/Filter/codec2LPCPostFilterGamma"), (int)(m_gamma*100.0));
+
+ pConfig->Write(wxT("/Filter/MicInBassFreqHz"), (int)m_MicInBass.freqHz);
+ pConfig->Write(wxT("/Filter/MicInBassGaindB"), (int)(10.0*m_MicInBass.gaindB));
+ pConfig->Write(wxT("/Filter/MicInTrebleFreqHz"), (int)m_MicInTreble.freqHz);
+ pConfig->Write(wxT("/Filter/MicInTrebleGaindB"), (int)(10.0*m_MicInTreble.gaindB));
+ pConfig->Write(wxT("/Filter/MicInMidFreqHz"), (int)m_MicInMid.freqHz);
+ pConfig->Write(wxT("/Filter/MicInMidGaindB"), (int)(10.0*m_MicInMid.gaindB));
+ pConfig->Write(wxT("/Filter/MicInMidQ"), (int)(100.0*m_MicInMid.Q));
+
+ pConfig->Write(wxT("/Filter/SpkOutBassFreqHz"), (int)m_SpkOutBass.freqHz);
+ pConfig->Write(wxT("/Filter/SpkOutBassGaindB"), (int)(10.0*m_SpkOutBass.gaindB));
+ pConfig->Write(wxT("/Filter/SpkOutTrebleFreqHz"), (int)m_SpkOutTreble.freqHz);
+ pConfig->Write(wxT("/Filter/SpkOutTrebleGaindB"), (int)(10.0*m_SpkOutTreble.gaindB));
+ pConfig->Write(wxT("/Filter/SpkOutMidQ"), (int)(100.0*m_SpkOutMid.Q));
+ pConfig->Write(wxT("/Filter/SpkOutMidFreqHz"), (int)m_SpkOutMid.freqHz);
+ pConfig->Write(wxT("/Filter/SpkOutMidGaindB"), (int)(10.0*m_SpkOutMid.gaindB));
+
+ pConfig->Flush();
+ }
}
delete wxConfigBase::Set((wxConfigBase *) NULL);
}
void FilterDlg::OnOK(wxCommandEvent& event)
{
//printf("FilterDlg::OnOK\n");
- ExchangeData(EXCHANGE_DATA_OUT);
+ ExchangeData(EXCHANGE_DATA_OUT, true);
this->EndModal(wxID_OK);
}
void FilterDlg::OnInitDialog(wxInitDialogEvent& event)
{
//printf("FilterDlg::OnInitDialog\n");
- ExchangeData(EXCHANGE_DATA_IN);
+ ExchangeData(EXCHANGE_DATA_IN, false);
//printf("m_beta: %f\n", m_beta);
}
setCodec2();
}
-// immediately change rather using ExchangeData() so we can switch on and off at run time
+// immediately change enable flags rather using ExchangeData() so we can switch on and off at run time
+
void FilterDlg::OnMicInEnable(wxScrollEvent& event) {
- wxGetApp().m_MicInEnable = m_MicInEnable->GetValue();
+ wxGetApp().m_MicInEQEnable = m_MicInEnable->GetValue();
}
void FilterDlg::OnSpkOutEnable(wxScrollEvent& event) {
- wxGetApp().m_SpkOutEnable = m_SpkOutEnable->GetValue();
+ wxGetApp().m_SpkOutEQEnable = m_SpkOutEnable->GetValue();
}
void FilterDlg::setFreq(EQ *eq)
void FilterDlg::plotMicInFilterSpectrum(void) {
plotFilterSpectrum(&m_MicInBass, &m_MicInMid, &m_MicInTreble, m_MicInFreqRespPlot, m_MicInMagdB);
+
+ // signal an adjustment in running filter coeffs
+
+ if (m_running) {
+ ExchangeData(EXCHANGE_DATA_OUT, false);
+ *m_newMicInFilter = true;
+ }
+
}
void FilterDlg::plotSpkOutFilterSpectrum(void) {
plotFilterSpectrum(&m_SpkOutBass, &m_SpkOutMid, &m_SpkOutTreble, m_SpkOutFreqRespPlot, m_SpkOutMagdB);
+
+ // signal an adjustment in running filter coeffs
+
+ if (m_running) {
+ ExchangeData(EXCHANGE_DATA_OUT, false);
+ *m_newSpkOutFilter = true;
+ }
+
}
void FilterDlg::plotFilterSpectrum(EQ *eqBass, EQ *eqMid, EQ *eqTreble, PlotSpectrum* freqRespPlot, float *magdB) {
//out[0] = IMP_AMP;
// calculate discrete time continous frequency Fourer transform
- // doing this from basic principles rather than FFT for no good reason
+ // doing this from first principles rather than FFT for no good reason
for(f=0,i=0; f<MAX_F_HZ; f+=F_STEP_DFT,i++) {
w = M_PI*f/(FS/2);
wxGetApp().m_show_speech_out = pConfig->Read(wxT("/MainFrame/show_speech_out"), 1);
wxGetApp().m_show_demod_in = pConfig->Read(wxT("/MainFrame/show_demod_in"), 1);
+ wxGetApp().m_rxNbookCtrl = pConfig->Read(wxT("/MainFrame/rxNbookCtrl"), (long)0);
+
g_SquelchActive = pConfig->Read(wxT("/Audio/SquelchActive"), 1);
g_SquelchLevel = pConfig->Read(wxT("/Audio/SquelchLevel"), (int)(SQ_DEFAULT_SNR*2));
g_SquelchLevel /= 2.0;
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_MicInEnable = (float)pConfig->Read(wxT("/Filter/MicInEnable"), t);
+ bool f = false;
+ wxGetApp().m_MicInEQEnable = (float)pConfig->Read(wxT("/Filter/MicInEQEnable"), f);
wxGetApp().m_SpkOutBassFreqHz = (float)pConfig->Read(wxT("/Filter/SpkOutBassFreqHz"), 1);
wxGetApp().m_SpkOutBassGaindB = (float)pConfig->Read(wxT("/Filter/SpkOutBassGaindB"), (long)0)/10.0;
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_SpkOutEnable = (float)pConfig->Read(wxT("/Filter/SpkOutEnable"), t);
+ wxGetApp().m_SpkOutEQEnable = (float)pConfig->Read(wxT("/Filter/SpkOutEQEnable"), f);
wxGetApp().m_callSign = pConfig->Read("/Data/CallSign", wxT(""));
g_txDataInFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS);
g_rxDataOutFifo = fifo_create(MAX_CALLSIGN*VARICODE_MAX_BITS);
varicode_decode_init(&g_varicode_dec_states);
+
+ sox_biquad_start();
+
}
//-------------------------------------------------------------------------
pConfig->Write(wxT("/MainFrame/show_speech_out"), wxGetApp().m_show_speech_out);
pConfig->Write(wxT("/MainFrame/show_demod_in"), wxGetApp().m_show_demod_in);
+ pConfig->Write(wxT("/MainFrame/rxNbookCtrl"), wxGetApp().m_rxNbookCtrl);
+
pConfig->Write(wxT("/Audio/SquelchActive"), g_SquelchActive);
pConfig->Write(wxT("/Audio/SquelchLevel"), (int)(g_SquelchLevel*2.0));
pConfig->Write(wxT("/Data/CallSign"), wxGetApp().m_callSign);
- pConfig->Write(wxT("/Filter/MicInEnable"), wxGetApp().m_MicInEnable);
- pConfig->Write(wxT("/Filter/SpkOutEnable"), wxGetApp().m_SpkOutEnable);
+ pConfig->Write(wxT("/Filter/MicInEQEnable"), wxGetApp().m_MicInEQEnable);
+ pConfig->Write(wxT("/Filter/SpkOutEQEnable"), wxGetApp().m_SpkOutEQEnable);
}
//m_togRxID->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnRxIDUI), NULL, this);
m_btnTogPTT->Disconnect(wxEVT_UPDATE_UI, wxUpdateUIEventHandler(MainFrame::OnTogBtnTXClickUI), NULL, this);
CloseSerialPort();
+ sox_biquad_finish();
if (m_RxRunning)
{
m_maxLevel *= LEVEL_BETA;
- // sync LED (Colours don't work on Windows)
+ // sync LED (Colours don't work on Windows) ------------------------
if (g_State) {
m_rbSync->SetForegroundColour( wxColour( 0, 255, 0 ) ); // green
m_rbSync->SetValue(false);
}
- // send Callsign
+ // send Callsign ----------------------------------------------------
if (fifo_used(g_txDataInFifo) == 0) {
char callsign[MAX_CALLSIGN];
//printf("Callsign sending: %s nout: %d\n", callsign, nout);
}
- // See if any callsign info received
+ // See if any Callsign info received --------------------------------
short ashort;
while (fifo_read(g_rxDataOutFifo, &ashort, 1) == 0) {
}
}
+ // Run time upodate of EQ filters -----------------------------------
+
+ if (m_newMicInFilter || m_newSpkOutFilter) {
+ printf("new filter...\n");
+ g_mutexProtectingCallbackData.Lock();
+ deleteEQFilters(g_rxUserdata);
+ designEQFilters(g_rxUserdata);
+ g_mutexProtectingCallbackData.Unlock();
+ g_rxUserdata->micInEQEnable = wxGetApp().m_MicInEQEnable;
+ g_rxUserdata->spkOutEQEnable = wxGetApp().m_SpkOutEQEnable;
+ m_newMicInFilter = m_newSpkOutFilter = false;
+ }
}
+
#endif
#ifdef _USE_ONIDLE
{
if (g_tx)
{
- // tx-> rx transition, swap to Waterfall
- m_auiNbookCtrl->ChangeSelection(0);
+ // tx-> rx transition, swap to the page we were on for last rx
+ m_auiNbookCtrl->ChangeSelection(wxGetApp().m_rxNbookCtrl);
}
else
{
// rx-> tx transition, swap to Mic In page to monitor speech
+
+ wxGetApp().m_rxNbookCtrl = m_auiNbookCtrl->GetSelection();
m_auiNbookCtrl->ChangeSelection(4); // is there a way to avoid hard coding this?
+
}
g_tx = m_btnTogPTT->GetValue();
+
// The following sets and clears may be exactly inverted.
// I don't know and I'm not set up to tell yet.
// If so, one just needs to invert the polarity selection
}
}
}
-
+
// reset level gauge
m_maxLevel = 0;
m_textLevel->SetLabel(wxT(""));
void MainFrame::OnToolsFilter(wxCommandEvent& event)
{
wxUnusedVar(event);
- FilterDlg *dlg = new FilterDlg(NULL, m_RxRunning);
+ FilterDlg *dlg = new FilterDlg(NULL, m_RxRunning, &m_newMicInFilter, &m_newSpkOutFilter);
dlg->ShowModal();
delete dlg;
}
//printf("In OK\n");
wxStringOutputStream html_stream(&htmldata);
in->Read(html_stream);
- wxLogDebug(htmldata);
+ //wxLogDebug(htmldata);
wxString s("<h2>freetel - Revision ");
int startIndex = htmldata.find(s) + s.Length();
if (startStop.IsSameAs("Start"))
{
+ //
+ // Start Running -------------------------------------------------
+ //
+
m_togBtnSplit->Enable();
//m_togRxID->Enable();
//m_togTxID->Enable();
if (startStop.IsSameAs("Stop") || !m_RxRunning ) {
+ //
+ // Stop Running -------------------------------------------------
+ //
+
#ifdef _USE_TIMER
m_plotTimer.Stop();
#endif // _USE_TIMER
src_delete(g_rxUserdata->outsrc2);
}
-void MainFrame::autoDetectSoundCards(PortAudioWrap *pa)
-{
- const PaDeviceInfo *deviceInfo;
- int i;
-
- // trap zero sound devices
-
- if (pa->getDeviceCount() == 0) {
- wxMessageBox(wxT("No sound devices found"), wxT("Error"), wxOK);
- return;
- }
-
- for(i=0; i<pa->getDeviceCount(); i++) {
- deviceInfo = Pa_GetDeviceInfo( i );
-
- // supports full duplex and 44800 and 44100
- // is there something unique so we know it's a hw device?
- // does this work on Linux & Windows?
-
- printf( "--------------------------------------- device #%d\n", i );
- printf( "Name = %s\n", deviceInfo->name );
- printf( "Host API = %s\n", Pa_GetHostApiInfo( deviceInfo->hostApi )->name );
- printf( "Max inputs = %d", deviceInfo->maxInputChannels );
- printf( ", Max outputs = %d\n", deviceInfo->maxOutputChannels );
- printf( "Default sample rate = %8.2f\n", deviceInfo->defaultSampleRate );
- }
-}
-
void MainFrame::initPortAudioDevice(PortAudioWrap *pa, int inDevice, int outDevice,
int soundCard, int sampleRate, int inputChannels)
{
g_rxUserdata->rxinfifo = fifo_create(3 * FDMDV_NOM_SAMPLES_PER_FRAME);
g_rxUserdata->rxoutfifo = fifo_create(2 * codec2_samples_per_frame(g_pCodec2));
+ // Init Equaliser Filters ------------------------------------------------------
+
+ designEQFilters(g_rxUserdata);
+ g_rxUserdata->micInEQEnable = wxGetApp().m_MicInEQEnable;
+ g_rxUserdata->spkOutEQEnable = wxGetApp().m_SpkOutEQEnable;
+
// Start sound card 1 ----------------------------------------------------------
m_rxPa->setUserData(g_rxUserdata);
{
wxLogError(wxT("Can't start thread!"));
}
- }
+ }
}
+#define SBQ_MAX_ARGS 4
+
+void *MainFrame::designAnEQFilter(const char filterType[], float freqHz, float gaindB, float Q)
+{
+ 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));
+
+ for(i=0; i<SBQ_MAX_ARGS; i++) {
+ arg[i] = &argstorage[i][0];
+ arg[i] = &argstorage[i][0];
+ arg[i] = &argstorage[i][0];
+ }
+
+ argc = 0;
+
+ if ((strcmp(filterType, "bass") == 0) || (strcmp(filterType, "treble") == 0)) {
+ sprintf(arg[argc++], "%s", filterType);
+ sprintf(arg[argc++], "%f", gaindB+1E-6);
+ sprintf(arg[argc++], "%f", freqHz);
+ }
+
+ if (strcmp(filterType, "equalizer") == 0) {
+ sprintf(arg[argc++], "%s", filterType);
+ sprintf(arg[argc++], "%f", freqHz);
+ sprintf(arg[argc++], "%f", Q);
+ sprintf(arg[argc++], "%f", gaindB+1E-6);
+ }
+
+ assert(argc <= SBQ_MAX_ARGS);
+
+ sbq = sox_biquad_create(argc-1, (const char **)arg);
+
+ return sbq;
+}
+
+void MainFrame::designEQFilters(paCallBackData *cb)
+{
+ // init Mic In Equaliser Filters
+
+ if (m_newMicInFilter) {
+ printf("designing new Min In filters\n");
+ cb->sbqMicInBass = designAnEQFilter("bass", wxGetApp().m_MicInBassFreqHz, wxGetApp().m_MicInBassGaindB);
+ cb->sbqMicInTreble = designAnEQFilter("treble", wxGetApp().m_MicInTrebleFreqHz, wxGetApp().m_MicInTrebleGaindB);
+ cb->sbqMicInMid = designAnEQFilter("equalizer", wxGetApp().m_MicInMidFreqHz, wxGetApp().m_MicInMidGaindB, wxGetApp().m_MicInMidQ);
+ }
+
+ // init Spk Out Equaliser Filters
+
+ if (m_newSpkOutFilter) {
+ printf("designing new Spk Out filters\n");
+ cb->sbqSpkOutBass = designAnEQFilter("bass", wxGetApp().m_SpkOutBassFreqHz, wxGetApp().m_SpkOutBassGaindB);
+ cb->sbqSpkOutTreble = designAnEQFilter("treble", wxGetApp().m_SpkOutTrebleFreqHz, wxGetApp().m_SpkOutTrebleGaindB);
+ cb->sbqSpkOutMid = designAnEQFilter("equalizer", wxGetApp().m_SpkOutMidFreqHz, wxGetApp().m_SpkOutMidGaindB, wxGetApp().m_SpkOutMidQ);
+ }
+
+}
+
+void MainFrame::deleteEQFilters(paCallBackData *cb)
+{
+ if (m_newMicInFilter) {
+ sox_biquad_destroy(cb->sbqMicInBass);
+ sox_biquad_destroy(cb->sbqMicInTreble);
+ sox_biquad_destroy(cb->sbqMicInMid);
+ }
+ if (m_newSpkOutFilter) {
+ sox_biquad_destroy(cb->sbqSpkOutBass);
+ sox_biquad_destroy(cb->sbqSpkOutTreble);
+ sox_biquad_destroy(cb->sbqSpkOutMid);
+ }
+}
+
// returns number of output samples generated by resampling
int resample(SRC_STATE *src,
g_mutexProtectingCallbackData.Lock();
if (g_playFileFromRadio && (g_sfPlayFileFromRadio != NULL)) {
- int n = sf_read_short(g_sfPlayFileFromRadio, in8k_short, N8);
+ int n = sf_read_short(g_sfPlayFileFromRadio, in8k_short, n8k);
if (n != N8) {
if (g_loopPlayFileFromRadio)
sf_seek(g_sfPlayFileFromRadio, 0, SEEK_SET);
}
}
g_mutexProtectingCallbackData.Unlock();
-
+
fifo_write(cbData->rxinfifo, in8k_short, n8k);
resample_for_plot(g_plotDemodInFifo, in8k_short, n8k);
fifo_read(cbData->rxoutfifo, out8k_short, N8);
}
+ // Opional Spk Out EQ Filtering, need mutex as filter can change at run time
+ g_mutexProtectingCallbackData.Lock();
+ if (cbData->spkOutEQEnable) {
+ sox_biquad_filter(cbData->sbqSpkOutBass, out8k_short, out8k_short, N8);
+ sox_biquad_filter(cbData->sbqSpkOutTreble, out8k_short, out8k_short, N8);
+ sox_biquad_filter(cbData->sbqSpkOutMid, out8k_short, out8k_short, N8);
+ }
+ g_mutexProtectingCallbackData.Unlock();
+
if (g_SquelchActive && (g_SquelchLevel > g_snr)) {
//printf("g_SquelchLevel: %f g_snr: %f\n", g_SquelchLevel, g_snr);
memset(out8k_short, 0, sizeof(short)*N8);
// optionally use file for mic input signal
g_mutexProtectingCallbackData.Lock();
if (g_playFileToMicIn && (g_sfPlayFile != NULL)) {
- int n = sf_read_short(g_sfPlayFile, in8k_short, 2*N8);
- if (n != 2*N8) {
+ int n = sf_read_short(g_sfPlayFile, in8k_short, nout);
+ if (n != nout) {
if (g_loopPlayFileToMicIn)
sf_seek(g_sfPlayFile, 0, SEEK_SET);
else {
}
g_mutexProtectingCallbackData.Unlock();
+ // Opional Mic In EQ Filtering, need mutex as filter can change at run time
+ g_mutexProtectingCallbackData.Lock();
+ if (cbData->micInEQEnable) {
+ sox_biquad_filter(cbData->sbqMicInBass, in8k_short, in8k_short, nout);
+ sox_biquad_filter(cbData->sbqMicInTreble, in8k_short, in8k_short, nout);
+ sox_biquad_filter(cbData->sbqMicInMid, in8k_short, in8k_short, nout);
+ }
+ g_mutexProtectingCallbackData.Unlock();
+
resample_for_plot(g_plotSpeechInFifo, in8k_short, nout);
if (g_analog)