mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
Start dumping snd aliases
This commit is contained in:
parent
b1fce0f4fb
commit
4f212562fc
@ -3,15 +3,87 @@
|
||||
#include <filesystem>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Utils/ClassUtils.h"
|
||||
#include "Csv/CsvStream.h"
|
||||
#include "ObjContainer/SoundBank/SoundBank.h"
|
||||
|
||||
using namespace T6;
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
std::string AssetDumperSndBank::GetExtensionForFormat(const snd_asset_format format)
|
||||
class AssetDumperSndBank::Internal
|
||||
{
|
||||
switch(format)
|
||||
inline static const std::string ALIAS_HEADERS[]
|
||||
{
|
||||
"# name",
|
||||
"# file",
|
||||
"# template",
|
||||
"# loadspec",
|
||||
"# secondary",
|
||||
"# group",
|
||||
"# vol_min",
|
||||
"# vol_max",
|
||||
"# team_vol_mod",
|
||||
"# dist_min",
|
||||
"# dist_max",
|
||||
"# dist_reverb_max",
|
||||
"# volume_falloff_curve",
|
||||
"# reverb_falloff_curve",
|
||||
"# volume_min_falloff_curve",
|
||||
"# reverb_min_falloff_curve",
|
||||
"# limit_count",
|
||||
"# limit_type",
|
||||
"# entity_limit_count",
|
||||
"# entity_limit_type",
|
||||
"# pitch_min",
|
||||
"# pitch_max",
|
||||
"# team_pitch_mod",
|
||||
"# min_priority",
|
||||
"# max_priority",
|
||||
"# min_priority_threshold",
|
||||
"# max_priority_threshold",
|
||||
"# spatialized",
|
||||
"# type",
|
||||
"# loop",
|
||||
"# randomize_type",
|
||||
"# probability",
|
||||
"# start_delay",
|
||||
"# reverb_send",
|
||||
"# duck",
|
||||
"# pan",
|
||||
"# center_send",
|
||||
"# envelop_min",
|
||||
"# envelop_max",
|
||||
"# envelop_percentage",
|
||||
"# occlusion_level",
|
||||
"# occlusion_wet_dry",
|
||||
"# is_big",
|
||||
"# distance_lpf",
|
||||
"# move_type",
|
||||
"# move_time",
|
||||
"# real_delay",
|
||||
"# subtitle",
|
||||
"# mature",
|
||||
"# doppler",
|
||||
"# futz",
|
||||
"# context_type",
|
||||
"# context_value",
|
||||
"# compression",
|
||||
"# timescale",
|
||||
"# music",
|
||||
"# fade_in",
|
||||
"# fade_out",
|
||||
"# pc_format",
|
||||
"# pause",
|
||||
"# stop_on_death",
|
||||
"# bus",
|
||||
"# snapshot",
|
||||
};
|
||||
|
||||
AssetDumpingContext& m_context;
|
||||
|
||||
static std::string GetExtensionForFormat(const snd_asset_format format)
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case SND_ASSET_FORMAT_MP3:
|
||||
return ".mp3";
|
||||
@ -36,20 +108,20 @@ std::string AssetDumperSndBank::GetExtensionForFormat(const snd_asset_format for
|
||||
std::cout << "Unknown sound format " << format << std::endl;
|
||||
return std::string();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<std::ostream> AssetDumperSndBank::OpenAssetOutputFile(AssetDumpingContext& context, const std::string& outputFileName, const SoundAssetBankEntry& entry) const
|
||||
{
|
||||
fs::path assetPath(context.m_base_path);
|
||||
_NODISCARD std::string GetAssetFilename(const std::string& outputFileName, const SoundAssetBankEntry& entry) const
|
||||
{
|
||||
fs::path assetPath(m_context.m_base_path);
|
||||
|
||||
fs::path assetName(outputFileName);
|
||||
auto firstPart = true;
|
||||
for(const auto& part : assetName)
|
||||
for (const auto& part : assetName)
|
||||
{
|
||||
if(firstPart)
|
||||
if (firstPart)
|
||||
{
|
||||
firstPart = false;
|
||||
if(part.string() == "raw"
|
||||
if (part.string() == "raw"
|
||||
|| part.string() == "devraw")
|
||||
continue;
|
||||
}
|
||||
@ -58,9 +130,16 @@ std::unique_ptr<std::ostream> AssetDumperSndBank::OpenAssetOutputFile(AssetDumpi
|
||||
}
|
||||
|
||||
const auto extension = GetExtensionForFormat(static_cast<snd_asset_format>(entry.format));
|
||||
if(!extension.empty())
|
||||
if (!extension.empty())
|
||||
assetPath.concat(extension);
|
||||
|
||||
return assetPath.string();
|
||||
}
|
||||
|
||||
_NODISCARD std::unique_ptr<std::ostream> OpenAssetOutputFile(const std::string& outputFileName, const SoundAssetBankEntry& entry) const
|
||||
{
|
||||
fs::path assetPath(GetAssetFilename(outputFileName, entry));
|
||||
|
||||
auto assetDir(assetPath);
|
||||
assetDir.remove_filename();
|
||||
|
||||
@ -68,40 +147,134 @@ std::unique_ptr<std::ostream> AssetDumperSndBank::OpenAssetOutputFile(AssetDumpi
|
||||
|
||||
auto outputStream = std::make_unique<std::ofstream>(assetPath, std::ios_base::out | std::ios_base::binary);
|
||||
|
||||
if(outputStream->is_open())
|
||||
if (outputStream->is_open())
|
||||
{
|
||||
return std::move(outputStream);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<std::ostream> AssetDumperSndBank::OpenAliasOutputFile(AssetDumpingContext& context, SndBank* sndBank) const
|
||||
{
|
||||
std::unique_ptr<std::ostream> OpenAliasOutputFile(const SndBank* sndBank) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void WriteAliasFileHeader(CsvOutputStream& stream)
|
||||
{
|
||||
for (const auto& headerField : ALIAS_HEADERS)
|
||||
{
|
||||
stream.WriteColumn(headerField);
|
||||
}
|
||||
|
||||
stream.NextRow();
|
||||
}
|
||||
|
||||
void WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias)
|
||||
{
|
||||
// name
|
||||
stream.WriteColumn(alias->name);
|
||||
|
||||
// file
|
||||
stream.WriteColumn(alias->assetFileName);
|
||||
|
||||
// "# template",
|
||||
// template
|
||||
stream.WriteColumn("");
|
||||
|
||||
// loadspec
|
||||
stream.WriteColumn("");
|
||||
|
||||
// "# secondary",
|
||||
// "# group",
|
||||
// "# vol_min",
|
||||
// "# vol_max",
|
||||
// "# team_vol_mod",
|
||||
// "# dist_min",
|
||||
// "# dist_max",
|
||||
// "# dist_reverb_max",
|
||||
// "# volume_falloff_curve",
|
||||
// "# reverb_falloff_curve",
|
||||
// "# volume_min_falloff_curve",
|
||||
// "# reverb_min_falloff_curve",
|
||||
// "# limit_count",
|
||||
// "# limit_type",
|
||||
// "# entity_limit_count",
|
||||
// "# entity_limit_type",
|
||||
// "# pitch_min",
|
||||
// "# pitch_max",
|
||||
// "# team_pitch_mod",
|
||||
// "# min_priority",
|
||||
// "# max_priority",
|
||||
// "# min_priority_threshold",
|
||||
// "# max_priority_threshold",
|
||||
// "# spatialized",
|
||||
// "# type",
|
||||
// "# loop",
|
||||
// "# randomize_type",
|
||||
// "# probability",
|
||||
// "# start_delay",
|
||||
// "# reverb_send",
|
||||
// "# duck",
|
||||
// "# pan",
|
||||
// "# center_send",
|
||||
// "# envelop_min",
|
||||
// "# envelop_max",
|
||||
// "# envelop_percentage",
|
||||
// "# occlusion_level",
|
||||
// "# occlusion_wet_dry",
|
||||
// "# is_big",
|
||||
// "# distance_lpf",
|
||||
// "# move_type",
|
||||
// "# move_time",
|
||||
// "# real_delay",
|
||||
// "# subtitle",
|
||||
// "# mature",
|
||||
// "# doppler",
|
||||
// "# futz",
|
||||
// "# context_type",
|
||||
// "# context_value",
|
||||
// "# compression",
|
||||
// "# timescale",
|
||||
// "# music",
|
||||
// "# fade_in",
|
||||
// "# fade_out",
|
||||
// "# pc_format",
|
||||
// "# pause",
|
||||
// "# stop_on_death",
|
||||
// "# bus",
|
||||
// "# snapshot",
|
||||
}
|
||||
|
||||
void DumpSndBankAliases(const SndBank* sndBank, std::unordered_map<unsigned, std::string>& aliasFiles)
|
||||
{
|
||||
const auto outputFile = OpenAliasOutputFile(sndBank);
|
||||
|
||||
if (outputFile == nullptr)
|
||||
{
|
||||
std::cout << "Failed to open sound alias output file for: \"" << sndBank->name << "\"" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
CsvOutputStream csvStream(*outputFile);
|
||||
WriteAliasFileHeader(csvStream);
|
||||
|
||||
void AssetDumperSndBank::DumpSndBankAliases(AssetDumpingContext& context, SndBank* sndBank, std::unordered_map<unsigned, std::string>& aliasFiles)
|
||||
{
|
||||
for (auto i = 0u; i < sndBank->aliasCount; i++)
|
||||
{
|
||||
const auto& aliasList = sndBank->alias[i];
|
||||
for (auto j = 0; j < aliasList.count; j++)
|
||||
{
|
||||
const auto& alias = aliasList.head[j];
|
||||
WriteAliasToFile(csvStream, &alias);
|
||||
if (alias.assetId && alias.assetFileName)
|
||||
aliasFiles[alias.assetId] = alias.assetFileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssetDumperSndBank::DumpSndBank(AssetDumpingContext& context, const XAssetInfo<SndBank>* sndBankInfo)
|
||||
{
|
||||
const auto* sndBank = sndBankInfo->Asset();
|
||||
|
||||
std::unordered_map<unsigned int, std::string> aliasMappings;
|
||||
|
||||
for (const auto& [id, filename] : aliasMappings)
|
||||
void DumpSoundData(std::unordered_map<unsigned, std::string>& aliasFiles) const
|
||||
{
|
||||
for (const auto& [id, filename] : aliasFiles)
|
||||
{
|
||||
auto foundEntry = false;
|
||||
|
||||
@ -110,7 +283,7 @@ void AssetDumperSndBank::DumpSndBank(AssetDumpingContext& context, const XAssetI
|
||||
auto soundFile = soundBank->GetEntryStream(id);
|
||||
if (soundFile.IsOpen())
|
||||
{
|
||||
auto outFile = OpenAssetOutputFile(context, filename, soundFile.m_entry);
|
||||
auto outFile = OpenAssetOutputFile(filename, soundFile.m_entry);
|
||||
if (!outFile)
|
||||
{
|
||||
std::cout << "Failed to open sound outputfile: \"" << filename << "\"" << std::endl;
|
||||
@ -130,20 +303,42 @@ void AssetDumperSndBank::DumpSndBank(AssetDumpingContext& context, const XAssetI
|
||||
}
|
||||
}
|
||||
|
||||
if(!foundEntry)
|
||||
if (!foundEntry)
|
||||
{
|
||||
std::cout << "Could not find data for sound \"" << filename << "\"" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AssetDumperSndBank::DumpPool(AssetDumpingContext& context, AssetPool<SndBank>* pool)
|
||||
{
|
||||
for(const auto* assetInfo : *pool)
|
||||
void DumpSndBank(const XAssetInfo<SndBank>* sndBankInfo)
|
||||
{
|
||||
const auto* sndBank = sndBankInfo->Asset();
|
||||
|
||||
std::unordered_map<unsigned int, std::string> aliasMappings;
|
||||
DumpSndBankAliases(sndBank, aliasMappings);
|
||||
DumpSoundData(aliasMappings);
|
||||
}
|
||||
|
||||
public:
|
||||
explicit Internal(AssetDumpingContext& context)
|
||||
: m_context(context)
|
||||
{
|
||||
}
|
||||
|
||||
void DumpPool(AssetPool<SndBank>* pool)
|
||||
{
|
||||
for (const auto* assetInfo : *pool)
|
||||
{
|
||||
if (!assetInfo->m_name.empty() && assetInfo->m_name[0] == ',')
|
||||
continue;
|
||||
|
||||
DumpSndBank(context, assetInfo);
|
||||
DumpSndBank(assetInfo);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void AssetDumperSndBank::DumpPool(AssetDumpingContext& context, AssetPool<SndBank>* pool)
|
||||
{
|
||||
Internal internal(context);
|
||||
internal.DumpPool(pool);
|
||||
}
|
||||
|
@ -1,22 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "Dumping/AbstractAssetDumper.h"
|
||||
#include "Game/T6/T6.h"
|
||||
#include "ObjContainer/SoundBank/SoundBankTypes.h"
|
||||
|
||||
namespace T6
|
||||
{
|
||||
class AssetDumperSndBank final : public IAssetDumper<SndBank>
|
||||
{
|
||||
static std::string GetExtensionForFormat(snd_asset_format format);
|
||||
std::unique_ptr<std::ostream> OpenAssetOutputFile(AssetDumpingContext& context, const std::string& outputFileName, const SoundAssetBankEntry& entry) const;
|
||||
std::unique_ptr<std::ostream> OpenAliasOutputFile(AssetDumpingContext& context, SndBank* sndBank) const;
|
||||
void DumpSndBankAliases(AssetDumpingContext& context, SndBank* sndBank, std::unordered_map<unsigned int, std::string>& aliasFiles);
|
||||
void DumpSndBank(AssetDumpingContext& context, const XAssetInfo<SndBank>* sndBankInfo);
|
||||
class Internal;
|
||||
|
||||
public:
|
||||
void DumpPool(AssetDumpingContext& context, AssetPool<SndBank>* pool) override;
|
||||
|
Loading…
x
Reference in New Issue
Block a user