GUI: prepare for oscilloscope improvements

This commit is contained in:
tildearrow 2022-04-09 02:42:58 -05:00
parent 320250b831
commit 7bf2a3ea1a
6 changed files with 65 additions and 17 deletions

View file

@ -298,6 +298,7 @@ class DivEngine {
bool keyHit[DIV_MAX_CHANS]; bool keyHit[DIV_MAX_CHANS];
float* oscBuf[2]; float* oscBuf[2];
float oscSize; float oscSize;
int oscReadPos, oscWritePos;
void runExportThread(); void runExportThread();
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size); void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
@ -772,6 +773,8 @@ class DivEngine {
totalProcessed(0), totalProcessed(0),
oscBuf{NULL,NULL}, oscBuf{NULL,NULL},
oscSize(1), oscSize(1),
oscReadPos(0),
oscWritePos(0),
adpcmAMem(NULL), adpcmAMem(NULL),
adpcmAMemLen(0), adpcmAMemLen(0),
adpcmBMem(NULL), adpcmBMem(NULL),

View file

@ -1896,8 +1896,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
while (metroPos>=1) metroPos--; while (metroPos>=1) metroPos--;
} }
memcpy(oscBuf[0],out[0],size*sizeof(float)); for (unsigned int i=0; i<size; i++) {
memcpy(oscBuf[1],out[1],size*sizeof(float)); oscBuf[0][oscWritePos]=out[0][i];
oscBuf[1][oscWritePos]=out[1][i];
if (++oscWritePos>=32768) oscWritePos=0;
}
oscSize=size; oscSize=size;
if (forceMono) { if (forceMono) {

View file

@ -2600,6 +2600,9 @@ bool FurnaceGUI::loop() {
drawInsList(); drawInsList();
drawInsEdit(); drawInsEdit();
drawMixer(); drawMixer();
readOsc();
drawOsc(); drawOsc();
drawVolMeter(); drawVolMeter();
drawSettings(); drawSettings();
@ -3428,7 +3431,8 @@ FurnaceGUI::FurnaceGUI():
openSampleResampleOpt(false), openSampleResampleOpt(false),
openSampleAmplifyOpt(false), openSampleAmplifyOpt(false),
openSampleSilenceOpt(false), openSampleSilenceOpt(false),
openSampleFilterOpt(false) { openSampleFilterOpt(false),
oscTotal(0) {
// value keys // value keys
valueKeys[SDLK_0]=0; valueKeys[SDLK_0]=0;
valueKeys[SDLK_1]=1; valueKeys[SDLK_1]=1;
@ -3469,4 +3473,5 @@ FurnaceGUI::FurnaceGUI():
memset(patChanX,0,sizeof(float)*(DIV_MAX_CHANS+1)); memset(patChanX,0,sizeof(float)*(DIV_MAX_CHANS+1));
memset(patChanSlideY,0,sizeof(float)*(DIV_MAX_CHANS+1)); memset(patChanSlideY,0,sizeof(float)*(DIV_MAX_CHANS+1));
memset(lastIns,-1,sizeof(int)*DIV_MAX_CHANS); memset(lastIns,-1,sizeof(int)*DIV_MAX_CHANS);
memset(oscValues,0,sizeof(float)*512);
} }

View file

@ -976,6 +976,10 @@ class FurnaceGUI {
size_t sampleClipboardLen; size_t sampleClipboardLen;
bool openSampleResizeOpt, openSampleResampleOpt, openSampleAmplifyOpt, openSampleSilenceOpt, openSampleFilterOpt; bool openSampleResizeOpt, openSampleResampleOpt, openSampleAmplifyOpt, openSampleSilenceOpt, openSampleFilterOpt;
// oscilloscope
int oscTotal;
float oscValues[512];
// visualizer // visualizer
float keyHit[DIV_MAX_CHANS]; float keyHit[DIV_MAX_CHANS];
int lastIns[DIV_MAX_CHANS]; int lastIns[DIV_MAX_CHANS];
@ -996,6 +1000,8 @@ class FurnaceGUI {
void updateWindowTitle(); void updateWindowTitle();
void prepareLayout(); void prepareLayout();
void readOsc();
float calcBPM(int s1, int s2, float hz); float calcBPM(int s1, int s2, float hz);
void patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord, const DivPattern** patCache); void patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord, const DivPattern** patCache);

View file

@ -18,6 +18,50 @@
*/ */
#include "gui.h" #include "gui.h"
#include <math.h>
void FurnaceGUI::readOsc() {
int writePos=e->oscWritePos;
int readPos=e->oscReadPos;
int avail=0;
int total=0;
if (writePos>=readPos) {
avail=writePos-readPos;
} else {
avail=writePos-readPos+32768;
}
if (oscTotal==0) {
oscTotal=ImGui::GetIO().DeltaTime*e->getAudioDescGot().rate;
} else {
oscTotal=(oscTotal+(int)round(ImGui::GetIO().DeltaTime*e->getAudioDescGot().rate))>>1;
}
int bias=avail-oscTotal-e->getAudioDescGot().bufsize;
if (bias<0) bias=0;
total=oscTotal+(bias>>6);
if (total>avail) total=avail;
//printf("total: %d. avail: %d bias: %d\n",total,avail,bias);
for (int i=0; i<512; i++) {
int pos=(readPos+(i*total/512))&0x7fff;
oscValues[i]=(e->oscBuf[0][pos]+e->oscBuf[1][pos])*0.5f;
}
float peakDecay=0.05f*60.0f*ImGui::GetIO().DeltaTime;
for (int i=0; i<2; i++) {
peak[i]*=1.0-peakDecay;
if (peak[i]<0.0001) peak[i]=0.0;
float newPeak=peak[i];
for (int j=0; j<total; j++) {
int pos=(readPos+j)&0x7fff;
if (fabs(e->oscBuf[i][pos])>newPeak) {
newPeak=fabs(e->oscBuf[i][pos]);
}
}
peak[i]+=(newPeak-peak[i])*0.9;
}
readPos=(readPos+total)&0x7fff;
e->oscReadPos=readPos;
}
void FurnaceGUI::drawOsc() { void FurnaceGUI::drawOsc() {
if (nextWindow==GUI_WINDOW_OSCILLOSCOPE) { if (nextWindow==GUI_WINDOW_OSCILLOSCOPE) {
@ -31,14 +75,9 @@ void FurnaceGUI::drawOsc() {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0)); ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0));
if (ImGui::Begin("Oscilloscope",&oscOpen)) { if (ImGui::Begin("Oscilloscope",&oscOpen)) {
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::SetCursorPos(ImVec2(0,0)); //ImGui::SetCursorPos(ImVec2(0,0));
ImGui::BeginDisabled(); ImGui::BeginDisabled();
ImGui::PlotLines("##SingleOsc",values,512,0,NULL,-1.0f,1.0f,ImGui::GetContentRegionAvail()); ImGui::PlotLines("##SingleOsc",oscValues,512,0,NULL,-1.0f,1.0f,ImGui::GetContentRegionAvail());
ImGui::EndDisabled(); ImGui::EndDisabled();
} }
ImGui::PopStyleVar(3); ImGui::PopStyleVar(3);

View file

@ -49,17 +49,9 @@ void FurnaceGUI::drawVolMeter() {
ImGuiStyle& style=ImGui::GetStyle(); ImGuiStyle& style=ImGui::GetStyle();
ImGui::ItemSize(ImVec2(4.0f,4.0f),style.FramePadding.y); ImGui::ItemSize(ImVec2(4.0f,4.0f),style.FramePadding.y);
ImU32 lowColor=ImGui::GetColorU32(uiColors[GUI_COLOR_VOLMETER_LOW]); ImU32 lowColor=ImGui::GetColorU32(uiColors[GUI_COLOR_VOLMETER_LOW]);
float peakDecay=0.05f*60.0f*ImGui::GetIO().DeltaTime;
if (ImGui::ItemAdd(rect,ImGui::GetID("volMeter"))) { if (ImGui::ItemAdd(rect,ImGui::GetID("volMeter"))) {
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding); ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding);
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
peak[i]*=1.0-peakDecay;
if (peak[i]<0.0001) peak[i]=0.0;
for (int j=0; j<e->oscSize; j++) {
if (fabs(e->oscBuf[i][j])>peak[i]) {
peak[i]=fabs(e->oscBuf[i][j]);
}
}
float logPeak=(20*log10(peak[i])/36.0); float logPeak=(20*log10(peak[i])/36.0);
if (logPeak==NAN) logPeak=0.0; if (logPeak==NAN) logPeak=0.0;
if (logPeak<-1.0) logPeak=-1.0; if (logPeak<-1.0) logPeak=-1.0;