Skip to content

Commit fde4619

Browse files
authored
Support loading large FSB5 chunks (#14)
* Large FSB5 files * I messed up offset
1 parent 9cdb76a commit fde4619

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

Fmod5Sharp/FsbLoader.cs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ public static class FsbLoader
2323
{ 10, 96_000 },
2424
};
2525

26-
private static FmodSoundBank? LoadInternal(byte[] bankBytes, bool throwIfError)
26+
private static FmodSoundBank? LoadInternal(Stream stream, bool throwIfError)
2727
{
28-
using MemoryStream stream = new(bankBytes);
2928
using BinaryReader reader = new(stream);
3029

3130
FmodAudioHeader header = new(reader);
@@ -38,24 +37,26 @@ public static class FsbLoader
3837
return null;
3938
}
4039

41-
List<FmodSample> samples = new();
42-
43-
//Remove header from data block.
44-
var bankData = bankBytes.AsSpan((int)(header.SizeOfThisHeader + header.SizeOfNameTable + header.SizeOfSampleHeaders));
40+
long dataStartOffset = header.SizeOfThisHeader + header.SizeOfNameTable + header.SizeOfSampleHeaders;
4541

42+
List<FmodSample> samples = new(header.Samples.Count);
4643
for (var i = 0; i < header.Samples.Count; i++)
4744
{
4845
var sampleMetadata = header.Samples[i];
4946

50-
var firstByteOfSample = (int)sampleMetadata.DataOffset;
51-
var lastByteOfSample = (int)header.SizeOfData;
47+
var firstByteOfSample = (long)sampleMetadata.DataOffset;
48+
var lastByteOfSample = (long)header.SizeOfData;
5249

5350
if (i < header.Samples.Count - 1)
5451
{
55-
lastByteOfSample = (int)header.Samples[i + 1].DataOffset;
52+
lastByteOfSample = (long)header.Samples[i + 1].DataOffset;
5653
}
5754

58-
var sample = new FmodSample(sampleMetadata, bankData[firstByteOfSample..lastByteOfSample].ToArray());
55+
byte[] sampleData = new byte[lastByteOfSample - firstByteOfSample];
56+
stream.Position = dataStartOffset + firstByteOfSample;
57+
stream.Read(sampleData, 0, sampleData.Length);
58+
59+
var sample = new FmodSample(sampleMetadata, sampleData);
5960

6061
if (header.SizeOfNameTable > 0)
6162
{
@@ -65,7 +66,8 @@ public static class FsbLoader
6566

6667
nameOffset += header.SizeOfThisHeader + header.SizeOfSampleHeaders;
6768

68-
sample.Name = bankBytes.ReadNullTerminatedString((int)nameOffset);
69+
stream.Position = nameOffset;
70+
sample.Name = stream.ReadNullTerminatedString();
6971
}
7072

7173
samples.Add(sample);
@@ -74,13 +76,26 @@ public static class FsbLoader
7476
return new FmodSoundBank(header, samples);
7577
}
7678

79+
public static bool TryLoadFsbFromStream(Stream stream, out FmodSoundBank? bank)
80+
{
81+
bank = LoadInternal(stream, false);
82+
return bank != null;
83+
}
84+
85+
public static FmodSoundBank LoadFsbFromStream(Stream stream)
86+
=> LoadInternal(stream, true)!;
87+
7788
public static bool TryLoadFsbFromByteArray(byte[] bankBytes, out FmodSoundBank? bank)
7889
{
79-
bank = LoadInternal(bankBytes, false);
90+
using var stream = new MemoryStream(bankBytes);
91+
bank = LoadInternal(stream, false);
8092
return bank != null;
8193
}
8294

8395
public static FmodSoundBank LoadFsbFromByteArray(byte[] bankBytes)
84-
=> LoadInternal(bankBytes, true)!;
96+
{
97+
using var stream = new MemoryStream(bankBytes);
98+
return LoadInternal(stream, true)!;
99+
}
85100
}
86101
}

Fmod5Sharp/Util/Extensions.cs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Text;
45

@@ -41,13 +42,14 @@ internal static ulong Bits(this ulong raw, int lowestBit, int numBits)
4142
return (raw & mask) >> lowestBit;
4243
}
4344

44-
internal static string ReadNullTerminatedString(this byte[] bytes, int startOffset)
45+
internal static string ReadNullTerminatedString(this Stream stream)
4546
{
46-
var strLen = bytes.AsSpan(startOffset).IndexOf((byte)0);
47-
if (strLen == -1)
48-
throw new("Could not find null terminator");
49-
50-
return Encoding.UTF8.GetString(bytes, startOffset, strLen);
47+
List<byte> bytes = new(16);
48+
int b;
49+
while ((b = stream.ReadByte()) > 0)
50+
bytes.Add((byte)b);
51+
52+
return Encoding.UTF8.GetString(bytes.ToArray());
5153
}
5254
}
5355
}

0 commit comments

Comments
 (0)