triggerbox: start some attempts at complexifying MIDI note -> trigger mapping

This commit is contained in:
Paul Davis 2021-10-08 20:35:25 -06:00
parent af02413aef
commit 4031a03588
2 changed files with 77 additions and 18 deletions

View file

@ -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 {

View file

@ -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<Stripable*> (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 ();
}
}
}