Skip to content

Instantly share code, notes, and snippets.

@cmathew
Created January 3, 2024 07:01
Show Gist options
  • Save cmathew/6906ed779453d4e78477b5e86b9e9da0 to your computer and use it in GitHub Desktop.
Save cmathew/6906ed779453d4e78477b5e86b9e9da0 to your computer and use it in GitHub Desktop.
Serialize Frostbite3 SoundWaveAsset chunks into per-channel WAVs
// Call this instead of SoundExportMenuItem_Export
private void SoundExportMenuItem_ExportChannels(IList tracks, String baseFilename)
{
// Assume common metadata, derive with first track
SoundDataTrack firstTrack = (SoundDataTrack)tracks[0];
int channelCount = firstTrack.ChannelCount;
WAV.WAVFormatChunk fmt = new WAV.WAVFormatChunk(WAV.WAVFormatChunk.DataFormats.WAVE_FORMAT_PCM, 1, (uint)firstTrack.SampleRate, (uint)(2 * firstTrack.SampleRate), (ushort)2, 16);
FrostyTaskWindow.Show("Exporting Sound", "", task =>
{
for (int channelIndex = 0; channelIndex < channelCount; channelIndex++)
{
String channelFilename = GetChannelFilename(baseFilename, channelIndex);
List<WAV.WAVDataFrame> frames = new List<WAV.WAVDataFrame>();
for (int trackIndex = 0; trackIndex < tracks.Count; trackIndex++)
{
SoundDataTrack thisTrack = (SoundDataTrack) tracks[trackIndex];
int frameCount = thisTrack.Samples.Length / thisTrack.ChannelCount;
for (int frameIndex = 0; frameIndex < frameCount; frameIndex++)
{
// write frame
WAV.WAV16BitDataFrame frame = new WAV.WAV16BitDataFrame((ushort)1);
frame.Data[0] = thisTrack.Samples[frameIndex * thisTrack.ChannelCount + channelIndex];
frames.Add(frame);
}
}
WAV.WAVDataChunk data = new WAV.WAVDataChunk(fmt, frames);
WAV.RIFFMainChunk main = new WAV.RIFFMainChunk(new WAV.RIFFChunkHeader(0, new byte[] { 0x52, 0x49, 0x46, 0x46 }, 0), new byte[] { 0x57, 0x41, 0x56, 0x45 });
using (FileStream stream = new FileStream(channelFilename, FileMode.Create))
using (BinaryWriter writer = new BinaryWriter(stream))
{
main.Write(writer, new List<WAV.IRIFFChunk>(new WAV.IRIFFChunk[] { fmt, data }));
}
}
});
}
// Give each WAV a name (assumes input has at most 4 channels)
private String GetChannelFilename(String baseFilename, int channelIndex)
{
String channelSuffix = null;
if (channelIndex == 0)
{
channelSuffix = "front-left";
} else if (channelIndex == 1)
{
channelSuffix = "front-right";
} else if (channelIndex == 2)
{
channelSuffix = "back-left";
} else if (channelIndex == 3)
{
channelSuffix = "back-right";
}
return baseFilename.Replace(".wav", "-" + channelSuffix + ".wav");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment