CubicSDR/src/CubicSDR.cpp

355 lines
8.8 KiB
C++
Raw Normal View History

#define OPENGL
#include "CubicSDRDefs.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 "CubicSDR.h"
2015-05-04 19:44:03 -04:00
#include "FrequencyDialog.h"
#ifdef _OSX_APP_
#include "CoreFoundation/CoreFoundation.h"
#endif
IMPLEMENT_APP(CubicSDR)
bool CubicSDR::OnInit() {
#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
if (!wxApp::OnInit()) {
return false;
}
2015-04-21 23:19:45 -04:00
wxApp::SetAppName("CubicSDR");
frequency = DEFAULT_FREQ;
offset = 0;
ppm = 0;
directSamplingMode = 0;
audioVisualQueue = new DemodulatorThreadOutputQueue();
2014-12-10 21:22:13 -05:00
audioVisualQueue->set_max_num_items(1);
threadCmdQueueSDR = new SDRThreadCommandQueue;
sdrThread = new SDRThread(threadCmdQueueSDR);
sdrPostThread = new SDRPostThread();
sdrPostThread->setNumVisSamples(16384 * 2);
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);
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);
SDRDeviceInfo *dev = NULL;
2015-01-12 00:40:43 -05:00
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-07-08 23:32:30 -04:00
int devId = wxGetSingleChoiceIndex(wxT("Devices"), wxT("Choose Input Device"), choices);
if (devId == -1) { // User chose to cancel
return false;
}
dev = devs[devId];
2015-01-12 00:40:43 -05:00
sdrThread->setDeviceId(devId);
} else if (devs.size() == 1) {
dev = devs[0];
2015-01-12 00:40:43 -05:00
}
2015-07-08 23:32:30 -04:00
if (!dev) {
wxMessageDialog *info;
info = new wxMessageDialog(NULL, wxT("\x28\u256F\xB0\u25A1\xB0\uFF09\u256F\uFE35\x20\u253B\u2501\u253B"), wxT("RTL-SDR device not found"), wxOK | wxICON_ERROR);
info->ShowModal();
return false;
}
2015-01-12 00:40:43 -05:00
t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread);
t_SDR = new std::thread(&SDRThread::threadMain, sdrThread);
2015-05-04 19:44:03 -04:00
appframe = new AppFrame();
if (dev != NULL) {
appframe->initDeviceParams(dev->getDeviceId());
DeviceConfig *devConfig = wxGetApp().getConfig()->getDevice(dev->getDeviceId());
ppm = devConfig->getPPM();
offset = devConfig->getOffset();
directSamplingMode = devConfig->getDirectSampling();
}
#ifdef __APPLE__
int main_policy;
struct sched_param main_param;
main_policy = SCHED_RR;
main_param.sched_priority = sched_get_priority_min(SCHED_RR)+2;
pthread_setschedparam(pthread_self(), main_policy, &main_param);
#endif
return true;
}
int CubicSDR::OnExit() {
demodMgr.terminateAll();
std::cout << "Terminating SDR thread.." << std::endl;
sdrThread->terminate();
t_SDR->join();
std::cout << "Terminating SDR post-processing thread.." << std::endl;
sdrPostThread->terminate();
t_PostSDR->join();
delete sdrThread;
delete t_SDR;
delete sdrPostThread;
delete t_PostSDR;
delete threadCmdQueueSDR;
delete iqVisualQueue;
delete audioVisualQueue;
delete iqPostDataQueue;
delete m_glContext;
2015-01-10 21:49:58 -05:00
#ifdef __APPLE__
AudioThread::deviceCleanup();
#endif
return wxApp::OnExit();
}
PrimaryGLContext& CubicSDR::GetContext(wxGLCanvas *canvas) {
PrimaryGLContext *glContext;
if (!m_glContext) {
m_glContext = new PrimaryGLContext(canvas, NULL);
}
glContext = m_glContext;
return *glContext;
}
void CubicSDR::OnInitCmdLine(wxCmdLineParser& parser) {
parser.SetDesc (commandLineInfo);
parser.SetSwitchChars (wxT("-"));
}
bool CubicSDR::OnCmdLineParsed(wxCmdLineParser& parser) {
wxString *confName = new wxString;
if (parser.Found("c",confName)) {
if (confName) {
config.setConfigName(confName->ToStdString());
}
}
config.load();
return true;
}
void CubicSDR::setFrequency(long long freq) {
2015-01-11 17:08:16 -05:00
if (freq < sampleRate / 2) {
freq = sampleRate / 2;
}
frequency = freq;
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_TUNE);
command.llong_value = freq;
threadCmdQueueSDR->push(command);
}
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);
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
config.getDevice(dev->getDeviceId())->setOffset(ofs);
}
void CubicSDR::setDirectSampling(int mode) {
directSamplingMode = mode;
SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_SET_DIRECT_SAMPLING);
command.llong_value = mode;
threadCmdQueueSDR->push(command);
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
config.getDevice(dev->getDeviceId())->setDirectSampling(mode);
}
int CubicSDR::getDirectSampling() {
return directSamplingMode;
}
2015-05-31 22:13:14 -04:00
void CubicSDR::setSwapIQ(bool swapIQ) {
sdrPostThread->setSwapIQ(swapIQ);
SDRDeviceInfo *dev = (*getDevices())[getDevice()];
config.getDevice(dev->getDeviceId())->setIQSwap(swapIQ);
2015-05-31 22:13:14 -04:00
}
bool CubicSDR::getSwapIQ() {
return sdrPostThread->getSwapIQ();
}
long long CubicSDR::getFrequency() {
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);
SDRDeviceInfo *dev = (*getDevices())[deviceId];
DeviceConfig *devConfig = config.getDevice(dev->getDeviceId());
setPPM(devConfig->getPPM());
setDirectSampling(devConfig->getDirectSampling());
setSwapIQ(devConfig->getIQSwap());
setOffset(devConfig->getOffset());
2015-01-12 00:40:43 -05:00
}
2015-01-12 00:51:57 -05:00
int CubicSDR::getDevice() {
return sdrThread->getDeviceId();
}
AppConfig *CubicSDR::getConfig() {
return &config;
}
2015-04-22 22:54:48 -04:00
void CubicSDR::saveConfig() {
config.save();
}
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);
}
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();
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
void CubicSDR::setFrequencySnap(int snap) {
if (snap > 1000000) {
snap = 1000000;
}
this->snap = snap;
}
int CubicSDR::getFrequencySnap() {
return snap;
}