diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 657fa79e..6fdc3944 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -4857,6 +4857,7 @@ bool DivEngine::initAudioBackend() { output=NULL; return false; } + return true; } @@ -4931,6 +4932,9 @@ bool DivEngine::init() { isMuted[i]=0; } + oscBuf[0]=new float[32768]; + oscBuf[1]=new float[32768]; + initDispatch(); reset(); active=true; @@ -4948,5 +4952,7 @@ bool DivEngine::quit() { logI("saving config.\n"); saveConf(); active=false; + delete[] oscBuf[0]; + delete[] oscBuf[1]; return true; } diff --git a/src/engine/engine.h b/src/engine/engine.h index 340e3801..3cdef106 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -206,6 +206,8 @@ class DivEngine { DivSystem sysOfChan[DIV_MAX_CHANS]; int dispatchOfChan[DIV_MAX_CHANS]; int dispatchChanOfChan[DIV_MAX_CHANS]; + float* oscBuf[2]; + float oscSize; void runExportThread(); void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size); @@ -549,6 +551,8 @@ class DivEngine { metroAmp(0.0f), totalProcessed(0), jediTable(NULL), + oscBuf{NULL,NULL}, + oscSize(1), adpcmMem(NULL), adpcmMemLen(0) {} }; diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 9bc04fd6..22aed29b 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1138,5 +1138,10 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi metroPos+=metroFreq; while (metroPos>=1) metroPos--; } + + // TODO: improve + memcpy(oscBuf[0],out[0],size*sizeof(float)); + memcpy(oscBuf[1],out[1],size*sizeof(float)); + oscSize=size; isBusy.unlock(); } diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index b1c2b26d..f76e270e 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -1977,6 +1977,25 @@ void FurnaceGUI::drawMixer() { ImGui::End(); } +void FurnaceGUI::drawOsc() { + if (!oscOpen) return; + ImGui::SetNextWindowSizeConstraints(ImVec2(64.0f*dpiScale,32.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale)); + if (ImGui::Begin("Oscilloscope",&oscOpen)) { + ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,ImVec2(0,0)); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,ImVec2(0,0)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0)); + ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0)); + float values[512]; + for (int i=0; i<512; i++) { + int pos=i*e->oscSize/512; + values[i]=(e->oscBuf[0][pos]+e->oscBuf[1][pos])*0.5f; + } + ImGui::PlotLines("##SingleOsc",values,512,0,NULL,-1.0f,1.0f,ImGui::GetContentRegionAvail()); + ImGui::PopStyleVar(4); + } + ImGui::End(); +} + void FurnaceGUI::drawPattern() { if (!patternOpen) return; if (e->isPlaying() && followPattern) cursor.y=oldRow; @@ -4571,6 +4590,7 @@ bool FurnaceGUI::loop() { if (ImGui::MenuItem("orders")) ordersOpen=!ordersOpen; if (ImGui::MenuItem("pattern")) patternOpen=!patternOpen; if (ImGui::MenuItem("mixer")) mixerOpen=!mixerOpen; + if (ImGui::MenuItem("oscilloscope")) oscOpen=!oscOpen; ImGui::EndMenu(); } if (ImGui::BeginMenu("help")) { @@ -4607,6 +4627,7 @@ bool FurnaceGUI::loop() { drawSampleList(); drawSampleEdit(); drawMixer(); + drawOsc(); drawPattern(); drawSettings(); drawDebug(); @@ -5209,6 +5230,7 @@ FurnaceGUI::FurnaceGUI(): settingsOpen(false), mixerOpen(false), debugOpen(false), + oscOpen(true), selecting(false), curNibble(false), orderNibble(false), diff --git a/src/gui/gui.h b/src/gui/gui.h index 02b0fc4a..54ef1b88 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -236,7 +236,7 @@ class FurnaceGUI { int loopOrder, loopRow, loopEnd; bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen; bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen; - bool mixerOpen, debugOpen; + bool mixerOpen, debugOpen, oscOpen; SelectionPoint selStart, selEnd, cursor; bool selecting, curNibble, orderNibble, extraChannelButtons, followOrders, followPattern, changeAllOrders; FurnaceGUIWindows curWindow; @@ -315,6 +315,7 @@ class FurnaceGUI { void drawSampleList(); void drawSampleEdit(); void drawMixer(); + void drawOsc(); void drawAbout(); void drawSettings(); void drawDebug();