Demodulator can now be initialized with parameters

This commit is contained in:
Charles J. Cliffe 2014-11-17 22:58:56 -05:00
parent 7f5031b6e5
commit dd42d112c9
8 changed files with 123 additions and 34 deletions

View File

@ -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

View File

@ -12,7 +12,7 @@
#include <vector>
#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);

View File

@ -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();
};

View File

View File

@ -0,0 +1,65 @@
#pragma once
#include <vector>
#include <map>
#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, &params);
}
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<DemodulatorInstance *> demods;
};

View File

@ -3,17 +3,21 @@
#include <vector>
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);
}

View File

@ -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;
};

View File

@ -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 {