triggerbox: vaguely working MIDI triggers
This commit is contained in:
parent
32408db777
commit
66fe6e937a
@ -201,7 +201,7 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
|
||||
PBD::Property<bool> _use_follow;
|
||||
FollowAction _follow_action[2];
|
||||
int _follow_action_probability;
|
||||
uint32_t _follow_cnt;
|
||||
uint32_t _loop_cnt;
|
||||
uint32_t _follow_count;
|
||||
boost::shared_ptr<Region> _region;
|
||||
Temporal::BBT_Offset _quantization;
|
||||
@ -274,7 +274,7 @@ class LIBARDOUR_API MIDITrigger : public Trigger {
|
||||
MIDITrigger (uint64_t index, TriggerBox&);
|
||||
~MIDITrigger ();
|
||||
|
||||
int run (BufferSet&, pframes_t nframes, pframes_t offset, bool first);
|
||||
int run (BufferSet&, samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, pframes_t offset, bool first);
|
||||
|
||||
void set_start (timepos_t const &);
|
||||
void set_end (timepos_t const &);
|
||||
|
@ -59,7 +59,7 @@ Trigger::Trigger (uint64_t n, TriggerBox& b)
|
||||
, _use_follow (Properties::use_follow, true)
|
||||
, _follow_action { NextTrigger, Stop }
|
||||
, _follow_action_probability (100)
|
||||
, _follow_cnt (0)
|
||||
, _loop_cnt (0)
|
||||
, _follow_count (1)
|
||||
, _quantization (Temporal::BBT_Offset (0, 1, 0))
|
||||
, _legato (Properties::legato, false)
|
||||
@ -256,7 +256,8 @@ Trigger::startup()
|
||||
{
|
||||
_state = WaitingToStart;
|
||||
_gain = _pending_gain;
|
||||
_follow_cnt = _follow_count;
|
||||
_loop_cnt = 0;
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 starts up\n", name()));
|
||||
PropertyChanged (ARDOUR::Properties::running);
|
||||
}
|
||||
|
||||
@ -265,6 +266,7 @@ Trigger::shutdown ()
|
||||
{
|
||||
_state = Stopped;
|
||||
_gain = 1.0;
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 shuts down\n", name()));
|
||||
PropertyChanged (ARDOUR::Properties::running);
|
||||
}
|
||||
|
||||
@ -429,6 +431,8 @@ Trigger::maybe_compute_next_transition (Temporal::Beats const & start, Temporal:
|
||||
transition_samples = transition_time.samples();
|
||||
transition_beats = transition_time.beats ();
|
||||
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 in range, should start/stop at %2 aka %3\n", index(), transition_samples, transition_beats));
|
||||
|
||||
if (_state == WaitingToStop) {
|
||||
_state = Stopping;
|
||||
PropertyChanged (ARDOUR::Properties::running);
|
||||
@ -820,6 +824,7 @@ AudioTrigger::drop_data ()
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
AudioTrigger::load_data (boost::shared_ptr<AudioRegion> ar)
|
||||
{
|
||||
const uint32_t nchans = ar->n_channels();
|
||||
@ -903,9 +908,9 @@ AudioTrigger::run (BufferSet& bufs, pframes_t nframes, pframes_t dest_offset, bo
|
||||
|
||||
/* We reached the end */
|
||||
|
||||
_follow_cnt--;
|
||||
_loop_cnt++;
|
||||
|
||||
if ((_follow_cnt != 0) || (_launch_style == Repeat) || (_box.peek_next_trigger() == this)) { /* self repeat */
|
||||
if ((_loop_cnt == _follow_count) || (_launch_style == Repeat) || (_box.peek_next_trigger() == this)) { /* self repeat */
|
||||
nframes -= this_read;
|
||||
dest_offset += this_read;
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 reached end, but set to loop, so retrigger\n", index()));
|
||||
@ -1176,8 +1181,10 @@ int
|
||||
MIDITrigger::load_data (boost::shared_ptr<MidiRegion> mr)
|
||||
{
|
||||
drop_data ();
|
||||
mr->render (data, 0, Sustained, 0);
|
||||
mr->render_range (data, 0, Sustained, mr->start(), mr->length(), timepos_t (Temporal::BeatTime), 0);
|
||||
set_name (mr->name());
|
||||
data_length = data.span();
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 loaded midi region, span is %2\n", name(), data_length));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1189,30 +1196,34 @@ MIDITrigger::retrigger ()
|
||||
read_index = 0;
|
||||
end_run_sample = transition_samples;
|
||||
_legato_offset = Temporal::BBT_Offset ();
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 retriggered to %2\n", _index, read_index));
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 retriggered to %2, ts = %3\n", _index, read_index, transition_samples));
|
||||
}
|
||||
|
||||
int
|
||||
MIDITrigger::run (BufferSet& bufs, pframes_t nframes, pframes_t dest_offset, bool first)
|
||||
MIDITrigger::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample, pframes_t nframes, pframes_t dest_offset, bool first)
|
||||
{
|
||||
MidiBuffer& mb (bufs.get_midi (0));
|
||||
|
||||
end_run_sample += nframes;
|
||||
|
||||
while (true) {
|
||||
|
||||
RTMidiBuffer::Item const & item (data[read_index]);
|
||||
/* timestamps inside the RTMidiBuffer are relative to
|
||||
zero. Offset them to give us process/timeline timestamps.
|
||||
*/
|
||||
const samplepos_t effective_time = transition_samples + item.timestamp;
|
||||
|
||||
if (effective_time < end_run_sample) {
|
||||
const samplepos_t effective_time = transition_samples + item.timestamp + (_loop_cnt * data_length); /* XXX handle multiple loops */
|
||||
|
||||
// cerr << "Item " << read_index << " @ " << item.timestamp << " + " << transition_samples << " = " << effective_time << endl;
|
||||
|
||||
if (effective_time < end_sample) {
|
||||
|
||||
uint32_t sz;
|
||||
uint8_t const * bytes = data.bytes (item, sz);
|
||||
|
||||
const Evoral::Event<MidiBuffer::TimeType> ev (Evoral::MIDI_EVENT, item.timestamp, sz, const_cast<uint8_t*>(bytes), false);
|
||||
samplepos_t process_relative_timestamp = effective_time - start_sample;
|
||||
|
||||
const Evoral::Event<MidiBuffer::TimeType> ev (Evoral::MIDI_EVENT, process_relative_timestamp, sz, const_cast<uint8_t*>(bytes), false);
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("inserting %1\n", ev));
|
||||
mb.insert_event (ev);
|
||||
|
||||
// _tracker.track (bytes);
|
||||
@ -1220,14 +1231,18 @@ MIDITrigger::run (BufferSet& bufs, pframes_t nframes, pframes_t dest_offset, boo
|
||||
read_index++;
|
||||
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (read_index >= data.size()) {
|
||||
|
||||
/* We reached the end */
|
||||
|
||||
// _tracker.resolve_notes (mb);
|
||||
|
||||
_follow_cnt--;
|
||||
_loop_cnt++;
|
||||
|
||||
if ((_follow_cnt != 0) || (_launch_style == Repeat) || (_box.peek_next_trigger() == this)) { /* self repeat */
|
||||
if ((_loop_cnt == _follow_count) || (_launch_style == Repeat) || (_box.peek_next_trigger() == this)) { /* self repeat */
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 reached end, but set to loop, so retrigger\n", index()));
|
||||
|
||||
/* We need to preserve end_run_sample across
|
||||
@ -1380,6 +1395,8 @@ TriggerBox::get_next_trigger ()
|
||||
int
|
||||
TriggerBox::set_from_selection (uint64_t slot, boost::shared_ptr<Region> region)
|
||||
{
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("load %1 into %2\n", region->name(), slot));
|
||||
|
||||
if (slot >= all_triggers.size()) {
|
||||
return 0;
|
||||
}
|
||||
@ -1760,6 +1777,7 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
||||
case Trigger::WaitingToStop:
|
||||
case Trigger::WaitingToStart:
|
||||
case Trigger::WaitingForRetrigger:
|
||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 in state %2, recompute next transition\n", currently_playing->name(), currently_playing->state()));
|
||||
rt = currently_playing->maybe_compute_next_transition (start_beats, end_beats);
|
||||
break;
|
||||
default:
|
||||
@ -1829,8 +1847,12 @@ TriggerBox::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_samp
|
||||
first = false;
|
||||
|
||||
} else {
|
||||
MIDITrigger* mt = dynamic_cast<MIDITrigger*> (currently_playing);
|
||||
|
||||
/* XXX MIDI triggers to be implemented */
|
||||
if (mt) {
|
||||
mt->run (bufs, start_sample, end_sample, trigger_samples, dest_offset, first);
|
||||
first = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user