CubicSDR/src/AppFrame.cpp

204 lines
6.0 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"
#include "DemodulatorMgr.h"
2014-11-16 16:51:45 -05:00
#include "AudioThread.h"
#include "CubicSDR.h"
2014-11-21 21:50:14 -05:00
#include <thread>
#include <wx/panel.h>
wxBEGIN_EVENT_TABLE(AppFrame, wxFrame)
//EVT_MENU(wxID_NEW, AppFrame::OnNewWindow)
EVT_MENU(wxID_CLOSE, AppFrame::OnClose)
EVT_COMMAND(wxID_ANY, wxEVT_THREAD, AppFrame::OnThread)
EVT_IDLE(AppFrame::OnIdle)
wxEND_EVENT_TABLE()
AppFrame::AppFrame() :
wxFrame(NULL, wxID_ANY, wxT("CubicSDR")) {
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *demodOpts = new wxBoxSizer(wxVERTICAL);
2014-12-28 20:55:05 -05:00
wxBoxSizer *demodVisuals = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *demodTray = new wxBoxSizer(wxHORIZONTAL);
demodTray->AddSpacer(5);
demodOpts->AddSpacer(5);
wxStaticText *audioDeviceLabel = new wxStaticText(this, wxID_ANY, wxString("Audio Device:"));
demodOpts->Add(audioDeviceLabel, 1, wxFIXED_MINSIZE | wxALL, 0);
wxArrayString str;
str.Add("Primary Device");
wxChoice *wxCh = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, str);
demodOpts->Add(wxCh, 1, wxFIXED_MINSIZE | wxALL, 0);
demodOpts->AddSpacer(2);
wxStaticText *demodTypeLabel = new wxStaticText(this, wxID_ANY, wxString("Demodulation:"));
demodOpts->Add(demodTypeLabel, 1, wxFIXED_MINSIZE | wxALL, 0);
str.Clear();
str.Add("FM");
str.Add("FM Stereo");
str.Add("AM");
str.Add("LSB");
str.Add("USB");
wxChoice *wxDemodChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, str);
demodOpts->Add(wxDemodChoice, 1, wxFIXED_MINSIZE | wxALL, 0);
demodOpts->AddSpacer(5);
demodTray->AddSpacer(5);
demodTray->Add(demodOpts, 1, wxEXPAND | wxALL, 0);
2014-12-28 20:55:05 -05:00
demodWaterfallCanvas = new WaterfallCanvas(this, NULL);
demodWaterfallCanvas->Setup(1024,128);
demodWaterfallCanvas->SetView(DEFAULT_FREQ,300000);
2014-12-28 20:55:05 -05:00
demodVisuals->Add(demodWaterfallCanvas, 3, wxEXPAND | wxALL, 0);
demodTray->Add(demodVisuals, 7, wxEXPAND | wxALL, 0);
demodTray->AddSpacer(2);
scopeCanvas = new ScopeCanvas(this, NULL);
demodTray->Add(scopeCanvas, 7, wxEXPAND | wxALL, 0);
2014-12-28 20:55:05 -05:00
vbox->Add(demodTray, 2, wxEXPAND | wxALL, 0);
vbox->AddSpacer(2);
spectrumCanvas = new SpectrumCanvas(this, NULL);
spectrumCanvas->Setup(2048);
vbox->Add(spectrumCanvas, 1, wxEXPAND | wxALL, 0);
vbox->AddSpacer(2);
waterfallCanvas = new WaterfallCanvas(this, NULL);
waterfallCanvas->Setup(2048,512);
vbox->Add(waterfallCanvas, 4, wxEXPAND | wxALL, 0);
this->SetSizer(vbox);
2014-12-10 21:22:13 -05:00
waterfallCanvas->SetFocusFromKbd();
waterfallCanvas->SetFocus();
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-12-16 21:30:03 -05:00
GetStatusBar()->SetStatusText(wxString::Format(wxT("Set center frequency: %i"), DEFAULT_FREQ));
// 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() {
}
void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) {
// true is to force the frame to close
Close(true);
}
void AppFrame::OnNewWindow(wxCommandEvent& WXUNUSED(event)) {
new AppFrame();
}
void AppFrame::OnThread(wxCommandEvent& event) {
event.Skip();
2014-11-16 16:51:45 -05:00
}
void AppFrame::OnIdle(wxIdleEvent& event) {
bool work_done = false;
//#ifdef __APPLE__
// std::this_thread::sleep_for(std::chrono::milliseconds(4));
// std::this_thread::yield();
//#endif
DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator();
if (demod) {
2014-12-28 20:55:05 -05:00
if (demodWaterfallCanvas->getDragState() == WaterfallCanvas::WF_DRAG_NONE) {
if (demod->getParams().frequency != demodWaterfallCanvas->GetCenterFrequency()) {
demodWaterfallCanvas->SetCenterFrequency(demod->getParams().frequency);
}
unsigned int demodBw = (unsigned int) ceil((float) demod->getParams().bandwidth * 2.5);
if (demodBw > SRATE/2) {
demodBw = SRATE/2;
}
if (demodBw != demodWaterfallCanvas->GetBandwidth()) {
demodWaterfallCanvas->SetBandwidth(demodBw);
}
}
}
if (!wxGetApp().getIQVisualQueue()->empty()) {
2014-12-26 16:15:35 -05:00
DemodulatorThreadIQData *iqData;
wxGetApp().getIQVisualQueue()->pop(iqData);
2014-12-23 01:59:03 -05:00
if (iqData && iqData->data.size()) {
spectrumCanvas->setData(iqData);
waterfallCanvas->setData(iqData);
demodWaterfallCanvas->setData(iqData);
2014-12-23 01:59:03 -05:00
delete iqData;
} else {
std::cout << "Incoming IQ data empty?" << std::endl;
}
work_done = true;
}
if (!wxGetApp().getAudioVisualQueue()->empty()) {
2014-12-23 01:59:03 -05:00
AudioThreadInput *demodAudioData;
wxGetApp().getAudioVisualQueue()->pop(demodAudioData);
2014-12-23 01:59:03 -05:00
if (demodAudioData && demodAudioData->data.size()) {
if (scopeCanvas->waveform_points.size() != demodAudioData->data.size() * 2) {
scopeCanvas->waveform_points.resize(demodAudioData->data.size() * 2);
}
2014-12-23 01:59:03 -05:00
for (int i = 0, iMax = demodAudioData->data.size(); i < iMax; i++) {
scopeCanvas->waveform_points[i * 2 + 1] = demodAudioData->data[i] * 0.5f;
scopeCanvas->waveform_points[i * 2] = ((double) i / (double) iMax);
}
2014-12-26 23:28:18 -05:00
scopeCanvas->setDivider(demodAudioData->channels == 2);
2014-12-23 01:59:03 -05:00
delete demodAudioData;
} else {
std::cout << "Incoming Demodulator data empty?" << std::endl;
}
work_done = true;
}
if (!work_done) {
2014-12-16 21:30:03 -05:00
event.Skip();
}
}