Fix Mismatching Audio Streamed Buffer Size

This commit is contained in:
Ralty
2025-07-13 21:10:42 +07:00
parent e669eb32af
commit 2ead99cdf4
3 changed files with 19 additions and 17 deletions
+6 -6
View File
@@ -2,11 +2,11 @@ package funkin.backend.utils;
import flixel.sound.FlxSound;
import lime.media.AudioBuffer;
import lime.utils.ArrayBufferView;
#if lime_vorbis
import lime.media.vorbis.Vorbis;
import lime.media.vorbis.VorbisFile;
import lime.utils.ArrayBuffer;
#end
// ORIGINAL CODES FROM YOSH & LUNAR https://github.com/CodenameCrew/YoshiCrafterEngine/blob/main/source/WaveformSprite.hx
@@ -72,12 +72,12 @@ class AudioAnalyzer {
}
#if lime_vorbis // As far i know, only native supports vorbis
var __buffer:ArrayBufferView;
var __buffer:ArrayBuffer;
function __prepareVorbis():Bool @:privateAccess {
if (buffer.__srcVorbisFile == null) return __vorbis != null;
if (__vorbis != null) return true;
if ((__vorbis = buffer.__srcVorbisFile.clone()) != null) { // IM HOPING IT HAVE A GC CLOSURE.
__buffer = new ArrayBufferView(0x1000, buffer.bitsPerSample == 32 ? Int32 : buffer.bitsPerSample == 16 ? Int16 : Int8);
__buffer = new ArrayBuffer(0x400 * buffer.channels * (buffer.bitsPerSample >> 3));
return true;
}
return false;
@@ -95,17 +95,17 @@ class AudioAnalyzer {
prevPos = Math.floor(endPos);
}
var isBigEndian = lime.system.System.endianness == lime.system.Endian.BIG_ENDIAN, bufferSize = __buffer.length, buf = __buffer.buffer;
var isBigEndian = lime.system.System.endianness == lime.system.Endian.BIG_ENDIAN, bufferSize = __buffer.length;
var max = 0, b = 0, pos = 0, w = 0, result;
while (n > 0) {
n -= (result = __vorbis.read(buf, 0, n < bufferSize ? n : bufferSize, isBigEndian, __wordSize, true));
n -= (result = __vorbis.read(__buffer, 0, n < bufferSize ? n : bufferSize, isBigEndian, __wordSize, true));
if (result == Vorbis.HOLE) continue;
else if (result <= 0) break;
while (pos < result) {
while (w < buffer.bitsPerSample) {
b |= #if js buf[pos] #else buf.get(pos) #end << w;
b |= #if js __buffer[pos] #else __buffer.get(pos) #end << w;
w += 8;
pos++;
}
@@ -25,7 +25,7 @@ import lime.utils.ArrayBufferView;
@:access(lime.media.AudioBuffer)
@:access(lime.utils.ArrayBufferView)
class NativeAudioSource {
private static var STREAM_BUFFER_SIZE:Int = 0x4000; // what if it was odd channels (excluding mono).
private static var STREAM_BUFFER_SIZE:Int = 0x1000;
private static var STREAM_MAX_BUFFERS:Int = 32;
private static var STREAM_TIMER_FREQUENCY:Int = 100;
private static var STREAM_BUFFER_FREQUENCY:Int = 6;
@@ -47,6 +47,7 @@ class NativeAudioSource {
private var bufferDatas:Array<ArrayBufferView>;
private var bufferTimes:Array<Float>;
private var bufferSizes:Array<Int>;
private var bufferSize:Int;
private var requestBuffers:Int;
private var queuedBuffers:Int;
private var toLoop:Int;
@@ -107,11 +108,13 @@ class NativeAudioSource {
dataLength = (samples = getFloat(buffer.__srcVorbisFile.pcmTotal())) * buffer.channels * (buffer.bitsPerSample >> 3);
var constructor = buffer.bitsPerSample == 32 ? Int32 : buffer.bitsPerSample == 16 ? Int16 : Int8;
bufferSize = STREAM_BUFFER_SIZE * buffer.channels * (constructor == Int8 ? buffer.bitsPerSample >> 3 : 1);
buffers = AL.genBuffers(STREAM_MAX_BUFFERS);
bufferDatas = [for (i in 0...STREAM_MAX_BUFFERS) new ArrayBufferView(STREAM_BUFFER_SIZE, constructor)];
bufferDatas = [for (i in 0...STREAM_MAX_BUFFERS) new ArrayBufferView(bufferSize, constructor)];
bufferTimes = [for (i in 0...STREAM_MAX_BUFFERS) 0];
bufferSizes = [for (i in 0...STREAM_MAX_BUFFERS) 0];
unusedBuffers = [];
bufferSize *= constructor == Int8 ? 1 : buffer.bitsPerSample >> 3;
}
else #end {
streamed = false;
@@ -184,10 +187,10 @@ class NativeAudioSource {
#if lime_vorbis
var isBigEndian = lime.system.System.endianness == lime.system.Endian.BIG_ENDIAN, wordSize = parent.buffer.bitsPerSample >> 3;
var size = dataLength - (streamTell() * parent.buffer.sampleRate * parent.buffer.channels * wordSize);
var n:Int = size < STREAM_BUFFER_SIZE ? Math.floor(size) : STREAM_BUFFER_SIZE;
var n:Int = size < bufferSize ? Math.floor(size) : bufferSize;
var total = 0, result = 0, wasEOF = false;
while (total < STREAM_BUFFER_SIZE) {
while (total < bufferSize) {
result = n > 0 ? parent.buffer.__srcVorbisFile.read(data.buffer, total, n, isBigEndian, wordSize, true) : 0;
if (result == Vorbis.HOLE) continue;
@@ -200,7 +203,7 @@ class NativeAudioSource {
var samples = getSamples(loopTime != null ? loopTime + parent.offset : parent.offset);
streamSeek(samples);
if ((size = dataLength - (getFloat(samples) * parent.buffer.channels * wordSize)) < (n = STREAM_BUFFER_SIZE - total))
if ((size = dataLength - (getFloat(samples) * parent.buffer.channels * wordSize)) < (n = bufferSize - total))
n = Math.floor(size);
}
}
@@ -211,7 +214,7 @@ class NativeAudioSource {
}
}
if (total < STREAM_BUFFER_SIZE) data.buffer.fill(total, n, 0);
if (total < bufferSize) data.buffer.fill(total, n, 0);
if (result < 0) {
trace('NativeAudioSource Streaming Bug! reading result is $result');
return result;
+4 -5
View File
@@ -164,20 +164,19 @@ import lime.media.openal.AL;
var buffer = __source.buffer;
var wordSize = buffer.bitsPerSample >> 3, bitUnsignedSize = 1 << buffer.bitsPerSample, bitSize = 1 << (buffer.bitsPerSample - 1);
var pos = Math.floor(samples * buffer.channels * wordSize);
var n = Math.floor(Math.min(buffer.sampleRate / 80, 600)), b = 0, w = 0, c = 0, i = 0, size = 0, buf;
var pos = Math.floor(samples * buffer.channels * wordSize), size = 0, i = 0, buf;
pos -= pos % wordSize;
if (backend.streamed) {
buf = backend.bufferDatas[i = NativeAudioSource.STREAM_MAX_BUFFERS - backend.queuedBuffers] #if !js .buffer #end;
pos %= (size = NativeAudioSource.STREAM_BUFFER_SIZE * wordSize);
size = backend.bufferSize;
}
else {
buf = buffer.data #if !js .buffer #end;
size = #if js buf.byteLength #else buf.length #end;
}
pos -= pos % wordSize;
var n = Math.floor(Math.min(buffer.sampleRate / 80, 512)), b = 0, w = 0, c = 0;
while (n > 0) {
if (wordSize == 1) b = #if js buf[pos] #else buf.get(pos) #end - bitSize;
else {