Created
January 3, 2024 07:01
-
-
Save cmathew/6906ed779453d4e78477b5e86b9e9da0 to your computer and use it in GitHub Desktop.
Serialize Frostbite3 SoundWaveAsset chunks into per-channel WAVs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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