Crash fixes, apply FIR filter to stereo output

This commit is contained in:
Charles J. Cliffe 2014-12-27 15:04:43 -05:00
parent 5e9414702d
commit a93deee564
8 changed files with 53 additions and 70 deletions

View File

@ -31,7 +31,7 @@ public:
}
~AudioThreadInput() {
std::lock_guard < std::mutex > lock(m_mutex);
}
};

View File

@ -83,7 +83,7 @@ public:
}
~DemodulatorThreadPostIQData() {
std::lock_guard < std::mutex > lock(m_mutex);
}
};

View File

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

View File

@ -52,7 +52,6 @@ protected:
DemodulatorThreadCommandQueue* commandQueue;
AudioThreadInputQueue *audioInputQueue;
firfilt_crcf fir_filter;
msresamp_crcf resampler;
float resample_ratio;

View File

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

View File

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

View File

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

View File

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