@@ -204,12 +204,10 @@ struct DecoderStream {
204204 float * loadingBuffer = nullptr ;
205205
206206 // Audio thread state (only touched by audio thread)
207- std::atomic< ma_uint64> filePosition{ 0 } ;
207+ ma_uint64 filePosition = 0 ;
208208 ma_uint64 bufferStartPos = 0 ;
209209 ma_uint64 localReadPos = 0 ;
210210 ma_uint64 validFrames = 0 ;
211-
212- bool justSeeked = false ;
213211
214212 // Async loading state (atomic for lock-free access)
215213 struct AsyncState {
@@ -332,7 +330,7 @@ struct DecoderStream {
332330 }
333331
334332 // Reset state
335- void resetState (bool seeking = false ) {
333+ void resetState () {
336334 // Reset atomic flags
337335 asyncState.nextBufferReady .store (false , std::memory_order_release);
338336 asyncState.loadingBufferReady .store (false , std::memory_order_release);
@@ -341,17 +339,15 @@ struct DecoderStream {
341339 asyncState.requestNextBuffer .store (false , std::memory_order_release);
342340 asyncState.requestLoadingBuffer .store (false , std::memory_order_release);
343341
344- if (!seeking) {
345- asyncState.nextBufferValidFrames = 0 ;
346- asyncState.loadingBufferValidFrames = 0 ;
347- asyncState.nextBufferStartPos = 0 ;
348- asyncState.loadingBufferStartPos = 0 ;
349-
350- filePosition.store (0 , std::memory_order_relaxed);
351- bufferStartPos = 0 ;
352- localReadPos = 0 ;
353- validFrames = 0 ;
354- }
342+ asyncState.nextBufferValidFrames = 0 ;
343+ asyncState.loadingBufferValidFrames = 0 ;
344+ asyncState.nextBufferStartPos = 0 ;
345+ asyncState.loadingBufferStartPos = 0 ;
346+
347+ filePosition = 0 ;
348+ bufferStartPos = 0 ;
349+ localReadPos = 0 ;
350+ validFrames = 0 ;
355351
356352 if (pcmBufferA) memset (pcmBufferA, 0 , TOTAL_BUFFER_FRAMES * CHANNEL_COUNT * sizeof (float ));
357353 if (pcmBufferB) memset (pcmBufferB, 0 , TOTAL_BUFFER_FRAMES * CHANNEL_COUNT * sizeof (float ));
@@ -466,7 +462,7 @@ struct DecoderStream {
466462 memcpy (&decoder, &other.decoder , sizeof (ma_decoder));
467463
468464 // Move regular members
469- filePosition. store ( other.filePosition , std::memory_order_relaxed) ;
465+ filePosition = other.filePosition ;
470466 bufferStartPos = other.bufferStartPos ;
471467 localReadPos = other.localReadPos ;
472468 validFrames = other.validFrames ;
@@ -783,9 +779,12 @@ class AudioSystem {
783779 s.asyncState .asyncLoadingBuffer = s.pcmBufferC ;
784780
785781 // Store per-decoder latency
786- s.detectedLatency = detectLatency (i);
787- if (s.detectedLatency > detectedLatency) {
788- detectedLatency = s.detectedLatency ;
782+ // the inst starts first so yeah
783+ if (i == 0 ) {
784+ s.detectedLatency = detectLatency (i);
785+ if (s.detectedLatency > detectedLatency) {
786+ detectedLatency = s.detectedLatency ;
787+ }
789788 }
790789
791790 // Fill initial buffer (starts at 0)
@@ -969,6 +968,7 @@ class AudioSystem {
969968 void seekToPCMFrame (int64_t pos) {
970969 if (!exists) return ;
971970
971+ // Pause async loading during seek
972972 if (asyncLoader) {
973973 asyncLoader->pauseLoading ();
974974 }
@@ -981,24 +981,20 @@ class AudioSystem {
981981 for (size_t i = 0 ; i < streams.size (); i++) {
982982 DecoderStream& s = streams[i];
983983
984- ma_uint64 target = pos;
985-
986- printf ( " SEEKING TO TARGET: %lld \n " , ( long long )target);
987- printf ( " Before seek - filePos: %lld, bufferStart: %lld, localRead: %lld \n " ,
988- ( long long )s. filePosition , ( long long )s. bufferStartPos , ( long long )s. localReadPos );
984+ // Seek to the exact position requested
985+ ma_uint64 target = std::min<ma_uint64>(
986+ (ma_uint64)std::max< int64_t >(pos, ( int64_t ) 0 ),
987+ s. decoderLength
988+ );
989989
990- s.resetState (true );
991- s.justSeeked = true ;
990+ s.resetState ();
992991 fillInitialBuffer (i, target);
993992
994- printf (" After seek - filePos: %lld, bufferStart: %lld, localRead: %lld\n " ,
995- (long long )s.filePosition , (long long )s.bufferStartPos , (long long )s.localReadPos );
996-
997- // Verify the math
998- ma_uint64 calculatedFilePos = s.bufferStartPos + s.localReadPos ;
999- printf (" Calculated filePos should be: %lld (matches: %s)\n " ,
1000- (long long )calculatedFilePos, (calculatedFilePos == s.filePosition ) ? " YES" : " NO" );
993+ if (s.active && target < s.decoderLength ) {
994+ s.filePosition = target;
995+ }
1001996
997+ // Aggressively preload both buffers synchronously
1002998 if (s.active ) {
1003999 loadNextBufferSync (i);
10041000 if (s.asyncState .nextBufferReady .load (std::memory_order_relaxed)) {
@@ -1010,6 +1006,7 @@ class AudioSystem {
10101006 mixerState = (pos < (int64_t )streams[longestDecoderIndex].decoderLength ) ? 2 : 3 ;
10111007
10121008 if (wasPlaying && mixerState == 2 ) {
1009+ // Resume async loading before starting playback
10131010 if (asyncLoader) {
10141011 asyncLoader->resumeLoading ();
10151012 }
@@ -1065,7 +1062,6 @@ class AudioSystem {
10651062 void fillInitialBuffer (size_t index, ma_uint64 startFrame) {
10661063 DecoderStream& s = streams[index];
10671064
1068- // Calculate where to start decoding (with padding before the target)
10691065 ma_uint64 decodeStart = 0 ;
10701066 if (startFrame > PADDING_FRAMES) {
10711067 decodeStart = startFrame - PADDING_FRAMES;
@@ -1077,28 +1073,18 @@ class AudioSystem {
10771073 s.bufferStartPos = decodeStart;
10781074 s.validFrames = framesRead;
10791075
1080- // Calculate the local read position within this buffer
1081- if (startFrame >= decodeStart && startFrame < decodeStart + framesRead) {
1076+ if (startFrame >= decodeStart) {
10821077 s.localReadPos = startFrame - decodeStart;
1083- } else if (startFrame < decodeStart) {
1084- s.localReadPos = 0 ;
10851078 } else {
1086- // startFrame is beyond what we loaded
1087- s.localReadPos = framesRead;
1079+ s.localReadPos = 0 ;
10881080 }
10891081
1090- // Ensure localReadPos is within bounds
10911082 if (s.localReadPos >= TOTAL_BUFFER_FRAMES) {
10921083 s.localReadPos = TOTAL_BUFFER_FRAMES - 1 ;
10931084 }
10941085
1095- // Set filePosition to the ACTUAL position we'll start reading from
1096- // This is critical - it should be bufferStart + localReadPos
1097- // printf("before? %lld\n", s.filePosition);
1098- s.filePosition .store (s.bufferStartPos + s.localReadPos , std::memory_order_relaxed);
1099- // printf("after? %lld\n", s.filePosition);
1100-
1101- s.active = (s.filePosition < s.decoderLength && framesRead > 0 );
1086+ s.filePosition = startFrame;
1087+ s.active = (startFrame < s.decoderLength && framesRead > 0 );
11021088 s.asyncState .needsLoad .store (false , std::memory_order_release);
11031089 }
11041090
@@ -1110,7 +1096,6 @@ class AudioSystem {
11101096 return ;
11111097 }
11121098
1113- // Calculate next buffer start from CURRENT buffer position, not file position
11141099 ma_uint64 nextBufferStart = s.bufferStartPos + HALF_BUFFER_FRAMES;
11151100 if (nextBufferStart > PADDING_FRAMES) {
11161101 nextBufferStart -= PADDING_FRAMES;
@@ -1195,11 +1180,8 @@ class AudioSystem {
11951180 return 0 ;
11961181 }
11971182
1198- // Don't swap buffers immediately after seeking
1199- if (!s.justSeeked ) {
1200- if (s.shouldSwapBuffers () || s.isBufferLow ()) {
1201- s.trySwapBuffers ();
1202- }
1183+ if (s.shouldSwapBuffers () || s.isBufferLow ()) {
1184+ s.trySwapBuffers ();
12031185 }
12041186
12051187 ma_uint32 framesRead = 0 ;
@@ -1213,7 +1195,6 @@ class AudioSystem {
12131195 if (available == 0 ) {
12141196 if (s.filePosition < s.decoderLength ) {
12151197 if (s.asyncState .nextBufferReady .load (std::memory_order_acquire)) {
1216- s.justSeeked = false ; // Clear flag before swapping
12171198 s.trySwapBuffers ();
12181199 continue ;
12191200 } else {
@@ -1242,14 +1223,9 @@ class AudioSystem {
12421223 }
12431224
12441225 s.localReadPos += toRead;
1245- s.filePosition . store (s. filePosition . load (std::memory_order_relaxed) + toRead, std::memory_order_relaxed) ;
1226+ s.filePosition += toRead;
12461227 framesRead += toRead;
12471228
1248- // Clear the justSeeked flag after first successful read
1249- if (framesRead > 0 ) {
1250- s.justSeeked = false ;
1251- }
1252-
12531229 if (s.filePosition >= s.decoderLength ) {
12541230 s.active = false ;
12551231 break ;
@@ -2150,7 +2126,7 @@ bool wearingPlugNPlay() {
21502126
21512127int detectLatency () {
21522128 #if HX_WINDOWS
2153- int osMs = 56 ;
2129+ int osMs = 61 ;
21542130 #else
21552131 int osMs = 1 ;
21562132 #endif
@@ -2215,4 +2191,4 @@ float getMixerMasterVolume() {
22152191
22162192void destroyMixer () {
22172193 g_mixer.destroy ();
2218- }
2194+ }
0 commit comments