Can now spawn/delete demodulators

This commit is contained in:
Charles J. Cliffe 2014-12-10 21:22:13 -05:00
parent f2c59fedd1
commit 4d35075655
16 changed files with 132 additions and 121 deletions

View File

@ -41,6 +41,9 @@ AppFrame::AppFrame() :
this->SetSizer(vbox);
waterfallCanvas->SetFocusFromKbd();
waterfallCanvas->SetFocus();
// SetIcon(wxICON(sample));
// Make a menubar

View File

@ -21,15 +21,11 @@ bool CubicSDR::OnInit() {
frequency = DEFAULT_FREQ;
for (int i = 0; i < NUM_DEMODULATORS; i++) {
demodulatorTest[i] = demodMgr.newThread();
demodulatorTest[i]->getParams().frequency = DEFAULT_FREQ;
demodulatorTest[i]->run();
}
audioVisualQueue = new DemodulatorThreadOutputQueue();
demodulatorTest[0]->setVisualOutputQueue(audioVisualQueue);
demodMgr.setActiveDemodulator(demodulatorTest[0]);
audioVisualQueue->set_max_num_items(1);
// demodulatorTest[0]->setVisualOutputQueue(audioVisualQueue);
// demodMgr.setActiveDemodulator(demodulatorTest[0]);
threadCmdQueueSDR = new SDRThreadCommandQueue;
sdrThread = new SDRThread(threadCmdQueueSDR);
@ -38,15 +34,12 @@ bool CubicSDR::OnInit() {
iqPostDataQueue = new SDRThreadIQDataQueue;
iqVisualQueue = new SDRThreadIQDataQueue;
iqVisualQueue->set_max_num_items(1);
sdrThread->setIQDataOutQueue(iqPostDataQueue);
sdrPostThread->setIQDataInQueue(iqPostDataQueue);
sdrPostThread->setIQVisualQueue(iqVisualQueue);
for (int i = 0; i < NUM_DEMODULATORS; i++) {
sdrPostThread->bindDemodulator(demodulatorTest[i]);
}
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
@ -82,7 +75,6 @@ int CubicSDR::OnExit() {
demodMgr.terminateAll();
delete threadCmdQueueSDR;
delete iqVisualQueue;
@ -117,3 +109,29 @@ void CubicSDR::setFrequency(unsigned int freq) {
int CubicSDR::getFrequency() {
return frequency;
}
DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() {
return audioVisualQueue;
}
SDRThreadIQDataQueue* CubicSDR::getIQVisualQueue() {
return iqVisualQueue;
}
DemodulatorMgr &CubicSDR::getDemodMgr() {
return demodMgr;
}
void CubicSDR::bindDemodulator(DemodulatorInstance *demod) {
if (!demod) {
return;
}
sdrPostThread->bindDemodulator(demod);
}
void CubicSDR::removeDemodulator(DemodulatorInstance *demod) {
if (!demod) {
return;
}
sdrPostThread->removeDemodulator(demod);
}

View File

@ -21,7 +21,7 @@ class CubicSDR: public wxApp {
public:
CubicSDR() :
m_glContext(NULL), t_PostSDR(NULL), t_SDR(NULL), audioVisualQueue(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), frequency(
DEFAULT_FREQ), sdrPostThread(NULL), iqPostDataQueue(NULL), sdrThread(NULL) {
DEFAULT_FREQ), sdrPostThread(NULL), iqPostDataQueue(NULL), sdrThread(NULL) {
}
@ -33,25 +33,12 @@ public:
void setFrequency(unsigned int freq);
int getFrequency();
DemodulatorThreadOutputQueue* getAudioVisualQueue() {
return audioVisualQueue;
}
DemodulatorThreadOutputQueue* getAudioVisualQueue();
SDRThreadIQDataQueue* getIQVisualQueue();
DemodulatorMgr &getDemodMgr();
SDRThreadIQDataQueue* getIQVisualQueue() {
return iqVisualQueue;
}
DemodulatorInstance *getDemodTest() {
return demodulatorTest[0];
}
DemodulatorMgr &getDemodMgr() {
return demodMgr;
}
void bindDemodulator(DemodulatorInstance *newDemod) {
sdrPostThread->bindDemodulator(newDemod);
}
void bindDemodulator(DemodulatorInstance *demod);
void removeDemodulator(DemodulatorInstance *demod);
private:
PrimaryGLContext *m_glContext;
@ -60,8 +47,6 @@ private:
unsigned int frequency;
DemodulatorInstance *demodulatorTest[NUM_DEMODULATORS];
SDRThread *sdrThread;
SDRPostThread *sdrPostThread;

View File

@ -1,6 +1,7 @@
#include <DemodulatorMgr.h>
#include <sstream>
#include <algorithm>
#include "CubicSDR.h"
DemodulatorInstance::DemodulatorInstance() :
t_Demod(NULL), t_Audio(NULL), threadQueueDemod(NULL), demodulatorThread(NULL) {
@ -83,14 +84,12 @@ DemodulatorThreadParameters &DemodulatorInstance::getParams() {
void DemodulatorInstance::terminate() {
std::cout << "Terminating demodulator thread.." << std::endl;
demodulatorThread->terminate();
#ifdef __APPLE__
pthread_join(t_Demod,NULL);
#else
t_Demod->join();
#endif
//#ifdef __APPLE__
// pthread_join(t_Demod,NULL);
//#else
//#endif
std::cout << "Terminating demodulator audio thread.." << std::endl;
audioThread->terminate();
t_Audio->join();
}
std::string DemodulatorInstance::getLabel() {
@ -102,7 +101,7 @@ void DemodulatorInstance::setLabel(std::string labelStr) {
}
DemodulatorMgr::DemodulatorMgr() :
activeDemodulator(NULL), lastActiveDemodulator(NULL) {
activeDemodulator(NULL), lastActiveDemodulator(NULL), activeVisualDemodulator(NULL) {
}
@ -127,7 +126,6 @@ void DemodulatorMgr::terminateAll() {
DemodulatorInstance *d = demods.back();
demods.pop_back();
d->terminate();
delete d;
}
}
@ -135,6 +133,27 @@ std::vector<DemodulatorInstance *> &DemodulatorMgr::getDemodulators() {
return demods;
}
void DemodulatorMgr::deleteThread(DemodulatorInstance *demod) {
std::vector<DemodulatorInstance *>::iterator i;
i = std::find(demods.begin(),demods.end(),demod);
if (activeDemodulator == demod) {
activeDemodulator = NULL;
}
if (lastActiveDemodulator == demod) {
lastActiveDemodulator = NULL;
}
if (activeVisualDemodulator == demod) {
activeVisualDemodulator = NULL;
}
if (i != demods.end()) {
demods.erase(i);
demod->terminate();
}
}
std::vector<DemodulatorInstance *> *DemodulatorMgr::getDemodulatorsAt(int freq, int bandwidth) {
std::vector<DemodulatorInstance *> *foundDemods = new std::vector<DemodulatorInstance *>();
@ -163,6 +182,22 @@ void DemodulatorMgr::setActiveDemodulator(DemodulatorInstance *demod, bool tempo
lastActiveDemodulator = demod;
}
}
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;
}

View File

@ -47,6 +47,7 @@ public:
DemodulatorInstance *newThread();
std::vector<DemodulatorInstance *> &getDemodulators();
std::vector<DemodulatorInstance *> *getDemodulatorsAt(int freq, int bandwidth);
void deleteThread(DemodulatorInstance *);
void terminateAll();
@ -58,4 +59,5 @@ private:
std::vector<DemodulatorInstance *> demods;
DemodulatorInstance *activeDemodulator;
DemodulatorInstance *lastActiveDemodulator;
DemodulatorInstance *activeVisualDemodulator;
};

View File

@ -255,7 +255,5 @@ void DemodulatorThread::terminate() {
terminated = true;
DemodulatorThreadIQData inp; // push dummy to nudge queue
inputQueue->push(inp);
workerThread->terminate();
t_Worker->join();
}

View File

@ -131,7 +131,6 @@ public:
void setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) {
visOutQueue = tQueue;
visOutQueue->set_max_num_items(1);
}
void setCommandQueue(DemodulatorThreadCommandQueue *tQueue) {

View File

@ -50,7 +50,9 @@ void SDRPostThread::threadMain() {
}
if (iqVisualQueue != NULL) {
iqVisualQueue.load()->push(dataOut);
if (iqVisualQueue.load()->empty()) {
iqVisualQueue.load()->push(dataOut);
}
}
if (demodulators.size()) {

View File

@ -1,6 +1,7 @@
#pragma once
#include "SDRThread.h"
#include <algorithm>
class SDRPostThread {
public:
@ -15,6 +16,20 @@ public:
demodulators.push_back(demod);
}
void removeDemodulator(DemodulatorInstance *demod) {
if (!demod) {
return;
}
std::vector<DemodulatorInstance *>::iterator i;
i = std::find(demodulators.begin(), demodulators.end(), demod);
if (i != demodulators.end()) {
demodulators.erase(i);
}
}
void threadMain();
void setIQDataInQueue(SDRThreadIQDataQueue* iqDataQueue) {
@ -25,7 +40,6 @@ public:
}
void setIQVisualQueue(SDRThreadIQDataQueue *iqVisQueue) {
iqVisualQueue = iqVisQueue;
iqVisualQueue.load()->set_max_num_items(1);
}
void terminate();

View File

@ -194,7 +194,7 @@ void PrimaryGLContext::DrawFreqSelector(float uxPos, float r, float g, float b)
int bw = 0;
if (!demod) {
bw = 200000;
bw = defaultDemodParams.bandwidth;
} else {
bw = demod->getParams().bandwidth;
}
@ -211,7 +211,7 @@ void PrimaryGLContext::DrawFreqSelector(float uxPos, float r, float g, float b)
glVertex3f((uxPos - 0.5) * 2.0, 1.0, 0.0);
glVertex3f((uxPos - 0.5) * 2.0, -1.0, 0.0);
float ofs = ((float) demod->getParams().bandwidth) / (float) SRATE;
float ofs = ((float) bw) / (float) SRATE;
glVertex3f((uxPos - 0.5) * 2.0 - ofs, 1.0, 0.0);
glVertex3f((uxPos - 0.5) * 2.0 - ofs, -1.0, 0.0);

View File

@ -29,4 +29,5 @@ public:
private:
static GLFont fonts[GLFONT_MAX];
DemodulatorThreadParameters defaultDemodParams;
};

View File

@ -16,7 +16,6 @@
#include <algorithm>
wxBEGIN_EVENT_TABLE(ScopeCanvas, wxGLCanvas) EVT_PAINT(ScopeCanvas::OnPaint)
EVT_KEY_DOWN(ScopeCanvas::OnKeyDown)
EVT_IDLE(ScopeCanvas::OnIdle)
wxEND_EVENT_TABLE()
@ -48,35 +47,6 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
SwapBuffers();
}
void ScopeCanvas::OnKeyDown(wxKeyEvent& event) {
float angle = 5.0;
unsigned int freq;
switch (event.GetKeyCode()) {
case WXK_RIGHT:
freq = wxGetApp().getFrequency();
freq += SRATE/2;
wxGetApp().setFrequency(freq);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_LEFT:
freq = wxGetApp().getFrequency();
freq -= SRATE/2;
wxGetApp().setFrequency(freq);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_DOWN:
break;
case WXK_UP:
break;
case WXK_SPACE:
break;
default:
event.Skip();
return;
}
}
void ScopeCanvas::OnIdle(wxIdleEvent &event) {
// timer.update();
// frameTimer += timer.lastUpdateSeconds();

View File

@ -21,7 +21,6 @@ public:
void setWaveformPoints(std::vector<float> &waveform_points_in);
private:
void OnPaint(wxPaintEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnIdle(wxIdleEvent &event);

View File

@ -17,7 +17,6 @@
#include <wx/numformatter.h>
wxBEGIN_EVENT_TABLE(SpectrumCanvas, wxGLCanvas) EVT_PAINT(SpectrumCanvas::OnPaint)
EVT_KEY_DOWN(SpectrumCanvas::OnKeyDown)
EVT_IDLE(SpectrumCanvas::OnIdle)
EVT_MOTION(SpectrumCanvas::mouseMoved)
EVT_LEFT_DOWN(SpectrumCanvas::mouseDown)
@ -75,35 +74,6 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
SwapBuffers();
}
void SpectrumCanvas::OnKeyDown(wxKeyEvent& event) {
float angle = 5.0;
unsigned int freq;
switch (event.GetKeyCode()) {
case WXK_RIGHT:
freq = wxGetApp().getFrequency();
freq += SRATE / 2;
wxGetApp().setFrequency(freq);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_LEFT:
freq = wxGetApp().getFrequency();
freq -= SRATE / 2;
wxGetApp().setFrequency(freq);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_DOWN:
break;
case WXK_UP:
break;
case WXK_SPACE:
break;
default:
event.Skip();
return;
}
}
void SpectrumCanvas::setData(std::vector<signed char> *data) {
if (data && data->size()) {

View File

@ -20,7 +20,6 @@ public:
void setData(std::vector<signed char> *data);
private:
void OnPaint(wxPaintEvent& event);
void OnKeyDown(wxKeyEvent& event);
void OnIdle(wxIdleEvent &event);

View File

@ -30,8 +30,8 @@ wxEND_EVENT_TABLE()
WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) :
wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), activeDemodulatorBandwidth(0), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(
false) {
wxFULL_REPAINT_ON_RESIZE), parent(parent), frameTimer(0), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), shiftDown(
false), activeDemodulatorBandwidth(0), activeDemodulatorFrequency(0) {
int in_block_size = BUF_SIZE / 2;
int out_block_size = FFT_SIZE;
@ -88,6 +88,8 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glContext->DrawDemod(lastActiveDemodulator, 1, 0, 0);
glContext->DrawFreqSelector(mTracker.getMouseX(), 1, 1, 0);
}
} else {
glContext->DrawFreqSelector(mTracker.getMouseX(), 1, 1, 0);
}
} else {
if (lastActiveDemodulator) {
@ -117,6 +119,7 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
}
void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) {
shiftDown = event.ShiftDown();
// switch (event.GetKeyCode()) {
// }
@ -125,6 +128,10 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) {
void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
float angle = 5.0;
shiftDown = event.ShiftDown();
DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator();
unsigned int freq;
switch (event.GetKeyCode()) {
case WXK_RIGHT:
@ -139,12 +146,15 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) {
wxGetApp().setFrequency(freq);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), freq));
break;
case WXK_DOWN:
break;
case WXK_UP:
break;
case WXK_SPACE:
case 'D':
case WXK_DELETE:
if (!activeDemod) {
break;
}
wxGetApp().getDemodMgr().deleteThread(activeDemod);
wxGetApp().removeDemodulator(activeDemod);
break;
default:
event.Skip();
return;
@ -354,6 +364,8 @@ void WaterfallCanvas::mouseDown(wxMouseEvent& event) {
mTracker.OnMouseDown(event);
dragState = nextDragState;
shiftDown = event.ShiftDown();
if (dragState) {
wxGetApp().getDemodMgr().setActiveDemodulator(wxGetApp().getDemodMgr().getActiveDemodulator(), false);
}
@ -363,13 +375,14 @@ void WaterfallCanvas::mouseDown(wxMouseEvent& event) {
}
void WaterfallCanvas::mouseWheelMoved(wxMouseEvent& event) {
DemodulatorInstance *demod = wxGetApp().getDemodTest();
mTracker.OnMouseWheelMoved(event);
}
void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
mTracker.OnMouseReleased(event);
shiftDown = event.ShiftDown();
mTracker.setVertDragLock(true);
mTracker.setHorizDragLock(true);
@ -380,7 +393,7 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
int center_freq = wxGetApp().getFrequency();
int freq = center_freq - (int) (0.5 * (float) SRATE) + (int) ((float) pos * (float) SRATE);
if (!shiftDown) {
if (!shiftDown && wxGetApp().getDemodMgr().getDemodulators().size()) {
demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
} else {
demod = wxGetApp().getDemodMgr().newThread();
@ -393,6 +406,8 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
demod->run();
wxGetApp().bindDemodulator(demod);
wxGetApp().getDemodMgr().setActiveDemodulator(demod);
}
if (dragState == WF_DRAG_NONE) {
@ -401,12 +416,13 @@ void WaterfallCanvas::mouseReleased(wxMouseEvent& event) {
return;
}
DemodulatorThreadCommand command;
command.cmd = DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_FREQUENCY;
command.int_value = freq;
demod->getCommandQueue()->push(command); // doesn't always work on first push?
demod->getCommandQueue()->push(command);
((wxFrame*) parent)->GetStatusBar()->SetStatusText(
wxString::Format(wxT("Set demodulator frequency: %s"),
wxNumberFormatter::ToString((long) freq, wxNumberFormatter::Style_WithThousandsSep)));