ddf / Minim

A Java audio library, designed to be used with Processing.
http://code.compartmental.net/tools/minim
GNU Lesser General Public License v3.0
670 stars 137 forks source link

Way to calculate instantaneous AudioPlayer position? #118

Open GanerCodes opened 3 years ago

GanerCodes commented 3 years ago

I have an AudioPlayer and I need to pull the current song time very rapidly however .position() only updates ~60 times per second and I need it to be updated at least 300 times per second. It can work if I lower the sample rate to 128/256 or so but that brings in a quantity of other issues

ddf commented 3 years ago

The underlying implementation reads data from the source file in chunks defined by the bufferSize argument to the loadFile method. By default that buffer size is 1024, which means position will change ~43 times per second for an audio file that has a sample rate of 44100. You might be able to specify a smaller buffer size to achieve what you want. For example a buffer size of 64 would see position updated ~689 times per second. Is this what you are talking about when you say "lower the sample rate to 128/256"? Generally speaking, how well that lower latency playback works will depend on the audio drivers in use and may not be achievable without some kind of ASIO driver on Windows. I'm curious to know why such a high level of precision is necessary? That's clearly not something happening inside of a Processing draw() function or similar.

GanerCodes commented 3 years ago

Thanks for the reply, When I lower the sample rate too far it causes audio glitches, [under 128 doesn't even work] and at 128 there's a 50/50 chance it will have random pauses and clipping, and I'd imagine it start higher than that for people with worse computers

As for my use case, I'm developing a procedural generated rhythm game, and recently I've switched my spawning system to generate all objects you need to avoid before the song actually starts. This requires me pulling the precalculated positions every frame the game runs by providing it with the current time in the song. For people with good systems, this needs to be able to occur ~430 times per second (as current max refresh monitors are 360hz, and having a bit extra guarantees the smoothness won't ever break)

GanerCodes commented 3 years ago

any ideas on how to do this?

ddf commented 3 years ago

In your case, particularly because you already know what all of your objects will be before the song starts, I'd recommend updating your own "play position" in your main game thread, since this is just a number that will have each frame's dt added to it. If you were very concerned about getting out of sync with the actual play position of the song, you could sync your play position with the one from the audio player by adding an audio listener that would be called with every block of samples the audio player reads. However, I suspect that you'll have to introduce some kind of latency to get the visuals to "feel" right with the actual sound coming out of the speakers. Like, the "play position" used by the game for visuals may actually need to run slightly ahead of or behind the play position of the audio player itself.

GanerCodes commented 3 years ago

Thanks, yea I ended up just using something like what you suggested image

Also, kinda off topic but is there a way to have an AudioPlayer buffer the entire file in memory? I know theres other classes for this however their methods and such vary compared to this like AudioSample but they lack many of the methods I use often [ex. position, pause, cue, skip, etc]