From 3ea5d38d22ef829378c8ffe838c33b254980c21e Mon Sep 17 00:00:00 2001 From: Masusder <59669685+Masusder@users.noreply.github.com> Date: Sun, 26 Oct 2025 12:42:01 +0100 Subject: [PATCH 1/2] Large FSB5 files --- Fmod5Sharp/FsbLoader.cs | 41 +++++++++++++++++++++++------------ Fmod5Sharp/Util/Extensions.cs | 14 +++++++----- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/Fmod5Sharp/FsbLoader.cs b/Fmod5Sharp/FsbLoader.cs index ac8a149..7a9a40a 100644 --- a/Fmod5Sharp/FsbLoader.cs +++ b/Fmod5Sharp/FsbLoader.cs @@ -22,9 +22,8 @@ public static class FsbLoader { 10, 96_000 }, }; - private static FmodSoundBank? LoadInternal(byte[] bankBytes, bool throwIfError) + private static FmodSoundBank? LoadInternal(Stream stream, bool throwIfError) { - using MemoryStream stream = new(bankBytes); using BinaryReader reader = new(stream); FmodAudioHeader header = new(reader); @@ -37,24 +36,24 @@ public static class FsbLoader return null; } - List samples = new(); - - //Remove header from data block. - var bankData = bankBytes.AsSpan((int)(header.SizeOfThisHeader + header.SizeOfNameTable + header.SizeOfSampleHeaders)); - + List samples = new(header.Samples.Count); for (var i = 0; i < header.Samples.Count; i++) { var sampleMetadata = header.Samples[i]; - var firstByteOfSample = (int)sampleMetadata.DataOffset; - var lastByteOfSample = (int)header.SizeOfData; + var firstByteOfSample = (long)sampleMetadata.DataOffset; + var lastByteOfSample = (long)header.SizeOfData; if (i < header.Samples.Count - 1) { - lastByteOfSample = (int)header.Samples[i + 1].DataOffset; + lastByteOfSample = (long)header.Samples[i + 1].DataOffset; } - var sample = new FmodSample(sampleMetadata, bankData[firstByteOfSample..lastByteOfSample].ToArray()); + byte[] sampleData = new byte[lastByteOfSample - firstByteOfSample]; + stream.Position = firstByteOfSample; + stream.Read(sampleData, 0, sampleData.Length); + + var sample = new FmodSample(sampleMetadata, sampleData); if (header.SizeOfNameTable > 0) { @@ -64,7 +63,8 @@ public static class FsbLoader nameOffset += header.SizeOfThisHeader + header.SizeOfSampleHeaders; - sample.Name = bankBytes.ReadNullTerminatedString((int)nameOffset); + stream.Position = nameOffset; + sample.Name = stream.ReadNullTerminatedString(); } samples.Add(sample); @@ -73,13 +73,26 @@ public static class FsbLoader return new FmodSoundBank(header, samples); } + public static bool TryLoadFsbFromStream(Stream stream, out FmodSoundBank? bank) + { + bank = LoadInternal(stream, false); + return bank != null; + } + + public static FmodSoundBank LoadFsbFromStream(Stream stream) + => LoadInternal(stream, true)!; + public static bool TryLoadFsbFromByteArray(byte[] bankBytes, out FmodSoundBank? bank) { - bank = LoadInternal(bankBytes, false); + using var stream = new MemoryStream(bankBytes); + bank = LoadInternal(stream, false); return bank != null; } public static FmodSoundBank LoadFsbFromByteArray(byte[] bankBytes) - => LoadInternal(bankBytes, true)!; + { + using var stream = new MemoryStream(bankBytes); + return LoadInternal(stream, true)!; + } } } \ No newline at end of file diff --git a/Fmod5Sharp/Util/Extensions.cs b/Fmod5Sharp/Util/Extensions.cs index 1d63e0e..34e1925 100644 --- a/Fmod5Sharp/Util/Extensions.cs +++ b/Fmod5Sharp/Util/Extensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.IO; using System.Text; @@ -41,13 +42,14 @@ internal static ulong Bits(this ulong raw, int lowestBit, int numBits) return (raw & mask) >> lowestBit; } - internal static string ReadNullTerminatedString(this byte[] bytes, int startOffset) + internal static string ReadNullTerminatedString(this Stream stream) { - var strLen = bytes.AsSpan(startOffset).IndexOf((byte)0); - if (strLen == -1) - throw new("Could not find null terminator"); - - return Encoding.UTF8.GetString(bytes, startOffset, strLen); + List bytes = new(16); + int b; + while ((b = stream.ReadByte()) > 0) + bytes.Add((byte)b); + + return Encoding.UTF8.GetString(bytes.ToArray()); } } } \ No newline at end of file From ee8fa97565d2dc59baea9e58b1596a31828cf626 Mon Sep 17 00:00:00 2001 From: Masusder <59669685+Masusder@users.noreply.github.com> Date: Sun, 26 Oct 2025 13:27:03 +0100 Subject: [PATCH 2/2] I messed up offset --- Fmod5Sharp/FsbLoader.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Fmod5Sharp/FsbLoader.cs b/Fmod5Sharp/FsbLoader.cs index 7a9a40a..aa9268c 100644 --- a/Fmod5Sharp/FsbLoader.cs +++ b/Fmod5Sharp/FsbLoader.cs @@ -36,6 +36,8 @@ public static class FsbLoader return null; } + long dataStartOffset = header.SizeOfThisHeader + header.SizeOfNameTable + header.SizeOfSampleHeaders; + List samples = new(header.Samples.Count); for (var i = 0; i < header.Samples.Count; i++) { @@ -50,7 +52,7 @@ public static class FsbLoader } byte[] sampleData = new byte[lastByteOfSample - firstByteOfSample]; - stream.Position = firstByteOfSample; + stream.Position = dataStartOffset + firstByteOfSample; stream.Read(sampleData, 0, sampleData.Length); var sample = new FmodSample(sampleMetadata, sampleData);