A game framework written with osu! in mind.

Return false if attempting to seek to end in TrackBass (#2499)

Return false if attempting to seek to end in TrackBass

authored by

Dean Herbert and committed by
GitHub
3a5da84d 633abe34

+18 -7
+4 -1
osu.Framework.Tests/Audio/TrackBassTest.cs
··· 109 109 [Test] 110 110 public void TestSeekToEndFails() 111 111 { 112 - track.SeekAsync(track.Length); 112 + bool? success = null; 113 + 114 + runOnAudioThread(() => { success = track.Seek(track.Length); }); 113 115 updateTrack(); 114 116 115 117 Assert.AreEqual(0, track.CurrentTime); 118 + Assert.IsFalse(success); 116 119 } 117 120 118 121 [Test]
+11 -1
osu.Framework/Audio/Track/TrackBass.cs
··· 16 16 { 17 17 public sealed class TrackBass : Track, IBassAudio, IHasPitchAdjust 18 18 { 19 + public const int BYTES_PER_SAMPLE = 4; 20 + 19 21 private AsyncBufferStream dataStream; 20 22 21 23 /// <summary> ··· 39 41 private bool isPlayed; 40 42 41 43 private long byteLength; 44 + 45 + /// <summary> 46 + /// The last position that a seek will succeed for. 47 + /// </summary> 48 + private double lastSeekablePosition; 42 49 43 50 private FileCallbacks fileCallbacks; 44 51 private SyncCallback stopCallback; ··· 96 103 if (success) 97 104 { 98 105 Length = seconds * 1000; 106 + 107 + // Bass does not allow seeking to the end of the track, so the last available position is 1 sample before. 108 + lastSeekablePosition = Bass.ChannelBytes2Seconds(activeStream, byteLength - BYTES_PER_SAMPLE) * 1000; 99 109 100 110 Bass.ChannelGetAttribute(activeStream, ChannelAttribute.Frequency, out float frequency); 101 111 initialFrequency = frequency; ··· 227 237 { 228 238 // At this point the track may not yet be loaded which is indicated by a 0 length. 229 239 // In that case we still want to return true, hence the conservative length. 230 - double conservativeLength = Length == 0 ? double.MaxValue : Length; 240 + double conservativeLength = Length == 0 ? double.MaxValue : lastSeekablePosition; 231 241 double conservativeClamped = MathHelper.Clamp(seek, 0, conservativeLength); 232 242 233 243 await EnqueueAction(() =>
+3 -5
osu.Framework/Audio/Track/Waveform.cs
··· 28 28 /// </summary> 29 29 private const int points_per_iteration = 100000; 30 30 31 - private const int bytes_per_sample = 4; 32 - 33 31 /// <summary> 34 32 /// FFT1024 gives ~40hz accuracy. 35 33 /// </summary> ··· 93 91 // Each "point" is generated from a number of samples, each sample contains a number of channels 94 92 int samplesPerPoint = (int)(info.Frequency * resolution * info.Channels); 95 93 96 - int bytesPerPoint = samplesPerPoint * bytes_per_sample; 94 + int bytesPerPoint = samplesPerPoint * TrackBass.BYTES_PER_SAMPLE; 97 95 98 96 points.Capacity = (int)(length / bytesPerPoint); 99 97 100 98 // Each iteration pulls in several samples 101 99 int bytesPerIteration = bytesPerPoint * points_per_iteration; 102 - var sampleBuffer = new float[bytesPerIteration / bytes_per_sample]; 100 + var sampleBuffer = new float[bytesPerIteration / TrackBass.BYTES_PER_SAMPLE]; 103 101 104 102 // Read sample data 105 103 while (length > 0) 106 104 { 107 105 length = Bass.ChannelGetData(decodeStream, sampleBuffer, bytesPerIteration); 108 - int samplesRead = (int)(length / bytes_per_sample); 106 + int samplesRead = (int)(length / TrackBass.BYTES_PER_SAMPLE); 109 107 110 108 // Each point is composed of multiple samples 111 109 for (int i = 0; i < samplesRead; i += samplesPerPoint)