mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-19 15:52:53 +00:00
First iteration for dumping t6 sound aliases
This commit is contained in:
parent
d29dc082e2
commit
3a825d1440
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user