Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Fmod5Sharp/CodecRebuilders/FmodVorbisRebuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ private static void ReadSamplePackets(BinaryReader inputReader, out List<int> pa
{
var packetSize = inputReader.ReadUInt16();

if (packetSize == 0)
if (packetSize == 0 || packetSize == 0xFFFF)
break; //EOS

packetLengths.Add(packetSize);
Expand Down
65 changes: 35 additions & 30 deletions Fmod5Sharp/FmodTypes/FmodSampleMetadata.cs
Original file line number Diff line number Diff line change
@@ -1,38 +1,43 @@
using System.Collections.Generic;
using Fmod5Sharp.Util;
using System.Collections.Generic;
using System.IO;
using Fmod5Sharp.Util;

namespace Fmod5Sharp.FmodTypes
{
public class FmodSampleMetadata : IBinaryReadable
{
internal bool HasAnyChunks;
internal uint FrequencyId;
internal ulong DataOffset;
internal List<FmodSampleChunk> Chunks = new();
Comment on lines 7 to 12
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't make formatting changes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure

internal int NumChannels;
public class FmodSampleMetadata : IBinaryReadable
{
internal bool HasAnyChunks;
internal uint FrequencyId;
internal ulong DataOffset;
internal List<FmodSampleChunk> Chunks = new();
internal int NumChannels;

public bool IsStereo;
public ulong SampleCount;
public bool IsStereo;
public ulong SampleCount;

public int Frequency => FsbLoader.Frequencies.TryGetValue(FrequencyId, out var actualFrequency) ? actualFrequency : (int)FrequencyId; //If set by FREQUENCY chunk, id is actual frequency
public uint Channels => (uint)NumChannels;
public int Frequency => FsbLoader.Frequencies.TryGetValue(FrequencyId, out var actualFrequency) ? actualFrequency : (int)FrequencyId; // If set by FREQUENCY chunk, id is actual frequency
public uint Channels => (uint)NumChannels;

void IBinaryReadable.Read(BinaryReader reader)
{
var encoded = reader.ReadUInt64();

HasAnyChunks = (encoded & 1) == 1; //Bit 0
FrequencyId = (uint) encoded.Bits( 1, 4); //Bits 1-4
var pow2 = (int) encoded.Bits(5, 2); //Bits 5-6
NumChannels = 1 << pow2;
if (NumChannels > 2)
throw new("> 2 channels not supported");

IsStereo = NumChannels == 2;

DataOffset = encoded.Bits(7, 27) * 32;
SampleCount = encoded.Bits(34, 30);
}
}
void IBinaryReadable.Read(BinaryReader reader)
{
var sampleMode = reader.ReadUInt64();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the name change?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify what it represents. I’ve reverted it back to how it was if that’s an issue


HasAnyChunks = (sampleMode & 1) == 1; // Bit 0
FrequencyId = (uint)sampleMode.Bits(1, 4); // Bits 1-4

int channelBits = (int)sampleMode.Bits(5, 2); // Bits 5-6
NumChannels = channelBits switch
{
0 => 1,
1 => 2,
2 => 6,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this 4?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be 6, that's the whole point

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any FMOD documentation about this?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think there is any, all I can give you is an example of converted audio:
4 channels
vs
6 channels

Tested on soundbanks from three different games

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From FMOD::CodecFSB5::decodeSubSoundHeader:

18001644e        if (channels != 0)
180016462            int128_t __xmm@00000008000000060000000200000001_1 =
180016462                __xmm@00000008000000060000000200000001
18001646c            *channels = *(&__xmm@00000008000000060000000200000001_1
18001646c                + ((zx.q((r10 u>> 5).d) & 3) << 2))

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From FMOD::CodecFSB5::decodeSubSoundHeader:

18001644e        if (channels != 0)
180016462            int128_t __xmm@00000008000000060000000200000001_1 =
180016462                __xmm@00000008000000060000000200000001
18001646c            *channels = *(&__xmm@00000008000000060000000200000001_1
18001646c                + ((zx.q((r10 u>> 5).d) & 3) << 2))

@ds5678 and after looking at this it appears that frequencies table was also incorrect, so I also changed it
Correct one should match to this:

180016472        if (frequency != 0)
180016493            __builtin_memcpy(dest: &var_58, 
180016493                src: "\xa0\x0f\x00\x00\x40\x1f\x00\x00\xf8\x2a\x00\x00\xe0\x2e\x00\x00\x80\x3e"
180016493            "00\x00\x22\x56\x00\x00\xc0\x5d\x00\x00\x00\x7d\x00\x00\x44\xac\x00\x00\x80\xbb"
180016493            "00\x00\x00\x77\x01\x00", 
180016493                count: 0x2c)
1800164b2            *frequency = *(&var_58 + ((zx.q((r10 u>> 1).d) & 0xf) << 2))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From FMOD::CodecFSB5::decodeSubSoundHeader

Please document in the code that the behavior can be verified by disassembling this function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

3 => 8,
_ => throw new("Number of channels not supported"),
};
IsStereo = NumChannels == 2;

DataOffset = sampleMode.Bits(7, 27) * 32;
SampleCount = sampleMode.Bits(34, 30);
}
}
}