GUI: prepare for oscilloscope improvements
This commit is contained in:
parent
320250b831
commit
7bf2a3ea1a
|
@ -298,6 +298,7 @@ class DivEngine {
|
|||
bool keyHit[DIV_MAX_CHANS];
|
||||
float* oscBuf[2];
|
||||
float oscSize;
|
||||
int oscReadPos, oscWritePos;
|
||||
|
||||
void runExportThread();
|
||||
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
|
||||
|
@ -772,6 +773,8 @@ class DivEngine {
|
|||
totalProcessed(0),
|
||||
oscBuf{NULL,NULL},
|
||||
oscSize(1),
|
||||
oscReadPos(0),
|
||||
oscWritePos(0),
|
||||
adpcmAMem(NULL),
|
||||
adpcmAMemLen(0),
|
||||
adpcmBMem(NULL),
|
||||
|
|
|
@ -1896,8 +1896,11 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
while (metroPos>=1) metroPos--;
|
||||
}
|
||||
|
||||
memcpy(oscBuf[0],out[0],size*sizeof(float));
|
||||
memcpy(oscBuf[1],out[1],size*sizeof(float));
|
||||
for (unsigned int i=0; i<size; i++) {
|
||||
oscBuf[0][oscWritePos]=out[0][i];
|
||||
oscBuf[1][oscWritePos]=out[1][i];
|
||||
if (++oscWritePos>=32768) oscWritePos=0;
|
||||
}
|
||||
oscSize=size;
|
||||
|
||||
if (forceMono) {
|
||||
|
|
|
@ -2600,6 +2600,9 @@ bool FurnaceGUI::loop() {
|
|||
drawInsList();
|
||||
drawInsEdit();
|
||||
drawMixer();
|
||||
|
||||
readOsc();
|
||||
|
||||
drawOsc();
|
||||
drawVolMeter();
|
||||
drawSettings();
|
||||
|
@ -3428,7 +3431,8 @@ FurnaceGUI::FurnaceGUI():
|
|||
openSampleResampleOpt(false),
|
||||
openSampleAmplifyOpt(false),
|
||||
openSampleSilenceOpt(false),
|
||||
openSampleFilterOpt(false) {
|
||||
openSampleFilterOpt(false),
|
||||
oscTotal(0) {
|
||||
// value keys
|
||||
valueKeys[SDLK_0]=0;
|
||||
valueKeys[SDLK_1]=1;
|
||||
|
@ -3469,4 +3473,5 @@ FurnaceGUI::FurnaceGUI():
|
|||
memset(patChanX,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(oscValues,0,sizeof(float)*512);
|
||||
}
|
||||
|
|
|
@ -976,6 +976,10 @@ class FurnaceGUI {
|
|||
size_t sampleClipboardLen;
|
||||
bool openSampleResizeOpt, openSampleResampleOpt, openSampleAmplifyOpt, openSampleSilenceOpt, openSampleFilterOpt;
|
||||
|
||||
// oscilloscope
|
||||
int oscTotal;
|
||||
float oscValues[512];
|
||||
|
||||
// visualizer
|
||||
float keyHit[DIV_MAX_CHANS];
|
||||
int lastIns[DIV_MAX_CHANS];
|
||||
|
@ -996,6 +1000,8 @@ class FurnaceGUI {
|
|||
void updateWindowTitle();
|
||||
void prepareLayout();
|
||||
|
||||
void readOsc();
|
||||
|
||||
float calcBPM(int s1, int s2, float hz);
|
||||
|
||||
void patternRow(int i, bool isPlaying, float lineHeight, int chans, int ord, const DivPattern** patCache);
|
||||
|
|
|
@ -18,6 +18,50 @@
|
|||
*/
|
||||
|
||||
#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() {
|
||||
if (nextWindow==GUI_WINDOW_OSCILLOSCOPE) {
|
||||
|
@ -31,14 +75,9 @@ void FurnaceGUI::drawOsc() {
|
|||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing,ImVec2(0,0));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing,ImVec2(0,0));
|
||||
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::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::PopStyleVar(3);
|
||||
|
|
|
@ -49,17 +49,9 @@ void FurnaceGUI::drawVolMeter() {
|
|||
ImGuiStyle& style=ImGui::GetStyle();
|
||||
ImGui::ItemSize(ImVec2(4.0f,4.0f),style.FramePadding.y);
|
||||
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"))) {
|
||||
ImGui::RenderFrame(rect.Min,rect.Max,ImGui::GetColorU32(ImGuiCol_FrameBg),true,style.FrameRounding);
|
||||
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);
|
||||
if (logPeak==NAN) logPeak=0.0;
|
||||
if (logPeak<-1.0) logPeak=-1.0;
|
||||
|
|
Loading…
Reference in a new issue