triggerbox: add "final sample" concept to start dealing with post-data playout
This commit is contained in:
parent
1afc0ce69c
commit
dbb816b1f9
@ -95,7 +95,11 @@ class LIBARDOUR_API Trigger : public PBD::Stateful {
|
|||||||
* during the current call to ::run(). By the end of that call, it will
|
* during the current call to ::run(). By the end of that call, it will
|
||||||
* have transitioned to Stopped.
|
* have transitioned to Stopped.
|
||||||
*/
|
*/
|
||||||
Stopping
|
Stopping,
|
||||||
|
/* a Trigger in this state has played all of its data and is
|
||||||
|
* now silent-filling until we reach the "true end" of the trigger
|
||||||
|
*/
|
||||||
|
Playout,
|
||||||
};
|
};
|
||||||
|
|
||||||
Trigger (uint32_t index, TriggerBox&);
|
Trigger (uint32_t index, TriggerBox&);
|
||||||
@ -363,7 +367,8 @@ class LIBARDOUR_API AudioTrigger : public Trigger {
|
|||||||
/* computed after data is reset */
|
/* computed after data is reset */
|
||||||
|
|
||||||
samplecnt_t usable_length;
|
samplecnt_t usable_length;
|
||||||
samplepos_t last_sample;
|
samplepos_t last_sample; /* where the data runs out */
|
||||||
|
samplepos_t final_sample; /* where we stop playing */
|
||||||
|
|
||||||
/* computed during run */
|
/* computed during run */
|
||||||
|
|
||||||
|
@ -499,6 +499,7 @@ Trigger::process_state_requests (BufferSet& bufs, pframes_t dest_offset)
|
|||||||
|
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case Running:
|
case Running:
|
||||||
|
case Playout:
|
||||||
switch (launch_style()) {
|
switch (launch_style()) {
|
||||||
case OneShot:
|
case OneShot:
|
||||||
/* do nothing, just let it keep playing */
|
/* do nothing, just let it keep playing */
|
||||||
@ -543,6 +544,7 @@ Trigger::process_state_requests (BufferSet& bufs, pframes_t dest_offset)
|
|||||||
|
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case Running:
|
case Running:
|
||||||
|
case Playout:
|
||||||
begin_stop (true);
|
begin_stop (true);
|
||||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 unbanged, now in WaitingToStop\n", index()));
|
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 unbanged, now in WaitingToStop\n", index()));
|
||||||
break;
|
break;
|
||||||
@ -859,6 +861,7 @@ AudioTrigger::set_state (const XMLNode& node, int version)
|
|||||||
node.get_property (X_("length"), t);
|
node.get_property (X_("length"), t);
|
||||||
usable_length = t.samples();
|
usable_length = t.samples();
|
||||||
last_sample = _start_offset + usable_length;
|
last_sample = _start_offset + usable_length;
|
||||||
|
final_sample = _start_offset + usable_length;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -907,6 +910,7 @@ AudioTrigger::set_usable_length ()
|
|||||||
default:
|
default:
|
||||||
usable_length = data.length;
|
usable_length = data.length;
|
||||||
last_sample = _start_offset + usable_length;
|
last_sample = _start_offset + usable_length;
|
||||||
|
final_sample = last_sample;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -915,6 +919,7 @@ AudioTrigger::set_usable_length ()
|
|||||||
if (q == Temporal::BBT_Offset ()) {
|
if (q == Temporal::BBT_Offset ()) {
|
||||||
usable_length = data.length;
|
usable_length = data.length;
|
||||||
last_sample = _start_offset + usable_length;
|
last_sample = _start_offset + usable_length;
|
||||||
|
final_sample = last_sample;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,6 +928,7 @@ AudioTrigger::set_usable_length ()
|
|||||||
timecnt_t len (Temporal::Beats (q.beats, q.ticks), timepos_t (Temporal::Beats()));
|
timecnt_t len (Temporal::Beats (q.beats, q.ticks), timepos_t (Temporal::Beats()));
|
||||||
usable_length = len.samples();
|
usable_length = len.samples();
|
||||||
last_sample = _start_offset + usable_length;
|
last_sample = _start_offset + usable_length;
|
||||||
|
final_sample = last_sample;
|
||||||
|
|
||||||
// std::cerr << name() << " SUL ul " << usable_length << " of " << data.length << " so " << _start_offset << " ls " << last_sample << std::endl;
|
// std::cerr << name() << " SUL ul " << usable_length << " of " << data.length << " so " << _start_offset << " ls " << last_sample << std::endl;
|
||||||
}
|
}
|
||||||
@ -1175,6 +1181,7 @@ AudioTrigger::load_data (boost::shared_ptr<AudioRegion> ar)
|
|||||||
if (!usable_length || usable_length > data.length) {
|
if (!usable_length || usable_length > data.length) {
|
||||||
usable_length = data.length;
|
usable_length = data.length;
|
||||||
last_sample = _start_offset + usable_length;
|
last_sample = _start_offset + usable_length;
|
||||||
|
final_sample = last_sample;
|
||||||
}
|
}
|
||||||
|
|
||||||
drop_data ();
|
drop_data ();
|
||||||
@ -1233,6 +1240,7 @@ AudioTrigger::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
|
|||||||
/* did everything we could do */
|
/* did everything we could do */
|
||||||
return nframes;
|
return nframes;
|
||||||
case Running:
|
case Running:
|
||||||
|
case Playout:
|
||||||
case WaitingToStop:
|
case WaitingToStop:
|
||||||
case Stopping:
|
case Stopping:
|
||||||
/* stuff to do */
|
/* stuff to do */
|
||||||
@ -1298,7 +1306,7 @@ AudioTrigger::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while (nframes) {
|
while (nframes && (_state != Playout)) {
|
||||||
|
|
||||||
pframes_t to_stretcher;
|
pframes_t to_stretcher;
|
||||||
pframes_t from_stretcher;
|
pframes_t from_stretcher;
|
||||||
@ -1414,19 +1422,53 @@ AudioTrigger::run (BufferSet& bufs, samplepos_t start_sample, samplepos_t end_sa
|
|||||||
avail = _stretcher->available ();
|
avail = _stretcher->available ();
|
||||||
dest_offset += from_stretcher;
|
dest_offset += from_stretcher;
|
||||||
|
|
||||||
if (read_index >= last_sample && (_apparent_tempo == 0. || avail <= 0)) {
|
if (read_index >= last_sample && (!do_stretch || avail <= 0)) {
|
||||||
_state = Stopped;
|
|
||||||
_loop_cnt++;
|
if (last_sample < final_sample) {
|
||||||
|
_state = Playout;
|
||||||
|
} else {
|
||||||
|
_state = Stopped;
|
||||||
|
_loop_cnt++;
|
||||||
|
}
|
||||||
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 reached end, now stopped, retrieved %2, avail %3\n", index(), retrieved, avail));
|
DEBUG_TRACE (DEBUG::Triggers, string_compose ("%1 reached end, now stopped, retrieved %2, avail %3\n", index(), retrieved, avail));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pframes_t covered_frames = orig_nframes - nframes;
|
||||||
|
|
||||||
|
if (_state == Playout) {
|
||||||
|
|
||||||
|
const pframes_t remaining_frames_for_run= orig_nframes - covered_frames;
|
||||||
|
const pframes_t remaining_frames_till_final = final_sample - read_index;
|
||||||
|
const pframes_t to_fill = std::min (remaining_frames_till_final, remaining_frames_for_run);
|
||||||
|
|
||||||
|
for (uint32_t chn = 0; chn < bufs.count().n_audio(); ++chn) {
|
||||||
|
|
||||||
|
uint32_t channel = chn % data.size();
|
||||||
|
AudioBuffer& buf (bufs.get_audio (chn));
|
||||||
|
|
||||||
|
buf.silence (to_fill, dest_offset + covered_frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
read_index += to_fill;
|
||||||
|
covered_frames += to_fill;
|
||||||
|
|
||||||
|
if (read_index < final_sample) {
|
||||||
|
/* more playout to be done */
|
||||||
|
return covered_frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
_state == Stopped;
|
||||||
|
_loop_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
if (_state == Stopped || _state == Stopping) {
|
if (_state == Stopped || _state == Stopping) {
|
||||||
when_stopped_during_run (bufs, dest_offset);
|
when_stopped_during_run (bufs, dest_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
return orig_nframes - nframes;
|
return covered_frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Loading…
Reference in New Issue
Block a user