From 411dd7566f64959167419713e702e06af09465e2 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 20 Jan 2013 02:31:41 +0000 Subject: [PATCH] Fix completely wrong MidiRegionView::get_patch_key_at(). This fixes the note name displayed at a given time to be based on the correct program at that time, and not one in the future. git-svn-id: svn://localhost/ardour2/branches/3.0@13912 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/midi_region_view.cc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 6931e5172b..ec0a426ccb 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -1845,16 +1845,28 @@ MidiRegionView::patch_change_to_patch_key (MidiModel::PatchChangePtr p) return MIDI::Name::PatchPrimaryKey (p->program(), p->bank()); } +/// Return true iff @p pc applies to the given time on the given channel. +static bool +patch_applies (const ARDOUR::MidiModel::constPatchChangePtr pc, double time, uint8_t channel) +{ + return pc->time() <= time && pc->channel() == channel; +} + void MidiRegionView::get_patch_key_at (double time, uint8_t channel, MIDI::Name::PatchPrimaryKey& key) const { + // The earliest event not before time MidiModel::PatchChanges::iterator i = _model->patch_change_lower_bound (time); - while (i != _model->patch_changes().end() && (*i)->channel() != channel) { - ++i; + + // Go backwards until we find the latest PC for this channel, or the start + while (i != _model->patch_changes().begin() && + (i == _model->patch_changes().end() || + !patch_applies(*i, time, channel))) { + --i; } - if (i != _model->patch_changes().end()) { - key.bank_number = (*i)->bank(); + if (patch_applies(*i, time, channel)) { + key.bank_number = (*i)->bank(); key.program_number = (*i)->program (); } else { key.bank_number = key.program_number = 0;