From f3ff5cf5529dc03130f3503890928b6977e0788f Mon Sep 17 00:00:00 2001 From: nILS Date: Thu, 29 Jan 2026 13:18:22 +0100 Subject: [PATCH 1/3] re-enables PC messages on change, when the player is running --- .../Views/BaseClasses/UIIntVarOffField.cpp | 4 ++++ sources/Application/Views/InstrumentView.cpp | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/sources/Application/Views/BaseClasses/UIIntVarOffField.cpp b/sources/Application/Views/BaseClasses/UIIntVarOffField.cpp index f023c9af4..20a04d74c 100644 --- a/sources/Application/Views/BaseClasses/UIIntVarOffField.cpp +++ b/sources/Application/Views/BaseClasses/UIIntVarOffField.cpp @@ -54,6 +54,10 @@ void UIIntVarOffField::ProcessArrow(unsigned short mask) { } } src_.SetInt(value); + + SetChanged(); + NotifyObservers(reinterpret_cast( + static_cast(src_.GetID()))); }; void UIIntVarOffField::Draw(GUIWindow &w, int offset) { diff --git a/sources/Application/Views/InstrumentView.cpp b/sources/Application/Views/InstrumentView.cpp index d6d324809..7002541b2 100644 --- a/sources/Application/Views/InstrumentView.cpp +++ b/sources/Application/Views/InstrumentView.cpp @@ -569,7 +569,6 @@ void InstrumentView::fillMidiParameters() { intVarOffField_.emplace_back( UIIntVarOffField(position, *v, "program: %2.2X", 0, 0x7F, 1, 0x10)); fieldList_.insert(fieldList_.end(), &(*intVarOffField_.rbegin())); - (*intVarOffField_.rbegin()).AddObserver(*this); position._y += 1; v = instrument->FindVariable(FourCC::MidiInstrumentTableAutomation); @@ -1103,7 +1102,12 @@ void InstrumentView::Update(Observable &o, I_ObservableData *data) { NotifyObservers(&ve); } break; case FourCC::MidiInstrumentProgram: { - // When program value changes, send a MIDI Program Change message + // When program value changes, send a MIDI Program Change message during + // playback + if (!Player::GetInstance()->IsRunning()) { + break; + } + I_Instrument *instr = getInstrument(); if (instr && instr->GetType() == IT_MIDI) { MidiInstrument *midiInstr = (MidiInstrument *)instr; @@ -1118,8 +1122,8 @@ void InstrumentView::Update(Observable &o, I_ObservableData *data) { int channel = channelVar->GetInt(); int program = programVar->GetInt(); - // Send Program Change message and play C3 note using the helper method - midiInstr->SendProgramChangeWithNote(channel, program); + // Send Program Change message + midiInstr->SendProgramChange(channel, program); } } } break; From 22515e640803e708accd1c219b8f50ec760c85c6 Mon Sep 17 00:00:00 2001 From: nILS Date: Sat, 31 Jan 2026 00:28:12 +0100 Subject: [PATCH 2/3] fixes delay command handling --- sources/Application/Player/Player.cpp | 17 ++++++++++++++--- sources/Application/Player/Player.h | 2 +- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/sources/Application/Player/Player.cpp b/sources/Application/Player/Player.cpp index 2615bc86d..7412ca4e6 100644 --- a/sources/Application/Player/Player.cpp +++ b/sources/Application/Player/Player.cpp @@ -538,17 +538,21 @@ void Player::Update(Observable &o, I_ObservableData *d) { }; } + // Track which channels just had their delay expire + bool delayExpired[SONG_CHANNEL_COUNT]; for (int i = 0; i < SONG_CHANNEL_COUNT; i++) { + delayExpired[i] = false; if (timeToStart_[i] > 0) { if (--timeToStart_[i] == 0) { playCursorPosition(i); + delayExpired[i] = true; } } } // Process commands in current phrase if (viewData_->playMode_ != PM_AUDITION) - ProcessCommands(); + ProcessCommands(delayExpired); // Initialise retrigger table int instrRetrigger[SONG_CHANNEL_COUNT]; @@ -613,7 +617,7 @@ void Player::Update(Observable &o, I_ObservableData *d) { position for all channels ************************************************************/ -void Player::ProcessCommands() { +void Player::ProcessCommands(bool delayExpired[SONG_CHANNEL_COUNT]) { // loop on all channels @@ -627,7 +631,14 @@ void Player::ProcessCommands() { uchar phrase = viewData_->currentPlayPhrase_[i]; if (phrase != 0xFF) { - if (gs->TriggerChannel(i)) { // If groove says it is time to play + + // Skip if waiting for delayed trigger + if (timeToStart_[i]) { + continue; + } + + // If groove says it is time to play OR or the delay just expired + if (gs->TriggerChannel(i) || (delayExpired && delayExpired[i])) { int pos = viewData_->phrasePlayPos_[i]; FourCC cc = viewData_->song_->phrase_.cmd1_[phrase * 16 + pos]; ushort param = viewData_->song_->phrase_.param1_[phrase * 16 + pos]; diff --git a/sources/Application/Player/Player.h b/sources/Application/Player/Player.h index a7d81277b..b32411e19 100644 --- a/sources/Application/Player/Player.h +++ b/sources/Application/Player/Player.h @@ -82,7 +82,7 @@ class Player : public I_Observer, bool IsRunning(); bool GetStopAtEnd() { return stopAtEnd_; } - void ProcessCommands(); + void ProcessCommands(bool delayExpired[SONG_CHANNEL_COUNT] = nullptr); bool ProcessChannelCommand(int channel, FourCC cmd, ushort param); void StartStreaming(const char *name, int startSample = 0); From 25cad4b96ea80b620f05d1d54f9089df166ecb41 Mon Sep 17 00:00:00 2001 From: nILS Date: Thu, 5 Feb 2026 09:11:07 +0100 Subject: [PATCH 3/3] removing superflouos ProcessCommands call --- sources/Application/Player/Player.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/Application/Player/Player.cpp b/sources/Application/Player/Player.cpp index 7412ca4e6..34486226d 100644 --- a/sources/Application/Player/Player.cpp +++ b/sources/Application/Player/Player.cpp @@ -192,7 +192,7 @@ void Player::Start(PlayMode mode, bool forceSongMode, MixerServiceMode msmMode, break; } - ProcessCommands(); + Trace::Error("USELESS?"); startTime_ = mixer_.GetAudioOut()->GetStreamTime();