mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2024-11-26 13:48:38 -05:00
Crash fixes, apply FIR filter to stereo output
This commit is contained in:
parent
5e9414702d
commit
a93deee564
@ -31,7 +31,7 @@ public:
|
||||
}
|
||||
|
||||
~AudioThreadInput() {
|
||||
|
||||
std::lock_guard < std::mutex > lock(m_mutex);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -83,7 +83,7 @@ public:
|
||||
}
|
||||
|
||||
~DemodulatorThreadPostIQData() {
|
||||
|
||||
std::lock_guard < std::mutex > lock(m_mutex);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,6 @@ protected:
|
||||
DemodulatorThreadCommandQueue* commandQueue;
|
||||
AudioThreadInputQueue *audioInputQueue;
|
||||
|
||||
firfilt_crcf fir_filter;
|
||||
msresamp_crcf resampler;
|
||||
float resample_ratio;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user