From 6624ec11a37267a39025bb5badc59e396c04cb07 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Tue, 18 Nov 2014 18:00:06 -0500 Subject: [PATCH] IQ->Demod->Audio threads now chained No longer passing anything through the main thread which was causing audio and IQ interrupts on UI events -- hopefully improves OSX jitter. SDRThread can now have unlimited Demodulator bindings.. :) --- src/AppFrame.cpp | 17 ++++++----------- src/demod/DemodulatorThread.cpp | 6 ++++++ src/demod/DemodulatorThread.h | 2 +- src/demod/DemodulatorThreadTask.h | 5 ++++- src/sdr/SDRThread.cpp | 9 +++++++++ src/sdr/SDRThread.h | 8 ++++++++ 6 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 3d508f1..647e9a6 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -65,9 +65,6 @@ AppFrame::AppFrame() : t_SDR = NULL; } - demodulatorTest = demodMgr.newThread(this); - demodulatorTest->run(); - threadQueueAudio = new AudioThreadQueue(this); t_Audio = new AudioThread(threadQueueAudio); if (t_Audio->Run() != wxTHREAD_NO_ERROR) { @@ -77,6 +74,11 @@ AppFrame::AppFrame() : t_Audio = NULL; } + demodulatorTest = demodMgr.newThread(this); + demodulatorTest->params.audioQueue = threadQueueAudio; + demodulatorTest->run(); + + t_SDR->bindDemodulator(*demodulatorTest); // static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 }; // wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not"); // ShowFullScreen(true); @@ -123,10 +125,6 @@ void AppFrame::OnThread(wxCommandEvent& event) { iqData = (SDRThreadIQData *) event.GetClientData(); new_uc_buffer = &(iqData->data); if (new_uc_buffer->size()) { - DemodulatorThreadTask task = DemodulatorThreadTask(DemodulatorThreadTask::DEMOD_THREAD_DATA); - task.data = new DemodulatorThreadIQData(iqData->bandwidth, iqData->frequency, iqData->data); - demodulatorTest->addTask(task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST); - spectrumCanvas->setData(new_uc_buffer); waterfallCanvas->setData(new_uc_buffer); } else { @@ -140,10 +138,7 @@ void AppFrame::OnThread(wxCommandEvent& event) { case DemodulatorThreadTask::DEMOD_THREAD_AUDIO_DATA: demodAudioData = (DemodulatorThreadAudioData *) event.GetClientData(); new_float_buffer = &(demodAudioData->data); - if (new_float_buffer->size()) { - AudioThreadTask task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA); - task.data = new AudioThreadData(demodAudioData->frequency, demodAudioData->sampleRate, demodAudioData->data); - threadQueueAudio->addTask(task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST); + if (new_float_buffer != NULL && new_float_buffer->size()) { if (scopeCanvas->waveform_points.size() != new_float_buffer->size() * 2) { scopeCanvas->waveform_points.resize(new_float_buffer->size() * 2); diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index be093ea..d5a3dd8 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -139,6 +139,12 @@ wxThread::ExitCode DemodulatorThread::Entry() { DemodulatorThreadAudioData *audioOut = new DemodulatorThreadAudioData(task.data->frequency,params.audioSampleRate,newBuffer); m_pQueue->sendAudioData(DemodulatorThreadTask::DEMOD_THREAD_AUDIO_DATA,audioOut); + + if (params.audioQueue != NULL) { + AudioThreadTask audio_task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA); + audio_task.data = new AudioThreadData(task.data->frequency, params.audioSampleRate, newBuffer); + params.audioQueue->addTask(audio_task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST); + } } delete task.data; diff --git a/src/demod/DemodulatorThread.h b/src/demod/DemodulatorThread.h index 21f201a..7f3fcf0 100644 --- a/src/demod/DemodulatorThread.h +++ b/src/demod/DemodulatorThread.h @@ -12,7 +12,7 @@ #include "DemodulatorThreadQueue.h" #include "liquid/liquid.h" - +#include "AudioThread.h" class DemodulatorThread: public wxThread { public: diff --git a/src/demod/DemodulatorThreadTask.h b/src/demod/DemodulatorThreadTask.h index 9bb78c5..80b8355 100644 --- a/src/demod/DemodulatorThreadTask.h +++ b/src/demod/DemodulatorThreadTask.h @@ -5,6 +5,7 @@ #include "wx/string.h" #include "wx/object.h" #include "CubicSDRDefs.h" +#include "AudioThreadQueue.h" enum DemodulatorType { DEMOD_TYPE_NULL, DEMOD_TYPE_AM, DEMOD_TYPE_FM, DEMOD_TYPE_LSB, DEMOD_TYPE_USB, DEMOD_TYPE_WFM @@ -51,10 +52,12 @@ public: unsigned int demodResampleRate; unsigned int filterFrequency; unsigned int audioSampleRate; + AudioThreadQueue *audioQueue; + DemodulatorType demodType; DemodulatorThreadParameters() : - inputRate(SRATE), inputResampleRate(200000), demodResampleRate(100000), audioSampleRate(48000), filterFrequency(32000), demodType(DEMOD_TYPE_WFM) { + audioQueue(NULL), inputRate(SRATE), inputResampleRate(200000), demodResampleRate(100000), audioSampleRate(48000), filterFrequency(32000), demodType(DEMOD_TYPE_WFM) { } diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index 8fd5a50..79232a5 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -160,6 +160,15 @@ wxThread::ExitCode SDRThread::Entry() { if (!TestDestroy()) { SDRThreadIQData *iqData = new SDRThreadIQData(bandwidth,frequency,new_buffer); m_pQueue->sendIQData(SDRThreadTask::SDR_THREAD_DATA, iqData); + + if (demodulators.size()) { + for (int i = 0, iMax = demodulators.size(); ibandwidth, iqData->frequency, iqData->data); + demodQueue->addTask(demod_task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST); + } + } } } else { this->Yield(); diff --git a/src/sdr/SDRThread.h b/src/sdr/SDRThread.h index c52afa5..df1068e 100644 --- a/src/sdr/SDRThread.h +++ b/src/sdr/SDRThread.h @@ -10,6 +10,8 @@ #include "wx/thread.h" #include "SDRThreadQueue.h" +#include "DemodulatorThreadQueue.h" +#include "DemodulatorMgr.h" class SDRThread: public wxThread { public: @@ -20,9 +22,15 @@ public: int enumerate_rtl(); + void bindDemodulator(DemodulatorInstance &demod) { + demodulators.push_back(demod.threadQueueDemod); + } + protected: virtual ExitCode Entry(); uint32_t sample_rate; SDRThreadQueue* m_pQueue; int m_ID; + + std::vector demodulators; };