triggerbox: estimate_midi_patches tries to retain patch info across domains
* initialize patches to GM standard (drums on 10) in case file has none * in the case where file had none, check the Auditioner to see if user set any * in the case where a file has patches, use those instead * also stash the UsedChannels so we can show only the used chans in the UI
This commit is contained in:
parent
fcd45cfca7
commit
dce3f2eb65
|
@ -539,6 +539,8 @@ class LIBARDOUR_API MIDITrigger : public Trigger {
|
||||||
void reload (BufferSet&, void*);
|
void reload (BufferSet&, void*);
|
||||||
bool probably_oneshot () const;
|
bool probably_oneshot () const;
|
||||||
|
|
||||||
|
void estimate_midi_patches ();
|
||||||
|
|
||||||
int set_region_in_worker_thread (boost::shared_ptr<Region>);
|
int set_region_in_worker_thread (boost::shared_ptr<Region>);
|
||||||
void jump_start ();
|
void jump_start ();
|
||||||
void shutdown (BufferSet& bufs, pframes_t dest_offset);
|
void shutdown (BufferSet& bufs, pframes_t dest_offset);
|
||||||
|
|
|
@ -2371,6 +2371,48 @@ MIDITrigger::natural_length() const
|
||||||
return timepos_t (Temporal::BeatTime);
|
return timepos_t (Temporal::BeatTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MIDITrigger::estimate_midi_patches ()
|
||||||
|
{
|
||||||
|
/* first, intialize all our slot's patches to GM defaults, to make playback deterministic */
|
||||||
|
for (uint8_t chan = 0; chan < 16; ++chan) {
|
||||||
|
_patch_change[chan].set_channel(chan);
|
||||||
|
_patch_change[chan].set_bank( chan == 9 ? 120 : 0 );
|
||||||
|
_patch_change[chan].set_program( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<SMFSource> smfs = boost::dynamic_pointer_cast<SMFSource> (_region->source(0));
|
||||||
|
if (smfs) {
|
||||||
|
/* second, apply any patches that the Auditioner has in its memory
|
||||||
|
* ...this handles the case where the user chose patches for a file that itself lacked patch-settings
|
||||||
|
* (it's possible that the user didn't audition the actual file they dragged in, but this is still the best starting-point we have)
|
||||||
|
* */
|
||||||
|
boost::shared_ptr<ARDOUR::Auditioner> aud = _box.session().the_auditioner();
|
||||||
|
if (aud) {
|
||||||
|
for (uint8_t chan = 0; chan < 16; ++chan) {
|
||||||
|
if (aud->patch_change (chan).is_set()) {
|
||||||
|
_patch_change[chan] = aud->patch_change (chan);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* thirdly, apply the patches from the file itself (if it has any) */
|
||||||
|
boost::shared_ptr<MidiModel> model = smfs->model();
|
||||||
|
for (MidiModel::PatchChanges::const_iterator i = model->patch_changes().begin(); i != model->patch_changes().end(); ++i) {
|
||||||
|
if ((*i)->is_set()) {
|
||||||
|
int chan = (*i)->channel(); /* behavior is undefined for SMF's with multiple patch changes. I'm not sure that we care */
|
||||||
|
_patch_change[chan].set_channel ((*i)->channel());
|
||||||
|
_patch_change[chan].set_bank((*i)->bank());
|
||||||
|
_patch_change[chan].set_program((*i)->program());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finally, store the used_channels so the UI can show patches only for those chans actually used */
|
||||||
|
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 estimate_midi_patches(), using channels %2\n", name(), smfs->used_channels().to_string().c_str()));
|
||||||
|
set_segment_used_channels(smfs->used_channels());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
MIDITrigger::set_region_in_worker_thread (boost::shared_ptr<Region> r)
|
MIDITrigger::set_region_in_worker_thread (boost::shared_ptr<Region> r)
|
||||||
{
|
{
|
||||||
|
@ -2386,6 +2428,11 @@ MIDITrigger::set_region_in_worker_thread (boost::shared_ptr<Region> r)
|
||||||
set_length (mr->length());
|
set_length (mr->length());
|
||||||
model = mr->model ();
|
model = mr->model ();
|
||||||
|
|
||||||
|
estimate_midi_patches ();
|
||||||
|
|
||||||
|
/* we've changed some of our internal values; we need to update our queued UIState or they will be lost when UIState is applied */
|
||||||
|
copy_to_ui_state ();
|
||||||
|
|
||||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 loaded midi region, span is %2\n", name(), data_length));
|
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 loaded midi region, span is %2\n", name(), data_length));
|
||||||
|
|
||||||
send_property_change (ARDOUR::Properties::name);
|
send_property_change (ARDOUR::Properties::name);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user