Thealexbarney / VGAudio

A library for encoding, decoding, and manipulating audio files from video games.
MIT License
219 stars 37 forks source link

Skyrim NX sound support - MCADPCM and FUZ with OPUS #111

Open ThyWoof opened 5 years ago

ThyWoof commented 5 years ago

Nintendo Switch Skyrim uses 2 container types for sound:

  1. Modified GC DSP codec on a MCADPCM container

    • Used in Music and FX;
    • Supports up to 2 channels;
    • Has a 3 x Uint32 Header for Mono and a 5 x Uint32 Header for Stereo; (channel count, header size, channel0 payload size, [channel1 offset, channel1 payload size];
    • Stores audio payload in GC DSP format but GC DSP header is stored in little-endian;
    • Supports the metadata command;
  2. Skyrim NX OPUS codec on a FUZ container

    • Used in Voices;
    • Supports up to 1 channel (couldn't find any sample with more than 1);
    • OPUS payload has a 5 x Uint32 Header (signature, duration ms, channel count, header size, channel0 payload size);
    • Skyrim NX OPUS header is followed by the standard OPUS header;
    • Skyrim NX stores both a Skyrim NX OPUS payload and a Skyrim NX LIP file (data for lips sync with sound) on a FUZ container;
    • A NX FUZ container has a 4 x Uint32 header (signature, channel count = 1, lip size, Skyrim NX OPUS payload offset);

Added the FUZ logic in VGAudioCli convert.cs itself instead of creating a new container as I did for MCADPCM. Maybe not the best solution but good enough for our requirements on https://github.com/Lord-Akkrand/Skyrim-NX-Toolkit/

ThyWoof commented 5 years ago

With latest change the FUZ logic is now entire contained (no PUN intended) in containers/NxOpusWriter.cs. Much better than previous spaghetti in convert.cs.

Thealexbarney commented 5 years ago

I played around with your additions and wasn't able to convert the created opus with a Skyrim header back to wav.

Does vgmstream support the Skyrim header opus files?

If MCADPCM is just a container for Nintendo's ADPCM, it wouldn't be added to the audio format enum.

I don't know about adding the fuz code. In the past, the decision was that parsing and creating archives/containers that audio files might come in was out-of-scope for the library.

I'll have more detailed feedback when I'm back at my computer and not on my phone.

ThyWoof commented 5 years ago

Fixed the header check on Skyrim OPUS reader but producing an empty wav. will take a look later as had seen this issue before. At least the header recognition is fixed.

Made McAdpcm an audio format as it slightly differs from DSP on header data. Header on McAdpcm is little-endian and data follows this pattern: channel0 header, channel0 data, channel1 header, channel1 data.

DSP does all channels headers first (big-endian) and then DSP data.

Thealexbarney commented 5 years ago

I've made some small tweaks to match the code style.

Creating a Skyrim Opus file won't work unless you're writing it to a FileStream. VGAudio only operates on plain Streams and isn't aware of any kind of underlying filesystem. Any metadata should be passed to the library some other way.

The audio format of mcadpcm files should be GcAdpcm because mcadpcm is a container for audio in that format, just like containers such as brstm contain that formst.