From faca1d1ea1d6810efa3df6b15937ff95467dcc5a Mon Sep 17 00:00:00 2001 From: "Robin E. R. Davies" Date: Tue, 2 Sep 2025 09:50:14 -0400 Subject: [PATCH] Misc bug fixes Alsa trace, NAM legacy flag, --- src/AlsaDriver.cpp | 64 +++++++++++++++++++++-- src/AudioDriver.hpp | 1 + src/Pedalboard.cpp | 7 ++- src/Pedalboard.hpp | 2 +- src/PiPedalModel.cpp | 60 +++++++++------------ src/PiPedalUI.cpp | 2 +- todo.txt | 2 +- vite/src/pipedal/ToobParametricEqView.tsx | 38 ++++++++++---- 8 files changed, 122 insertions(+), 54 deletions(-) diff --git a/src/AlsaDriver.cpp b/src/AlsaDriver.cpp index aa21092..a374068 100644 --- a/src/AlsaDriver.cpp +++ b/src/AlsaDriver.cpp @@ -37,6 +37,8 @@ #include "DummyAudioDriver.hpp" #include "SchedulerPriority.hpp" #include "CrashGuard.hpp" +#include +#include #include "CpuUse.hpp" @@ -260,6 +262,8 @@ namespace pipedal std::vector bufferTraces{1000}; size_t bufferTraceIndex = 0; + virtual void DumpBufferTrace(size_t nEntries) override; + inline void TraceBufferPositions(size_t framesInBuffer, char code = ' ') { #if TRACE_BUFFER_POSITIONS @@ -1077,7 +1081,7 @@ namespace pipedal float *p = (float *)rawPlaybackBuffer.data(); std::vector &buffers = this->playbackBuffers; - int channels = this->captureChannels; + int channels = this->playbackChannels; for (size_t frame = 0; frame < frames; ++frame) { for (int channel = 0; channel < channels; ++channel) @@ -1092,7 +1096,7 @@ namespace pipedal float *p = (float *)rawPlaybackBuffer.data(); std::vector &buffers = this->playbackBuffers; - int channels = this->captureChannels; + int channels = this->playbackChannels; for (size_t frame = 0; frame < frames; ++frame) { for (int channel = 0; channel < channels; ++channel) @@ -1167,7 +1171,6 @@ namespace pipedal OpenAudio(this->jackServerSettings, this->channelSelection); validate_capture_handle(); FillOutputBuffer(); - audioRunning = true; } catch (const std::exception &e) { @@ -1180,6 +1183,7 @@ namespace pipedal Lv2Log::error(SS("Unable to restart ALSA capture: " << snd_strerror(err))); throw PiPedalStateException("Unable to restart ALSA capture."); } + audioRunning = true; } void PrepareCaptureFunctions(snd_pcm_format_t captureFormat) @@ -1617,6 +1621,8 @@ namespace pipedal auto frame_bytes = this->captureFrameSize; do { + TraceBufferPositions(framesRead,'1'); + framesRead = snd_pcm_readi(handle, buffer, frames); if (framesRead < 0) { @@ -1629,10 +1635,12 @@ namespace pipedal } if (framesRead == 0) { - snd_pcm_wait(captureHandle, 1); + snd_pcm_wait(handle, frames); } - TraceBufferPositions(framesRead); } while (frames > 0); + + TraceBufferPositions(framesRead,'2'); + return framesRead; } @@ -2331,4 +2339,50 @@ namespace pipedal { snd_config_update_free_global(); // to get a clean Valgrind report. } + + void AlsaDriverImpl::DumpBufferTrace(size_t nEntries) + { + using namespace std; + int savedPrecision = cout.precision(); + auto savedFlags = cout.flags(); + + size_t ix = bufferTraceIndex; + if (ix < nEntries) + { + ix = ix + bufferTraces.size()-nEntries; + } else { + ix -= nEntries; + } + uint64_t t0; + if (bufferTraceIndex == 0) { + t0 = bufferTraces[bufferTraces.size()-1].time; + } else { + t0 = bufferTraces[bufferTraceIndex-1].time; + } + while (ix != bufferTraceIndex) + { + auto&bufferTrace = bufferTraces[ix]; + + int64_t dt = (int64_t)bufferTrace.time - (int64_t)t0; + + + cout << bufferTrace.code << " " + << fixed << setprecision(3) << dt*0.001 + << " " << "inAvail: " << bufferTrace.inAvail + << " " << "outAvail: " << bufferTrace.outAvail + << " " << "bufferd: " << bufferTrace.buffered + << " " << "total: " << bufferTrace.total + << endl; + + ++ix; + if (ix == bufferTraces.size()) + { + ix = 0; + } + } + + cout.precision(savedPrecision); + cout.flags(savedFlags); + } + } // namespace diff --git a/src/AudioDriver.hpp b/src/AudioDriver.hpp index 71b94c2..245aeb3 100644 --- a/src/AudioDriver.hpp +++ b/src/AudioDriver.hpp @@ -80,6 +80,7 @@ namespace pipedal { virtual void Close() = 0; virtual std::string GetConfigurationDescription() = 0; + virtual void DumpBufferTrace(size_t nEntries) {} }; diff --git a/src/Pedalboard.cpp b/src/Pedalboard.cpp index a6f1119..590b27d 100644 --- a/src/Pedalboard.cpp +++ b/src/Pedalboard.cpp @@ -91,10 +91,15 @@ ControlValue* PedalboardItem::GetControlValue(const std::string&symbol) } + bool PedalboardItem::SetControlValue(const std::string&symbol, float value) { ControlValue*controlValue = GetControlValue(symbol); - if (controlValue == nullptr) return false; + if (controlValue == nullptr) + { + this->controlValues().push_back(ControlValue(symbol.c_str(),value)); + return true; + } if (controlValue->value() != value) { controlValue->value(value); diff --git a/src/Pedalboard.hpp b/src/Pedalboard.hpp index f5d0ab8..cf9771e 100644 --- a/src/Pedalboard.hpp +++ b/src/Pedalboard.hpp @@ -108,7 +108,6 @@ public: const ControlValue*GetControlValue(const std::string&symbol) const; bool SetControlValue(const std::string&key, float value); - bool IsStructurallyIdentical(const PedalboardItem&other) const; void ApplySnapshotValue(SnapshotValue*snapshotValue); @@ -161,6 +160,7 @@ public: // } DECLARE_JSON_MAP(PedalboardItem); + }; class SnapshotValue { diff --git a/src/PiPedalModel.cpp b/src/PiPedalModel.cpp index d5f20e1..4d9c5fa 100644 --- a/src/PiPedalModel.cpp +++ b/src/PiPedalModel.cpp @@ -272,16 +272,17 @@ void PiPedalModel::Load() this->pedalboard = storage.GetCurrentPreset(); // the current *saved* preset. - - // the current edited preset, saved only across orderly shutdowns. CrashGuard::SetCrashGuardFileName(storage.GetDataRoot() / "crash_guard.data"); - if (CrashGuard::HasCrashed()) { + if (CrashGuard::HasCrashed()) + { // ignore the current preset, and load a blank pedalboard in order to avoid a potential plugin crash. this->pedalboard = Pedalboard::MakeDefault(); - } else { + } + else + { CurrentPreset currentPreset; try { @@ -289,7 +290,7 @@ void PiPedalModel::Load() { this->pedalboard = currentPreset.preset_; this->hasPresetChanged = currentPreset.modified_; - } + } } catch (const std::exception &e) { @@ -297,8 +298,6 @@ void PiPedalModel::Load() } } - - UpdateDefaults(&this->pedalboard); std::unique_ptr p{AudioHost::CreateInstance(pluginHost.asIHost())}; @@ -644,11 +643,9 @@ void PiPedalModel::SetPedalboardItemUseModUi(int64_t clientId, int64_t instanceI subscriber->OnItemUseModUiChanged(clientId, instanceId, enabled); } this->SetPresetChanged(clientId, true); - } } - void PiPedalModel::SetPedalboardItemEnable(int64_t clientId, int64_t pedalItemId, bool enabled) { std::lock_guard guard{mutex}; @@ -1449,7 +1446,8 @@ void PiPedalModel::OnAlsaSequencerDeviceAdded(int client, const std::string &cli { // reconfigure connections. std::lock_guard lock(this->mutex); - if (this->audioHost) { + if (this->audioHost) + { this->audioHost->SetAlsaSequencerConfiguration(this->storage.GetAlsaSequencerConfiguration()); } }); @@ -1457,7 +1455,7 @@ void PiPedalModel::OnAlsaSequencerDeviceAdded(int client, const std::string &cli } void PiPedalModel::OnAlsaSequencerDeviceRemoved(int client) { - // no action required. + // no action required. } void PiPedalModel::SetAlsaSequencerConfiguration(const AlsaSequencerConfiguration &alsaSequencerConfiguration) @@ -2027,27 +2025,25 @@ void PiPedalModel::UpdateDefaults(PedalboardItem *pedalboardItem, std::unordered pedalboardItem->midiChannelBinding(std::optional()); // clear it. } } + //////// PLUGIN SPECIFIC UPGRADES ////////////////////// + if (pPlugin->uri() == "http://two-play.com/plugins/toob-nam") + { + ControlValue *pValue = pedalboardItem->GetControlValue("inputCalibrationMode"); + if (pValue == nullptr) + { + // calibration is OFF when upgrading. + pedalboardItem->SetControlValue("inputCalibrationMode", 0.0f); + } + pValue = pedalboardItem->GetControlValue("version"); + if (pValue == nullptr) + { + pedalboardItem->SetControlValue("version", 0.0f); + } + } for (size_t i = 0; i < pPlugin->ports().size(); ++i) { auto port = pPlugin->ports()[i]; - //////// PLUGIN SPECIFIC UPGRADES ////////////////////// - if (pPlugin->uri() == "http://two-play.com/plugins/toob-nam") - { - ControlValue *pValue = pedalboardItem->GetControlValue("inputCalibrationMode"); - if (pValue == nullptr) - { - // calibration is OFF when upgrading. - pedalboardItem->SetControlValue("inputCalibrationMode",0.0f); - } - pValue = pedalboardItem->GetControlValue("version"); - if (pValue == nullptr) - { - pedalboardItem->SetControlValue("version",0.0f); - } - - } - if (port->is_control_port() && port->is_input()) { ControlValue *pValue = pedalboardItem->GetControlValue(port->symbol()); @@ -3107,19 +3103,15 @@ void PiPedalModel::SetTone3000Auth(const std::string &apiKey) { std::lock_guard lock(mutex); storage.SetTone3000Auth(apiKey); - + std::vector t{subscribers.begin(), subscribers.end()}; bool hasAuth = apiKey != ""; for (auto &subscriber : t) { - subscriber->OnTone3000AuthChanged(hasAuth); + subscriber->OnTone3000AuthChanged(hasAuth); } - } bool PiPedalModel::HasTone3000Auth() const { return storage.GetTone3000Auth() != ""; } - - - diff --git a/src/PiPedalUI.cpp b/src/PiPedalUI.cpp index fd3215f..a635073 100644 --- a/src/PiPedalUI.cpp +++ b/src/PiPedalUI.cpp @@ -539,7 +539,7 @@ UiFrequencyPlot::UiFrequencyPlot(PluginHost*pHost, const LilvNode*node, this->yTop_ = GetFloat(pWorld,node,pHost->lilvUris->pipedalUI__yTop,5); this->yBottom_ = GetFloat(pWorld,node,pHost->lilvUris->pipedalUI__yBottom,-35); this->xLog_ = GetFloat(pWorld,node,pHost->lilvUris->pipedalUI__xLog,-35); - this->width_ = GetFloat(pWorld,node,pHost->lilvUris->pipedalUI__width,60); + this->width_ = GetFloat(pWorld,node,pHost->lilvUris->pipedalUI__width,176); } diff --git a/todo.txt b/todo.txt index 7fd066e..4ed9691 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,5 @@ +Check ToOB Cab SIM F/R range. -Versioning for legacy NAM presets! Convert CRVB presets! double select on double-click/ok in file dialog. diff --git a/vite/src/pipedal/ToobParametricEqView.tsx b/vite/src/pipedal/ToobParametricEqView.tsx index d40fb70..1bc64cf 100644 --- a/vite/src/pipedal/ToobParametricEqView.tsx +++ b/vite/src/pipedal/ToobParametricEqView.tsx @@ -451,7 +451,7 @@ const ToobParametricEqView = if (isLandscape) { panelStyle = { display: "flex", flexDirection: "row", alignItems: "stretch", width: "100%" }; scrollStyle = { flex: "1 1 auto", overflowX: "auto", overflowY: "hidden", whiteSpace: "nowrap" }; - frameStyle = { display: "flex", flexFlow: "row nowrap", alignItems: "center",paddingTop: 8 }; + frameStyle = { display: "flex", flexFlow: "row nowrap", alignItems: "center", paddingTop: 8 }; } else { panelStyle = { display: "flex", flexDirection: "column", alignItems: "stretch", height: "100%" }; scrollStyle = { flex: "1 1 auto", overflowX: "hidden", overflowY: "auto", whiteSpace: "nowrap" }; @@ -460,17 +460,33 @@ const ToobParametricEqView = return [(
-
- {controls[0] as React.ReactNode} -
- { - e.stopPropagation(); - this.setState({ maximized: true }); - }}> - - + {host.isLandscapeGrid() ? ( +
+
+ { + e.stopPropagation(); + this.setState({ maximized: true }); + }}> + + +
+ {controls[0] as React.ReactNode}
-
+ ) : ( +
+ {controls[0] as React.ReactNode} +
+ { + e.stopPropagation(); + this.setState({ maximized: true }); + }}> + + +
+
+ )}
{panelControls}