From a93deee564c0bce26f2931a241726482c32cce5d Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Sat, 27 Dec 2014 15:04:43 -0500 Subject: [PATCH] Crash fixes, apply FIR filter to stereo output --- src/audio/AudioThread.h | 2 +- src/demod/DemodDefs.h | 2 +- src/demod/DemodulatorPreThread.cpp | 31 +-------------- src/demod/DemodulatorPreThread.h | 1 - src/demod/DemodulatorThread.cpp | 56 +++++++++++++++++++++------ src/demod/DemodulatorWorkerThread.cpp | 18 --------- src/demod/DemodulatorWorkerThread.h | 5 +-- src/visual/WaterfallCanvas.cpp | 8 ++-- 8 files changed, 53 insertions(+), 70 deletions(-) diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index da411b3..941fdaf 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -31,7 +31,7 @@ public: } ~AudioThreadInput() { - + std::lock_guard < std::mutex > lock(m_mutex); } }; diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index 93e6511..ac899ba 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -83,7 +83,7 @@ public: } ~DemodulatorThreadPostIQData() { - + std::lock_guard < std::mutex > lock(m_mutex); } }; diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 5a96e49..5acf025 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -10,7 +10,7 @@ DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* pQueueIn, DemodulatorThreadPostInputQueue* pQueueOut, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) : inputQueue(pQueueIn), postInputQueue(pQueueOut), terminated(false), initialized(false), audio_resampler(NULL), stereo_resampler(NULL), resample_ratio(1), audio_resample_ratio( - 1), resampler(NULL), commandQueue(NULL), fir_filter(NULL), audioInputQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl( + 1), resampler(NULL), commandQueue(NULL), audioInputQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl( threadQueueControl) { float kf = 0.5; // modulation factor @@ -33,30 +33,7 @@ void DemodulatorPreThread::initialize() { resample_ratio = (float) (params.bandwidth) / (float) params.inputRate; audio_resample_ratio = (float) (params.audioSampleRate) / (float) params.bandwidth; - float fc = 0.5 * ((double) params.bandwidth / (double) params.inputRate); // filter cutoff frequency - - if (fc <= 0) { - fc = 0; - } - - if (fc >= 0.5) { - fc = 0.5; - } - - float ft = 0.05f; // filter transition float As = 60.0f; // stop-band attenuation [dB] - float mu = 0.0f; // fractional timing offset - - // estimate required filter length and generate filter - unsigned int h_len = estimate_req_filter_len(ft, As); - float h[h_len]; - liquid_firdes_kaiser(h_len, fc, As, mu, h); - - if (fir_filter) { - firfilt_crcf_recreate(fir_filter, h, h_len); - } else { - fir_filter = firfilt_crcf_create(h, h_len); - } // create multi-stage arbitrary resampler object if (resampler) { @@ -240,11 +217,6 @@ void DemodulatorPreThread::threadMain() { switch (result.cmd) { case DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS: - firfilt_crcf_destroy(fir_filter); -// msresamp_crcf_destroy(resampler); -// msresamp_crcf_destroy(audio_resampler); - - fir_filter = result.fir_filter; resampler = result.resampler; audio_resampler = result.audio_resampler; stereo_resampler = result.stereo_resampler; @@ -265,7 +237,6 @@ void DemodulatorPreThread::threadMain() { while (!buffers.empty()) { DemodulatorThreadPostIQData *iqDataDel = buffers.front(); buffers.pop_front(); - std::lock_guard < std::mutex > lock(iqDataDel->m_mutex); delete iqDataDel; } diff --git a/src/demod/DemodulatorPreThread.h b/src/demod/DemodulatorPreThread.h index 540f9a6..7bd0b23 100644 --- a/src/demod/DemodulatorPreThread.h +++ b/src/demod/DemodulatorPreThread.h @@ -52,7 +52,6 @@ protected: DemodulatorThreadCommandQueue* commandQueue; AudioThreadInputQueue *audioInputQueue; - firfilt_crcf fir_filter; msresamp_crcf resampler; float resample_ratio; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 672aa23..3f10217 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -32,8 +32,27 @@ void DemodulatorThread::threadMain() { msresamp_rrrf audio_resampler = NULL; msresamp_rrrf stereo_resampler = NULL; + firfilt_rrrf fir_filter = NULL; + firfilt_rrrf fir_filter2 = NULL; msresamp_crcf resampler = NULL; + float fc = 0.5 * ((double) 36000 / (double) AUDIO_FREQUENCY); // filter cutoff frequency + if (fc <= 0) { + fc = 0; + } + if (fc >= 0.5) { + fc = 0.5; + } + float ft = 0.05f; // filter transition + float As = 60.0f; // stop-band attenuation [dB] + float mu = 0.0f; // fractional timing offset + // estimate required filter length and generate filter + unsigned int h_len = estimate_req_filter_len(ft, As); + float h[h_len]; + liquid_firdes_kaiser(h_len, fc, As, mu, h); + fir_filter = firfilt_rrrf_create(h, h_len); + fir_filter2 = firfilt_rrrf_create(h, h_len); + unsigned int m = 5; // filter semi-length float slsl = 60.0f; // filter sidelobe suppression level liquid_float_complex x, y; @@ -144,7 +163,7 @@ void DemodulatorThread::threadMain() { firhilbf_r2c_execute(firR2C, demod_output[i], &x); nco_crcf_mix_down(nco_shift, x, &y); nco_crcf_step(nco_shift); - firhilbf_c2r_execute(firR2C, y, &demod_output_stereo[i]); + firhilbf_c2r_execute(firC2R, y, &demod_output_stereo[i]); } if (audio_out_size != resampled_audio_output_stereo.size()) { @@ -157,9 +176,10 @@ void DemodulatorThread::threadMain() { msresamp_rrrf_execute(stereo_resampler, &demod_output_stereo[0], num_written, &resampled_audio_output_stereo[0], &num_audio_written); } + AudioThreadInput *ati = NULL; + if (audioInputQueue != NULL) { if (!squelch_enabled || ((agc_crcf_get_signal_level(agc)) >= 0.1)) { - AudioThreadInput *ati = NULL; for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { if ((*buffers_i)->getRefCount() <= 0) { @@ -182,8 +202,16 @@ void DemodulatorThread::threadMain() { } ati->data.resize(num_audio_written * 2); for (int i = 0; i < num_audio_written; i++) { - ati->data[i * 2] = (resampled_audio_output[i] - (resampled_audio_output_stereo[i])); - ati->data[i * 2 + 1] = (resampled_audio_output[i] + (resampled_audio_output_stereo[i])); + float l, r; + + firfilt_rrrf_push(fir_filter, (resampled_audio_output[i] - (resampled_audio_output_stereo[i]))); + firfilt_rrrf_execute(fir_filter, &l); + + firfilt_rrrf_push(fir_filter2, (resampled_audio_output[i] + (resampled_audio_output_stereo[i]))); + firfilt_rrrf_execute(fir_filter2, &r); + + ati->data[i * 2] = l; + ati->data[i * 2 + 1] = r; } } else { ati->channels = 1; @@ -194,25 +222,24 @@ void DemodulatorThread::threadMain() { } } - if (visOutQueue != NULL && visOutQueue->empty()) { + if (ati && visOutQueue != NULL && visOutQueue->empty()) { AudioThreadInput *ati_vis = new AudioThreadInput; - ati_vis->channels = 1; int num_vis = DEMOD_VIS_SIZE; if (stereo) { - - int stereoSize = resampled_audio_output.size(); + ati_vis->channels = 2; + int stereoSize = ati->data.size(); if (stereoSize > DEMOD_VIS_SIZE) { stereoSize = DEMOD_VIS_SIZE; } ati_vis->data.resize(stereoSize); - ati_vis->channels = stereo ? 2 : 1; for (int i = 0; i < stereoSize / 2; i++) { - ati_vis->data[i] = (resampled_audio_output[i] - (resampled_audio_output_stereo[i])); - ati_vis->data[i + stereoSize / 2] = (resampled_audio_output[i] + (resampled_audio_output_stereo[i])); + ati_vis->data[i] = ati->data[i*2]; + ati_vis->data[i + stereoSize / 2] = ati->data[i*2+1]; } } else { + ati_vis->channels = 1; if (num_audio_written > num_written) { if (num_vis > num_audio_written) { @@ -265,6 +292,12 @@ void DemodulatorThread::threadMain() { if (stereo_resampler != NULL) { msresamp_rrrf_destroy(stereo_resampler); } + if (fir_filter != NULL) { + firfilt_rrrf_destroy(fir_filter); + } + if (fir_filter2 != NULL) { + firfilt_rrrf_destroy(fir_filter2); + } agc_crcf_destroy(agc); firhilbf_destroy(firR2C); @@ -274,7 +307,6 @@ void DemodulatorThread::threadMain() { while (!buffers.empty()) { AudioThreadInput *audioDataDel = buffers.front(); buffers.pop_front(); - std::lock_guard < std::mutex > lock(audioDataDel->m_mutex); delete audioDataDel; } diff --git a/src/demod/DemodulatorWorkerThread.cpp b/src/demod/DemodulatorWorkerThread.cpp index 206f2c5..1d79c9f 100644 --- a/src/demod/DemodulatorWorkerThread.cpp +++ b/src/demod/DemodulatorWorkerThread.cpp @@ -37,26 +37,8 @@ void DemodulatorWorkerThread::threadMain() { result.resample_ratio = (float) (filterCommand.bandwidth) / (float) filterCommand.inputRate; result.audio_resample_ratio = (float) (filterCommand.audioSampleRate) / (float) filterCommand.bandwidth; - float fc = 0.5 * ((double) filterCommand.bandwidth / (double) filterCommand.inputRate); // filter cutoff frequency - - if (fc <= 0) { - fc = 0; - } - - if (fc >= 0.5) { - fc = 0.5; - } - - float ft = 0.05f; // filter transition float As = 60.0f; // stop-band attenuation [dB] - float mu = 0.0f; // fractional timing offset - // estimate required filter length and generate filter - unsigned int h_len = estimate_req_filter_len(ft, As); - float h[h_len]; - liquid_firdes_kaiser(h_len, fc, As, mu, h); - - result.fir_filter = firfilt_crcf_create(h, h_len); result.resampler = msresamp_crcf_create(result.resample_ratio, As); result.audio_resampler = msresamp_rrrf_create(result.audio_resample_ratio, As); result.stereo_resampler = msresamp_rrrf_create(result.audio_resample_ratio, As); diff --git a/src/demod/DemodulatorWorkerThread.h b/src/demod/DemodulatorWorkerThread.h index 94e9af7..a51e88d 100644 --- a/src/demod/DemodulatorWorkerThread.h +++ b/src/demod/DemodulatorWorkerThread.h @@ -22,20 +22,19 @@ public: }; DemodulatorWorkerThreadResult() : - cmd(DEMOD_WORKER_THREAD_RESULT_NULL), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), stereo_resampler(NULL), audio_resample_ratio( + cmd(DEMOD_WORKER_THREAD_RESULT_NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), stereo_resampler(NULL), audio_resample_ratio( 0), inputRate(0), bandwidth(0), audioSampleRate(0) { } DemodulatorWorkerThreadResult(DemodulatorThreadResultEnum cmd) : - cmd(cmd), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), stereo_resampler(NULL), audio_resample_ratio(0), inputRate(0), bandwidth( + cmd(cmd), resampler(NULL), resample_ratio(0), audio_resampler(NULL), stereo_resampler(NULL), audio_resample_ratio(0), inputRate(0), bandwidth( 0), audioSampleRate(0) { } DemodulatorThreadResultEnum cmd; - firfilt_crcf fir_filter; msresamp_crcf resampler; float resample_ratio; msresamp_rrrf audio_resampler; diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 1fc00e8..597ecee 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -323,8 +323,8 @@ void WaterfallCanvas::mouseMoved(wxMouseEvent& event) { DemodulatorThreadCommand command; command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_BANDWIDTH; activeDemodulatorBandwidth = activeDemodulatorBandwidth + bwDiff; - if (activeDemodulatorBandwidth < 1000) { - activeDemodulatorBandwidth = 1000; + if (activeDemodulatorBandwidth < 2000) { + activeDemodulatorBandwidth = 2000; } if (activeDemodulatorBandwidth > SRATE) { activeDemodulatorBandwidth = SRATE; @@ -517,8 +517,8 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) { int freq = center_freq - (int) (0.5 * (float) SRATE) + (int) ((float) pos * (float) SRATE); int bandwidth = (int) (fabs(width) * (float) SRATE); - if (bandwidth < 1000) { - bandwidth = 1000; + if (bandwidth < 2000) { + bandwidth = 2000; } if (!bandwidth) {