#include "AssetDumperLoadedSound.h" #include "Sound/WavTypes.h" using namespace IW3; bool AssetDumperLoadedSound::ShouldDump(XAssetInfo* asset) { return true; } void AssetDumperLoadedSound::DumpWavPcm(AssetDumpingContext& context, const LoadedSound* asset, std::ostream& stream) { const auto riffMasterChunkSize = sizeof(WAV_CHUNK_ID_RIFF) + sizeof(uint32_t) + sizeof(WAV_WAVE_ID) + sizeof(WavChunkHeader) + sizeof(WavFormatChunkPcm) + sizeof(WavChunkHeader) + sizeof(asset->sound.info.data_len); stream.write(reinterpret_cast(&WAV_CHUNK_ID_RIFF), sizeof(WAV_CHUNK_ID_RIFF)); stream.write(reinterpret_cast(&riffMasterChunkSize), sizeof(riffMasterChunkSize)); stream.write(reinterpret_cast(&WAV_WAVE_ID), sizeof(WAV_WAVE_ID)); const WavChunkHeader formatChunkHeader { WAV_CHUNK_ID_FMT, sizeof(WavFormatChunkPcm) }; stream.write(reinterpret_cast(&formatChunkHeader), sizeof(formatChunkHeader)); WavFormatChunkPcm formatChunk { WavFormat::PCM, static_cast(asset->sound.info.channels), asset->sound.info.rate, asset->sound.info.rate * asset->sound.info.channels * asset->sound.info.bits / 8, static_cast(asset->sound.info.block_size), static_cast(asset->sound.info.bits) }; stream.write(reinterpret_cast(&formatChunk), sizeof(formatChunk)); const WavChunkHeader dataChunkHeader { WAV_CHUNK_ID_DATA, asset->sound.info.data_len }; stream.write(reinterpret_cast(&dataChunkHeader), sizeof(dataChunkHeader)); stream.write(asset->sound.data, asset->sound.info.data_len); } void AssetDumperLoadedSound::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) { const auto* loadedSound = asset->Asset(); const auto assetFile = context.OpenAssetFile("sound/" + asset->m_name); if (!assetFile) return; auto& stream = *assetFile; switch (static_cast(loadedSound->sound.info.format)) { case WavFormat::PCM: DumpWavPcm(context, loadedSound, stream); break; default: printf("Unknown format %i for loaded sound: %s\n", loadedSound->sound.info.format, loadedSound->name); break; } }