mirror of
https://github.com/cjcliffe/CubicSDR.git
synced 2025-02-03 09:44:26 -05:00
Update remaining buffers, cleanup
This commit is contained in:
parent
8c852ed491
commit
576a77e095
@ -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
|
||||||
@ -73,10 +74,12 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
|
|||||||
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) {
|
||||||
@ -150,10 +153,12 @@ static int audioCallback(void *outputBuffer, void *inputBuffer, unsigned int nBu
|
|||||||
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) {
|
||||||
|
@ -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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
|
@ -32,7 +32,6 @@ public:
|
|||||||
threadQueueControl = tQueue;
|
threadQueueControl = tQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DemodulatorThreadParameters &getParams() {
|
DemodulatorThreadParameters &getParams() {
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
@ -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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ void SDRPostThread::threadMain() {
|
|||||||
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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user