Do not report timestamps smaller than zero to plugins

This can happen during pre-roll when buffers are filled
to start audible playback at zero.

While the position argument is signed for all plugin-standards,
it seems that some do not support negative timestamps before
00:00:00:00. (e.g. https://github.com/falkTX/Carla/issues/1236)

Furthermore TempoMap::bbt_at_sample() returns 0 for all negative
timestamps, but it was possible tthat tempo-map transmission,
as well as beat-position returned negative values.
This commit is contained in:
Robin Gareus 2020-09-06 16:00:20 +02:00
parent dc05230039
commit 1b55648131
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04
3 changed files with 30 additions and 24 deletions

View File

@ -1594,8 +1594,9 @@ AUPlugin::connect_and_run (BufferSet& bufs,
{
Plugin::connect_and_run(bufs, start, end, speed, in_map, out_map, nframes, offset);
transport_sample = start;
transport_speed = speed;
/* remain at zero during pre-roll at zero */
transport_speed = end > 0 ? speed : 0;
transport_sample = std::max (start, samplepos_t (0));
AudioUnitRenderActionFlags flags = 0;
AudioTimeStamp ts;
@ -1774,11 +1775,11 @@ AUPlugin::get_beat_and_tempo_callback (Float64* outCurrentBeat,
DEBUG_TRACE (DEBUG::AudioUnits, "AU calls ardour beat&tempo callback\n");
if (outCurrentBeat) {
*outCurrentBeat = tmap.quarter_note_at_sample (transport_sample + input_offset);
*outCurrentBeat = tmap.quarter_note_at_sample (transport_sample);
}
if (outCurrentTempo) {
*outCurrentTempo = tmap.tempo_at_sample (transport_sample + input_offset).quarter_notes_per_minute();
*outCurrentTempo = tmap.tempo_at_sample (transport_sample).quarter_notes_per_minute();
}
return noErr;
@ -1795,18 +1796,18 @@ AUPlugin::get_musical_time_location_callback (UInt32* outDeltaSampleOffsetToNe
DEBUG_TRACE (DEBUG::AudioUnits, "AU calls ardour music time location callback\n");
TempoMetric metric = tmap.metric_at (transport_sample + input_offset);
Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_sample (transport_sample + input_offset);
TempoMetric metric = tmap.metric_at (transport_sample);
Timecode::BBT_Time bbt = _session.tempo_map().bbt_at_sample (transport_sample);
if (outDeltaSampleOffsetToNextBeat) {
if (bbt.ticks == 0) {
/* on the beat */
*outDeltaSampleOffsetToNextBeat = 0;
} else {
double const next_beat = ceil (tmap.quarter_note_at_sample (transport_sample + input_offset));
double const next_beat = ceil (tmap.quarter_note_at_sample (transport_sample));
samplepos_t const next_beat_sample = tmap.sample_at_quarter_note (next_beat);
*outDeltaSampleOffsetToNextBeat = next_beat_sample - (transport_sample + input_offset);
*outDeltaSampleOffsetToNextBeat = next_beat_sample - transport_sample;
}
}
@ -1866,7 +1867,7 @@ AUPlugin::get_transport_state_callback (Boolean* outIsPlaying,
/* this assumes that the AU can only call this host callback from render context,
where input_offset is valid.
*/
*outCurrentSampleInTimeLine = transport_sample + input_offset;
*outCurrentSampleInTimeLine = transport_sample;
}
if (outIsCycling) {
@ -1884,11 +1885,11 @@ AUPlugin::get_transport_state_callback (Boolean* outIsPlaying,
Timecode::BBT_Time bbt;
if (outCycleStartBeat) {
*outCycleStartBeat = tmap.quarter_note_at_sample (loc->start() + input_offset);
*outCycleStartBeat = tmap.quarter_note_at_sample (loc->start());
}
if (outCycleEndBeat) {
*outCycleEndBeat = tmap.quarter_note_at_sample (loc->end() + input_offset);
*outCycleEndBeat = tmap.quarter_note_at_sample (loc->end());
}
}
}

View File

@ -2671,16 +2671,20 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
cycles_t then = get_cycles();
/* remain at zero during pre-roll at zero */
speed = end > 0 ? speed : 0;
samplepos_t start0 = std::max (samplepos_t (0), start);
TempoMap& tmap = _session.tempo_map();
Metrics::const_iterator metric_i = tmap.metrics_end();
TempoMetric tmetric = tmap.metric_at(start, &metric_i);
TempoMetric tmetric = tmap.metric_at(start0, &metric_i);
if (_freewheel_control_port) {
*_freewheel_control_port = _session.engine().freewheeling() ? 1.f : 0.f;
}
if (_bpm_control_port) {
float bpm = tmap.tempo_at_sample (start).note_types_per_minute();
float bpm = tmap.tempo_at_sample (start0).note_types_per_minute();
if (*_bpm_control_port != bpm) {
AutomationCtrlPtr c = get_automation_control (_bpm_control_port_index);
if (c && c->ac) {
@ -2759,9 +2763,9 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
if (valid && (flags & PORT_INPUT)) {
if ((flags & PORT_POSITION)) {
Timecode::BBT_Time bbt (tmap.bbt_at_sample (start));
Timecode::BBT_Time bbt (tmap.bbt_at_sample (start0));
double time_scale = Port::speed_ratio ();
double bpm = tmap.tempo_at_sample (start).note_types_per_minute();
double bpm = tmap.tempo_at_sample (start0).note_types_per_minute();
double beatpos = (bbt.bars - 1) * tmetric.meter().divisions_per_bar()
+ (bbt.beats - 1)
+ (bbt.ticks / Timecode::BBT_Time::ticks_per_beat);
@ -2773,7 +2777,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
bpm != _current_bpm) {
// Transport or Tempo has changed, write position at cycle start
write_position(&_impl->forge, _ev_buffers[port_index],
tmetric, bbt, speed, time_scale, bpm, start, 0);
tmetric, bbt, speed, time_scale, bpm, start, 0);
}
}
@ -2805,11 +2809,11 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
tmetric.set_metric(metric);
Timecode::BBT_Time bbt;
bbt = tmap.bbt_at_sample (metric->sample());
double bpm = tmap.tempo_at_sample (start/*XXX*/).note_types_per_minute();
double bpm = tmap.tempo_at_sample (start0 /*XXX metric->sample() */).note_types_per_minute();
write_position(&_impl->forge, _ev_buffers[port_index],
tmetric, bbt, speed, Port::speed_ratio (),
bpm, metric->sample(),
metric->sample() - start);
metric->sample() - start0);
++metric_i;
}
}
@ -3102,7 +3106,7 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
// Update expected transport information for next cycle so we can detect changes
_next_cycle_speed = speed;
_next_cycle_start = end;
_next_cycle_start = end + (start - start0);
_prev_time_scale = Port::speed_ratio ();
{
@ -3110,9 +3114,9 @@ LV2Plugin::connect_and_run(BufferSet& bufs,
* Note: for no-midi plugins, we only ever send information at cycle-start,
* so it needs to be realative to that.
*/
TempoMetric t = tmap.metric_at(start);
_current_bpm = tmap.tempo_at_sample (start).note_types_per_minute();
Timecode::BBT_Time bbt (tmap.bbt_at_sample (start));
TempoMetric t = tmap.metric_at (start0);
_current_bpm = tmap.tempo_at_sample (start0).note_types_per_minute();
Timecode::BBT_Time bbt (tmap.bbt_at_sample (start0));
double beatpos = (bbt.bars - 1) * t.meter().divisions_per_bar()
+ (bbt.beats - 1)
+ (bbt.ticks / Timecode::BBT_Time::ticks_per_beat);

View File

@ -687,8 +687,9 @@ VSTPlugin::connect_and_run (BufferSet& bufs,
return 0;
}
_transport_sample = start;
_transport_speed = speed;
/* remain at zero during pre-roll at zero */
_transport_speed = end > 0 ? speed : 0;
_transport_sample = std::max (samplepos_t (0), start);
ChanCount bufs_count;
bufs_count.set(DataType::AUDIO, 1);