pa_threaded_mainloop_wait might wake up for several reasons. And there
is no point (but possibly harm) in moving on before we have verified
that PA actually is ready to receive our write without overflow.
ae3c8b19c6 and 03a17df68c reworked the transitions to and from
freewheeling. Some of it seems to have been experiments that tried
several things out, and generally it seems to have worked. It left some
commented out code. Clean that up.
The draining was introduced in ae3c8b19c6, apparently as an experiment
doing several changes. But the drain is outside the loop where
freewheeling changes, so the fix must have worked for other reasons.
There doesn't seem to be any benefit from draining at that point. The
stream is already empty. If not, we could have flushed it.
Draining right after uncorking will conceptualy create an intentional
underflow, even though it isn't reported as such. PipeWire seems to
(something like 6-12 months ago) have regressed in handling of that grey
area, causing that *underflow* to cause a request for too much data, and
thus causing constant *overflows* and unusable playback.
This change makes PulseAudio playback work for me again.
This is never for inline references to parameters, only for starting parameter
documentation blocks. The "@p" command is for this, although unfortunately
Doxygen doesn't actually do anything with it and it's just an alias for code
text.
Graph::prep is a private function called initially from the main
process-callback before doing any work, and later at the end of
each process cycle. This sets up the process graph-chain and
process trigger queue.
Tempo information is irrelevant here.
This is required to collect relevent undo/redo information, notably
automation-data changes from Playlist::update_after_tempo_map_change and
DiskReader::playlist_ranges_moved.
The realtime thread should not move regions to begin with, and debug
builds woudl also assert since no undo operation was started.
MIDI clock start at the next beat (round_up_to_beat), so
here we have to round the current tick, rather than fall
back to a tick that is not yet complete, as 14da117bc8 does.
Reproduced with the Session from #9027
Start loop at bar 40 with MClk generator enabled.
```
#3 in __GI___assert_fail (assertion=0x7fedd86c4fd5 "clk_pos >= pos", file=0x7fedd86c38b7 "../libs/temporal/tempo.cc", line=3336, function=0x7fedd86c4f60 "void Temporal::TempoMap::midi_clock_beat_at_or_after(Temporal::samplepos_t, Temporal::samplepos_t&, uint32_t&) const") at assert.c:101
#4 in Temporal::TempoMap::midi_clock_beat_at_or_after(long, long&, unsigned int&) const (this= 0x560187e92c00, pos=20691033, clk_pos=@0x7fedc02178b8: 20691032, clk_beat=@0x7fedc02178c4: 11472) at ../libs/temporal/tempo.cc:3336
#5 in ARDOUR::MidiClockTicker::tick(long, long, unsigned int, long) (this=0x56018eed6db0, start_sample=20691033, end_sample=20692057, n_samples=1024, pre_roll=0) at ../libs/ardour/ticker.cc:170
#6 in ARDOUR::Session::send_mclk_for_cycle(long, long, unsigned int, long) (this=0x56018a216340, start_sample=20691033, end_sample=20692057, n_samples=1024, pre_roll=0) at ../libs/ardour/session.cc:7495
#7 in ARDOUR::AudioEngine::process_callback(unsigned int) (this=0x5601881a4f20, nframes=1024) at ../libs/ardour/audioengine.cc:563
```
This is the first step to fix various MIDI edit issues for sessions with
tempo-changes.
The old code, using .earlier returned an absolute position when
calculating a relative distance. This is only valid if the session has a
fixed tempo, and the origin is irrelevant when converting the timepos.
This resulted in follow up issues since there is a difference when
summing two positions (each with an origin) vs adding an offset to a
position.
Note: this API changes breaks compilation until the GUI is updated.
This fixes various rounding issues. Notably superclock to sample
conversion must always round down when playing forward.
`::process (start, end, speed = 1)` uses exclusive end.
Processing begins at `start` and end ends just before `end`.
Next cycle will begin with the current end.
One example where this failed:
- New session at 48kHz
- Change tempo to 130 BPM
- Enable snap to 1/8 note
- Snap playhead to 1|3|0
- Enable Metronome
- Play
`assert (superclock_to_samples ((*i).sclock(), sample_rate()) < end);`
end = 177231 samples == superclock 1042118280
A grid point is found at superclock 1042116920 (that is < 1042118280).
However converting it back to samples rounded it to sample 177231 == end,
while actual location is 1360 super-clock ticks before end.
The metronome click has to be started this cycle, since the same
position will not be found at the beginning of the next cycle, with
start = 177232.
Similarly a samplecnt_t t, converted to music-time and back must not be
later than the given sample.
```
timepos_t tsc (t);
assert (timepos_t::from_ticks (tsc.ticks ()).samples () <= t);
```
IOW. When playing forward, all super-clock time between 1|1|0 and 1|1|1
should round down to 1|1|0. "We have not yet reached the first tick".
This allows to export a session from the commandline tool
```Lua
AudioEngine:set_backend("None (Dummy)", "", "")
s = load_session ("/path/to/session", "snapshot")
assert (s);
e = s:simple_export()
assert (e:check_outputs ())
e:run_export ()
e = nil
```
This fixes an issue when destroying VST plugin UIs
rather than hiding them. Even though is hidden before destroying it,
the vistracker is also destroyed in the same function call, before
the event can be processed. The window state remains visible="1"