diff --git a/README.md b/README.md index 42c194e..8e7631b 100644 --- a/README.md +++ b/README.md @@ -21,15 +21,15 @@ Basic Goals and Status: ---------------------- - Simple UI - Devices - - [x] RTL-SDR (RTL2832U) + - [x] RTL-SDR - [ ] HackRF - [ ] Whatever else I can get my hands on - Minimal configuration - - [ ] Device Selection - - [ ] Bandwidth - - [ ] Default audio device and settings + - [x] Device Selection + - [x] Bandwidth - [x] Color scheme - [x] Load/Save session + - [ ] Default audio device and settings - Neat Visuals - [x] Scope - [x] Spectrum @@ -52,7 +52,7 @@ Basic Goals and Status: - [x] Display separate zoomed-in view of current waterfall and spectrum, allow adjustments - [x] Display signal level and allow squelch control - [x] Display audio output selection - - [ ] Volume control + - [x] Volume control - [ ] Basic noise reduction / filter controls? - Basic Input Controls - [x] Drag spectrum to change center frequency diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 7030e00..c641864 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -158,19 +158,61 @@ AppFrame::AppFrame() : menuBar->Append(menu, wxT("Active Demodulator &Output")); - menu = new wxMenu; - menu->Append(wxID_THEME_DEFAULT, "Default"); - menu->Append(wxID_THEME_RADAR, "RADAR"); - menu->Append(wxID_THEME_BW, "Black & White"); - menu->Append(wxID_THEME_SHARP, "Sharp"); - menu->Append(wxID_THEME_RAD, "Rad"); - menu->Append(wxID_THEME_TOUCH, "Touch"); - menu->Append(wxID_THEME_HD, "HD"); + menu->AppendRadioItem(wxID_THEME_DEFAULT, "Default")->Check(true); + menu->AppendRadioItem(wxID_THEME_RADAR, "RADAR"); + menu->AppendRadioItem(wxID_THEME_BW, "Black & White"); + menu->AppendRadioItem(wxID_THEME_SHARP, "Sharp"); + menu->AppendRadioItem(wxID_THEME_RAD, "Rad"); + menu->AppendRadioItem(wxID_THEME_TOUCH, "Touch"); + menu->AppendRadioItem(wxID_THEME_HD, "HD"); menuBar->Append(menu, wxT("&Color Scheme")); + menu = new wxMenu; + + sampleRateMenuItems[wxID_BANDWIDTH_1000M] = menu->AppendRadioItem(wxID_BANDWIDTH_1000M, "1.0M"); + sampleRateMenuItems[wxID_BANDWIDTH_1500M] = menu->AppendRadioItem(wxID_BANDWIDTH_1500M, "1.5M"); + sampleRateMenuItems[wxID_BANDWIDTH_2000M] = menu->AppendRadioItem(wxID_BANDWIDTH_2000M, "2.0M"); + sampleRateMenuItems[wxID_BANDWIDTH_2500M] = menu->AppendRadioItem(wxID_BANDWIDTH_2500M, "2.5M"); + sampleRateMenuItems[wxID_BANDWIDTH_2880M] = menu->AppendRadioItem(wxID_BANDWIDTH_2880M, "2.88M"); + sampleRateMenuItems[wxID_BANDWIDTH_3200M] = menu->AppendRadioItem(wxID_BANDWIDTH_3200M, "3.2M"); + +#ifdef __APPLE + sampleRateMenuItems[wxID_BANDWIDTH_2000M]->Check(true); +#else + sampleRateMenuItems[wxID_BANDWIDTH_2500M]->Check(true); +#endif + + menuBar->Append(menu, wxT("&Input Bandwidth")); + + std::vector *devs = wxGetApp().getDevices(); + std::vector::iterator devs_i; + + if (devs->size() > 1) { + + menu = new wxMenu; + + int p = 0; + 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?)"); + } + + menu->AppendRadioItem(wxID_DEVICE_ID+p, devName)->Check(wxGetApp().getDevice() == p); + p++; + } + + menuBar->Append(menu,wxT("&Device")); + } SetMenuBar(menuBar); @@ -262,6 +304,32 @@ void AppFrame::OnMenu(wxCommandEvent& event) { waterfallCanvas->setTheme(COLOR_THEME_RADAR); demodWaterfallCanvas->setTheme(COLOR_THEME_RADAR); } + + switch (event.GetId()) { + case wxID_BANDWIDTH_1000M: + wxGetApp().setSampleRate(1000000); + break; + case wxID_BANDWIDTH_1500M: + wxGetApp().setSampleRate(1500000); + break; + case wxID_BANDWIDTH_2000M: + wxGetApp().setSampleRate(2000000); + break; + case wxID_BANDWIDTH_2500M: + wxGetApp().setSampleRate(2500000); + break; + case wxID_BANDWIDTH_2880M: + wxGetApp().setSampleRate(2880000); + break; + case wxID_BANDWIDTH_3200M: + wxGetApp().setSampleRate(3200000); + break; + } + + std::vector *devs = wxGetApp().getDevices(); + if (event.GetId() >= wxID_DEVICE_ID && event.GetId() <= wxID_DEVICE_ID+devs->size()) { + wxGetApp().setDevice(event.GetId()-wxID_DEVICE_ID); + } } void AppFrame::OnClose(wxCommandEvent& WXUNUSED(event)) { @@ -307,8 +375,8 @@ void AppFrame::OnIdle(wxIdleEvent& event) { } unsigned int demodBw = (unsigned int) ceil((float) demod->getParams().bandwidth * 2.5); - if (demodBw > SRATE / 2) { - demodBw = SRATE / 2; + if (demodBw > wxGetApp().getSampleRate() / 2) { + demodBw = wxGetApp().getSampleRate() / 2; } if (demodBw < 80000) { demodBw = 80000; @@ -399,9 +467,8 @@ void AppFrame::saveSession(std::string fileName) { s.SaveToFileXML(fileName); - currentSessionFile = fileName; - std::string filePart = fileName.substr(fileName.find_last_of(filePathSeparator)+1); + std::string filePart = fileName.substr(fileName.find_last_of(filePathSeparator) + 1); GetStatusBar()->SetStatusText(wxString::Format(wxT("Saved session: %s"), currentSessionFile.c_str())); SetTitle(wxString::Format(wxT("%s: %s"), CUBICSDR_TITLE, filePart.c_str())); } @@ -425,8 +492,8 @@ bool AppFrame::loadSession(std::string fileName) { std::cout << "\tCenter Frequency: " << center_freq << std::endl; std::cout << "\tOffset: " << offset << std::endl; - wxGetApp().setOffset(offset); wxGetApp().setFrequency(center_freq); + wxGetApp().setOffset(offset); DataNode *demodulators = l.rootNode()->getNext("demodulators"); @@ -494,7 +561,7 @@ bool AppFrame::loadSession(std::string fileName) { currentSessionFile = fileName; - std::string filePart = fileName.substr(fileName.find_last_of(filePathSeparator)+1); + std::string filePart = fileName.substr(fileName.find_last_of(filePathSeparator) + 1); GetStatusBar()->SetStatusText(wxString::Format(wxT("Loaded session file: %s"), currentSessionFile.c_str())); SetTitle(wxString::Format(wxT("%s: %s"), CUBICSDR_TITLE, filePart.c_str())); diff --git a/src/AppFrame.h b/src/AppFrame.h index 893cb31..93dad38 100644 --- a/src/AppFrame.h +++ b/src/AppFrame.h @@ -24,6 +24,16 @@ #define wxID_THEME_HD 2105 #define wxID_THEME_RADAR 2106 +#define wxID_BANDWIDTH_1000M 2152 +#define wxID_BANDWIDTH_1500M 2153 +#define wxID_BANDWIDTH_2000M 2154 +#define wxID_BANDWIDTH_2500M 2155 +#define wxID_BANDWIDTH_2880M 2156 +#define wxID_BANDWIDTH_3200M 2158 + +#define wxID_DEVICE_ID 3500 + + // Define a new frame type class AppFrame: public wxFrame { public: @@ -59,6 +69,9 @@ private: std::map outputDevices; std::map outputDeviceMenuItems; + std::map sampleRateMenuItems; + + std::string currentSessionFile; wxDECLARE_EVENT_TABLE(); diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 407f591..e84bcda 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -39,6 +39,32 @@ bool CubicSDR::OnInit() { sdrPostThread->setIQDataInQueue(iqPostDataQueue); sdrPostThread->setIQVisualQueue(iqVisualQueue); + std::vector::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); + } + + int devId = wxGetSingleChoiceIndex(wxT("Devices"),wxT("Choose Input Device"),choices); + + std::cout << "Chosen: " << devId << std::endl; + sdrThread->setDeviceId(devId); + } + t_PostSDR = new std::thread(&SDRPostThread::threadMain, sdrPostThread); t_SDR = new std::thread(&SDRThread::threadMain, sdrThread); @@ -82,7 +108,6 @@ int CubicSDR::OnExit() { delete m_glContext; - #ifdef __APPLE__ AudioThread::deviceCleanup(); #endif @@ -103,8 +128,8 @@ PrimaryGLContext& CubicSDR::GetContext(wxGLCanvas *canvas) { } void CubicSDR::setFrequency(long long freq) { - if (freq < SRATE/2) { - freq = SRATE/2; + if (freq < sampleRate / 2) { + freq = sampleRate / 2; } frequency = freq; SDRThreadCommand command(SDRThreadCommand::SDR_THREAD_CMD_TUNE); @@ -146,9 +171,36 @@ void CubicSDR::bindDemodulator(DemodulatorInstance *demod) { sdrPostThread->bindDemodulator(demod); } +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; +} + void CubicSDR::removeDemodulator(DemodulatorInstance *demod) { if (!demod) { return; } sdrPostThread->removeDemodulator(demod); } + +std::vector* 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); +} + +int CubicSDR::getDevice() { + return sdrThread->getDeviceId(); +} diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 6317273..f2a24b8 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -20,7 +20,7 @@ class CubicSDR: public wxApp { public: CubicSDR() : - m_glContext(NULL), frequency(DEFAULT_FREQ), sdrThread(NULL), sdrPostThread(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), iqPostDataQueue(NULL), audioVisualQueue(NULL), t_SDR(NULL), t_PostSDR(NULL) { + m_glContext(NULL), frequency(DEFAULT_FREQ), sdrThread(NULL), sdrPostThread(NULL), threadCmdQueueSDR(NULL), iqVisualQueue(NULL), iqPostDataQueue(NULL), audioVisualQueue(NULL), t_SDR(NULL), t_PostSDR(NULL), sampleRate(DEFAULT_SAMPLE_RATE) { } @@ -35,6 +35,13 @@ public: void setOffset(long long ofs); long long getOffset(); + void setSampleRate(long long rate_in); + long long getSampleRate(); + + std::vector *getDevices(); + void setDevice(int deviceId); + int getDevice(); + DemodulatorThreadOutputQueue* getAudioVisualQueue(); DemodulatorThreadInputQueue* getIQVisualQueue(); DemodulatorMgr &getDemodMgr(); @@ -44,11 +51,13 @@ public: private: PrimaryGLContext *m_glContext; + std::vector devs; DemodulatorMgr demodMgr; long long frequency; long long offset; + long long sampleRate; SDRThread *sdrThread; SDRPostThread *sdrPostThread; diff --git a/src/CubicSDRDefs.h b/src/CubicSDRDefs.h index f2655b3..2f3d1a1 100644 --- a/src/CubicSDRDefs.h +++ b/src/CubicSDRDefs.h @@ -12,10 +12,10 @@ const char filePathSeparator = #ifdef __APPLE__ #define BUF_SIZE (16384*2) -#define SRATE 2000000 +#define DEFAULT_SAMPLE_RATE 2000000 #else #define BUF_SIZE (16384*5) -#define SRATE 2500000 +#define DEFAULT_SAMPLE_RATE 2500000 #endif #define DEFAULT_FFT_SIZE 2048 diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index 701ca66..f41d506 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -421,13 +421,12 @@ void AudioThread::threadMain() { } #endif - std::cout << "Audio thread done." << std::endl; - if (threadQueueNotify != NULL) { DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED); tCmd.context = this; threadQueueNotify->push(tCmd); } + std::cout << "Audio thread done." << std::endl; } void AudioThread::terminate() { diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index f7c52ba..f68686c 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -14,7 +14,6 @@ #define DEMOD_TYPE_USB 4 #define DEMOD_TYPE_DSB 5 - class DemodulatorThread; class DemodulatorThreadCommand { public: @@ -59,11 +58,11 @@ public: class DemodulatorThreadIQData: public ReferenceCounter { public: long long frequency; - unsigned int bandwidth; + long long sampleRate; std::vector data; DemodulatorThreadIQData() : - frequency(0), bandwidth(0) { + frequency(0), sampleRate(0) { } @@ -75,13 +74,13 @@ public: class DemodulatorThreadPostIQData: public ReferenceCounter { public: std::vector data; - int bandwidth; + long long sampleRate; msresamp_rrrf audioResampler; msresamp_rrrf stereoResampler; double audioResampleRatio; DemodulatorThreadPostIQData() : - bandwidth(0), audioResampler(NULL), stereoResampler(NULL), audioResampleRatio(0) { + sampleRate(0), audioResampler(NULL), stereoResampler(NULL), audioResampleRatio(0) { } @@ -121,14 +120,14 @@ typedef ThreadQueue DemodulatorThreadControlCom class DemodulatorThreadParameters { public: long long frequency; - unsigned int inputRate; + long long sampleRate; unsigned int bandwidth; // set equal to disable second stage re-sampling? unsigned int audioSampleRate; int demodType; DemodulatorThreadParameters() : - frequency(0), inputRate(SRATE), bandwidth(200000), audioSampleRate( + frequency(0), sampleRate(DEFAULT_SAMPLE_RATE), bandwidth(200000), audioSampleRate( AUDIO_FREQUENCY), demodType(DEMOD_TYPE_FM) { } diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index 3981658..e82c8af 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -126,12 +126,14 @@ bool DemodulatorInstance::isTerminated() { case DemodulatorThreadCommand::DEMOD_THREAD_CMD_AUDIO_TERMINATED: t_Audio->join(); audioTerminated = true; + delete t_Audio; break; case DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED: #ifdef __APPLE__ pthread_join(t_Demod, NULL); #else t_Demod->join(); + delete t_Demod; #endif demodTerminated = true; break; @@ -140,6 +142,7 @@ bool DemodulatorInstance::isTerminated() { pthread_join(t_PreDemod, NULL); #else t_PreDemod->join(); + delete t_PreDemod; #endif preDemodTerminated = true; break; diff --git a/src/demod/DemodulatorPreThread.cpp b/src/demod/DemodulatorPreThread.cpp index 5dedd65..b412e0d 100644 --- a/src/demod/DemodulatorPreThread.cpp +++ b/src/demod/DemodulatorPreThread.cpp @@ -6,6 +6,7 @@ #endif #include "DemodulatorPreThread.h" +#include "CubicSDR.h" DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* iqInputQueue, DemodulatorThreadPostInputQueue* iqOutputQueue, DemodulatorThreadControlCommandQueue *threadQueueControl, DemodulatorThreadCommandQueue* threadQueueNotify) : @@ -26,7 +27,7 @@ DemodulatorPreThread::DemodulatorPreThread(DemodulatorThreadInputQueue* iqInputQ void DemodulatorPreThread::initialize() { initialized = false; - iqResampleRatio = (double) (params.bandwidth) / (double) params.inputRate; + iqResampleRatio = (double) (params.bandwidth) / (double) params.sampleRate; audioResampleRatio = (double) (params.audioSampleRate) / (double) params.bandwidth; float As = 120.0f; // stop-band attenuation [dB] @@ -77,10 +78,10 @@ void DemodulatorPreThread::threadMain() { iqInputQueue->pop(inp); bool bandwidthChanged = false; - DemodulatorThreadParameters bandwidthParams = params; + bool rateChanged = false; + DemodulatorThreadParameters tempParams = params; if (!commandQueue->empty()) { - bool paramsChanged = false; while (!commandQueue->empty()) { DemodulatorThreadCommand command; commandQueue->pop(command); @@ -89,10 +90,11 @@ void DemodulatorPreThread::threadMain() { if (command.llong_value < 1500) { command.llong_value = 1500; } - if (command.llong_value > SRATE) { - command.llong_value = SRATE; + if (command.llong_value > params.sampleRate) { + tempParams.bandwidth = params.sampleRate; + } else { + tempParams.bandwidth = command.llong_value; } - bandwidthParams.bandwidth = command.llong_value; bandwidthChanged = true; break; case DemodulatorThreadCommand::DEMOD_THREAD_CMD_SET_FREQUENCY: @@ -100,16 +102,21 @@ void DemodulatorPreThread::threadMain() { break; } } + } - if (bandwidthChanged) { - DemodulatorWorkerThreadCommand command(DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_BUILD_FILTERS); - command.audioSampleRate = bandwidthParams.audioSampleRate; - command.bandwidth = bandwidthParams.bandwidth; - command.frequency = bandwidthParams.frequency; - command.inputRate = bandwidthParams.inputRate; + if (inp->sampleRate != tempParams.sampleRate) { + tempParams.sampleRate = inp->sampleRate; + rateChanged = true; + } - workerQueue->push(command); - } + if (bandwidthChanged || rateChanged) { + DemodulatorWorkerThreadCommand command(DemodulatorWorkerThreadCommand::DEMOD_WORKER_THREAD_CMD_BUILD_FILTERS); + command.sampleRate = tempParams.sampleRate; + command.audioSampleRate = tempParams.audioSampleRate; + command.bandwidth = tempParams.bandwidth; + command.frequency = tempParams.frequency; + + workerQueue->push(command); } if (!initialized) { @@ -118,21 +125,21 @@ void DemodulatorPreThread::threadMain() { // Requested frequency is not center, shift it into the center! if (inp->frequency != params.frequency) { - if ((params.frequency - inp->frequency) != shiftFrequency) { + if ((params.frequency - inp->frequency) != shiftFrequency || rateChanged) { shiftFrequency = params.frequency - inp->frequency; - if (abs(shiftFrequency) <= (int) ((double) (SRATE / 2) * 1.5)) { - nco_crcf_set_frequency(freqShifter, (2.0 * M_PI) * (((double) abs(shiftFrequency)) / ((double) SRATE))); + if (abs(shiftFrequency) <= (int) ((double) (wxGetApp().getSampleRate() / 2) * 1.5)) { + nco_crcf_set_frequency(freqShifter, (2.0 * M_PI) * (((double) abs(shiftFrequency)) / ((double) wxGetApp().getSampleRate()))); } } } - if (abs(shiftFrequency) > (int) ((double) (SRATE / 2) * 1.5)) { + if (abs(shiftFrequency) > (int) ((double) (wxGetApp().getSampleRate() / 2) * 1.5)) { continue; } // std::lock_guard < std::mutex > lock(inp->m_mutex); std::vector *data = &inp->data; - if (data->size()) { + if (data->size() && (inp->sampleRate == params.sampleRate)) { int bufSize = data->size(); if (in_buf_data.size() != bufSize) { @@ -193,7 +200,7 @@ void DemodulatorPreThread::threadMain() { resamp->audioResampleRatio = audioResampleRatio; resamp->audioResampler = audioResampler; resamp->stereoResampler = stereoResampler; - resamp->bandwidth = params.bandwidth; + resamp->sampleRate = params.bandwidth; iqOutputQueue->push(resamp); } @@ -209,16 +216,16 @@ void DemodulatorPreThread::threadMain() { case DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS: msresamp_crcf_destroy(iqResampler); - iqResampler = result.resampler; + iqResampler = result.iqResampler; audioResampler = result.audioResampler; stereoResampler = result.stereoResampler; - iqResampleRatio = result.resamplerRatio; + iqResampleRatio = result.iqResampleRatio; audioResampleRatio = result.audioResamplerRatio; params.audioSampleRate = result.audioSampleRate; params.bandwidth = result.bandwidth; - params.inputRate = result.inputRate; + params.sampleRate = result.sampleRate; break; } @@ -232,10 +239,10 @@ void DemodulatorPreThread::threadMain() { delete iqDataDel; } - std::cout << "Demodulator preprocessor thread done." << std::endl; DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_PREPROCESS_TERMINATED); tCmd.context = this; threadQueueNotify->push(tCmd); + std::cout << "Demodulator preprocessor thread done." << std::endl; } void DemodulatorPreThread::terminate() { @@ -243,4 +250,6 @@ void DemodulatorPreThread::terminate() { DemodulatorThreadIQData *inp = new DemodulatorThreadIQData; // push dummy to nudge queue iqInputQueue->push(inp); workerThread->terminate(); + t_Worker->detach(); + delete t_Worker; } diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index bd13056..8ed1b20 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -217,7 +217,7 @@ void DemodulatorThread::threadMain() { demodStereoData.resize(bufSize); } - double freq = (2.0 * M_PI) * (((double) abs(38000)) / ((double) inp->bandwidth)); + double freq = (2.0 * M_PI) * (((double) abs(38000)) / ((double) inp->sampleRate)); if (stereoShiftFrequency != freq) { nco_crcf_set_frequency(stereoShifter, freq); @@ -406,10 +406,10 @@ void DemodulatorThread::threadMain() { delete audioDataDel; } - std::cout << "Demodulator thread done." << std::endl; DemodulatorThreadCommand tCmd(DemodulatorThreadCommand::DEMOD_THREAD_CMD_DEMOD_TERMINATED); tCmd.context = this; threadQueueNotify->push(tCmd); + std::cout << "Demodulator thread done." << std::endl; } void DemodulatorThread::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) { diff --git a/src/demod/DemodulatorWorkerThread.cpp b/src/demod/DemodulatorWorkerThread.cpp index 4f25a69..302fb14 100644 --- a/src/demod/DemodulatorWorkerThread.cpp +++ b/src/demod/DemodulatorWorkerThread.cpp @@ -31,21 +31,21 @@ void DemodulatorWorkerThread::threadMain() { done = commandQueue->empty(); } - if (filterChanged) { + if (filterChanged && !terminated) { DemodulatorWorkerThreadResult result(DemodulatorWorkerThreadResult::DEMOD_WORKER_THREAD_RESULT_FILTERS); - result.resamplerRatio = (double) (filterCommand.bandwidth) / (double) filterCommand.inputRate; + result.iqResampleRatio = (double) (filterCommand.bandwidth) / (double) filterCommand.sampleRate; result.audioResamplerRatio = (double) (filterCommand.audioSampleRate) / (double) filterCommand.bandwidth; float As = 60.0f; // stop-band attenuation [dB] - result.resampler = msresamp_crcf_create(result.resamplerRatio, As); + result.iqResampler = msresamp_crcf_create(result.iqResampleRatio, As); result.audioResampler = msresamp_rrrf_create(result.audioResamplerRatio, As); result.stereoResampler = msresamp_rrrf_create(result.audioResamplerRatio, As); result.audioSampleRate = filterCommand.audioSampleRate; result.bandwidth = filterCommand.bandwidth; - result.inputRate = filterCommand.inputRate; + result.sampleRate = filterCommand.sampleRate; resultQueue->push(result); } diff --git a/src/demod/DemodulatorWorkerThread.h b/src/demod/DemodulatorWorkerThread.h index 489652f..3654c27 100644 --- a/src/demod/DemodulatorWorkerThread.h +++ b/src/demod/DemodulatorWorkerThread.h @@ -22,26 +22,26 @@ public: }; DemodulatorWorkerThreadResult() : - cmd(DEMOD_WORKER_THREAD_RESULT_NULL), resampler(NULL), resamplerRatio(0), audioResampler(NULL), stereoResampler(NULL), audioResamplerRatio( - 0), inputRate(0), bandwidth(0), audioSampleRate(0) { + cmd(DEMOD_WORKER_THREAD_RESULT_NULL), iqResampler(NULL), iqResampleRatio(0), audioResampler(NULL), stereoResampler(NULL), audioResamplerRatio( + 0), sampleRate(0), bandwidth(0), audioSampleRate(0) { } DemodulatorWorkerThreadResult(DemodulatorThreadResultEnum cmd) : - cmd(cmd), resampler(NULL), resamplerRatio(0), audioResampler(NULL), stereoResampler(NULL), audioResamplerRatio(0), inputRate(0), bandwidth( + cmd(cmd), iqResampler(NULL), iqResampleRatio(0), audioResampler(NULL), stereoResampler(NULL), audioResamplerRatio(0), sampleRate(0), bandwidth( 0), audioSampleRate(0) { } DemodulatorThreadResultEnum cmd; - msresamp_crcf resampler; - double resamplerRatio; + msresamp_crcf iqResampler; + double iqResampleRatio; msresamp_rrrf audioResampler; msresamp_rrrf stereoResampler; double audioResamplerRatio; - unsigned int inputRate; + long long sampleRate; unsigned int bandwidth; unsigned int audioSampleRate; @@ -54,19 +54,19 @@ public: }; DemodulatorWorkerThreadCommand() : - cmd(DEMOD_WORKER_THREAD_CMD_NULL), frequency(0), inputRate(0), bandwidth(0), audioSampleRate(0) { + cmd(DEMOD_WORKER_THREAD_CMD_NULL), frequency(0), sampleRate(0), bandwidth(0), audioSampleRate(0) { } DemodulatorWorkerThreadCommand(DemodulatorThreadCommandEnum cmd) : - cmd(cmd), frequency(0), inputRate(0), bandwidth(0), audioSampleRate(0) { + cmd(cmd), frequency(0), sampleRate(0), bandwidth(0), audioSampleRate(0) { } DemodulatorThreadCommandEnum cmd; long long frequency; - unsigned int inputRate; + long long sampleRate; unsigned int bandwidth; unsigned int audioSampleRate; }; diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 7282bca..168d623 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -6,7 +6,7 @@ #include SDRPostThread::SDRPostThread() : - sample_rate(SRATE), iqDataOutQueue(NULL), iqDataInQueue(NULL), iqVisualQueue(NULL), terminated(false), dcFilter(NULL), num_vis_samples(2048) { + iqDataOutQueue(NULL), iqDataInQueue(NULL), iqVisualQueue(NULL), terminated(false), dcFilter(NULL), num_vis_samples(2048) { } SDRPostThread::~SDRPostThread() { @@ -90,7 +90,7 @@ void SDRPostThread::threadMain() { DemodulatorThreadIQData *pipeDataOut = new DemodulatorThreadIQData; pipeDataOut->frequency = data_in->frequency; - pipeDataOut->bandwidth = data_in->bandwidth; + pipeDataOut->sampleRate = data_in->sampleRate; pipeDataOut->data.assign(dataOut.begin(), dataOut.end()); iqDataOutQueue.load()->push(pipeDataOut); } @@ -98,7 +98,7 @@ void SDRPostThread::threadMain() { if (iqVisualQueue != NULL && iqVisualQueue.load()->empty()) { DemodulatorThreadIQData *visualDataOut = new DemodulatorThreadIQData; visualDataOut->frequency = data_in->frequency; - visualDataOut->bandwidth = data_in->bandwidth; + visualDataOut->sampleRate = data_in->sampleRate; visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + num_vis_samples); iqVisualQueue.load()->push(visualDataOut); } @@ -131,7 +131,7 @@ void SDRPostThread::threadMain() { for (i = demodulators.begin(); i != demodulators.end(); i++) { DemodulatorInstance *demod = *i; if (demod->getFrequency() != data_in->frequency - && abs(data_in->frequency - demod->getFrequency()) > (SRATE / 2)) { + && abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) { continue; } activeDemods++; @@ -155,7 +155,7 @@ void SDRPostThread::threadMain() { // std::lock_guard < std::mutex > lock(demodDataOut->m_mutex); demodDataOut->frequency = data_in->frequency; - demodDataOut->bandwidth = data_in->bandwidth; + demodDataOut->sampleRate = data_in->sampleRate; demodDataOut->setRefCount(activeDemods); demodDataOut->data.assign(dataOut.begin(), dataOut.end()); @@ -165,12 +165,12 @@ void SDRPostThread::threadMain() { DemodulatorThreadInputQueue *demodQueue = demod->threadQueueDemod; if (demod->getFrequency() != data_in->frequency - && abs(data_in->frequency - demod->getFrequency()) > (SRATE / 2)) { + && abs(data_in->frequency - demod->getFrequency()) > (wxGetApp().getSampleRate() / 2)) { if (demod->isActive()) { demod->setActive(false); DemodulatorThreadIQData *dummyDataOut = new DemodulatorThreadIQData; dummyDataOut->frequency = data_in->frequency; - dummyDataOut->bandwidth = data_in->bandwidth; + dummyDataOut->sampleRate = data_in->sampleRate; demodQueue->push(dummyDataOut); } } else if (!demod->isActive()) { diff --git a/src/sdr/SDRPostThread.h b/src/sdr/SDRPostThread.h index 7b222a7..c76aecf 100644 --- a/src/sdr/SDRPostThread.h +++ b/src/sdr/SDRPostThread.h @@ -22,8 +22,6 @@ public: void terminate(); protected: - uint32_t sample_rate; - std::atomic iqDataInQueue; std::atomic iqDataOutQueue; std::atomic iqVisualQueue; diff --git a/src/sdr/SDRThread.cpp b/src/sdr/SDRThread.cpp index 528b2a2..8cd7dbb 100644 --- a/src/sdr/SDRThread.cpp +++ b/src/sdr/SDRThread.cpp @@ -4,16 +4,16 @@ #include "CubicSDR.h" SDRThread::SDRThread(SDRThreadCommandQueue* pQueue) : - commandQueue(pQueue), iqDataOutQueue(NULL), terminated(false), offset(0) { + commandQueue(pQueue), iqDataOutQueue(NULL), terminated(false), offset(0), deviceId(-1) { dev = NULL; - sampleRate = SRATE; + sampleRate = DEFAULT_SAMPLE_RATE; } SDRThread::~SDRThread() { rtlsdr_close(dev); } -int SDRThread::enumerate_rtl() { +int SDRThread::enumerate_rtl(std::vector *devs) { int first_available = -1; @@ -24,37 +24,51 @@ int SDRThread::enumerate_rtl() { std::cout << "RTL Devices: " << rtl_count << std::endl; for (int i = 0; i < rtl_count; i++) { - std::cout << "Device #" << i << ": " << rtlsdr_get_device_name(i) << std::endl; + std::string deviceName(rtlsdr_get_device_name(i)); + std::string deviceManufacturer; + std::string deviceProduct; + std::string deviceTuner; + std::string deviceSerial; + + bool deviceAvailable = false; + std::cout << "Device #" << i << ": " << deviceName << std::endl; if (rtlsdr_get_device_usb_strings(i, manufact, product, serial) == 0) { std::cout << "\tManufacturer: " << manufact << ", Product Name: " << product << ", Serial: " << serial << std::endl; - rtlsdr_open(&dev, i); + deviceSerial = serial; + deviceAvailable = true; + deviceProduct = product; + deviceManufacturer = manufact; + + rtlsdr_dev_t *devTest; + rtlsdr_open(&devTest, i); std::cout << "\t Tuner type: "; - switch (rtlsdr_get_tuner_type(dev)) { + switch (rtlsdr_get_tuner_type(devTest)) { case RTLSDR_TUNER_UNKNOWN: - std::cout << "Unknown"; + deviceTuner = "Unknown"; break; case RTLSDR_TUNER_E4000: - std::cout << "Elonics E4000"; + deviceTuner = "Elonics E4000"; break; case RTLSDR_TUNER_FC0012: - std::cout << "Fitipower FC0012"; + deviceTuner = "Fitipower FC0012"; break; case RTLSDR_TUNER_FC0013: - std::cout << "Fitipower FC0013"; + deviceTuner = "Fitipower FC0013"; break; case RTLSDR_TUNER_FC2580: - std::cout << "Fitipower FC2580"; + deviceTuner = "Fitipower FC2580"; break; case RTLSDR_TUNER_R820T: - std::cout << "Rafael Micro R820T"; + deviceTuner = "Rafael Micro R820T"; break; case RTLSDR_TUNER_R828D: + deviceTuner = "Rafael Micro R828D"; break; } - std::cout << std::endl; + std::cout << deviceTuner << std::endl; /* int num_gains = rtlsdr_get_tuner_gains(dev, NULL); @@ -73,7 +87,7 @@ int SDRThread::enumerate_rtl() { free(gains); */ - rtlsdr_close(dev); + rtlsdr_close(devTest); if (first_available == -1) { first_available = i; } @@ -82,6 +96,15 @@ int SDRThread::enumerate_rtl() { std::cout << "\tUnable to access device #" << i << " (in use?)" << std::endl; } + if (devs != NULL) { + SDRDeviceInfo *devInfo = new SDRDeviceInfo(); + devInfo->setName(deviceName); + devInfo->setAvailable(deviceAvailable); + devInfo->setProduct(deviceProduct); + devInfo->setSerial(deviceSerial); + devInfo->setManufacturer(deviceManufacturer); + devs->push_back(devInfo); + } } return first_available; @@ -92,35 +115,36 @@ void SDRThread::threadMain() { #ifdef __APPLE__ pthread_t tID = pthread_self(); // ID of this thread int priority = sched_get_priority_max( SCHED_FIFO) - 1; - sched_param prio = {priority}; // scheduling priority of thread + sched_param prio = { priority }; // scheduling priority of thread pthread_setschedparam(tID, SCHED_FIFO, &prio); #endif std::cout << "SDR thread initializing.." << std::endl; int devCount = rtlsdr_get_device_count(); - int firstDevAvailable = enumerate_rtl(); + if (deviceId == -1) { + deviceId = enumerate_rtl(NULL); + } - if (firstDevAvailable == -1) { + if (deviceId == -1) { std::cout << "No devices found.. SDR Thread exiting.." << std::endl; return; } else { - std::cout << "Using first available RTL-SDR device #" << firstDevAvailable << std::endl; + std::cout << "Using device #" << deviceId << std::endl; } signed char buf[BUF_SIZE]; long long frequency = DEFAULT_FREQ; - unsigned int bandwidth = SRATE; - rtlsdr_open(&dev, firstDevAvailable); - rtlsdr_set_sample_rate(dev, bandwidth); - rtlsdr_set_center_freq(dev, frequency); + rtlsdr_open(&dev, deviceId); + rtlsdr_set_sample_rate(dev, sampleRate); + rtlsdr_set_center_freq(dev, frequency - offset); rtlsdr_set_agc_mode(dev, 1); rtlsdr_set_offset_tuning(dev, 0); rtlsdr_reset_buffer(dev); - sampleRate = rtlsdr_get_sample_rate(dev); +// sampleRate = rtlsdr_get_sample_rate(dev); std::cout << "Sample Rate is: " << sampleRate << std::endl; @@ -138,8 +162,12 @@ void SDRThread::threadMain() { if (!cmdQueue->empty()) { bool freq_changed = false; bool offset_changed = false; + bool rate_changed = false; + bool device_changed = false; long long new_freq; long long new_offset; + long long new_rate; + int new_device; while (!cmdQueue->empty()) { SDRThreadCommand command; @@ -149,8 +177,8 @@ void SDRThread::threadMain() { case SDRThreadCommand::SDR_THREAD_CMD_TUNE: freq_changed = true; new_freq = command.llong_value; - if (new_freq < SRATE / 2) { - new_freq = SRATE / 2; + if (new_freq < sampleRate / 2) { + new_freq = sampleRate / 2; } std::cout << "Set frequency: " << new_freq << std::endl; break; @@ -159,19 +187,41 @@ void SDRThread::threadMain() { new_offset = command.llong_value; std::cout << "Set offset: " << new_offset << std::endl; break; + case SDRThreadCommand::SDR_THREAD_CMD_SET_SAMPLERATE: + rate_changed = true; + new_rate = command.llong_value; + std::cout << "Set sample rate: " << new_rate << std::endl; + break; + case SDRThreadCommand::SDR_THREAD_CMD_SET_DEVICE: + device_changed = true; + new_device = (int) command.llong_value; + std::cout << "Set device: " << new_device << std::endl; + break; default: break; } } + if (device_changed) { + rtlsdr_close(dev); + rtlsdr_open(&dev, new_device); + rtlsdr_set_sample_rate(dev, sampleRate); + rtlsdr_set_center_freq(dev, frequency - offset); + rtlsdr_set_agc_mode(dev, 1); + rtlsdr_set_offset_tuning(dev, 0); + rtlsdr_reset_buffer(dev); + } if (offset_changed && !freq_changed) { new_freq = frequency; freq_changed = true; offset = new_offset; } - if (freq_changed) { + if (rate_changed) { + sampleRate = new_rate; + rtlsdr_set_sample_rate(dev, new_rate); + } else if (freq_changed) { frequency = new_freq; - rtlsdr_set_center_freq(dev, frequency-offset); + rtlsdr_set_center_freq(dev, frequency - offset); } } @@ -194,7 +244,7 @@ void SDRThread::threadMain() { // std::lock_guard < std::mutex > lock(dataOut->m_mutex); dataOut->setRefCount(1); dataOut->frequency = frequency; - dataOut->bandwidth = bandwidth; + dataOut->sampleRate = sampleRate; if (dataOut->data.capacity() < n_read) { dataOut->data.reserve(n_read); diff --git a/src/sdr/SDRThread.h b/src/sdr/SDRThread.h index 3143d4c..032178f 100644 --- a/src/sdr/SDRThread.h +++ b/src/sdr/SDRThread.h @@ -14,10 +14,71 @@ #include "ThreadQueue.h" #include "DemodulatorMgr.h" +class SDRDeviceInfo { +public: + SDRDeviceInfo() : name(""), serial(""), available(false) { } + + bool isAvailable() const { + return available; + } + + void setAvailable(bool available) { + this->available = available; + } + + const std::string& getName() const { + return name; + } + + void setName(const std::string& name) { + this->name = name; + } + + const std::string& getSerial() const { + return serial; + } + + void setSerial(const std::string& serial) { + this->serial = serial; + } + + const std::string& getTuner() const { + return tuner; + } + + void setTuner(const std::string& tuner) { + this->tuner = tuner; + } + + const std::string& getManufacturer() const { + return manufacturer; + } + + void setManufacturer(const std::string& manufacturer) { + this->manufacturer = manufacturer; + } + + const std::string& getProduct() const { + return product; + } + + void setProduct(const std::string& product) { + this->product = product; + } + +private: + std::string name; + std::string serial; + std::string product; + std::string manufacturer; + std::string tuner; + bool available; +}; + class SDRThreadCommand { public: enum SDRThreadCommandEnum { - SDR_THREAD_CMD_NULL, SDR_THREAD_CMD_TUNE, SDR_THREAD_CMD_SET_OFFSET + SDR_THREAD_CMD_NULL, SDR_THREAD_CMD_TUNE, SDR_THREAD_CMD_SET_OFFSET, SDR_THREAD_CMD_SET_SAMPLERATE, SDR_THREAD_CMD_SET_DEVICE }; SDRThreadCommand() : @@ -37,16 +98,16 @@ public: class SDRThreadIQData: public ReferenceCounter { public: long long frequency; - unsigned int bandwidth; + long long sampleRate; std::vector data; SDRThreadIQData() : - frequency(0), bandwidth(0) { + frequency(0), sampleRate(DEFAULT_SAMPLE_RATE) { } - SDRThreadIQData(unsigned int bandwidth, long long frequency, std::vector *data) : - frequency(frequency), bandwidth(bandwidth) { + SDRThreadIQData(long long bandwidth, long long frequency, std::vector *data) : + frequency(frequency), sampleRate(bandwidth) { } @@ -65,7 +126,7 @@ public: SDRThread(SDRThreadCommandQueue* pQueue); ~SDRThread(); - int enumerate_rtl(); + static int enumerate_rtl(std::vector *devs); void threadMain(); @@ -74,6 +135,15 @@ public: } void terminate(); + + int getDeviceId() const { + return deviceId; + } + + void setDeviceId(int deviceId) { + this->deviceId = deviceId; + } + protected: uint32_t sampleRate; long long offset; @@ -81,4 +151,5 @@ protected: std::atomic iqDataOutQueue; std::atomic terminated; + int deviceId; }; diff --git a/src/visual/InteractiveCanvas.cpp b/src/visual/InteractiveCanvas.cpp index 204a808..226d8f5 100644 --- a/src/visual/InteractiveCanvas.cpp +++ b/src/visual/InteractiveCanvas.cpp @@ -37,7 +37,7 @@ void InteractiveCanvas::setView(long long center_freq_in, int bandwidth_in) { void InteractiveCanvas::disableView() { isView = false; centerFreq = wxGetApp().getFrequency(); - bandwidth = SRATE; + bandwidth = wxGetApp().getSampleRate(); lastBandwidth = 0; } @@ -69,7 +69,7 @@ unsigned int InteractiveCanvas::getBandwidth() { if (isView) { return bandwidth; } else { - return SRATE; + return wxGetApp().getSampleRate(); } } diff --git a/src/visual/PrimaryGLContext.cpp b/src/visual/PrimaryGLContext.cpp index 4bb3719..2189dcb 100644 --- a/src/visual/PrimaryGLContext.cpp +++ b/src/visual/PrimaryGLContext.cpp @@ -96,6 +96,9 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, float r, float if (!demod) { return; } + if (!srate) { + srate = wxGetApp().getSampleRate(); + } GLint vp[4]; glGetIntegerv( GL_VIEWPORT, vp); @@ -171,6 +174,9 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, float r, float g, f if (!demod) { return; } + if (!srate) { + srate = wxGetApp().getSampleRate(); + } if (center_freq == -1) { center_freq = wxGetApp().getFrequency(); @@ -271,6 +277,10 @@ void PrimaryGLContext::DrawFreqSelector(float uxPos, float r, float g, float b, bw = demod->getBandwidth(); } + if (!srate) { + srate = wxGetApp().getSampleRate(); + } + glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); diff --git a/src/visual/PrimaryGLContext.h b/src/visual/PrimaryGLContext.h index 85e22af..620ae2a 100644 --- a/src/visual/PrimaryGLContext.h +++ b/src/visual/PrimaryGLContext.h @@ -23,9 +23,9 @@ public: void BeginDraw(); void EndDraw(); - void DrawFreqSelector(float uxPos, float r = 1, float g = 1, float b = 1, float w = 0, long long center_freq = -1, long long srate = SRATE); - void DrawDemod(DemodulatorInstance *demod, float r = 1, float g = 1, float b = 1, long long center_freq = -1, long long srate = SRATE); - void DrawDemodInfo(DemodulatorInstance *demod, float r = 1, float g = 1, float b = 1, long long center_freq = -1, long long srate = SRATE); + void DrawFreqSelector(float uxPos, float r = 1, float g = 1, float b = 1, float w = 0, long long center_freq = -1, long long srate = 0); + void DrawDemod(DemodulatorInstance *demod, float r = 1, float g = 1, float b = 1, long long center_freq = -1, long long srate = 0); + void DrawDemodInfo(DemodulatorInstance *demod, float r = 1, float g = 1, float b = 1, long long center_freq = -1, long long srate = 0); static GLFont &getFont(GLFontSize esize); diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index e92b066..bdfc668 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -196,16 +196,16 @@ void SpectrumCanvas::OnMouseMoved(wxMouseEvent& event) { long long bwOfs = (centerFreq > freq) ? ((long long) bandwidth / 2) : (-(long long) bandwidth / 2); long long freqEdge = centerFreq + bwOfs; - if (abs(freq - freqEdge) > (SRATE / 2)) { - freqChange = -((centerFreq > freq) ? (freqEdge - freq - (SRATE / 2)) : (freqEdge - freq + (SRATE / 2))); + if (abs(freq - freqEdge) > (wxGetApp().getSampleRate() / 2)) { + freqChange = -((centerFreq > freq) ? (freqEdge - freq - (wxGetApp().getSampleRate() / 2)) : (freqEdge - freq + (wxGetApp().getSampleRate() / 2))); } else { freqChange = 0; } } if (freqChange) { - if (freq - freqChange < SRATE/2) { - freq = SRATE/2; + if (freq - freqChange < wxGetApp().getSampleRate()/2) { + freq = wxGetApp().getSampleRate()/2; } else { freq -= freqChange; } diff --git a/src/visual/TuningCanvas.cpp b/src/visual/TuningCanvas.cpp index eec0293..b0d6ab5 100644 --- a/src/visual/TuningCanvas.cpp +++ b/src/visual/TuningCanvas.cpp @@ -67,7 +67,7 @@ void TuningCanvas::OnIdle(wxIdleEvent &event) { dragAccum += mouseTracker.getMouseX() - mouseTracker.getOriginMouseX(); if (uxDown > 0.275) { - wxGetApp().setFrequency(wxGetApp().getFrequency() + (int) (mouseTracker.getOriginDeltaMouseX() * SRATE * 15.0)); + wxGetApp().setFrequency(wxGetApp().getFrequency() + (int) (mouseTracker.getOriginDeltaMouseX() * (float)wxGetApp().getSampleRate() * 15.0)); } if (abs(dragAccum * 10.0) >= 1) { diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index f2540cd..1f5a8a5 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -214,7 +214,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { freq = wxGetApp().getFrequency(); originalFreq = freq; if (shiftDown) { - freq += SRATE * 10; + freq += wxGetApp().getSampleRate() * 10; if (isView) { setView(centerFreq + (freq - originalFreq), getBandwidth()); if (spectrumCanvas) { @@ -222,7 +222,7 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { } } } else { - freq += SRATE / 2; + freq += wxGetApp().getSampleRate() / 2; if (isView) { setView(centerFreq + (freq - originalFreq), getBandwidth()); if (spectrumCanvas) { @@ -237,10 +237,10 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { freq = wxGetApp().getFrequency(); originalFreq = freq; if (shiftDown) { - if ((freq - SRATE * 10) < SRATE / 2) { - freq = SRATE / 2; + if ((freq - wxGetApp().getSampleRate() * 10) < wxGetApp().getSampleRate() / 2) { + freq = wxGetApp().getSampleRate() / 2; } else { - freq -= SRATE * 10; + freq -= wxGetApp().getSampleRate() * 10; } if (isView) { setView(centerFreq + (freq - originalFreq), getBandwidth()); @@ -249,10 +249,10 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { } } } else { - if ((freq - SRATE / 2) < SRATE / 2) { - freq = SRATE / 2; + if ((freq - wxGetApp().getSampleRate() / 2) < wxGetApp().getSampleRate() / 2) { + freq = wxGetApp().getSampleRate() / 2; } else { - freq -= SRATE / 2; + freq -= wxGetApp().getSampleRate() / 2; } if (isView) { setView(centerFreq + (freq - originalFreq), getBandwidth()); @@ -339,8 +339,8 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) { if (isView) { bw = getBandwidth(); bw = (long long) ceil((long double) bw * currentZoom); - if (bw >= SRATE) { - bw = SRATE; + if (bw >= wxGetApp().getSampleRate()) { + bw = wxGetApp().getSampleRate(); disableView(); if (spectrumCanvas) { spectrumCanvas->disableView(); @@ -361,11 +361,11 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) { } } } - if (centerFreq < freq && (centerFreq - bandwidth / 2) < (freq - SRATE / 2)) { - centerFreq = (freq - SRATE / 2) + bandwidth / 2; + if (centerFreq < freq && (centerFreq - bandwidth / 2) < (freq - wxGetApp().getSampleRate() / 2)) { + centerFreq = (freq - wxGetApp().getSampleRate() / 2) + bandwidth / 2; } - if (centerFreq > freq && (centerFreq + bandwidth / 2) > (freq + SRATE / 2)) { - centerFreq = (freq + SRATE / 2) - bandwidth / 2; + if (centerFreq > freq && (centerFreq + bandwidth / 2) > (freq + wxGetApp().getSampleRate() / 2)) { + centerFreq = (freq + wxGetApp().getSampleRate() / 2) - bandwidth / 2; } } @@ -385,16 +385,16 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) { } if (isView) { - if (!input->frequency || !input->bandwidth) { + if (!input->frequency || !input->sampleRate) { return; } if (centerFreq != input->frequency) { - if ((centerFreq - input->frequency) != shiftFrequency || lastInputBandwidth != input->bandwidth) { - if (abs(input->frequency - centerFreq) < (SRATE / 2)) { + if ((centerFreq - input->frequency) != shiftFrequency || lastInputBandwidth != input->sampleRate) { + if (abs(input->frequency - centerFreq) < (wxGetApp().getSampleRate() / 2)) { shiftFrequency = centerFreq - input->frequency; nco_crcf_reset(freqShifter); - nco_crcf_set_frequency(freqShifter, (2.0 * M_PI) * (((double) abs(shiftFrequency)) / ((double) input->bandwidth))); + nco_crcf_set_frequency(freqShifter, (2.0 * M_PI) * (((double) abs(shiftFrequency)) / ((double) input->sampleRate))); } } @@ -414,8 +414,8 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) { shiftBuffer.assign(input->data.begin(), input->data.end()); } - if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != input->bandwidth) { - resamplerRatio = (double) (bandwidth) / (double) input->bandwidth; + if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != input->sampleRate) { + resamplerRatio = (double) (bandwidth) / (double) input->sampleRate; float As = 120.0f; @@ -425,7 +425,7 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) { resampler = msresamp_crcf_create(resamplerRatio, As); lastBandwidth = bandwidth; - lastInputBandwidth = input->bandwidth; + lastInputBandwidth = input->sampleRate; } int out_size = ceil((double) (input->data.size()) * resamplerRatio) + 512; @@ -562,8 +562,8 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) { int currentBW = demod->getBandwidth(); currentBW = currentBW + bwDiff; - if (currentBW > SRATE) { - currentBW = SRATE; + if (currentBW > wxGetApp().getSampleRate()) { + currentBW = wxGetApp().getSampleRate(); } if (currentBW < MIN_BANDWIDTH) { currentBW = MIN_BANDWIDTH;