-
-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Speed effect doesn't affect TrackPosition #81
Comments
Hello @SKProCH, I've recently pushed a prerelease version of Lavalink4NET (2.0.1-preview.3). You may see there a new property on the LavalinkPlayer class called I was unsure how the speed and rate of the timescale effect are correlated to each other, but I think by looking at the source code of SoundTouch (the filter library that Lavaplayer uses for time stretching) includes speed and rate both. So I used a simple multiplication for calculating the actual time stretch (e.g., rate = 2, speed = 0.5, stretch = 1?) (Rate modifies pitch/tempo by modifying the sample rate, speed adjusts only the speed while preserving the same pitch level). Could you try out the latest release, and tell me if this works for you? Thank you! |
Hello, @angelobreuer Seems like this is not working properly. |
I see. I think I have found the mistake in Lavalink4NET why the track position is not properly calculated. The Lavalink server sends about every five seconds a player update (in the following sometimes called 'synchronization') which contains a timestamp where the payload was generated, and the relative offset of the track position. The track position sent by the Lavalink server simply represents the time when the track has been started; and not the actual position in the track. For example, when using 2x speed, the timestamp "flows" in natural time, and not the expected 2x speed (which is also the reason why this issue occurred at all). When using a constant time scaling, like 2x which is not modified while playing the track, it is relatively easy to calculate the position of the player by multiplying the natural position by 2. But if the speed of the track changes while playing, it becomes harder, as some parts are played faster, slower, or exactly the same as the natural time. This makes it a lot harder for Lavalink4NET to calculate the position of the track because Lavalink4NET needs to track every single change in the time scale filter options (rate & speed), which is not possible with multi-cluster environments or the already implemented Stay Online feature (as some nodes are not able to restore the exact player state). If Lavalink4NET would calculate each tile of the track with the position during its period, this would also lead to a high error rate as Lavalink4NET does not really know when the time scale filter is really applied on the server-side (e.g., delays due to filter initialization or network latencies). Another option would be to implement a property in the player update, that indicates the current position in the track (calculated from the actual sample position of the track, not the starting position), which is sent every five seconds for each player (which is also part of the current behavior) and instantly when the time-scale filter is updated (to reduce error rates). I've done some tests and fixed the calculation error in Lavalink4NET by simply applying the time scale also on the timestamp reported by the Lavalink server. As said above this will only work if a constant time scale is applied from the beginning of the track and is not changed while playing the track. Using this, I could achieve an error rate between 0.6 and 0.0005 (the theoretical error rate sinks every second passed, as it benefits from resyncing and calculation errors that are based on the starting of the whole process, the practical error rate should be much lower but is hard to measure). The first sample can be ignored as the resync did not occur at this time (thus the explosive error rate).
When using a non-constant time, like emulating a user changing the speed of the track while playing, the following happens (note that the error rate is incorrect in the following as the speed jumps are not respected in the example):
Here is also a test I made to see whether the Lavalink server reports the actual timestamp measured by actual audio samples played. You can see that it just sends the time the passed since the song started (with respecting pause/resume). 0, 1632169708790, 0, 0
4820, 1632169713638, 4820, 0.964
9820, 1632169718631, 5000, 1
14800, 1632169723627, 4980, 0.996
19800, 1632169728629, 5000, 1
change time scale to 4x
24800, 1632169733632, 5000, 1
29800, 1632169738629, 5000, 1
34820, 1632169743629, 5020, 1.004
39800, 1632169748635, 4980, 0.996
44800, 1632169753637, 5000, 1
change time scale to 2x
49820, 1632169758639, 5020, 1.004
54820, 1632169763636, 5000, 1 I have created an issue in the Lavalink repository that mentions this issue and a probably easier and more realistic fix for this (lavalink-devs/Lavalink#521). For a workaround, I pushed a prerelease(2.0.1-preview.3.1) that works with constant-time time scaling. |
Closing as stale until there is a response in the dependent issues |
Linking lavalink-devs/lavaplayer#94 |
Describe the bug
When the effect that changes the playback speed is on, the
TrackPosition
changes at the normal speed.To Reproduce
Steps to reproduce the behavior:
speed
Expected behavior
TrackPosition
must be actual track position.The text was updated successfully, but these errors were encountered: