From 58de885ebe078371af586adc689a7f643641fe51 Mon Sep 17 00:00:00 2001 From: Jan Laupetin Date: Thu, 31 Jul 2025 20:57:13 +0100 Subject: [PATCH] refactor: streamline sound dumping --- src/ObjLoading/Game/T6/ObjLoaderT6.cpp | 2 +- .../Game/T6/Sound/LoaderSoundBankT6.cpp | 2 +- .../Game/T6/Sound/LoaderSoundBankT6.h | 2 +- src/ObjWriting/Game/IW3/ObjWriterIW3.cpp | 4 +- .../Game/IW3/Sound/AssetDumperLoadedSound.cpp | 46 -- .../Game/IW3/Sound/LoadedSoundDumperIW3.cpp | 52 +++ ...erLoadedSound.h => LoadedSoundDumperIW3.h} | 8 +- src/ObjWriting/Game/IW4/ObjWriterIW4.cpp | 8 +- .../Game/IW4/Sound/AssetDumperLoadedSound.cpp | 46 -- .../Game/IW4/Sound/AssetDumperSndCurve.cpp | 39 -- .../Game/IW4/Sound/LoadedSoundDumperIW4.cpp | 52 +++ ...erLoadedSound.h => LoadedSoundDumperIW4.h} | 8 +- .../Game/IW4/Sound/SndCurveDumperIW4.cpp | 45 ++ ...etDumperSndCurve.h => SndCurveDumperIW4.h} | 8 +- src/ObjWriting/Game/IW5/ObjWriterIW5.cpp | 4 +- .../Game/IW5/Sound/AssetDumperLoadedSound.cpp | 46 -- .../Game/IW5/Sound/LoadedSoundDumperIW5.cpp | 52 +++ ...erLoadedSound.h => LoadedSoundDumperIW5.h} | 8 +- src/ObjWriting/Game/T5/ObjWriterT5.cpp | 1 - .../Game/T5/Sound/AssetDumperSndBank.cpp | 0 .../Game/T5/Sound/AssetDumperSndBank.h | 0 src/ObjWriting/Game/T6/ObjWriterT6.cpp | 8 +- .../T6/Sound/AssetDumperSndDriverGlobals.cpp | 385 ----------------- ...tDumperSndBank.cpp => SndBankDumperT6.cpp} | 21 +- ...AssetDumperSndBank.h => SndBankDumperT6.h} | 8 +- .../T6/Sound/SndDriverGlobalsDumperT6.cpp | 392 ++++++++++++++++++ ...erGlobals.h => SndDriverGlobalsDumperT6.h} | 8 +- 27 files changed, 638 insertions(+), 617 deletions(-) delete mode 100644 src/ObjWriting/Game/IW3/Sound/AssetDumperLoadedSound.cpp create mode 100644 src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.cpp rename src/ObjWriting/Game/IW3/Sound/{AssetDumperLoadedSound.h => LoadedSoundDumperIW3.h} (58%) delete mode 100644 src/ObjWriting/Game/IW4/Sound/AssetDumperLoadedSound.cpp delete mode 100644 src/ObjWriting/Game/IW4/Sound/AssetDumperSndCurve.cpp create mode 100644 src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.cpp rename src/ObjWriting/Game/IW4/Sound/{AssetDumperLoadedSound.h => LoadedSoundDumperIW4.h} (58%) create mode 100644 src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.cpp rename src/ObjWriting/Game/IW4/Sound/{AssetDumperSndCurve.h => SndCurveDumperIW4.h} (59%) delete mode 100644 src/ObjWriting/Game/IW5/Sound/AssetDumperLoadedSound.cpp create mode 100644 src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.cpp rename src/ObjWriting/Game/IW5/Sound/{AssetDumperLoadedSound.h => LoadedSoundDumperIW5.h} (58%) delete mode 100644 src/ObjWriting/Game/T5/Sound/AssetDumperSndBank.cpp delete mode 100644 src/ObjWriting/Game/T5/Sound/AssetDumperSndBank.h delete mode 100644 src/ObjWriting/Game/T6/Sound/AssetDumperSndDriverGlobals.cpp rename src/ObjWriting/Game/T6/Sound/{AssetDumperSndBank.cpp => SndBankDumperT6.cpp} (98%) rename src/ObjWriting/Game/T6/Sound/{AssetDumperSndBank.h => SndBankDumperT6.h} (61%) create mode 100644 src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.cpp rename src/ObjWriting/Game/T6/Sound/{AssetDumperSndDriverGlobals.h => SndDriverGlobalsDumperT6.h} (59%) diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index a1f029f3..7ebfbc3b 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -403,7 +403,7 @@ namespace T6 collection.AddAssetCreator(CreateMaterialLoader(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); collection.AddAssetCreator(CreateImageLoader(memory, searchPath)); - collection.AddAssetCreator(CreateSoundBankLoader(memory, searchPath)); + collection.AddAssetCreator(sound::CreateSoundBankLoader(memory, searchPath)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); // collection.AddAssetCreator(std::make_unique(memory)); diff --git a/src/ObjLoading/Game/T6/Sound/LoaderSoundBankT6.cpp b/src/ObjLoading/Game/T6/Sound/LoaderSoundBankT6.cpp index f72d2a77..eac377d0 100644 --- a/src/ObjLoading/Game/T6/Sound/LoaderSoundBankT6.cpp +++ b/src/ObjLoading/Game/T6/Sound/LoaderSoundBankT6.cpp @@ -1079,7 +1079,7 @@ namespace }; } // namespace -namespace T6 +namespace T6::sound { std::unique_ptr> CreateSoundBankLoader(MemoryManager& memory, ISearchPath& searchPath) { diff --git a/src/ObjLoading/Game/T6/Sound/LoaderSoundBankT6.h b/src/ObjLoading/Game/T6/Sound/LoaderSoundBankT6.h index 6e99e962..6bc4a5df 100644 --- a/src/ObjLoading/Game/T6/Sound/LoaderSoundBankT6.h +++ b/src/ObjLoading/Game/T6/Sound/LoaderSoundBankT6.h @@ -7,7 +7,7 @@ #include -namespace T6 +namespace T6::sound { std::unique_ptr> CreateSoundBankLoader(MemoryManager& memory, ISearchPath& searchPath); } // namespace T6 diff --git a/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp b/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp index 2c5d2e13..8a7ce5e0 100644 --- a/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp +++ b/src/ObjWriting/Game/IW3/ObjWriterIW3.cpp @@ -8,7 +8,7 @@ #include "Maps/MapEntsDumperIW3.h" #include "ObjWriting.h" #include "RawFile/RawFileDumperIW3.h" -#include "Sound/AssetDumperLoadedSound.h" +#include "Sound/LoadedSoundDumperIW3.h" #include "StringTable/StringTableDumperIW3.h" #include "Weapon/AssetDumperWeapon.h" @@ -33,7 +33,7 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const DUMP_ASSET_POOL(image::Dumper, m_image, ASSET_TYPE_IMAGE) // DUMP_ASSET_POOL(AssetDumpersnd_alias_list_t, m_sound, ASSET_TYPE_SOUND) // DUMP_ASSET_POOL(AssetDumperSndCurve, m_sound_curve, ASSET_TYPE_SOUND_CURVE) - DUMP_ASSET_POOL(AssetDumperLoadedSound, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) + DUMP_ASSET_POOL(sound::LoadedSoundDumper, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) // DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map, ASSET_TYPE_CLIPMAP_PVS) // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) // DUMP_ASSET_POOL(AssetDumperGameWorldSp, m_game_world_sp, ASSET_TYPE_GAMEWORLD_SP) diff --git a/src/ObjWriting/Game/IW3/Sound/AssetDumperLoadedSound.cpp b/src/ObjWriting/Game/IW3/Sound/AssetDumperLoadedSound.cpp deleted file mode 100644 index de40981f..00000000 --- a/src/ObjWriting/Game/IW3/Sound/AssetDumperLoadedSound.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "AssetDumperLoadedSound.h" - -#include "Sound/WavTypes.h" -#include "Sound/WavWriter.h" - -#include - -using namespace IW3; - -bool AssetDumperLoadedSound::ShouldDump(XAssetInfo* asset) -{ - return true; -} - -void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream) -{ - const WavWriter writer(stream); - - const WavMetaData metaData{.channelCount = static_cast(asset->sound.info.channels), - .samplesPerSec = static_cast(asset->sound.info.rate), - .bitsPerSample = static_cast(asset->sound.info.bits)}; - - writer.WritePcmHeader(metaData, asset->sound.info.data_len); - writer.WritePcmData(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(std::format("sound/{}", asset->m_name)); - - if (!assetFile) - return; - - auto& stream = *assetFile; - switch (static_cast(loadedSound->sound.info.format)) - { - case WavFormat::PCM: - DumpWavPcm(loadedSound, stream); - break; - - default: - std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name); - break; - } -} diff --git a/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.cpp b/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.cpp new file mode 100644 index 00000000..4e3ab817 --- /dev/null +++ b/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.cpp @@ -0,0 +1,52 @@ +#include "LoadedSoundDumperIW3.h" + +#include "Sound/WavTypes.h" +#include "Sound/WavWriter.h" + +#include + +using namespace IW3; + +namespace +{ + void DumpWavPcm(const LoadedSound* asset, std::ostream& stream) + { + const WavWriter writer(stream); + + const WavMetaData metaData{.channelCount = static_cast(asset->sound.info.channels), + .samplesPerSec = static_cast(asset->sound.info.rate), + .bitsPerSample = static_cast(asset->sound.info.bits)}; + + writer.WritePcmHeader(metaData, asset->sound.info.data_len); + writer.WritePcmData(asset->sound.data, asset->sound.info.data_len); + } +} // namespace + +namespace IW3::sound +{ + bool LoadedSoundDumper::ShouldDump(XAssetInfo* asset) + { + return true; + } + + void LoadedSoundDumper::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + { + const auto* loadedSound = asset->Asset(); + const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name)); + + if (!assetFile) + return; + + auto& stream = *assetFile; + switch (static_cast(loadedSound->sound.info.format)) + { + case WavFormat::PCM: + DumpWavPcm(loadedSound, stream); + break; + + default: + std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name); + break; + } + } +} // namespace IW3::sound diff --git a/src/ObjWriting/Game/IW3/Sound/AssetDumperLoadedSound.h b/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.h similarity index 58% rename from src/ObjWriting/Game/IW3/Sound/AssetDumperLoadedSound.h rename to src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.h index 239e3b5b..cfe8b811 100644 --- a/src/ObjWriting/Game/IW3/Sound/AssetDumperLoadedSound.h +++ b/src/ObjWriting/Game/IW3/Sound/LoadedSoundDumperIW3.h @@ -3,14 +3,12 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW3/IW3.h" -namespace IW3 +namespace IW3::sound { - class AssetDumperLoadedSound final : public AbstractAssetDumper + class LoadedSoundDumper final : public AbstractAssetDumper { - static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream); - protected: bool ShouldDump(XAssetInfo* asset) override; void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; }; -} // namespace IW3 +} // namespace IW3::sound diff --git a/src/ObjWriting/Game/IW4/ObjWriterIW4.cpp b/src/ObjWriting/Game/IW4/ObjWriterIW4.cpp index 2dfd1df1..3723fbe2 100644 --- a/src/ObjWriting/Game/IW4/ObjWriterIW4.cpp +++ b/src/ObjWriting/Game/IW4/ObjWriterIW4.cpp @@ -17,8 +17,8 @@ #include "RawFile/RawFileDumperIW4.h" #include "Shader/AssetDumperPixelShader.h" #include "Shader/AssetDumperVertexShader.h" -#include "Sound/AssetDumperLoadedSound.h" -#include "Sound/AssetDumperSndCurve.h" +#include "Sound/LoadedSoundDumperIW4.h" +#include "Sound/SndCurveDumperIW4.h" #include "StringTable/StringTableDumperIW4.h" #include "StructuredDataDef/AssetDumperStructuredDataDefSet.h" #include "Techset/TechsetDumperIW4.h" @@ -52,8 +52,8 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const DUMP_ASSET_POOL(techset::Dumper, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) DUMP_ASSET_POOL(image::Dumper, m_image, ASSET_TYPE_IMAGE) // DUMP_ASSET_POOL(AssetDumpersnd_alias_list_t, m_sound, ASSET_TYPE_SOUND) - DUMP_ASSET_POOL(AssetDumperSndCurve, m_sound_curve, ASSET_TYPE_SOUND_CURVE) - DUMP_ASSET_POOL(AssetDumperLoadedSound, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) + DUMP_ASSET_POOL(sound::SndCurveDumper, m_sound_curve, ASSET_TYPE_SOUND_CURVE) + DUMP_ASSET_POOL(sound::LoadedSoundDumper, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) // DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map, ASSET_TYPE_CLIPMAP_MP) // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) // DUMP_ASSET_POOL(AssetDumperGameWorldSp, m_game_world_sp, ASSET_TYPE_GAMEWORLD_SP) diff --git a/src/ObjWriting/Game/IW4/Sound/AssetDumperLoadedSound.cpp b/src/ObjWriting/Game/IW4/Sound/AssetDumperLoadedSound.cpp deleted file mode 100644 index 7348db5e..00000000 --- a/src/ObjWriting/Game/IW4/Sound/AssetDumperLoadedSound.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "AssetDumperLoadedSound.h" - -#include "Sound/WavTypes.h" -#include "Sound/WavWriter.h" - -#include - -using namespace IW4; - -bool AssetDumperLoadedSound::ShouldDump(XAssetInfo* asset) -{ - return true; -} - -void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream) -{ - const WavWriter writer(stream); - - const WavMetaData metaData{.channelCount = static_cast(asset->sound.info.channels), - .samplesPerSec = static_cast(asset->sound.info.rate), - .bitsPerSample = static_cast(asset->sound.info.bits)}; - - writer.WritePcmHeader(metaData, asset->sound.info.data_len); - writer.WritePcmData(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(std::format("sound/{}", asset->m_name)); - - if (!assetFile) - return; - - auto& stream = *assetFile; - switch (static_cast(loadedSound->sound.info.format)) - { - case WavFormat::PCM: - DumpWavPcm(loadedSound, stream); - break; - - default: - std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name); - break; - } -} diff --git a/src/ObjWriting/Game/IW4/Sound/AssetDumperSndCurve.cpp b/src/ObjWriting/Game/IW4/Sound/AssetDumperSndCurve.cpp deleted file mode 100644 index 71958fbb..00000000 --- a/src/ObjWriting/Game/IW4/Sound/AssetDumperSndCurve.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "AssetDumperSndCurve.h" - -#include "Dumping/SndCurve/SndCurveDumper.h" - -#include - -using namespace IW4; - -std::string AssetDumperSndCurve::GetAssetFilename(const std::string& assetName) -{ - std::ostringstream ss; - - ss << "soundaliases/" << assetName << ".vfcurve"; - - return ss.str(); -} - -bool AssetDumperSndCurve::ShouldDump(XAssetInfo* asset) -{ - return true; -} - -void AssetDumperSndCurve::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) -{ - const auto* sndCurve = asset->Asset(); - - const auto assetFile = context.OpenAssetFile(GetAssetFilename(sndCurve->filename)); - - if (!assetFile) - return; - - SndCurveDumper dumper(*assetFile); - - const auto knotCount = std::min(static_cast(sndCurve->knotCount), std::extent_v); - dumper.Init(knotCount); - - for (auto i = 0u; i < knotCount; i++) - dumper.WriteKnot(sndCurve->knots[i][0], sndCurve->knots[i][1]); -} diff --git a/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.cpp b/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.cpp new file mode 100644 index 00000000..8a363418 --- /dev/null +++ b/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.cpp @@ -0,0 +1,52 @@ +#include "LoadedSoundDumperIW4.h" + +#include "Sound/WavTypes.h" +#include "Sound/WavWriter.h" + +#include + +using namespace IW4; + +namespace +{ + void DumpWavPcm(const LoadedSound* asset, std::ostream& stream) + { + const WavWriter writer(stream); + + const WavMetaData metaData{.channelCount = static_cast(asset->sound.info.channels), + .samplesPerSec = static_cast(asset->sound.info.rate), + .bitsPerSample = static_cast(asset->sound.info.bits)}; + + writer.WritePcmHeader(metaData, asset->sound.info.data_len); + writer.WritePcmData(asset->sound.data, asset->sound.info.data_len); + } +} // namespace + +namespace IW4::sound +{ + bool LoadedSoundDumper::ShouldDump(XAssetInfo* asset) + { + return true; + } + + void LoadedSoundDumper::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + { + const auto* loadedSound = asset->Asset(); + const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name)); + + if (!assetFile) + return; + + auto& stream = *assetFile; + switch (static_cast(loadedSound->sound.info.format)) + { + case WavFormat::PCM: + DumpWavPcm(loadedSound, stream); + break; + + default: + std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name); + break; + } + } +} // namespace IW4::sound diff --git a/src/ObjWriting/Game/IW4/Sound/AssetDumperLoadedSound.h b/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.h similarity index 58% rename from src/ObjWriting/Game/IW4/Sound/AssetDumperLoadedSound.h rename to src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.h index 8065af76..2799152c 100644 --- a/src/ObjWriting/Game/IW4/Sound/AssetDumperLoadedSound.h +++ b/src/ObjWriting/Game/IW4/Sound/LoadedSoundDumperIW4.h @@ -3,14 +3,12 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -namespace IW4 +namespace IW4::sound { - class AssetDumperLoadedSound final : public AbstractAssetDumper + class LoadedSoundDumper final : public AbstractAssetDumper { - static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream); - protected: bool ShouldDump(XAssetInfo* asset) override; void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; }; -} // namespace IW4 +} // namespace IW4::sound diff --git a/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.cpp b/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.cpp new file mode 100644 index 00000000..f5a38e94 --- /dev/null +++ b/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.cpp @@ -0,0 +1,45 @@ +#include "SndCurveDumperIW4.h" + +#include "Dumping/SndCurve/SndCurveDumper.h" + +#include + +using namespace IW4; + +namespace +{ + std::string GetAssetFilename(const std::string& assetName) + { + std::ostringstream ss; + + ss << "soundaliases/" << assetName << ".vfcurve"; + + return ss.str(); + } +} // namespace + +namespace IW4::sound +{ + bool SndCurveDumper::ShouldDump(XAssetInfo* asset) + { + return true; + } + + void SndCurveDumper::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + { + const auto* sndCurve = asset->Asset(); + + const auto assetFile = context.OpenAssetFile(GetAssetFilename(sndCurve->filename)); + + if (!assetFile) + return; + + ::SndCurveDumper dumper(*assetFile); + + const auto knotCount = std::min(static_cast(sndCurve->knotCount), std::extent_v); + dumper.Init(knotCount); + + for (auto i = 0u; i < knotCount; i++) + dumper.WriteKnot(sndCurve->knots[i][0], sndCurve->knots[i][1]); + } +} // namespace IW4::sound diff --git a/src/ObjWriting/Game/IW4/Sound/AssetDumperSndCurve.h b/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.h similarity index 59% rename from src/ObjWriting/Game/IW4/Sound/AssetDumperSndCurve.h rename to src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.h index 0139fafe..18cc1264 100644 --- a/src/ObjWriting/Game/IW4/Sound/AssetDumperSndCurve.h +++ b/src/ObjWriting/Game/IW4/Sound/SndCurveDumperIW4.h @@ -3,14 +3,12 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW4/IW4.h" -namespace IW4 +namespace IW4::sound { - class AssetDumperSndCurve final : public AbstractAssetDumper + class SndCurveDumper final : public AbstractAssetDumper { - static std::string GetAssetFilename(const std::string& assetName); - protected: bool ShouldDump(XAssetInfo* asset) override; void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; }; -} // namespace IW4 +} // namespace IW4::sound diff --git a/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp b/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp index 5bf579ea..43ce039f 100644 --- a/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp +++ b/src/ObjWriting/Game/IW5/ObjWriterIW5.cpp @@ -12,7 +12,7 @@ #include "ObjWriting.h" #include "RawFile/RawFileDumperIW5.h" #include "Script/ScriptDumperIW5.h" -#include "Sound/AssetDumperLoadedSound.h" +#include "Sound/LoadedSoundDumperIW5.h" #include "StringTable/StringTableDumperIW5.h" #include "Weapon/AssetDumperWeapon.h" #include "Weapon/AssetDumperWeaponAttachment.h" @@ -42,7 +42,7 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const DUMP_ASSET_POOL(image::Dumper, m_image, ASSET_TYPE_IMAGE) // DUMP_ASSET_POOL(AssetDumpersnd_alias_list_t, m_sound, ASSET_TYPE_SOUND) // DUMP_ASSET_POOL(AssetDumperSndCurve, m_sound_curve, ASSET_TYPE_SOUND_CURVE) - DUMP_ASSET_POOL(AssetDumperLoadedSound, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) + DUMP_ASSET_POOL(sound::LoadedSoundDumper, m_loaded_sound, ASSET_TYPE_LOADED_SOUND) // DUMP_ASSET_POOL(AssetDumperclipMap_t, m_clip_map, ASSET_TYPE_CLIPMAP) // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) // DUMP_ASSET_POOL(AssetDumperGlassWorld, m_glass_world, ASSET_TYPE_GLASSWORLD) diff --git a/src/ObjWriting/Game/IW5/Sound/AssetDumperLoadedSound.cpp b/src/ObjWriting/Game/IW5/Sound/AssetDumperLoadedSound.cpp deleted file mode 100644 index 7cb254e2..00000000 --- a/src/ObjWriting/Game/IW5/Sound/AssetDumperLoadedSound.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include "AssetDumperLoadedSound.h" - -#include "Sound/WavTypes.h" -#include "Sound/WavWriter.h" - -#include - -using namespace IW5; - -bool AssetDumperLoadedSound::ShouldDump(XAssetInfo* asset) -{ - return true; -} - -void AssetDumperLoadedSound::DumpWavPcm(const LoadedSound* asset, std::ostream& stream) -{ - const WavWriter writer(stream); - - const WavMetaData metaData{.channelCount = static_cast(asset->sound.info.channels), - .samplesPerSec = static_cast(asset->sound.info.rate), - .bitsPerSample = static_cast(asset->sound.info.bits)}; - - writer.WritePcmHeader(metaData, asset->sound.info.data_len); - writer.WritePcmData(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(std::format("sound/{}", asset->m_name)); - - if (!assetFile) - return; - - auto& stream = *assetFile; - switch (static_cast(loadedSound->sound.info.format)) - { - case WavFormat::PCM: - DumpWavPcm(loadedSound, stream); - break; - - default: - std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name); - break; - } -} diff --git a/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.cpp b/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.cpp new file mode 100644 index 00000000..8feae9b7 --- /dev/null +++ b/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.cpp @@ -0,0 +1,52 @@ +#include "LoadedSoundDumperIW5.h" + +#include "Sound/WavTypes.h" +#include "Sound/WavWriter.h" + +#include + +using namespace IW5; + +namespace +{ + void DumpWavPcm(const LoadedSound* asset, std::ostream& stream) + { + const WavWriter writer(stream); + + const WavMetaData metaData{.channelCount = static_cast(asset->sound.info.channels), + .samplesPerSec = static_cast(asset->sound.info.rate), + .bitsPerSample = static_cast(asset->sound.info.bits)}; + + writer.WritePcmHeader(metaData, asset->sound.info.data_len); + writer.WritePcmData(asset->sound.data, asset->sound.info.data_len); + } +} // namespace + +namespace IW5::sound +{ + bool LoadedSoundDumper::ShouldDump(XAssetInfo* asset) + { + return true; + } + + void LoadedSoundDumper::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) + { + const auto* loadedSound = asset->Asset(); + const auto assetFile = context.OpenAssetFile(std::format("sound/{}", asset->m_name)); + + if (!assetFile) + return; + + auto& stream = *assetFile; + switch (static_cast(loadedSound->sound.info.format)) + { + case WavFormat::PCM: + DumpWavPcm(loadedSound, stream); + break; + + default: + std::cerr << std::format("Unknown format {} for loaded sound: {}\n", loadedSound->sound.info.format, loadedSound->name); + break; + } + } +} // namespace IW5::sound diff --git a/src/ObjWriting/Game/IW5/Sound/AssetDumperLoadedSound.h b/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.h similarity index 58% rename from src/ObjWriting/Game/IW5/Sound/AssetDumperLoadedSound.h rename to src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.h index 4f575072..9758b545 100644 --- a/src/ObjWriting/Game/IW5/Sound/AssetDumperLoadedSound.h +++ b/src/ObjWriting/Game/IW5/Sound/LoadedSoundDumperIW5.h @@ -3,14 +3,12 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/IW5/IW5.h" -namespace IW5 +namespace IW5::sound { - class AssetDumperLoadedSound final : public AbstractAssetDumper + class LoadedSoundDumper final : public AbstractAssetDumper { - static void DumpWavPcm(const LoadedSound* asset, std::ostream& stream); - protected: bool ShouldDump(XAssetInfo* asset) override; void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override; }; -} // namespace IW5 +} // namespace IW5::sound diff --git a/src/ObjWriting/Game/T5/ObjWriterT5.cpp b/src/ObjWriting/Game/T5/ObjWriterT5.cpp index f224f067..55466d5d 100644 --- a/src/ObjWriting/Game/T5/ObjWriterT5.cpp +++ b/src/ObjWriting/Game/T5/ObjWriterT5.cpp @@ -7,7 +7,6 @@ #include "Localize/LocalizeDumperT5.h" #include "ObjWriting.h" #include "RawFile/RawFileDumperT5.h" -#include "Sound/AssetDumperSndBank.h" #include "StringTable/StringTableDumperT5.h" #include "Weapon/AssetDumperWeapon.h" diff --git a/src/ObjWriting/Game/T5/Sound/AssetDumperSndBank.cpp b/src/ObjWriting/Game/T5/Sound/AssetDumperSndBank.cpp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/ObjWriting/Game/T5/Sound/AssetDumperSndBank.h b/src/ObjWriting/Game/T5/Sound/AssetDumperSndBank.h deleted file mode 100644 index e69de29b..00000000 diff --git a/src/ObjWriting/Game/T6/ObjWriterT6.cpp b/src/ObjWriting/Game/T6/ObjWriterT6.cpp index 3a3f05a8..93cfea5a 100644 --- a/src/ObjWriting/Game/T6/ObjWriterT6.cpp +++ b/src/ObjWriting/Game/T6/ObjWriterT6.cpp @@ -15,8 +15,8 @@ #include "RawFile/RawFileDumperT6.h" #include "Script/ScriptDumperT6.h" #include "Slug/SlugDumperT6.h" -#include "Sound/AssetDumperSndBank.h" -#include "Sound/AssetDumperSndDriverGlobals.h" +#include "Sound/SndBankDumperT6.h" +#include "Sound/SndDriverGlobalsDumperT6.h" #include "StringTable/StringTableDumperT6.h" #include "Techset/TechsetDumperT6.h" #include "Tracer/TracerDumperT6.h" @@ -54,7 +54,7 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const DUMP_ASSET_POOL(material::JsonDumper, m_material, ASSET_TYPE_MATERIAL) DUMP_ASSET_POOL(techset::Dumper, m_technique_set, ASSET_TYPE_TECHNIQUE_SET) DUMP_ASSET_POOL(image::Dumper, m_image, ASSET_TYPE_IMAGE) - DUMP_ASSET_POOL(AssetDumperSndBank, m_sound_bank, ASSET_TYPE_SOUND) + DUMP_ASSET_POOL(sound::SndBankDumper, m_sound_bank, ASSET_TYPE_SOUND) // DUMP_ASSET_POOL(AssetDumperSndPatch, m_sound_patch, ASSET_TYPE_SOUND_PATCH) // DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map, ASSET_TYPE_CLIPMAP_PVS) // DUMP_ASSET_POOL(AssetDumperComWorld, m_com_world, ASSET_TYPE_COMWORLD) @@ -72,7 +72,7 @@ bool ObjWriter::DumpZone(AssetDumpingContext& context) const DUMP_ASSET_POOL(AssetDumperWeaponAttachment, m_attachment, ASSET_TYPE_ATTACHMENT) DUMP_ASSET_POOL(AssetDumperWeaponAttachmentUnique, m_attachment_unique, ASSET_TYPE_ATTACHMENT_UNIQUE) DUMP_ASSET_POOL(AssetDumperWeaponCamo, m_camo, ASSET_TYPE_WEAPON_CAMO) - DUMP_ASSET_POOL(AssetDumperSndDriverGlobals, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS) + DUMP_ASSET_POOL(sound::SndDriverGlobalsDumper, m_snd_driver_globals, ASSET_TYPE_SNDDRIVER_GLOBALS) // DUMP_ASSET_POOL(AssetDumperFxEffectDef, m_fx, ASSET_TYPE_FX) // DUMP_ASSET_POOL(AssetDumperFxImpactTable, m_fx_impact_table, ASSET_TYPE_IMPACT_FX) DUMP_ASSET_POOL(raw_file::Dumper, m_raw_file, ASSET_TYPE_RAWFILE) diff --git a/src/ObjWriting/Game/T6/Sound/AssetDumperSndDriverGlobals.cpp b/src/ObjWriting/Game/T6/Sound/AssetDumperSndDriverGlobals.cpp deleted file mode 100644 index 452858ce..00000000 --- a/src/ObjWriting/Game/T6/Sound/AssetDumperSndDriverGlobals.cpp +++ /dev/null @@ -1,385 +0,0 @@ -#include "AssetDumperSndDriverGlobals.h" - -#include "Csv/CsvStream.h" -#include "ObjContainer/SoundBank/SoundBank.h" - -using namespace T6; - -class AssetDumperSndDriverGlobals::Internal -{ - AssetDumpingContext& m_context; - - inline static const std::string GROUPS_HEADERS[]{ - "name", - "attenuationSp", - "attenuationMp", - "category", - "parent", - "id", - }; - - inline static const std::string GROUPS_CATEGORIES[]{ - "sfx", - "music", - "void", - "ui", - "cinematic", - "id", - }; - - inline static const std::string CURVE_HEADERS[]{ - "name", - "x0", - "y0", - "x1", - "y1", - "x2", - "y2", - "x3", - "y3", - "x4", - "y4", - "x5", - "y5", - "x6", - "y6", - "x7", - "y7", - "id", - }; - - inline static const std::string PAN_HEADERS[]{ - "name", - "front", - "back", - "center", - "lfe", - "left", - "right", - "id", - }; - - inline static const std::string MASTER_HEADERS[]{ - "name", "lowE", "lowG", "lowF", "lowQ", "peak1E", "peak1G", "peak1F", "peak1Q", "peak2E", "peak2G", - "peak2F", "peak2Q", "hiE", "hiG", "hiF", "hiQ", "eqG", "compE", "compPG", "compMG", "compT", - "compR", "compTA", "compTR", "limitE", "limitPG", "limitMG", "limitT", "limitR", "limitTA", "limitTR", "busReverbG", - "busFxG", "busVoiceG", "busPfutzG", "busHdrfxG", "busUiG", "busMusicG", "busMovieG", "busVcsG", "busReverbE", "busFxE", "busVoiceE", - "busPfutzE", "busHdrfxE", "busUiE", "busMusicE", "busMovieE", "hdrfxCompE", "voiceEqE", "voiceCompE", "id", - }; - - inline static const std::string SIDECHAIN_HEADERS[]{ - "name", - "g", - "f", - "q", - "ta", - "tr", - "tf", - "id", - }; - - inline static const std::string FUTZ_HEADERS[]{ - "name", - "bpfF", - "bpfQ", - "lsG", - "lsF", - "lsQ", - "dist", - "preG", - "postG", - "th", - "tg", - "clippre", - "clippost", - "blend", - "startAliasId", - "stopAliasId", - "loopAliasId", - "id", - }; - - std::unique_ptr OpenAssetFile(const std::string& filename) - { - auto outputFile = this->m_context.OpenAssetFile(filename); - if (outputFile == nullptr) - { - std::cout << "Failed to open sound driver globals output file for: \"" << filename << "\"\n"; - } - - return outputFile; - } - - static void WriteFileHeader(CsvOutputStream& stream, const std::string* headers, size_t count) - { - for (auto i = 0u; i < count; i++) - { - stream.WriteColumn(headers[i]); - } - - stream.NextRow(); - } - - void DumpSndVolumesGroups(const SndVolumeGroup* groups, const size_t count) - { - const auto outputFile = this->OpenAssetFile("soundbank/globals/group.csv"); - - if (outputFile != nullptr) - { - CsvOutputStream csvStream(*outputFile); - WriteFileHeader(csvStream, GROUPS_HEADERS, std::extent_v); - - for (auto i = 0u; i < count; i++) - { - const auto& group = groups[i]; - csvStream.WriteColumn(group.name); - csvStream.WriteColumn(std::to_string(group.attenuationSp)); - csvStream.WriteColumn(std::to_string(group.attenuationMp)); - csvStream.WriteColumn(GROUPS_CATEGORIES[group.category]); - csvStream.WriteColumn(group.parentName); - csvStream.WriteColumn(std::to_string(group.id)); - csvStream.NextRow(); - } - } - } - - void DumpSndCurves(const SndCurve* curves, const size_t count) - { - const auto outputFile = this->OpenAssetFile("soundbank/globals/curves.csv"); - - if (outputFile != nullptr) - { - CsvOutputStream csvStream(*outputFile); - WriteFileHeader(csvStream, CURVE_HEADERS, std::extent_v); - - for (auto i = 0u; i < count; i++) - { - const auto& curve = curves[i]; - csvStream.WriteColumn(curve.name); - - for (auto j = 0u; j < 8; j++) - { - csvStream.WriteColumn(std::to_string(curve.points[j].x)); - csvStream.WriteColumn(std::to_string(curve.points[j].y)); - } - - csvStream.WriteColumn(std::to_string(curve.id)); - - csvStream.NextRow(); - } - } - } - - void DumpSndPans(const SndPan* pans, const size_t count) - { - const auto outputFile = this->OpenAssetFile("soundbank/globals/pan.csv"); - - if (outputFile != nullptr) - { - CsvOutputStream csvStream(*outputFile); - WriteFileHeader(csvStream, PAN_HEADERS, std::extent_v); - - for (auto i = 0u; i < count; i++) - { - const auto& pan = pans[i]; - csvStream.WriteColumn(pan.name); - csvStream.WriteColumn(std::to_string(pan.front)); - csvStream.WriteColumn(std::to_string(pan.back)); - csvStream.WriteColumn(std::to_string(pan.center)); - csvStream.WriteColumn(std::to_string(pan.lfe)); - csvStream.WriteColumn(std::to_string(pan.left)); - csvStream.WriteColumn(std::to_string(pan.right)); - csvStream.WriteColumn(std::to_string(pan.id)); - csvStream.NextRow(); - } - } - } - - void DumpSndDuckGroups(const SndDuckGroup* duckGroups, const size_t count) - { - const auto outputFile = this->OpenAssetFile("soundbank/globals/duck_groups.csv"); - - if (outputFile != nullptr) - { - CsvOutputStream csvStream(*outputFile); - csvStream.WriteColumn("name"); - csvStream.WriteColumn("id"); - csvStream.NextRow(); - - for (auto i = 0u; i < count; i++) - { - const auto& duckGroup = duckGroups[i]; - csvStream.WriteColumn(duckGroup.name); - csvStream.WriteColumn(std::to_string(duckGroup.id)); - csvStream.NextRow(); - } - } - } - - void DumpSndMasters(const SndMaster* masters, const size_t count) - { - const auto outputFile = this->OpenAssetFile("soundbank/globals/master.csv"); - - if (outputFile != nullptr) - { - CsvOutputStream csvStream(*outputFile); - WriteFileHeader(csvStream, MASTER_HEADERS, std::extent_v); - - for (auto i = 0u; i < count; i++) - { - const auto& master = masters[i]; - csvStream.WriteColumn(master.name); - csvStream.WriteColumn(std::to_string(master.lowE)); - csvStream.WriteColumn(std::to_string(master.lowG)); - csvStream.WriteColumn(std::to_string(master.lowF)); - csvStream.WriteColumn(std::to_string(master.lowQ)); - csvStream.WriteColumn(std::to_string(master.peak1E)); - csvStream.WriteColumn(std::to_string(master.peak1G)); - csvStream.WriteColumn(std::to_string(master.peak1F)); - csvStream.WriteColumn(std::to_string(master.peak1Q)); - csvStream.WriteColumn(std::to_string(master.peak2E)); - csvStream.WriteColumn(std::to_string(master.peak2G)); - csvStream.WriteColumn(std::to_string(master.peak2F)); - csvStream.WriteColumn(std::to_string(master.peak2Q)); - csvStream.WriteColumn(std::to_string(master.hiE)); - csvStream.WriteColumn(std::to_string(master.hiG)); - csvStream.WriteColumn(std::to_string(master.hiF)); - csvStream.WriteColumn(std::to_string(master.hiQ)); - csvStream.WriteColumn(std::to_string(master.eqG)); - csvStream.WriteColumn(std::to_string(master.compE)); - csvStream.WriteColumn(std::to_string(master.compPG)); - csvStream.WriteColumn(std::to_string(master.compMG)); - csvStream.WriteColumn(std::to_string(master.compT)); - csvStream.WriteColumn(std::to_string(master.compR)); - csvStream.WriteColumn(std::to_string(master.compTA)); - csvStream.WriteColumn(std::to_string(master.compTR)); - csvStream.WriteColumn(std::to_string(master.limitE)); - csvStream.WriteColumn(std::to_string(master.limitPG)); - csvStream.WriteColumn(std::to_string(master.limitMG)); - csvStream.WriteColumn(std::to_string(master.limitT)); - csvStream.WriteColumn(std::to_string(master.limitR)); - csvStream.WriteColumn(std::to_string(master.limitTA)); - csvStream.WriteColumn(std::to_string(master.limitTR)); - csvStream.WriteColumn(std::to_string(master.busReverbG)); - csvStream.WriteColumn(std::to_string(master.busFxG)); - csvStream.WriteColumn(std::to_string(master.busVoiceG)); - csvStream.WriteColumn(std::to_string(master.busPfutzG)); - csvStream.WriteColumn(std::to_string(master.busHdrfxG)); - csvStream.WriteColumn(std::to_string(master.busUiG)); - csvStream.WriteColumn(std::to_string(master.busMusicG)); - csvStream.WriteColumn(std::to_string(master.busMovieG)); - csvStream.WriteColumn(std::to_string(master.busVcsG)); - csvStream.WriteColumn(std::to_string(master.busReverbE)); - csvStream.WriteColumn(std::to_string(master.busFxE)); - csvStream.WriteColumn(std::to_string(master.busVoiceE)); - csvStream.WriteColumn(std::to_string(master.busPfutzE)); - csvStream.WriteColumn(std::to_string(master.busHdrfxE)); - csvStream.WriteColumn(std::to_string(master.busUiE)); - csvStream.WriteColumn(std::to_string(master.busMusicE)); - csvStream.WriteColumn(std::to_string(master.busMovieE)); - csvStream.WriteColumn(std::to_string(master.hdrfxCompE)); - csvStream.WriteColumn(std::to_string(master.voiceEqE)); - csvStream.WriteColumn(std::to_string(master.voiceCompE)); - csvStream.WriteColumn(std::to_string(master.id)); - csvStream.NextRow(); - } - } - } - - void DumpSndSidechainDucks(const SndSidechainDuck* sidechains, const size_t count) - { - const auto outputFile = this->OpenAssetFile("soundbank/globals/sidechain_duck.csv"); - - if (outputFile != nullptr) - { - CsvOutputStream csvStream(*outputFile); - WriteFileHeader(csvStream, SIDECHAIN_HEADERS, std::extent_v); - - for (auto i = 0u; i < count; i++) - { - const auto& sidechain = sidechains[i]; - csvStream.WriteColumn(sidechain.name); - csvStream.WriteColumn(std::to_string(sidechain.g)); - csvStream.WriteColumn(std::to_string(sidechain.f)); - csvStream.WriteColumn(std::to_string(sidechain.q)); - csvStream.WriteColumn(std::to_string(sidechain.ta)); - csvStream.WriteColumn(std::to_string(sidechain.tr)); - csvStream.WriteColumn(std::to_string(sidechain.tf)); - csvStream.WriteColumn(std::to_string(sidechain.id)); - csvStream.NextRow(); - } - } - } - - void DumpSndFutz(const SndFutz* futzes, const size_t count) - { - const auto outputFile = this->OpenAssetFile("soundbank/globals/futz.csv"); - - if (outputFile != nullptr) - { - CsvOutputStream csvStream(*outputFile); - WriteFileHeader(csvStream, FUTZ_HEADERS, std::extent_v); - - for (auto i = 0u; i < count; i++) - { - const auto& futz = futzes[i]; - csvStream.WriteColumn(futz.name); - csvStream.WriteColumn(std::to_string(futz.bpfF)); - csvStream.WriteColumn(std::to_string(futz.bpfQ)); - csvStream.WriteColumn(std::to_string(futz.lsG)); - csvStream.WriteColumn(std::to_string(futz.lsF)); - csvStream.WriteColumn(std::to_string(futz.lsQ)); - csvStream.WriteColumn(std::to_string(futz.dist)); - csvStream.WriteColumn(std::to_string(futz.preG)); - csvStream.WriteColumn(std::to_string(futz.postG)); - csvStream.WriteColumn(std::to_string(futz.th)); - csvStream.WriteColumn(std::to_string(futz.tg)); - csvStream.WriteColumn(std::to_string(futz.clippre)); - csvStream.WriteColumn(std::to_string(futz.clippost)); - csvStream.WriteColumn(std::to_string(futz.blend)); - csvStream.WriteColumn(std::to_string(futz.startAliasId)); - csvStream.WriteColumn(std::to_string(futz.stopAliasId)); - csvStream.WriteColumn(std::to_string(futz.loopAliasId)); - csvStream.WriteColumn(std::to_string(futz.id)); - csvStream.NextRow(); - } - } - } - - void DumpSndDriverGlobals(const XAssetInfo* sndDriverGlobalsInfo) - { - const auto* sndDriverGlobals = sndDriverGlobalsInfo->Asset(); - - DumpSndVolumesGroups(sndDriverGlobals->groups, sndDriverGlobals->groupCount); - DumpSndCurves(sndDriverGlobals->curves, sndDriverGlobals->curveCount); - DumpSndPans(sndDriverGlobals->pans, sndDriverGlobals->panCount); - DumpSndDuckGroups(sndDriverGlobals->duckGroups, sndDriverGlobals->duckGroupCount); - // DumpSndContexts(sndDriverGlobals->contexts, sndDriverGlobals->contextCount); - DumpSndMasters(sndDriverGlobals->masters, sndDriverGlobals->masterCount); - DumpSndSidechainDucks(sndDriverGlobals->voiceDucks, sndDriverGlobals->voiceDuckCount); - DumpSndFutz(sndDriverGlobals->futzes, sndDriverGlobals->futzCount); - } - -public: - explicit Internal(AssetDumpingContext& context) - : m_context(context) - { - } - - void DumpPool(AssetPool* pool) - { - for (const auto* assetInfo : *pool) - { - if (!assetInfo->m_name.empty() && assetInfo->m_name[0] == ',') - continue; - - DumpSndDriverGlobals(assetInfo); - } - } -}; - -void AssetDumperSndDriverGlobals::DumpPool(AssetDumpingContext& context, AssetPool* pool) -{ - Internal internal(context); - internal.DumpPool(pool); -} diff --git a/src/ObjWriting/Game/T6/Sound/AssetDumperSndBank.cpp b/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.cpp similarity index 98% rename from src/ObjWriting/Game/T6/Sound/AssetDumperSndBank.cpp rename to src/ObjWriting/Game/T6/Sound/SndBankDumperT6.cpp index 5d407b86..f72517a4 100644 --- a/src/ObjWriting/Game/T6/Sound/AssetDumperSndBank.cpp +++ b/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.cpp @@ -1,4 +1,4 @@ -#include "AssetDumperSndBank.h" +#include "SndBankDumperT6.h" #include "Csv/CsvStream.h" #include "Game/T6/CommonT6.h" @@ -910,15 +910,18 @@ namespace } } // namespace -void AssetDumperSndBank::DumpPool(AssetDumpingContext& context, AssetPool* pool) +namespace T6::sound { - LoadedSoundBankHashes soundBankHashes; - soundBankHashes.Initialize(); - for (const auto* assetInfo : *pool) + void SndBankDumper::DumpPool(AssetDumpingContext& context, AssetPool* pool) { - if (!assetInfo->m_name.empty() && assetInfo->m_name[0] == ',') - continue; + LoadedSoundBankHashes soundBankHashes; + soundBankHashes.Initialize(); + for (const auto* assetInfo : *pool) + { + if (!assetInfo->m_name.empty() && assetInfo->m_name[0] == ',') + continue; - DumpSndBank(context, soundBankHashes, *assetInfo); + DumpSndBank(context, soundBankHashes, *assetInfo); + } } -} +} // namespace T6::sound diff --git a/src/ObjWriting/Game/T6/Sound/AssetDumperSndBank.h b/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.h similarity index 61% rename from src/ObjWriting/Game/T6/Sound/AssetDumperSndBank.h rename to src/ObjWriting/Game/T6/Sound/SndBankDumperT6.h index 61883c58..77141ac3 100644 --- a/src/ObjWriting/Game/T6/Sound/AssetDumperSndBank.h +++ b/src/ObjWriting/Game/T6/Sound/SndBankDumperT6.h @@ -3,13 +3,11 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -namespace T6 +namespace T6::sound { - class AssetDumperSndBank final : public IAssetDumper + class SndBankDumper final : public IAssetDumper { - class Internal; - public: void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; }; -} // namespace T6 +} // namespace T6::sound diff --git a/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.cpp b/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.cpp new file mode 100644 index 00000000..1b27898e --- /dev/null +++ b/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.cpp @@ -0,0 +1,392 @@ +#include "SndDriverGlobalsDumperT6.h" + +#include "Csv/CsvStream.h" +#include "ObjContainer/SoundBank/SoundBank.h" + +#include + +using namespace T6; + +namespace +{ + const std::string GROUPS_HEADERS[]{ + "name", + "attenuationSp", + "attenuationMp", + "category", + "parent", + "id", + }; + + const std::string GROUPS_CATEGORIES[]{ + "sfx", + "music", + "void", + "ui", + "cinematic", + "id", + }; + + const std::string CURVE_HEADERS[]{ + "name", + "x0", + "y0", + "x1", + "y1", + "x2", + "y2", + "x3", + "y3", + "x4", + "y4", + "x5", + "y5", + "x6", + "y6", + "x7", + "y7", + "id", + }; + + const std::string PAN_HEADERS[]{ + "name", + "front", + "back", + "center", + "lfe", + "left", + "right", + "id", + }; + + const std::string MASTER_HEADERS[]{ + "name", "lowE", "lowG", "lowF", "lowQ", "peak1E", "peak1G", "peak1F", "peak1Q", "peak2E", "peak2G", + "peak2F", "peak2Q", "hiE", "hiG", "hiF", "hiQ", "eqG", "compE", "compPG", "compMG", "compT", + "compR", "compTA", "compTR", "limitE", "limitPG", "limitMG", "limitT", "limitR", "limitTA", "limitTR", "busReverbG", + "busFxG", "busVoiceG", "busPfutzG", "busHdrfxG", "busUiG", "busMusicG", "busMovieG", "busVcsG", "busReverbE", "busFxE", "busVoiceE", + "busPfutzE", "busHdrfxE", "busUiE", "busMusicE", "busMovieE", "hdrfxCompE", "voiceEqE", "voiceCompE", "id", + }; + + const std::string SIDECHAIN_HEADERS[]{ + "name", + "g", + "f", + "q", + "ta", + "tr", + "tf", + "id", + }; + + const std::string FUTZ_HEADERS[]{ + "name", + "bpfF", + "bpfQ", + "lsG", + "lsF", + "lsQ", + "dist", + "preG", + "postG", + "th", + "tg", + "clippre", + "clippost", + "blend", + "startAliasId", + "stopAliasId", + "loopAliasId", + "id", + }; + + class Internal + { + public: + explicit Internal(AssetDumpingContext& context) + : m_context(context) + { + } + + void DumpPool(AssetPool* pool) + { + for (const auto* assetInfo : *pool) + { + if (!assetInfo->m_name.empty() && assetInfo->m_name[0] == ',') + continue; + + DumpSndDriverGlobals(assetInfo); + } + } + + private: + std::unique_ptr OpenAssetFile(const std::string& filename) + { + auto outputFile = this->m_context.OpenAssetFile(filename); + if (outputFile == nullptr) + std::cerr << std::format("Failed to open sound driver globals output file for: \"{}\"\n", filename); + + return outputFile; + } + + static void WriteFileHeader(CsvOutputStream& stream, const std::string* headers, size_t count) + { + for (auto i = 0u; i < count; i++) + { + stream.WriteColumn(headers[i]); + } + + stream.NextRow(); + } + + void DumpSndVolumesGroups(const SndVolumeGroup* groups, const size_t count) + { + const auto outputFile = this->OpenAssetFile("soundbank/globals/group.csv"); + + if (outputFile != nullptr) + { + CsvOutputStream csvStream(*outputFile); + WriteFileHeader(csvStream, GROUPS_HEADERS, std::extent_v); + + for (auto i = 0u; i < count; i++) + { + const auto& group = groups[i]; + csvStream.WriteColumn(group.name); + csvStream.WriteColumn(std::to_string(group.attenuationSp)); + csvStream.WriteColumn(std::to_string(group.attenuationMp)); + csvStream.WriteColumn(GROUPS_CATEGORIES[group.category]); + csvStream.WriteColumn(group.parentName); + csvStream.WriteColumn(std::to_string(group.id)); + csvStream.NextRow(); + } + } + } + + void DumpSndCurves(const SndCurve* curves, const size_t count) + { + const auto outputFile = this->OpenAssetFile("soundbank/globals/curves.csv"); + + if (outputFile != nullptr) + { + CsvOutputStream csvStream(*outputFile); + WriteFileHeader(csvStream, CURVE_HEADERS, std::extent_v); + + for (auto i = 0u; i < count; i++) + { + const auto& curve = curves[i]; + csvStream.WriteColumn(curve.name); + + for (auto j = 0u; j < 8; j++) + { + csvStream.WriteColumn(std::to_string(curve.points[j].x)); + csvStream.WriteColumn(std::to_string(curve.points[j].y)); + } + + csvStream.WriteColumn(std::to_string(curve.id)); + + csvStream.NextRow(); + } + } + } + + void DumpSndPans(const SndPan* pans, const size_t count) + { + const auto outputFile = this->OpenAssetFile("soundbank/globals/pan.csv"); + + if (outputFile != nullptr) + { + CsvOutputStream csvStream(*outputFile); + WriteFileHeader(csvStream, PAN_HEADERS, std::extent_v); + + for (auto i = 0u; i < count; i++) + { + const auto& pan = pans[i]; + csvStream.WriteColumn(pan.name); + csvStream.WriteColumn(std::to_string(pan.front)); + csvStream.WriteColumn(std::to_string(pan.back)); + csvStream.WriteColumn(std::to_string(pan.center)); + csvStream.WriteColumn(std::to_string(pan.lfe)); + csvStream.WriteColumn(std::to_string(pan.left)); + csvStream.WriteColumn(std::to_string(pan.right)); + csvStream.WriteColumn(std::to_string(pan.id)); + csvStream.NextRow(); + } + } + } + + void DumpSndDuckGroups(const SndDuckGroup* duckGroups, const size_t count) + { + const auto outputFile = this->OpenAssetFile("soundbank/globals/duck_groups.csv"); + + if (outputFile != nullptr) + { + CsvOutputStream csvStream(*outputFile); + csvStream.WriteColumn("name"); + csvStream.WriteColumn("id"); + csvStream.NextRow(); + + for (auto i = 0u; i < count; i++) + { + const auto& duckGroup = duckGroups[i]; + csvStream.WriteColumn(duckGroup.name); + csvStream.WriteColumn(std::to_string(duckGroup.id)); + csvStream.NextRow(); + } + } + } + + void DumpSndMasters(const SndMaster* masters, const size_t count) + { + const auto outputFile = this->OpenAssetFile("soundbank/globals/master.csv"); + + if (outputFile != nullptr) + { + CsvOutputStream csvStream(*outputFile); + WriteFileHeader(csvStream, MASTER_HEADERS, std::extent_v); + + for (auto i = 0u; i < count; i++) + { + const auto& master = masters[i]; + csvStream.WriteColumn(master.name); + csvStream.WriteColumn(std::to_string(master.lowE)); + csvStream.WriteColumn(std::to_string(master.lowG)); + csvStream.WriteColumn(std::to_string(master.lowF)); + csvStream.WriteColumn(std::to_string(master.lowQ)); + csvStream.WriteColumn(std::to_string(master.peak1E)); + csvStream.WriteColumn(std::to_string(master.peak1G)); + csvStream.WriteColumn(std::to_string(master.peak1F)); + csvStream.WriteColumn(std::to_string(master.peak1Q)); + csvStream.WriteColumn(std::to_string(master.peak2E)); + csvStream.WriteColumn(std::to_string(master.peak2G)); + csvStream.WriteColumn(std::to_string(master.peak2F)); + csvStream.WriteColumn(std::to_string(master.peak2Q)); + csvStream.WriteColumn(std::to_string(master.hiE)); + csvStream.WriteColumn(std::to_string(master.hiG)); + csvStream.WriteColumn(std::to_string(master.hiF)); + csvStream.WriteColumn(std::to_string(master.hiQ)); + csvStream.WriteColumn(std::to_string(master.eqG)); + csvStream.WriteColumn(std::to_string(master.compE)); + csvStream.WriteColumn(std::to_string(master.compPG)); + csvStream.WriteColumn(std::to_string(master.compMG)); + csvStream.WriteColumn(std::to_string(master.compT)); + csvStream.WriteColumn(std::to_string(master.compR)); + csvStream.WriteColumn(std::to_string(master.compTA)); + csvStream.WriteColumn(std::to_string(master.compTR)); + csvStream.WriteColumn(std::to_string(master.limitE)); + csvStream.WriteColumn(std::to_string(master.limitPG)); + csvStream.WriteColumn(std::to_string(master.limitMG)); + csvStream.WriteColumn(std::to_string(master.limitT)); + csvStream.WriteColumn(std::to_string(master.limitR)); + csvStream.WriteColumn(std::to_string(master.limitTA)); + csvStream.WriteColumn(std::to_string(master.limitTR)); + csvStream.WriteColumn(std::to_string(master.busReverbG)); + csvStream.WriteColumn(std::to_string(master.busFxG)); + csvStream.WriteColumn(std::to_string(master.busVoiceG)); + csvStream.WriteColumn(std::to_string(master.busPfutzG)); + csvStream.WriteColumn(std::to_string(master.busHdrfxG)); + csvStream.WriteColumn(std::to_string(master.busUiG)); + csvStream.WriteColumn(std::to_string(master.busMusicG)); + csvStream.WriteColumn(std::to_string(master.busMovieG)); + csvStream.WriteColumn(std::to_string(master.busVcsG)); + csvStream.WriteColumn(std::to_string(master.busReverbE)); + csvStream.WriteColumn(std::to_string(master.busFxE)); + csvStream.WriteColumn(std::to_string(master.busVoiceE)); + csvStream.WriteColumn(std::to_string(master.busPfutzE)); + csvStream.WriteColumn(std::to_string(master.busHdrfxE)); + csvStream.WriteColumn(std::to_string(master.busUiE)); + csvStream.WriteColumn(std::to_string(master.busMusicE)); + csvStream.WriteColumn(std::to_string(master.busMovieE)); + csvStream.WriteColumn(std::to_string(master.hdrfxCompE)); + csvStream.WriteColumn(std::to_string(master.voiceEqE)); + csvStream.WriteColumn(std::to_string(master.voiceCompE)); + csvStream.WriteColumn(std::to_string(master.id)); + csvStream.NextRow(); + } + } + } + + void DumpSndSidechainDucks(const SndSidechainDuck* sidechains, const size_t count) + { + const auto outputFile = this->OpenAssetFile("soundbank/globals/sidechain_duck.csv"); + + if (outputFile != nullptr) + { + CsvOutputStream csvStream(*outputFile); + WriteFileHeader(csvStream, SIDECHAIN_HEADERS, std::extent_v); + + for (auto i = 0u; i < count; i++) + { + const auto& sidechain = sidechains[i]; + csvStream.WriteColumn(sidechain.name); + csvStream.WriteColumn(std::to_string(sidechain.g)); + csvStream.WriteColumn(std::to_string(sidechain.f)); + csvStream.WriteColumn(std::to_string(sidechain.q)); + csvStream.WriteColumn(std::to_string(sidechain.ta)); + csvStream.WriteColumn(std::to_string(sidechain.tr)); + csvStream.WriteColumn(std::to_string(sidechain.tf)); + csvStream.WriteColumn(std::to_string(sidechain.id)); + csvStream.NextRow(); + } + } + } + + void DumpSndFutz(const SndFutz* futzes, const size_t count) + { + const auto outputFile = this->OpenAssetFile("soundbank/globals/futz.csv"); + + if (outputFile != nullptr) + { + CsvOutputStream csvStream(*outputFile); + WriteFileHeader(csvStream, FUTZ_HEADERS, std::extent_v); + + for (auto i = 0u; i < count; i++) + { + const auto& futz = futzes[i]; + csvStream.WriteColumn(futz.name); + csvStream.WriteColumn(std::to_string(futz.bpfF)); + csvStream.WriteColumn(std::to_string(futz.bpfQ)); + csvStream.WriteColumn(std::to_string(futz.lsG)); + csvStream.WriteColumn(std::to_string(futz.lsF)); + csvStream.WriteColumn(std::to_string(futz.lsQ)); + csvStream.WriteColumn(std::to_string(futz.dist)); + csvStream.WriteColumn(std::to_string(futz.preG)); + csvStream.WriteColumn(std::to_string(futz.postG)); + csvStream.WriteColumn(std::to_string(futz.th)); + csvStream.WriteColumn(std::to_string(futz.tg)); + csvStream.WriteColumn(std::to_string(futz.clippre)); + csvStream.WriteColumn(std::to_string(futz.clippost)); + csvStream.WriteColumn(std::to_string(futz.blend)); + csvStream.WriteColumn(std::to_string(futz.startAliasId)); + csvStream.WriteColumn(std::to_string(futz.stopAliasId)); + csvStream.WriteColumn(std::to_string(futz.loopAliasId)); + csvStream.WriteColumn(std::to_string(futz.id)); + csvStream.NextRow(); + } + } + } + + void DumpSndDriverGlobals(const XAssetInfo* sndDriverGlobalsInfo) + { + const auto* sndDriverGlobals = sndDriverGlobalsInfo->Asset(); + + DumpSndVolumesGroups(sndDriverGlobals->groups, sndDriverGlobals->groupCount); + DumpSndCurves(sndDriverGlobals->curves, sndDriverGlobals->curveCount); + DumpSndPans(sndDriverGlobals->pans, sndDriverGlobals->panCount); + DumpSndDuckGroups(sndDriverGlobals->duckGroups, sndDriverGlobals->duckGroupCount); + // DumpSndContexts(sndDriverGlobals->contexts, sndDriverGlobals->contextCount); + DumpSndMasters(sndDriverGlobals->masters, sndDriverGlobals->masterCount); + DumpSndSidechainDucks(sndDriverGlobals->voiceDucks, sndDriverGlobals->voiceDuckCount); + DumpSndFutz(sndDriverGlobals->futzes, sndDriverGlobals->futzCount); + } + + AssetDumpingContext& m_context; + }; +} // namespace + +namespace T6::sound +{ + void SndDriverGlobalsDumper::DumpPool(AssetDumpingContext& context, AssetPool* pool) + { + Internal internal(context); + internal.DumpPool(pool); + } +} // namespace T6::sound diff --git a/src/ObjWriting/Game/T6/Sound/AssetDumperSndDriverGlobals.h b/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.h similarity index 59% rename from src/ObjWriting/Game/T6/Sound/AssetDumperSndDriverGlobals.h rename to src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.h index 18f0cf89..b20c4f16 100644 --- a/src/ObjWriting/Game/T6/Sound/AssetDumperSndDriverGlobals.h +++ b/src/ObjWriting/Game/T6/Sound/SndDriverGlobalsDumperT6.h @@ -3,13 +3,11 @@ #include "Dumping/AbstractAssetDumper.h" #include "Game/T6/T6.h" -namespace T6 +namespace T6::sound { - class AssetDumperSndDriverGlobals final : public IAssetDumper + class SndDriverGlobalsDumper final : public IAssetDumper { - class Internal; - public: void DumpPool(AssetDumpingContext& context, AssetPool* pool) override; }; -} // namespace T6 +} // namespace T6::sound