Skip to content

Commit

Permalink
fix: formula for dbspl and cent values
Browse files Browse the repository at this point in the history
  • Loading branch information
Laupetin committed Oct 6, 2024
1 parent 70bfd06 commit 513d849
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 66 deletions.
88 changes: 45 additions & 43 deletions src/ObjLoading/Game/T6/AssetLoaders/AssetLoaderSoundBank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,40 @@ unsigned int GetAliasSubListCount(const unsigned int startRow, const ParsedCsv&
return count;
}

double DecibelsToAmp(double decibels)
float DbsplToLinear(const float dbsplValue)
{
return std::pow(10.0, decibels / 20.0);
return std::pow(10.0f, (dbsplValue - 100.0f) / 20.0f);
}

double CentsToHertz(double cents)
float CentToHertz(const float cents)
{
return std::numeric_limits<int16_t>::max() * std::pow(2, cents / 1200.0);
return std::pow(2.0f, cents / 1200.0f);
}

bool ReadColumnVolumeDbspl(const float dbsplValue, const char* colName, const unsigned rowIndex, uint16_t& value)
{
if (dbsplValue < 0.0f || dbsplValue > 100.0f)
{
std::cerr << std::format("Invalid value for row {} col '{}' - {} [0.0, 100.0]\n", rowIndex + 1, colName, dbsplValue);
return false;
}

value = static_cast<uint16_t>(DbsplToLinear(dbsplValue) * static_cast<float>(std::numeric_limits<uint16_t>::max()));

return true;
}

bool ReadColumnPitchCents(const float centValue, const char* colName, const unsigned rowIndex, uint16_t& value)
{
if (centValue < -2400.0f || centValue > 1200.0f)
{
std::cerr << std::format("Invalid value for row {} col '{}' - {} [-2400.0, 1200.0]\n", rowIndex + 1, colName, centValue);
return false;
}

value = static_cast<uint16_t>(CentToHertz(centValue) * static_cast<float>(std::numeric_limits<uint16_t>::max()));

return true;
}

bool LoadSoundAlias(MemoryManager* memory, SndAlias* alias, const ParsedCsvRow& row, const unsigned int rowNum)
Expand Down Expand Up @@ -153,49 +179,17 @@ bool LoadSoundAlias(MemoryManager* memory, SndAlias* alias, const ParsedCsvRow&

alias->duck = Common::SND_HashName(row.GetValue("duck").data());

const auto volMinDecibels = row.GetValueFloat("vol_min");

if (volMinDecibels < 0.0f || volMinDecibels > 100.0f)
{
std::cerr << std::format("Invalid value for row {} col 'vol_min' - {} [0.0, 100.0]\n", rowNum + 1, volMinDecibels);
if (!ReadColumnVolumeDbspl(row.GetValueFloat("vol_min"), "vol_min", rowNum, alias->volMin))
return false;
}

const auto volMinAmp = static_cast<int>(std::round(DecibelsToAmp(volMinDecibels) / T6::Common::AMP_RATIO));
alias->volMin = volMinAmp;

const auto volMaxDecibels = row.GetValueFloat("vol_max");

if (volMaxDecibels < 0.0f || volMaxDecibels > 100.0f)
{
std::cerr << std::format("Invalid value for row {} col 'vol_max' - {} [0.0, 100.0]\n", rowNum + 1, volMaxDecibels);
if (!ReadColumnVolumeDbspl(row.GetValueFloat("vol_max"), "vol_max", rowNum, alias->volMax))
return false;
}

const auto volMaxAmp = static_cast<int>(std::round(DecibelsToAmp(volMaxDecibels) / T6::Common::AMP_RATIO));
alias->volMax = volMaxAmp;

const auto pitchMinCents = row.GetValueFloat("pitch_min");

if (pitchMinCents < -2400.0f || pitchMinCents > 1200.0f)
{
std::cerr << std::format("Invalid value for row {} col 'pitch_min' - {} [-2400.0, 1200.0]\n", rowNum + 1, pitchMinCents);
if (!ReadColumnVolumeDbspl(row.GetValueFloat("pitch_min"), "pitch_min", rowNum, alias->pitchMin))
return false;
}

const auto pitchMinHertz = static_cast<int>(std::round(CentsToHertz(pitchMinCents)));
alias->pitchMin = pitchMinHertz;

const auto pitchMaxCents = row.GetValueFloat("pitch_max");

if (pitchMaxCents < -2400.0f || pitchMaxCents > 1200.0f)
{
std::cerr << std::format("Invalid value for row {} col 'pitch_max' - {} [-2400.0, 1200.0]\n", rowNum + 1, pitchMaxCents);
if (!ReadColumnVolumeDbspl(row.GetValueFloat("pitch_max"), "pitch_max", rowNum, alias->pitchMax))
return false;
}

const auto pitchMaxHertz = static_cast<int>(std::round(CentsToHertz(pitchMaxCents)));
alias->pitchMax = pitchMaxHertz;

alias->distMin = row.GetValueInt<decltype(alias->distMin)>("dist_min");
alias->distMax = row.GetValueInt<decltype(alias->distMax)>("dist_max");
Expand All @@ -208,11 +202,19 @@ bool LoadSoundAlias(MemoryManager* memory, SndAlias* alias, const ParsedCsvRow&
alias->maxPriorityThreshold = row.GetValueInt<decltype(alias->maxPriorityThreshold)>("max_priority_threshold");
alias->probability = row.GetValueInt<decltype(alias->probability)>("probability");
alias->startDelay = row.GetValueInt<decltype(alias->startDelay)>("start_delay");
alias->reverbSend = row.GetValueInt<decltype(alias->reverbSend)>("reverb_send");
alias->centerSend = row.GetValueInt<decltype(alias->centerSend)>("center_send");

if (!ReadColumnVolumeDbspl(row.GetValueFloat("reverb_send"), "reverb_send", rowNum, alias->reverbSend))
return false;

if (!ReadColumnVolumeDbspl(row.GetValueFloat("center_send"), "center_send", rowNum, alias->centerSend))
return false;

alias->envelopMin = row.GetValueInt<decltype(alias->envelopMin)>("envelop_min");
alias->envelopMax = row.GetValueInt<decltype(alias->envelopMax)>("envelop_max");
alias->envelopPercentage = row.GetValueInt<decltype(alias->envelopPercentage)>("envelop_percentage");

if (!ReadColumnVolumeDbspl(row.GetValueFloat("envelop_percentage"), "envelop_percentage", rowNum, alias->envelopPercentage))
return false;

alias->occlusionLevel = row.GetValueInt<decltype(alias->occlusionLevel)>("occlusion_level");
alias->fluxTime = row.GetValueInt<decltype(alias->fluxTime)>("move_time");
alias->futzPatch = row.GetValueInt<decltype(alias->futzPatch)>("futz");
Expand Down
53 changes: 30 additions & 23 deletions src/ObjWriting/Game/T6/AssetDumpers/AssetDumperSndBank.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,19 +226,34 @@ class AssetDumperSndBank::Internal
}
}

static double AmpToDecibels(double amp)
static float LinearToDbspl(float linear)
{
if (amp == 0.0)
{
return 0.0;
}
linear = std::max(linear, 0.0000152879f);

const auto db = 20.0f * std::log10(linear);
if (db > -95.0f)
return db + 100.0f;

return 0;
}

return 20.0 * std::log10(amp);
static float HertzToCents(const float hertz)
{
return 1200.0f * std::log2(hertz);
}

static void WriteColumnVolumeLinear(CsvOutputStream& stream, const uint16_t value)
{
const auto linear = static_cast<float>(value) / static_cast<float>(std::numeric_limits<uint16_t>::max());
const auto dbSpl = std::clamp(LinearToDbspl(linear), 0.0f, 100.0f);
stream.WriteColumn(std::format("{:.3g}", dbSpl));
}

static double HertzToCents(double hertz)
static void WriteColumnPitchHertz(CsvOutputStream& stream, const uint16_t value)
{
return 1200.0 * std::log2(hertz / std::numeric_limits<int16_t>::max());
const auto hertz = static_cast<float>(value) / static_cast<float>(std::numeric_limits<uint16_t>::max());
const auto cents = std::clamp(HertzToCents(hertz), -2400.0f, 1200.0f);
stream.WriteColumn(std::format("{:.4g}", cents));
}

static void WriteAliasToFile(CsvOutputStream& stream, const SndAlias* alias, const std::optional<snd_asset_format> maybeFormat, const SndBank* bank)
Expand All @@ -263,14 +278,10 @@ class AssetDumperSndBank::Internal
stream.WriteColumn(SOUND_GROUPS[alias->flags.volumeGroup]);

// vol_min
const auto volMinAmp = alias->volMin * T6::Common::AMP_RATIO;
const auto volMinDecibels = static_cast<int>(std::round(AmpToDecibels(volMinAmp)));
stream.WriteColumn(std::to_string(volMinDecibels));
WriteColumnVolumeLinear(stream, alias->volMin);

// vol_max
const auto volMaxAmp = alias->volMax * T6::Common::AMP_RATIO;
const auto volMaxDecibels = static_cast<int>(std::round(AmpToDecibels(volMaxAmp)));
stream.WriteColumn(std::to_string(volMaxDecibels));
WriteColumnVolumeLinear(stream, alias->volMax);

// team_vol_mod
stream.WriteColumn("");
Expand Down Expand Up @@ -309,14 +320,10 @@ class AssetDumperSndBank::Internal
stream.WriteColumn(SOUND_LIMIT_TYPES[alias->flags.entityLimitType]);

// pitch_min
const auto pitchMinHertz = alias->pitchMin;
const auto pitchMinCents = static_cast<int>(std::round(HertzToCents(pitchMinHertz)));
stream.WriteColumn(std::to_string(pitchMinCents));
WriteColumnPitchHertz(stream, alias->pitchMin);

// pitch_max
const auto pitchMaxHertz = alias->pitchMax;
const auto pitchMaxCents = static_cast<int>(std::round(HertzToCents(pitchMaxHertz)));
stream.WriteColumn(std::to_string(pitchMaxCents));
WriteColumnPitchHertz(stream, alias->pitchMax);

// team_pitch_mod
stream.WriteColumn("");
Expand Down Expand Up @@ -352,7 +359,7 @@ class AssetDumperSndBank::Internal
stream.WriteColumn(std::to_string(alias->startDelay));

// reverb_send
stream.WriteColumn(std::to_string(alias->reverbSend));
WriteColumnVolumeLinear(stream, alias->reverbSend);

// duck
stream.WriteColumn(FindNameForDuck(alias->duck, bank));
Expand All @@ -364,7 +371,7 @@ class AssetDumperSndBank::Internal
stream.WriteColumn(alias->flags.panType == SA_PAN_2D ? "2d" : "3d");

// center_send
stream.WriteColumn(std::to_string(alias->centerSend));
WriteColumnVolumeLinear(stream, alias->centerSend);

// envelop_min
stream.WriteColumn(std::to_string(alias->envelopMin));
Expand All @@ -373,7 +380,7 @@ class AssetDumperSndBank::Internal
stream.WriteColumn(std::to_string(alias->envelopMax));

// envelop_percentage
stream.WriteColumn(std::to_string(alias->envelopPercentage));
WriteColumnVolumeLinear(stream, alias->envelopPercentage);

// occlusion_level
stream.WriteColumn(std::to_string(alias->occlusionLevel));
Expand Down

0 comments on commit 513d849

Please sign in to comment.