From 9d8ebaf71840fa9b58d26359471e128c76f31d77 Mon Sep 17 00:00:00 2001 From: Jean Pierre Cimalando Date: Wed, 12 Aug 2020 19:23:50 +0200 Subject: [PATCH] Add VST info panel --- vst/SfizzVstController.cpp | 10 +++ vst/SfizzVstController.h | 4 + vst/SfizzVstEditor.cpp | 155 +++++++++++++++++++++++++++++++++++++ vst/SfizzVstEditor.h | 8 ++ vst/SfizzVstProcessor.cpp | 24 +++++- vst/SfizzVstProcessor.h | 4 + vst/SfizzVstState.h | 9 +++ 7 files changed, 213 insertions(+), 1 deletion(-) diff --git a/vst/SfizzVstController.cpp b/vst/SfizzVstController.cpp index b8c75a10..8f13bab2 100644 --- a/vst/SfizzVstController.cpp +++ b/vst/SfizzVstController.cpp @@ -283,6 +283,16 @@ tresult SfizzVstController::notify(Vst::IMessage* message) _state.scalaFile.assign(static_cast(data), size); } + else if (!strcmp(id, "NotifiedPlayState")) { + const void* data = nullptr; + uint32 size = 0; + result = attr->getBinary("PlayState", data, size); + + if (result != kResultTrue) + return result; + + _playState = *static_cast(data); + } for (StateListener* listener : _stateListeners) listener->onStateChanged(); diff --git a/vst/SfizzVstController.h b/vst/SfizzVstController.h index 854a3722..bd363a2c 100644 --- a/vst/SfizzVstController.h +++ b/vst/SfizzVstController.h @@ -56,6 +56,9 @@ public: const SfizzUiState& getSfizzUiState() const { return _uiState; } SfizzUiState& getSfizzUiState() { return _uiState; } + const SfizzPlayState& getSfizzPlayState() const { return _playState; } + SfizzPlayState& getSfizzPlayState() { return _playState; } + void addSfizzStateListener(StateListener* listener); void removeSfizzStateListener(StateListener* listener); @@ -67,5 +70,6 @@ public: private: SfizzVstState _state; SfizzUiState _uiState; + SfizzPlayState _playState {}; std::vector _stateListeners; }; diff --git a/vst/SfizzVstEditor.cpp b/vst/SfizzVstEditor.cpp index 6b35b213..5863cdc5 100644 --- a/vst/SfizzVstEditor.cpp +++ b/vst/SfizzVstEditor.cpp @@ -508,6 +508,139 @@ void SfizzVstEditor::createFrameContents() _subPanels[kPanelTuning] = panel; } + // info panel + { + panel = new CViewContainer(bounds); + frame->addView(panel); + panel->setTransparency(true); + + CTextLabel* topLeftLabel = new CTextLabel(topLeftLabelBox, "Information"); + topLeftLabel->setFontColor(CColor(0x00, 0x00, 0x00)); + topLeftLabel->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + panel->addView(topLeftLabel); + + CRect row = topRow; + row.top += 45.0; + row.bottom += 45.0; + row.left += 20.0; + row.right -= 20.0; + + static const CCoord interRow = 20.0; + static const CCoord interColumn = 20.0; + static const int numColumns = 3; + + auto nthColumn = [&row](int colIndex) -> CRect { + CRect div = row; + CCoord columnWidth = (div.right - div.left + interColumn) / numColumns - interColumn; + div.left = div.left + colIndex * (columnWidth + interColumn); + div.right = div.left + columnWidth; + return div; + }; + + CTextLabel* label; + + label = new CTextLabel(nthColumn(0), "Curves"); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + panel->addView(label); + label = new CTextLabel(nthColumn(1), ""); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + _infoCurvesLabel = label; + panel->addView(label); + + row.top += interRow; + row.bottom += interRow; + + label = new CTextLabel(nthColumn(0), "Masters"); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + panel->addView(label); + label = new CTextLabel(nthColumn(1), ""); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + _infoMastersLabel = label; + panel->addView(label); + + row.top += interRow; + row.bottom += interRow; + + label = new CTextLabel(nthColumn(0), "Groups"); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + panel->addView(label); + label = new CTextLabel(nthColumn(1), ""); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + _infoGroupsLabel = label; + panel->addView(label); + + row.top += interRow; + row.bottom += interRow; + + label = new CTextLabel(nthColumn(0), "Regions"); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + panel->addView(label); + label = new CTextLabel(nthColumn(1), ""); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + _infoRegionsLabel = label; + panel->addView(label); + + row.top += interRow; + row.bottom += interRow; + + label = new CTextLabel(nthColumn(0), "Samples"); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + panel->addView(label); + label = new CTextLabel(nthColumn(1), ""); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + _infoSamplesLabel = label; + panel->addView(label); + + row.top += interRow; + row.bottom += interRow; + + label = new CTextLabel(nthColumn(0), "Voices"); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + panel->addView(label); + label = new CTextLabel(nthColumn(1), ""); + label->setFontColor(CColor(0x00, 0x00, 0x00)); + label->setFrameColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setBackColor(CColor(0x00, 0x00, 0x00, 0x00)); + label->setHoriAlign(kLeftText); + _infoVoicesLabel = label; + panel->addView(label); + + _subPanels[kPanelInfo] = panel; + } + // all panels for (unsigned currentPanel = 0; currentPanel < kNumPanels; ++currentPanel) { panel = _subPanels[currentPanel]; @@ -528,6 +661,7 @@ void SfizzVstEditor::createFrameContents() case kPanelGeneral: text = "File"; break; case kPanelSettings: text = "Setup"; break; case kPanelTuning: text = "Tuning"; break; + case kPanelInfo: text = "Info"; break; default: text = "?"; break; } @@ -549,7 +683,9 @@ void SfizzVstEditor::updateStateDisplay() SfizzVstController* controller = getController(); const SfizzVstState& state = controller->getSfizzState(); const SfizzUiState& uiState = controller->getSfizzUiState(); + const SfizzPlayState& playState = controller->getSfizzPlayState(); + /// updateSfzFileLabel(state.sfzFile); if (_volumeSlider) _volumeSlider->setValue(state.volume); @@ -574,6 +710,25 @@ void SfizzVstEditor::updateStateDisplay() _stretchedTuningSlider->setValue(state.stretchedTuning); updateStretchedTuningLabel(state.stretchedTuning); + /// + struct InfoLabel { const uint32* src; CTextLabel* dst; }; + for (const auto& item : { + InfoLabel{&playState.curves, _infoCurvesLabel}, + InfoLabel{&playState.masters, _infoMastersLabel}, + InfoLabel{&playState.groups, _infoGroupsLabel}, + InfoLabel{&playState.regions, _infoRegionsLabel}, + InfoLabel{&playState.preloadedSamples, _infoSamplesLabel}, + InfoLabel{&playState.activeVoices, _infoVoicesLabel} }) + { + if (item.dst) { + char text[64]; + sprintf(text, "%u", *item.src); + text[sizeof(text) - 1] = '\0'; + item.dst->setText(text); + } + } + + /// setActivePanel(uiState.activePanel); } diff --git a/vst/SfizzVstEditor.h b/vst/SfizzVstEditor.h index f0228b7e..7b6e8392 100644 --- a/vst/SfizzVstEditor.h +++ b/vst/SfizzVstEditor.h @@ -73,6 +73,7 @@ private: // kPanelControls, kPanelSettings, kPanelTuning, + kPanelInfo, kNumPanels, }; @@ -111,6 +112,13 @@ private: CSliderBase *_stretchedTuningSlider = nullptr; CTextLabel* _stretchedTuningLabel = nullptr; + CTextLabel* _infoCurvesLabel = nullptr; + CTextLabel* _infoMastersLabel = nullptr; + CTextLabel* _infoGroupsLabel = nullptr; + CTextLabel* _infoRegionsLabel = nullptr; + CTextLabel* _infoSamplesLabel = nullptr; + CTextLabel* _infoVoicesLabel = nullptr; + #if !defined(__APPLE__) && !defined(_WIN32) SharedPointer _runLoop; #endif diff --git a/vst/SfizzVstProcessor.cpp b/vst/SfizzVstProcessor.cpp index e64e184f..bedde084 100644 --- a/vst/SfizzVstProcessor.cpp +++ b/vst/SfizzVstProcessor.cpp @@ -132,7 +132,8 @@ tresult PLUGIN_API SfizzVstProcessor::setActive(TBool state) synth->setSampleRate(processSetup.sampleRate); synth->setSamplesPerBlock(processSetup.maxSamplesPerBlock); - _fileChangePeriod = static_cast(processSetup.sampleRate); + _fileChangePeriod = static_cast(1.0 * processSetup.sampleRate); + _playStateChangePeriod = static_cast(50e-3 * processSetup.sampleRate); _workRunning = true; _worker = std::thread([this]() { doBackgroundWork(); }); @@ -203,6 +204,20 @@ tresult PLUGIN_API SfizzVstProcessor::process(Vst::ProcessData& data) _semaToWorker.post(); } + _playStateChangeCounter += numFrames; + if (_playStateChangeCounter > _playStateChangePeriod) { + _playStateChangeCounter %= _playStateChangePeriod; + SfizzPlayState playState; + playState.curves = synth.getNumCurves(); + playState.masters = synth.getNumMasters(); + playState.groups = synth.getNumGroups(); + playState.regions = synth.getNumRegions(); + playState.preloadedSamples = synth.getNumPreloadedSamples(); + playState.activeVoices = synth.getNumActiveVoices(); + if (writeWorkerMessage("NotifyPlayState", &playState, sizeof(playState))) + _semaToWorker.post(); + } + return kResultTrue; } @@ -465,6 +480,13 @@ void SfizzVstProcessor::doBackgroundWork() _synth->loadScalaFile(_state.scalaFile); } } + else if (!std::strcmp(id, "NotifyPlayState")) { + SfizzPlayState playState = *msg->payload(); + Steinberg::OPtr notification { allocateMessage() }; + notification->setMessageID("NotifiedPlayState"); + notification->getAttributes()->setBinary("PlayState", &playState, sizeof(playState)); + sendMessage(notification); + } } } diff --git a/vst/SfizzVstProcessor.h b/vst/SfizzVstProcessor.h index 76af84a6..1eb68cea 100644 --- a/vst/SfizzVstProcessor.h +++ b/vst/SfizzVstProcessor.h @@ -64,6 +64,10 @@ private: uint32 _fileChangeCounter = 0; uint32 _fileChangePeriod = 0; + // state notification periodic timer + uint32 _playStateChangeCounter = 0; + uint32 _playStateChangePeriod = 0; + // time info int _timeSigNumerator = 0; int _timeSigDenominator = 0; diff --git a/vst/SfizzVstState.h b/vst/SfizzVstState.h index becafad3..f356d04e 100644 --- a/vst/SfizzVstState.h +++ b/vst/SfizzVstState.h @@ -62,6 +62,15 @@ public: tresult store(IBStream* state) const; }; +struct SfizzPlayState { + uint32 curves; + uint32 masters; + uint32 groups; + uint32 regions; + uint32 preloadedSamples; + uint32 activeVoices; +}; + struct SfizzParameterRange { float def = 0.0; float min = 0.0;