mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-08 07:45:00 +01:00
triggerbox: consolidate ::start_and_roll_to() across Audio & MIDI triggers
This uses a mild trick to pass both the object and ptr-to-member-function from the child class to the parent class. Note: before this commit, both instances of ::start_and_roll_to() were identical.
This commit is contained in:
parent
e75a8ab77c
commit
c09ffd4fcd
2 changed files with 56 additions and 76 deletions
|
|
@ -310,6 +310,12 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
|
||||||
Temporal::BBT_Time& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
|
Temporal::BBT_Time& t_bbt, Temporal::Beats& t_beats, samplepos_t& t_samples,
|
||||||
Temporal::TempoMap::SharedPtr const & tmap);
|
Temporal::TempoMap::SharedPtr const & tmap);
|
||||||
|
|
||||||
|
|
||||||
|
template<typename TriggerType>
|
||||||
|
void start_and_roll_to (samplepos_t start_pos, samplepos_t end_position, TriggerType& trigger,
|
||||||
|
pframes_t (TriggerType::*run_method) (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample,
|
||||||
|
Temporal::Beats const & start_beats, Temporal::Beats const & end_beats,
|
||||||
|
pframes_t nframes, pframes_t dest_offset, double bpm));
|
||||||
void set_next_trigger (int n);
|
void set_next_trigger (int n);
|
||||||
int next_trigger() const { return _next_trigger; }
|
int next_trigger() const { return _next_trigger; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1026,6 +1026,54 @@ Trigger::when_stopped_during_run (BufferSet& bufs, pframes_t dest_offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename TriggerType>
|
||||||
|
void
|
||||||
|
Trigger::start_and_roll_to (samplepos_t start_pos, samplepos_t end_position, TriggerType& trigger,
|
||||||
|
pframes_t (TriggerType::*run_method) (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sample,
|
||||||
|
Temporal::Beats const & start_beats, Temporal::Beats const & end_beats,
|
||||||
|
pframes_t nframes, pframes_t dest_offset, double bpm))
|
||||||
|
{
|
||||||
|
const pframes_t block_size = AudioEngine::instance()->samples_per_cycle ();
|
||||||
|
BufferSet bufs;
|
||||||
|
|
||||||
|
/* no need to allocate any space for BufferSet because we call
|
||||||
|
audio_run<false>() which is guaranteed to never use the buffers.
|
||||||
|
|
||||||
|
AudioTrigger::_startup() also does not use BufferSet (MIDITrigger
|
||||||
|
does, and we use virtual functions so the argument list is the same
|
||||||
|
for both, even though only the MIDI case needs the BufferSet).
|
||||||
|
*/
|
||||||
|
|
||||||
|
startup (bufs, 0, _quantization);
|
||||||
|
_cue_launched = true;
|
||||||
|
|
||||||
|
samplepos_t pos = start_pos;
|
||||||
|
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
|
||||||
|
|
||||||
|
while (pos < end_position) {
|
||||||
|
pframes_t nframes = std::min (block_size, (pframes_t) (end_position - pos));
|
||||||
|
Temporal::Beats start_beats = tmap->quarters_at (timepos_t (pos));
|
||||||
|
Temporal::Beats end_beats = tmap->quarters_at (timepos_t (pos+nframes));
|
||||||
|
const double bpm = tmap->quarters_per_minute_at (timepos_t (start_beats));
|
||||||
|
|
||||||
|
pframes_t n = (trigger.*run_method) (bufs, pos, pos+nframes, start_beats, end_beats, nframes, 0, bpm);
|
||||||
|
|
||||||
|
/* We could have reached the end. Check and restart, because
|
||||||
|
* TriggerBox::fast_forward() already determined that we are
|
||||||
|
* the active trigger at @param end_position
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (_state == Stopped) {
|
||||||
|
retrigger ();
|
||||||
|
_state = WaitingToStart;
|
||||||
|
_cue_launched = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------*/
|
/*--------------------*/
|
||||||
|
|
||||||
|
|
@ -1189,44 +1237,7 @@ AudioTrigger::start_offset () const
|
||||||
void
|
void
|
||||||
AudioTrigger::start_and_roll_to (samplepos_t start_pos, samplepos_t end_position)
|
AudioTrigger::start_and_roll_to (samplepos_t start_pos, samplepos_t end_position)
|
||||||
{
|
{
|
||||||
const pframes_t block_size = AudioEngine::instance()->samples_per_cycle ();
|
Trigger::start_and_roll_to<AudioTrigger> (start_pos, end_position, *this, &AudioTrigger::audio_run<false>);
|
||||||
BufferSet bufs;
|
|
||||||
|
|
||||||
/* no need to allocate any space for BufferSet because we call
|
|
||||||
audio_run<false>() which is guaranteed to never use the buffers.
|
|
||||||
|
|
||||||
AudioTrigger::_startup() also does not use BufferSet (MIDITrigger
|
|
||||||
does, and we use virtual functions so the argument list is the same
|
|
||||||
for both, even though only the MIDI case needs the BufferSet).
|
|
||||||
*/
|
|
||||||
|
|
||||||
startup (bufs, 0, _quantization);
|
|
||||||
_cue_launched = true;
|
|
||||||
|
|
||||||
samplepos_t pos = start_pos;
|
|
||||||
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
|
|
||||||
|
|
||||||
while (pos < end_position) {
|
|
||||||
pframes_t nframes = std::min (block_size, (pframes_t) (end_position - pos));
|
|
||||||
Temporal::Beats start_beats = tmap->quarters_at (timepos_t (pos));
|
|
||||||
Temporal::Beats end_beats = tmap->quarters_at (timepos_t (pos+nframes));
|
|
||||||
const double bpm = tmap->quarters_per_minute_at (timepos_t (start_beats));
|
|
||||||
|
|
||||||
pframes_t n = audio_run<false> (bufs, pos, pos+nframes, start_beats, end_beats, nframes, 0, bpm);
|
|
||||||
|
|
||||||
/* We could have reached the end. Check and restart, because
|
|
||||||
* TriggerBox::fast_forward() already determined that we are
|
|
||||||
* the active trigger at @param end_position
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_state == Stopped) {
|
|
||||||
retrigger ();
|
|
||||||
_state = WaitingToStart;
|
|
||||||
_cue_launched = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timepos_t
|
timepos_t
|
||||||
|
|
@ -2049,44 +2060,7 @@ MIDITrigger::probably_oneshot () const
|
||||||
void
|
void
|
||||||
MIDITrigger::start_and_roll_to (samplepos_t start_pos, samplepos_t end_position)
|
MIDITrigger::start_and_roll_to (samplepos_t start_pos, samplepos_t end_position)
|
||||||
{
|
{
|
||||||
const pframes_t block_size = AudioEngine::instance()->samples_per_cycle ();
|
Trigger::start_and_roll_to (start_pos, end_position, *this, &MIDITrigger::midi_run<false>);
|
||||||
BufferSet bufs;
|
|
||||||
|
|
||||||
/* no need to allocate any space for BufferSet because we call
|
|
||||||
audio_run<false>() which is guaranteed to never use the buffers.
|
|
||||||
|
|
||||||
AudioTrigger::_startup() also does not use BufferSet (MIDITrigger
|
|
||||||
does, and we use virtual functions so the argument list is the same
|
|
||||||
for both, even though only the MIDI case needs the BufferSet).
|
|
||||||
*/
|
|
||||||
|
|
||||||
startup (bufs, 0, _quantization);
|
|
||||||
_cue_launched = true;
|
|
||||||
|
|
||||||
samplepos_t pos = start_pos;
|
|
||||||
Temporal::TempoMap::SharedPtr tmap (Temporal::TempoMap::use());
|
|
||||||
|
|
||||||
while (pos < end_position) {
|
|
||||||
pframes_t nframes = std::min (block_size, (pframes_t) (end_position - pos));
|
|
||||||
Temporal::Beats start_beats = tmap->quarters_at (timepos_t (pos));
|
|
||||||
Temporal::Beats end_beats = tmap->quarters_at (timepos_t (pos+nframes));
|
|
||||||
const double bpm = tmap->quarters_per_minute_at (timepos_t (start_beats));
|
|
||||||
|
|
||||||
pframes_t n = midi_run<false> (bufs, pos, pos+nframes, start_beats, end_beats, nframes, 0, bpm);
|
|
||||||
|
|
||||||
/* We could have reached the end. Check and restart, because
|
|
||||||
* TriggerBox::fast_forward() already determined that we are
|
|
||||||
* the active trigger at @param end_position
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (_state == Stopped) {
|
|
||||||
retrigger ();
|
|
||||||
_state = WaitingToStart;
|
|
||||||
_cue_launched = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos += n;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timepos_t
|
timepos_t
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue