Extract a Vorbis page from Vorbis FSB files

Hello!

I’m trying to update an old video game process with a new FMOD version. The previous FMOD version looks to be FMOD Ex 4.26.02. The revision text shows the most recent update was on 16/07/09.

The version of FMOD I’m updating to is version 2.02.11, revision text shows last updated on 1/12/22.

So in broad terms what the old code did was it used FSBank_Build with FSBANK_FORMAT_MP3 and FSBANK_BUILD_BASICHEADERS defined. No encryption flags. This process was that they split a .wav file into channel specific files and then run FSBank_Build on each file. After some other small modifications these files are then passed on to a stream mixer.

The stream mixer handles the small modifications and then breaks up the files into MP3 frames, those frames get inserted into a new file along with and inbetween information from other processes (such as animation and subtitle data) before compressing the resulting file using a secondary process.

On game execution it decompresses the files and reassembles the frames all together into an mp3 encoded FMOD file and uses that along with the FMOD library to create the system and execute sound events and such.

Now updating it is difficult because of two main features, the first feature is that MP3 no longer seems to be supported. Unfortunately I’m unable to find a version of FMOD that both handles new console platforms such as PS5 and XBS as well as supports MP3 (But I also may have missed something certainly).
The second feature is that the new versions of FMOD no longer seem to include BASICHEADER as an argument, and I can’t find any information on if FSBANK_BUILD_DEFAULT does include a default header or if it has no header.

I’ve found that the Vorbis encoding style both supports all the platforms we’re moving to as well as still gives options for compression. As such I’ve changed FSBANK_FORMAT_MP3 to FSBANK_FORMAT_VORBIS. I also spent some time studying Vorbis, including downloading the Vorbis and Ogg libraries from Xiph.org.

From my research I’ve found that Vorbis/Ogg coded files are broken up into pages similar to how MP3 files are broken up into frames. However trying to use the Vorbis examples to extract pages from the fsb files created through FSBank_Build is not working. I’ve found that the files all start with ‘FSB5\x1’ and then move onto the compressed bytes. So I imagine FSB5 is the header versioning given, but I haven’t seen any information on any header information including the FSB5 characters.

The Vorbis library indicated in order to get a page out you read a portion of the file into a buffer and it will try to make a page out of the data in said buffer, however following the example code in decoder_example.c (in the Vorbis library) has provided me with no pages.

I thought I might not know how large the header segment is, so I attempted to read a sufficient buffer size (example is 4096 bytes) starting on every byte in the file to see if any of them could make a page. None of them made a page unfortunately all the way through to the end of the file (minus 4096 bytes).

The specific failing call is ogg_sync_pageout, with a -1 value which indicates that the stream has not yet captured sync (bytes were skipped) so I’m imagining that means it wasn’t started at a page start yet.

Am I missing something? Is there a way to extract a page from the vorbis encoded fsb file in order to try to emulate what the rest of the process expects?

Thank you,
Luke A.

The FMOD API doesn’t actually use ogg at all, however it does use our own version of Vorbis and with our own packet headers (which are 2 bytes and contain the size of the packets).

Navigating the FSB and encoding/decoding manually is a bit outside the intended use of FMOD, if that is something you want to do then by all means but we cannot guarantee the stability of it.

I see. At this moment in time I’m trying to figure out enough about the previous company’s stream mixing/demixing process to see what I can modify safely.

With the packet headers you’ve indicated that seems like a perfect place I can break up the file like they’ve done. With the modified version of Vorbis is there a way to not decode it specifically but at least grab the sizes of the packet headers so I can break it up into those portions?

As I mentioned the packet header is two bytes which contains the actual size, this is stored as a little-endian 16-bit integer.

We use something similar to this:

for (int i = 0; i < length; i++)
{
    packetLength |= readbuffer[i] << (i*8);
}