GUI: add a volume meter

This commit is contained in:
tildearrow 2022-01-29 18:56:08 -05:00
parent adbe70fa05
commit de5327d89a
2 changed files with 112 additions and 2 deletions

View file

@ -1,3 +1,4 @@
#include <cmath>
#define _USE_MATH_DEFINES
#include "gui.h"
#include "debug.h"
@ -2019,6 +2020,89 @@ void FurnaceGUI::drawOsc() {
ImGui::End();
}
void FurnaceGUI::drawVolMeter() {
if (!volMeterOpen) return;
if (--isClipping<0) isClipping=0;
ImGui::SetNextWindowSizeConstraints(ImVec2(6.0f*dpiScale,6.0f*dpiScale),ImVec2(scrW*dpiScale,scrH*dpiScale));
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));
if (ImGui::Begin("Volume Meter",&volMeterOpen)) {
ImDrawList* dl=ImGui::GetWindowDrawList();
bool aspectRatio=(ImGui::GetWindowSize().x/ImGui::GetWindowSize().y)>1.0;
ImVec2 minArea=ImVec2(
ImGui::GetWindowPos().x+ImGui::GetCursorPos().x,
ImGui::GetWindowPos().y+ImGui::GetCursorPos().y
);
ImVec2 maxArea=ImVec2(
ImGui::GetWindowPos().x+ImGui::GetCursorPos().x+ImGui::GetContentRegionAvail().x,
ImGui::GetWindowPos().y+ImGui::GetCursorPos().y+ImGui::GetContentRegionAvail().y
);
ImRect rect=ImRect(minArea,maxArea);
ImGuiStyle& style=ImGui::GetStyle();
ImGui::ItemSize(ImVec2(4.0f,4.0f),style.FramePadding.y);
ImU32 lowColor=ImGui::GetColorU32(uiColors[GUI_COLOR_VOLMETER_LOW]);
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]*=0.95;
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;
if (logPeak>0.0) {
isClipping=8;
logPeak=0.0;
}
logPeak+=1.0;
ImU32 highColor=ImGui::GetColorU32(
ImLerp(uiColors[GUI_COLOR_VOLMETER_LOW],uiColors[GUI_COLOR_VOLMETER_HIGH],logPeak)
);
ImRect s;
if (aspectRatio) {
s=ImRect(
ImLerp(rect.Min,rect.Max,ImVec2(0,float(i)*0.5)),
ImLerp(rect.Min,rect.Max,ImVec2(logPeak,float(i+1)*0.5))
);
if (i==0) s.Max.y-=dpiScale;
if (isClipping) {
dl->AddRectFilled(s.Min,s.Max,ImGui::GetColorU32(uiColors[GUI_COLOR_VOLMETER_PEAK]));
} else {
dl->AddRectFilledMultiColor(s.Min,s.Max,lowColor,highColor,highColor,lowColor);
}
} else {
s=ImRect(
ImLerp(rect.Min,rect.Max,ImVec2(float(i)*0.5,1.0-logPeak)),
ImLerp(rect.Min,rect.Max,ImVec2(float(i+1)*0.5,1.0))
);
if (i==0) s.Max.x-=dpiScale;
if (isClipping) {
dl->AddRectFilled(s.Min,s.Max,ImGui::GetColorU32(uiColors[GUI_COLOR_VOLMETER_PEAK]));
} else {
dl->AddRectFilledMultiColor(s.Min,s.Max,highColor,highColor,lowColor,lowColor);
}
}
}
if (ImGui::IsItemHovered()) {
if (aspectRatio) {
ImGui::SetTooltip("%.1fdB",36*((ImGui::GetMousePos().x-ImGui::GetItemRectMin().x)/(rect.Max.x-rect.Min.x)-1.0));
} else {
ImGui::SetTooltip("%.1fdB",-(36+36*((ImGui::GetMousePos().y-ImGui::GetItemRectMin().y)/(rect.Max.y-rect.Min.y)-1.0)));
}
}
}
}
ImGui::PopStyleVar(4);
ImGui::End();
}
void FurnaceGUI::drawPattern() {
if (!patternOpen) return;
if (e->isPlaying() && followPattern) cursor.y=oldRow;
@ -2721,6 +2805,12 @@ void FurnaceGUI::drawSettings() {
UI_COLOR_CONFIG(GUI_COLOR_PLAYBACK_STAT,"Playback status");
ImGui::TreePop();
}
if (ImGui::TreeNode("Volume Meter")) {
UI_COLOR_CONFIG(GUI_COLOR_VOLMETER_LOW,"Low");
UI_COLOR_CONFIG(GUI_COLOR_VOLMETER_HIGH,"High");
UI_COLOR_CONFIG(GUI_COLOR_VOLMETER_PEAK,"Clip");
ImGui::TreePop();
}
if (ImGui::TreeNode("Macro Editor")) {
UI_COLOR_CONFIG(GUI_COLOR_MACRO_VOLUME,"Volume");
UI_COLOR_CONFIG(GUI_COLOR_MACRO_PITCH,"Pitch");
@ -2865,6 +2955,9 @@ void FurnaceGUI::commitSettings() {
PUT_UI_COLOR(GUI_COLOR_ACCENT_SECONDARY);
PUT_UI_COLOR(GUI_COLOR_EDITING);
PUT_UI_COLOR(GUI_COLOR_SONG_LOOP);
PUT_UI_COLOR(GUI_COLOR_VOLMETER_LOW);
PUT_UI_COLOR(GUI_COLOR_VOLMETER_HIGH);
PUT_UI_COLOR(GUI_COLOR_VOLMETER_PEAK);
PUT_UI_COLOR(GUI_COLOR_MACRO_VOLUME);
PUT_UI_COLOR(GUI_COLOR_MACRO_PITCH);
PUT_UI_COLOR(GUI_COLOR_MACRO_OTHER);
@ -4815,6 +4908,7 @@ bool FurnaceGUI::loop() {
if (ImGui::MenuItem("pattern")) patternOpen=!patternOpen;
if (ImGui::MenuItem("mixer")) mixerOpen=!mixerOpen;
if (ImGui::MenuItem("oscilloscope")) oscOpen=!oscOpen;
if (ImGui::MenuItem("volume meter")) volMeterOpen=!volMeterOpen;
ImGui::EndMenu();
}
if (ImGui::BeginMenu("help")) {
@ -4852,6 +4946,7 @@ bool FurnaceGUI::loop() {
drawSampleEdit();
drawMixer();
drawOsc();
drawVolMeter();
drawPattern();
drawSettings();
drawDebug();
@ -5151,6 +5246,9 @@ void FurnaceGUI::applyUISettings() {
GET_UI_COLOR(GUI_COLOR_ACCENT_SECONDARY,ImVec4(0.26f,0.59f,0.98f,1.0f));
GET_UI_COLOR(GUI_COLOR_EDITING,ImVec4(0.2f,0.1f,0.1f,1.0f));
GET_UI_COLOR(GUI_COLOR_SONG_LOOP,ImVec4(0.3f,0.5f,0.8f,0.4f));
GET_UI_COLOR(GUI_COLOR_VOLMETER_LOW,ImVec4(0.2f,0.6f,0.2f,1.0f));
GET_UI_COLOR(GUI_COLOR_VOLMETER_HIGH,ImVec4(1.0f,0.9f,0.2f,1.0f));
GET_UI_COLOR(GUI_COLOR_VOLMETER_PEAK,ImVec4(1.0f,0.1f,0.1f,1.0f));
GET_UI_COLOR(GUI_COLOR_MACRO_VOLUME,ImVec4(0.2f,1.0f,0.0f,1.0f));
GET_UI_COLOR(GUI_COLOR_MACRO_PITCH,ImVec4(1.0f,0.8f,0.0f,1.0f));
GET_UI_COLOR(GUI_COLOR_MACRO_OTHER,ImVec4(0.0f,0.9f,1.0f,1.0f));
@ -5348,6 +5446,7 @@ bool FurnaceGUI::init() {
settingsOpen=e->getConfBool("settingsOpen",false);
mixerOpen=e->getConfBool("mixerOpen",false);
oscOpen=e->getConfBool("oscOpen",true);
volMeterOpen=e->getConfBool("volMeterOpen",true);
syncSettings();
@ -5452,6 +5551,7 @@ bool FurnaceGUI::finish() {
e->setConf("settingsOpen",settingsOpen);
e->setConf("mixerOpen",mixerOpen);
e->setConf("oscOpen",oscOpen);
e->setConf("volMeterOpen",volMeterOpen);
// commit last window size
e->setConf("lastWindowWidth",scrW);
@ -5497,6 +5597,7 @@ FurnaceGUI::FurnaceGUI():
loopOrder(-1),
loopRow(-1),
loopEnd(-1),
isClipping(0),
editControlsOpen(true),
ordersOpen(true),
insListOpen(true),
@ -5512,6 +5613,7 @@ FurnaceGUI::FurnaceGUI():
mixerOpen(false),
debugOpen(false),
oscOpen(true),
volMeterOpen(true),
selecting(false),
curNibble(false),
orderNibble(false),
@ -5607,4 +5709,7 @@ FurnaceGUI::FurnaceGUI():
valueKeys[SDLK_f]=15;
memset(willExport,1,32*sizeof(bool));
peak[0]=0;
peak[1]=0;
}

View file

@ -17,6 +17,9 @@ enum FurnaceGUIColors {
GUI_COLOR_ACCENT_SECONDARY,
GUI_COLOR_EDITING,
GUI_COLOR_SONG_LOOP,
GUI_COLOR_VOLMETER_LOW,
GUI_COLOR_VOLMETER_HIGH,
GUI_COLOR_VOLMETER_PEAK,
GUI_COLOR_MACRO_VOLUME,
GUI_COLOR_MACRO_PITCH,
GUI_COLOR_MACRO_OTHER,
@ -241,13 +244,14 @@ class FurnaceGUI {
char finalLayoutPath[4096];
int curIns, curWave, curSample, curOctave, oldRow, oldOrder, oldOrder1, editStep, exportLoops, soloChan, soloTimeout, orderEditMode, orderCursor;
int loopOrder, loopRow, loopEnd;
int loopOrder, loopRow, loopEnd, isClipping;
bool editControlsOpen, ordersOpen, insListOpen, songInfoOpen, patternOpen, insEditOpen;
bool waveListOpen, waveEditOpen, sampleListOpen, sampleEditOpen, aboutOpen, settingsOpen;
bool mixerOpen, debugOpen, oscOpen;
bool mixerOpen, debugOpen, oscOpen, volMeterOpen;
SelectionPoint selStart, selEnd, cursor;
bool selecting, curNibble, orderNibble, extraChannelButtons, followOrders, followPattern, changeAllOrders;
FurnaceGUIWindows curWindow;
float peak[2];
struct ActiveNote {
int chan;
@ -324,6 +328,7 @@ class FurnaceGUI {
void drawSampleEdit();
void drawMixer();
void drawOsc();
void drawVolMeter();
void drawAbout();
void drawSettings();
void drawDebug();