From dd42d112c99f44038f2fb3d75f48dcdcf40ceff8 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 17 Nov 2014 22:58:56 -0500 Subject: [PATCH] Demodulator can now be initialized with parameters --- CMakeLists.txt | 2 + src/AppFrame.cpp | 16 +++----- src/AppFrame.h | 7 ++-- src/demod/DemodulatorMgr.cpp | 0 src/demod/DemodulatorMgr.h | 65 +++++++++++++++++++++++++++++++ src/demod/DemodulatorThread.cpp | 32 ++++++++------- src/demod/DemodulatorThread.h | 11 +++--- src/demod/DemodulatorThreadTask.h | 24 ++++++++++++ 8 files changed, 123 insertions(+), 34 deletions(-) create mode 100644 src/demod/DemodulatorMgr.cpp create mode 100644 src/demod/DemodulatorMgr.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 244bbfe..10526bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,6 +91,7 @@ SET (cubicsdr_sources src/demod/DemodulatorThread.cpp src/demod/DemodulatorThreadQueue.cpp src/demod/DemodulatorThreadTask.cpp + src/demod/DemodulatorMgr.cpp src/audio/AudioThread.cpp src/audio/AudioThreadQueue.cpp src/audio/AudioThreadTask.cpp @@ -115,6 +116,7 @@ SET (cubicsdr_headers src/demod/DemodulatorThread.h src/demod/DemodulatorThreadQueue.h src/demod/DemodulatorThreadTask.h + src/demod/DemodulatorMgr.h src/audio/AudioThread.h src/audio/AudioThreadQueue.h src/audio/AudioThreadTask.h diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 5a06c78..27aa063 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -12,7 +12,7 @@ #include #include "SDRThread.h" -#include "DemodulatorThread.h" +#include "DemodulatorMgr.h" #include "AudioThread.h" #include "CubicSDR.h" @@ -65,14 +65,9 @@ AppFrame::AppFrame() : t_SDR = NULL; } - threadQueueDemod = new DemodulatorThreadQueue(this); - t_Demod = new DemodulatorThread(threadQueueDemod); - if (t_Demod->Run() != wxTHREAD_NO_ERROR) { - wxLogError - ("Can't create the Demodulator thread!"); - delete t_Demod; - t_Demod = NULL; - } + demodulatorTest = demodMgr.newThread(this); + demodulatorTest->params.inputResampleRate=170000; + demodulatorTest->run(); threadQueueAudio = new AudioThreadQueue(this); t_Audio = new AudioThread(threadQueueAudio); @@ -102,7 +97,6 @@ AppFrame::~AppFrame() { // delete t_SDR; delete threadQueueAudio; - delete threadQueueDemod; delete threadQueueSDR; } @@ -132,7 +126,7 @@ void AppFrame::OnThread(wxCommandEvent& event) { if (new_uc_buffer->size()) { DemodulatorThreadTask task = DemodulatorThreadTask(DemodulatorThreadTask::DEMOD_THREAD_DATA); task.data = new DemodulatorThreadIQData(iqData->bandwidth, iqData->frequency, iqData->data); - threadQueueDemod->addTask(task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST); + demodulatorTest->addTask(task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST); spectrumCanvas->setData(new_uc_buffer); waterfallCanvas->setData(new_uc_buffer); diff --git a/src/AppFrame.h b/src/AppFrame.h index c25431b..60db1a9 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -4,7 +4,7 @@ #include "PrimaryGLContext.h" #include "SDRThread.h" #include "AudioThread.h" -#include "DemodulatorThread.h" +#include "DemodulatorMgr.h" #include "ScopeCanvas.h" #include "SpectrumCanvas.h" @@ -35,12 +35,13 @@ private: SDRThreadQueue* threadQueueSDR; AudioThread *t_Audio; AudioThreadQueue* threadQueueAudio; - DemodulatorThread *t_Demod; - DemodulatorThreadQueue* threadQueueDemod; + DemodulatorMgr demodMgr; wxCriticalSection m_pThreadCS; unsigned int frequency; + DemodulatorInstance *demodulatorTest; + // event table wxDECLARE_EVENT_TABLE(); }; diff --git a/src/demod/DemodulatorMgr.cpp b/src/demod/DemodulatorMgr.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/demod/DemodulatorMgr.h b/src/demod/DemodulatorMgr.h new file mode 100644 index 0000000..3724fd6 --- /dev/null +++ b/src/demod/DemodulatorMgr.h @@ -0,0 +1,65 @@ +#pragma once + +#include +#include + +#include "DemodulatorThread.h" +#include "DemodulatorThreadQueue.h" +#include "DemodulatorThreadTask.h" + +class DemodulatorInstance { +public: + DemodulatorThread *t_Demod; + DemodulatorThreadQueue* threadQueueDemod; + DemodulatorThreadParameters params; + wxEvtHandler* parent; + + DemodulatorInstance(wxEvtHandler* pParent) : + t_Demod(NULL), threadQueueDemod(NULL), parent(pParent) { + } + + void init() { + threadQueueDemod = new DemodulatorThreadQueue(parent); + t_Demod = new DemodulatorThread(threadQueueDemod, ¶ms); + } + + void addTask(const DemodulatorThreadTask& task, const DemodulatorThreadQueue::DEMOD_PRIORITY& priority) { + threadQueueDemod->addTask(task, priority); + } + + bool run() { + init(); + + if (t_Demod->Run() != wxTHREAD_NO_ERROR) { + wxLogError + ("Can't create the Demodulator thread!"); + delete t_Demod; + delete threadQueueDemod; + t_Demod = NULL; + threadQueueDemod = NULL; + } + } +}; + +class DemodulatorMgr { +public: + DemodulatorMgr() { + + } + + ~DemodulatorMgr() { + while (demods.size()) { + DemodulatorInstance *d = demods.back(); + demods.pop_back(); + delete d; + } + } + + DemodulatorInstance *newThread(wxEvtHandler* pParent) { + DemodulatorInstance *newDemod = new DemodulatorInstance(pParent); + demods.push_back(newDemod); + return newDemod; + } + + std::vector demods; +}; diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index d1d0250..be093ea 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -3,17 +3,21 @@ #include -DemodulatorThread::DemodulatorThread(DemodulatorThreadQueue* pQueue, int id) : +DemodulatorThread::DemodulatorThread(DemodulatorThreadQueue* pQueue, DemodulatorThreadParameters *params_in, int id) : wxThread(wxTHREAD_DETACHED), m_pQueue(pQueue), m_ID(id) { - bandwidth = 200000; - resample_ratio = (float) (bandwidth) / (float) SRATE; - wbfm_frequency = 100000; - wbfm_resample_ratio = (float) (wbfm_frequency) / (float) bandwidth; - audio_frequency = AUDIO_FREQUENCY; - audio_resample_ratio = (float) (audio_frequency) / (float) wbfm_frequency; + DemodulatorThreadParameters defaultParams; + if (!params_in) { + params = defaultParams; + } else { + params = *params_in; + } - float fc = 0.5f * ((float) bandwidth / (float) SRATE) * 0.75; // filter cutoff frequency + resample_ratio = (float) (params.inputResampleRate) / (float) params.inputRate; + second_resampler_ratio = (float) (params.demodResampleRate) / (float) params.inputResampleRate; + audio_resample_ratio = (float) (params.audioSampleRate) / (float) params.demodResampleRate; + + float fc = 0.5f * ((float) params.inputResampleRate / (float) params.inputRate) * 0.75; // filter cutoff frequency float ft = 0.05f; // filter transition float As = 60.0f; // stop-band attenuation [dB] float mu = 0.0f; // fractional timing offset @@ -26,7 +30,7 @@ DemodulatorThread::DemodulatorThread(DemodulatorThreadQueue* pQueue, int id) : fir_filter = firfilt_crcf_create(h, h_len); h_len = estimate_req_filter_len(ft, As); - liquid_firdes_kaiser(h_len, 32000.0 / (float) wbfm_frequency, As, mu, h); + liquid_firdes_kaiser(h_len, (float)params.filterFrequency / (float) params.demodResampleRate, As, mu, h); fir_audio_filter = firfilt_crcf_create(h, h_len); @@ -34,8 +38,8 @@ DemodulatorThread::DemodulatorThread(DemodulatorThreadQueue* pQueue, int id) : resampler = msresamp_crcf_create(resample_ratio, As); msresamp_crcf_print(resampler); - wbfm_resampler = msresamp_crcf_create(wbfm_resample_ratio, As); - msresamp_crcf_print(wbfm_resampler); + second_resampler = msresamp_crcf_create(second_resampler_ratio, As); + msresamp_crcf_print(second_resampler); audio_resampler = msresamp_crcf_create(audio_resample_ratio, As); msresamp_crcf_print(audio_resampler); @@ -104,11 +108,11 @@ wxThread::ExitCode DemodulatorThread::Entry() { } } - int wbfm_out_size = ceil((float) (num_written) * wbfm_resample_ratio); + int wbfm_out_size = ceil((float) (num_written) * second_resampler_ratio); liquid_float_complex resampled_wbfm_output[wbfm_out_size]; unsigned int num_wbfm_written; - msresamp_crcf_execute(wbfm_resampler, resampled_output, num_written, resampled_wbfm_output, &num_wbfm_written); + msresamp_crcf_execute(second_resampler, resampled_output, num_written, resampled_wbfm_output, &num_wbfm_written); for (int i = 0; i < num_wbfm_written; i++) { firfilt_crcf_push(fir_audio_filter, resampled_wbfm_output[i]); @@ -132,7 +136,7 @@ wxThread::ExitCode DemodulatorThread::Entry() { if (!TestDestroy()) { - DemodulatorThreadAudioData *audioOut = new DemodulatorThreadAudioData(task.data->frequency,audio_frequency,newBuffer); + DemodulatorThreadAudioData *audioOut = new DemodulatorThreadAudioData(task.data->frequency,params.audioSampleRate,newBuffer); m_pQueue->sendAudioData(DemodulatorThreadTask::DEMOD_THREAD_AUDIO_DATA,audioOut); } diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index 7d053e5..21f201a 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -16,7 +16,8 @@ class DemodulatorThread: public wxThread { public: - DemodulatorThread(DemodulatorThreadQueue* pQueue, int id = 0); + + DemodulatorThread(DemodulatorThreadQueue* pQueue, DemodulatorThreadParameters *params, int id = 0); ~DemodulatorThread(); protected: @@ -27,17 +28,15 @@ protected: firfilt_crcf fir_filter; firfilt_crcf fir_audio_filter; - unsigned int bandwidth; msresamp_crcf resampler; float resample_ratio; - unsigned int wbfm_frequency; - msresamp_crcf wbfm_resampler; - float wbfm_resample_ratio; + msresamp_crcf second_resampler; + float second_resampler_ratio; - unsigned int audio_frequency; msresamp_crcf audio_resampler; float audio_resample_ratio; + DemodulatorThreadParameters params; freqdem fdem; }; diff --git a/src/demod/DemodulatorThreadTask.h b/src/demod/DemodulatorThreadTask.h index 757bdb2..9bb78c5 100644 --- a/src/demod/DemodulatorThreadTask.h +++ b/src/demod/DemodulatorThreadTask.h @@ -4,6 +4,11 @@ #include "wx/defs.h" #include "wx/string.h" #include "wx/object.h" +#include "CubicSDRDefs.h" + +enum DemodulatorType { + DEMOD_TYPE_NULL, DEMOD_TYPE_AM, DEMOD_TYPE_FM, DEMOD_TYPE_LSB, DEMOD_TYPE_USB, DEMOD_TYPE_WFM +}; class DemodulatorThreadIQData: public wxObject { public: @@ -39,6 +44,25 @@ public: } }; +class DemodulatorThreadParameters: public wxObject { +public: + unsigned int inputRate; + unsigned int inputResampleRate; // set equal to disable second stage re-sampling? + unsigned int demodResampleRate; + unsigned int filterFrequency; + unsigned int audioSampleRate; + DemodulatorType demodType; + + DemodulatorThreadParameters() : + inputRate(SRATE), inputResampleRate(200000), demodResampleRate(100000), audioSampleRate(48000), filterFrequency(32000), demodType(DEMOD_TYPE_WFM) { + + } + + ~DemodulatorThreadParameters() { + + } +}; + class DemodulatorThreadTask { public: enum DEMOD_THREAD_COMMAND {