RustAudio / cpal

Cross-platform audio I/O library in pure Rust
Apache License 2.0
2.62k stars 347 forks source link

[JACK] timing imprecisions #507

Open the-drunk-coder opened 3 years ago

the-drunk-coder commented 3 years ago

While looking for a solution to #472, exposed the as_nanos method of StreamInstant, and also added a method as_secs.

My expectation is that the playback timestamp, representing the playback time of the first sample in the block, always increases by the same amount, or put in a different way, the difference between the current playback timestamp and the last one should always be the same.

I haven't tested with other hosts so far, but at least with the JACK host, the difference from one call to the next constantly varies by a couple of microseconds from one call to the next.

The C++ library i'm most familiar with (RtAudio) does not show the same behavior, the timestamp passed to the audio callback increases constantly by the same amount of time.

This causes audible timing issues in the application I'm currently working on.

pietervandermeer commented 3 years ago

Hhhmm, I think Cpal kinda forces the programmer to sync to the audio streams. Which is kinda ok.. for me. Some jitter is to be expected. A non-realtime OS is lucky to manage to get jitter consistently down below 1ms, actually. If the timestamp jitters too much you can always use a samplecounter and scale that to seconds? Am I missing something?

the-drunk-coder commented 3 years ago

If the timestamp jitters too much you can always use a samplecounter and scale that to seconds? Am I missing something?

Sure, but I somehow expected the playback timestamp to be exactly that (the logical sample-counter time, without jitter) whereas the callback timestamp is the jittery one ...

I mean, if the playback timestamp (or performance time or whatever you want to call it) would not increase without jitter, it'd be impossible to reconstruct an audio stream without glitches ...

ollpu commented 2 years ago

Unrelated to playback, but this should probably be start_cycle_instant: https://github.com/RustAudio/cpal/blob/7ff54f17a733b18b6c457e240f01e43f2c910632/src/host/jack/stream.rs#L336

Either way, the playback timestamp will not increase uniformly, because the period time is not an integer amount of microseconds (which is the precision of the timestamp provided by JACK). The sample clock (how many samples have been output so far) should be your ground truth when sample-level accuracy is required. CPAL could possibly provide that too, but for now you have to keep count of it manually.