diff --git a/libs/ardour/ardour/triggerbox.h b/libs/ardour/ardour/triggerbox.h index e3894b9c65..d755f080fd 100644 --- a/libs/ardour/ardour/triggerbox.h +++ b/libs/ardour/ardour/triggerbox.h @@ -293,9 +293,21 @@ class LIBARDOUR_API TriggerBox : public Processor void add_midi_sidechain (); + enum TriggerMidiMapMode { + AbletonPush, + SequentialNote, + ByMidiChannel + }; + static Temporal::BBT_Offset assumed_trigger_duration () { return _assumed_trigger_duration; } static void set_assumed_trigger_duration (Temporal::BBT_Offset const &); + static TriggerMidiMapMode midi_map_mode () { return _midi_map_mode; } + static void set_midi_map_mode (TriggerMidiMapMode m); + + static int first_midi_note() { return _first_midi_note; } + static void set_first_midi_note (int n); + private: static Temporal::BBT_Offset _assumed_trigger_duration; @@ -321,6 +333,8 @@ class LIBARDOUR_API TriggerBox : public Processor int determine_next_trigger (uint64_t n); void stop_all (); + int note_to_trigger (int node, int channel); + void tempo_map_change (); PBD::ScopedConnection tempo_map_connection; @@ -331,6 +345,8 @@ class LIBARDOUR_API TriggerBox : public Processor MidiTriggerMap midi_trigger_map; static const uint64_t default_triggers_per_box; + static int _first_midi_note; + static TriggerMidiMapMode _midi_map_mode; }; namespace Properties { diff --git a/libs/ardour/triggerbox.cc b/libs/ardour/triggerbox.cc index cc7477547b..b5da9b0ff3 100644 --- a/libs/ardour/triggerbox.cc +++ b/libs/ardour/triggerbox.cc @@ -17,6 +17,7 @@ #include "ardour/debug.h" #include "ardour/midi_buffer.h" #include "ardour/minibpm.h" +#include "ardour/port.h" #include "ardour/region_factory.h" #include "ardour/session.h" #include "ardour/session_object.h" @@ -909,6 +910,8 @@ Trigger::make_property_quarks () const uint64_t TriggerBox::default_triggers_per_box = 8; Temporal::BBT_Offset TriggerBox::_assumed_trigger_duration (4, 0, 0); +TriggerBox::TriggerMidiMapMode TriggerBox::_midi_map_mode (TriggerBox::AbletonPush); +int TriggerBox::_first_midi_note = 60; TriggerBox::TriggerBox (Session& s, DataType dt) : Processor (s, _("TriggerBox"), Temporal::BeatTime) @@ -1119,6 +1122,7 @@ TriggerBox::add_midi_sidechain () _sidechain.reset (new SideChain (_session, "trigger-side")); _sidechain->activate (); _sidechain->input()->add_port ("", owner(), DataType::MIDI); // add a port, don't connect. + _sidechain->input()->nth (0)->connect (Config->get_default_trigger_input_port()); } } @@ -1148,6 +1152,47 @@ TriggerBox::add_trigger (Trigger* trigger) all_triggers.push_back (trigger); } +void +TriggerBox::set_midi_map_mode (TriggerMidiMapMode m) +{ + _midi_map_mode = m; +} + +void +TriggerBox::set_first_midi_note (int n) +{ + _first_midi_note = n; +} + +int +TriggerBox::note_to_trigger (int midi_note, int channel) +{ + Stripable* s = dynamic_cast (owner()); + const int column = s->presentation_info().order(); + int first_note; + + switch (_midi_map_mode) { + + case AbletonPush: + first_note = 92 + column; + return (midi_note - first_note) / 8; /* gives row index */ + + case SequentialNote: + first_note = _first_midi_note - (column * all_triggers.size()); + return midi_note - first_note; /* direct access to row */ + + case ByMidiChannel: + first_note = 3; + break; + + default: + break; + + } + + return midi_note; +} + void TriggerBox::process_midi_trigger_requests (BufferSet& bufs) { @@ -1162,32 +1207,30 @@ TriggerBox::process_midi_trigger_requests (BufferSet& bufs) continue; } - MidiTriggerMap::iterator mt = midi_trigger_map.find ((*ev).note()); - Trigger* t = 0; + int trigger_number = note_to_trigger ((*ev).note(), (*ev).channel()); - if (mt != midi_trigger_map.end()) { + if (trigger_number < 0) { + /* not for us */ + continue; + } - if (mt->second >= all_triggers.size()) { - cerr << "target slot " << mt->second << endl; - } - assert (mt->second < all_triggers.size()); + if (trigger_number > (int) all_triggers.size()) { + continue; + } - t = all_triggers[mt->second]; + Trigger* t = all_triggers[trigger_number]; - if (!t) { - continue; - } + if (!t) { + continue; + } - cerr << "note " << int ((*ev).note()) << " to trigger " << t << endl; + if ((*ev).is_note_on()) { - if ((*ev).is_note_on()) { + t->bang (); - t->bang (); + } else if ((*ev).is_note_off()) { - } else if ((*ev).is_note_off()) { - - t->unbang (); - } + t->unbang (); } } }