CubicSDR/src/demod/DemodulatorMgr.cpp

244 lines
6.8 KiB
C++
Raw Normal View History

2014-11-22 22:33:32 -05:00
#include <DemodulatorMgr.h>
#include <sstream>
#include <algorithm>
2014-12-10 21:22:13 -05:00
#include "CubicSDR.h"
2014-11-22 22:33:32 -05:00
DemodulatorInstance::DemodulatorInstance() :
2014-12-11 19:07:21 -05:00
t_Demod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL), terminated(false), audioTerminated(false), demodTerminated(
false) {
threadQueueDemod = new DemodulatorThreadInputQueue;
threadQueueCommand = new DemodulatorThreadCommandQueue;
2014-12-11 19:07:21 -05:00
threadQueueNotify = new DemodulatorThreadCommandQueue;
demodulatorThread = new DemodulatorThread(threadQueueDemod, threadQueueNotify);
demodulatorThread->setCommandQueue(threadQueueCommand);
audioInputQueue = new AudioThreadInputQueue;
2014-12-11 19:07:21 -05:00
audioThread = new AudioThread(audioInputQueue, threadQueueNotify);
demodulatorThread->setAudioInputQueue(audioInputQueue);
2014-11-22 22:33:32 -05:00
}
DemodulatorInstance::~DemodulatorInstance() {
delete audioThread;
2014-12-11 19:07:21 -05:00
delete demodulatorThread;
delete audioInputQueue;
delete threadQueueDemod;
2014-12-01 19:45:34 -05:00
#ifndef __APPLE__
2014-12-11 19:07:21 -05:00
// delete t_Demod;
2014-12-01 19:45:34 -05:00
#endif
2014-12-11 19:07:21 -05:00
// delete t_Audio;
}
2014-11-22 22:33:32 -05:00
void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
demodulatorThread->setVisualOutputQueue(tQueue);
}
void DemodulatorInstance::run() {
t_Audio = new std::thread(&AudioThread::threadMain, audioThread);
#ifdef __APPLE__ // Already using pthreads, might as well do some custom init..
pthread_attr_t attr;
size_t size;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 2048000);
pthread_attr_getstacksize(&attr, &size);
pthread_create(&t_Demod, &attr, &DemodulatorThread::pthread_helper, demodulatorThread);
pthread_attr_destroy(&attr);
std::cout << "Initialized demodulator stack size of " << size << std::endl;
#else
2014-11-22 22:33:32 -05:00
t_Demod = new std::thread(&DemodulatorThread::threadMain, demodulatorThread);
#endif
2014-11-22 22:33:32 -05:00
}
DemodulatorThreadCommandQueue *DemodulatorInstance::getCommandQueue() {
return threadQueueCommand;
}
DemodulatorThreadParameters &DemodulatorInstance::getParams() {
return demodulatorThread->getParams();
}
void DemodulatorInstance::terminate() {
std::cout << "Terminating demodulator thread.." << std::endl;
demodulatorThread->terminate();
2014-12-10 21:22:13 -05:00
//#ifdef __APPLE__
// pthread_join(t_Demod,NULL);
//#else
//#endif
std::cout << "Terminating demodulator audio thread.." << std::endl;
audioThread->terminate();
}
std::string DemodulatorInstance::getLabel() {
return label;
}
void DemodulatorInstance::setLabel(std::string labelStr) {
label = labelStr;
}
DemodulatorMgr::DemodulatorMgr() :
2014-12-10 21:22:13 -05:00
activeDemodulator(NULL), lastActiveDemodulator(NULL), activeVisualDemodulator(NULL) {
2014-11-22 22:33:32 -05:00
}
DemodulatorMgr::~DemodulatorMgr() {
terminateAll();
2014-11-22 22:33:32 -05:00
}
DemodulatorInstance *DemodulatorMgr::newThread() {
DemodulatorInstance *newDemod = new DemodulatorInstance;
2014-11-22 22:33:32 -05:00
demods.push_back(newDemod);
std::stringstream label;
label << demods.size();
newDemod->setLabel(label.str());
2014-11-22 22:33:32 -05:00
return newDemod;
}
void DemodulatorMgr::terminateAll() {
while (demods.size()) {
DemodulatorInstance *d = demods.back();
2014-12-11 19:07:21 -05:00
deleteThread(d);
}
}
std::vector<DemodulatorInstance *> &DemodulatorMgr::getDemodulators() {
return demods;
}
2014-12-10 21:22:13 -05:00
void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
std::vector<DemodulatorInstance *>::iterator i;
2014-12-11 19:07:21 -05:00
i = std::find(demods.begin(), demods.end(), demod);
2014-12-10 21:22:13 -05:00
if (activeDemodulator == demod) {
activeDemodulator = NULL;
}
if (lastActiveDemodulator == demod) {
lastActiveDemodulator = NULL;
}
if (activeVisualDemodulator == demod) {
activeVisualDemodulator = NULL;
}
if (i != demods.end()) {
demods.erase(i);
demod->terminate();
}
2014-12-11 19:07:21 -05:00
demods_deleted.push_back(demod);
garbageCollect();
2014-12-10 21:22:13 -05:00
}
std::vector<DemodulatorInstance *> *DemodulatorMgr::getDemodulatorsAt(int freq, int bandwidth) {
std::vector<DemodulatorInstance *> *foundDemods = new std::vector<DemodulatorInstance *>();
for (int i = 0, iMax = demods.size(); i < iMax; i++) {
DemodulatorInstance *testDemod = demods[i];
int freqTest = testDemod->getParams().frequency;
int bandwidthTest = testDemod->getParams().bandwidth;
int halfBandwidthTest = bandwidthTest / 2;
int halfBuffer = bandwidth / 2;
if ((freq <= (freqTest + halfBandwidthTest + halfBuffer)) && (freq >= (freqTest - halfBandwidthTest - halfBuffer))) {
foundDemods->push_back(testDemod);
}
}
return foundDemods;
}
void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool temporary) {
if (!temporary) {
if (activeDemodulator != NULL) {
lastActiveDemodulator = activeDemodulator;
} else {
lastActiveDemodulator = demod;
}
}
2014-12-10 21:22:13 -05:00
if (activeVisualDemodulator) {
activeVisualDemodulator->setVisualOutputQueue(NULL);
}
if (demod) {
demod->setVisualOutputQueue(wxGetApp().getAudioVisualQueue());
activeVisualDemodulator = demod;
} else {
DemodulatorInstance *last = getLastActiveDemodulator();
if (last) {
last->setVisualOutputQueue(wxGetApp().getAudioVisualQueue());
}
activeVisualDemodulator = last;
}
activeDemodulator = demod;
2014-12-11 19:07:21 -05:00
garbageCollect();
}
DemodulatorInstance *DemodulatorMgr::getActiveDemodulator() {
return activeDemodulator;
}
DemodulatorInstance *DemodulatorMgr::getLastActiveDemodulator() {
if (std::find(demods.begin(), demods.end(), lastActiveDemodulator) == demods.end()) {
lastActiveDemodulator = activeDemodulator;
}
return lastActiveDemodulator;
}
2014-12-11 19:07:21 -05:00
void DemodulatorMgr::garbageCollect() {
if (demods_deleted.size()) {
std::vector<DemodulatorInstance *>::iterator i;
for (i = demods_deleted.begin(); i != demods_deleted.end(); i++) {
if ((*i)->isTerminated()) {
DemodulatorInstance *deleted = (*i);
demods_deleted.erase(i);
std::cout << "Garbage collected demodulator instance " << deleted->getLabel() << std::endl;
delete deleted;
return;
}
}
}
}
bool DemodulatorInstance::isTerminated() {
while (!threadQueueNotify->empty()) {
DemodulatorThreadCommand cmd;
threadQueueNotify->pop(cmd);
switch (cmd.cmd) {
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED:
audioThread = NULL;
t_Audio->join();
audioTerminated = true;
break;
case DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED:
demodulatorThread = NULL;
t_Demod->join();
demodTerminated = true;
break;
default:
break;
}
}
terminated = audioTerminated && demodTerminated;
return terminated;
}