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:
parent
dc05230039
commit
1b55648131
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user