From 7f2a0b355da8059971d5181d4f037ad716e823bf Mon Sep 17 00:00:00 2001 From: Paul Date: Fri, 2 Aug 2024 16:02:27 -0400 Subject: [PATCH] API cleanup; CPU and RAM levels in place (#1064) API cleanup to get theme colors directly from editor CPU and RAM levels in place. CPU is percent of time in engine::process vs seconds at sample rate. RAM is sum of bytes of samples. --- src-ui/components/HeaderRegion.cpp | 17 +++++++--- src-ui/components/HeaderRegion.h | 9 +++--- src-ui/components/SCXTEditor.cpp | 25 +++++---------- src-ui/components/SCXTEditor.h | 1 + src-ui/components/SCXTEditorMenus.cpp | 8 ++--- src-ui/components/multi/LFOPane.cpp | 10 +++--- src-ui/components/multi/MappingPane.cpp | 31 ++++++++----------- .../multi/ProcessorPaneEQsFilters.cpp | 12 +++---- src-ui/theme/ThemeApplier.h | 14 ++++++--- src/engine/engine.cpp | 11 +++++++ src/engine/engine.h | 3 ++ src/sample/sample_manager.cpp | 15 +++++++++ src/sample/sample_manager.h | 7 ++++- 13 files changed, 98 insertions(+), 65 deletions(-) diff --git a/src-ui/components/HeaderRegion.cpp b/src-ui/components/HeaderRegion.cpp index f6458f47..d7a8a656 100644 --- a/src-ui/components/HeaderRegion.cpp +++ b/src-ui/components/HeaderRegion.cpp @@ -177,11 +177,11 @@ void HeaderRegion::resized() scMenu->setBounds(b.withTrimmedLeft(1148).withWidth(24)); - cpuLabel->setBounds(b.withTrimmedLeft(979).withWidth(20).withHeight(14)); - ramLabel->setBounds(b.withTrimmedLeft(979).withWidth(20).withHeight(14).translated(0, 14)); + cpuLabel->setBounds(b.withTrimmedLeft(975).withWidth(20).withHeight(14)); + ramLabel->setBounds(b.withTrimmedLeft(975).withWidth(20).withHeight(14).translated(0, 14)); - cpuLevel->setBounds(b.withTrimmedLeft(1002).withWidth(35).withHeight(14)); - ramLevel->setBounds(b.withTrimmedLeft(1002).withWidth(35).withHeight(14).translated(0, 14)); + cpuLevel->setBounds(b.withTrimmedLeft(1000).withWidth(40).withHeight(14)); + ramLevel->setBounds(b.withTrimmedLeft(1000).withWidth(40).withHeight(14).translated(0, 14)); vuMeter->setBounds(b.withTrimmedLeft(1048).withWidth(96).withHeight(28)); } @@ -205,4 +205,13 @@ void HeaderRegion::setVULevel(float L, float R) } } +void HeaderRegion::setCPULevel(float lev) +{ + if (std::fabs(cpuLevValue - lev) > 1.5) + { + cpuLevValue = lev; + cpuLevel->setText(fmt::format("{:.0f} %", lev)); + } +} + } // namespace scxt::ui \ No newline at end of file diff --git a/src-ui/components/HeaderRegion.h b/src-ui/components/HeaderRegion.h index 4aceb6d6..c4f199d7 100644 --- a/src-ui/components/HeaderRegion.h +++ b/src-ui/components/HeaderRegion.h @@ -79,17 +79,18 @@ struct HeaderRegion : juce::Component, HasEditor float memUsageInMegabytes{0.f}; void setMemUsage(float m) { -#if MAC if (m != memUsageInMegabytes) { memUsageInMegabytes = m; - repaint(); + ramLevel->setText(fmt::format("{:.0f} MB", m)); } -#endif } - float vuLevel[2]; + float vuLevel[2]{0, 0}; void setVULevel(float L, float R); + + float cpuLevValue{-100}; + void setCPULevel(float); }; } // namespace scxt::ui diff --git a/src-ui/components/SCXTEditor.cpp b/src-ui/components/SCXTEditor.cpp index 28eba236..d93122eb 100644 --- a/src-ui/components/SCXTEditor.cpp +++ b/src-ui/components/SCXTEditor.cpp @@ -232,30 +232,14 @@ void SCXTEditor::idle() headerRegion->setVULevel(sharedUiMemoryState.busVULevels[0][0], sharedUiMemoryState.busVULevels[0][1]); + headerRegion->setCPULevel((double)sharedUiMemoryState.cpuLevel); if (mixerScreen->isVisible()) { mixerScreen->setVULevelForBusses(sharedUiMemoryState.busVULevels); } -#if MAC - struct task_basic_info t_info; - mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; - - if (KERN_SUCCESS == - task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count)) - { - auto pmm = (1.f * t_info.resident_size) / 1024 / 1024; - if (std::fabs(pmm - lastProcessMemoryInMegabytes) > 0.1) - { - lastProcessMemoryInMegabytes = pmm; - // SCLOG("MEM: macOS Memory Stats: res=" << lastProcessMemoryInMegabytes << " Mb"); - headerRegion->setMemUsage(lastProcessMemoryInMegabytes); - } - } - - headerRegion->repaint(); -#endif + headerRegion->setMemUsage((float)std::round(sampleManager.sampleMemoryInBytes / 1024 / 1024)); } void SCXTEditor::drainCallbackQueue() @@ -376,4 +360,9 @@ void SCXTEditor::configureHasDiscreteMenuBuilder( int16_t SCXTEditor::getSelectedPart() const { return selectedPart; } +juce::Colour SCXTEditor::themeColor(scxt::ui::theme::ColorMap::Colors c, float alpha) +{ + return themeApplier.colors->get(c, alpha); +} + } // namespace scxt::ui diff --git a/src-ui/components/SCXTEditor.h b/src-ui/components/SCXTEditor.h index 9e71e258..a7ae8b0a 100644 --- a/src-ui/components/SCXTEditor.h +++ b/src-ui/components/SCXTEditor.h @@ -103,6 +103,7 @@ struct SCXTEditor : sst::jucegui::components::WindowPanel, juce::DragAndDropCont * This is an object responsible for theme and color management */ theme::ThemeApplier themeApplier; + juce::Colour themeColor(scxt::ui::theme::ColorMap::Colors, float alpha = 1.f); sst::basic_blocks::dsp::RNG rng; diff --git a/src-ui/components/SCXTEditorMenus.cpp b/src-ui/components/SCXTEditorMenus.cpp index 783af245..7b556456 100644 --- a/src-ui/components/SCXTEditorMenus.cpp +++ b/src-ui/components/SCXTEditorMenus.cpp @@ -204,7 +204,7 @@ void SCXTEditor::addUIThemesMenu(juce::PopupMenu &p, bool addTitle) {theme::ColorMap::HICONTRAST_DARK, "High Contrast Dark"}, {theme::ColorMap::TEST, "Test Colors"}, }; - auto cid = themeApplier.colorMap()->myId; + auto cid = themeApplier.colors->myId; for (const auto &[mo, d] : maps) { p.addItem(d, true, cid == mo, [m = mo, w = juce::Component::SafePointer(this)]() { @@ -223,13 +223,13 @@ void SCXTEditor::addUIThemesMenu(juce::PopupMenu &p, bool addTitle) } p.addSeparator(); - auto knobsOn = themeApplier.colorMap()->hasKnobs; + auto knobsOn = themeApplier.colors->hasKnobs; p.addItem("Use Knob Bodies", true, knobsOn, [w = juce::Component::SafePointer(this)]() { if (w) { - w->themeApplier.colorMap()->hasKnobs = !w->themeApplier.colorMap()->hasKnobs; + w->themeApplier.colors->hasKnobs = !w->themeApplier.colors->hasKnobs; w->defaultsProvider.updateUserDefaultValue(infrastructure::DefaultKeys::showKnobs, - w->themeApplier.colorMap()->hasKnobs); + w->themeApplier.colors->hasKnobs); w->themeApplier.recolorStylesheet(w->style()); w->setStyle(w->style()); diff --git a/src-ui/components/multi/LFOPane.cpp b/src-ui/components/multi/LFOPane.cpp index d47e4cbe..649c0dd5 100644 --- a/src-ui/components/multi/LFOPane.cpp +++ b/src-ui/components/multi/LFOPane.cpp @@ -71,11 +71,11 @@ struct StepLFOPane : juce::Component, HasEditor if (!parent) return; - auto &cmap = *parent->editor->themeApplier.colorMap(); - auto bg = cmap.get(theme::ColorMap::bg_2); - auto bgq = cmap.get(theme::ColorMap::accent_2a_alpha_a); - auto boxc = cmap.get(theme::ColorMap::generic_content_low); - auto valc = cmap.get(theme::ColorMap::accent_2a); + auto *ed = parent->editor; + auto bg = ed->themeColor(theme::ColorMap::bg_2); + auto bgq = ed->themeColor(theme::ColorMap::accent_2a_alpha_a); + auto boxc = ed->themeColor(theme::ColorMap::generic_content_low); + auto valc = ed->themeColor(theme::ColorMap::accent_2a); auto valhovc = valc.brighter(0.1); auto hanc = valhovc; diff --git a/src-ui/components/multi/MappingPane.cpp b/src-ui/components/multi/MappingPane.cpp index 02b2504b..a7b88226 100644 --- a/src-ui/components/multi/MappingPane.cpp +++ b/src-ui/components/multi/MappingPane.cpp @@ -817,7 +817,7 @@ void Keyboard::paint(juce::Graphics &g) g.fillRect(kr); } - auto selZoneColor = editor->themeApplier.colorMap()->get(theme::ColorMap::accent_1b); + auto selZoneColor = editor->themeColor(theme::ColorMap::accent_1b); if (i == display->mappingView.rootKey) { g.setColour(selZoneColor); @@ -846,10 +846,10 @@ void Keyboard::paint(juce::Graphics &g) juce::Justification::centredLeft, 1); glyphs.createPath(textPath); - g.setColour(editor->themeApplier.colorMap()->get(theme::ColorMap::bg_1)); + g.setColour(editor->themeColor(theme::ColorMap::bg_1)); juce::PathStrokeType strokeType(2.5f); g.strokePath(textPath, strokeType); - g.setColour(editor->themeApplier.colorMap()->get(theme::ColorMap::generic_content_highest)); + g.setColour(editor->themeColor(theme::ColorMap::generic_content_highest)); g.fillPath(textPath); } } @@ -1379,8 +1379,7 @@ void MappingZones::paint(juce::Graphics &g) auto lb = getLocalBounds().toFloat().withTrimmedTop(1.f); auto displayRegion = lb.withTrimmedBottom(Keyboard::keyboardHeight); - auto dashCol = - editor->themeApplier.colorMap()->get(theme::ColorMap::generic_content_low, 0.4f); + auto dashCol = editor->themeColor(theme::ColorMap::generic_content_low, 0.4f); g.setColour(dashCol); g.drawVerticalLine(lb.getX() + 1, lb.getY(), lb.getY() + lb.getHeight()); g.drawVerticalLine(lb.getX() + lb.getWidth() - 1, lb.getY(), lb.getY() + lb.getHeight()); @@ -1450,10 +1449,9 @@ void MappingZones::paint(juce::Graphics &g) auto r = rectangleForZone(z.second); - auto nonSelZoneColor = - editor->themeApplier.colorMap()->get(theme::ColorMap::generic_content_medium); + auto nonSelZoneColor = editor->themeColor(theme::ColorMap::generic_content_medium); if (drawSelected) - nonSelZoneColor = editor->themeApplier.colorMap()->get(theme::ColorMap::accent_1a); + nonSelZoneColor = editor->themeColor(theme::ColorMap::accent_1a); g.setColour(nonSelZoneColor.withAlpha(drawSelected ? 0.5f : 0.2f)); g.fillRect(r); g.setColour(nonSelZoneColor); @@ -1478,7 +1476,7 @@ void MappingZones::paint(juce::Graphics &g) const auto &[kb, vel, name] = z.second; - auto selZoneColor = editor->themeApplier.colorMap()->get(theme::ColorMap::accent_1b); + auto selZoneColor = editor->themeColor(theme::ColorMap::accent_1b); auto c1{selZoneColor.withAlpha(0.f)}; auto c2{selZoneColor.withAlpha(0.5f)}; @@ -1652,8 +1650,7 @@ void MappingZones::paint(juce::Graphics &g) g.setColour(selZoneColor); g.drawRect(r, 2.f); - g.setColour( - editor->themeApplier.colorMap()->get(theme::ColorMap::generic_content_highest)); + g.setColour(editor->themeColor(theme::ColorMap::generic_content_highest)); g.setFont(editor->themeApplier.interMediumFor(12)); g.drawText(std::get<2>(z.second), r.reduced(5, 3), juce::Justification::topLeft); @@ -1666,7 +1663,7 @@ void MappingZones::paint(juce::Graphics &g) { auto rr = rootAndRangeForPosition(display->currentDragPoint); auto rb = rectangleForRange(rr[1], rr[2], 0, 127); - g.setColour(editor->themeApplier.colorMap()->get(theme::ColorMap::accent_1a, 0.4f)); + g.setColour(editor->themeColor(theme::ColorMap::accent_1a, 0.4f)); g.fillRect(rb); } @@ -1683,15 +1680,13 @@ void MappingZones::paint(juce::Graphics &g) auto rz = rectangleForZone(z.second); if (rz.intersects(r)) { - g.setColour(editor->themeApplier.colorMap()->get( - theme::ColorMap::generic_content_high)); + g.setColour(editor->themeColor(theme::ColorMap::generic_content_high)); g.drawRect(rz, 2); } } - g.setColour( - editor->themeApplier.colorMap()->get(theme::ColorMap::generic_content_highest)); + g.setColour(editor->themeColor(theme::ColorMap::generic_content_highest)); auto p = juce::Path(); p.addRectangle(r); @@ -1702,7 +1697,7 @@ void MappingZones::paint(juce::Graphics &g) } else { - auto col = editor->themeApplier.colorMap()->get(theme::ColorMap::accent_2a); + auto col = editor->themeColor(theme::ColorMap::accent_2a); g.setColour(col.withAlpha(0.3f)); g.fillRect(r); g.setColour(col); @@ -2924,7 +2919,7 @@ struct MacroDisplay : HasEditor, juce::Component MacroDisplay(SCXTEditor *e) : HasEditor(e) {} void paint(juce::Graphics &g) { - g.setColour(editor->themeApplier.colorMap()->get(theme::ColorMap::warning_1a)); + g.setColour(editor->themeColor(theme::ColorMap::warning_1a)); g.setFont(editor->themeApplier.interMediumFor(25)); g.drawText("Macro Region Coming Soon", getLocalBounds(), juce::Justification::centred); } diff --git a/src-ui/components/multi/ProcessorPaneEQsFilters.cpp b/src-ui/components/multi/ProcessorPaneEQsFilters.cpp index 6e67b0c6..2392a75d 100644 --- a/src-ui/components/multi/ProcessorPaneEQsFilters.cpp +++ b/src-ui/components/multi/ProcessorPaneEQsFilters.cpp @@ -206,7 +206,7 @@ template struct EqDisplaySupport : EqDisplayBase if (!curvesBuilt) rebuildCurves(); - auto &colorMap = mProcessorPane.editor->themeApplier.colorMap(); + auto ed = mProcessorPane.editor; auto c2p = [this](auto &c) { auto p = juce::Path(); @@ -227,23 +227,23 @@ template struct EqDisplaySupport : EqDisplayBase return p; }; - g.setColour(colorMap->get(theme::ColorMap::bg_1)); + g.setColour(ed->themeColor(theme::ColorMap::bg_1)); g.fillRect(getLocalBounds()); - g.setColour(colorMap->get(theme::ColorMap::panel_outline_2)); + g.setColour(ed->themeColor(theme::ColorMap::panel_outline_2)); g.drawRect(getLocalBounds()); - g.setColour(colorMap->get(theme::ColorMap::accent_2b)); + g.setColour(ed->themeColor(theme::ColorMap::accent_2b)); g.drawLine(0, getHeight() * centerPoint, getWidth(), getHeight() * centerPoint); for (int i = 0; i < nSub; ++i) { auto p = c2p(curves[i + 1]); - g.setColour(colorMap->get(theme::ColorMap::accent_1b).withAlpha(0.7f)); + g.setColour(ed->themeColor(theme::ColorMap::accent_1b).withAlpha(0.7f)); g.strokePath(p, juce::PathStrokeType(1)); } auto p = c2p(curves[0]); - g.setColour(colorMap->get(theme::ColorMap::accent_1a)); + g.setColour(ed->themeColor(theme::ColorMap::accent_1a)); g.strokePath(p, juce::PathStrokeType(3)); } }; diff --git a/src-ui/theme/ThemeApplier.h b/src-ui/theme/ThemeApplier.h index 53e05dab..25d7572a 100644 --- a/src-ui/theme/ThemeApplier.h +++ b/src-ui/theme/ThemeApplier.h @@ -36,7 +36,10 @@ #include "ColorMap.h" -namespace scxt::ui::theme +namespace scxt::ui +{ +struct SCXTEditor; +namespace theme { struct ThemeApplier { @@ -59,12 +62,13 @@ struct ThemeApplier // Some utilities to move single items void setLabelToHighlight(sst::jucegui::style::StyleConsumer *); - const std::unique_ptr &colorMap() { return colors; } - juce::Font interMediumFor(int ht) const; - protected: + friend scxt::ui::SCXTEditor; + + private: std::unique_ptr colors; }; -} // namespace scxt::ui::theme +} // namespace theme +} // namespace scxt::ui #endif // SHORTCIRCUITXT_THEMEAPPLIER_H diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index aabb41e2..221d54ef 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -236,6 +236,8 @@ void Engine::stopAllSounds() bool Engine::processAudio() { + auto processingStartTime = std::chrono::high_resolution_clock::now(); + namespace mech = sst::basic_blocks::mechanics; #if BUILD_IS_DEBUG messageController->threadingChecker.registerAsAudioThread(); @@ -354,6 +356,15 @@ bool Engine::processAudio() } lastUpdateVoiceDisplayState++; + auto processingEndTime = std::chrono::high_resolution_clock::now(); + + auto time_span = std::chrono::duration_cast>(processingEndTime - + processingStartTime); + // auto maxtime = blockSize * sampleRateInv; + // auto pct = time_span.count / maxtime; + // or... + auto pct = time_span.count() * sampleRate * blockSizeInv * 100.0; + sharedUIMemoryState.cpuLevel = pct; return true; } diff --git a/src/engine/engine.h b/src/engine/engine.h index 914e4eca..d45b8949 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -322,6 +322,9 @@ struct Engine : MoveableOnly, SampleRateSupport std::atomic tsnum, tsden; std::atomic hostpos, timepos; } transportDisplay; + + std::atomic cpuLevel{0}; + std::atomic ramUsage{0}; } sharedUIMemoryState; /* When we actually unstream an entire engine we want to know if we are doing diff --git a/src/sample/sample_manager.cpp b/src/sample/sample_manager.cpp index 7db642de..b626f8d3 100644 --- a/src/sample/sample_manager.cpp +++ b/src/sample/sample_manager.cpp @@ -109,6 +109,7 @@ std::optional SampleManager::loadSampleByPathToID(const fs::path &p, c } samples[sp->id] = sp; + updateSampleMemory(); return sp->id; } @@ -159,6 +160,7 @@ std::optional SampleManager::loadSampleFromSF2ToID(const fs::path &p, return {}; samples[sp->id] = sp; + updateSampleMemory(); return sp->id; } @@ -173,6 +175,7 @@ std::optional SampleManager::setupSampleFromMultifile(const fs::path & sp->region = idx; sp->mFileName = p; samples[sp->id] = sp; + updateSampleMemory(); return sp->id; } @@ -197,6 +200,7 @@ std::optional SampleManager::loadSampleFromMultiSample(const fs::path sp->region = idx; sp->mFileName = p; samples[sp->id] = sp; + updateSampleMemory(); free(data); @@ -226,5 +230,16 @@ void SampleManager::purgeUnreferencedSamples() { SCLOG_WFUNC("PostPurge : Purged " << (preSize - samples.size())); } + updateSampleMemory(); +} + +void SampleManager::updateSampleMemory() +{ + uint64_t res = 0; + for (const auto &[id, smp] : samples) + { + res += smp->sample_length * smp->channels * (smp->bitDepth == Sample::BD_I16 ? 4 : 8); + } + sampleMemoryInBytes = res; } } // namespace scxt::sample diff --git a/src/sample/sample_manager.h b/src/sample/sample_manager.h index d72e3589..728f3169 100644 --- a/src/sample/sample_manager.h +++ b/src/sample/sample_manager.h @@ -123,15 +123,20 @@ struct SampleManager : MoveableOnly samples.clear(); sf2FilesByPath.clear(); streamingVersion = 0x2112'01'01; + updateSampleMemory(); } std::vector missingList; void resetMissingList() { missingList.clear(); } uint64_t streamingVersion{0x2112'01'01}; // see comment in patch.h - std::unordered_map> samples; + + std::atomic sampleMemoryInBytes{0}; private: + void updateSampleMemory(); + + std::unordered_map> samples; std::unordered_map, std::unique_ptr>> sf2FilesByPath;