I'm a total laymen with all of this, so sorry if the questions are tedious, but I'm trying to understand how this process works. So are you saying you can take an external .wav, and convert it using the "ffmpeg -i song.wav -c:a libopus -b:a 196k -ar 48000 -ac 2 song_opus.ogg"? And if so, is that something I would have to execute through something like Powershell similar to Masagrator's script for unpacking the Music.pck?
Hey, going to break this response into parts. This would typically work in most cases, yes. You'd do this all through commandline with an ffmpeg binary. (To make this easier, put the wav file in the ffmpeg.exe folder, click the address bar and type cmd.) It'll convert it from WAV to OPUS.
And then you add the "52 49 46 46 28 C7 48 00 57 41 56 45 66 6D 74 20 28 00 00 00 39 30 02 00 80 BB 00 00 00 EE 02 00 04 00 10 00 06 00 C0 03 02 31 00 00 6A FD 8D 00 00 00 00 00 30 2F 48 00 78 97 00 00 73 6D 70 6C 3C" to that file with Hexediting? And then you can repack it into Music.pck?
So in theory, yes, you can rip the header out of one of the non-converted files and replace the first 64 bytes of your new song via a hex editor (0x40),
then save it as a WAV again. This is how I actually ended up swapping the music files for the Final Fantasy games before people developed tools for them. FFXIII, FFXIII-2, FFXIV and I'm sure many others use .SCD which is basically just an OGG wrapped in a few bytes of hex data. Here's the first 64 bytes of the the title theme.
I was also wondering about the loop points. When I did audio files for the Cemu version, in .adx, I never made loop points as the songs just looped automatically. Some faded out and restarted, others, I would trim the song really tight so it would "loop", I'm just wondering, would a converted .wav repacked into Music.pck without loop points, still result in a song that would keep replaying, or would it just go silent after it played once?
You can confirm the headers and encoding of the original WAVs (pre conversion) by using vgmstream's (another binary) metadata function. You'll see they have start and endpoint metadata, which WAVs typically do not possess. You
can add looping metadata using something like Looping Audio Converter, but this is a problem, because I'm pretty sure ffmpeg's libopus encoding doesn't preserve metadata so it gets wiped afterward.
For example running 3BF547BA.wav (the title theme) outputs:
vgmstream-cli -m 3BF547BA.wav
metadata for 3BF547BA.wav
sample rate: 48000 Hz
channels: 2channel mask: 0x3 / FL FR
loop start: 0 samples (0:00.000 seconds)
loop end: 9305449 samples (3:13.864 seconds)
stream total samples: 9305450 (3:13.864 seconds)
encoding: libopus Opus
layout: flat
metadata from: Audiokinetic Wwise RIFF header
bitrate: 196 kbps
play duration: 19090898 samples (6:37.727 seconds)
However, running the WAV file that I encoded with looping metadata through ffmpeg to convert it to OPUS:
vgmstream-cli -m ownsong_opus.ogg
metadata for fixed_opus.ogg
sample rate: 48000 Hz
channels: 2channel mask: 0x3 / FL FR
stream total samples: 11581851 (4:01.289 seconds)
encoding: libopus Opus
layout: flat
metadata from: Ogg Opus header
bitrate: 207 kbps
play duration: 11581851 samples (4:01.289 seconds)
You'll see the start and endpoints are missing in my own file, I can't confirm or deny whether you
need loop points or not, it's only conjecture, but the new WWise format is a lot different to ADX (which is several decades old), I used ADX on the wii version of Xenoblade 1 to change the music too, and again in Sonic Adventure 2 Battle. That's how old the format is lol
Doing this all in Wwise is much easier for me, but far less user friendly for anyone else that's not used to working with it. As I can just hard-encode the header, spit out a WEM file and convert that instead. Admittedly, I haven't tested this manual conversion way all too much, most of this is guesswork from my time modding other switch game music (I modded XB1 DE's music in a similar fashion).
There's also the possibility of needing to also make some changes to the .bnk file. Putting it fairly simply, if the file you're swapping with is larger, it could be a case of the .bnk file (which stores all sorts of important things) rejecting the file altogether as it's a larger size than the original file. That causes all sorts of byte shifts that throw things out of whack.
I won't get much time until the weekend to properly delve into things sadly.
Edit: Hey I can post proof that at least the WWise import method works now (yay for my first 5 posts nerding about music hacking lol)