itdelatrisu / opsu

opsu! ~ an open-source osu! client
https://itdelatrisu.github.io/opsu/
GNU General Public License v3.0
762 stars 123 forks source link

Inaccurate track position in OpenALStreamPlayer #42

Closed itdelatrisu closed 9 years ago

itdelatrisu commented 9 years ago

OpenALStreamPlayer.getPosition() returns track positions that are up to 20ms off (on my machine). This is pretty obvious if you call MusicController.getPosition() in a while loop and take the difference of the return values: an interval is skipped on a fairly regular basis. This is probably causing some of the unpredictable gameplay inaccuracies.

Here's the relevant code:

    public float getPosition() {
        float playedTime = ((float) playedPos / (float) sampleSize) / sampleRate;
        float timePosition = playedTime + (getTime() - lastUpdateTime) / 1000f;
        return timePosition;
    }

I don't really know how to approach this, so any help would be greatly appreciated.

fluddokt commented 9 years ago

Well we could change it to float timePosition = playedTime + AL10.alGetSourcef(source, AL11.AL_SEC_OFFSET); as this is pretty much what it was before.

But I only get changes in increments of 10ms (which is probably fine)

We could also use what I'm doing in my port which runs a timer and tries to sync that to the music position. But takes a bit time to sync up.

chong601 commented 9 years ago

10 ms is already quite decent (since any audio delays, early or vice versa can be conpensated using the Offset in Options)

Another probable idea is totally remove the OpenALStreamPlayer.getPosition() and use Sys.getTime() to get a initial time and then use the difference from starting getTime() call to the current getTime() call to control the notes (may cause even more delays and off-sync issues since the audio and gameplay may no longer in sync)

itdelatrisu commented 9 years ago

I only noticed the delay now because I'm trying to write a replay system, and frames can be in the ~10ms range apart. Which solution do you prefer? (I'll play around more later.)

fluddokt commented 9 years ago

@chong601 I mean that multiple calls will return the same value even if a few milliseconds has passed. as in : ALTme:0.13997734 time:774442960 ALTme:0.14997733 time:774442963 ALTme:0.14997733 time:774442967 ALTme:0.15997733 time:774442973 ALTme:0.15997733 time:774442976 ALTme:0.15997733 time:774442980 ALTme:0.16997732 time:774442984 ALTme:0.16997732 time:774442988 ALTme:0.17997731 time:774442993 ALTme:0.17997731 time:774442997 ALTme:0.18997732 time:774443001 ALTme:0.18997732 time:774443005

@itdelatrisu I think I'll try my second solution since I prefer the ms accuracy. I'll make a pull request in a while.

chong601 commented 9 years ago

@fluddokt Oh that.... misinterpreted that :P

itdelatrisu commented 9 years ago

Fixed by fluddokt in #44.