diff --git a/external/rtaudio/RtAudio.cpp b/external/rtaudio/RtAudio.cpp index 6ad1eb5..ddd8ff3 100644 --- a/external/rtaudio/RtAudio.cpp +++ b/external/rtaudio/RtAudio.cpp @@ -180,7 +180,7 @@ RtAudio :: RtAudio( RtAudio::Api api ) getCompiledApi( apis ); for ( unsigned int i=0; igetDeviceCount() ) break; + if ( rtapi_ && rtapi_->getDeviceCount() ) break; } if ( rtapi_ ) return; diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index c55e61c..6532d0a 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -45,7 +45,6 @@ AppFrame::AppFrame() : #endif wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); - wxBoxSizer *demodOpts = new wxBoxSizer(wxVERTICAL); wxBoxSizer *demodVisuals = new wxBoxSizer(wxVERTICAL); wxBoxSizer *demodTray = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *demodScopeTray = new wxBoxSizer(wxVERTICAL); diff --git a/src/audio/AudioThread.h b/src/audio/AudioThread.h index 0d10f97..7adfa6f 100644 --- a/src/audio/AudioThread.h +++ b/src/audio/AudioThread.h @@ -18,6 +18,7 @@ public: int channels; float peak; std::vector data; + std::mutex busy_update; AudioThreadInput() : frequency(0), sampleRate(0), channels(0), peak(0) { diff --git a/src/demod/DemodDefs.h b/src/demod/DemodDefs.h index 6282ac0..5f3e3fb 100644 --- a/src/demod/DemodDefs.h +++ b/src/demod/DemodDefs.h @@ -61,6 +61,7 @@ public: long long frequency; long long sampleRate; std::vector data; + std::mutex busy_rw; DemodulatorThreadIQData() : frequency(0), sampleRate(0) { diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index a14f8e2..57031e5 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -310,6 +310,8 @@ void DemodulatorThread::threadMain() { if (ati && audioVisOutputQueue != NULL && audioVisOutputQueue->empty()) { + ati_vis->busy_update.lock(); + int num_vis = DEMOD_VIS_SIZE; if (stereo) { ati_vis->channels = 2; @@ -342,6 +344,8 @@ void DemodulatorThread::threadMain() { // std::cout << "Signal: " << agc_crcf_get_signal_level(agc) << " -- " << agc_crcf_get_rssi(agc) << "dB " << std::endl; } + ati_vis->busy_update.unlock(); + audioVisOutputQueue->push(ati_vis); } if (!threadQueueControl->empty()) { diff --git a/src/sdr/SDRPostThread.cpp b/src/sdr/SDRPostThread.cpp index 43839cb..9b5ab71 100644 --- a/src/sdr/SDRPostThread.cpp +++ b/src/sdr/SDRPostThread.cpp @@ -111,6 +111,9 @@ void SDRPostThread::threadMain() { } if (iqVisualQueue.load() != NULL && iqVisualQueue.load()->empty()) { + + visualDataOut->busy_rw.lock(); + if (visualDataOut->data.size() < num_vis_samples) { if (visualDataOut->data.capacity() < num_vis_samples) { visualDataOut->data.reserve(num_vis_samples); @@ -121,6 +124,9 @@ void SDRPostThread::threadMain() { visualDataOut->frequency = data_in->frequency; visualDataOut->sampleRate = data_in->sampleRate; visualDataOut->data.assign(dataOut.begin(), dataOut.begin() + num_vis_samples); + + visualDataOut->busy_rw.unlock(); + iqVisualQueue.load()->push(visualDataOut); } diff --git a/src/util/DataTree.cpp b/src/util/DataTree.cpp index 2f54cfa..1a17ec7 100755 --- a/src/util/DataTree.cpp +++ b/src/util/DataTree.cpp @@ -38,7 +38,7 @@ DataElement::DataElement() : data_type(DATA_NULL), data_val(NULL), data_size(0), DataElement::~DataElement() { if (data_val) { - delete data_val; + delete[] data_val; data_val = NULL; } } @@ -1309,9 +1309,9 @@ long DataTree::getSerialized(char **ser_str, bool debug) { memcpy(data_out + data_ptr, element_serialized, element_serialized_size); data_ptr += element_serialized_size; - delete de_name_index_serialized; - delete de_num_children_serialized; - delete element_serialized; + delete[] de_name_index_serialized; + delete[] de_num_children_serialized; + delete[] element_serialized; /* if it has children, traverse into them */ if (dn_stack.top()->hasAnother()) { @@ -1360,8 +1360,8 @@ void DataTree::setSerialized(char *ser_str, bool debug) { /* unserialization is a little less straightforward since we have to do a countdown of remaining children */ while (!dn_stack.empty()) { - int name_index; - int num_children; + int name_index = 0; + int num_children = 0; /* pull the index of the name of this node */ de_name_index.setSerialized(ser_str + data_ptr); @@ -1389,7 +1389,7 @@ void DataTree::setSerialized(char *ser_str, bool debug) { /* end debug output */ /* name index >= 1 means it has a name */ - if (name_index) { + if (name_index >= 1) { dn_stack.top()->setName(node_names[name_index - 1].c_str()); } else /* name is nil */ @@ -1568,10 +1568,10 @@ bool DataTree::SaveToFile(const std::string& filename, bool compress, int compre fout << flush; fout.close(); - delete hdr_serialized; + free(hdr_serialized); if (!compress) { - delete serialized; + free(serialized); } else { delete compressed; } @@ -1630,8 +1630,8 @@ bool DataTree::LoadFromFile(const std::string& filename) { setSerialized(serialized); - delete serialized; - delete hdr_serialized; + delete[] serialized; + delete[] hdr_serialized; return true; } diff --git a/src/visual/ModeSelectorCanvas.cpp b/src/visual/ModeSelectorCanvas.cpp index 8c16e5b..04bd0c1 100644 --- a/src/visual/ModeSelectorCanvas.cpp +++ b/src/visual/ModeSelectorCanvas.cpp @@ -59,13 +59,6 @@ void ModeSelectorCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { glContext->DrawBegin(); - DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); - - int demodType = 0; - if (demod) { - demodType = demod->getDemodulatorType(); - } - int yval = getHoveredSelection(); for (int i = 0; i < numChoices; i++) { diff --git a/src/visual/PrimaryGLContext.cpp b/src/visual/PrimaryGLContext.cpp index 74a406a..427f436 100644 --- a/src/visual/PrimaryGLContext.cpp +++ b/src/visual/PrimaryGLContext.cpp @@ -151,8 +151,6 @@ void PrimaryGLContext::DrawDemodInfo(DemodulatorInstance *demod, RGBColor color, glEnd(); if (ofs * 2.0 < 16.0 / viewWidth) { - ofs = 16.0 / viewWidth; - glColor4f(color.r, color.g, color.b, 0.2); glBegin(GL_QUADS); glVertex3f(uxPos - ofsLeft, hPos + labelHeight, 0.0); @@ -241,8 +239,8 @@ void PrimaryGLContext::DrawDemod(DemodulatorInstance *demod, RGBColor color, lon glEnable(GL_BLEND); - std::string demodStr; - GLFont::Align demodAlign; + std::string demodStr = ""; + GLFont::Align demodAlign = GLFont::GLFONT_ALIGN_CENTER; switch (demod->getDemodulatorType()) { case DEMOD_TYPE_FM: diff --git a/src/visual/ScopeCanvas.cpp b/src/visual/ScopeCanvas.cpp index 2b01de8..c80cc54 100644 --- a/src/visual/ScopeCanvas.cpp +++ b/src/visual/ScopeCanvas.cpp @@ -61,16 +61,23 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { if (!wxGetApp().getAudioVisualQueue()->empty()) { AudioThreadInput *demodAudioData; wxGetApp().getAudioVisualQueue()->pop(demodAudioData); - if (demodAudioData && demodAudioData->data.size()) { - if (waveform_points.size() != demodAudioData->data.size() * 2) { - waveform_points.resize(demodAudioData->data.size() * 2); + + int iMax = demodAudioData?demodAudioData->data.size():0; + + if (demodAudioData && iMax) { + if (waveform_points.size() != iMax * 2) { + waveform_points.resize(iMax * 2); } - for (int i = 0, iMax = demodAudioData->data.size(); i < iMax; i++) { + demodAudioData->busy_update.lock(); + + for (int i = 0; i < iMax; i++) { waveform_points[i * 2 + 1] = demodAudioData->data[i] * 0.5f; waveform_points[i * 2] = ((double) i / (double) iMax); } + demodAudioData->busy_update.unlock(); + setStereo(demodAudioData->channels == 2); } else { std::cout << "Incoming Demodulator data empty?" << std::endl; diff --git a/src/visual/TuningCanvas.cpp b/src/visual/TuningCanvas.cpp index 375c2d5..273fbf0 100644 --- a/src/visual/TuningCanvas.cpp +++ b/src/visual/TuningCanvas.cpp @@ -328,12 +328,6 @@ void TuningCanvas::OnMouseWheelMoved(wxMouseEvent& event) { } void TuningCanvas::OnMouseReleased(wxMouseEvent& event) { - GLint vp[4]; - glGetIntegerv( GL_VIEWPORT, vp); - - float viewHeight = (float) vp[3]; - float viewWidth = (float) vp[2]; - InteractiveCanvas::OnMouseReleased(event); int hExponent = hoverIndex - 1; diff --git a/src/visual/TuningContext.cpp b/src/visual/TuningContext.cpp index 16d49ac..8d1bdba 100644 --- a/src/visual/TuningContext.cpp +++ b/src/visual/TuningContext.cpp @@ -69,7 +69,6 @@ void TuningContext::DrawTuner(long long freq, int count, float displayPos, float glGetIntegerv( GL_VIEWPORT, vp); float viewHeight = (float) vp[3]; - float viewWidth = (float) vp[2]; freqStr.str(""); freqStr << freq; @@ -118,8 +117,6 @@ void TuningContext::DrawTunerDigitBox(int index, int count, float displayPos, fl glGetIntegerv( GL_VIEWPORT, vp); float viewHeight = (float) vp[3]; - float viewWidth = (float) vp[2]; - float pixelHeight = 2.0/viewHeight; glColor4f(1.0, 0,0,1); @@ -187,12 +184,6 @@ bool bottom) { } void TuningContext::DrawDemodFreqBw(long long freq, unsigned int bw, long long center) { - GLint vp[4]; - glGetIntegerv( GL_VIEWPORT, vp); - - float viewHeight = (float) vp[3]; - float viewWidth = (float) vp[2]; - DrawTuner(freq, 11, -1.0, (1.0 / 3.0) * 2.0); DrawTuner(bw, 7, -1.0 + (2.25 / 3.0), (1.0 / 4.0) * 2.0); DrawTuner(center, 11, -1.0 + (2.0 / 3.0) * 2.0, (1.0 / 3.0) * 2.0); diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index c504dcf..59f7c21 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -110,6 +110,8 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { DemodulatorThreadIQData *iqData; wxGetApp().getIQVisualQueue()->pop(iqData); + iqData->busy_rw.lock(); + if (iqData && iqData->data.size()) { setData(iqData); if (otherWaterfallCanvas) { @@ -118,6 +120,8 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { } else { std::cout << "Incoming IQ data empty?" << std::endl; } + + iqData->busy_rw.unlock(); } glContext->SetCurrent(*this); @@ -362,14 +366,12 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) { bw = getBandwidth(); bw = (long long) ceil((long double) bw * currentZoom); if (bw >= wxGetApp().getSampleRate()) { - bw = wxGetApp().getSampleRate(); disableView(); if (spectrumCanvas) { spectrumCanvas->disableView(); } } else { if (mouseTracker.mouseInView()) { - long long freq = wxGetApp().getFrequency(); long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); setBandwidth(bw); long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); @@ -517,8 +519,7 @@ void WaterfallCanvas::setData(DemodulatorThreadIQData *input) { } else { if (last_data_size + num_written < fft_size) { // priming - unsigned int num_copy = fft_size; - num_copy = fft_size - last_data_size; + unsigned int num_copy = fft_size - last_data_size; if (num_written > num_copy) { num_copy = num_written; } diff --git a/src/visual/WaterfallContext.cpp b/src/visual/WaterfallContext.cpp index f28a818..3ff3e30 100644 --- a/src/visual/WaterfallContext.cpp +++ b/src/visual/WaterfallContext.cpp @@ -13,8 +13,6 @@ void WaterfallContext::Setup(int fft_size_in, int num_waterfall_lines_in) { waterfall_lines = num_waterfall_lines_in; fft_size = fft_size_in; - int half_fft_size = fft_size / 2; - for (int i = 0; i < 2; i++) { if (waterfall[i]) { glDeleteTextures(1, &waterfall[i]); @@ -23,7 +21,6 @@ void WaterfallContext::Setup(int fft_size_in, int num_waterfall_lines_in) { waterfall_ofs[i] = waterfall_lines - 1; } - // Stagger memory updates at half intervals for tiles } void WaterfallContext::refreshTheme() { @@ -72,7 +69,7 @@ void WaterfallContext::Draw(std::vector &points) { } waterfall_slice = new unsigned char[half_fft_size]; - delete waterfall_tex; + delete[] waterfall_tex; } if (activeTheme != ThemeMgr::mgr.currentTheme) { @@ -107,7 +104,6 @@ void WaterfallContext::Draw(std::vector &points) { glGetIntegerv(GL_VIEWPORT, vp); float viewWidth = (float) vp[2]; - float viewHeight = (float) vp[3]; // some bias to prevent seams at odd scales float half_pixel = 1.0 / viewWidth;