Update remaining buffers, cleanup

This commit is contained in:
Charles J. Cliffe 2014-12-24 01:28:33 -05:00
parent 8c852ed491
commit 576a77e095
13 changed files with 159 additions and 110 deletions

View File

@ -10,7 +10,8 @@ std::map<int, std::thread *> AudioThread::deviceThread;
#endif #endif
AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) : AudioThread::AudioThread(AudioThreadInputQueue *inputQueue, DemodulatorThreadCommandQueue* threadQueueNotify) :
currentInput(NULL), inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), gain(1.0), threadQueueNotify(threadQueueNotify) { currentInput(NULL), inputQueue(inputQueue), audio_queue_ptr(0), underflow_count(0), terminated(false), active(false), gain(1.0), threadQueueNotify(
threadQueueNotify) {
#ifdef __APPLE__ #ifdef __APPLE__
boundThreads = new std::vector<AudioThread *>; boundThreads = new std::vector<AudioThread *>;
#endif #endif
@ -72,11 +73,13 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
srcmix->audio_queue_ptr = 0; srcmix->audio_queue_ptr = 0;
continue; continue;
} }
std::lock_guard < std::mutex > lock(srcmix->currentInput->m_mutex);
if (srcmix->currentInput->channels == 0 || !srcmix->currentInput->data.size()) { if (srcmix->currentInput->channels == 0 || !srcmix->currentInput->data.size()) {
if (!srcmix->inputQueue->empty()) { if (!srcmix->inputQueue->empty()) {
if (srcmix->currentInput) { if (srcmix->currentInput) {
delete srcmix->currentInput; srcmix->currentInput->decRefCount();
srcmix->currentInput = NULL; srcmix->currentInput = NULL;
} }
if (srcmix->terminated) { if (srcmix->terminated) {
@ -92,7 +95,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
for (int i = 0; i < nBufferFrames; i++) { for (int i = 0; i < nBufferFrames; i++) {
if (srcmix->audio_queue_ptr >= srcmix->currentInput->data.size()) { if (srcmix->audio_queue_ptr >= srcmix->currentInput->data.size()) {
if (srcmix->currentInput) { if (srcmix->currentInput) {
delete srcmix->currentInput; srcmix->currentInput->decRefCount();
srcmix->currentInput = NULL; srcmix->currentInput = NULL;
} }
if (srcmix->terminated) { if (srcmix->terminated) {
@ -112,7 +115,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
for (int i = 0, iMax = src->currentInput->channels * nBufferFrames; i < iMax; i++) { for (int i = 0, iMax = src->currentInput->channels * nBufferFrames; i < iMax; i++) {
if (srcmix->audio_queue_ptr >= srcmix->currentInput->data.size()) { if (srcmix->audio_queue_ptr >= srcmix->currentInput->data.size()) {
if (srcmix->currentInput) { if (srcmix->currentInput) {
delete srcmix->currentInput; srcmix->currentInput->decRefCount();
srcmix->currentInput = NULL; srcmix->currentInput = NULL;
} }
if (srcmix->terminated) { if (srcmix->terminated) {
@ -143,17 +146,19 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
if (status) { if (status) {
std::cout << "Audio buffer underflow.." << (src->underflow_count++) << std::endl; std::cout << "Audio buffer underflow.." << (src->underflow_count++) << std::endl;
} }
if (!src->currentInput) { if (!src->currentInput) {
src->inputQueue->pop(src->currentInput); src->inputQueue->pop(src->currentInput);
src->audio_queue_ptr = 0; src->audio_queue_ptr = 0;
return 0; return 0;
} }
std::lock_guard < std::mutex > lock(src->currentInput->m_mutex);
if (src->currentInput->channels == 0 || !src->currentInput->data.size()) { if (src->currentInput->channels == 0 || !src->currentInput->data.size()) {
if (!src->inputQueue->empty()) { if (!src->inputQueue->empty()) {
if (src->currentInput) { if (src->currentInput) {
delete src->currentInput; src->currentInput->decRefCount();
src->currentInput = NULL; src->currentInput = NULL;
} }
if (src->terminated) { if (src->terminated) {
@ -169,7 +174,7 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
for (int i = 0; i < nBufferFrames; i++) { for (int i = 0; i < nBufferFrames; i++) {
if (src->audio_queue_ptr >= src->currentInput->data.size()) { if (src->audio_queue_ptr >= src->currentInput->data.size()) {
if (src->currentInput) { if (src->currentInput) {
delete src->currentInput; src->currentInput->decRefCount();
src->currentInput = NULL; src->currentInput = NULL;
} }
if (src->terminated) { if (src->terminated) {

View File

@ -18,14 +18,15 @@
#include "RtAudio.h" #include "RtAudio.h"
#include "DemodDefs.h" #include "DemodDefs.h"
class AudioThreadInput: public ReferenceCounter { class AudioThreadInput: public ReferenceCounter {
public: public:
int frequency; int frequency;
int sampleRate; int sampleRate;
int channels; int channels;
std::vector<float> data; std::vector<float> data;
AudioThreadInput(): frequency(0), sampleRate(0), channels(0) { AudioThreadInput() :
frequency(0), sampleRate(0), channels(0) {
} }

View File

@ -8,10 +8,7 @@
#include <mutex> #include <mutex>
enum DemodulatorType { enum DemodulatorType {
DEMOD_TYPE_NULL, DEMOD_TYPE_NULL, DEMOD_TYPE_AM, DEMOD_TYPE_FM, DEMOD_TYPE_LSB, DEMOD_TYPE_USB
DEMOD_TYPE_AM,
DEMOD_TYPE_FM,
DEMOD_TYPE_LSB, DEMOD_TYPE_USB
}; };
class DemodulatorThread; class DemodulatorThread;
@ -34,19 +31,17 @@ public:
DemodulatorThreadCommand(DemodulatorThreadCommandEnum cmd) : DemodulatorThreadCommand(DemodulatorThreadCommandEnum cmd) :
cmd(cmd), context(NULL), int_value(0) { cmd(cmd), context(NULL), int_value(0) {
} }
DemodulatorThreadCommandEnum cmd; DemodulatorThreadCommandEnum cmd;
void *context; void *context;
int int_value; int int_value;
}; };
class DemodulatorThreadControlCommand { class DemodulatorThreadControlCommand {
public: public:
enum DemodulatorThreadControlCommandEnum { enum DemodulatorThreadControlCommandEnum {
DEMOD_THREAD_CMD_CTL_NULL, DEMOD_THREAD_CMD_CTL_NULL, DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO, DEMOD_THREAD_CMD_CTL_SQUELCH_OFF
DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO,
DEMOD_THREAD_CMD_CTL_SQUELCH_OFF
}; };
DemodulatorThreadControlCommand() : DemodulatorThreadControlCommand() :
@ -56,62 +51,61 @@ public:
DemodulatorThreadControlCommandEnum cmd; DemodulatorThreadControlCommandEnum cmd;
}; };
class DemodulatorThreadIQData : public ReferenceCounter { class DemodulatorThreadIQData: public ReferenceCounter {
public: public:
unsigned int frequency; unsigned int frequency;
unsigned int bandwidth; unsigned int bandwidth;
std::vector<signed char> data; std::vector<signed char> data;
DemodulatorThreadIQData() : DemodulatorThreadIQData() :
frequency(0), bandwidth(0) { frequency(0), bandwidth(0) {
} }
~DemodulatorThreadIQData() { ~DemodulatorThreadIQData() {
} }
}; };
class DemodulatorThreadPostIQData : public ReferenceCounter { class DemodulatorThreadPostIQData: public ReferenceCounter {
public: public:
std::vector<liquid_float_complex> data; std::vector<liquid_float_complex> data;
float audio_resample_ratio; float audio_resample_ratio;
msresamp_rrrf audio_resampler; msresamp_rrrf audio_resampler;
float resample_ratio; float resample_ratio;
msresamp_crcf resampler; msresamp_crcf resampler;
DemodulatorThreadPostIQData(): audio_resample_ratio(0), audio_resampler(NULL), resample_ratio(0), resampler(NULL) { DemodulatorThreadPostIQData() :
audio_resample_ratio(0), audio_resampler(NULL), resample_ratio(0), resampler(NULL) {
} }
~DemodulatorThreadPostIQData() { ~DemodulatorThreadPostIQData() {
} }
}; };
class DemodulatorThreadAudioData: public ReferenceCounter {
class DemodulatorThreadAudioData : public ReferenceCounter {
public: public:
unsigned int frequency; unsigned int frequency;
unsigned int sampleRate; unsigned int sampleRate;
unsigned char channels; unsigned char channels;
std::vector<float> *data; std::vector<float> *data;
DemodulatorThreadAudioData() : DemodulatorThreadAudioData() :
frequency(0), sampleRate(0), channels(0), data(NULL) { frequency(0), sampleRate(0), channels(0), data(NULL) {
} }
DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, DemodulatorThreadAudioData(unsigned int frequency, unsigned int sampleRate, std::vector<float> *data) :
std::vector<float> *data) : frequency(frequency), sampleRate(sampleRate), channels(1), data(data) {
frequency(frequency), sampleRate(sampleRate), channels(1), data(data) {
} }
~DemodulatorThreadAudioData() { ~DemodulatorThreadAudioData() {
} }
}; };
typedef ThreadQueue<DemodulatorThreadIQData *> DemodulatorThreadInputQueue; typedef ThreadQueue<DemodulatorThreadIQData *> DemodulatorThreadInputQueue;
@ -119,7 +113,6 @@ typedef ThreadQueue<DemodulatorThreadPostIQData *> DemodulatorThreadPostInputQue
typedef ThreadQueue<DemodulatorThreadCommand> DemodulatorThreadCommandQueue; typedef ThreadQueue<DemodulatorThreadCommand> DemodulatorThreadCommandQueue;
typedef ThreadQueue<DemodulatorThreadControlCommand> DemodulatorThreadControlCommandQueue; typedef ThreadQueue<DemodulatorThreadControlCommand> DemodulatorThreadControlCommandQueue;
class DemodulatorThreadParameters { class DemodulatorThreadParameters {
public: public:
unsigned int frequency; unsigned int frequency;
@ -131,7 +124,7 @@ public:
DemodulatorThreadParameters() : DemodulatorThreadParameters() :
frequency(0), inputRate(SRATE), bandwidth(200000), audioSampleRate( frequency(0), inputRate(SRATE), bandwidth(200000), audioSampleRate(
AUDIO_FREQUENCY), demodType(DEMOD_TYPE_FM) { AUDIO_FREQUENCY), demodType(DEMOD_TYPE_FM) {
} }

View File

@ -77,12 +77,12 @@ DemodulatorThreadParameters &DemodulatorInstance::getParams() {
} }
void DemodulatorInstance::terminate() { void DemodulatorInstance::terminate() {
std::cout << "Terminating demodulator preprocessor thread.." << std::endl;
demodulatorPreThread->terminate();
std::cout << "Terminating demodulator thread.." << std::endl;
demodulatorThread->terminate();
std::cout << "Terminating demodulator audio thread.." << std::endl; std::cout << "Terminating demodulator audio thread.." << std::endl;
audioThread->terminate(); audioThread->terminate();
std::cout << "Terminating demodulator thread.." << std::endl;
demodulatorThread->terminate();
std::cout << "Terminating demodulator preprocessor thread.." << std::endl;
demodulatorPreThread->terminate();
} }
std::string DemodulatorInstance::getLabel() { std::string DemodulatorInstance::getLabel() {
@ -146,7 +146,6 @@ void DemodulatorInstance::setActive(bool state) {
audioThread->setActive(state); audioThread->setActive(state);
} }
void DemodulatorInstance::squelchAuto() { void DemodulatorInstance::squelchAuto() {
DemodulatorThreadControlCommand command; DemodulatorThreadControlCommand command;
command.cmd = DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO; command.cmd = DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO;

View File

@ -49,16 +49,11 @@ public:
bool isActive(); bool isActive();
void setActive(bool state); void setActive(bool state);
void squelchAuto(); void squelchAuto();bool isSquelchEnabled();
bool isSquelchEnabled();
void setSquelchEnabled(bool state); void setSquelchEnabled(bool state);
private: private:
std::atomic<std::string *> label; std::atomic<std::string *> label;bool terminated;bool demodTerminated;bool audioTerminated;bool preDemodTerminated;
bool terminated;
bool demodTerminated;
bool audioTerminated;
bool preDemodTerminated;
std::atomic<bool> active; std::atomic<bool> active;
std::atomic<bool> squelch; std::atomic<bool> squelch;
}; };

View File

@ -10,7 +10,8 @@
DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* pQueueIn, DemodulatorThreadPostInputQueue* pQueueOut, DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* pQueueIn, DemodulatorThreadPostInputQueue* pQueueOut,
DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) : DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) :
inputQueue(pQueueIn), postInputQueue(pQueueOut), terminated(false), initialized(false), audio_resampler(NULL), resample_ratio(1), audio_resample_ratio( inputQueue(pQueueIn), postInputQueue(pQueueOut), terminated(false), initialized(false), audio_resampler(NULL), resample_ratio(1), audio_resample_ratio(
1), resampler(NULL), commandQueue(NULL), fir_filter(NULL), audioInputQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl) { 1), resampler(NULL), commandQueue(NULL), fir_filter(NULL), audioInputQueue(NULL), threadQueueNotify(threadQueueNotify), threadQueueControl(
threadQueueControl) {
float kf = 0.5; // modulation factor float kf = 0.5; // modulation factor
fdem = freqdem_create(kf); fdem = freqdem_create(kf);
@ -90,7 +91,7 @@ void DemodulatorPreThread::threadMain() {
#ifdef __APPLE__ #ifdef __APPLE__
pthread_t tID = pthread_self(); // ID of this thread pthread_t tID = pthread_self(); // ID of this thread
int priority = sched_get_priority_max( SCHED_FIFO )-1; int priority = sched_get_priority_max( SCHED_FIFO )-1;
sched_param prio = { priority }; // scheduling priority of thread sched_param prio = {priority}; // scheduling priority of thread
pthread_setschedparam(tID, SCHED_FIFO, &prio); pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif #endif
@ -99,6 +100,10 @@ void DemodulatorPreThread::threadMain() {
} }
std::cout << "Demodulator preprocessor thread started.." << std::endl; std::cout << "Demodulator preprocessor thread started.." << std::endl;
std::deque<DemodulatorThreadPostIQData *> buffers;
std::deque<DemodulatorThreadPostIQData *>::iterator buffers_i;
while (!terminated) { while (!terminated) {
DemodulatorThreadIQData *inp; DemodulatorThreadIQData *inp;
inputQueue->pop(inp); inputQueue->pop(inp);
@ -157,7 +162,7 @@ void DemodulatorPreThread::threadMain() {
continue; continue;
} }
std::lock_guard < std::mutex > lock(inp->m_mutex); // std::lock_guard < std::mutex > lock(inp->m_mutex);
std::vector<signed char> *data = &inp->data; std::vector<signed char> *data = &inp->data;
if (data->size()) { if (data->size()) {
int bufSize = data->size() / 2; int bufSize = data->size() / 2;
@ -174,8 +179,6 @@ void DemodulatorPreThread::threadMain() {
in_buf[i].imag = (float) (*data)[i * 2 + 1] / 127.0f; in_buf[i].imag = (float) (*data)[i * 2 + 1] / 127.0f;
} }
inp->decRefCount();
if (shift_freq != 0) { if (shift_freq != 0) {
if (shift_freq < 0) { if (shift_freq < 0) {
nco_crcf_mix_block_up(nco_shift, in_buf, out_buf, bufSize); nco_crcf_mix_block_up(nco_shift, in_buf, out_buf, bufSize);
@ -187,8 +190,22 @@ void DemodulatorPreThread::threadMain() {
out_buf = temp_buf; out_buf = temp_buf;
} }
DemodulatorThreadPostIQData *resamp = new DemodulatorThreadPostIQData; DemodulatorThreadPostIQData *resamp = NULL;
resamp->data.assign(in_buf,in_buf+bufSize);
for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) {
if ((*buffers_i)->getRefCount() <= 0) {
resamp = (*buffers_i);
break;
}
}
if (resamp == NULL) {
resamp = new DemodulatorThreadPostIQData;
buffers.push_back(resamp);
}
resamp->setRefCount(1);
resamp->data.assign(in_buf, in_buf + bufSize);
// firfilt_crcf_execute_block(fir_filter, in_buf, bufSize, &((*resamp.data)[0])); // firfilt_crcf_execute_block(fir_filter, in_buf, bufSize, &((*resamp.data)[0]));
@ -198,6 +215,8 @@ void DemodulatorPreThread::threadMain() {
resamp->resampler = resampler; resamp->resampler = resampler;
postInputQueue->push(resamp); postInputQueue->push(resamp);
inp->decRefCount();
} else { } else {
inp->decRefCount(); inp->decRefCount();
} }
@ -230,6 +249,13 @@ void DemodulatorPreThread::threadMain() {
} }
} }
while (!buffers.empty()) {
DemodulatorThreadPostIQData *iqDataDel = buffers.front();
buffers.pop_front();
std::lock_guard < std::mutex > lock(iqDataDel->m_mutex);
delete iqDataDel;
}
std::cout << "Demodulator preprocessor thread done." << std::endl; std::cout << "Demodulator preprocessor thread done." << std::endl;
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED); DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED);
tCmd.context = this; tCmd.context = this;

View File

@ -32,7 +32,6 @@ public:
threadQueueControl = tQueue; threadQueueControl = tQueue;
} }
DemodulatorThreadParameters &getParams() { DemodulatorThreadParameters &getParams() {
return params; return params;
} }

View File

@ -6,8 +6,10 @@
#include <pthread.h> #include <pthread.h>
#endif #endif
DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* pQueue, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) : DemodulatorThread::DemodulatorThread(DemodulatorThreadPostInputQueue* pQueue, DemodulatorThreadControlCommandQueue *threadQueueControl,
postInputQueue(pQueue), visOutQueue(NULL), audioInputQueue(NULL), agc(NULL), terminated(false), threadQueueNotify(threadQueueNotify), threadQueueControl(threadQueueControl), squelch_level(0), squelch_tolerance(0), squelch_enabled(false) { DemodulatorThreadCommandQueue* threadQueueNotify) :
postInputQueue(pQueue), visOutQueue(NULL), audioInputQueue(NULL), agc(NULL), terminated(false), threadQueueNotify(threadQueueNotify), threadQueueControl(
threadQueueControl), squelch_level(0), squelch_tolerance(0), squelch_enabled(false) {
float kf = 0.5; // modulation factor float kf = 0.5; // modulation factor
fdem = freqdem_create(kf); fdem = freqdem_create(kf);
@ -35,14 +37,19 @@ void DemodulatorThread::threadMain() {
agc_crcf_set_bandwidth(agc, 1e-3f); agc_crcf_set_bandwidth(agc, 1e-3f);
std::cout << "Demodulator thread started.." << std::endl; std::cout << "Demodulator thread started.." << std::endl;
std::deque<AudioThreadInput *> buffers;
std::deque<AudioThreadInput *>::iterator buffers_i;
while (!terminated) { while (!terminated) {
DemodulatorThreadPostIQData *inp; DemodulatorThreadPostIQData *inp;
postInputQueue->pop(inp); postInputQueue->pop(inp);
std::lock_guard < std::mutex > lock(inp->m_mutex);
int bufSize = inp->data.size(); int bufSize = inp->data.size();
if (!bufSize) { if (!bufSize) {
delete inp; inp->decRefCount();
continue; continue;
} }
@ -76,26 +83,40 @@ void DemodulatorThread::threadMain() {
unsigned int num_audio_written; unsigned int num_audio_written;
msresamp_rrrf_execute(audio_resampler, demod_output, num_written, resampled_audio_output, &num_audio_written); msresamp_rrrf_execute(audio_resampler, demod_output, num_written, resampled_audio_output, &num_audio_written);
AudioThreadInput *ati = new AudioThreadInput;
ati->channels = 1;
ati->data.assign(resampled_audio_output,resampled_audio_output+num_audio_written);
if (audioInputQueue != NULL) { if (audioInputQueue != NULL) {
if (!squelch_enabled || ((agc_crcf_get_signal_level(agc)) >= 0.1)) { 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) {
ati = (*buffers_i);
break;
}
}
if (ati == NULL) {
ati = new AudioThreadInput;
buffers.push_back(ati);
}
ati->setRefCount(1);
ati->channels = 1;
ati->data.assign(resampled_audio_output, resampled_audio_output + num_audio_written);
audioInputQueue->push(ati); audioInputQueue->push(ati);
} }
} }
if (visOutQueue != NULL && visOutQueue->empty()) { if (visOutQueue != NULL && visOutQueue->empty()) {
AudioThreadInput *ati_vis = new AudioThreadInput; AudioThreadInput *ati_vis = new AudioThreadInput;
ati_vis->channels = ati->channels; ati_vis->channels = 1;
int num_vis = DEMOD_VIS_SIZE; int num_vis = DEMOD_VIS_SIZE;
if (num_audio_written > num_written) { if (num_audio_written > num_written) {
if (num_vis > num_audio_written) { if (num_vis > num_audio_written) {
num_vis = num_audio_written; num_vis = num_audio_written;
} }
ati_vis->data.assign(ati->data.begin(), ati->data.begin()+num_vis); ati_vis->data.assign(resampled_audio_output, resampled_audio_output + num_vis);
} else { } else {
if (num_vis > num_written) { if (num_vis > num_written) {
num_vis = num_written; num_vis = num_written;
@ -115,7 +136,7 @@ void DemodulatorThread::threadMain() {
switch (command.cmd) { switch (command.cmd) {
case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO: case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_AUTO:
squelch_level = agc_crcf_get_signal_level(agc); squelch_level = agc_crcf_get_signal_level(agc);
squelch_tolerance = agc_crcf_get_signal_level(agc)/2.0; squelch_tolerance = agc_crcf_get_signal_level(agc) / 2.0;
squelch_enabled = true; squelch_enabled = true;
break; break;
case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_OFF: case DemodulatorThreadControlCommand::DEMOD_THREAD_CMD_CTL_SQUELCH_OFF:
@ -129,7 +150,7 @@ void DemodulatorThread::threadMain() {
} }
} }
delete inp; inp->decRefCount();
} }
if (resampler != NULL) { if (resampler != NULL) {
@ -141,6 +162,13 @@ void DemodulatorThread::threadMain() {
agc_crcf_destroy(agc); agc_crcf_destroy(agc);
while (!buffers.empty()) {
AudioThreadInput *audioDataDel = buffers.front();
buffers.pop_front();
std::lock_guard < std::mutex > lock(audioDataDel->m_mutex);
delete audioDataDel;
}
std::cout << "Demodulator thread done." << std::endl; std::cout << "Demodulator thread done." << std::endl;
DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED); DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED);
tCmd.context = this; tCmd.context = this;

View File

@ -13,7 +13,8 @@ typedef ThreadQueue<AudioThreadInput *> DemodulatorThreadOutputQueue;
class DemodulatorThread { class DemodulatorThread {
public: public:
DemodulatorThread(DemodulatorThreadPostInputQueue* pQueueIn, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify); DemodulatorThread(DemodulatorThreadPostInputQueue* pQueueIn, DemodulatorThreadControlCommandQueue *threadQueueControl,
DemodulatorThreadCommandQueue* threadQueueNotify);
~DemodulatorThread(); ~DemodulatorThread();
#ifdef __APPLE__ #ifdef __APPLE__
@ -53,6 +54,5 @@ protected:
DemodulatorThreadCommandQueue* threadQueueNotify; DemodulatorThreadCommandQueue* threadQueueNotify;
DemodulatorThreadControlCommandQueue *threadQueueControl; DemodulatorThreadControlCommandQueue *threadQueueControl;
float squelch_level; float squelch_level;
float squelch_tolerance; float squelch_tolerance;bool squelch_enabled;
bool squelch_enabled;
}; };

View File

@ -22,14 +22,14 @@ public:
}; };
DemodulatorWorkerThreadResult() : DemodulatorWorkerThreadResult() :
cmd(DEMOD_WORKER_THREAD_RESULT_NULL), fir_filter(NULL), resampler(NULL), resample_ratio( cmd(DEMOD_WORKER_THREAD_RESULT_NULL), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), audio_resample_ratio(
0), audio_resampler(NULL), audio_resample_ratio(0), inputRate(0), bandwidth(0), audioSampleRate(0) { 0), inputRate(0), bandwidth(0), audioSampleRate(0) {
} }
DemodulatorWorkerThreadResult(DemodulatorThreadResultEnum cmd) : DemodulatorWorkerThreadResult(DemodulatorThreadResultEnum cmd) :
cmd(cmd), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), audio_resample_ratio( cmd(cmd), fir_filter(NULL), resampler(NULL), resample_ratio(0), audio_resampler(NULL), audio_resample_ratio(0), inputRate(0), bandwidth(
0), inputRate(0), bandwidth(0), audioSampleRate(0) { 0), audioSampleRate(0) {
} }

View File

@ -41,7 +41,7 @@ void SDRPostThread::threadMain() {
#ifdef __APPLE__ #ifdef __APPLE__
pthread_t tID = pthread_self(); // ID of this thread pthread_t tID = pthread_self(); // ID of this thread
int priority = sched_get_priority_max( SCHED_FIFO) - 1; int priority = sched_get_priority_max( SCHED_FIFO) - 1;
sched_param prio = { priority }; // scheduling priority of thread sched_param prio = {priority}; // scheduling priority of thread
pthread_setschedparam(tID, SCHED_FIFO, &prio); pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif #endif
@ -123,22 +123,22 @@ void SDRPostThread::threadMain() {
} }
if (demodulators.size()) { if (demodulators.size()) {
DemodulatorThreadIQData *demodDataOut = NULL; DemodulatorThreadIQData *demodDataOut = NULL;
for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) { for (buffers_i = buffers.begin(); buffers_i != buffers.end(); buffers_i++) {
if ((*buffers_i)->getRefCount() <= 0) { if ((*buffers_i)->getRefCount() <= 0) {
demodDataOut = (*buffers_i); demodDataOut = (*buffers_i);
break; break;
} }
} }
if (demodDataOut == NULL) { if (demodDataOut == NULL) {
demodDataOut = new DemodulatorThreadIQData; demodDataOut = new DemodulatorThreadIQData;
buffers.push_back(demodDataOut); buffers.push_back(demodDataOut);
} }
std::lock_guard < std::mutex > lock(demodDataOut->m_mutex); // std::lock_guard < std::mutex > lock(demodDataOut->m_mutex);
demodDataOut->frequency = data_in->frequency; demodDataOut->frequency = data_in->frequency;
demodDataOut->bandwidth = data_in->bandwidth; demodDataOut->bandwidth = data_in->bandwidth;
demodDataOut->setRefCount(activeDemods); demodDataOut->setRefCount(activeDemods);
@ -183,8 +183,8 @@ void SDRPostThread::threadMain() {
while (!buffers.empty()) { while (!buffers.empty()) {
DemodulatorThreadIQData *demodDataDel = buffers.front(); DemodulatorThreadIQData *demodDataDel = buffers.front();
buffers.pop_front(); buffers.pop_front();
std::lock_guard < std::mutex > lock(demodDataDel->m_mutex); // std::lock_guard < std::mutex > lock(demodDataDel->m_mutex);
delete demodDataDel; // delete demodDataDel;
} }
std::cout << "SDR post-processing thread done." << std::endl; std::cout << "SDR post-processing thread done." << std::endl;

View File

@ -92,7 +92,7 @@ void SDRThread::threadMain() {
#ifdef __APPLE__ #ifdef __APPLE__
pthread_t tID = pthread_self(); // ID of this thread pthread_t tID = pthread_self(); // ID of this thread
int priority = sched_get_priority_max( SCHED_FIFO) - 1; int priority = sched_get_priority_max( SCHED_FIFO) - 1;
sched_param prio = { priority }; // scheduling priority of thread sched_param prio = {priority}; // scheduling priority of thread
pthread_setschedparam(tID, SCHED_FIFO, &prio); pthread_setschedparam(tID, SCHED_FIFO, &prio);
#endif #endif
@ -176,7 +176,7 @@ void SDRThread::threadMain() {
buffers.push_back(dataOut); buffers.push_back(dataOut);
} }
std::lock_guard < std::mutex > lock(dataOut->m_mutex); // std::lock_guard < std::mutex > lock(dataOut->m_mutex);
dataOut->setRefCount(1); dataOut->setRefCount(1);
dataOut->frequency = frequency; dataOut->frequency = frequency;
dataOut->bandwidth = bandwidth; dataOut->bandwidth = bandwidth;
@ -200,8 +200,8 @@ void SDRThread::threadMain() {
while (!buffers.empty()) { while (!buffers.empty()) {
SDRThreadIQData *iqDataDel = buffers.front(); SDRThreadIQData *iqDataDel = buffers.front();
buffers.pop_front(); buffers.pop_front();
std::lock_guard < std::mutex > lock(iqDataDel->m_mutex); // std::lock_guard < std::mutex > lock(iqDataDel->m_mutex);
delete iqDataDel; // delete iqDataDel;
} }
std::cout << "SDR thread done." << std::endl; std::cout << "SDR thread done." << std::endl;

View File

@ -30,7 +30,8 @@ wxEND_EVENT_TABLE()
WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false) { wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0), dragState(
WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(false), altDown(false), ctrlDown(false) {
int in_block_size = FFT_SIZE; int in_block_size = FFT_SIZE;
int out_block_size = FFT_SIZE; int out_block_size = FFT_SIZE;
@ -76,7 +77,8 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
DemodulatorInstance *activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator(); DemodulatorInstance *activeDemodulator = wxGetApp().getDemodMgr().getActiveDemodulator();
DemodulatorInstance *lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator(); DemodulatorInstance *lastActiveDemodulator = wxGetApp().getDemodMgr().getLastActiveDemodulator();
bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); bool isNew = shiftDown
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive());
if (mTracker.mouseInView()) { if (mTracker.mouseInView()) {
if (nextDragState == WF_DRAG_RANGE) { if (nextDragState == WF_DRAG_RANGE) {
@ -163,7 +165,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
case WXK_RIGHT: case WXK_RIGHT:
freq = wxGetApp().getFrequency(); freq = wxGetApp().getFrequency();
if (shiftDown) { if (shiftDown) {
freq += SRATE*10; freq += SRATE * 10;
} else { } else {
freq += SRATE / 2; freq += SRATE / 2;
} }
@ -173,7 +175,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
case WXK_LEFT: case WXK_LEFT:
freq = wxGetApp().getFrequency(); freq = wxGetApp().getFrequency();
if (shiftDown) { if (shiftDown) {
freq -= SRATE*10; freq -= SRATE * 10;
} else { } else {
freq -= SRATE / 2; freq -= SRATE / 2;
} }
@ -438,7 +440,8 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
altDown = event.AltDown(); altDown = event.AltDown();
ctrlDown = event.ControlDown(); ctrlDown = event.ControlDown();
bool isNew = shiftDown || (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive()); bool isNew = shiftDown
|| (wxGetApp().getDemodMgr().getLastActiveDemodulator() && !wxGetApp().getDemodMgr().getLastActiveDemodulator()->isActive());
mTracker.setVertDragLock(false); mTracker.setVertDragLock(false);
mTracker.setHorizDragLock(false); mTracker.setHorizDragLock(false);