mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-05-27 20:52:27 -04:00
Demodulator can now be initialized with parameters
This commit is contained in:
parent
7f5031b6e5
commit
dd42d112c9
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
};
|
||||
|
0
src/demod/DemodulatorMgr.cpp
Normal file
0
src/demod/DemodulatorMgr.cpp
Normal file
65
src/demod/DemodulatorMgr.h
Normal file
65
src/demod/DemodulatorMgr.h
Normal 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, ¶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<DemodulatorInstance *> demods;
|
||||
};
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user