Skip to content

Commit ecb9df3

Browse files
Now here comes the real fix
1 parent 21bd094 commit ecb9df3

File tree

6 files changed

+51
-70
lines changed

6 files changed

+51
-70
lines changed

hdlls/windows/ma_thing.hdll

1.5 KB
Binary file not shown.

src/debug/DeveloperStuff.hx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ class DeveloperStuff {
2020
if (playField == null) return;
2121
switch (code) {
2222
case KeyCode.PERIOD:
23-
playField.setTime(playField.songPosition + 200);
23+
playField.setTime(playField.songPosition + 1500);
2424
case KeyCode.COMMA:
25-
playField.setTime(playField.songPosition - 200);
26-
case KeyCode.S:
27-
playField.setTime(2200);
25+
playField.setTime(playField.songPosition - 1500);
26+
/*case KeyCode.S:
27+
playField.setTime(2200);*/
2828
case KeyCode.NUMBER_9:
2929
if (playField.songStarted)
3030
Mixer.speed -= 0.25;

src/miniaudio/ma_thing.cpp

Lines changed: 39 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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

21512127
int 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

22162192
void destroyMixer() {
22172193
g_mixer.destroy();
2218-
}
2194+
}

src/miniaudio/ma_thing_hl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2135,7 +2135,7 @@ HL_PRIM bool HL_NAME(wearingPlugNPlay)(_NO_ARG) {
21352135

21362136
HL_PRIM int HL_NAME(detectLatency)(_NO_ARG) {
21372137
#if HX_WINDOWS
2138-
int osMs = 56;
2138+
int osMs = 61;
21392139
#else
21402140
int osMs = 1;
21412141
#endif

src/music/Mixer.hx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,9 @@ class Mixer {
8585
}
8686

8787
static function setTime(value:Float, playfield:PlayField) {
88-
MiniAudio.seekToPCMFrame(Tools.betterInt64FromFloat(value * 0.001) * sampleRate);
88+
var pcmFrame = Tools.betterInt64FromFloat(value * (sampleRate / 1000.0));
89+
// Ah HAH! I found it! It's that
90+
MiniAudio.seekToPCMFrame(pcmFrame);
8991
if (playfield != null) {
9092
if (playfield.songEnded) playfield.songPosition = MiniAudio.getPlaybackPosition();
9193
}

src/structures/gameplay/PlayField.hx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ class PlayField implements State {
241241
/**
242242
Updates the playfield.
243243
**/
244+
var lastsongpos:Float = 0;
244245
function update(deltaTime:Float) {
245246
if (disposed || paused) return;
246247

@@ -261,7 +262,7 @@ class PlayField implements State {
261262

262263
if (!died) {
263264
Mixer.update(this, deltaTime);
264-
Sys.println(songPosition);
265+
Sys.println('$songPosition' + (((lastsongpos - songPosition) > 50) ? " (CHANGE ALERT! CHANGE ALERT! CHANGE!)" : ""));
265266

266267
#if !FV_LIME_FORK
267268
// If the song hasn't started yet, update the countdown conductor only.
@@ -298,6 +299,8 @@ class PlayField implements State {
298299
songPosition += latencyCompensation;
299300
songPosition += Mixer.latency();
300301

302+
lastsongpos = songPosition;
303+
301304
return;
302305
}
303306

0 commit comments

Comments
 (0)