diff --git a/CMakeLists.txt b/CMakeLists.txt index 841d5cd..0d16cd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -244,6 +244,7 @@ SET (cubicsdr_sources src/util/GLExt.cpp src/util/GLFont.cpp src/util/DataTree.cpp + src/panel/ScopePanel.cpp src/visual/ColorTheme.cpp src/visual/PrimaryGLContext.cpp src/visual/InteractiveCanvas.cpp @@ -296,6 +297,7 @@ SET (cubicsdr_headers src/util/GLExt.h src/util/GLFont.h src/util/DataTree.h + src/panel/ScopePanel.h src/visual/ColorTheme.h src/visual/PrimaryGLContext.h src/visual/InteractiveCanvas.h @@ -346,6 +348,7 @@ SOURCE_GROUP("SDR" REGULAR_EXPRESSION src/sdr/${REG_EXT}) SOURCE_GROUP("Demodulator" REGULAR_EXPRESSION src/demod/${REG_EXT}) SOURCE_GROUP("Audio" REGULAR_EXPRESSION src/audio/${REG_EXT}) SOURCE_GROUP("Utility" REGULAR_EXPRESSION src/util/${REG_EXT}) +SOURCE_GROUP("Panel" REGULAR_EXPRESSION src/panel/${REG_EXT}) SOURCE_GROUP("Visual" REGULAR_EXPRESSION src/visual/${REG_EXT}) SOURCE_GROUP("Process" REGULAR_EXPRESSION src/process/${REG_EXT}) SOURCE_GROUP("UI" REGULAR_EXPRESSION src/ui/${REG_EXT}) @@ -359,6 +362,7 @@ include_directories ( ${PROJECT_SOURCE_DIR}/src/demod ${PROJECT_SOURCE_DIR}/src/audio ${PROJECT_SOURCE_DIR}/src/util + ${PROJECT_SOURCE_DIR}/src/panel ${PROJECT_SOURCE_DIR}/src/visual ${PROJECT_SOURCE_DIR}/src/process ${PROJECT_SOURCE_DIR}/src/ui diff --git a/src/AppFrame.cpp b/src/AppFrame.cpp index 842267c..85ecdfa 100644 --- a/src/AppFrame.cpp +++ b/src/AppFrame.cpp @@ -707,6 +707,7 @@ void AppFrame::OnTimer(wxTimerEvent& event) { demodSpectrumCanvas->Refresh(); demodSignalMeter->Refresh(); + demodGainMeter->Refresh(); if (demodTuner->getMouseTracker()->mouseInView() || demodTuner->changed()) { demodTuner->Refresh(); @@ -714,9 +715,6 @@ void AppFrame::OnTimer(wxTimerEvent& event) { if (demodModeSelector->getMouseTracker()->mouseInView()) { demodModeSelector->Refresh(); } - if (demodGainMeter->getMouseTracker()->mouseInView()) { - demodGainMeter->Refresh(); - } event.Skip(); } diff --git a/src/panel/ScopePanel.cpp b/src/panel/ScopePanel.cpp new file mode 100644 index 0000000..7f60597 --- /dev/null +++ b/src/panel/ScopePanel.cpp @@ -0,0 +1,91 @@ +#include "ScopePanel.h" +#include "ColorTheme.h" + +ScopePanel::ScopePanel() : GLPanel(), scopeMode(SCOPE_MODE_Y) { + bgPanel.setFill(GLPanelFillType::GLPANEL_FILL_GRAD_BAR_Y); + bgPanelStereo[0].setFill(GLPanelFillType::GLPANEL_FILL_GRAD_BAR_Y); + bgPanelStereo[0].setPosition(0, 0.5); + bgPanelStereo[0].setSize(1, 0.5); + bgPanelStereo[1].setFill(GLPanelFillType::GLPANEL_FILL_GRAD_BAR_Y); + bgPanelStereo[1].setPosition(0, -0.5); + bgPanelStereo[1].setSize(1, 0.5); +} + +void ScopePanel::setMode(ScopeMode scopeMode) { + this->scopeMode = scopeMode; +} + + +void ScopePanel::setPoints(std::vector &points) { + this->points.assign(points.begin(),points.end()); +} + +void ScopePanel::drawPanelContents() { + + glLineWidth(1.0); + + if (scopeMode == SCOPE_MODE_Y) { + bgPanel.setFillColor(ThemeMgr::mgr.currentTheme->scopeBackground, ThemeMgr::mgr.currentTheme->scopeBackground * 2.0); + bgPanel.calcTransform(transform); + bgPanel.draw(); + + glLoadIdentity(); + glColor3f(ThemeMgr::mgr.currentTheme->scopeLine.r * 0.35, ThemeMgr::mgr.currentTheme->scopeLine.g * 0.35, + ThemeMgr::mgr.currentTheme->scopeLine.b * 0.35); + glBegin (GL_LINES); + glVertex2f(-1.0, 0.0); + glVertex2f(1.0, 0.0); + glEnd(); + } else if (scopeMode == SCOPE_MODE_2Y) { + bgPanelStereo[0].setFillColor(ThemeMgr::mgr.currentTheme->scopeBackground, ThemeMgr::mgr.currentTheme->scopeBackground * 2.0); + bgPanelStereo[1].setFillColor(ThemeMgr::mgr.currentTheme->scopeBackground, ThemeMgr::mgr.currentTheme->scopeBackground * 2.0); + + bgPanelStereo[0].calcTransform(transform); + bgPanelStereo[0].draw(); + bgPanelStereo[1].calcTransform(transform); + bgPanelStereo[1].draw(); + + glLoadIdentity(); + glColor3f(ThemeMgr::mgr.currentTheme->scopeLine.r, ThemeMgr::mgr.currentTheme->scopeLine.g, ThemeMgr::mgr.currentTheme->scopeLine.b); + glBegin (GL_LINES); + glVertex2f(-1.0, 0.0); + glVertex2f(1.0, 0.0); + glColor3f(ThemeMgr::mgr.currentTheme->scopeLine.r * 0.35, ThemeMgr::mgr.currentTheme->scopeLine.g * 0.35, + ThemeMgr::mgr.currentTheme->scopeLine.b * 0.35); + glVertex2f(-1.0, 0.5); + glVertex2f(1.0, 0.5); + glVertex2f(-1.0, -0.5); + glVertex2f(1.0, -0.5); + glEnd(); + + } else if (scopeMode == SCOPE_MODE_XY) { + // ... + } + + if (points.size()) { + glEnable (GL_BLEND); + glEnable (GL_LINE_SMOOTH); + glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glColor4f(ThemeMgr::mgr.currentTheme->scopeLine.r, ThemeMgr::mgr.currentTheme->scopeLine.g, ThemeMgr::mgr.currentTheme->scopeLine.b, 1.0); + glEnableClientState (GL_VERTEX_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, &points[0]); + glLineWidth(1.5); + if (scopeMode == SCOPE_MODE_Y) { + glLoadMatrixf(bgPanel.transform); + glDrawArrays(GL_LINE_STRIP, 0, points.size() / 2); + } else if (scopeMode == SCOPE_MODE_2Y) { + glLoadMatrixf(bgPanelStereo[0].transform); + glDrawArrays(GL_LINE_STRIP, 0, points.size() / 4); + + glLoadMatrixf(bgPanelStereo[1].transform); + glDrawArrays(GL_LINE_STRIP, points.size() / 4, points.size() / 4); + } else if (scopeMode == SCOPE_MODE_XY) { + // ... + } + glLineWidth(1.0); + glDisableClientState(GL_VERTEX_ARRAY); + glDisable(GL_BLEND); + } +} + diff --git a/src/panel/ScopePanel.h b/src/panel/ScopePanel.h new file mode 100644 index 0000000..2907448 --- /dev/null +++ b/src/panel/ScopePanel.h @@ -0,0 +1,20 @@ +#pragma once + +#include "GLPanel.h" + +class ScopePanel : public GLPanel { + +public: + typedef enum ScopeMode { SCOPE_MODE_Y, SCOPE_MODE_2Y, SCOPE_MODE_XY } ScopeMode; + + ScopePanel(); + + void setMode(ScopeMode scopeMode); + void setPoints(std::vector &points); + void drawPanelContents(); + + std::vector points; + ScopeMode scopeMode; + GLPanel bgPanel; + GLPanel bgPanelStereo[2]; +}; \ No newline at end of file diff --git a/src/process/ScopeVisualProcessor.cpp b/src/process/ScopeVisualProcessor.cpp index 4eff90d..7439977 100644 --- a/src/process/ScopeVisualProcessor.cpp +++ b/src/process/ScopeVisualProcessor.cpp @@ -23,12 +23,27 @@ void ScopeVisualProcessor::process() { if (renderData->waveform_points.size() != iMax * 2) { renderData->waveform_points.resize(iMax * 2); } + + float peak = 1.0f; 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); + float p = fabs(audioInputData->data[i]); + if (p > peak) { + peak = p; + } } + if (audioInputData->channels == 2) { + for (int i = 0; i < iMax; i++) { + renderData->waveform_points[i * 2] = (((double) (i % (iMax/2)) / (double) iMax) * 2.0 - 0.5) * 2.0; + renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] / peak; + } + } else { + for (int i = 0; i < iMax; i++) { + renderData->waveform_points[i * 2] = (((double) i / (double) iMax) - 0.5) * 2.0; + renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] / peak; + } + } distribute(renderData); } } diff --git a/src/ui/GLPanel.cpp b/src/ui/GLPanel.cpp index 5de9387..ae44400 100644 --- a/src/ui/GLPanel.cpp +++ b/src/ui/GLPanel.cpp @@ -225,7 +225,7 @@ void GLPanel::drawPanelContents() { void GLPanel::calcTransform(mat4 transform_in) { // compute local transform - localTransform = mat4::translate(pos[0], pos[1], 0) * mat4::scale(size[0], size[1], 0); + localTransform = mat4::translate(pos[0], pos[1], 0) * mat4::scale(size[0], size[1], 1); // compute global transform transform = transform_in * localTransform; @@ -250,10 +250,10 @@ void GLPanel::calcTransform(mat4 transform_in) { pdim = vec2((vmax.x - vmin.x) / 2.0 * view[0], (vmax.y - vmin.y) / 2.0 * view[1]); pvec = vec2(((vmax.x - vmin.x) / 2.0) / pdim.x, ((vmax.y - vmin.y) / 2.0) / pdim.y); - std::cout << umin << " :: " << ucenter << " :: " << pdim << " :: " << pvec << std::endl; +// std::cout << umin << " :: " << ucenter << " :: " << pdim << " :: " << pvec << std::endl; if (marginPx) { - transform *= mat4::scale(1.0 - marginPx * 2.0 * pvec.x / size[0], 1.0 - marginPx * 2.0 * pvec.y / size[1], 0); + transform *= mat4::scale(1.0 - marginPx * 2.0 * pvec.x / size[0], 1.0 - marginPx * 2.0 * pvec.y / size[1], 1); } } diff --git a/src/visual/ColorTheme.h b/src/visual/ColorTheme.h index 1318ac6..52b431a 100644 --- a/src/visual/ColorTheme.h +++ b/src/visual/ColorTheme.h @@ -35,6 +35,9 @@ public: b = other.b; return *this; } + + RGB3f operator*(float v) { return RGB3f(r*v, g*v, b*v); } + }; class ColorTheme { diff --git a/src/visual/ScopeCanvas.cpp b/src/visual/ScopeCanvas.cpp index 268fe7b..febc3b5 100644 --- a/src/visual/ScopeCanvas.cpp +++ b/src/visual/ScopeCanvas.cpp @@ -15,6 +15,7 @@ #include "AppFrame.h" #include + wxBEGIN_EVENT_TABLE(ScopeCanvas, wxGLCanvas) EVT_PAINT(ScopeCanvas::OnPaint) EVT_IDLE(ScopeCanvas::OnIdle) wxEND_EVENT_TABLE() @@ -66,8 +67,9 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { avData->decRefCount(); return; } - - waveform_points.assign(avData->waveform_points.begin(),avData->waveform_points.end()); + + scopePanel.setPoints(avData->waveform_points); +// waveform_points.assign(avData->waveform_points.begin(),avData->waveform_points.end()); setStereo(avData->channels == 2); avData->decRefCount(); @@ -79,7 +81,10 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) { glViewport(0, 0, ClientSize.x, ClientSize.y); glContext->DrawBegin(); - glContext->Plot(waveform_points, stereo, ppmMode); + scopePanel.setMode(stereo?ScopePanel::SCOPE_MODE_2Y:ScopePanel::SCOPE_MODE_Y); + scopePanel.calcTransform(CubicVR::mat4::identity()); + scopePanel.draw(); + glContext->DrawTunerTitles(ppmMode); if (!deviceName.empty()) { glContext->DrawDeviceName(deviceName); } diff --git a/src/visual/ScopeCanvas.h b/src/visual/ScopeCanvas.h index 23203b7..6cdff03 100644 --- a/src/visual/ScopeCanvas.h +++ b/src/visual/ScopeCanvas.h @@ -8,12 +8,11 @@ #include "ScopeContext.h" #include "ScopeVisualProcessor.h" +#include "ScopePanel.h" #include "fftw3.h" class ScopeCanvas: public wxGLCanvas { public: - std::vector waveform_points; - ScopeCanvas(wxWindow *parent, int *attribList = NULL); ~ScopeCanvas(); @@ -29,6 +28,7 @@ private: void OnIdle(wxIdleEvent &event); ScopeRenderDataQueue inputData; + ScopePanel scopePanel; ScopeContext *glContext; std::string deviceName; bool stereo; diff --git a/src/visual/ScopeContext.cpp b/src/visual/ScopeContext.cpp index 267b038..8c4a889 100644 --- a/src/visual/ScopeContext.cpp +++ b/src/visual/ScopeContext.cpp @@ -23,56 +23,8 @@ void ScopeContext::DrawBegin() { glDisable (GL_TEXTURE_2D); } -void ScopeContext::Plot(std::vector &points, bool stereo, bool ppmMode) { - if (stereo) { - glBegin(GL_QUADS); - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g, ThemeMgr::mgr.currentTheme->scopeBackground.b); - glVertex2f(1, 1); - glVertex2f(-1, 1); - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r*2.0, ThemeMgr::mgr.currentTheme->scopeBackground.g*2.0, ThemeMgr::mgr.currentTheme->scopeBackground.b*2.0); - glVertex2f(-1, 0.5); - glVertex2f(1, 0.5); - - glVertex2f(-1, 0.5); - glVertex2f(1, 0.5); - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g, ThemeMgr::mgr.currentTheme->scopeBackground.b); - glVertex2f(1, 0.0); - glVertex2f(-1, 0.0); - - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g, ThemeMgr::mgr.currentTheme->scopeBackground.b); - glVertex2f(1, 0); - glVertex2f(-1, 0); - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r*2.0, ThemeMgr::mgr.currentTheme->scopeBackground.g*2.0, ThemeMgr::mgr.currentTheme->scopeBackground.b*2.0); - glVertex2f(-1, -0.5); - glVertex2f(1, -0.5); - - glVertex2f(-1, -0.5); - glVertex2f(1, -0.5); - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g, ThemeMgr::mgr.currentTheme->scopeBackground.b); - glVertex2f(1, -1.0); - glVertex2f(-1, -1.0); - glEnd(); - } else { - glBegin (GL_QUADS); - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g, - ThemeMgr::mgr.currentTheme->scopeBackground.b); - glVertex2f(1, 1); - glVertex2f(-1, 1); - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r * 2.0, ThemeMgr::mgr.currentTheme->scopeBackground.g * 2.0, - ThemeMgr::mgr.currentTheme->scopeBackground.b * 2.0); - glVertex2f(-1, 0); - glVertex2f(1, 0); - - glVertex2f(-1, 0); - glVertex2f(1, 0); - glColor3f(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g, - ThemeMgr::mgr.currentTheme->scopeBackground.b); - glVertex2f(1, -1); - glVertex2f(-1, -1); - glEnd(); - } - glLineWidth(1.0); - +void ScopeContext::DrawTunerTitles(bool ppmMode) { + glLoadIdentity(); GLint vp[4]; glGetIntegerv(GL_VIEWPORT, vp); @@ -84,64 +36,6 @@ void ScopeContext::Plot(std::vector &points, bool stereo, bool ppmMode) { GLFont::getFont(GLFont::GLFONT_SIZE12).drawString(ppmMode?"Device PPM":"Frequency", -0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); GLFont::getFont(GLFont::GLFONT_SIZE12).drawString("Bandwidth", 0.0, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); GLFont::getFont(GLFont::GLFONT_SIZE12).drawString("Center Frequency", 0.66, -1.0+hPos, 12, GLFont::GLFONT_ALIGN_CENTER, GLFont::GLFONT_ALIGN_CENTER); - - - if (stereo) { - glColor3f(ThemeMgr::mgr.currentTheme->scopeLine.r, ThemeMgr::mgr.currentTheme->scopeLine.g, ThemeMgr::mgr.currentTheme->scopeLine.b); - glBegin (GL_LINES); - glVertex2f(-1.0, 0.0); - glVertex2f(1.0, 0.0); - glColor3f(ThemeMgr::mgr.currentTheme->scopeLine.r * 0.35, ThemeMgr::mgr.currentTheme->scopeLine.g * 0.35, - ThemeMgr::mgr.currentTheme->scopeLine.b * 0.35); - glVertex2f(-1.0, 0.5); - glVertex2f(1.0, 0.5); - glVertex2f(-1.0, -0.5); - glVertex2f(1.0, -0.5); - glEnd(); - } else { - glColor3f(ThemeMgr::mgr.currentTheme->scopeLine.r * 0.35, ThemeMgr::mgr.currentTheme->scopeLine.g * 0.35, - ThemeMgr::mgr.currentTheme->scopeLine.b * 0.35); - glBegin (GL_LINES); - glVertex2f(-1.0, 0.0); - glVertex2f(1.0, 0.0); - glEnd(); - } - - if (points.size()) { - glEnable (GL_BLEND); - glEnable (GL_LINE_SMOOTH); - glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glColor4f(ThemeMgr::mgr.currentTheme->scopeLine.r, ThemeMgr::mgr.currentTheme->scopeLine.g, ThemeMgr::mgr.currentTheme->scopeLine.b, 1.0); - glEnableClientState (GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, &points[0]); - if (stereo) { - glLineWidth(1.5); - glPushMatrix(); - glTranslatef(-1.0f, 0.5f, 0.0f); - glScalef(4.0f, 0.92f, 1.0f); - glDrawArrays(GL_LINE_STRIP, 0, points.size() / 4); - glPopMatrix(); - - glPushMatrix(); - glTranslatef(-3.0f, -0.5f, 0.0f); - glPushMatrix(); - glScalef(4.0f, 0.92f, 1.0f); - glDrawArrays(GL_LINE_STRIP, points.size() / 4, points.size() / 4); - glPopMatrix(); - glPopMatrix(); - } else { - glLineWidth(1.5); - glPushMatrix(); - glTranslatef(-1.0f, 0.0f, 0.0f); - glScalef(2.0f, 2.0f, 1.0f); - glDrawArrays(GL_LINE_STRIP, 0, points.size() / 2); - glPopMatrix(); - } - glLineWidth(1.0); - glDisableClientState(GL_VERTEX_ARRAY); - glDisable(GL_BLEND); - } } void ScopeContext::DrawDeviceName(std::string deviceName) { diff --git a/src/visual/ScopeContext.h b/src/visual/ScopeContext.h index 4afc6ad..c962429 100644 --- a/src/visual/ScopeContext.h +++ b/src/visual/ScopeContext.h @@ -12,7 +12,7 @@ public: ScopeContext(ScopeCanvas *canvas, wxGLContext *sharedContext); void DrawBegin(); - void Plot(std::vector &points, bool stereo=false, bool ppmMode=false); + void DrawTunerTitles(bool ppmMode=false); void DrawDeviceName(std::string deviceName); void DrawDivider(); void DrawEnd();