mixer: per-chp peak meters, fix almost every ui issue:
- fix wrong verticaltext clipping - fix verticaltext overflow centering - add hscroll to mixer
This commit is contained in:
parent
76b29fa31c
commit
2108cffec2
4 changed files with 62 additions and 11 deletions
|
|
@ -698,6 +698,8 @@ class DivEngine {
|
|||
int lastNBIns, lastNBOuts, lastNBSize;
|
||||
std::atomic<size_t> processTime;
|
||||
|
||||
float chipPeak[DIV_MAX_CHIPS][DIV_MAX_OUTPUTS];
|
||||
|
||||
void runExportThread();
|
||||
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
|
||||
DivInstrument* getIns(int index, DivInstrumentType fallbackType=DIV_INS_FM);
|
||||
|
|
@ -1542,6 +1544,7 @@ class DivEngine {
|
|||
memset(walked,0,8192);
|
||||
memset(oscBuf,0,DIV_MAX_OUTPUTS*(sizeof(float*)));
|
||||
memset(exportChannelMask,1,DIV_MAX_CHANS*sizeof(bool));
|
||||
memset(chipPeak,0,DIV_MAX_CHIPS*DIV_MAX_OUTPUTS*sizeof(float));
|
||||
|
||||
for (int i=0; i<DIV_MAX_CHIP_DEFS; i++) {
|
||||
sysFileMapFur[i]=DIV_SYSTEM_NULL;
|
||||
|
|
|
|||
|
|
@ -2706,6 +2706,36 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
}
|
||||
oscSize=size;
|
||||
|
||||
// get per-chip peaks
|
||||
float decay=2.f*size/got.rate;
|
||||
for (int i=0; i<song.systemLen; i++) {
|
||||
DivDispatch* disp=disCont[i].dispatch;
|
||||
for (int j=0; j<disp->getOutputCount(); j++) {
|
||||
chipPeak[i][j]*=1.0-decay;
|
||||
float peak=chipPeak[i][j];
|
||||
for (unsigned int k=0; k<size; k++) {
|
||||
float out=disCont[i].bbOut[j][k]*song.systemVol[i]*disp->getPostAmp()/32768.0f; // TODO: PARSE PANNING, FRONT/REAR AND PATCHBAY
|
||||
// switch (j) {
|
||||
// case 0:
|
||||
// out*=MIN(1.0f,1.0f-song.systemPan[i])*MIN(1.0f,1.0f+song.systemPanFR[i]);
|
||||
// break;
|
||||
// case 1:
|
||||
// out*=MIN(1.0f,1.0f+song.systemPan[i])*MIN(1.0f,1.0f+song.systemPanFR[i]);
|
||||
// break;
|
||||
// case 2:
|
||||
// out*=MIN(1.0f,1.0f-song.systemPan[i])*MIN(1.0f,1.0f-song.systemPanFR[i]);
|
||||
// break;
|
||||
// case 3:
|
||||
// out*=MIN(1.0f,1.0f+song.systemPan[i])*MIN(1.0f,1.0f-song.systemPanFR[i]);
|
||||
// break;
|
||||
// default: break;
|
||||
// }
|
||||
if (out>peak) peak=out;
|
||||
}
|
||||
chipPeak[i][j]+=(peak-chipPeak[i][j])*0.9;
|
||||
}
|
||||
}
|
||||
|
||||
// force mono audio (if enabled)
|
||||
if (forceMono && outChans>1) {
|
||||
for (size_t i=0; i<size; i++) {
|
||||
|
|
|
|||
|
|
@ -451,14 +451,14 @@ void FurnaceGUI::VerticalText(const char* fmt, ...) {
|
|||
ImVec2 size=ImGui::CalcTextSize(text);
|
||||
dl->AddText(pos, ImGui::GetColorU32(ImGuiCol_Text), text);
|
||||
vtxEnd=dl->_VtxCurrentIdx;
|
||||
ImGui::ShadeVertsTransformPos(dl, vtxBegin, vtxEnd, pos+ImVec2(size.x,0), 0, -1, pos);
|
||||
ImGui::ShadeVertsTransformPos(dl, vtxBegin, vtxEnd, pos+ImVec2(size.x,0), 0, -1, ImGui::GetCursorScreenPos());
|
||||
ImGui::Dummy(ImVec2(size.y,size.x));
|
||||
}
|
||||
|
||||
void FurnaceGUI::VerticalText(float maxSize, bool centered, const char* fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
ImVec2 pos=ImGui::GetCursorScreenPos();
|
||||
ImVec2 pos=ImGui::GetWindowPos();
|
||||
ImDrawList* dl=ImGui::GetWindowDrawList();
|
||||
int vtxBegin, vtxEnd;
|
||||
vtxBegin=dl->_VtxCurrentIdx;
|
||||
|
|
@ -466,10 +466,12 @@ void FurnaceGUI::VerticalText(float maxSize, bool centered, const char* fmt, ...
|
|||
vsnprintf(text, 4096, fmt, args);
|
||||
const char* textEol=ImGui::FindRenderedTextEnd(text);
|
||||
ImVec2 size=ImGui::CalcTextSize(text);
|
||||
dl->PushClipRect(pos,pos+ImGui::GetWindowSize());
|
||||
ImGui::RenderTextEllipsis(dl,pos,pos+ImVec2(maxSize,ImGui::GetFontSize()),maxSize,text,textEol,&size);
|
||||
dl->PopClipRect();
|
||||
vtxEnd=dl->_VtxCurrentIdx;
|
||||
float ySize=(size.x>maxSize)?maxSize:size.x;
|
||||
ImGui::ShadeVertsTransformPos(dl, vtxBegin, vtxEnd, pos, 0, -1, pos+ImVec2(0,ySize+(centered?(maxSize-size.x)/2.0f:0)));
|
||||
ImGui::ShadeVertsTransformPos(dl, vtxBegin, vtxEnd, pos, 0, -1, ImGui::GetCursorScreenPos()+ImVec2(0,(size.x+ySize)/2+(centered?(maxSize-size.x)/2.0f:0)));
|
||||
ImGui::Dummy(ImVec2(size.y,centered?maxSize:ySize));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -229,16 +229,34 @@ void FurnaceGUI::drawMixer() {
|
|||
float maxY=ImGui::GetContentRegionAvail().y;
|
||||
VerticalText(maxY, true,_("Master Volume"));
|
||||
ImGui::SameLine();
|
||||
ImVec2 pos=ImGui::GetCursorScreenPos();
|
||||
drawVolMeterInternal(ImGui::GetWindowDrawList(), ImRect(pos,pos+ImVec2(40*dpiScale,maxY)),peak,e->getAudioDescGot().outChans,false);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg,0);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive,0);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered,127<<IM_COL32_A_SHIFT);
|
||||
if (ImGui::VSliderFloat("##mixerMaster",ImVec2(40*dpiScale,maxY),&e->song.masterVol,0,3,"%.2fx")) {
|
||||
if (e->song.masterVol<0) e->song.masterVol=0;
|
||||
if (e->song.masterVol>3) e->song.masterVol=3;
|
||||
MARK_MODIFIED;
|
||||
} rightClickable
|
||||
ImGui::PopStyleColor(3);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::BeginChild("##mixerPerChipContainer")) {
|
||||
const float childWidth=60*dpiScale;
|
||||
|
||||
const float itemWidth=60*dpiScale;
|
||||
// figure out if we need to cut the height for the scrollbar
|
||||
float calcWidth=(itemWidth+1.5f*ImGui::GetStyle().FramePadding.x+4*ImGui::GetStyle().FramePadding.x+dpiScale)*e->song.systemLen;
|
||||
float realwidth=ImGui::GetWindowWidth()-ImGui::GetCursorPosX();
|
||||
if (calcWidth>realwidth) maxY-=ImGui::GetStyle().ScrollbarSize;
|
||||
if (ImGui::BeginChild("##mixerPerChipContainer", ImVec2(0,0),0,ImGuiWindowFlags_HorizontalScrollbar)) {
|
||||
for (int i=0; i<e->song.systemLen; i++) {
|
||||
if (chipMixer(i, ImVec2(childWidth,maxY))) MARK_MODIFIED;
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(
|
||||
ImGui::GetCursorScreenPos(),
|
||||
ImGui::GetCursorScreenPos()+ImVec2(dpiScale,maxY),
|
||||
ImGui::GetColorU32(ImGuiCol_Separator)
|
||||
);
|
||||
ImGui::Dummy(ImVec2(dpiScale,maxY));
|
||||
ImGui::SameLine();
|
||||
if (chipMixer(i, ImVec2(itemWidth,maxY))) MARK_MODIFIED;
|
||||
ImGui::SameLine();
|
||||
}
|
||||
}
|
||||
|
|
@ -436,17 +454,14 @@ bool FurnaceGUI::chipMixer(int which, ImVec2 size) {
|
|||
ImGui::SameLine();
|
||||
|
||||
float vTextWidth=textHeight+2*ImGui::GetStyle().FramePadding.x;
|
||||
// TODO: per-chip per-out peak
|
||||
float volMeter[2];
|
||||
volMeter[0]=0.5;
|
||||
volMeter[1]=0.5;
|
||||
ImGui::SetCursorPos(curPos);
|
||||
ImVec2 pos=ImGui::GetCursorScreenPos();
|
||||
drawVolMeterInternal(ImGui::GetWindowDrawList(),ImRect(pos,pos+ImVec2(size.x-vTextWidth,volSliderHeight)),volMeter,2,false);
|
||||
drawVolMeterInternal(ImGui::GetWindowDrawList(),ImRect(pos,pos+ImVec2(size.x-vTextWidth,volSliderHeight)),e->chipPeak[which],e->getDispatch(which)->getOutputCount(),false);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBg,0);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgActive,0);
|
||||
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered,127<<IM_COL32_A_SHIFT);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0);
|
||||
if (ImGui::VSliderFloat("##ChipVol", ImVec2(size.x-vTextWidth,volSliderHeight), &vol, 0.0f, 2.0f)) {
|
||||
if (doInvert) {
|
||||
if (vol<0.0001) vol=0.0001;
|
||||
|
|
@ -459,6 +474,7 @@ bool FurnaceGUI::chipMixer(int which, ImVec2 size) {
|
|||
if (ImGui::IsItemHovered(ImGuiHoveredFlags_DelayShort)) {
|
||||
ImGui::SetTooltip(_("Volume"));
|
||||
}
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::PopStyleColor(3);
|
||||
|
||||
ImGui::SetNextItemWidth(size.x+1.5f*ImGui::GetStyle().FramePadding.x);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue