CubicSDR/src/AppFrame.cpp

214 lines
6.2 KiB
C++
Raw Normal View History

#include "AppFrame.h"
#include "wx/wxprec.h"
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#if !wxUSE_GLCANVAS
#error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
#endif
#include <vector>
#include "SDRThread.h"
2014-11-16 16:51:45 -05:00
#include "DemodulatorThread.h"
#include "AudioThread.h"
#include "CubicSDR.h"
wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
//EVT_MENU(wxID_NEW, AppFrame::OnNewWindow)
EVT_MENU(wxID_CLOSE, AppFrame::OnClose)
EVT_THREAD(EVENT_SDR_INPUT, AppFrame::OnEventInput)
2014-11-16 16:51:45 -05:00
EVT_THREAD(EVENT_DEMOD_INPUT, AppFrame::OnDemodInput)
EVT_THREAD(EVENT_AUDIO_INPUT, AppFrame::OnAudioInput)
EVT_IDLE(AppFrame::OnIdle)
wxEND_EVENT_TABLE()
AppFrame::AppFrame() :
wxFrame(NULL, wxID_ANY, wxT("CubicSDR")), frequency(DEFAULT_FREQ) {
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
scopeCanvas = new ScopeCanvas(this, NULL);
vbox->Add(scopeCanvas, 1, wxEXPAND | wxALL, 0);
vbox->AddSpacer(2);
spectrumCanvas = new SpectrumCanvas(this, NULL);
vbox->Add(spectrumCanvas, 1, wxEXPAND | wxALL, 0);
vbox->AddSpacer(2);
waterfallCanvas = new WaterfallCanvas(this, NULL);
vbox->Add(waterfallCanvas, 4, wxEXPAND | wxALL, 0);
this->SetSizer(vbox);
2014-10-27 23:52:25 -04:00
// SetIcon(wxICON(sample));
// Make a menubar
wxMenu *menu = new wxMenu;
// menu->Append(wxID_NEW);
// menu->AppendSeparator();
menu->Append(wxID_CLOSE);
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menu, wxT("&File"));
SetMenuBar(menuBar);
CreateStatusBar();
SetClientSize(1280, 600);
Centre();
Show();
2014-11-16 16:51:45 -05:00
threadQueueSDR = new SDRThreadQueue(this);
t_SDR = new SDRThread(threadQueueSDR);
if (t_SDR->Run() != wxTHREAD_NO_ERROR) {
wxLogError
2014-11-16 16:51:45 -05:00
("Can't create the SDR thread!");
delete t_SDR;
t_SDR = NULL;
}
2014-11-16 16:51:45 -05:00
threadQueueDemod = new DemodulatorThreadQueue(this);
t_Demod = new DemodulatorThread(threadQueueDemod);
if (t_Demod->Run() != wxTHREAD_NO_ERROR) {
wxLogError
("Can't create the Demodulator thread!");
delete t_Demod;
t_Demod = NULL;
}
threadQueueAudio = new AudioThreadQueue(this);
t_Audio = new AudioThread(threadQueueAudio);
if (t_Audio->Run() != wxTHREAD_NO_ERROR) {
wxLogError
("Can't create the Audio thread!");
delete t_Audio;
t_Audio = NULL;
}
// t_IQBuffer = new IQBufferThread(this);
// if (t_IQBuffer->Run() != wxTHREAD_NO_ERROR) {
// wxLogError
// ("Can't create the thread!");
// delete t_IQBuffer;
2014-11-16 16:51:45 -05:00
// t_IQBuffer = NULL;
// }
// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
// wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not");
// ShowFullScreen(true);
}
AppFrame::~AppFrame() {
{
wxCriticalSectionLocker enter(m_pThreadCS);
if (t_SDR) {
wxMessageOutputDebug().Printf("CubicSDR: deleting thread");
if (t_SDR->Delete() != wxTHREAD_NO_ERROR) {
wxLogError
("Can't delete the thread!");
}
}
}
// {
// wxCriticalSectionLocker enter(m_pThreadCS);
// if (t_IQBuffer) {
// wxMessageOutputDebug().Printf("CubicSDR: deleting thread");
// if (t_IQBuffer->Delete() != wxTHREAD_NO_ERROR) {
// wxLogError
// ("Can't delete the thread!");
// }
// }
// }
2014-11-16 16:51:45 -05:00
// delete t_SDR;
// delete t_IQBuffer;
2014-11-16 16:51:45 -05:00
delete threadQueueAudio;
delete threadQueueDemod;
delete threadQueueSDR;
}
void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {
// true is to force the frame to close
Close(true);
}
void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
new AppFrame();
}
2014-11-16 16:51:45 -05:00
// SDR IQ -> Demodulator
void AppFrame::OnEventInput(wxThreadEvent& event) {
std::vector<signed char> *new_buffer = event.GetPayload<std::vector<signed char> *>();
2014-11-16 16:51:45 -05:00
// std::cout << new_buffer->size() << std::endl;
if (new_buffer->size()) {
DemodulatorThreadTask task = DemodulatorThreadTask(DemodulatorThreadTask::DEMOD_THREAD_DATA);
task.setData(*new_buffer);
threadQueueDemod->addTask(task, DemodulatorThreadQueue::DEMOD_PRIORITY_HIGHEST);
// test_demod.writeBuffer(new_buffer);
// scopeCanvas->setWaveformPoints(test_demod.waveform_points);
2014-11-16 16:51:45 -05:00
spectrumCanvas->setData(new_buffer);
waterfallCanvas->setData(new_buffer);
} else {
std::cout << "Incoming IQ data empty?" << std::endl;
}
delete new_buffer;
}
2014-11-16 16:51:45 -05:00
// Demodulator -> Audio
void AppFrame::OnDemodInput(wxThreadEvent& event) {
std::vector<float> *new_buffer = event.GetPayload<std::vector<float> *>();
if (new_buffer->size()) {
AudioThreadTask task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA);
task.setData(*new_buffer);
threadQueueAudio->addTask(task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST);
if (scopeCanvas->waveform_points.size() != new_buffer->size() * 2) {
scopeCanvas->waveform_points.resize(new_buffer->size() * 2);
}
for (int i = 0, iMax = new_buffer->size(); i < iMax; i++) {
scopeCanvas->waveform_points[i * 2 + 1] = (*new_buffer)[i] * 0.5f;
scopeCanvas->waveform_points[i * 2] = ((double) i / (double) iMax);
}
2014-11-16 16:51:45 -05:00
} else {
std::cout << "Incoming Demod data empty?" << std::endl;
}
delete new_buffer;
}
2014-11-16 16:51:45 -05:00
// Audio -> Visual
void AppFrame::OnAudioInput(wxThreadEvent& event) {
// std::vector<float> *new_buffer = event.GetPayload<std::vector<float> *>();
//
// if (new_buffer->size()) {
// AudioThreadTask task = AudioThreadTask(AudioThreadTask::AUDIO_THREAD_DATA);
// task.setData(*new_buffer);
// threadQueueAudio->addTask(task, AudioThreadQueue::AUDIO_PRIORITY_HIGHEST);
// } else {
// std::cout << "Incoming Demod data empty?" << std::endl;
// }
// delete new_buffer;
}
void AppFrame::OnIdle(wxIdleEvent& event) {
wxGetApp().Yield();
event.Skip();
}
void AppFrame::setFrequency(unsigned int freq) {
frequency = freq;
SDRThreadTask task = SDRThreadTask(SDRThreadTask::SDR_THREAD_TUNING);
task.setUInt(freq);
2014-11-16 16:51:45 -05:00
threadQueueSDR->addTask(task, SDRThreadQueue::SDR_PRIORITY_HIGHEST);
}
int AppFrame::getFrequency() {
return frequency;
}