Merge pull request #495 from FoolHen/snapshot-next-prev-midi

Add snapshot next/prev MIDI bindings
This commit is contained in:
Robin Davies
2026-06-07 21:47:50 -04:00
committed by GitHub
8 changed files with 135 additions and 1 deletions
+28
View File
@@ -516,6 +516,8 @@ private:
SystemMidiBinding snapshot5MidiBinding;
SystemMidiBinding snapshot6MidiBinding;
SystemMidiBinding nextSnapshotMidiBinding;
SystemMidiBinding prevSnapshotMidiBinding;
SystemMidiBinding startHotspotMidiBinding;
SystemMidiBinding stopHotspotMidiBinding;
SystemMidiBinding rebootMidiBinding;
@@ -1015,6 +1017,18 @@ private:
midiProgramChangePending = true;
this->realtimeWriter.OnNextMidiProgram(++(this->midiProgramChangeId), -1);
}
else if (nextSnapshotMidiBinding.IsTriggered(event))
{
this->deferredMidiMessageCount = 0; // we can discard previous control changes.
midiProgramChangePending = true;
this->realtimeWriter.OnNextMidiSnapshot(++(this->midiProgramChangeId), 1);
}
else if (prevSnapshotMidiBinding.IsTriggered(event))
{
this->deferredMidiMessageCount = 0; // we can discard previous control changes.
midiProgramChangePending = true;
this->realtimeWriter.OnNextMidiSnapshot(++(this->midiProgramChangeId), -1);
}
else if (shutdownMidiBinding.IsTriggered(event))
{
@@ -1737,6 +1751,12 @@ public:
hostReader.read(&request);
pNotifyCallbacks->OnNotifyNextMidiBank(request);
}
else if (command == RingBufferCommand::NextMidiSnapshot)
{
RealtimeNextMidiProgramRequest request;
hostReader.read(&request);
pNotifyCallbacks->OnNotifyNextMidiSnapshot(request);
}
else if (command == RingBufferCommand::RealtimeMidiEvent)
{
@@ -2423,6 +2443,14 @@ void AudioHostImpl::SetSystemMidiBindings(const std::vector<MidiBinding> &bindin
{
this->snapshot6MidiBinding.SetBinding(*i);
}
else if (i->symbol() == "nextSnapshot")
{
this->nextSnapshotMidiBinding.SetBinding(*i);
}
else if (i->symbol() == "prevSnapshot")
{
this->prevSnapshotMidiBinding.SetBinding(*i);
}
else
{
Lv2Log::error(SS("Invalid system midi binding: " << i->symbol()));
+1
View File
@@ -177,6 +177,7 @@ namespace pipedal
virtual void OnNotifyMidiProgramChange(RealtimeMidiProgramRequest &midiProgramRequest) = 0;
virtual void OnNotifyNextMidiProgram(const RealtimeNextMidiProgramRequest &request) = 0;
virtual void OnNotifyNextMidiBank(const RealtimeNextMidiProgramRequest &request) = 0;
virtual void OnNotifyNextMidiSnapshot(const RealtimeNextMidiProgramRequest &request) = 0;
virtual void OnNotifyLv2RealtimeError(int64_t instanceId, const std::string &error) = 0;
virtual void OnNotifyMidiRealtimeEvent(RealtimeMidiEventType eventType) = 0;
virtual void OnNotifyMidiRealtimeSnapshotRequest(int32_t snapshotIndex,int64_t snapshotRequestId) = 0;
+86
View File
@@ -1181,6 +1181,92 @@ void PiPedalModel::NextPreset(Direction direction)
LoadPreset(-1, index.presets()[currentPresetIndex].instanceId());
}
void PiPedalModel::NextSnapshot(Direction direction)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
auto &snapshots = this->pedalboard.snapshots();
if (snapshots.size() == 0)
{
return;
}
int64_t currentSnapshot = this->pedalboard.selectedSnapshot();
int64_t nextSnapshot = -1;
if (direction == Direction::Increase)
{
for (int64_t i = currentSnapshot + 1; i < (int64_t)snapshots.size(); ++i)
{
if (snapshots[i])
{
nextSnapshot = i;
break;
}
}
if (nextSnapshot == -1)
{
for (int64_t i = 0; i <= currentSnapshot && i < (int64_t)snapshots.size(); ++i)
{
if (snapshots[i])
{
nextSnapshot = i;
break;
}
}
}
}
else
{
for (int64_t i = currentSnapshot - 1; i >= 0; --i)
{
if (snapshots[i])
{
nextSnapshot = i;
break;
}
}
if (nextSnapshot == -1)
{
for (int64_t i = (int64_t)snapshots.size() - 1; i > currentSnapshot; --i)
{
if (snapshots[i])
{
nextSnapshot = i;
break;
}
}
}
}
if (nextSnapshot != -1 && nextSnapshot != currentSnapshot)
{
SetSnapshot(nextSnapshot);
}
}
void PiPedalModel::OnNotifyNextMidiSnapshot(const RealtimeNextMidiProgramRequest &request)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
try
{
if (request.direction >= 0)
{
NextSnapshot();
}
else
{
PreviousSnapshot();
}
}
catch (std::exception &e)
{
Lv2Log::error(e.what());
}
if (this->audioHost)
{
this->audioHost->AckMidiProgramRequest(request.requestId);
}
}
void PiPedalModel::OnNotifyNextMidiProgram(const RealtimeNextMidiProgramRequest &request)
{
std::lock_guard<std::recursive_mutex> guard{mutex};
+3
View File
@@ -273,6 +273,7 @@ namespace pipedal
virtual void OnNotifyMidiProgramChange(RealtimeMidiProgramRequest &midiProgramRequest) override;
virtual void OnNotifyNextMidiProgram(const RealtimeNextMidiProgramRequest &request) override;
virtual void OnNotifyNextMidiBank(const RealtimeNextMidiProgramRequest &request) override;
virtual void OnNotifyNextMidiSnapshot(const RealtimeNextMidiProgramRequest &request) override;
virtual void OnNotifyLv2RealtimeError(int64_t instanceId, const std::string &error) override;
PostHandle networkChangingDelayHandle = 0;
@@ -311,6 +312,8 @@ namespace pipedal
void PreviousBank() { NextBank(Direction::Decrease); }
void NextPreset(Direction direction = Direction::Increase);
void PreviousPreset() { NextPreset(Direction::Decrease); }
void NextSnapshot(Direction direction = Direction::Increase);
void PreviousSnapshot() { NextSnapshot(Direction::Decrease); }
int64_t DownloadModelsFromTone3000(
const std::string &responseuri,
+6
View File
@@ -83,6 +83,7 @@ namespace pipedal
NextMidiProgram,
NextMidiBank,
NextMidiSnapshot,
Lv2StateChanged,
MaybeLv2StateChanged,
@@ -444,6 +445,11 @@ namespace pipedal
RealtimeNextMidiProgramRequest msg{requestId : requestId, direction : direction};
write(RingBufferCommand::NextMidiBank, msg);
}
void OnNextMidiSnapshot(int64_t requestId, int32_t direction)
{
RealtimeNextMidiProgramRequest msg{requestId : requestId, direction : direction};
write(RingBufferCommand::NextMidiSnapshot, msg);
}
void SetControlValue(int effectIndex, int controlIndex, float value)
{
+3
View File
@@ -2213,6 +2213,9 @@ std::vector<MidiBinding> Storage::GetSystemMidiBindings()
result.push_back(MidiBinding::SystemBinding("snapshot5"));
result.push_back(MidiBinding::SystemBinding("snapshot6"));
result.push_back(MidiBinding::SystemBinding("prevSnapshot"));
result.push_back(MidiBinding::SystemBinding("nextSnapshot"));
result.push_back(MidiBinding::SystemBinding("stopHotspot"));
result.push_back(MidiBinding::SystemBinding("startHotspot"));
result.push_back(MidiBinding::SystemBinding("shutdown"));