2014-10-27 20:05:40 -04:00
# define OPENGL
2015-02-17 21:26:14 -05:00
# include "CubicSDRDefs.h"
2014-10-27 20:05:40 -04:00
# 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
2014-10-27 21:22:29 -04:00
# include "CubicSDR.h"
2015-05-04 19:44:03 -04:00
# include "FrequencyDialog.h"
2014-10-27 20:05:40 -04:00
2015-02-17 21:26:14 -05:00
# ifdef _OSX_APP_
# include "CoreFoundation/CoreFoundation.h"
# endif
2014-10-27 20:05:40 -04:00
IMPLEMENT_APP ( CubicSDR )
bool CubicSDR : : OnInit ( ) {
2015-02-17 21:26:14 -05:00
# ifdef _OSX_APP_
CFBundleRef mainBundle = CFBundleGetMainBundle ( ) ;
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL ( mainBundle ) ;
char path [ PATH_MAX ] ;
if ( ! CFURLGetFileSystemRepresentation ( resourcesURL , TRUE , ( UInt8 * ) path , PATH_MAX ) )
{
// error!
}
CFRelease ( resourcesURL ) ;
chdir ( path ) ;
# endif
2015-04-13 21:18:45 -04:00
2015-04-13 19:58:34 -04:00
if ( ! wxApp : : OnInit ( ) ) {
2014-10-27 20:05:40 -04:00
return false ;
2015-04-13 19:58:34 -04:00
}
2015-04-21 23:19:45 -04:00
wxApp : : SetAppName ( " CubicSDR " ) ;
2015-04-13 19:58:34 -04:00
config . load ( ) ;
2014-11-23 19:39:27 -05:00
frequency = DEFAULT_FREQ ;
2015-01-06 00:57:57 -05:00
offset = 0 ;
2015-04-13 21:18:45 -04:00
ppm = 0 ;
2014-11-23 19:39:27 -05:00
audioVisualQueue = new DemodulatorThreadOutputQueue ( ) ;
2014-12-10 21:22:13 -05:00
audioVisualQueue - > set_max_num_items ( 1 ) ;
2014-11-23 19:39:27 -05:00
threadCmdQueueSDR = new SDRThreadCommandQueue ;
sdrThread = new SDRThread ( threadCmdQueueSDR ) ;
2014-11-29 13:58:20 -05:00
sdrPostThread = new SDRPostThread ( ) ;
2015-04-13 21:18:45 -04:00
sdrPostThread - > setNumVisSamples ( 16384 * 2 ) ;
2014-11-29 13:58:20 -05:00
iqPostDataQueue = new SDRThreadIQDataQueue ;
2014-12-26 16:15:35 -05:00
iqVisualQueue = new DemodulatorThreadInputQueue ;
2014-12-10 21:22:13 -05:00
iqVisualQueue - > set_max_num_items ( 1 ) ;
2014-11-23 19:39:27 -05:00
2014-11-29 13:58:20 -05:00
sdrThread - > setIQDataOutQueue ( iqPostDataQueue ) ;
sdrPostThread - > setIQDataInQueue ( iqPostDataQueue ) ;
sdrPostThread - > setIQVisualQueue ( iqVisualQueue ) ;
2015-01-12 00:40:43 -05:00
std : : vector < SDRDeviceInfo * > : : iterator devs_i ;
SDRThread : : enumerate_rtl ( & devs ) ;
if ( devs . size ( ) > 1 ) {
wxArrayString choices ;
for ( devs_i = devs . begin ( ) ; devs_i ! = devs . end ( ) ; devs_i + + ) {
std : : string devName = ( * devs_i ) - > getName ( ) ;
if ( ( * devs_i ) - > isAvailable ( ) ) {
devName . append ( " : " ) ;
devName . append ( ( * devs_i ) - > getProduct ( ) ) ;
devName . append ( " [ " ) ;
devName . append ( ( * devs_i ) - > getSerial ( ) ) ;
devName . append ( " ] " ) ;
} else {
devName . append ( " (In Use?) " ) ;
}
choices . Add ( devName ) ;
2015-05-26 10:37:15 -04:00
}
2015-04-13 21:18:45 -04:00
int devId = wxGetSingleChoiceIndex ( wxT ( " Devices " ) , wxT ( " Choose Input Device " ) , choices ) ;
2015-01-12 00:40:43 -05:00
std : : cout < < " Chosen: " < < devId < < std : : endl ;
sdrThread - > setDeviceId ( devId ) ;
2015-05-26 10:37:15 -04:00
}
2015-05-27 05:08:47 -04:00
else if ( devs . size ( ) = = 0 ) {
2015-05-29 07:45:15 -04:00
wxGetApp ( ) . showMessage ( " No devices found! " , " warning " ) ;
2015-05-27 05:08:47 -04:00
}
2014-11-30 17:11:29 -05:00
t_PostSDR = new std : : thread ( & SDRPostThread : : threadMain , sdrPostThread ) ;
t_SDR = new std : : thread ( & SDRThread : : threadMain , sdrThread ) ;
2014-11-23 19:39:27 -05:00
2015-05-04 19:44:03 -04:00
appframe = new AppFrame ( ) ;
2014-10-28 21:39:59 -04:00
2014-12-05 18:20:28 -05:00
# ifdef __APPLE__
2014-12-04 22:25:18 -05:00
int main_policy ;
struct sched_param main_param ;
2014-12-05 20:13:45 -05:00
main_policy = SCHED_RR ;
main_param . sched_priority = sched_get_priority_min ( SCHED_RR ) + 2 ;
2014-12-04 22:25:18 -05:00
pthread_setschedparam ( pthread_self ( ) , main_policy , & main_param ) ;
2014-12-05 18:20:28 -05:00
# endif
2014-12-04 22:25:18 -05:00
2014-10-27 20:05:40 -04:00
return true ;
}
int CubicSDR : : OnExit ( ) {
2014-11-23 19:39:27 -05:00
std : : cout < < " Terminating SDR thread.. " < < std : : endl ;
sdrThread - > terminate ( ) ;
2014-11-30 17:11:29 -05:00
t_SDR - > join ( ) ;
2014-10-27 20:05:40 -04:00
2014-11-30 17:11:29 -05:00
std : : cout < < " Terminating SDR post-processing thread.. " < < std : : endl ;
2014-11-29 13:58:20 -05:00
sdrPostThread - > terminate ( ) ;
2014-11-30 17:11:29 -05:00
t_PostSDR - > join ( ) ;
2014-11-29 13:58:20 -05:00
2014-11-23 19:39:27 -05:00
delete sdrThread ;
2014-11-30 17:11:29 -05:00
delete t_SDR ;
2014-11-23 19:39:27 -05:00
2014-11-29 13:58:20 -05:00
delete sdrPostThread ;
2014-11-30 17:11:29 -05:00
delete t_PostSDR ;
2014-11-29 13:58:20 -05:00
2014-11-23 19:39:27 -05:00
demodMgr . terminateAll ( ) ;
delete threadCmdQueueSDR ;
delete iqVisualQueue ;
delete audioVisualQueue ;
2014-11-29 13:58:20 -05:00
delete iqPostDataQueue ;
2014-11-23 19:39:27 -05:00
delete m_glContext ;
2014-10-27 20:05:40 -04:00
2015-01-10 21:49:58 -05:00
# ifdef __APPLE__
AudioThread : : deviceCleanup ( ) ;
# endif
2014-10-27 20:05:40 -04:00
return wxApp : : OnExit ( ) ;
}
PrimaryGLContext & CubicSDR : : GetContext ( wxGLCanvas * canvas ) {
PrimaryGLContext * glContext ;
if ( ! m_glContext ) {
2014-11-12 21:55:11 -05:00
m_glContext = new PrimaryGLContext ( canvas , NULL ) ;
2014-10-27 20:05:40 -04:00
}
glContext = m_glContext ;
return * glContext ;
}
2015-01-04 17:11:20 -05:00
void CubicSDR : : setFrequency ( long long freq ) {
2015-01-11 17:08:16 -05:00
if ( freq < sampleRate / 2 ) {
freq = sampleRate / 2 ;
2015-01-04 13:20:31 -05:00
}
2014-11-23 19:39:27 -05:00
frequency = freq ;
SDRThreadCommand command ( SDRThreadCommand : : SDR_THREAD_CMD_TUNE ) ;
2015-01-04 17:11:20 -05:00
command . llong_value = freq ;
2014-11-23 19:39:27 -05:00
threadCmdQueueSDR - > push ( command ) ;
}
2015-01-06 00:57:57 -05:00
long long CubicSDR : : getOffset ( ) {
return offset ;
}
void CubicSDR : : setOffset ( long long ofs ) {
offset = ofs ;
SDRThreadCommand command ( SDRThreadCommand : : SDR_THREAD_CMD_SET_OFFSET ) ;
command . llong_value = ofs ;
threadCmdQueueSDR - > push ( command ) ;
}
2015-01-04 17:11:20 -05:00
long long CubicSDR : : getFrequency ( ) {
2014-11-23 19:39:27 -05:00
return frequency ;
}
2014-12-10 21:22:13 -05:00
DemodulatorThreadOutputQueue * CubicSDR : : getAudioVisualQueue ( ) {
return audioVisualQueue ;
}
2014-12-26 16:15:35 -05:00
DemodulatorThreadInputQueue * CubicSDR : : getIQVisualQueue ( ) {
2014-12-10 21:22:13 -05:00
return iqVisualQueue ;
}
DemodulatorMgr & CubicSDR : : getDemodMgr ( ) {
return demodMgr ;
}
void CubicSDR : : bindDemodulator ( DemodulatorInstance * demod ) {
if ( ! demod ) {
return ;
}
sdrPostThread - > bindDemodulator ( demod ) ;
}
2015-01-11 17:08:16 -05:00
void CubicSDR : : setSampleRate ( long long rate_in ) {
sampleRate = rate_in ;
SDRThreadCommand command ( SDRThreadCommand : : SDR_THREAD_CMD_SET_SAMPLERATE ) ;
command . llong_value = rate_in ;
threadCmdQueueSDR - > push ( command ) ;
setFrequency ( frequency ) ;
}
long long CubicSDR : : getSampleRate ( ) {
return sampleRate ;
}
2014-12-10 21:22:13 -05:00
void CubicSDR : : removeDemodulator ( DemodulatorInstance * demod ) {
if ( ! demod ) {
return ;
}
2015-01-22 23:41:33 -05:00
demod - > setActive ( false ) ;
2014-12-10 21:22:13 -05:00
sdrPostThread - > removeDemodulator ( demod ) ;
}
2015-01-12 00:40:43 -05:00
std : : vector < SDRDeviceInfo * > * CubicSDR : : getDevices ( ) {
return & devs ;
}
void CubicSDR : : setDevice ( int deviceId ) {
sdrThread - > setDeviceId ( deviceId ) ;
SDRThreadCommand command ( SDRThreadCommand : : SDR_THREAD_CMD_SET_DEVICE ) ;
command . llong_value = deviceId ;
threadCmdQueueSDR - > push ( command ) ;
2015-04-13 21:18:45 -04:00
SDRDeviceInfo * dev = ( * getDevices ( ) ) [ deviceId ] ;
SDRThreadCommand command_ppm ( SDRThreadCommand : : SDR_THREAD_CMD_SET_PPM ) ;
2015-04-21 23:19:45 -04:00
ppm = config . getDevice ( dev - > getDeviceId ( ) ) - > getPPM ( ) ;
2015-04-13 21:18:45 -04:00
command_ppm . llong_value = ppm ;
threadCmdQueueSDR - > push ( command_ppm ) ;
2015-01-12 00:40:43 -05:00
}
2015-01-12 00:51:57 -05:00
int CubicSDR : : getDevice ( ) {
return sdrThread - > getDeviceId ( ) ;
}
2015-04-13 19:58:34 -04:00
AppConfig * CubicSDR : : getConfig ( ) {
return & config ;
}
2015-04-13 21:18:45 -04:00
2015-04-22 22:54:48 -04:00
void CubicSDR : : saveConfig ( ) {
config . save ( ) ;
}
2015-04-13 21:18:45 -04:00
void CubicSDR : : setPPM ( int ppm_in ) {
if ( sdrThread - > getDeviceId ( ) < 0 ) {
return ;
}
ppm = ppm_in ;
SDRThreadCommand command ( SDRThreadCommand : : SDR_THREAD_CMD_SET_PPM ) ;
command . llong_value = ppm ;
threadCmdQueueSDR - > push ( command ) ;
SDRDeviceInfo * dev = ( * getDevices ( ) ) [ getDevice ( ) ] ;
2015-04-21 23:19:45 -04:00
config . getDevice ( dev - > getDeviceId ( ) ) - > setPPM ( ppm_in ) ;
2015-04-13 21:18:45 -04:00
config . save ( ) ;
}
int CubicSDR : : getPPM ( ) {
if ( sdrThread - > getDeviceId ( ) < 0 ) {
return 0 ;
}
SDRDeviceInfo * dev = ( * getDevices ( ) ) [ getDevice ( ) ] ;
SDRThreadCommand command_ppm ( SDRThreadCommand : : SDR_THREAD_CMD_SET_PPM ) ;
2015-04-21 23:19:45 -04:00
ppm = config . getDevice ( dev - > getDeviceId ( ) ) - > getPPM ( ) ;
2015-04-13 21:18:45 -04:00
return ppm ;
}
2015-05-04 19:44:03 -04:00
void CubicSDR : : showFrequencyInput ( ) {
2015-05-10 20:00:48 -04:00
FrequencyDialog fdialog ( appframe , - 1 , demodMgr . getActiveDemodulator ( ) ? _ ( " Set Demodulator Frequency " ) : _ ( " Set Center Frequency " ) , demodMgr . getActiveDemodulator ( ) , wxPoint ( - 100 , - 100 ) , wxSize ( 320 , 75 ) ) ;
2015-05-10 01:39:10 -04:00
fdialog . ShowModal ( ) ;
2015-05-04 19:44:03 -04:00
}
2015-05-10 01:39:10 -04:00
2015-05-10 21:43:03 -04:00
void CubicSDR : : setFrequencySnap ( int snap ) {
if ( snap > 1000000 ) {
snap = 1000000 ;
}
this - > snap = snap ;
}
int CubicSDR : : getFrequencySnap ( ) {
return snap ;
}
2015-05-26 10:37:15 -04:00
2015-05-29 07:45:15 -04:00
void CubicSDR : : showMessage ( std : : string text , std : : string title ) {
2015-05-26 10:37:15 -04:00
wxMessageDialog * message = new wxMessageDialog ( NULL , wxString : : Format ( text . c_str ( ) ) , wxString : : Format ( title . c_str ( ) ) , wxOK | wxICON_ERROR ) ;
message - > ShowModal ( ) ;
}