2014-10-27 21:22:29 -04:00
# include "AppFrame.h"
# include "wx/wxprec.h"
# ifndef WX_PRECOMP
# include "wx/wx.h"
# endif
2015-01-06 00:57:57 -05:00
# include "wx/numdlg.h"
2014-10-27 21:22:29 -04:00
# if !wxUSE_GLCANVAS
# error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild the library"
# endif
2014-10-28 21:39:59 -04:00
# include <vector>
# include "SDRThread.h"
2014-11-17 22:58:56 -05:00
# include "DemodulatorMgr.h"
2014-11-16 16:51:45 -05:00
# include "AudioThread.h"
2014-11-16 19:02:40 -05:00
# include "CubicSDR.h"
2014-10-27 21:22:29 -04:00
2014-11-21 21:50:14 -05:00
# include <thread>
2014-12-27 23:47:56 -05:00
# include <wx/panel.h>
2014-10-28 21:39:59 -04:00
wxBEGIN_EVENT_TABLE ( AppFrame , wxFrame )
//EVT_MENU(wxID_NEW, AppFrame::OnNewWindow)
2014-12-31 22:38:59 -05:00
EVT_MENU ( wxID_CLOSE , AppFrame : : OnClose )
2014-12-31 21:31:37 -05:00
EVT_MENU ( wxID_ANY , AppFrame : : OnMenu )
2014-11-17 18:14:37 -05:00
EVT_COMMAND ( wxID_ANY , wxEVT_THREAD , AppFrame : : OnThread )
2014-10-28 21:39:59 -04:00
EVT_IDLE ( AppFrame : : OnIdle )
2014-10-27 21:22:29 -04:00
wxEND_EVENT_TABLE ( )
AppFrame : : AppFrame ( ) :
2014-12-31 21:31:37 -05:00
wxFrame ( NULL , wxID_ANY , wxT ( " CubicSDR " ) ) , activeDemodulator ( NULL ) {
2014-10-27 21:22:29 -04:00
2014-11-15 23:41:41 -05:00
wxBoxSizer * vbox = new wxBoxSizer ( wxVERTICAL ) ;
2014-12-27 23:47:56 -05:00
wxBoxSizer * demodOpts = new wxBoxSizer ( wxVERTICAL ) ;
2014-12-28 20:55:05 -05:00
wxBoxSizer * demodVisuals = new wxBoxSizer ( wxVERTICAL ) ;
wxBoxSizer * demodTray = new wxBoxSizer ( wxHORIZONTAL ) ;
2015-01-04 17:11:20 -05:00
wxBoxSizer * demodScopeTray = new wxBoxSizer ( wxVERTICAL ) ;
2014-12-27 23:47:56 -05:00
2015-01-05 19:12:16 -05:00
demodModeSelector = new ModeSelectorCanvas ( this , NULL ) ;
2015-01-06 00:29:33 -05:00
demodModeSelector - > addChoice ( DEMOD_TYPE_FM , " FM " ) ;
demodModeSelector - > addChoice ( DEMOD_TYPE_AM , " AM " ) ;
demodModeSelector - > addChoice ( DEMOD_TYPE_LSB , " LSB " ) ;
demodModeSelector - > addChoice ( DEMOD_TYPE_USB , " USB " ) ;
2015-01-05 19:12:16 -05:00
demodTray - > Add ( demodModeSelector , 2 , wxEXPAND | wxALL , 0 ) ;
// demodTray->AddSpacer(2);
2014-12-29 00:24:10 -05:00
demodSpectrumCanvas = new SpectrumCanvas ( this , NULL ) ;
2015-01-03 17:07:39 -05:00
demodSpectrumCanvas - > setup ( 1024 ) ;
demodSpectrumCanvas - > setView ( DEFAULT_FREQ , 300000 ) ;
2014-12-29 00:24:10 -05:00
demodVisuals - > Add ( demodSpectrumCanvas , 1 , wxEXPAND | wxALL , 0 ) ;
demodVisuals - > AddSpacer ( 1 ) ;
2014-12-28 20:55:05 -05:00
2014-12-28 05:13:46 -05:00
demodWaterfallCanvas = new WaterfallCanvas ( this , NULL ) ;
2015-01-03 17:07:39 -05:00
demodWaterfallCanvas - > setup ( 1024 , 256 ) ;
demodWaterfallCanvas - > setView ( DEFAULT_FREQ , 300000 ) ;
2014-12-29 00:24:10 -05:00
demodWaterfallCanvas - > attachSpectrumCanvas ( demodSpectrumCanvas ) ;
2015-01-01 21:10:54 -05:00
demodSpectrumCanvas - > attachWaterfallCanvas ( demodWaterfallCanvas ) ;
2014-12-28 20:55:05 -05:00
demodVisuals - > Add ( demodWaterfallCanvas , 3 , wxEXPAND | wxALL , 0 ) ;
2014-12-31 19:45:01 -05:00
demodTray - > Add ( demodVisuals , 30 , wxEXPAND | wxALL , 0 ) ;
demodTray - > AddSpacer ( 2 ) ;
demodSignalMeter = new MeterCanvas ( this , NULL ) ;
demodSignalMeter - > setMax ( 0.5 ) ;
2015-01-04 13:20:31 -05:00
demodSignalMeter - > setHelpTip ( " Current Signal Level. Click / Drag to set Squelch level. " ) ;
2014-12-31 19:45:01 -05:00
demodTray - > Add ( demodSignalMeter , 1 , wxEXPAND | wxALL , 0 ) ;
2014-12-28 20:55:05 -05:00
demodTray - > AddSpacer ( 2 ) ;
2014-12-28 05:13:46 -05:00
2014-11-15 23:41:41 -05:00
scopeCanvas = new ScopeCanvas ( this , NULL ) ;
2015-01-04 17:11:20 -05:00
demodScopeTray - > Add ( scopeCanvas , 8 , wxEXPAND | wxALL , 0 ) ;
demodScopeTray - > AddSpacer ( 2 ) ;
demodTuner = new TuningCanvas ( this , NULL ) ;
demodTuner - > setHelpTip ( " Testing tuner " ) ;
demodScopeTray - > Add ( demodTuner , 1 , wxEXPAND | wxALL , 0 ) ;
demodTray - > Add ( demodScopeTray , 30 , wxEXPAND | wxALL , 0 ) ;
2014-12-27 23:47:56 -05:00
2014-12-28 20:55:05 -05:00
vbox - > Add ( demodTray , 2 , wxEXPAND | wxALL , 0 ) ;
2014-11-15 23:41:41 -05:00
vbox - > AddSpacer ( 2 ) ;
spectrumCanvas = new SpectrumCanvas ( this , NULL ) ;
2015-01-03 17:07:39 -05:00
spectrumCanvas - > setup ( 2048 ) ;
2014-11-15 23:41:41 -05:00
vbox - > Add ( spectrumCanvas , 1 , wxEXPAND | wxALL , 0 ) ;
vbox - > AddSpacer ( 2 ) ;
waterfallCanvas = new WaterfallCanvas ( this , NULL ) ;
2015-01-03 17:07:39 -05:00
waterfallCanvas - > setup ( 2048 , 512 ) ;
2014-12-29 00:24:10 -05:00
waterfallCanvas - > attachSpectrumCanvas ( spectrumCanvas ) ;
2015-01-01 21:10:54 -05:00
spectrumCanvas - > attachWaterfallCanvas ( waterfallCanvas ) ;
2014-11-15 23:41:41 -05:00
vbox - > Add ( waterfallCanvas , 4 , wxEXPAND | wxALL , 0 ) ;
this - > SetSizer ( vbox ) ;
2014-10-27 21:22:29 -04:00
2015-01-06 00:29:33 -05:00
// waterfallCanvas->SetFocusFromKbd();
2014-12-10 21:22:13 -05:00
waterfallCanvas - > SetFocus ( ) ;
2014-10-27 23:52:25 -04:00
// SetIcon(wxICON(sample));
2014-10-27 21:22:29 -04:00
2014-10-28 21:39:59 -04:00
// Make a menubar
2015-01-06 00:29:33 -05:00
wxMenuBar * menuBar = new wxMenuBar ;
wxMenu * menu = new wxMenu ;
2014-10-27 21:22:29 -04:00
// menu->Append(wxID_NEW);
2015-01-06 00:57:57 -05:00
menu - > Append ( wxID_SET_FREQ_OFFSET , " Set Frequency Offset " ) ;
menu - > AppendSeparator ( ) ;
2015-01-06 00:29:33 -05:00
menu - > Append ( wxID_CLOSE ) ;
2014-12-31 19:45:01 -05:00
2015-01-06 00:29:33 -05:00
menuBar - > Append ( menu , wxT ( " &File " ) ) ;
menu = new wxMenu ;
2014-12-31 19:45:01 -05:00
std : : vector < RtAudio : : DeviceInfo > : : iterator devices_i ;
2015-01-01 18:08:54 -05:00
std : : map < int , RtAudio : : DeviceInfo > : : iterator mdevices_i ;
2014-12-31 19:45:01 -05:00
AudioThread : : enumerateDevices ( devices ) ;
int i = 0 ;
for ( devices_i = devices . begin ( ) ; devices_i ! = devices . end ( ) ; devices_i + + ) {
if ( devices_i - > inputChannels ) {
2015-01-03 17:07:39 -05:00
inputDevices [ i ] = * devices_i ;
2014-12-31 19:45:01 -05:00
}
if ( devices_i - > outputChannels ) {
2015-01-03 17:07:39 -05:00
outputDevices [ i ] = * devices_i ;
2014-12-31 19:45:01 -05:00
}
i + + ;
}
2014-12-31 21:31:37 -05:00
i = 0 ;
2014-12-31 19:45:01 -05:00
2015-01-03 17:07:39 -05:00
for ( mdevices_i = outputDevices . begin ( ) ; mdevices_i ! = outputDevices . end ( ) ; mdevices_i + + ) {
2015-01-01 18:08:54 -05:00
wxMenuItem * itm = menu - > AppendRadioItem ( wxID_RT_AUDIO_DEVICE + mdevices_i - > first , mdevices_i - > second . name , wxT ( " Description? " ) ) ;
itm - > SetId ( wxID_RT_AUDIO_DEVICE + mdevices_i - > first ) ;
2014-12-31 19:45:01 -05:00
if ( mdevices_i - > second . isDefaultOutput ) {
itm - > Check ( true ) ;
}
2015-01-03 17:07:39 -05:00
outputDeviceMenuItems [ mdevices_i - > first ] = itm ;
2014-12-31 19:45:01 -05:00
}
2015-01-02 22:44:09 -05:00
menuBar - > Append ( menu , wxT ( " Active Demodulator &Output " ) ) ;
2015-01-01 03:48:32 -05:00
2014-10-27 21:22:29 -04:00
SetMenuBar ( menuBar ) ;
CreateStatusBar ( ) ;
2014-11-16 19:02:40 -05:00
SetClientSize ( 1280 , 600 ) ;
2014-10-31 01:37:01 -04:00
Centre ( ) ;
2014-10-27 21:22:29 -04:00
Show ( ) ;
2014-12-16 21:30:03 -05:00
GetStatusBar ( ) - > SetStatusText ( wxString : : Format ( wxT ( " Set center frequency: %i " ) , DEFAULT_FREQ ) ) ;
2014-11-25 00:35:06 -05:00
2014-10-27 21:22:29 -04:00
// static const int attribs[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, 0 };
// wxLogStatus("Double-buffered display %s supported", wxGLCanvas::IsDisplaySupported(attribs) ? "is" : "not");
// ShowFullScreen(true);
}
2014-11-04 18:39:08 -05:00
AppFrame : : ~ AppFrame ( ) {
2014-11-11 20:25:16 -05:00
}
2014-12-31 21:31:37 -05:00
void AppFrame : : OnMenu ( wxCommandEvent & event ) {
2015-01-01 18:08:54 -05:00
if ( event . GetId ( ) > = wxID_RT_AUDIO_DEVICE & & event . GetId ( ) < wxID_RT_AUDIO_DEVICE + devices . size ( ) ) {
2014-12-31 21:31:37 -05:00
if ( activeDemodulator ) {
2015-01-01 18:08:54 -05:00
activeDemodulator - > setOutputDevice ( event . GetId ( ) - wxID_RT_AUDIO_DEVICE ) ;
2014-12-31 21:31:37 -05:00
activeDemodulator = NULL ;
}
2015-01-06 00:57:57 -05:00
} else if ( event . GetId ( ) = = wxID_SET_FREQ_OFFSET ) {
long ofs = wxGetNumberFromUser ( " Shift the displayed frequency by this amount. \n i.e. -125000000 for -125 MHz " , " Frequency (Hz) " , " Frequency Offset " , 0 , - 2000000000 , 2000000000 , this ) ;
wxGetApp ( ) . setOffset ( ofs ) ;
2014-12-31 21:31:37 -05:00
}
2014-10-27 21:22:29 -04:00
}
2014-12-31 22:38:59 -05:00
void AppFrame : : OnClose ( wxCommandEvent & WXUNUSED ( event ) ) {
Close ( true ) ;
}
2014-10-27 21:22:29 -04:00
void AppFrame : : OnNewWindow ( wxCommandEvent & WXUNUSED ( event ) ) {
new AppFrame ( ) ;
}
2014-10-28 21:39:59 -04:00
2014-11-17 18:14:37 -05:00
void AppFrame : : OnThread ( wxCommandEvent & event ) {
2014-11-22 22:17:33 -05:00
event . Skip ( ) ;
2014-11-16 16:51:45 -05:00
}
2014-10-28 21:39:59 -04:00
void AppFrame : : OnIdle ( wxIdleEvent & event ) {
2014-11-22 20:57:06 -05:00
bool work_done = false ;
2014-10-28 21:39:59 -04:00
2014-12-16 20:33:44 -05:00
//#ifdef __APPLE__
// std::this_thread::sleep_for(std::chrono::milliseconds(4));
// std::this_thread::yield();
//#endif
2014-12-28 05:13:46 -05:00
DemodulatorInstance * demod = wxGetApp ( ) . getDemodMgr ( ) . getLastActiveDemodulator ( ) ;
if ( demod ) {
2014-12-31 19:45:01 -05:00
if ( demod ! = activeDemodulator ) {
demodSignalMeter - > setInputValue ( demod - > getSquelchLevel ( ) ) ;
2014-12-31 21:31:37 -05:00
int outputDevice = demod - > getOutputDevice ( ) ;
2015-01-03 17:07:39 -05:00
scopeCanvas - > setDeviceName ( outputDevices [ outputDevice ] . name ) ;
outputDeviceMenuItems [ outputDevice ] - > Check ( true ) ;
2015-01-01 18:08:54 -05:00
int dType = demod - > getDemodulatorType ( ) ;
2015-01-06 00:29:33 -05:00
demodModeSelector - > setSelection ( dType ) ;
2014-12-31 19:45:01 -05:00
}
2014-12-28 20:55:05 -05:00
if ( demodWaterfallCanvas - > getDragState ( ) = = WaterfallCanvas : : WF_DRAG_NONE ) {
2015-01-03 17:07:39 -05:00
if ( demod - > getParams ( ) . frequency ! = demodWaterfallCanvas - > getCenterFrequency ( ) ) {
2015-01-04 17:11:20 -05:00
demodWaterfallCanvas - > setCenterFrequency ( demod - > getFrequency ( ) ) ;
demodSpectrumCanvas - > setCenterFrequency ( demod - > getFrequency ( ) ) ;
2014-12-28 20:55:05 -05:00
}
2015-01-06 00:29:33 -05:00
int dSelection = demodModeSelector - > getSelection ( ) ;
if ( dSelection ! = - 1 & & dSelection ! = demod - > getDemodulatorType ( ) ) {
demod - > setDemodulatorType ( dSelection ) ;
}
2014-12-28 20:55:05 -05:00
unsigned int demodBw = ( unsigned int ) ceil ( ( float ) demod - > getParams ( ) . bandwidth * 2.5 ) ;
2014-12-29 00:24:10 -05:00
if ( demodBw > SRATE / 2 ) {
demodBw = SRATE / 2 ;
2014-12-28 20:55:05 -05:00
}
2015-01-01 18:08:54 -05:00
if ( demodBw < 80000 ) {
demodBw = 80000 ;
2014-12-28 20:55:05 -05:00
}
2015-01-03 17:07:39 -05:00
demodWaterfallCanvas - > setBandwidth ( demodBw ) ;
demodSpectrumCanvas - > setBandwidth ( demodBw ) ;
2014-12-28 05:13:46 -05:00
}
2014-12-31 19:45:01 -05:00
demodSignalMeter - > setLevel ( demod - > getSignalLevel ( ) ) ;
if ( demodSignalMeter - > inputChanged ( ) ) {
demod - > setSquelchLevel ( demodSignalMeter - > getInputValue ( ) ) ;
}
activeDemodulator = demod ;
2014-12-28 05:13:46 -05:00
}
2014-11-23 19:39:27 -05:00
if ( ! wxGetApp ( ) . getIQVisualQueue ( ) - > empty ( ) ) {
2014-12-26 16:15:35 -05:00
DemodulatorThreadIQData * iqData ;
2014-11-23 19:39:27 -05:00
wxGetApp ( ) . getIQVisualQueue ( ) - > pop ( iqData ) ;
2014-11-22 20:57:06 -05:00
2014-12-23 01:59:03 -05:00
if ( iqData & & iqData - > data . size ( ) ) {
2014-12-29 00:24:10 -05:00
// spectrumCanvas->setData(iqData);
2014-12-28 05:13:46 -05:00
waterfallCanvas - > setData ( iqData ) ;
demodWaterfallCanvas - > setData ( iqData ) ;
2014-12-23 01:59:03 -05:00
delete iqData ;
2014-11-22 20:57:06 -05:00
} else {
std : : cout < < " Incoming IQ data empty? " < < std : : endl ;
}
work_done = true ;
}
2014-11-23 19:39:27 -05:00
if ( ! wxGetApp ( ) . getAudioVisualQueue ( ) - > empty ( ) ) {
2014-12-23 01:59:03 -05:00
AudioThreadInput * demodAudioData ;
2014-11-23 19:39:27 -05:00
wxGetApp ( ) . getAudioVisualQueue ( ) - > pop ( demodAudioData ) ;
2014-12-23 01:59:03 -05:00
if ( demodAudioData & & demodAudioData - > data . size ( ) ) {
2014-12-28 05:13:46 -05:00
if ( scopeCanvas - > waveform_points . size ( ) ! = demodAudioData - > data . size ( ) * 2 ) {
scopeCanvas - > waveform_points . resize ( demodAudioData - > data . size ( ) * 2 ) ;
2014-11-22 22:17:33 -05:00
}
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 ;
2014-11-22 22:17:33 -05:00
scopeCanvas - > waveform_points [ i * 2 ] = ( ( double ) i / ( double ) iMax ) ;
}
2014-12-29 00:24:10 -05:00
scopeCanvas - > setStereo ( demodAudioData - > channels = = 2 ) ;
2014-12-26 23:28:18 -05:00
2014-12-23 01:59:03 -05:00
delete demodAudioData ;
2014-11-22 22:17:33 -05:00
} else {
std : : cout < < " Incoming Demodulator data empty? " < < std : : endl ;
}
work_done = true ;
}
2015-01-06 00:29:33 -05:00
if ( ! waterfallCanvas - > HasFocus ( ) ) {
waterfallCanvas - > SetFocus ( ) ;
}
2014-11-22 20:57:06 -05:00
if ( ! work_done ) {
2014-12-16 21:30:03 -05:00
event . Skip ( ) ;
2014-11-22 20:57:06 -05:00
}
2014-10-28 21:39:59 -04:00
}