Basic X/Y scope plot while in digital mode

This commit is contained in:
Charles J. Cliffe 2015-11-29 13:35:12 -05:00
parent 7e4d173996
commit c303b68284
19 changed files with 226 additions and 150 deletions

View File

@ -18,6 +18,7 @@ public:
int sampleRate; int sampleRate;
int channels; int channels;
float peak; float peak;
int type;
std::vector<float> data; std::vector<float> data;
std::mutex busy_update; std::mutex busy_update;

View File

@ -79,6 +79,7 @@ class DemodulatorThreadPostIQData: public ReferenceCounter {
public: public:
std::vector<liquid_float_complex> data; std::vector<liquid_float_complex> data;
long long sampleRate; long long sampleRate;
std::string modemName;
std::string modemType; std::string modemType;
Modem *modem; Modem *modem;
ModemKit *modemKit; ModemKit *modemKit;

View File

@ -200,7 +200,8 @@ void DemodulatorPreThread::run() {
resamp->setRefCount(1); resamp->setRefCount(1);
resamp->data.assign(resampledData.begin(), resampledData.begin() + numWritten); resamp->data.assign(resampledData.begin(), resampledData.begin() + numWritten);
resamp->modemType = demodType; resamp->modemType = cModem->getType();
resamp->modemName = cModem->getName();
resamp->modem = cModem; resamp->modem = cModem;
resamp->modemKit = cModemKit; resamp->modemKit = cModemKit;
resamp->sampleRate = currentBandwidth; resamp->sampleRate = currentBandwidth;
@ -248,8 +249,8 @@ void DemodulatorPreThread::run() {
currentSampleRate = result.sampleRate; currentSampleRate = result.sampleRate;
} }
if (result.modemType != "") { if (result.modemName != "") {
demodType = result.modemType; demodType = result.modemName;
demodTypeChanged.store(false); demodTypeChanged.store(false);
} }

View File

@ -120,7 +120,7 @@ void DemodulatorThread::run() {
AudioThreadInput *ati = NULL; AudioThreadInput *ati = NULL;
ModemAnalog *modemAnalog = (cModem->getType() == "analog")?((ModemAnalog *)cModem):nullptr; ModemAnalog *modemAnalog = (cModem->getType() == "analog")?((ModemAnalog *)cModem):nullptr;
// ModemDigital *modemDigital = (cModem->getType() == "digital")?((ModemDigital *)cModem):nullptr; ModemDigital *modemDigital = (cModem->getType() == "digital")?((ModemDigital *)cModem):nullptr;
if (modemAnalog != nullptr) { if (modemAnalog != nullptr) {
ati = outputBuffers.getBuffer(); ati = outputBuffers.getBuffer();
@ -128,7 +128,14 @@ void DemodulatorThread::run() {
ati->sampleRate = cModemKit->audioSampleRate; ati->sampleRate = cModemKit->audioSampleRate;
ati->inputRate = inp->sampleRate; ati->inputRate = inp->sampleRate;
ati->setRefCount(1); ati->setRefCount(1);
} else if (modemDigital != nullptr) {
ati = outputBuffers.getBuffer();
ati->sampleRate = cModemKit->sampleRate;
ati->inputRate = inp->sampleRate;
ati->setRefCount(1);
} }
cModem->demodulate(cModemKit, &modemData, ati); cModem->demodulate(cModemKit, &modemData, ati);
if (currentSignalLevel > signalLevel) { if (currentSignalLevel > signalLevel) {
@ -160,7 +167,15 @@ void DemodulatorThread::run() {
ati_vis->inputRate = inp->sampleRate; ati_vis->inputRate = inp->sampleRate;
int num_vis = DEMOD_VIS_SIZE; int num_vis = DEMOD_VIS_SIZE;
if (ati->channels==2) { if (modemDigital) {
ati_vis->data.resize(inputData->size());
ati_vis->channels = 2;
for (int i = 0, iMax = inputData->size() / 2; i < iMax; i++) {
ati_vis->data[i * 2] = (*inputData)[i].real;
ati_vis->data[i * 2 + 1] = (*inputData)[i].imag;
}
ati_vis->type = 2;
} else if (ati->channels==2) {
ati_vis->channels = 2; ati_vis->channels = 2;
int stereoSize = ati->data.size(); int stereoSize = ati->data.size();
if (stereoSize > DEMOD_VIS_SIZE * 2) { if (stereoSize > DEMOD_VIS_SIZE * 2) {
@ -169,7 +184,7 @@ void DemodulatorThread::run() {
ati_vis->data.resize(stereoSize); ati_vis->data.resize(stereoSize);
if (inp->modemType == "I/Q") { if (inp->modemName == "I/Q") {
for (int i = 0; i < stereoSize / 2; i++) { for (int i = 0; i < stereoSize / 2; i++) {
ati_vis->data[i] = (*inputData)[i].real * 0.75; ati_vis->data[i] = (*inputData)[i].real * 0.75;
ati_vis->data[i + stereoSize / 2] = (*inputData)[i].imag * 0.75; ati_vis->data[i + stereoSize / 2] = (*inputData)[i].imag * 0.75;
@ -182,6 +197,7 @@ void DemodulatorThread::run() {
ati_vis->data[i + stereoSize / 2] = ati->data[i * 2 + 1]; ati_vis->data[i + stereoSize / 2] = ati->data[i * 2 + 1];
} }
} }
ati_vis->type = 1;
} else { } else {
int numAudioWritten = ati->data.size(); int numAudioWritten = ati->data.size();
ati_vis->channels = 1; ati_vis->channels = 1;
@ -198,7 +214,7 @@ void DemodulatorThread::run() {
} }
ati_vis->data.assign(demodOutData->begin(), demodOutData->begin() + num_vis); ati_vis->data.assign(demodOutData->begin(), demodOutData->begin() + num_vis);
} }
ati_vis->type = 0;
} }
audioVisOutputQueue->push(ati_vis); audioVisOutputQueue->push(ati_vis);

View File

@ -51,7 +51,8 @@ void DemodulatorWorkerThread::run() {
if (makeDemod) { if (makeDemod) {
cModem = Modem::makeModem(demodCommand.demodType); cModem = Modem::makeModem(demodCommand.demodType);
cModemType = demodCommand.demodType; cModemName = cModem->getName();
cModemType = cModem->getType();
if (demodCommand.settings.size()) { if (demodCommand.settings.size()) {
cModem->writeSettings(demodCommand.settings); cModem->writeSettings(demodCommand.settings);
} }
@ -91,6 +92,7 @@ void DemodulatorWorkerThread::run() {
result.modemKit = cModemKit; result.modemKit = cModemKit;
result.modemType = cModemType; result.modemType = cModemType;
result.modemName = cModemName;
resultQueue->push(result); resultQueue->push(result);
} }

View File

@ -37,6 +37,7 @@ public:
Modem *modem; Modem *modem;
ModemKit *modemKit; ModemKit *modemKit;
std::string modemType; std::string modemType;
std::string modemName;
}; };
class DemodulatorWorkerThreadCommand { class DemodulatorWorkerThreadCommand {
@ -93,4 +94,5 @@ protected:
Modem *cModem; Modem *cModem;
ModemKit *cModemKit; ModemKit *cModemKit;
std::string cModemType; std::string cModemType;
std::string cModemName;
}; };

View File

@ -90,114 +90,125 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
<object class="wxBoxSizer" expanded="1"> <object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">bSizer</property> <property name="name">mainSizer</property>
<property name="orient">wxVERTICAL</property> <property name="orient">wxVERTICAL</property>
<property name="permission">none</property> <property name="permission">none</property>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxEXPAND</property>
<property name="proportion">1</property> <property name="proportion">1</property>
<object class="wxTextCtrl" expanded="1"> <object class="wxBoxSizer" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font">,90,90,-1,76,0</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="maxlength"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="moveable">1</property> <property name="name">dataViewSizer</property>
<property name="name">m_dataView</property> <property name="orient">wxVERTICAL</property>
<property name="pane_border">1</property> <property name="permission">none</property>
<property name="pane_position"></property> <object class="sizeritem" expanded="0">
<property name="pane_size"></property> <property name="border">5</property>
<property name="permission">protected</property> <property name="flag">wxEXPAND</property>
<property name="pin_button">1</property> <property name="proportion">1</property>
<property name="pos"></property> <object class="wxTextCtrl" expanded="0">
<property name="resize">Resizable</property> <property name="BottomDockable">1</property>
<property name="show">1</property> <property name="LeftDockable">1</property>
<property name="size"></property> <property name="RightDockable">1</property>
<property name="style">wxTE_CHARWRAP|wxTE_MULTILINE|wxTE_NOHIDESEL|wxTE_READONLY|wxTE_WORDWRAP</property> <property name="TopDockable">1</property>
<property name="subclass"></property> <property name="aui_layer"></property>
<property name="toolbar_pane">0</property> <property name="aui_name"></property>
<property name="tooltip"></property> <property name="aui_position"></property>
<property name="validator_data_type"></property> <property name="aui_row"></property>
<property name="validator_style">wxFILTER_NONE</property> <property name="best_size"></property>
<property name="validator_type">wxDefaultValidator</property> <property name="bg"></property>
<property name="validator_variable"></property> <property name="caption"></property>
<property name="value"></property> <property name="caption_visible">1</property>
<property name="window_extra_style">wxWS_EX_PROCESS_UI_UPDATES</property> <property name="center_pane">0</property>
<property name="window_name"></property> <property name="close_button">1</property>
<property name="window_style">wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE|wxNO_BORDER|wxSIMPLE_BORDER|wxVSCROLL</property> <property name="context_help"></property>
<event name="OnChar"></event> <property name="context_menu">1</property>
<event name="OnEnterWindow"></event> <property name="default_pane">0</property>
<event name="OnEraseBackground"></event> <property name="dock">Dock</property>
<event name="OnKeyDown"></event> <property name="dock_fixed">0</property>
<event name="OnKeyUp"></event> <property name="docking">Left</property>
<event name="OnKillFocus"></event> <property name="enabled">1</property>
<event name="OnLeaveWindow"></event> <property name="fg"></property>
<event name="OnLeftDClick"></event> <property name="floatable">1</property>
<event name="OnLeftDown"></event> <property name="font">,90,90,-1,76,0</property>
<event name="OnLeftUp"></event> <property name="gripper">0</property>
<event name="OnMiddleDClick"></event> <property name="hidden">0</property>
<event name="OnMiddleDown"></event> <property name="id">wxID_ANY</property>
<event name="OnMiddleUp"></event> <property name="max_size"></property>
<event name="OnMotion"></event> <property name="maximize_button">0</property>
<event name="OnMouseEvents"></event> <property name="maximum_size"></property>
<event name="OnMouseWheel"></event> <property name="maxlength"></property>
<event name="OnPaint"></event> <property name="min_size"></property>
<event name="OnRightDClick"></event> <property name="minimize_button">0</property>
<event name="OnRightDown"></event> <property name="minimum_size"></property>
<event name="OnRightUp"></event> <property name="moveable">1</property>
<event name="OnSetFocus"></event> <property name="name">m_dataView</property>
<event name="OnSize"></event> <property name="pane_border">1</property>
<event name="OnText"></event> <property name="pane_position"></property>
<event name="OnTextEnter"></event> <property name="pane_size"></property>
<event name="OnTextMaxLen"></event> <property name="permission">protected</property>
<event name="OnTextURL"></event> <property name="pin_button">1</property>
<event name="OnUpdateUI"></event> <property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxTE_CHARWRAP|wxTE_MULTILINE|wxTE_NOHIDESEL|wxTE_READONLY|wxTE_WORDWRAP</property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="value"></property>
<property name="window_extra_style">wxWS_EX_PROCESS_UI_UPDATES</property>
<property name="window_name"></property>
<property name="window_style">wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE|wxNO_BORDER|wxSIMPLE_BORDER|wxVSCROLL</property>
<event name="OnChar"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnText"></event>
<event name="OnTextEnter"></event>
<event name="OnTextMaxLen"></event>
<event name="OnTextURL"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="1">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1"> <object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property> <property name="minimum_size"></property>
<property name="name">bSizer2</property> <property name="name">buttonSizer</property>
<property name="orient">wxHORIZONTAL</property> <property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property> <property name="permission">none</property>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL</property> <property name="flag">wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">1</property>
<object class="wxButton" expanded="1"> <object class="wxButton" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -281,11 +292,11 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL</property> <property name="flag">wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">1</property>
<object class="wxButton" expanded="1"> <object class="wxButton" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>
@ -369,11 +380,11 @@
<event name="OnUpdateUI"></event> <event name="OnUpdateUI"></event>
</object> </object>
</object> </object>
<object class="sizeritem" expanded="1"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxEXPAND</property> <property name="flag">wxEXPAND</property>
<property name="proportion">0</property> <property name="proportion">1</property>
<object class="wxButton" expanded="1"> <object class="wxButton" expanded="0">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
<property name="RightDockable">1</property> <property name="RightDockable">1</property>

View File

@ -14,32 +14,38 @@ DigitalConsoleFrame::DigitalConsoleFrame( wxWindow* parent, wxWindowID id, const
this->SetSizeHints( wxDefaultSize, wxDefaultSize ); this->SetSizeHints( wxDefaultSize, wxDefaultSize );
this->SetExtraStyle( wxWS_EX_PROCESS_UI_UPDATES ); this->SetExtraStyle( wxWS_EX_PROCESS_UI_UPDATES );
wxBoxSizer* bSizer; wxBoxSizer* mainSizer;
bSizer = new wxBoxSizer( wxVERTICAL ); mainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* dataViewSizer;
dataViewSizer = new wxBoxSizer( wxVERTICAL );
m_dataView = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CHARWRAP|wxTE_MULTILINE|wxTE_NOHIDESEL|wxTE_READONLY|wxTE_WORDWRAP|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE|wxNO_BORDER|wxSIMPLE_BORDER|wxVSCROLL ); m_dataView = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_CHARWRAP|wxTE_MULTILINE|wxTE_NOHIDESEL|wxTE_READONLY|wxTE_WORDWRAP|wxALWAYS_SHOW_SB|wxFULL_REPAINT_ON_RESIZE|wxNO_BORDER|wxSIMPLE_BORDER|wxVSCROLL );
m_dataView->SetExtraStyle( wxWS_EX_PROCESS_UI_UPDATES ); m_dataView->SetExtraStyle( wxWS_EX_PROCESS_UI_UPDATES );
m_dataView->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 76, 90, 90, false, wxEmptyString ) ); m_dataView->SetFont( wxFont( wxNORMAL_FONT->GetPointSize(), 76, 90, 90, false, wxEmptyString ) );
bSizer->Add( m_dataView, 1, wxEXPAND, 5 ); dataViewSizer->Add( m_dataView, 1, wxEXPAND, 5 );
wxBoxSizer* bSizer2;
bSizer2 = new wxBoxSizer( wxHORIZONTAL ); mainSizer->Add( dataViewSizer, 1, wxEXPAND, 5 );
wxBoxSizer* buttonSizer;
buttonSizer = new wxBoxSizer( wxHORIZONTAL );
m_clearButton = new wxButton( this, wxID_ANY, wxT("Clear"), wxDefaultPosition, wxDefaultSize, 0 ); m_clearButton = new wxButton( this, wxID_ANY, wxT("Clear"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_clearButton, 0, wxALL, 5 ); buttonSizer->Add( m_clearButton, 1, wxEXPAND, 5 );
m_copyButton = new wxButton( this, wxID_ANY, wxT("Copy"), wxDefaultPosition, wxDefaultSize, 0 ); m_copyButton = new wxButton( this, wxID_ANY, wxT("Copy"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_copyButton, 0, wxALL, 5 ); buttonSizer->Add( m_copyButton, 1, wxEXPAND, 5 );
m_pauseButton = new wxButton( this, wxID_ANY, wxT("Stop"), wxDefaultPosition, wxDefaultSize, 0 ); m_pauseButton = new wxButton( this, wxID_ANY, wxT("Stop"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer2->Add( m_pauseButton, 0, wxEXPAND, 5 ); buttonSizer->Add( m_pauseButton, 1, wxEXPAND, 5 );
bSizer->Add( bSizer2, 0, wxEXPAND, 5 ); mainSizer->Add( buttonSizer, 0, wxALL|wxEXPAND, 5 );
this->SetSizer( bSizer ); this->SetSizer( mainSizer );
this->Layout(); this->Layout();
m_refreshTimer.SetOwner( this, wxID_ANY ); m_refreshTimer.SetOwner( this, wxID_ANY );
m_refreshTimer.Start( 250 ); m_refreshTimer.Start( 250 );

View File

@ -16,8 +16,8 @@
#include <wx/font.h> #include <wx/font.h>
#include <wx/colour.h> #include <wx/colour.h>
#include <wx/settings.h> #include <wx/settings.h>
#include <wx/button.h>
#include <wx/sizer.h> #include <wx/sizer.h>
#include <wx/button.h>
#include <wx/timer.h> #include <wx/timer.h>
#include <wx/frame.h> #include <wx/frame.h>

View File

@ -44,9 +44,9 @@ ModemFactoryList Modem::getFactories() {
return modemFactories; return modemFactories;
} }
Modem *Modem::makeModem(std::string modemType) { Modem *Modem::makeModem(std::string modemName) {
if (modemFactories.find(modemType) != modemFactories.end()) { if (modemFactories.find(modemName) != modemFactories.end()) {
return modemFactories[modemType]->factory(); return modemFactories[modemName]->factory();
} }
return nullptr; return nullptr;

View File

@ -112,7 +112,7 @@ public:
static void addModemFactory(Modem *factorySingle); static void addModemFactory(Modem *factorySingle);
static ModemFactoryList getFactories(); static ModemFactoryList getFactories();
static Modem *makeModem(std::string modemType); static Modem *makeModem(std::string modemName);
virtual std::string getType() = 0; virtual std::string getType() = 0;
virtual std::string getName() = 0; virtual std::string getName() = 0;

View File

@ -16,6 +16,9 @@ void ScopePanel::setMode(ScopeMode scopeMode) {
this->scopeMode = scopeMode; this->scopeMode = scopeMode;
} }
ScopePanel::ScopeMode ScopePanel::getMode() {
return this->scopeMode;
}
void ScopePanel::setPoints(std::vector<float> &points) { void ScopePanel::setPoints(std::vector<float> &points) {
this->points.assign(points.begin(),points.end()); this->points.assign(points.begin(),points.end());
@ -61,14 +64,29 @@ void ScopePanel::drawPanelContents() {
glEnd(); glEnd();
} else if (scopeMode == SCOPE_MODE_XY) { } else if (scopeMode == SCOPE_MODE_XY) {
// ... RGBA4f bg1(ThemeMgr::mgr.currentTheme->scopeBackground), bg2(ThemeMgr::mgr.currentTheme->scopeBackground * 2.0);
bg1.a = 0.1;
bg2.a = 0.1;
bgPanel.setFillColor(bg1, bg2);
bgPanel.calcTransform(transform);
bgPanel.draw();
glLineWidth(1.0);
glEnable(GL_POINT_SMOOTH);
glPointSize(2.0);
glLoadMatrixf(transform);
glColor3f(ThemeMgr::mgr.currentTheme->scopeLine.r * 0.35, ThemeMgr::mgr.currentTheme->scopeLine.g * 0.35,
ThemeMgr::mgr.currentTheme->scopeLine.b * 0.35);
} }
if (points.size()) { if (points.size()) {
glEnable (GL_BLEND); glEnable (GL_BLEND);
glEnable (GL_LINE_SMOOTH); glEnable (GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if (scopeMode == SCOPE_MODE_XY) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
} else {
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); glColor4f(ThemeMgr::mgr.currentTheme->scopeLine.r, ThemeMgr::mgr.currentTheme->scopeLine.g, ThemeMgr::mgr.currentTheme->scopeLine.b, 1.0);
glEnableClientState (GL_VERTEX_ARRAY); glEnableClientState (GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, &points[0]); glVertexPointer(2, GL_FLOAT, 0, &points[0]);
@ -83,7 +101,8 @@ void ScopePanel::drawPanelContents() {
glLoadMatrixf(bgPanelStereo[1].transform); glLoadMatrixf(bgPanelStereo[1].transform);
glDrawArrays(GL_LINE_STRIP, points.size() / 4, points.size() / 4); glDrawArrays(GL_LINE_STRIP, points.size() / 4, points.size() / 4);
} else if (scopeMode == SCOPE_MODE_XY) { } else if (scopeMode == SCOPE_MODE_XY) {
// ... glLoadMatrixf(bgPanel.transform);
glDrawArrays(GL_POINTS, 0, points.size() / 2);
} }
glLineWidth(1.0); glLineWidth(1.0);
glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_VERTEX_ARRAY);

View File

@ -10,6 +10,7 @@ public:
ScopePanel(); ScopePanel();
void setMode(ScopeMode scopeMode); void setMode(ScopeMode scopeMode);
ScopeMode getMode();
void setPoints(std::vector<float> &points); void setPoints(std::vector<float> &points);
protected: protected:

View File

@ -95,7 +95,7 @@ void ScopeVisualProcessor::process() {
} }
} }
if (audioInputData->channels == 2) { if (audioInputData->type == 1) {
iMax = audioInputData->data.size(); iMax = audioInputData->data.size();
if (renderData->waveform_points.size() != iMax * 2) { if (renderData->waveform_points.size() != iMax * 2) {
renderData->waveform_points.resize(iMax * 2); renderData->waveform_points.resize(iMax * 2);
@ -104,11 +104,23 @@ void ScopeVisualProcessor::process() {
renderData->waveform_points[i * 2] = (((double) (i % (iMax/2)) / (double) iMax) * 2.0 - 0.5) * 2.0; 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; renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] / peak;
} }
renderData->mode = ScopePanel::SCOPE_MODE_2Y;
} else if (audioInputData->type == 2) {
iMax = audioInputData->data.size();
if (renderData->waveform_points.size() != iMax) {
renderData->waveform_points.resize(iMax);
}
for (i = 0; i < iMax/2; i++) {
renderData->waveform_points[i * 2] = audioInputData->data[i * 2] / peak;
renderData->waveform_points[i * 2 + 1] = audioInputData->data[i * 2 + 1] / peak;
}
renderData->mode = ScopePanel::SCOPE_MODE_XY;
} else { } else {
for (i = 0; i < iMax; i++) { for (i = 0; i < iMax; i++) {
renderData->waveform_points[i * 2] = (((double) i / (double) iMax) - 0.5) * 2.0; renderData->waveform_points[i * 2] = (((double) i / (double) iMax) - 0.5) * 2.0;
renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] / peak; renderData->waveform_points[i * 2 + 1] = audioInputData->data[i] / peak;
} }
renderData->mode = ScopePanel::SCOPE_MODE_Y;
} }
renderData->spectrum = false; renderData->spectrum = false;

View File

@ -3,10 +3,12 @@
#include "VisualProcessor.h" #include "VisualProcessor.h"
#include "AudioThread.h" #include "AudioThread.h"
#include "fftw3.h" #include "fftw3.h"
#include "ScopePanel.h"
class ScopeRenderData: public ReferenceCounter { class ScopeRenderData: public ReferenceCounter {
public: public:
std::vector<float> waveform_points; std::vector<float> waveform_points;
ScopePanel::ScopeMode mode;
int inputRate; int inputRate;
int sampleRate; int sampleRate;
int channels; int channels;

View File

@ -28,7 +28,7 @@ EVT_LEAVE_WINDOW(ScopeCanvas::OnMouseLeftWindow)
EVT_ENTER_WINDOW(ScopeCanvas::OnMouseEnterWindow) EVT_ENTER_WINDOW(ScopeCanvas::OnMouseEnterWindow)
wxEND_EVENT_TABLE() wxEND_EVENT_TABLE()
ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) : InteractiveCanvas(parent, attribList), stereo(false), ppmMode(false), ctr(0), ctrTarget(0), dragAccel(0), helpTip("") { ScopeCanvas::ScopeCanvas(wxWindow *parent, int *attribList) : InteractiveCanvas(parent, attribList), ppmMode(false), ctr(0), ctrTarget(0), dragAccel(0), helpTip("") {
glContext = new ScopeContext(this, &wxGetApp().GetContext(this)); glContext = new ScopeContext(this, &wxGetApp().GetContext(this));
inputData.set_max_num_items(2); inputData.set_max_num_items(2);
@ -65,7 +65,7 @@ bool ScopeCanvas::spectrumVisible() {
float panelInterval = (2.0 + panelSpacing); float panelInterval = (2.0 + panelSpacing);
ctrTarget = abs(round(ctr / panelInterval)); ctrTarget = abs(round(ctr / panelInterval));
if (ctrTarget == 1 || dragAccel || (ctr != ctrTarget)) { if (ctrTarget == 1 || dragAccel || (ctr != ctrTarget)) {
return true; return true;
} }
@ -73,10 +73,6 @@ bool ScopeCanvas::spectrumVisible() {
return false; return false;
} }
void ScopeCanvas::setStereo(bool state) {
stereo = state;
}
void ScopeCanvas::setDeviceName(std::string device_name) { void ScopeCanvas::setDeviceName(std::string device_name) {
deviceName = device_name; deviceName = device_name;
deviceName.append(" "); deviceName.append(" ");
@ -106,12 +102,12 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
ScopeRenderData *avData; ScopeRenderData *avData;
inputData.pop(avData); inputData.pop(avData);
if (!avData->spectrum) { if (!avData->spectrum) {
scopePanel.setMode(avData->mode);
if (avData->waveform_points.size()) { if (avData->waveform_points.size()) {
scopePanel.setPoints(avData->waveform_points); scopePanel.setPoints(avData->waveform_points);
setStereo(avData->channels == 2);
} }
avData->decRefCount(); avData->decRefCount();
} else { } else {
if (avData->waveform_points.size()) { if (avData->waveform_points.size()) {
@ -133,14 +129,18 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glViewport(0, 0, ClientSize.x, ClientSize.y); glViewport(0, 0, ClientSize.x, ClientSize.y);
glContext->DrawBegin(); if (scopePanel.getMode() == ScopePanel::SCOPE_MODE_XY && !spectrumVisible()) {
glDrawBuffer(GL_FRONT);
glContext->DrawBegin(false);
} else {
glDrawBuffer(GL_BACK);
glContext->DrawBegin();
bgPanel.setFillColor(ThemeMgr::mgr.currentTheme->scopeBackground * 3.0, RGBA4f(0,0,0,1));
bgPanel.calcTransform(CubicVR::mat4::identity());
bgPanel.draw();
}
bgPanel.setFillColor(ThemeMgr::mgr.currentTheme->scopeBackground * 3.0, RGBA4f(0,0,0,0));
bgPanel.calcTransform(CubicVR::mat4::identity());
bgPanel.draw();
scopePanel.setMode(stereo?ScopePanel::SCOPE_MODE_2Y:ScopePanel::SCOPE_MODE_Y);
glMatrixMode(GL_PROJECTION); glMatrixMode(GL_PROJECTION);
glLoadIdentity(); glLoadIdentity();
glLoadMatrixf(CubicVR::mat4::perspective(45.0, 1.0, 1.0, 1000.0)); glLoadMatrixf(CubicVR::mat4::perspective(45.0, 1.0, 1.0, 1000.0));
@ -190,7 +190,7 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
spectrumPanel.setPosition(panelInterval+ctr, 0); spectrumPanel.setPosition(panelInterval+ctr, 0);
if (spectrumVisible()) { if (spectrumVisible()) {
spectrumPanel.setFillColor(ThemeMgr::mgr.currentTheme->scopeBackground * 2.0, RGBA4f(0,0,0,0)); spectrumPanel.setFillColor(ThemeMgr::mgr.currentTheme->scopeBackground * 2.0, RGBA4f(0,0,0,1));
spectrumPanel.contentsVisible = true; spectrumPanel.contentsVisible = true;
roty = atan2(spectrumPanel.pos[0],1.2); roty = atan2(spectrumPanel.pos[0],1.2);
spectrumPanel.rot[1] = -(roty * (180.0 / M_PI)); spectrumPanel.rot[1] = -(roty * (180.0 / M_PI));
@ -217,7 +217,9 @@ void ScopeCanvas::OnPaint(wxPaintEvent& WXUNUSED(event)) {
glContext->DrawTunerTitles(ppmMode); glContext->DrawTunerTitles(ppmMode);
glContext->DrawEnd(); glContext->DrawEnd();
SwapBuffers(); if (scopePanel.getMode() != ScopePanel::SCOPE_MODE_XY || spectrumVisible()) {
SwapBuffers();
}
} }

View File

@ -18,7 +18,6 @@ public:
ScopeCanvas(wxWindow *parent, int *attribList = NULL); ScopeCanvas(wxWindow *parent, int *attribList = NULL);
~ScopeCanvas(); ~ScopeCanvas();
void setStereo(bool state);
void setDeviceName(std::string device_name); void setDeviceName(std::string device_name);
void setPPMMode(bool ppmMode); void setPPMMode(bool ppmMode);
bool getPPMMode(); bool getPPMMode();
@ -50,7 +49,6 @@ private:
GLPanel bgPanel; GLPanel bgPanel;
ScopeContext *glContext; ScopeContext *glContext;
std::string deviceName; std::string deviceName;
bool stereo;
bool ppmMode; bool ppmMode;
bool showDb; bool showDb;
float panelSpacing; float panelSpacing;

View File

@ -12,10 +12,12 @@ ScopeContext::ScopeContext(ScopeCanvas *canvas, wxGLContext *sharedContext) :
glLoadIdentity(); glLoadIdentity();
} }
void ScopeContext::DrawBegin() { void ScopeContext::DrawBegin(bool clear) {
glClearColor(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g, if (clear) {
ThemeMgr::mgr.currentTheme->scopeBackground.b, 1.0); glClearColor(ThemeMgr::mgr.currentTheme->scopeBackground.r, ThemeMgr::mgr.currentTheme->scopeBackground.g,
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ThemeMgr::mgr.currentTheme->scopeBackground.b, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
glMatrixMode (GL_MODELVIEW); glMatrixMode (GL_MODELVIEW);
glLoadIdentity(); glLoadIdentity();

View File

@ -11,7 +11,7 @@ class ScopeContext: public PrimaryGLContext {
public: public:
ScopeContext(ScopeCanvas *canvas, wxGLContext *sharedContext); ScopeContext(ScopeCanvas *canvas, wxGLContext *sharedContext);
void DrawBegin(); void DrawBegin(bool clear=true);
void DrawTunerTitles(bool ppmMode=false); void DrawTunerTitles(bool ppmMode=false);
void DrawDeviceName(std::string deviceName); void DrawDeviceName(std::string deviceName);
void DrawDivider(); void DrawDivider();