From 61add8ae09d13d3e0115fc7291e8816d99fdb436 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Fri, 31 Jul 2015 21:03:17 -0400 Subject: [PATCH 01/11] VisualProcessor now a template base, more tweaking needed --- src/process/ScopeVisualProcessor.h | 49 ++++++++++++++------- src/process/SpectrumVisualProcessor.h | 9 +++- src/process/VisualProcessor.h | 61 +++++++++++++++++++------- src/process/WaterfallVisualProcessor.h | 8 +++- src/util/ThreadQueue.h | 9 ++++ 5 files changed, 99 insertions(+), 37 deletions(-) diff --git a/src/process/ScopeVisualProcessor.h b/src/process/ScopeVisualProcessor.h index e5dd56c..e8d411b 100644 --- a/src/process/ScopeVisualProcessor.h +++ b/src/process/ScopeVisualProcessor.h @@ -3,35 +3,54 @@ #include "VisualProcessor.h" #include "AudioThread.h" -class ScopeVisualProcessor : public VisualProcessor { -protected: - std::vector waveform_points; +class ScopeRenderData: public ReferenceCounter { +public: + std::vector waveform_points; + int channels; +}; +typedef ThreadQueue ScopeRenderDataQueue; + +class ScopeVisualProcessor : public VisualProcessor { +protected: virtual void process() { + if (isOutputEmpty()) { + return; + } if (!input->empty()) { - ReferenceCounter *ati_ref; - input->pop(ati_ref); - - AudioThreadInput *ati = (AudioThreadInput *)ati_ref; - if (!ati) { + AudioThreadInput *audioInputData; + input->pop(audioInputData); + + if (!audioInputData) { return; } - int iMax = ati->data.size(); + int iMax = audioInputData->data.size(); if (!iMax) { - ati->decRefCount(); + audioInputData->decRefCount(); return; } - if (waveform_points.size() != iMax * 2) { - waveform_points.resize(iMax * 2); + + ScopeRenderData *renderData = outputBuffers.getBuffer(); + renderData->channels = audioInputData->channels; + + if (renderData->waveform_points.size() != iMax * 2) { + renderData->waveform_points.resize(iMax * 2); } for (int i = 0; i < iMax; i++) { - waveform_points[i * 2 + 1] = ati->data[i] * 0.5f; - waveform_points[i * 2] = ((double) i / (double) iMax); + renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] * 0.5f; + renderData->waveform_points[i * 2] = ((double) i / (double) iMax); } + distribute(renderData); // ati->channels } + } + + ReBuffer outputBuffers; +}; + + /* if (!wxGetApp().getAudioVisualQueue()->empty()) { AudioThreadInput *demodAudioData; @@ -59,5 +78,3 @@ protected: } } */ - } -}; \ No newline at end of file diff --git a/src/process/SpectrumVisualProcessor.h b/src/process/SpectrumVisualProcessor.h index 20fa627..76d0789 100644 --- a/src/process/SpectrumVisualProcessor.h +++ b/src/process/SpectrumVisualProcessor.h @@ -1,8 +1,13 @@ #pragma once #include "VisualProcessor.h" +#include "SpectrumCanvas.h" -class SpectrumVisualProcessor : public VisualProcessor { +class SpectrumVisualData : public ReferenceCounter { + +}; + +class SpectrumVisualProcessor : public VisualProcessor { protected: virtual void process() { /* @@ -82,4 +87,4 @@ protected: } */ } -}; \ No newline at end of file +}; diff --git a/src/process/VisualProcessor.h b/src/process/VisualProcessor.h index 5ca4b7d..f6c876e 100644 --- a/src/process/VisualProcessor.h +++ b/src/process/VisualProcessor.h @@ -5,27 +5,30 @@ #include "IOThread.h" #include -typedef ThreadQueue VisualDataQueue; - +template class VisualProcessor { public: - void setInput(VisualDataQueue *vis_in) { + virtual ~VisualProcessor() { + + } + + void setInput(InputQueueType *vis_in) { busy_update.lock(); input = vis_in; busy_update.unlock(); } - void attachOutput(VisualDataQueue *vis_out) { + void attachOutput(OutputQueueType *vis_out) { // attach an output queue busy_update.lock(); outputs.push_back(vis_out); busy_update.unlock(); } - void removeOutput(VisualDataQueue *vis_out) { + void removeOutput(OutputQueueType *vis_out) { // remove an output queue busy_update.lock(); - std::vector::iterator i = std::find(outputs.begin(), outputs.end(), vis_out); + typename std::vector::iterator i = std::find(outputs.begin(), outputs.end(), vis_out); if (i != outputs.end()) { outputs.erase(i); } @@ -46,29 +49,53 @@ protected: // distribute(output); } - void distribute(ReferenceCounter *output) { + void distribute(OutputDataType *output) { // distribute outputs output->setRefCount(outputs.size()); - std::vector::iterator outputs_i; for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { - (*outputs_i)->push(output); + if ((*outputs_i)->full()) { + output->decRefCount(); + } else { + (*outputs_i)->push(output); + } } } - VisualDataQueue * input; - std::vector outputs; + bool isOutputEmpty() { + for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { + if (!(*outputs_i)->empty()) { + return false; + } + } + return true; + } + + bool isAnyOutputEmpty() { + for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { + if ((*outputs_i)->empty()) { + return true; + } + } + return false; + } + + InputQueueType *input; + std::vector outputs; + typename std::vector::iterator outputs_i; std::mutex busy_update; }; -class VisualDataDistributor : public VisualProcessor { +template +class VisualDataDistributor : public VisualProcessor { protected: - virtual void process() { - while (!input->empty()) { - ReferenceCounter *inp; - input->pop(inp); + void process() { + + while (!VisualProcessor::input->empty()) { + ReferenceCounter *inp; + VisualProcessor::input->pop(inp); if (inp) { - distribute(inp); + VisualProcessor::distribute(inp); } } } diff --git a/src/process/WaterfallVisualProcessor.h b/src/process/WaterfallVisualProcessor.h index b33c37e..2fabeba 100644 --- a/src/process/WaterfallVisualProcessor.h +++ b/src/process/WaterfallVisualProcessor.h @@ -1,9 +1,13 @@ #pragma once #include "VisualProcessor.h" +#include "WaterfallCanvas.h" +class WaterfallVisualData : public ReferenceCounter { -class WaterfallVisualProcessor : public VisualProcessor { +}; + +class WaterfallVisualProcessor : public VisualProcessor { protected: virtual void process() { /* @@ -278,4 +282,4 @@ protected: } */ } -}; \ No newline at end of file +}; diff --git a/src/util/ThreadQueue.h b/src/util/ThreadQueue.h index 6ef108a..67247a6 100644 --- a/src/util/ThreadQueue.h +++ b/src/util/ThreadQueue.h @@ -211,6 +211,15 @@ public: return m_queue.empty(); } + /** + * Check if the queue is empty. + * \return true if queue is empty. + */ + bool full() const { + std::lock_guard < std::mutex > lock(m_mutex); + return m_queue.size() >= m_max_num_items; + } + /** * Remove any items in the queue. */ From 6f3d9a6c82678d7052010b81fbcf223144062244 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Fri, 31 Jul 2015 21:28:14 -0400 Subject: [PATCH 02/11] visual process template tweaks, full() logic error fix --- src/process/ScopeVisualProcessor.h | 2 +- src/process/VisualProcessor.h | 26 +++++++++++++------------- src/util/ThreadQueue.h | 6 +++--- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/process/ScopeVisualProcessor.h b/src/process/ScopeVisualProcessor.h index e8d411b..44262ab 100644 --- a/src/process/ScopeVisualProcessor.h +++ b/src/process/ScopeVisualProcessor.h @@ -11,7 +11,7 @@ public: typedef ThreadQueue ScopeRenderDataQueue; -class ScopeVisualProcessor : public VisualProcessor { +class ScopeVisualProcessor : public VisualProcessor { protected: virtual void process() { if (isOutputEmpty()) { diff --git a/src/process/VisualProcessor.h b/src/process/VisualProcessor.h index f6c876e..f84c32d 100644 --- a/src/process/VisualProcessor.h +++ b/src/process/VisualProcessor.h @@ -5,30 +5,30 @@ #include "IOThread.h" #include -template +template class VisualProcessor { public: virtual ~VisualProcessor() { } - void setInput(InputQueueType *vis_in) { + void setInput(ThreadQueue *vis_in) { busy_update.lock(); input = vis_in; busy_update.unlock(); } - void attachOutput(OutputQueueType *vis_out) { + void attachOutput(ThreadQueue *vis_out) { // attach an output queue busy_update.lock(); outputs.push_back(vis_out); busy_update.unlock(); } - void removeOutput(OutputQueueType *vis_out) { + void removeOutput(ThreadQueue *vis_out) { // remove an output queue busy_update.lock(); - typename std::vector::iterator i = std::find(outputs.begin(), outputs.end(), vis_out); + typename std::vector *>::iterator i = std::find(outputs.begin(), outputs.end(), vis_out); if (i != outputs.end()) { outputs.erase(i); } @@ -79,23 +79,23 @@ protected: return false; } - InputQueueType *input; - std::vector outputs; - typename std::vector::iterator outputs_i; + ThreadQueue *input; + std::vector *> outputs; + typename std::vector *>::iterator outputs_i; std::mutex busy_update; }; -template -class VisualDataDistributor : public VisualProcessor { +template +class VisualDataDistributor : public VisualProcessor { protected: void process() { - while (!VisualProcessor::input->empty()) { + while (!VisualProcessor::input->empty()) { ReferenceCounter *inp; - VisualProcessor::input->pop(inp); + VisualProcessor::input->pop(inp); if (inp) { - VisualProcessor::distribute(inp); + VisualProcessor::distribute(inp); } } } diff --git a/src/util/ThreadQueue.h b/src/util/ThreadQueue.h index 67247a6..8ba5e0a 100644 --- a/src/util/ThreadQueue.h +++ b/src/util/ThreadQueue.h @@ -212,12 +212,12 @@ public: } /** - * Check if the queue is empty. - * \return true if queue is empty. + * Check if the queue is full. + * \return true if queue is full. */ bool full() const { std::lock_guard < std::mutex > lock(m_mutex); - return m_queue.size() >= m_max_num_items; + return (m_max_num_items != 0) && (m_queue.size() >= m_max_num_items); } /** From 8dfd94df8dd893dc70a4948f3955399df904a0c3 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Fri, 31 Jul 2015 21:33:31 -0400 Subject: [PATCH 03/11] ScopeVisualProcessor cleanup --- src/process/ScopeVisualProcessor.cpp | 35 +++++++++++- src/process/ScopeVisualProcessor.h | 80 ---------------------------- 2 files changed, 34 insertions(+), 81 deletions(-) delete mode 100644 src/process/ScopeVisualProcessor.h diff --git a/src/process/ScopeVisualProcessor.cpp b/src/process/ScopeVisualProcessor.cpp index 89af21c..c3ffbc9 100644 --- a/src/process/ScopeVisualProcessor.cpp +++ b/src/process/ScopeVisualProcessor.cpp @@ -1 +1,34 @@ -#include "ScopeVisualProcessor.h" \ No newline at end of file +#include "ScopeVisualProcessor.h" + +void ScopeVisualProcessor::process() { + if (isOutputEmpty()) { + return; + } + if (!input->empty()) { + AudioThreadInput *audioInputData; + input->pop(audioInputData); + + if (!audioInputData) { + return; + } + int iMax = audioInputData->data.size(); + if (!iMax) { + audioInputData->decRefCount(); + return; + } + + ScopeRenderData *renderData = outputBuffers.getBuffer(); + renderData->channels = audioInputData->channels; + + if (renderData->waveform_points.size() != iMax * 2) { + renderData->waveform_points.resize(iMax * 2); + } + + for (int i = 0; i < iMax; i++) { + renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] * 0.5f; + renderData->waveform_points[i * 2] = ((double) i / (double) iMax); + } + + distribute(renderData); + } +} diff --git a/src/process/ScopeVisualProcessor.h b/src/process/ScopeVisualProcessor.h deleted file mode 100644 index 44262ab..0000000 --- a/src/process/ScopeVisualProcessor.h +++ /dev/null @@ -1,80 +0,0 @@ -#pragma once - -#include "VisualProcessor.h" -#include "AudioThread.h" - -class ScopeRenderData: public ReferenceCounter { -public: - std::vector waveform_points; - int channels; -}; - -typedef ThreadQueue ScopeRenderDataQueue; - -class ScopeVisualProcessor : public VisualProcessor { -protected: - virtual void process() { - if (isOutputEmpty()) { - return; - } - if (!input->empty()) { - AudioThreadInput *audioInputData; - input->pop(audioInputData); - - if (!audioInputData) { - return; - } - int iMax = audioInputData->data.size(); - if (!iMax) { - audioInputData->decRefCount(); - return; - } - - ScopeRenderData *renderData = outputBuffers.getBuffer(); - renderData->channels = audioInputData->channels; - - if (renderData->waveform_points.size() != iMax * 2) { - renderData->waveform_points.resize(iMax * 2); - } - - for (int i = 0; i < iMax; i++) { - renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] * 0.5f; - renderData->waveform_points[i * 2] = ((double) i / (double) iMax); - } - - distribute(renderData); - // ati->channels - } - } - - ReBuffer outputBuffers; -}; - - -/* - if (!wxGetApp().getAudioVisualQueue()->empty()) { - AudioThreadInput *demodAudioData; - wxGetApp().getAudioVisualQueue()->pop(demodAudioData); - - int iMax = demodAudioData?demodAudioData->data.size():0; - - if (demodAudioData && iMax) { - if (waveform_points.size() != iMax * 2) { - waveform_points.resize(iMax * 2); - } - - 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; - } - } -*/ From e616ae1ebb1b25c33d2d67e7e097b9bfdfabcc48 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Fri, 31 Jul 2015 21:44:25 -0400 Subject: [PATCH 04/11] ScopeVisualProcessor header.. --- src/process/ScopeVisualProcessor.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/process/ScopeVisualProcessor.h diff --git a/src/process/ScopeVisualProcessor.h b/src/process/ScopeVisualProcessor.h new file mode 100644 index 0000000..08ce3bb --- /dev/null +++ b/src/process/ScopeVisualProcessor.h @@ -0,0 +1,18 @@ +#pragma once + +#include "VisualProcessor.h" +#include "AudioThread.h" + +class ScopeRenderData: public ReferenceCounter { +public: + std::vector waveform_points; + int channels; +}; + +typedef ThreadQueue ScopeRenderDataQueue; + +class ScopeVisualProcessor : public VisualProcessor { +protected: + void process(); + ReBuffer outputBuffers; +}; From 77f172027e4a7996103f940cbbe721b5388ebbef Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Fri, 31 Jul 2015 21:47:21 -0400 Subject: [PATCH 05/11] Spectrum, Waterfall processor prep --- src/process/SpectrumVisualProcessor.cpp | 81 ++++++- src/process/SpectrumVisualProcessor.h | 90 ------- src/process/WaterfallVisualProcessor.cpp | 276 +++++++++++++++++++++- src/process/WaterfallVisualProcessor.h | 285 ----------------------- 4 files changed, 355 insertions(+), 377 deletions(-) delete mode 100644 src/process/SpectrumVisualProcessor.h delete mode 100644 src/process/WaterfallVisualProcessor.h diff --git a/src/process/SpectrumVisualProcessor.cpp b/src/process/SpectrumVisualProcessor.cpp index dd69858..dcd99b7 100644 --- a/src/process/SpectrumVisualProcessor.cpp +++ b/src/process/SpectrumVisualProcessor.cpp @@ -1 +1,80 @@ -#include "SpectrumVisualProcessor.h" \ No newline at end of file +#include "SpectrumVisualProcessor.h" + +void SpectrumVisualProcessor::process() { + /* + std::vector *data = &input->data; + if (data && data->size()) { + if (fft_size != data->size()) { + setup(data->size()); + } + if (spectrum_points.size() < fft_size * 2) { + if (spectrum_points.capacity() < fft_size * 2) { + spectrum_points.reserve(fft_size * 2); + } + spectrum_points.resize(fft_size * 2); + } + + for (int i = 0; i < fft_size; i++) { + in[i][0] = (*data)[i].real; + in[i][1] = (*data)[i].imag; + } + + fftwf_execute(plan); + + float fft_ceil = 0, fft_floor = 1; + + if (fft_result.size() != fft_size) { + if (fft_result.capacity() < fft_size) { + fft_result.reserve(fft_size); + fft_result_ma.reserve(fft_size); + fft_result_maa.reserve(fft_size); + } + fft_result.resize(fft_size); + fft_result_ma.resize(fft_size); + fft_result_maa.resize(fft_size); + } + + int n; + for (int i = 0, iMax = fft_size / 2; i < iMax; i++) { + float a = out[i][0]; + float b = out[i][1]; + float c = sqrt(a * a + b * b); + + float x = out[fft_size / 2 + i][0]; + float y = out[fft_size / 2 + i][1]; + float z = sqrt(x * x + y * y); + + fft_result[i] = (z); + fft_result[fft_size / 2 + i] = (c); + } + + for (int i = 0, iMax = fft_size; i < iMax; i++) { + fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; + fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; + + if (fft_result_maa[i] > fft_ceil) { + fft_ceil = fft_result_maa[i]; + } + if (fft_result_maa[i] < fft_floor) { + fft_floor = fft_result_maa[i]; + } + } + + fft_ceil += 1; + fft_floor -= 1; + + fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.01; + fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.01; + + fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.01; + fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.01; + + for (int i = 0, iMax = fft_size; i < iMax; i++) { + float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); + spectrum_points[i * 2] = ((float) i / (float) iMax); + spectrum_points[i * 2 + 1] = v; + } + + } + */ +} \ No newline at end of file diff --git a/src/process/SpectrumVisualProcessor.h b/src/process/SpectrumVisualProcessor.h deleted file mode 100644 index 76d0789..0000000 --- a/src/process/SpectrumVisualProcessor.h +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include "VisualProcessor.h" -#include "SpectrumCanvas.h" - -class SpectrumVisualData : public ReferenceCounter { - -}; - -class SpectrumVisualProcessor : public VisualProcessor { -protected: - virtual void process() { - /* - std::vector *data = &input->data; - if (data && data->size()) { - if (fft_size != data->size()) { - setup(data->size()); - } - if (spectrum_points.size() < fft_size * 2) { - if (spectrum_points.capacity() < fft_size * 2) { - spectrum_points.reserve(fft_size * 2); - } - spectrum_points.resize(fft_size * 2); - } - - for (int i = 0; i < fft_size; i++) { - in[i][0] = (*data)[i].real; - in[i][1] = (*data)[i].imag; - } - - fftwf_execute(plan); - - float fft_ceil = 0, fft_floor = 1; - - if (fft_result.size() != fft_size) { - if (fft_result.capacity() < fft_size) { - fft_result.reserve(fft_size); - fft_result_ma.reserve(fft_size); - fft_result_maa.reserve(fft_size); - } - fft_result.resize(fft_size); - fft_result_ma.resize(fft_size); - fft_result_maa.resize(fft_size); - } - - int n; - for (int i = 0, iMax = fft_size / 2; i < iMax; i++) { - float a = out[i][0]; - float b = out[i][1]; - float c = sqrt(a * a + b * b); - - float x = out[fft_size / 2 + i][0]; - float y = out[fft_size / 2 + i][1]; - float z = sqrt(x * x + y * y); - - fft_result[i] = (z); - fft_result[fft_size / 2 + i] = (c); - } - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - - if (fft_result_maa[i] > fft_ceil) { - fft_ceil = fft_result_maa[i]; - } - if (fft_result_maa[i] < fft_floor) { - fft_floor = fft_result_maa[i]; - } - } - - fft_ceil += 1; - fft_floor -= 1; - - fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.01; - fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.01; - - fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.01; - fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.01; - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); - spectrum_points[i * 2] = ((float) i / (float) iMax); - spectrum_points[i * 2 + 1] = v; - } - - } -*/ - } -}; diff --git a/src/process/WaterfallVisualProcessor.cpp b/src/process/WaterfallVisualProcessor.cpp index 2b8a46e..153e489 100644 --- a/src/process/WaterfallVisualProcessor.cpp +++ b/src/process/WaterfallVisualProcessor.cpp @@ -1 +1,275 @@ -#include "WaterfallVisualProcessor.h" \ No newline at end of file +#include "WaterfallVisualProcessor.h" + +void WaterfallVisualProcessor::process() { + /* + long double currentZoom = zoom; + + if (mouseZoom != 1) { + currentZoom = mouseZoom; + mouseZoom = mouseZoom + (1.0 - mouseZoom) * 0.2; + if (fabs(mouseZoom-1.0)<0.01) { + mouseZoom = 1; + } + } + + long long bw; + if (currentZoom != 1) { + long long freq = wxGetApp().getFrequency(); + + if (currentZoom < 1) { + centerFreq = getCenterFrequency(); + bw = getBandwidth(); + bw = (long long) ceil((long double) bw * currentZoom); + if (bw < 100000) { + bw = 100000; + } + if (mouseTracker.mouseInView()) { + long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); + setBandwidth(bw); + long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); + centerFreq += mfreqA - mfreqB; + } + + setView(centerFreq, bw); + if (spectrumCanvas) { + spectrumCanvas->setView(centerFreq, bw); + } + } else { + if (isView) { + bw = getBandwidth(); + bw = (long long) ceil((long double) bw * currentZoom); + if (bw >= wxGetApp().getSampleRate()) { + disableView(); + if (spectrumCanvas) { + spectrumCanvas->disableView(); + } + } else { + if (mouseTracker.mouseInView()) { + long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); + setBandwidth(bw); + long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); + centerFreq += mfreqA - mfreqB; + } + + setView(getCenterFrequency(), bw); + if (spectrumCanvas) { + spectrumCanvas->setView(centerFreq, bw); + } + } + } + } + if (centerFreq < freq && (centerFreq - bandwidth / 2) < (freq - wxGetApp().getSampleRate() / 2)) { + centerFreq = (freq - wxGetApp().getSampleRate() / 2) + bandwidth / 2; + } + if (centerFreq > freq && (centerFreq + bandwidth / 2) > (freq + wxGetApp().getSampleRate() / 2)) { + centerFreq = (freq + wxGetApp().getSampleRate() / 2) - bandwidth / 2; + } + } + + std::vector *data = &input->data; + + if (data && data->size()) { + // if (fft_size != data->size() && !isView) { + // Setup(data->size(), waterfall_lines); + // } + + // if (last_bandwidth != bandwidth && !isView) { + // Setup(bandwidth, waterfall_lines); + // } + + if (spectrum_points.size() < fft_size * 2) { + spectrum_points.resize(fft_size * 2); + } + + unsigned int num_written; + + if (isView) { + if (!input->frequency || !input->sampleRate) { + return; + } + + resamplerRatio = (double) (bandwidth) / (double) input->sampleRate; + + int desired_input_size = fft_size / resamplerRatio; + + if (input->data.size() < desired_input_size) { + // std::cout << "fft underflow, desired: " << desired_input_size << " actual:" << input->data.size() << std::endl; + desired_input_size = input->data.size(); + } + + if (centerFreq != input->frequency) { + 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->sampleRate))); + } + } + + if (shiftBuffer.size() != desired_input_size) { + if (shiftBuffer.capacity() < desired_input_size) { + shiftBuffer.reserve(desired_input_size); + } + shiftBuffer.resize(desired_input_size); + } + + if (shiftFrequency < 0) { + nco_crcf_mix_block_up(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size); + } else { + nco_crcf_mix_block_down(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size); + } + } else { + shiftBuffer.assign(input->data.begin(), input->data.end()); + } + + if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != input->sampleRate) { + float As = 60.0f; + + if (resampler) { + msresamp_crcf_destroy(resampler); + } + resampler = msresamp_crcf_create(resamplerRatio, As); + + lastBandwidth = bandwidth; + lastInputBandwidth = input->sampleRate; + } + + + int out_size = ceil((double) (desired_input_size) * resamplerRatio) + 512; + + if (resampleBuffer.size() != out_size) { + if (resampleBuffer.capacity() < out_size) { + resampleBuffer.reserve(out_size); + } + resampleBuffer.resize(out_size); + } + + + msresamp_crcf_execute(resampler, &shiftBuffer[0], desired_input_size, &resampleBuffer[0], &num_written); + + resampleBuffer.resize(fft_size); + + if (num_written < fft_size) { + for (int i = 0; i < num_written; i++) { + fft_in_data[i][0] = resampleBuffer[i].real; + fft_in_data[i][1] = resampleBuffer[i].imag; + } + for (int i = num_written; i < fft_size; i++) { + fft_in_data[i][0] = 0; + fft_in_data[i][1] = 0; + } + } else { + for (int i = 0; i < fft_size; i++) { + fft_in_data[i][0] = resampleBuffer[i].real; + fft_in_data[i][1] = resampleBuffer[i].imag; + } + } + } else { + num_written = data->size(); + if (data->size() < fft_size) { + for (int i = 0, iMax = data->size(); i < iMax; i++) { + fft_in_data[i][0] = (*data)[i].real; + fft_in_data[i][1] = (*data)[i].imag; + } + for (int i = data->size(); i < fft_size; i++) { + fft_in_data[i][0] = 0; + fft_in_data[i][1] = 0; + } + } else { + for (int i = 0; i < fft_size; i++) { + fft_in_data[i][0] = (*data)[i].real; + fft_in_data[i][1] = (*data)[i].imag; + } + } + } + + bool execute = false; + + if (num_written >= fft_size) { + execute = true; + memcpy(in, fft_in_data, fft_size * sizeof(fftwf_complex)); + memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex)); + + } else { + if (last_data_size + num_written < fft_size) { // priming + unsigned int num_copy = fft_size - last_data_size; + if (num_written > num_copy) { + num_copy = num_written; + } + memcpy(fft_last_data, fft_in_data, num_copy * sizeof(fftwf_complex)); + last_data_size += num_copy; + } else { + unsigned int num_last = (fft_size - num_written); + memcpy(in, fft_last_data + (last_data_size - num_last), num_last * sizeof(fftwf_complex)); + memcpy(in + num_last, fft_in_data, num_written * sizeof(fftwf_complex)); + memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex)); + execute = true; + } + } + + if (execute) { + fftwf_execute(plan); + + float fft_ceil = 0, fft_floor = 1; + + if (fft_result.size() < fft_size) { + fft_result.resize(fft_size); + fft_result_ma.resize(fft_size); + fft_result_maa.resize(fft_size); + } + + int n; + for (int i = 0, iMax = fft_size / 2; i < iMax; i++) { + float a = out[i][0]; + float b = out[i][1]; + float c = sqrt(a * a + b * b); + + float x = out[fft_size / 2 + i][0]; + float y = out[fft_size / 2 + i][1]; + float z = sqrt(x * x + y * y); + + fft_result[i] = (z); + fft_result[fft_size / 2 + i] = (c); + } + + for (int i = 0, iMax = fft_size; i < iMax; i++) { + if (isView) { + fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; + fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; + } else { + fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; + fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; + } + + if (fft_result_maa[i] > fft_ceil) { + fft_ceil = fft_result_maa[i]; + } + if (fft_result_maa[i] < fft_floor) { + fft_floor = fft_result_maa[i]; + } + } + + fft_ceil += 0.25; + fft_floor -= 1; + + fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05; + fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.05; + + fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.05; + fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05; + + for (int i = 0, iMax = fft_size; i < iMax; i++) { + float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); + spectrum_points[i * 2] = ((float) i / (float) iMax); + spectrum_points[i * 2 + 1] = v; + } + + if (spectrumCanvas) { + spectrumCanvas->spectrum_points.assign(spectrum_points.begin(), spectrum_points.end()); + spectrumCanvas->getSpectrumContext()->setCeilValue(fft_ceil_maa); + spectrumCanvas->getSpectrumContext()->setFloorValue(fft_floor_maa); + } + } + } + */ +} \ No newline at end of file diff --git a/src/process/WaterfallVisualProcessor.h b/src/process/WaterfallVisualProcessor.h deleted file mode 100644 index 2fabeba..0000000 --- a/src/process/WaterfallVisualProcessor.h +++ /dev/null @@ -1,285 +0,0 @@ -#pragma once - -#include "VisualProcessor.h" -#include "WaterfallCanvas.h" - -class WaterfallVisualData : public ReferenceCounter { - -}; - -class WaterfallVisualProcessor : public VisualProcessor { -protected: - virtual void process() { -/* - long double currentZoom = zoom; - - if (mouseZoom != 1) { - currentZoom = mouseZoom; - mouseZoom = mouseZoom + (1.0 - mouseZoom) * 0.2; - if (fabs(mouseZoom-1.0)<0.01) { - mouseZoom = 1; - } - } - - long long bw; - if (currentZoom != 1) { - long long freq = wxGetApp().getFrequency(); - - if (currentZoom < 1) { - centerFreq = getCenterFrequency(); - bw = getBandwidth(); - bw = (long long) ceil((long double) bw * currentZoom); - if (bw < 100000) { - bw = 100000; - } - if (mouseTracker.mouseInView()) { - long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); - setBandwidth(bw); - long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); - centerFreq += mfreqA - mfreqB; - } - - setView(centerFreq, bw); - if (spectrumCanvas) { - spectrumCanvas->setView(centerFreq, bw); - } - } else { - if (isView) { - bw = getBandwidth(); - bw = (long long) ceil((long double) bw * currentZoom); - if (bw >= wxGetApp().getSampleRate()) { - disableView(); - if (spectrumCanvas) { - spectrumCanvas->disableView(); - } - } else { - if (mouseTracker.mouseInView()) { - long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); - setBandwidth(bw); - long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); - centerFreq += mfreqA - mfreqB; - } - - setView(getCenterFrequency(), bw); - if (spectrumCanvas) { - spectrumCanvas->setView(centerFreq, bw); - } - } - } - } - if (centerFreq < freq && (centerFreq - bandwidth / 2) < (freq - wxGetApp().getSampleRate() / 2)) { - centerFreq = (freq - wxGetApp().getSampleRate() / 2) + bandwidth / 2; - } - if (centerFreq > freq && (centerFreq + bandwidth / 2) > (freq + wxGetApp().getSampleRate() / 2)) { - centerFreq = (freq + wxGetApp().getSampleRate() / 2) - bandwidth / 2; - } - } - - std::vector *data = &input->data; - - if (data && data->size()) { - // if (fft_size != data->size() && !isView) { - // Setup(data->size(), waterfall_lines); - // } - - // if (last_bandwidth != bandwidth && !isView) { - // Setup(bandwidth, waterfall_lines); - // } - - if (spectrum_points.size() < fft_size * 2) { - spectrum_points.resize(fft_size * 2); - } - - unsigned int num_written; - - if (isView) { - if (!input->frequency || !input->sampleRate) { - return; - } - - resamplerRatio = (double) (bandwidth) / (double) input->sampleRate; - - int desired_input_size = fft_size / resamplerRatio; - - if (input->data.size() < desired_input_size) { - // std::cout << "fft underflow, desired: " << desired_input_size << " actual:" << input->data.size() << std::endl; - desired_input_size = input->data.size(); - } - - if (centerFreq != input->frequency) { - 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->sampleRate))); - } - } - - if (shiftBuffer.size() != desired_input_size) { - if (shiftBuffer.capacity() < desired_input_size) { - shiftBuffer.reserve(desired_input_size); - } - shiftBuffer.resize(desired_input_size); - } - - if (shiftFrequency < 0) { - nco_crcf_mix_block_up(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size); - } else { - nco_crcf_mix_block_down(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size); - } - } else { - shiftBuffer.assign(input->data.begin(), input->data.end()); - } - - if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != input->sampleRate) { - float As = 60.0f; - - if (resampler) { - msresamp_crcf_destroy(resampler); - } - resampler = msresamp_crcf_create(resamplerRatio, As); - - lastBandwidth = bandwidth; - lastInputBandwidth = input->sampleRate; - } - - - int out_size = ceil((double) (desired_input_size) * resamplerRatio) + 512; - - if (resampleBuffer.size() != out_size) { - if (resampleBuffer.capacity() < out_size) { - resampleBuffer.reserve(out_size); - } - resampleBuffer.resize(out_size); - } - - - msresamp_crcf_execute(resampler, &shiftBuffer[0], desired_input_size, &resampleBuffer[0], &num_written); - - resampleBuffer.resize(fft_size); - - if (num_written < fft_size) { - for (int i = 0; i < num_written; i++) { - fft_in_data[i][0] = resampleBuffer[i].real; - fft_in_data[i][1] = resampleBuffer[i].imag; - } - for (int i = num_written; i < fft_size; i++) { - fft_in_data[i][0] = 0; - fft_in_data[i][1] = 0; - } - } else { - for (int i = 0; i < fft_size; i++) { - fft_in_data[i][0] = resampleBuffer[i].real; - fft_in_data[i][1] = resampleBuffer[i].imag; - } - } - } else { - num_written = data->size(); - if (data->size() < fft_size) { - for (int i = 0, iMax = data->size(); i < iMax; i++) { - fft_in_data[i][0] = (*data)[i].real; - fft_in_data[i][1] = (*data)[i].imag; - } - for (int i = data->size(); i < fft_size; i++) { - fft_in_data[i][0] = 0; - fft_in_data[i][1] = 0; - } - } else { - for (int i = 0; i < fft_size; i++) { - fft_in_data[i][0] = (*data)[i].real; - fft_in_data[i][1] = (*data)[i].imag; - } - } - } - - bool execute = false; - - if (num_written >= fft_size) { - execute = true; - memcpy(in, fft_in_data, fft_size * sizeof(fftwf_complex)); - memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex)); - - } else { - if (last_data_size + num_written < fft_size) { // priming - unsigned int num_copy = fft_size - last_data_size; - if (num_written > num_copy) { - num_copy = num_written; - } - memcpy(fft_last_data, fft_in_data, num_copy * sizeof(fftwf_complex)); - last_data_size += num_copy; - } else { - unsigned int num_last = (fft_size - num_written); - memcpy(in, fft_last_data + (last_data_size - num_last), num_last * sizeof(fftwf_complex)); - memcpy(in + num_last, fft_in_data, num_written * sizeof(fftwf_complex)); - memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex)); - execute = true; - } - } - - if (execute) { - fftwf_execute(plan); - - float fft_ceil = 0, fft_floor = 1; - - if (fft_result.size() < fft_size) { - fft_result.resize(fft_size); - fft_result_ma.resize(fft_size); - fft_result_maa.resize(fft_size); - } - - int n; - for (int i = 0, iMax = fft_size / 2; i < iMax; i++) { - float a = out[i][0]; - float b = out[i][1]; - float c = sqrt(a * a + b * b); - - float x = out[fft_size / 2 + i][0]; - float y = out[fft_size / 2 + i][1]; - float z = sqrt(x * x + y * y); - - fft_result[i] = (z); - fft_result[fft_size / 2 + i] = (c); - } - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - if (isView) { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - } else { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - } - - if (fft_result_maa[i] > fft_ceil) { - fft_ceil = fft_result_maa[i]; - } - if (fft_result_maa[i] < fft_floor) { - fft_floor = fft_result_maa[i]; - } - } - - fft_ceil += 0.25; - fft_floor -= 1; - - fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05; - fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.05; - - fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.05; - fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05; - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); - spectrum_points[i * 2] = ((float) i / (float) iMax); - spectrum_points[i * 2 + 1] = v; - } - - if (spectrumCanvas) { - spectrumCanvas->spectrum_points.assign(spectrum_points.begin(), spectrum_points.end()); - spectrumCanvas->getSpectrumContext()->setCeilValue(fft_ceil_maa); - spectrumCanvas->getSpectrumContext()->setFloorValue(fft_floor_maa); - } - } - } -*/ - } -}; From c448070319e08156631ab9375179fd1e699cf22a Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Fri, 31 Jul 2015 21:47:44 -0400 Subject: [PATCH 06/11] Spectrum, Waterfall new headers --- src/process/SpectrumVisualProcessor.h | 13 +++++++++++++ src/process/WaterfallVisualProcessor.h | 15 +++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/process/SpectrumVisualProcessor.h create mode 100644 src/process/WaterfallVisualProcessor.h diff --git a/src/process/SpectrumVisualProcessor.h b/src/process/SpectrumVisualProcessor.h new file mode 100644 index 0000000..3fcc0ff --- /dev/null +++ b/src/process/SpectrumVisualProcessor.h @@ -0,0 +1,13 @@ +#pragma once + +#include "VisualProcessor.h" +#include "SpectrumCanvas.h" + +class SpectrumVisualData : public ReferenceCounter { + +}; + +class SpectrumVisualProcessor : public VisualProcessor { +protected: + void process(); +}; diff --git a/src/process/WaterfallVisualProcessor.h b/src/process/WaterfallVisualProcessor.h new file mode 100644 index 0000000..76cca22 --- /dev/null +++ b/src/process/WaterfallVisualProcessor.h @@ -0,0 +1,15 @@ +#pragma once + +#include "VisualProcessor.h" +#include "WaterfallCanvas.h" + +class WaterfallVisualData : public ReferenceCounter { + +}; + +class WaterfallVisualProcessor : public VisualProcessor { +protected: + void process() { + + } +}; From cd0adb0339506028b2bd8fce3b7cdbd0d4f05b6b Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Fri, 31 Jul 2015 21:48:49 -0400 Subject: [PATCH 07/11] Bad header def.. --- src/process/WaterfallVisualProcessor.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/process/WaterfallVisualProcessor.h b/src/process/WaterfallVisualProcessor.h index 76cca22..5c2aa62 100644 --- a/src/process/WaterfallVisualProcessor.h +++ b/src/process/WaterfallVisualProcessor.h @@ -9,7 +9,5 @@ class WaterfallVisualData : public ReferenceCounter { class WaterfallVisualProcessor : public VisualProcessor { protected: - void process() { - - } + void process(); }; From 560eec1336e032c6ef2dfc37c84b0ecc7b18d01a Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Sat, 1 Aug 2015 11:03:00 -0400 Subject: [PATCH 08/11] ScopeVisualProcessor now working --- src/AppFrame.cpp | 1 + src/CubicSDR.cpp | 6 ++++ src/CubicSDR.h | 5 +++ src/demod/DemodulatorInstance.cpp | 10 +++--- src/demod/DemodulatorInstance.h | 2 +- src/process/ScopeVisualProcessor.cpp | 2 +- src/process/VisualProcessor.h | 6 ++-- src/visual/ScopeCanvas.cpp | 51 +++++++++++++--------------- src/visual/ScopeCanvas.h | 8 ++--- 9 files changed, 50 insertions(+), 41 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index e345bba..ea7910f 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -91,6 +91,7 @@ AppFrame::AppFrame() : scopeCanvas = new ScopeCanvas(this, attribList); demodScopeTray->Add(scopeCanvas, 8, wxEXPAND | wxALL, 0); + wxGetApp().getScopeProcessor()->attachOutput(scopeCanvas->getInputQueue()); demodScopeTray->AddSpacer(1); diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index 49658b2..f17cec3 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -58,6 +58,8 @@ bool CubicSDR::OnInit() { pipeAudioVisualData = new DemodulatorThreadOutputQueue(); pipeAudioVisualData->set_max_num_items(1); + scopeProcessor.setInput(pipeAudioVisualData); + // I/Q Data pipeSDRIQData = new SDRThreadIQDataQueue; pipeSDRCommand = new SDRThreadCommandQueue(); @@ -248,6 +250,10 @@ long long CubicSDR::getFrequency() { return frequency; } +ScopeVisualProcessor *CubicSDR::getScopeProcessor() { + return &scopeProcessor; +} + DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() { return pipeAudioVisualData; } diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 556773d..6d4c4c8 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -16,6 +16,7 @@ #include "DemodulatorMgr.h" #include "AppConfig.h" #include "AppFrame.h" +#include "ScopeVisualProcessor.h" #include @@ -52,6 +53,8 @@ public: void setDevice(int deviceId); int getDevice(); + ScopeVisualProcessor *getScopeProcessor(); + DemodulatorThreadOutputQueue* getAudioVisualQueue(); DemodulatorThreadInputQueue* getIQVisualQueue(); DemodulatorMgr &getDemodMgr(); @@ -92,6 +95,8 @@ private: DemodulatorThreadInputQueue* pipeIQVisualData; DemodulatorThreadOutputQueue* pipeAudioVisualData; + ScopeVisualProcessor scopeProcessor; + std::thread *t_SDR; std::thread *t_PostSDR; }; diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index d39dcb4..c92f5b5 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -1,7 +1,7 @@ #include "DemodulatorInstance.h" DemodulatorInstance::DemodulatorInstance() : - pipeIQInputData(NULL), demodulatorThread(NULL), t_PreDemod(NULL), t_Demod(NULL), t_Audio(NULL), currentAudioGain(1.0) { + t_PreDemod(NULL), pipeIQInputData(NULL), demodulatorThread(NULL), t_Demod(NULL), t_Audio(NULL), currentAudioGain(1.0) { terminated.store(true); audioTerminated.store(true); @@ -30,17 +30,17 @@ DemodulatorInstance::DemodulatorInstance() : demodulatorPreThread->setOutputQueue("NotifyQueue",pipeDemodNotify); demodulatorPreThread->setInputQueue("CommandQueue",pipeDemodCommand); - audioInputQueue = new AudioThreadInputQueue; + pipeAudioData = new AudioThreadInputQueue; threadQueueControl = new DemodulatorThreadControlCommandQueue; demodulatorThread = new DemodulatorThread(); demodulatorThread->setInputQueue("IQDataInput",pipeIQDemodData); demodulatorThread->setInputQueue("ControlQueue",threadQueueControl); demodulatorThread->setOutputQueue("NotifyQueue",pipeDemodNotify); - demodulatorThread->setOutputQueue("AudioDataOutput", audioInputQueue); + demodulatorThread->setOutputQueue("AudioDataOutput", pipeAudioData); audioThread = new AudioThread(); - audioThread->setInputQueue("AudioDataInput", audioInputQueue); + audioThread->setInputQueue("AudioDataInput", pipeAudioData); audioThread->setOutputQueue("NotifyQueue", pipeDemodNotify); currentDemodType = demodulatorThread->getDemodulatorType(); @@ -55,7 +55,7 @@ DemodulatorInstance::~DemodulatorInstance() { delete pipeDemodCommand; delete pipeDemodNotify; delete threadQueueControl; - delete audioInputQueue; + delete pipeAudioData; } void DemodulatorInstance::setVisualOutputQueue(DemodulatorThreadOutputQueue *tQueue) { diff --git a/src/demod/DemodulatorInstance.h b/src/demod/DemodulatorInstance.h index acd28ad..d211746 100644 --- a/src/demod/DemodulatorInstance.h +++ b/src/demod/DemodulatorInstance.h @@ -18,7 +18,6 @@ public: std::thread *t_Demod; #endif - AudioThreadInputQueue *audioInputQueue; AudioThread *audioThread; std::thread *t_Audio; @@ -80,6 +79,7 @@ public: protected: DemodulatorThreadInputQueue* pipeIQInputData; DemodulatorThreadPostInputQueue* pipeIQDemodData; + AudioThreadInputQueue *pipeAudioData; DemodulatorThreadCommandQueue* pipeDemodCommand; DemodulatorThreadCommandQueue* pipeDemodNotify; DemodulatorPreThread *demodulatorPreThread; diff --git a/src/process/ScopeVisualProcessor.cpp b/src/process/ScopeVisualProcessor.cpp index c3ffbc9..4eff90d 100644 --- a/src/process/ScopeVisualProcessor.cpp +++ b/src/process/ScopeVisualProcessor.cpp @@ -1,7 +1,7 @@ #include "ScopeVisualProcessor.h" void ScopeVisualProcessor::process() { - if (isOutputEmpty()) { + if (!isOutputEmpty()) { return; } if (!input->empty()) { diff --git a/src/process/VisualProcessor.h b/src/process/VisualProcessor.h index f84c32d..4f8c898 100644 --- a/src/process/VisualProcessor.h +++ b/src/process/VisualProcessor.h @@ -52,7 +52,7 @@ protected: void distribute(OutputDataType *output) { // distribute outputs output->setRefCount(outputs.size()); - for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { + for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { if ((*outputs_i)->full()) { output->decRefCount(); } else { @@ -62,7 +62,7 @@ protected: } bool isOutputEmpty() { - for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { + for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { if (!(*outputs_i)->empty()) { return false; } @@ -71,7 +71,7 @@ protected: } bool isAnyOutputEmpty() { - for (outputs_i = outputs.begin(); outputs_i != outputs.begin(); outputs_i++) { + for (outputs_i = outputs.begin(); outputs_i != outputs.end(); outputs_i++) { if ((*outputs_i)->empty()) { return true; } diff --git a/src/visual/ScopeCanvas.cpp b/src/visual/ScopeCanvas.cpp index c80cc54..5c6bd54 100644 --- a/src/visual/ScopeCanvas.cpp +++ b/src/visual/ScopeCanvas.cpp @@ -21,19 +21,16 @@ wxEND_EVENT_TABLE() ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) : wxGLCanvas(parent, wxID_ANY, attribList, wxDefaultPosition, wxDefaultSize, - wxFULL_REPAINT_ON_RESIZE), parent(parent), stereo(false), ppmMode(false) { + wxFULL_REPAINT_ON_RESIZE), stereo(false), ppmMode(false) { glContext = new ScopeContext(this, &wxGetApp().GetContext(this)); + inputData.set_max_num_items(1); } ScopeCanvas::~ScopeCanvas() { } -void ScopeCanvas::setWaveformPoints(std::vector &waveform_points_in) { - waveform_points = waveform_points_in; -} - void ScopeCanvas::setStereo(bool state) { stereo = state; } @@ -58,30 +55,26 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { #endif const wxSize ClientSize = GetClientSize(); - if (!wxGetApp().getAudioVisualQueue()->empty()) { - AudioThreadInput *demodAudioData; - wxGetApp().getAudioVisualQueue()->pop(demodAudioData); + wxGetApp().getScopeProcessor()->run(); + if (!inputData.empty()) { + ScopeRenderData *avData; + inputData.pop(avData); - int iMax = demodAudioData?demodAudioData->data.size():0; - - if (demodAudioData && iMax) { - if (waveform_points.size() != iMax * 2) { - waveform_points.resize(iMax * 2); - } - - 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; + if (!avData) { + return; } + + int iMax = avData->waveform_points.size(); + + if (!iMax) { + avData->decRefCount(); + return; + } + + waveform_points.assign(avData->waveform_points.begin(),avData->waveform_points.end()); + setStereo(avData->channels == 2); + + avData->decRefCount(); } glContext->SetCurrent(*this); @@ -103,3 +96,7 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { void ScopeCanvas::OnIdle(wxIdleEvent &event) { Refresh(false); } + +ScopeRenderDataQueue *ScopeCanvas::getInputQueue() { + return &inputData; +} diff --git a/src/visual/ScopeCanvas.h b/src/visual/ScopeCanvas.h index cb24fee..23203b7 100644 --- a/src/visual/ScopeCanvas.h +++ b/src/visual/ScopeCanvas.h @@ -7,6 +7,7 @@ #include #include "ScopeContext.h" +#include "ScopeVisualProcessor.h" #include "fftw3.h" class ScopeCanvas: public wxGLCanvas { @@ -16,19 +17,18 @@ public: ScopeCanvas(wxWindow *parent, int *attribList = NULL); ~ScopeCanvas(); - void setWaveformPoints(std::vector &waveform_points_in); void setStereo(bool state); void setDeviceName(std::string device_name); void setPPMMode(bool ppmMode); bool getPPMMode(); + ScopeRenderDataQueue *getInputQueue(); + private: void OnPaint(wxPaintEvent& event); - void OnIdle(wxIdleEvent &event); - wxWindow *parent; - + ScopeRenderDataQueue inputData; ScopeContext *glContext; std::string deviceName; bool stereo; From 2cff389d6be3825c5adfc871a337e85e71a9fa15 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 3 Aug 2015 01:38:38 -0400 Subject: [PATCH 09/11] SpectrumVisualProcessor now working, cleanup, refactoring --- CMakeLists.txt | 2 - src/AppFrame.cpp | 33 +- src/CubicSDR.cpp | 27 ++ src/CubicSDR.h | 11 + src/demod/DemodulatorInstance.cpp | 4 +- src/process/SpectrumVisualProcessor.cpp | 358 +++++++++++++++---- src/process/SpectrumVisualProcessor.h | 53 ++- src/process/VisualProcessor.h | 16 +- src/process/WaterfallVisualProcessor.cpp | 275 --------------- src/process/WaterfallVisualProcessor.h | 13 - src/visual/SpectrumCanvas.cpp | 128 ++----- src/visual/SpectrumCanvas.h | 28 +- src/visual/WaterfallCanvas.cpp | 424 +++++------------------ src/visual/WaterfallCanvas.h | 32 +- 14 files changed, 539 insertions(+), 865 deletions(-) delete mode 100644 src/process/WaterfallVisualProcessor.cpp delete mode 100644 src/process/WaterfallVisualProcessor.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f2f72e9..209f2a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -262,7 +262,6 @@ SET (cubicsdr_sources src/process/VisualProcessor.cpp src/process/ScopeVisualProcessor.cpp src/process/SpectrumVisualProcessor.cpp - src/process/WaterfallVisualProcessor.cpp src/ui/GLPanel.cpp external/rtaudio/RtAudio.cpp external/lodepng/lodepng.cpp @@ -315,7 +314,6 @@ SET (cubicsdr_headers src/process/VisualProcessor.h src/process/ScopeVisualProcessor.h src/process/SpectrumVisualProcessor.h - src/process/WaterfallVisualProcessor.h src/ui/GLPanel.h src/ui/UITestCanvas.cpp src/ui/UITestCanvas.h diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index ea7910f..d758322 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -64,10 +64,11 @@ AppFrame::AppFrame() : // demodTray->AddSpacer(2); + wxGetApp().getDemodSpectrumProcesor()->setup(1024); demodSpectrumCanvas = new SpectrumCanvas(this, attribList); - demodSpectrumCanvas->setup(1024); demodSpectrumCanvas->setView(wxGetApp().getConfig()->getCenterFreq(), 300000); demodVisuals->Add(demodSpectrumCanvas, 3, wxEXPAND | wxALL, 0); + wxGetApp().getDemodSpectrumProcesor()->attachOutput(demodSpectrumCanvas->getVisualDataQueue()); demodVisuals->AddSpacer(1); @@ -77,6 +78,7 @@ AppFrame::AppFrame() : demodWaterfallCanvas->attachSpectrumCanvas(demodSpectrumCanvas); demodSpectrumCanvas->attachWaterfallCanvas(demodWaterfallCanvas); demodVisuals->Add(demodWaterfallCanvas, 6, wxEXPAND | wxALL, 0); + wxGetApp().getDemodSpectrumProcesor()->attachOutput(demodWaterfallCanvas->getVisualDataQueue()); demodTray->Add(demodVisuals, 30, wxEXPAND | wxALL, 0); @@ -110,17 +112,19 @@ AppFrame::AppFrame() : vbox->Add(demodTray, 12, wxEXPAND | wxALL, 0); vbox->AddSpacer(1); + + wxGetApp().getSpectrumProcesor()->setup(2048); spectrumCanvas = new SpectrumCanvas(this, attribList); - spectrumCanvas->setup(2048); vbox->Add(spectrumCanvas, 5, wxEXPAND | wxALL, 0); vbox->AddSpacer(1); + wxGetApp().getSpectrumProcesor()->attachOutput(spectrumCanvas->getVisualDataQueue()); + waterfallCanvas = new WaterfallCanvas(this, attribList); waterfallCanvas->setup(2048, 512); waterfallCanvas->attachSpectrumCanvas(spectrumCanvas); - waterfallCanvas->attachWaterfallCanvas(demodWaterfallCanvas); spectrumCanvas->attachWaterfallCanvas(waterfallCanvas); vbox->Add(waterfallCanvas, 20, wxEXPAND | wxALL, 0); - + wxGetApp().getSpectrumProcesor()->attachOutput(waterfallCanvas->getVisualDataQueue()); /* vbox->AddSpacer(1); testCanvas = new UITestCanvas(this, attribList); @@ -674,7 +678,26 @@ void AppFrame::OnIdle(wxIdleEvent& event) { } scopeCanvas->setPPMMode(demodTuner->isAltDown()); - + + + wxGetApp().getSpectrumDistributor()->run(); + + SpectrumVisualProcessor *proc = wxGetApp().getSpectrumProcesor(); + + proc->setView(waterfallCanvas->getViewState()); + proc->setBandwidth(waterfallCanvas->getBandwidth()); + proc->setCenterFrequency(waterfallCanvas->getCenterFrequency()); + + proc->run(); + + SpectrumVisualProcessor *dproc = wxGetApp().getDemodSpectrumProcesor(); + + dproc->setView(demodWaterfallCanvas->getViewState()); + dproc->setBandwidth(demodWaterfallCanvas->getBandwidth()); + dproc->setCenterFrequency(demodWaterfallCanvas->getCenterFrequency()); + + dproc->run(); + event.Skip(); } diff --git a/src/CubicSDR.cpp b/src/CubicSDR.cpp index f17cec3..3033b6e 100644 --- a/src/CubicSDR.cpp +++ b/src/CubicSDR.cpp @@ -54,6 +54,20 @@ bool CubicSDR::OnInit() { // Visual Data pipeIQVisualData = new DemodulatorThreadInputQueue(); pipeIQVisualData->set_max_num_items(1); + + spectrumDistributor.setInput(pipeIQVisualData); + + pipeDemodIQVisualData = new DemodulatorThreadInputQueue(); + pipeIQVisualData->set_max_num_items(1); + + pipeSpectrumIQVisualData = new DemodulatorThreadInputQueue(); + pipeIQVisualData->set_max_num_items(1); + + spectrumDistributor.attachOutput(pipeDemodIQVisualData); + spectrumDistributor.attachOutput(pipeSpectrumIQVisualData); + + demodSpectrumProcessor.setInput(pipeDemodIQVisualData); + spectrumProcessor.setInput(pipeSpectrumIQVisualData); pipeAudioVisualData = new DemodulatorThreadOutputQueue(); pipeAudioVisualData->set_max_num_items(1); @@ -254,6 +268,19 @@ ScopeVisualProcessor *CubicSDR::getScopeProcessor() { return &scopeProcessor; } +SpectrumVisualProcessor *CubicSDR::getSpectrumProcesor() { + return &spectrumProcessor; +} + +SpectrumVisualProcessor *CubicSDR::getDemodSpectrumProcesor() { + return &demodSpectrumProcessor; +} + +VisualDataDistributor *CubicSDR::getSpectrumDistributor() { + return &spectrumDistributor; +} + + DemodulatorThreadOutputQueue* CubicSDR::getAudioVisualQueue() { return pipeAudioVisualData; } diff --git a/src/CubicSDR.h b/src/CubicSDR.h index 6d4c4c8..c20d522 100644 --- a/src/CubicSDR.h +++ b/src/CubicSDR.h @@ -16,7 +16,9 @@ #include "DemodulatorMgr.h" #include "AppConfig.h" #include "AppFrame.h" + #include "ScopeVisualProcessor.h" +#include "SpectrumVisualProcessor.h" #include @@ -54,6 +56,9 @@ public: int getDevice(); ScopeVisualProcessor *getScopeProcessor(); + SpectrumVisualProcessor *getSpectrumProcesor(); + SpectrumVisualProcessor *getDemodSpectrumProcesor(); + VisualDataDistributor *getSpectrumDistributor(); DemodulatorThreadOutputQueue* getAudioVisualQueue(); DemodulatorThreadInputQueue* getIQVisualQueue(); @@ -94,8 +99,14 @@ private: SDRThreadIQDataQueue* pipeSDRIQData; DemodulatorThreadInputQueue* pipeIQVisualData; DemodulatorThreadOutputQueue* pipeAudioVisualData; + DemodulatorThreadInputQueue* pipeDemodIQVisualData; + DemodulatorThreadInputQueue* pipeSpectrumIQVisualData; ScopeVisualProcessor scopeProcessor; + SpectrumVisualProcessor spectrumProcessor; + SpectrumVisualProcessor demodSpectrumProcessor; + + VisualDataDistributor spectrumDistributor; std::thread *t_SDR; std::thread *t_PostSDR; diff --git a/src/demod/DemodulatorInstance.cpp b/src/demod/DemodulatorInstance.cpp index c92f5b5..d308327 100644 --- a/src/demod/DemodulatorInstance.cpp +++ b/src/demod/DemodulatorInstance.cpp @@ -1,7 +1,7 @@ #include "DemodulatorInstance.h" DemodulatorInstance::DemodulatorInstance() : - t_PreDemod(NULL), pipeIQInputData(NULL), demodulatorThread(NULL), t_Demod(NULL), t_Audio(NULL), currentAudioGain(1.0) { + t_PreDemod(NULL), t_Demod(NULL), t_Audio(NULL) { terminated.store(true); audioTerminated.store(true); @@ -16,7 +16,7 @@ DemodulatorInstance::DemodulatorInstance() : currentFrequency.store(0); currentBandwidth.store(0); currentOutputDevice.store(-1); - + currentAudioGain.store(1.0); label = new std::string("Unnamed"); pipeIQInputData = new DemodulatorThreadInputQueue; diff --git a/src/process/SpectrumVisualProcessor.cpp b/src/process/SpectrumVisualProcessor.cpp index dcd99b7..8defddc 100644 --- a/src/process/SpectrumVisualProcessor.cpp +++ b/src/process/SpectrumVisualProcessor.cpp @@ -1,80 +1,284 @@ #include "SpectrumVisualProcessor.h" +#include "CubicSDR.h" + + +SpectrumVisualProcessor::SpectrumVisualProcessor() : lastInputBandwidth(0), lastBandwidth(0), fftwInput(NULL), fftwOutput(NULL), fftInData(NULL), fftLastData(NULL), lastDataSize(0), fftw_plan(NULL), resampler(NULL), resamplerRatio(0) { + + is_view.store(false); + fftSize.store(0); + centerFreq.store(0); + bandwidth.store(0); + + freqShifter = nco_crcf_create(LIQUID_NCO); + shiftFrequency = 0; + + fft_ceil_ma = fft_ceil_maa = 100.0; + fft_floor_ma = fft_floor_maa = 0.0; +} + +SpectrumVisualProcessor::~SpectrumVisualProcessor() { + nco_crcf_destroy(freqShifter); +} + +bool SpectrumVisualProcessor::isView() { + return is_view.load(); +} + +void SpectrumVisualProcessor::setView(bool bView) { + is_view.store(bView); +} + + +void SpectrumVisualProcessor::setCenterFrequency(long long centerFreq_in) { + centerFreq.store(centerFreq_in); +} + +long long SpectrumVisualProcessor::getCenterFrequency() { + return centerFreq.load(); +} + +void SpectrumVisualProcessor::setBandwidth(long bandwidth_in) { + bandwidth.store(bandwidth_in); +} + +long SpectrumVisualProcessor::getBandwidth() { + return bandwidth.load(); +} + +void SpectrumVisualProcessor::setup(int fftSize_in) { + fftSize = fftSize_in; + + if (fftwInput) { + free(fftwInput); + } + fftwInput = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize); + if (fftInData) { + free(fftInData); + } + fftInData = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize); + if (fftLastData) { + free(fftLastData); + } + fftLastData = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize); + if (fftwOutput) { + free(fftwOutput); + } + fftwOutput = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fftSize); + if (fftw_plan) { + fftwf_destroy_plan(fftw_plan); + } + fftw_plan = fftwf_plan_dft_1d(fftSize, fftwInput, fftwOutput, FFTW_FORWARD, FFTW_ESTIMATE); + +} void SpectrumVisualProcessor::process() { - /* - std::vector *data = &input->data; - if (data && data->size()) { - if (fft_size != data->size()) { - setup(data->size()); - } - if (spectrum_points.size() < fft_size * 2) { - if (spectrum_points.capacity() < fft_size * 2) { - spectrum_points.reserve(fft_size * 2); - } - spectrum_points.resize(fft_size * 2); - } - - for (int i = 0; i < fft_size; i++) { - in[i][0] = (*data)[i].real; - in[i][1] = (*data)[i].imag; - } - - fftwf_execute(plan); - - float fft_ceil = 0, fft_floor = 1; - - if (fft_result.size() != fft_size) { - if (fft_result.capacity() < fft_size) { - fft_result.reserve(fft_size); - fft_result_ma.reserve(fft_size); - fft_result_maa.reserve(fft_size); - } - fft_result.resize(fft_size); - fft_result_ma.resize(fft_size); - fft_result_maa.resize(fft_size); - } - - int n; - for (int i = 0, iMax = fft_size / 2; i < iMax; i++) { - float a = out[i][0]; - float b = out[i][1]; - float c = sqrt(a * a + b * b); - - float x = out[fft_size / 2 + i][0]; - float y = out[fft_size / 2 + i][1]; - float z = sqrt(x * x + y * y); - - fft_result[i] = (z); - fft_result[fft_size / 2 + i] = (c); - } - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - - if (fft_result_maa[i] > fft_ceil) { - fft_ceil = fft_result_maa[i]; - } - if (fft_result_maa[i] < fft_floor) { - fft_floor = fft_result_maa[i]; - } - } - - fft_ceil += 1; - fft_floor -= 1; - - fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.01; - fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.01; - - fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.01; - fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.01; - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); - spectrum_points[i * 2] = ((float) i / (float) iMax); - spectrum_points[i * 2 + 1] = v; - } - - } - */ -} \ No newline at end of file + if (!isOutputEmpty()) { + return; + } + if (!input || input->empty()) { + return; + } + + DemodulatorThreadIQData *iqData; + + input->pop(iqData); + + std::vector *data = &iqData->data; + + if (data && data->size()) { + SpectrumVisualData *output = outputBuffers.getBuffer(); + + if (output->spectrum_points.size() < fftSize * 2) { + output->spectrum_points.resize(fftSize * 2); + } + + unsigned int num_written; + + if (is_view.load()) { + if (!iqData->frequency || !iqData->sampleRate) { + return; + } + + resamplerRatio = (double) (bandwidth) / (double) iqData->sampleRate; + + int desired_input_size = fftSize / resamplerRatio; + + if (iqData->data.size() < desired_input_size) { + // std::cout << "fft underflow, desired: " << desired_input_size << " actual:" << input->data.size() << std::endl; + desired_input_size = iqData->data.size(); + } + + if (centerFreq != iqData->frequency) { + if ((centerFreq - iqData->frequency) != shiftFrequency || lastInputBandwidth != iqData->sampleRate) { + if (abs(iqData->frequency - centerFreq) < (wxGetApp().getSampleRate() / 2)) { + shiftFrequency = centerFreq - iqData->frequency; + nco_crcf_reset(freqShifter); + nco_crcf_set_frequency(freqShifter, (2.0 * M_PI) * (((double) abs(shiftFrequency)) / ((double) iqData->sampleRate))); + } + } + + if (shiftBuffer.size() != desired_input_size) { + if (shiftBuffer.capacity() < desired_input_size) { + shiftBuffer.reserve(desired_input_size); + } + shiftBuffer.resize(desired_input_size); + } + + if (shiftFrequency < 0) { + nco_crcf_mix_block_up(freqShifter, &iqData->data[0], &shiftBuffer[0], desired_input_size); + } else { + nco_crcf_mix_block_down(freqShifter, &iqData->data[0], &shiftBuffer[0], desired_input_size); + } + } else { + shiftBuffer.assign(iqData->data.begin(), iqData->data.end()); + } + + if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != iqData->sampleRate) { + float As = 60.0f; + + if (resampler) { + msresamp_crcf_destroy(resampler); + } + resampler = msresamp_crcf_create(resamplerRatio, As); + + lastBandwidth = bandwidth; + lastInputBandwidth = iqData->sampleRate; + } + + + int out_size = ceil((double) (desired_input_size) * resamplerRatio) + 512; + + if (resampleBuffer.size() != out_size) { + if (resampleBuffer.capacity() < out_size) { + resampleBuffer.reserve(out_size); + } + resampleBuffer.resize(out_size); + } + + + msresamp_crcf_execute(resampler, &shiftBuffer[0], desired_input_size, &resampleBuffer[0], &num_written); + + resampleBuffer.resize(fftSize); + + if (num_written < fftSize) { + for (int i = 0; i < num_written; i++) { + fftInData[i][0] = resampleBuffer[i].real; + fftInData[i][1] = resampleBuffer[i].imag; + } + for (int i = num_written; i < fftSize; i++) { + fftInData[i][0] = 0; + fftInData[i][1] = 0; + } + } else { + for (int i = 0; i < fftSize; i++) { + fftInData[i][0] = resampleBuffer[i].real; + fftInData[i][1] = resampleBuffer[i].imag; + } + } + } else { + num_written = data->size(); + if (data->size() < fftSize) { + for (int i = 0, iMax = data->size(); i < iMax; i++) { + fftInData[i][0] = (*data)[i].real; + fftInData[i][1] = (*data)[i].imag; + } + for (int i = data->size(); i < fftSize; i++) { + fftInData[i][0] = 0; + fftInData[i][1] = 0; + } + } else { + for (int i = 0; i < fftSize; i++) { + fftInData[i][0] = (*data)[i].real; + fftInData[i][1] = (*data)[i].imag; + } + } + } + + bool execute = false; + + if (num_written >= fftSize) { + execute = true; + memcpy(fftwInput, fftInData, fftSize * sizeof(fftwf_complex)); + memcpy(fftLastData, fftwInput, fftSize * sizeof(fftwf_complex)); + + } else { + if (lastDataSize + num_written < fftSize) { // priming + unsigned int num_copy = fftSize - lastDataSize; + if (num_written > num_copy) { + num_copy = num_written; + } + memcpy(fftLastData, fftInData, num_copy * sizeof(fftwf_complex)); + lastDataSize += num_copy; + } else { + unsigned int num_last = (fftSize - num_written); + memcpy(fftwInput, fftLastData + (lastDataSize - num_last), num_last * sizeof(fftwf_complex)); + memcpy(fftwInput + num_last, fftInData, num_written * sizeof(fftwf_complex)); + memcpy(fftLastData, fftwInput, fftSize * sizeof(fftwf_complex)); + execute = true; + } + } + + if (execute) { + fftwf_execute(fftw_plan); + + float fft_ceil = 0, fft_floor = 1; + + if (fft_result.size() < fftSize) { + fft_result.resize(fftSize); + fft_result_ma.resize(fftSize); + fft_result_maa.resize(fftSize); + } + + for (int i = 0, iMax = fftSize / 2; i < iMax; i++) { + float a = fftwOutput[i][0]; + float b = fftwOutput[i][1]; + float c = sqrt(a * a + b * b); + + float x = fftwOutput[fftSize / 2 + i][0]; + float y = fftwOutput[fftSize / 2 + i][1]; + float z = sqrt(x * x + y * y); + + fft_result[i] = (z); + fft_result[fftSize / 2 + i] = (c); + } + + for (int i = 0, iMax = fftSize; i < iMax; i++) { + if (is_view.load()) { + fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; + fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; + } else { + fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; + fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; + } + + if (fft_result_maa[i] > fft_ceil) { + fft_ceil = fft_result_maa[i]; + } + if (fft_result_maa[i] < fft_floor) { + fft_floor = fft_result_maa[i]; + } + } + + fft_ceil += 0.25; + fft_floor -= 1; + + fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05; + fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.05; + + fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.05; + fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05; + + for (int i = 0, iMax = fftSize; i < iMax; i++) { + float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); + output->spectrum_points[i * 2] = ((float) i / (float) iMax); + output->spectrum_points[i * 2 + 1] = v; + } + + output->fft_ceiling = fft_ceil_maa; + output->fft_floor = fft_floor_maa; + } + + distribute(output); + } + +} diff --git a/src/process/SpectrumVisualProcessor.h b/src/process/SpectrumVisualProcessor.h index 3fcc0ff..6ffe848 100644 --- a/src/process/SpectrumVisualProcessor.h +++ b/src/process/SpectrumVisualProcessor.h @@ -1,13 +1,62 @@ #pragma once #include "VisualProcessor.h" -#include "SpectrumCanvas.h" +#include "DemodDefs.h" +#include "fftw3.h" class SpectrumVisualData : public ReferenceCounter { - +public: + std::vector spectrum_points; + double fft_ceiling, fft_floor; }; +typedef ThreadQueue SpectrumVisualDataQueue; + class SpectrumVisualProcessor : public VisualProcessor { +public: + SpectrumVisualProcessor(); + ~SpectrumVisualProcessor(); + + bool isView(); + void setView(bool bView); + + void setCenterFrequency(long long centerFreq_in); + long long getCenterFrequency(); + + void setBandwidth(long bandwidth_in); + long getBandwidth(); + + void setup(int fftSize); + protected: void process(); + + ReBuffer outputBuffers; + std::atomic_bool is_view; + std::atomic_int fftSize; + std::atomic_llong centerFreq; + std::atomic_long bandwidth; + +private: + long lastInputBandwidth; + long lastBandwidth; + + fftwf_complex *fftwInput, *fftwOutput, *fftInData, *fftLastData; + unsigned int lastDataSize; + fftwf_plan fftw_plan; + + float fft_ceil_ma, fft_ceil_maa; + float fft_floor_ma, fft_floor_maa; + + std::vector fft_result; + std::vector fft_result_ma; + std::vector fft_result_maa; + + msresamp_crcf resampler; + double resamplerRatio; + nco_crcf freqShifter; + long shiftFrequency; + + std::vector shiftBuffer; + std::vector resampleBuffer; }; diff --git a/src/process/VisualProcessor.h b/src/process/VisualProcessor.h index 4f8c898..1f02bbe 100644 --- a/src/process/VisualProcessor.h +++ b/src/process/VisualProcessor.h @@ -86,16 +86,18 @@ protected: }; -template -class VisualDataDistributor : public VisualProcessor { +template +class VisualDataDistributor : public VisualProcessor { protected: void process() { - - while (!VisualProcessor::input->empty()) { - ReferenceCounter *inp; - VisualProcessor::input->pop(inp); + if (!VisualProcessor::isOutputEmpty()) { + return; + } + while (!VisualProcessor::input->empty()) { + OutputDataType *inp; + VisualProcessor::input->pop(inp); if (inp) { - VisualProcessor::distribute(inp); + VisualProcessor::distribute(inp); } } } diff --git a/src/process/WaterfallVisualProcessor.cpp b/src/process/WaterfallVisualProcessor.cpp deleted file mode 100644 index 153e489..0000000 --- a/src/process/WaterfallVisualProcessor.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include "WaterfallVisualProcessor.h" - -void WaterfallVisualProcessor::process() { - /* - long double currentZoom = zoom; - - if (mouseZoom != 1) { - currentZoom = mouseZoom; - mouseZoom = mouseZoom + (1.0 - mouseZoom) * 0.2; - if (fabs(mouseZoom-1.0)<0.01) { - mouseZoom = 1; - } - } - - long long bw; - if (currentZoom != 1) { - long long freq = wxGetApp().getFrequency(); - - if (currentZoom < 1) { - centerFreq = getCenterFrequency(); - bw = getBandwidth(); - bw = (long long) ceil((long double) bw * currentZoom); - if (bw < 100000) { - bw = 100000; - } - if (mouseTracker.mouseInView()) { - long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); - setBandwidth(bw); - long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); - centerFreq += mfreqA - mfreqB; - } - - setView(centerFreq, bw); - if (spectrumCanvas) { - spectrumCanvas->setView(centerFreq, bw); - } - } else { - if (isView) { - bw = getBandwidth(); - bw = (long long) ceil((long double) bw * currentZoom); - if (bw >= wxGetApp().getSampleRate()) { - disableView(); - if (spectrumCanvas) { - spectrumCanvas->disableView(); - } - } else { - if (mouseTracker.mouseInView()) { - long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); - setBandwidth(bw); - long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); - centerFreq += mfreqA - mfreqB; - } - - setView(getCenterFrequency(), bw); - if (spectrumCanvas) { - spectrumCanvas->setView(centerFreq, bw); - } - } - } - } - if (centerFreq < freq && (centerFreq - bandwidth / 2) < (freq - wxGetApp().getSampleRate() / 2)) { - centerFreq = (freq - wxGetApp().getSampleRate() / 2) + bandwidth / 2; - } - if (centerFreq > freq && (centerFreq + bandwidth / 2) > (freq + wxGetApp().getSampleRate() / 2)) { - centerFreq = (freq + wxGetApp().getSampleRate() / 2) - bandwidth / 2; - } - } - - std::vector *data = &input->data; - - if (data && data->size()) { - // if (fft_size != data->size() && !isView) { - // Setup(data->size(), waterfall_lines); - // } - - // if (last_bandwidth != bandwidth && !isView) { - // Setup(bandwidth, waterfall_lines); - // } - - if (spectrum_points.size() < fft_size * 2) { - spectrum_points.resize(fft_size * 2); - } - - unsigned int num_written; - - if (isView) { - if (!input->frequency || !input->sampleRate) { - return; - } - - resamplerRatio = (double) (bandwidth) / (double) input->sampleRate; - - int desired_input_size = fft_size / resamplerRatio; - - if (input->data.size() < desired_input_size) { - // std::cout << "fft underflow, desired: " << desired_input_size << " actual:" << input->data.size() << std::endl; - desired_input_size = input->data.size(); - } - - if (centerFreq != input->frequency) { - 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->sampleRate))); - } - } - - if (shiftBuffer.size() != desired_input_size) { - if (shiftBuffer.capacity() < desired_input_size) { - shiftBuffer.reserve(desired_input_size); - } - shiftBuffer.resize(desired_input_size); - } - - if (shiftFrequency < 0) { - nco_crcf_mix_block_up(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size); - } else { - nco_crcf_mix_block_down(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size); - } - } else { - shiftBuffer.assign(input->data.begin(), input->data.end()); - } - - if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != input->sampleRate) { - float As = 60.0f; - - if (resampler) { - msresamp_crcf_destroy(resampler); - } - resampler = msresamp_crcf_create(resamplerRatio, As); - - lastBandwidth = bandwidth; - lastInputBandwidth = input->sampleRate; - } - - - int out_size = ceil((double) (desired_input_size) * resamplerRatio) + 512; - - if (resampleBuffer.size() != out_size) { - if (resampleBuffer.capacity() < out_size) { - resampleBuffer.reserve(out_size); - } - resampleBuffer.resize(out_size); - } - - - msresamp_crcf_execute(resampler, &shiftBuffer[0], desired_input_size, &resampleBuffer[0], &num_written); - - resampleBuffer.resize(fft_size); - - if (num_written < fft_size) { - for (int i = 0; i < num_written; i++) { - fft_in_data[i][0] = resampleBuffer[i].real; - fft_in_data[i][1] = resampleBuffer[i].imag; - } - for (int i = num_written; i < fft_size; i++) { - fft_in_data[i][0] = 0; - fft_in_data[i][1] = 0; - } - } else { - for (int i = 0; i < fft_size; i++) { - fft_in_data[i][0] = resampleBuffer[i].real; - fft_in_data[i][1] = resampleBuffer[i].imag; - } - } - } else { - num_written = data->size(); - if (data->size() < fft_size) { - for (int i = 0, iMax = data->size(); i < iMax; i++) { - fft_in_data[i][0] = (*data)[i].real; - fft_in_data[i][1] = (*data)[i].imag; - } - for (int i = data->size(); i < fft_size; i++) { - fft_in_data[i][0] = 0; - fft_in_data[i][1] = 0; - } - } else { - for (int i = 0; i < fft_size; i++) { - fft_in_data[i][0] = (*data)[i].real; - fft_in_data[i][1] = (*data)[i].imag; - } - } - } - - bool execute = false; - - if (num_written >= fft_size) { - execute = true; - memcpy(in, fft_in_data, fft_size * sizeof(fftwf_complex)); - memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex)); - - } else { - if (last_data_size + num_written < fft_size) { // priming - unsigned int num_copy = fft_size - last_data_size; - if (num_written > num_copy) { - num_copy = num_written; - } - memcpy(fft_last_data, fft_in_data, num_copy * sizeof(fftwf_complex)); - last_data_size += num_copy; - } else { - unsigned int num_last = (fft_size - num_written); - memcpy(in, fft_last_data + (last_data_size - num_last), num_last * sizeof(fftwf_complex)); - memcpy(in + num_last, fft_in_data, num_written * sizeof(fftwf_complex)); - memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex)); - execute = true; - } - } - - if (execute) { - fftwf_execute(plan); - - float fft_ceil = 0, fft_floor = 1; - - if (fft_result.size() < fft_size) { - fft_result.resize(fft_size); - fft_result_ma.resize(fft_size); - fft_result_maa.resize(fft_size); - } - - int n; - for (int i = 0, iMax = fft_size / 2; i < iMax; i++) { - float a = out[i][0]; - float b = out[i][1]; - float c = sqrt(a * a + b * b); - - float x = out[fft_size / 2 + i][0]; - float y = out[fft_size / 2 + i][1]; - float z = sqrt(x * x + y * y); - - fft_result[i] = (z); - fft_result[fft_size / 2 + i] = (c); - } - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - if (isView) { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - } else { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - } - - if (fft_result_maa[i] > fft_ceil) { - fft_ceil = fft_result_maa[i]; - } - if (fft_result_maa[i] < fft_floor) { - fft_floor = fft_result_maa[i]; - } - } - - fft_ceil += 0.25; - fft_floor -= 1; - - fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05; - fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.05; - - fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.05; - fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05; - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); - spectrum_points[i * 2] = ((float) i / (float) iMax); - spectrum_points[i * 2 + 1] = v; - } - - if (spectrumCanvas) { - spectrumCanvas->spectrum_points.assign(spectrum_points.begin(), spectrum_points.end()); - spectrumCanvas->getSpectrumContext()->setCeilValue(fft_ceil_maa); - spectrumCanvas->getSpectrumContext()->setFloorValue(fft_floor_maa); - } - } - } - */ -} \ No newline at end of file diff --git a/src/process/WaterfallVisualProcessor.h b/src/process/WaterfallVisualProcessor.h deleted file mode 100644 index 5c2aa62..0000000 --- a/src/process/WaterfallVisualProcessor.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "VisualProcessor.h" -#include "WaterfallCanvas.h" - -class WaterfallVisualData : public ReferenceCounter { - -}; - -class WaterfallVisualProcessor : public VisualProcessor { -protected: - void process(); -}; diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index 776b89a..65a52b2 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -27,8 +27,7 @@ EVT_MOUSEWHEEL(SpectrumCanvas::OnMouseWheelMoved) wxEND_EVENT_TABLE() SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) : - InteractiveCanvas(parent, attribList), fft_size(0), in(NULL), out(NULL), plan(NULL), fft_ceil_ma(1), fft_ceil_maa(1), fft_floor_ma(0), fft_floor_maa( - 0), waterfallCanvas(NULL), trackingRate(0) { + InteractiveCanvas(parent, attribList), fft_size(0), waterfallCanvas(NULL), trackingRate(0) { glContext = new SpectrumContext(this, &wxGetApp().GetContext(this)); @@ -37,30 +36,6 @@ SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) : SetCursor(wxCURSOR_SIZEWE); } -void SpectrumCanvas::setup(int fft_size_in) { - if (fft_size == fft_size_in) { - return; - } - - fft_size = fft_size_in; - - if (in) { - free(in); - } - in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size); - if (out) { - free(out); - } - out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size); - if (plan) { - fftwf_destroy_plan(plan); - } - plan = fftwf_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_MEASURE); - - fft_ceil_ma = fft_ceil_maa = 100.0; - fft_floor_ma = fft_floor_maa = 0.0; -} - SpectrumCanvas::~SpectrumCanvas() { } @@ -71,7 +46,23 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { glFinish(); #endif const wxSize ClientSize = GetClientSize(); - + + if (visualDataQueue.empty()) { + return; + } + + SpectrumVisualData *vData; + + visualDataQueue.pop(vData); + + if (!vData) { + return; + } + + spectrum_points.assign(vData->spectrum_points.begin(),vData->spectrum_points.end()); + + vData->decRefCount(); + glContext->SetCurrent(*this); initGLExtensions(); @@ -91,85 +82,6 @@ void SpectrumCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { SwapBuffers(); } -void SpectrumCanvas::setData(DemodulatorThreadIQData *input) { - if (!input) { - return; - } - std::vector *data = &input->data; - if (data && data->size()) { - if (fft_size != data->size()) { - setup(data->size()); - } - if (spectrum_points.size() < fft_size * 2) { - if (spectrum_points.capacity() < fft_size * 2) { - spectrum_points.reserve(fft_size * 2); - } - spectrum_points.resize(fft_size * 2); - } - - for (int i = 0; i < fft_size; i++) { - in[i][0] = (*data)[i].real; - in[i][1] = (*data)[i].imag; - } - - fftwf_execute(plan); - - float fft_ceil = 0, fft_floor = 1; - - if (fft_result.size() != fft_size) { - if (fft_result.capacity() < fft_size) { - fft_result.reserve(fft_size); - fft_result_ma.reserve(fft_size); - fft_result_maa.reserve(fft_size); - } - fft_result.resize(fft_size); - fft_result_ma.resize(fft_size); - fft_result_maa.resize(fft_size); - } - - int n; - for (int i = 0, iMax = fft_size / 2; i < iMax; i++) { - float a = out[i][0]; - float b = out[i][1]; - float c = sqrt(a * a + b * b); - - float x = out[fft_size / 2 + i][0]; - float y = out[fft_size / 2 + i][1]; - float z = sqrt(x * x + y * y); - - fft_result[i] = (z); - fft_result[fft_size / 2 + i] = (c); - } - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - - if (fft_result_maa[i] > fft_ceil) { - fft_ceil = fft_result_maa[i]; - } - if (fft_result_maa[i] < fft_floor) { - fft_floor = fft_result_maa[i]; - } - } - - fft_ceil += 1; - fft_floor -= 1; - - fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.01; - fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.01; - - fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.01; - fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.01; - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); - spectrum_points[i * 2] = ((float) i / (float) iMax); - spectrum_points[i * 2 + 1] = v; - } - - } -} void SpectrumCanvas::OnIdle(wxIdleEvent &event) { Refresh(false); @@ -250,3 +162,7 @@ void SpectrumCanvas::attachWaterfallCanvas(WaterfallCanvas* canvas_in) { SpectrumContext* SpectrumCanvas::getSpectrumContext() { return glContext; } + +SpectrumVisualDataQueue *SpectrumCanvas::getVisualDataQueue() { + return &visualDataQueue; +} \ No newline at end of file diff --git a/src/visual/SpectrumCanvas.h b/src/visual/SpectrumCanvas.h index f1469a2..636296d 100644 --- a/src/visual/SpectrumCanvas.h +++ b/src/visual/SpectrumCanvas.h @@ -11,6 +11,7 @@ #include "fftw3.h" #include "MouseTracker.h" +#include "SpectrumVisualProcessor.h" class WaterfallCanvas; @@ -19,15 +20,15 @@ public: std::vector spectrum_points; SpectrumCanvas(wxWindow *parent, int *attribList = NULL); - void setup(int fft_size_in); +// void setup(int fft_size_in); ~SpectrumCanvas(); - void setData(DemodulatorThreadIQData *input); void attachWaterfallCanvas(WaterfallCanvas *canvas_in); void moveCenterFrequency(long long freqChange); SpectrumContext* getSpectrumContext(); - + SpectrumVisualDataQueue *getVisualDataQueue(); + private: void OnPaint(wxPaintEvent& event); @@ -39,20 +40,23 @@ private: void OnMouseReleased(wxMouseEvent& event); void OnMouseLeftWindow(wxMouseEvent& event); - fftwf_complex *in, *out; - fftwf_plan plan; - - float fft_ceil_ma, fft_ceil_maa; - float fft_floor_ma, fft_floor_maa; - - std::vector fft_result; - std::vector fft_result_ma; - std::vector fft_result_maa; +// fftwf_complex *in, *out; +// fftwf_plan plan; +// +// float fft_ceil_ma, fft_ceil_maa; +// float fft_floor_ma, fft_floor_maa; +// +// std::vector fft_result; +// std::vector fft_result_ma; +// std::vector fft_result_maa; SpectrumContext *glContext; WaterfallCanvas *waterfallCanvas; int fft_size; int trackingRate; + + SpectrumVisualDataQueue visualDataQueue; + // event table wxDECLARE_EVENT_TABLE(); }; diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index abbcf0e..c928d89 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -35,23 +35,15 @@ EVT_MOUSEWHEEL(WaterfallCanvas::OnMouseWheelMoved) wxEND_EVENT_TABLE() WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : - InteractiveCanvas(parent, attribList), spectrumCanvas(NULL), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), fft_size(0), waterfall_lines( - 0), plan( - NULL), in(NULL), out(NULL), resampler(NULL), resamplerRatio(0), lastInputBandwidth(0), zoom(1), mouseZoom(1), otherWaterfallCanvas(NULL), polling(true), last_data_size(0), fft_in_data(NULL), fft_last_data(NULL), hoverAlpha(1.0), dragOfs(0) { + InteractiveCanvas(parent, attribList), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), fft_size(0), waterfall_lines( + 0), zoom(1), mouseZoom(1), hoverAlpha(1.0), dragOfs(0) { glContext = new WaterfallContext(this, &wxGetApp().GetContext(this)); - freqShifter = nco_crcf_create(LIQUID_NCO); - shiftFrequency = 0; - - fft_ceil_ma = fft_ceil_maa = 100.0; - fft_floor_ma = fft_floor_maa = 0.0; - SetCursor(wxCURSOR_CROSS); } WaterfallCanvas::~WaterfallCanvas() { - nco_crcf_destroy(freqShifter); } void WaterfallCanvas::setup(int fft_size_in, int waterfall_lines_in) { @@ -61,27 +53,6 @@ void WaterfallCanvas::setup(int fft_size_in, int waterfall_lines_in) { fft_size = fft_size_in; waterfall_lines = waterfall_lines_in; - if (in) { - free(in); - } - in = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size); - if (fft_in_data) { - free(fft_in_data); - } - fft_in_data = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size); - if (fft_last_data) { - free(fft_last_data); - } - fft_last_data = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size); - if (out) { - free(out); - } - out = (fftwf_complex*) fftwf_malloc(sizeof(fftwf_complex) * fft_size); - if (plan) { - fftwf_destroy_plan(plan); - } - plan = fftwf_plan_dft_1d(fft_size, in, out, FFTW_FORWARD, FFTW_ESTIMATE); - glContext->Setup(fft_size, waterfall_lines); } @@ -104,29 +75,89 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { #endif const wxSize ClientSize = GetClientSize(); - - - if (polling && !wxGetApp().getIQVisualQueue()->empty()) { - DemodulatorThreadIQData *iqData; - wxGetApp().getIQVisualQueue()->pop(iqData); - - iqData->busy_rw.lock(); - - if (iqData && iqData->data.size()) { - setData(iqData); - if (otherWaterfallCanvas) { - otherWaterfallCanvas->setData(iqData); + long double currentZoom = zoom; + + if (mouseZoom != 1) { + currentZoom = mouseZoom; + mouseZoom = mouseZoom + (1.0 - mouseZoom) * 0.2; + if (fabs(mouseZoom-1.0)<0.01) { + mouseZoom = 1; + } + } + + long long bw; + if (currentZoom != 1) { + long long freq = wxGetApp().getFrequency(); + + if (currentZoom < 1) { + centerFreq = getCenterFrequency(); + bw = getBandwidth(); + bw = (long long) ceil((long double) bw * currentZoom); + if (bw < 100000) { + bw = 100000; + } + if (mouseTracker.mouseInView()) { + long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); + setBandwidth(bw); + long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); + centerFreq += mfreqA - mfreqB; + } + + setView(centerFreq, bw); + if (spectrumCanvas) { + spectrumCanvas->setView(centerFreq, bw); } } else { - std::cout << "Incoming IQ data empty?" << std::endl; + if (isView) { + bw = getBandwidth(); + bw = (long long) ceil((long double) bw * currentZoom); + if (bw >= wxGetApp().getSampleRate()) { + disableView(); + if (spectrumCanvas) { + spectrumCanvas->disableView(); + } + } else { + if (mouseTracker.mouseInView()) { + long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); + setBandwidth(bw); + long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); + centerFreq += mfreqA - mfreqB; + } + + setView(getCenterFrequency(), bw); + if (spectrumCanvas) { + spectrumCanvas->setView(centerFreq, bw); + } + } + } + } + if (centerFreq < freq && (centerFreq - bandwidth / 2) < (freq - wxGetApp().getSampleRate() / 2)) { + centerFreq = (freq - wxGetApp().getSampleRate() / 2) + bandwidth / 2; + } + if (centerFreq > freq && (centerFreq + bandwidth / 2) > (freq + wxGetApp().getSampleRate() / 2)) { + centerFreq = (freq + wxGetApp().getSampleRate() / 2) - bandwidth / 2; } - - iqData->busy_rw.unlock(); } + if (visualDataQueue.empty()) { + return; + } + + SpectrumVisualData *vData; + + visualDataQueue.pop(vData); + + if (!vData) { + return; + } + + spectrum_points.assign(vData->spectrum_points.begin(),vData->spectrum_points.end()); + + vData->decRefCount(); + glContext->SetCurrent(*this); initGLExtensions(); - glViewport(0, 0, ClientSize.x, ClientSize.y); + glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->BeginDraw(0,0,0); glContext->Draw(spectrum_points); @@ -323,283 +354,6 @@ void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { return; } } - -void WaterfallCanvas::setData(DemodulatorThreadIQData *input) { - if (!input) { - return; - } - - long double currentZoom = zoom; - - if (mouseZoom != 1) { - currentZoom = mouseZoom; - mouseZoom = mouseZoom + (1.0 - mouseZoom) * 0.2; - if (fabs(mouseZoom-1.0)<0.01) { - mouseZoom = 1; - } - } - - long long bw; - if (currentZoom != 1) { - long long freq = wxGetApp().getFrequency(); - - if (currentZoom < 1) { - centerFreq = getCenterFrequency(); - bw = getBandwidth(); - bw = (long long) ceil((long double) bw * currentZoom); - if (bw < 100000) { - bw = 100000; - } - if (mouseTracker.mouseInView()) { - long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); - setBandwidth(bw); - long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); - centerFreq += mfreqA - mfreqB; - } - - setView(centerFreq, bw); - if (spectrumCanvas) { - spectrumCanvas->setView(centerFreq, bw); - } - } else { - if (isView) { - bw = getBandwidth(); - bw = (long long) ceil((long double) bw * currentZoom); - if (bw >= wxGetApp().getSampleRate()) { - disableView(); - if (spectrumCanvas) { - spectrumCanvas->disableView(); - } - } else { - if (mouseTracker.mouseInView()) { - long long mfreqA = getFrequencyAt(mouseTracker.getMouseX()); - setBandwidth(bw); - long long mfreqB = getFrequencyAt(mouseTracker.getMouseX()); - centerFreq += mfreqA - mfreqB; - } - - setView(getCenterFrequency(), bw); - if (spectrumCanvas) { - spectrumCanvas->setView(centerFreq, bw); - } - } - } - } - if (centerFreq < freq && (centerFreq - bandwidth / 2) < (freq - wxGetApp().getSampleRate() / 2)) { - centerFreq = (freq - wxGetApp().getSampleRate() / 2) + bandwidth / 2; - } - if (centerFreq > freq && (centerFreq + bandwidth / 2) > (freq + wxGetApp().getSampleRate() / 2)) { - centerFreq = (freq + wxGetApp().getSampleRate() / 2) - bandwidth / 2; - } - } - - std::vector *data = &input->data; - - if (data && data->size()) { -// if (fft_size != data->size() && !isView) { -// Setup(data->size(), waterfall_lines); -// } - -// if (last_bandwidth != bandwidth && !isView) { -// Setup(bandwidth, waterfall_lines); -// } - - if (spectrum_points.size() < fft_size * 2) { - spectrum_points.resize(fft_size * 2); - } - - unsigned int num_written; - - if (isView) { - if (!input->frequency || !input->sampleRate) { - return; - } - - resamplerRatio = (double) (bandwidth) / (double) input->sampleRate; - - int desired_input_size = fft_size / resamplerRatio; - - if (input->data.size() < desired_input_size) { -// std::cout << "fft underflow, desired: " << desired_input_size << " actual:" << input->data.size() << std::endl; - desired_input_size = input->data.size(); - } - - if (centerFreq != input->frequency) { - 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->sampleRate))); - } - } - - if (shiftBuffer.size() != desired_input_size) { - if (shiftBuffer.capacity() < desired_input_size) { - shiftBuffer.reserve(desired_input_size); - } - shiftBuffer.resize(desired_input_size); - } - - if (shiftFrequency < 0) { - nco_crcf_mix_block_up(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size); - } else { - nco_crcf_mix_block_down(freqShifter, &input->data[0], &shiftBuffer[0], desired_input_size); - } - } else { - shiftBuffer.assign(input->data.begin(), input->data.end()); - } - - if (!resampler || bandwidth != lastBandwidth || lastInputBandwidth != input->sampleRate) { - float As = 60.0f; - - if (resampler) { - msresamp_crcf_destroy(resampler); - } - resampler = msresamp_crcf_create(resamplerRatio, As); - - lastBandwidth = bandwidth; - lastInputBandwidth = input->sampleRate; - } - - - int out_size = ceil((double) (desired_input_size) * resamplerRatio) + 512; - - if (resampleBuffer.size() != out_size) { - if (resampleBuffer.capacity() < out_size) { - resampleBuffer.reserve(out_size); - } - resampleBuffer.resize(out_size); - } - - - msresamp_crcf_execute(resampler, &shiftBuffer[0], desired_input_size, &resampleBuffer[0], &num_written); - - resampleBuffer.resize(fft_size); - - if (num_written < fft_size) { - for (int i = 0; i < num_written; i++) { - fft_in_data[i][0] = resampleBuffer[i].real; - fft_in_data[i][1] = resampleBuffer[i].imag; - } - for (int i = num_written; i < fft_size; i++) { - fft_in_data[i][0] = 0; - fft_in_data[i][1] = 0; - } - } else { - for (int i = 0; i < fft_size; i++) { - fft_in_data[i][0] = resampleBuffer[i].real; - fft_in_data[i][1] = resampleBuffer[i].imag; - } - } - } else { - num_written = data->size(); - if (data->size() < fft_size) { - for (int i = 0, iMax = data->size(); i < iMax; i++) { - fft_in_data[i][0] = (*data)[i].real; - fft_in_data[i][1] = (*data)[i].imag; - } - for (int i = data->size(); i < fft_size; i++) { - fft_in_data[i][0] = 0; - fft_in_data[i][1] = 0; - } - } else { - for (int i = 0; i < fft_size; i++) { - fft_in_data[i][0] = (*data)[i].real; - fft_in_data[i][1] = (*data)[i].imag; - } - } - } - - bool execute = false; - - if (num_written >= fft_size) { - execute = true; - memcpy(in, fft_in_data, fft_size * sizeof(fftwf_complex)); - memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex)); - - } else { - if (last_data_size + num_written < fft_size) { // priming - unsigned int num_copy = fft_size - last_data_size; - if (num_written > num_copy) { - num_copy = num_written; - } - memcpy(fft_last_data, fft_in_data, num_copy * sizeof(fftwf_complex)); - last_data_size += num_copy; - } else { - unsigned int num_last = (fft_size - num_written); - memcpy(in, fft_last_data + (last_data_size - num_last), num_last * sizeof(fftwf_complex)); - memcpy(in + num_last, fft_in_data, num_written * sizeof(fftwf_complex)); - memcpy(fft_last_data, in, fft_size * sizeof(fftwf_complex)); - execute = true; - } - } - - if (execute) { - fftwf_execute(plan); - - float fft_ceil = 0, fft_floor = 1; - - if (fft_result.size() < fft_size) { - fft_result.resize(fft_size); - fft_result_ma.resize(fft_size); - fft_result_maa.resize(fft_size); - } - - int n; - for (int i = 0, iMax = fft_size / 2; i < iMax; i++) { - float a = out[i][0]; - float b = out[i][1]; - float c = sqrt(a * a + b * b); - - float x = out[fft_size / 2 + i][0]; - float y = out[fft_size / 2 + i][1]; - float z = sqrt(x * x + y * y); - - fft_result[i] = (z); - fft_result[fft_size / 2 + i] = (c); - } - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - if (isView) { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - } else { - fft_result_maa[i] += (fft_result_ma[i] - fft_result_maa[i]) * 0.65; - fft_result_ma[i] += (fft_result[i] - fft_result_ma[i]) * 0.65; - } - - if (fft_result_maa[i] > fft_ceil) { - fft_ceil = fft_result_maa[i]; - } - if (fft_result_maa[i] < fft_floor) { - fft_floor = fft_result_maa[i]; - } - } - - fft_ceil += 0.25; - fft_floor -= 1; - - fft_ceil_ma = fft_ceil_ma + (fft_ceil - fft_ceil_ma) * 0.05; - fft_ceil_maa = fft_ceil_maa + (fft_ceil_ma - fft_ceil_maa) * 0.05; - - fft_floor_ma = fft_floor_ma + (fft_floor - fft_floor_ma) * 0.05; - fft_floor_maa = fft_floor_maa + (fft_floor_ma - fft_floor_maa) * 0.05; - - for (int i = 0, iMax = fft_size; i < iMax; i++) { - float v = (log10(fft_result_maa[i] - fft_floor_maa) / log10(fft_ceil_maa - fft_floor_maa)); - spectrum_points[i * 2] = ((float) i / (float) iMax); - spectrum_points[i * 2 + 1] = v; - } - - if (spectrumCanvas) { - spectrumCanvas->spectrum_points.assign(spectrum_points.begin(), spectrum_points.end()); - spectrumCanvas->getSpectrumContext()->setCeilValue(fft_ceil_maa); - spectrumCanvas->getSpectrumContext()->setFloorValue(fft_floor_maa); - } - } - } -} - void WaterfallCanvas::OnIdle(wxIdleEvent &event) { Refresh(false); } @@ -963,16 +717,16 @@ void WaterfallCanvas::OnMouseRightReleased(wxMouseEvent& event) { mouseZoom = 1.0; } -void WaterfallCanvas::attachWaterfallCanvas(WaterfallCanvas* canvas_in) { - otherWaterfallCanvas = canvas_in; - otherWaterfallCanvas->setPolling(false); -} +// +//bool WaterfallCanvas::isPolling() { +// return polling; +//} +// +//void WaterfallCanvas::setPolling(bool polling) { +// this->polling = polling; +//} -bool WaterfallCanvas::isPolling() { - return polling; -} - -void WaterfallCanvas::setPolling(bool polling) { - this->polling = polling; -} +SpectrumVisualDataQueue *WaterfallCanvas::getVisualDataQueue() { + return &visualDataQueue; +} \ No newline at end of file diff --git a/src/visual/WaterfallCanvas.h b/src/visual/WaterfallCanvas.h index 7c06271..5c80c27 100644 --- a/src/visual/WaterfallCanvas.h +++ b/src/visual/WaterfallCanvas.h @@ -11,7 +11,6 @@ #include "MouseTracker.h" #include "SpectrumCanvas.h" -#include "fftw3.h" class WaterfallCanvas: public InteractiveCanvas { public: @@ -23,16 +22,11 @@ public: void setup(int fft_size_in, int waterfall_lines_in); ~WaterfallCanvas(); - void setData(DemodulatorThreadIQData *input); - DragState getDragState(); DragState getNextDragState(); - + void attachSpectrumCanvas(SpectrumCanvas *canvas_in); - void attachWaterfallCanvas(WaterfallCanvas *canvas_in); - - bool isPolling(); - void setPolling(bool polling); + SpectrumVisualDataQueue *getVisualDataQueue(); private: void OnPaint(wxPaintEvent& event); @@ -53,19 +47,6 @@ private: std::vector spectrum_points; SpectrumCanvas *spectrumCanvas; - WaterfallCanvas *otherWaterfallCanvas; - bool polling; - - fftwf_complex *in, *out, *fft_in_data, *fft_last_data; - unsigned int last_data_size; - fftwf_plan plan; - - float fft_ceil_ma, fft_ceil_maa; - float fft_floor_ma, fft_floor_maa; - - std::vector fft_result; - std::vector fft_result_ma; - std::vector fft_result_maa; WaterfallContext *glContext; @@ -76,18 +57,11 @@ private: int waterfall_lines; int dragOfs; - msresamp_crcf resampler; - double resamplerRatio; - nco_crcf freqShifter; - long shiftFrequency; - int lastInputBandwidth; float mouseZoom, zoom; float hoverAlpha; - std::vector shiftBuffer; - std::vector resampleBuffer; - + SpectrumVisualDataQueue visualDataQueue; // event table wxDECLARE_EVENT_TABLE(); From 00713c0259004eb01b254521280ac61476cf85af Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 3 Aug 2015 02:12:11 -0400 Subject: [PATCH 10/11] unused var, comment cleanup --- src/visual/SpectrumCanvas.cpp | 2 +- src/visual/SpectrumCanvas.h | 13 ------------- src/visual/WaterfallCanvas.cpp | 10 ---------- 3 files changed, 1 insertion(+), 24 deletions(-) diff --git a/src/visual/SpectrumCanvas.cpp b/src/visual/SpectrumCanvas.cpp index 65a52b2..e618cc5 100644 --- a/src/visual/SpectrumCanvas.cpp +++ b/src/visual/SpectrumCanvas.cpp @@ -27,7 +27,7 @@ EVT_MOUSEWHEEL(SpectrumCanvas::OnMouseWheelMoved) wxEND_EVENT_TABLE() SpectrumCanvas::SpectrumCanvas(wxWindow *parent, int *attribList) : - InteractiveCanvas(parent, attribList), fft_size(0), waterfallCanvas(NULL), trackingRate(0) { + InteractiveCanvas(parent, attribList), waterfallCanvas(NULL) { glContext = new SpectrumContext(this, &wxGetApp().GetContext(this)); diff --git a/src/visual/SpectrumCanvas.h b/src/visual/SpectrumCanvas.h index 636296d..eb05e79 100644 --- a/src/visual/SpectrumCanvas.h +++ b/src/visual/SpectrumCanvas.h @@ -20,7 +20,6 @@ public: std::vector spectrum_points; SpectrumCanvas(wxWindow *parent, int *attribList = NULL); -// void setup(int fft_size_in); ~SpectrumCanvas(); void attachWaterfallCanvas(WaterfallCanvas *canvas_in); @@ -40,20 +39,8 @@ private: void OnMouseReleased(wxMouseEvent& event); void OnMouseLeftWindow(wxMouseEvent& event); -// fftwf_complex *in, *out; -// fftwf_plan plan; -// -// float fft_ceil_ma, fft_ceil_maa; -// float fft_floor_ma, fft_floor_maa; -// -// std::vector fft_result; -// std::vector fft_result_ma; -// std::vector fft_result_maa; - SpectrumContext *glContext; WaterfallCanvas *waterfallCanvas; - int fft_size; - int trackingRate; SpectrumVisualDataQueue visualDataQueue; diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index c928d89..4efa1e6 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -717,16 +717,6 @@ void WaterfallCanvas::OnMouseRightReleased(wxMouseEvent& event) { mouseZoom = 1.0; } - -// -//bool WaterfallCanvas::isPolling() { -// return polling; -//} -// -//void WaterfallCanvas::setPolling(bool polling) { -// this->polling = polling; -//} - SpectrumVisualDataQueue *WaterfallCanvas::getVisualDataQueue() { return &visualDataQueue; } \ No newline at end of file From bab2ad3780f838f9a6223289f61da316a1b248f2 Mon Sep 17 00:00:00 2001 From: "Charles J. Cliffe" Date: Mon, 3 Aug 2015 23:41:37 -0400 Subject: [PATCH 11/11] cleanup --- src/AppFrame.cpp | 6 ------ src/audio/AudioThread.cpp | 4 ++-- src/demod/DemodulatorThread.cpp | 1 - src/util/DataTree.cpp | 2 +- src/util/GLExt.cpp | 2 -- src/util/GLFont.cpp | 2 +- src/util/GLFont.h | 1 - src/visual/SpectrumContext.cpp | 2 +- src/visual/SpectrumContext.h | 1 - src/visual/TuningCanvas.cpp | 2 +- src/visual/WaterfallCanvas.cpp | 6 +----- src/visual/WaterfallCanvas.h | 1 - src/visual/WaterfallContext.cpp | 2 +- 13 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index d758322..4463da5 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -561,12 +561,6 @@ void AppFrame::OnThread(wxCommandEvent& event) { } void AppFrame::OnIdle(wxIdleEvent& event) { - bool work_done = false; - -//#ifdef __APPLE__ -// std::this_thread::sleep_for(std::chrono::milliseconds(4)); -// std::this_thread::yield(); -//#endif DemodulatorInstance *demod = wxGetApp().getDemodMgr().getLastActiveDemodulator(); diff --git a/src/audio/AudioThread.cpp b/src/audio/AudioThread.cpp index 0c48fbb..789e016 100644 --- a/src/audio/AudioThread.cpp +++ b/src/audio/AudioThread.cpp @@ -12,13 +12,13 @@ std::map AudioThread::deviceSampleRate; std::map AudioThread::deviceThread; AudioThread::AudioThread() : IOThread(), - currentInput(NULL), inputQueue(NULL), gain( - 1.0), threadQueueNotify(NULL), sampleRate(0), nBufferFrames(1024) { + currentInput(NULL), inputQueue(NULL), nBufferFrames(1024), threadQueueNotify(NULL), sampleRate(0) { audioQueuePtr.store(0); underflowCount.store(0); active.store(false); outputDevice.store(-1); + gain.store(1.0); boundThreads = new std::vector; } diff --git a/src/demod/DemodulatorThread.cpp b/src/demod/DemodulatorThread.cpp index 70306f2..d987a15 100644 --- a/src/demod/DemodulatorThread.cpp +++ b/src/demod/DemodulatorThread.cpp @@ -188,7 +188,6 @@ void DemodulatorThread::run() { } else if (demodulatorType == DEMOD_TYPE_RAW) { // do nothing here.. } else { - float p; switch (demodulatorType.load()) { case DEMOD_TYPE_LSB: for (int i = 0; i < bufSize; i++) { // Reject upper band diff --git a/src/util/DataTree.cpp b/src/util/DataTree.cpp index 1a17ec7..e150307 100755 --- a/src/util/DataTree.cpp +++ b/src/util/DataTree.cpp @@ -1598,8 +1598,8 @@ bool DataTree::LoadFromFile(const std::string& filename) { string compressionType(*header->getNext("compression")); dataSize = *header->getNext("uncompressed_size"); - bool uncompress = false; #if USE_FASTLZ + bool uncompress = false; if (compressionType == "FastLZ") { uncompress = true; } diff --git a/src/util/GLExt.cpp b/src/util/GLExt.cpp index f3a50a0..1de46d8 100644 --- a/src/util/GLExt.cpp +++ b/src/util/GLExt.cpp @@ -36,8 +36,6 @@ void initGLExtensions() { std::cout << std::endl << "Supported GL Extensions: " << std::endl << extensions << std::endl << std::endl; - int interval = 2; - #ifdef _WIN32 if (GLExtSupported("WGL_EXT_swap_control")) { std::cout << "Initializing WGL swap control extensions.." << std::endl; diff --git a/src/util/GLFont.cpp b/src/util/GLFont.cpp index d922e33..75109ae 100644 --- a/src/util/GLFont.cpp +++ b/src/util/GLFont.cpp @@ -103,7 +103,7 @@ int GLFontChar::getIndex() { } GLFont::GLFont() : - numCharacters(0), lineHeight(0), base(0), imageWidth(0), imageHeight(0), loaded(false), texId(0) { + lineHeight(0), base(0), imageWidth(0), imageHeight(0), loaded(false), texId(0) { } diff --git a/src/util/GLFont.h b/src/util/GLFont.h index 825459b..048095a 100644 --- a/src/util/GLFont.h +++ b/src/util/GLFont.h @@ -76,7 +76,6 @@ private: std::string getParamKey(std::string param_str); std::string getParamValue(std::string param_str); - int numCharacters; int lineHeight; int base; int imageWidth, imageHeight; diff --git a/src/visual/SpectrumContext.cpp b/src/visual/SpectrumContext.cpp index 8ee8cd7..22b78b7 100644 --- a/src/visual/SpectrumContext.cpp +++ b/src/visual/SpectrumContext.cpp @@ -7,7 +7,7 @@ #include "ColorTheme.h" SpectrumContext::SpectrumContext(SpectrumCanvas *canvas, wxGLContext *sharedContext) : - PrimaryGLContext(canvas, sharedContext), fft_size(0), floorValue(0), ceilValue(1) { + PrimaryGLContext(canvas, sharedContext), floorValue(0), ceilValue(1) { glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST); diff --git a/src/visual/SpectrumContext.h b/src/visual/SpectrumContext.h index 13e3f98..03cc82a 100644 --- a/src/visual/SpectrumContext.h +++ b/src/visual/SpectrumContext.h @@ -19,6 +19,5 @@ public: void setCeilValue(float ceilValue); private: - int fft_size; float floorValue, ceilValue; }; diff --git a/src/visual/TuningCanvas.cpp b/src/visual/TuningCanvas.cpp index 5582f30..daed27e 100644 --- a/src/visual/TuningCanvas.cpp +++ b/src/visual/TuningCanvas.cpp @@ -31,7 +31,7 @@ EVT_KEY_UP(TuningCanvas::OnKeyUp) wxEND_EVENT_TABLE() TuningCanvas::TuningCanvas(wxWindow *parent, int *attribList) : - InteractiveCanvas(parent, attribList), dragAccum(0), top(false), bottom(false), uxDown(0) { + InteractiveCanvas(parent, attribList), dragAccum(0), uxDown(0), top(false), bottom(false) { glContext = new TuningContext(this, &wxGetApp().GetContext(this)); diff --git a/src/visual/WaterfallCanvas.cpp b/src/visual/WaterfallCanvas.cpp index 4efa1e6..7fe2011 100644 --- a/src/visual/WaterfallCanvas.cpp +++ b/src/visual/WaterfallCanvas.cpp @@ -36,7 +36,7 @@ wxEND_EVENT_TABLE() WaterfallCanvas::WaterfallCanvas(wxWindow *parent, int *attribList) : InteractiveCanvas(parent, attribList), dragState(WF_DRAG_NONE), nextDragState(WF_DRAG_NONE), fft_size(0), waterfall_lines( - 0), zoom(1), mouseZoom(1), hoverAlpha(1.0), dragOfs(0) { + 0), mouseZoom(1), zoom(1), hoverAlpha(1.0), dragOfs(0) { glContext = new WaterfallContext(this, &wxGetApp().GetContext(this)); @@ -173,7 +173,6 @@ void WaterfallCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { int currentBandwidth = getBandwidth(); long long currentCenterFreq = getCenterFrequency(); - float demodColor, selectorColor; ColorTheme *currentTheme = ThemeMgr::mgr.currentTheme; int last_type = wxGetApp().getDemodMgr().getLastDemodulatorType(); @@ -260,13 +259,11 @@ void WaterfallCanvas::OnKeyUp(wxKeyEvent& event) { void WaterfallCanvas::OnKeyDown(wxKeyEvent& event) { InteractiveCanvas::OnKeyDown(event); - float angle = 5.0; DemodulatorInstance *activeDemod = wxGetApp().getDemodMgr().getActiveDemodulator(); long long freq; long long originalFreq; - unsigned int bw; switch (event.GetKeyCode()) { case 'A': zoom = 0.95; @@ -425,7 +422,6 @@ void WaterfallCanvas::OnMouseMoved(wxMouseEvent& event) { setStatusText("Click and drag to set the current demodulator range."); } } else if (demodsHover->size() && !shiftDown) { - int hovered = -1; long near_dist = getBandwidth(); DemodulatorInstance *activeDemodulator = NULL; diff --git a/src/visual/WaterfallCanvas.h b/src/visual/WaterfallCanvas.h index 5c80c27..e7f3384 100644 --- a/src/visual/WaterfallCanvas.h +++ b/src/visual/WaterfallCanvas.h @@ -57,7 +57,6 @@ private: int waterfall_lines; int dragOfs; - int lastInputBandwidth; float mouseZoom, zoom; float hoverAlpha; diff --git a/src/visual/WaterfallContext.cpp b/src/visual/WaterfallContext.cpp index 3ff3e30..733cfc9 100644 --- a/src/visual/WaterfallContext.cpp +++ b/src/visual/WaterfallContext.cpp @@ -3,7 +3,7 @@ #include "CubicSDR.h" WaterfallContext::WaterfallContext(WaterfallCanvas *canvas, wxGLContext *sharedContext) : - PrimaryGLContext(canvas, sharedContext), waterfall_lines(0), waterfall_slice(NULL), fft_size(0), activeTheme(NULL) { + PrimaryGLContext(canvas, sharedContext), fft_size(0), waterfall_lines(0), waterfall_slice(NULL), activeTheme(NULL) { for (int i = 0; i < 2; i++) { waterfall[i] = 0; }