First iteration for dumping t6 sound aliases

This commit is contained in:
Jan 2023-11-26 12:47:34 +01:00
parent d29dc082e2
commit 3a825d1440
No known key found for this signature in database
GPG Key ID: 44B581F78FF5C57C
4 changed files with 303 additions and 80 deletions

View File

@ -5619,16 +5619,16 @@ namespace T6
int16_t fadeIn; int16_t fadeIn;
int16_t fadeOut; int16_t fadeOut;
int16_t dopplerScale; int16_t dopplerScale;
char minPriorityThreshold; uint8_t minPriorityThreshold;
char maxPriorityThreshold; uint8_t maxPriorityThreshold;
char probability; uint8_t probability;
char occlusionLevel; uint8_t occlusionLevel;
char minPriority; uint8_t minPriority;
char maxPriority; uint8_t maxPriority;
char pan; uint8_t pan;
char limitCount; uint8_t limitCount;
char entityLimitCount; uint8_t entityLimitCount;
char duckGroup; uint8_t duckGroup;
}; };
struct type_align(4) pathlink_s struct type_align(4) pathlink_s

View File

@ -297,6 +297,17 @@ bool SoundBank::VerifyChecksum(const SoundAssetBankChecksum& checksum) const
return m_initialized && memcmp(checksum.checksumBytes, m_header.checksumChecksum.checksumBytes, sizeof(SoundAssetBankChecksum)) == 0; return m_initialized && memcmp(checksum.checksumBytes, m_header.checksumChecksum.checksumBytes, sizeof(SoundAssetBankChecksum)) == 0;
} }
bool SoundBank::GetEntry(const unsigned id, SoundAssetBankEntry& entry) const
{
const auto foundEntry = m_entries_by_id.find(id);
if (foundEntry == m_entries_by_id.end())
return false;
entry = m_entries[foundEntry->second];
return true;
}
SoundBankEntryInputStream SoundBank::GetEntryStream(const unsigned id) const SoundBankEntryInputStream SoundBank::GetEntryStream(const unsigned id) const
{ {
const auto foundEntry = m_entries_by_id.find(id); const auto foundEntry = m_entries_by_id.find(id);

View File

@ -42,6 +42,8 @@ public:
_NODISCARD const std::vector<std::string>& GetDependencies() const; _NODISCARD const std::vector<std::string>& GetDependencies() const;
_NODISCARD bool VerifyChecksum(const SoundAssetBankChecksum& checksum) const; _NODISCARD bool VerifyChecksum(const SoundAssetBankChecksum& checksum) const;
bool GetEntry(unsigned id, SoundAssetBankEntry& entry) const;
_NODISCARD SoundBankEntryInputStream GetEntryStream(unsigned int id) const; _NODISCARD SoundBankEntryInputStream GetEntryStream(unsigned int id) const;
static ObjContainerRepository<SoundBank, Zone> Repository; static ObjContainerRepository<SoundBank, Zone> Repository;

View File

@ -8,6 +8,8 @@
#include <cassert> #include <cassert>
#include <filesystem> #include <filesystem>
#include <fstream> #include <fstream>
#include <iomanip>
#include <sstream>
#include <unordered_set> #include <unordered_set>
using namespace T6; using namespace T6;
@ -97,6 +99,21 @@ namespace
96000, 96000,
192000, 192000,
}; };
constexpr const char* EXTENSION_BY_FORMAT[SND_ASSET_FORMAT_COUNT]{
".wav", // SND_ASSET_FORMAT_PCMS16
".wav", // SND_ASSET_FORMAT_PCMS24
".wav", // SND_ASSET_FORMAT_PCMS32
".wav", // SND_ASSET_FORMAT_IEEE
".xma", // SND_ASSET_FORMAT_XMA4
".mp3", // SND_ASSET_FORMAT_MP3
".wav", // SND_ASSET_FORMAT_MSADPCM
".wma", // SND_ASSET_FORMAT_WMA
".flac", // SND_ASSET_FORMAT_FLAC
".wav", // SND_ASSET_FORMAT_WIIUADPCM
".mpc", // SND_ASSET_FORMAT_MPC
};
} // namespace } // namespace
class AssetDumperSndBank::Internal class AssetDumperSndBank::Internal
@ -143,9 +160,23 @@ class AssetDumperSndBank::Internal
return nullptr; return nullptr;
} }
static std::unique_ptr<std::ostream> OpenAliasOutputFile(const SndBank* sndBank) std::unique_ptr<std::ostream> OpenAliasOutputFile(const SndBank* sndBank) const
{ {
return nullptr; std::ostringstream ss;
const char* name;
if (sndBank->streamAssetBank.zone)
name = sndBank->streamAssetBank.zone;
else if (sndBank->loadAssetBank.zone)
name = sndBank->loadAssetBank.zone;
else if (sndBank->loadedAssets.zone)
name = sndBank->loadedAssets.zone;
else
name = sndBank->name;
ss << "soundaliases/" << name << "_aliases.csv";
return m_context.OpenAssetFile(ss.str());
} }
static void WriteAliasFileHeader(CsvOutputStream& stream) static void WriteAliasFileHeader(CsvOutputStream& stream)
@ -158,83 +189,249 @@ class AssetDumperSndBank::Internal
stream.NextRow(); stream.NextRow();
} }
static void WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias) void WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias) const
{ {
SoundAssetBankEntry entry;
std::string extension;
if (FindSoundBankEntry(alias->assetId, entry))
{
assert(entry.format < SND_ASSET_FORMAT_COUNT);
if (entry.format < SND_ASSET_FORMAT_COUNT)
extension = EXTENSION_BY_FORMAT[entry.format];
}
// name // name
stream.WriteColumn(alias->name); WriteColumnNullSafe(stream, alias->name);
// file // file
stream.WriteColumn(alias->assetFileName); if (alias->assetFileName)
stream.WriteColumn(GetAssetFilename(alias->assetFileName, extension));
else
stream.WriteColumn("");
// "# template",
// template // template
stream.WriteColumn(""); stream.WriteColumn("");
// loadspec // loadspec
stream.WriteColumn(""); stream.WriteColumn("");
// "# secondary", // secondary
// "# group", WriteColumnNullSafe(stream, alias->secondaryname);
// "# vol_min",
// "# vol_max", // group
// "# team_vol_mod", stream.WriteColumn("");
// "# dist_min",
// "# dist_max", // vol_min
// "# dist_reverb_max", WriteColumnFloat16(stream, alias->volMin);
// "# volume_falloff_curve",
// "# reverb_falloff_curve", // vol_max
// "# volume_min_falloff_curve", WriteColumnFloat16(stream, alias->volMax);
// "# reverb_min_falloff_curve",
// "# limit_count", // team_vol_mod
// "# limit_type", stream.WriteColumn("");
// "# entity_limit_count",
// "# entity_limit_type", // dist_min
// "# pitch_min", WriteColumnFloat16(stream, alias->distMin);
// "# pitch_max",
// "# team_pitch_mod", // dist_max
// "# min_priority", WriteColumnFloat16(stream, alias->distMax);
// "# max_priority",
// "# min_priority_threshold", // dist_reverb_max
// "# max_priority_threshold", WriteColumnFloat16(stream, alias->distReverbMax);
// "# spatialized",
// "# type", // volume_falloff_curve
// "# loop", stream.WriteColumn("");
// "# randomize_type",
// "# probability", // reverb_falloff_curve
// "# start_delay", stream.WriteColumn("");
// "# reverb_send",
// "# duck", // volume_min_falloff_curve
// "# pan", stream.WriteColumn("");
// "# center_send",
// "# envelop_min", // reverb_min_falloff_curve
// "# envelop_max", stream.WriteColumn("");
// "# envelop_percentage",
// "# occlusion_level", // limit_count
// "# occlusion_wet_dry", WriteColumnUnsignedNumeric(stream, alias->limitCount);
// "# is_big",
// "# distance_lpf", // limit_type
// "# move_type", stream.WriteColumn("");
// "# move_time",
// "# real_delay", // entity_limit_count
// "# subtitle", WriteColumnUnsignedNumeric(stream, alias->entityLimitCount);
// "# mature",
// "# doppler", // entity_limit_type
// "# futz", stream.WriteColumn("");
// "# context_type",
// "# context_value", // pitch_min
// "# compression", WriteColumnFloat16(stream, alias->pitchMin);
// "# timescale",
// "# music", // pitch_max
// "# fade_in", WriteColumnFloat16(stream, alias->pitchMax);
// "# fade_out",
// "# pc_format", // team_pitch_mod
// "# pause", stream.WriteColumn("");
// "# stop_on_death",
// "# bus", // min_priority
// "# snapshot", WriteColumnUnsignedNumeric(stream, alias->minPriority);
// max_priority
WriteColumnUnsignedNumeric(stream, alias->maxPriority);
// min_priority_threshold
WriteColumnUnsignedNumeric(stream, alias->minPriorityThreshold);
// max_priority_threshold
WriteColumnUnsignedNumeric(stream, alias->maxPriorityThreshold);
// spatialized
stream.WriteColumn("");
// type
stream.WriteColumn("");
// loop
stream.WriteColumn("");
// randomize_type
stream.WriteColumn("");
// probability
WriteColumnUnsignedNumeric(stream, alias->probability);
// start_delay
WriteColumnUnsignedNumeric(stream, alias->startDelay);
// reverb_send
WriteColumnUnsignedNumeric(stream, alias->reverbSend);
// duck
WriteColumnUnsignedNumeric(stream, alias->duck);
// pan
WriteColumnUnsignedNumeric(stream, alias->pan);
// center_send
WriteColumnUnsignedNumeric(stream, alias->centerSend);
// envelop_min
WriteColumnUnsignedNumeric(stream, alias->envelopMin);
// envelop_max
WriteColumnUnsignedNumeric(stream, alias->envelopMax);
// envelop_percentage
WriteColumnUnsignedNumeric(stream, alias->envelopPercentage);
// occlusion_level
WriteColumnFloat8(stream, alias->occlusionLevel);
// occlusion_wet_dry
stream.WriteColumn("");
// is_big
stream.WriteColumn("");
// distance_lpf
stream.WriteColumn("");
// move_type
stream.WriteColumn("");
// move_time
stream.WriteColumn("");
// real_delay
stream.WriteColumn("");
// subtitle
WriteColumnNullSafe(stream, alias->subtitle);
// mature
stream.WriteColumn("");
// doppler
stream.WriteColumn("");
// futz
WriteColumnUnsignedNumeric(stream, alias->futzPatch);
// context_type
stream.WriteColumn("");
// context_value
stream.WriteColumn("");
// compression
stream.WriteColumn("");
// timescale
stream.WriteColumn("");
// music
stream.WriteColumn("");
// fade_in
WriteColumnSignedNumeric(stream, alias->fadeIn);
// fade_out
WriteColumnSignedNumeric(stream, alias->fadeOut);
// pc_format
stream.WriteColumn("");
// pause
stream.WriteColumn("");
// stop_on_death
stream.WriteColumn("");
// bus
stream.WriteColumn("");
// snapshot
stream.WriteColumn("");
stream.NextRow();
} }
static void DumpSndBankAliases(const SndBank* sndBank) static void WriteColumnNullSafe(CsvOutputStream& stream, const char* value)
{
if (value)
stream.WriteColumn(value);
else
stream.WriteColumn("");
}
static void WriteColumnFloat8(CsvOutputStream& stream, const uint8_t value)
{
std::ostringstream ss;
ss << std::setprecision(6) << std::fixed << (static_cast<float>(value) / static_cast<float>(std::numeric_limits<uint8_t>::max()));
stream.WriteColumn(ss.str());
}
static void WriteColumnFloat16(CsvOutputStream& stream, const uint16_t value)
{
std::ostringstream ss;
ss << std::setprecision(6) << std::fixed << (static_cast<float>(value) / static_cast<float>(std::numeric_limits<uint16_t>::max()));
stream.WriteColumn(ss.str());
}
static void WriteColumnSignedNumeric(CsvOutputStream& stream, const int value)
{
stream.WriteColumn(std::to_string(value));
}
static void WriteColumnUnsignedNumeric(CsvOutputStream& stream, const unsigned int value)
{
stream.WriteColumn(std::to_string(value));
}
void DumpSndBankAliases(const SndBank* sndBank) const
{ {
const auto outputFile = OpenAliasOutputFile(sndBank); const auto outputFile = OpenAliasOutputFile(sndBank);
@ -258,6 +455,17 @@ class AssetDumperSndBank::Internal
} }
} }
static bool FindSoundBankEntry(const unsigned assetId, SoundAssetBankEntry& entry)
{
for (const auto* soundBank : SoundBank::Repository)
{
if (soundBank->GetEntry(assetId, entry))
return true;
}
return false;
}
static SoundBankEntryInputStream FindSoundDataInSoundBanks(const unsigned assetId) static SoundBankEntryInputStream FindSoundDataInSoundBanks(const unsigned assetId)
{ {
for (const auto* soundBank : SoundBank::Repository) for (const auto* soundBank : SoundBank::Repository)
@ -272,7 +480,8 @@ class AssetDumperSndBank::Internal
void DumpSoundFilePcm(const char* assetFileName, const SoundBankEntryInputStream& soundFile, const unsigned bitsPerSample) const void DumpSoundFilePcm(const char* assetFileName, const SoundBankEntryInputStream& soundFile, const unsigned bitsPerSample) const
{ {
const auto outFile = OpenAssetOutputFile(assetFileName, ".wav"); assert(soundFile.m_entry.format < SND_ASSET_FORMAT_COUNT);
const auto outFile = OpenAssetOutputFile(assetFileName, EXTENSION_BY_FORMAT[soundFile.m_entry.format]);
if (!outFile) if (!outFile)
{ {
std::cerr << "Failed to open sound output file: \"" << assetFileName << "\"\n"; std::cerr << "Failed to open sound output file: \"" << assetFileName << "\"\n";
@ -297,9 +506,10 @@ class AssetDumperSndBank::Internal
} }
} }
void DumpSoundFilePassthrough(const char* assetFileName, const SoundBankEntryInputStream& soundFile, const std::string& extension) const void DumpSoundFilePassthrough(const char* assetFileName, const SoundBankEntryInputStream& soundFile) const
{ {
const auto outFile = OpenAssetOutputFile(assetFileName, extension); assert(soundFile.m_entry.format < SND_ASSET_FORMAT_COUNT);
const auto outFile = OpenAssetOutputFile(assetFileName, EXTENSION_BY_FORMAT[soundFile.m_entry.format]);
if (!outFile) if (!outFile)
{ {
std::cerr << "Failed to open sound output file: \"" << assetFileName << "\"\n"; std::cerr << "Failed to open sound output file: \"" << assetFileName << "\"\n";
@ -328,7 +538,7 @@ class AssetDumperSndBank::Internal
break; break;
case SND_ASSET_FORMAT_FLAC: case SND_ASSET_FORMAT_FLAC:
DumpSoundFilePassthrough(alias.assetFileName, soundFile, ".flac"); DumpSoundFilePassthrough(alias.assetFileName, soundFile);
break; break;
case SND_ASSET_FORMAT_PCMS24: case SND_ASSET_FORMAT_PCMS24: