tesselode / kira

Library for expressive game audio.
https://crates.io/crates/kira
Apache License 2.0
837 stars 42 forks source link

Syncing a game to a sound instance's playback position #7

Closed ghost closed 3 years ago

ghost commented 3 years ago

I'm currently building a rhythm game, so I want to sync the game's clock to a soundtrack's playback position. What's the idiomatic way to get the playback position of a sound instance?

tesselode commented 3 years ago

Currently, there isn't any way to get the playback position of an instance. It's not that it would be impossible to implement, I'm just not sure what the right way is to do it. Since the sound instance and the main game code are living on different threads, the instance has to report its position to the main thread. The more often it reports the position, the higher performance impact there will be, but the less often it reports the position, the less accurate result you'll get when you query for the position.

How are you planning on syncing the game to the playback position? Is this a DDR/BeatMania/etc. type rhythm game with a scrolling notefield and timed button presses?

ghost commented 3 years ago

How are you planning on syncing the game to the playback position?

My game clocks at 1000fps, and per clock cycle, I update relevant parts of the game to the playback position of the soundtrack (checking hitobjects for whether they have been missed, ect). The same code is run on input presses (which also needs the playback position). I did something similar in Godot, but instead of working directly on the playback position, it would update using the system clock plus an offset maintained according to the playback position, mostly to prevent drifting (occurs a lot in terribly coded Unity games like Muse Dash) and jitter (values reported by Godot itself jitters a lot). I think with a low playback position report rate, I can use such a similar tactic to keep the game clocking smoothly.

Is this a DDR/BeatMania/etc. type rhythm game with a scrolling notefield and timed button presses?

Exactly.

tesselode commented 3 years ago

When you say drift, do you mean that the main thread tracks time separately from the audio thread and accumulates error over time? If so, how does that even happen?

ghost commented 3 years ago

If so, how does that even happen?

Could be either the audio thread or the main thread lagging, the audio device temporarily not being able to output audio (eg unplugging the audio jack on some OS'es/configurations, causing backpressure to the audio thread) or some other mishap.

Generally I think playback position tracking should be left to the audio thread, instead of letting the main thread run its own unsynched timings.

tesselode commented 3 years ago

OK, i was thinking playback position reporting interval could be customizable per-instance, so people can choose their level of precision vs. performance impact. I'll probably add that Soon™.

tesselode commented 3 years ago

By the way, have you tried having a customizable global audio offset, like StepMania does? I think that may be a better solution since playback querying is always going to have some amount of latency involved.

ghost commented 3 years ago

Latency is another issue, which I'm not sure is even a problem at all in kira - at least on my system, the latency is low enough to be practically negligible.

This issue was about getting the playback position, which does not depend on latency.

tesselode commented 3 years ago

I never replied to this, but playback position tracking was added in v0.5.0.