|
|
|
@ -84,6 +84,7 @@ static void UpdateReverbEffectParameter(const ReverbInfo::ParameterVersion2& par |
|
|
|
const auto pow_10 = [](f32 val) -> f32 { |
|
|
|
return (val >= 0.0f) ? 1.0f : (val <= -5.3f) ? 0.0f : std::pow(10.0f, val); |
|
|
|
}; |
|
|
|
|
|
|
|
const auto cos = [](f32 degrees) -> f32 { |
|
|
|
return std::cos(degrees * std::numbers::pi_v<f32> / 180.0f); |
|
|
|
}; |
|
|
|
@ -91,26 +92,39 @@ static void UpdateReverbEffectParameter(const ReverbInfo::ParameterVersion2& par |
|
|
|
static bool unk_initialized{false}; |
|
|
|
static Common::FixedPoint<50, 14> unk_value{}; |
|
|
|
|
|
|
|
const auto sample_rate{Common::FixedPoint<50, 14>::from_base(params.sample_rate)}; |
|
|
|
const auto pre_delay_time{Common::FixedPoint<50, 14>::from_base(params.pre_delay)}; |
|
|
|
auto sample_rate = Common::FixedPoint<50, 14>::from_base(params.sample_rate); |
|
|
|
if (sample_rate.to_float() < 1.0f) sample_rate = Common::FixedPoint<50, 14>(1.0f); |
|
|
|
|
|
|
|
auto pre_delay_time = Common::FixedPoint<50, 14>::from_base(params.pre_delay); |
|
|
|
if (pre_delay_time.to_float() < 0.0f) pre_delay_time = Common::FixedPoint<50, 14>(0.0f); |
|
|
|
|
|
|
|
for (u32 i = 0; i < ReverbInfo::MaxDelayTaps; i++) { |
|
|
|
auto early_delay{ |
|
|
|
((pre_delay_time + EarlyDelayTimes[params.early_mode][i]) * sample_rate).to_int()}; |
|
|
|
early_delay = (std::min)(early_delay, state.pre_delay_line.sample_count_max); |
|
|
|
state.early_delay_times[i] = early_delay + 1; |
|
|
|
state.early_gains[i] = Common::FixedPoint<50, 14>::from_base(params.early_gain) * |
|
|
|
EarlyDelayGains[params.early_mode][i]; |
|
|
|
int target_delay = ((pre_delay_time + EarlyDelayTimes[params.early_mode][i]) * sample_rate).to_int(); |
|
|
|
if (target_delay < 0) target_delay = 0; |
|
|
|
if (target_delay > state.pre_delay_line.sample_count_max) target_delay = state.pre_delay_line.sample_count_max; |
|
|
|
|
|
|
|
int old_delay = state.early_delay_times[i] - 1; |
|
|
|
int smooth_delay = old_delay + (target_delay - old_delay) / 4; |
|
|
|
state.early_delay_times[i] = smooth_delay + 1; |
|
|
|
|
|
|
|
auto target_gain = Common::FixedPoint<50, 14>::from_base(params.early_gain) * EarlyDelayGains[params.early_mode][i]; |
|
|
|
if (target_gain.to_float() < 0.0f) target_gain = Common::FixedPoint<50, 14>(0.0f); |
|
|
|
if (target_gain.to_float() > 1.0f) target_gain = Common::FixedPoint<50, 14>(1.0f); |
|
|
|
|
|
|
|
state.early_gains[i] = state.early_gains[i] + (target_gain - state.early_gains[i]) / 4; |
|
|
|
} |
|
|
|
|
|
|
|
if (params.channel_count == 2) { |
|
|
|
state.early_gains[4] * 0.5f; |
|
|
|
state.early_gains[5] * 0.5f; |
|
|
|
state.early_gains[4] *= Common::FixedPoint<50, 14>(0.5f); |
|
|
|
state.early_gains[5] *= Common::FixedPoint<50, 14>(0.5f); |
|
|
|
} |
|
|
|
|
|
|
|
auto pre_time{ |
|
|
|
((pre_delay_time + EarlyDelayTimes[params.early_mode][10]) * sample_rate).to_int()}; |
|
|
|
state.pre_delay_time = (std::min)(pre_time, state.pre_delay_line.sample_count_max); |
|
|
|
int target_pre_time = ((pre_delay_time + EarlyDelayTimes[params.early_mode][10]) * sample_rate).to_int(); |
|
|
|
if (target_pre_time < 0) target_pre_time = 0; |
|
|
|
if (target_pre_time > state.pre_delay_line.sample_count_max) target_pre_time = state.pre_delay_line.sample_count_max; |
|
|
|
|
|
|
|
int old_pre_time = state.pre_delay_time; |
|
|
|
state.pre_delay_time = old_pre_time + (target_pre_time - old_pre_time) / 4; |
|
|
|
|
|
|
|
if (!unk_initialized) { |
|
|
|
unk_value = cos((1280.0f / sample_rate).to_float()); |
|
|
|
@ -118,45 +132,64 @@ static void UpdateReverbEffectParameter(const ReverbInfo::ParameterVersion2& par |
|
|
|
} |
|
|
|
|
|
|
|
for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) { |
|
|
|
const auto fdn_delay{(FdnDelayTimes[params.late_mode][i] * sample_rate).to_int()}; |
|
|
|
state.fdn_delay_lines[i].sample_count = |
|
|
|
(std::min)(fdn_delay, state.fdn_delay_lines[i].sample_count_max); |
|
|
|
state.fdn_delay_lines[i].buffer_end = |
|
|
|
&state.fdn_delay_lines[i].buffer[state.fdn_delay_lines[i].sample_count - 1]; |
|
|
|
|
|
|
|
const auto decay_delay{(DecayDelayTimes[params.late_mode][i] * sample_rate).to_int()}; |
|
|
|
state.decay_delay_lines[i].sample_count = |
|
|
|
(std::min)(decay_delay, state.decay_delay_lines[i].sample_count_max); |
|
|
|
state.decay_delay_lines[i].buffer_end = |
|
|
|
&state.decay_delay_lines[i].buffer[state.decay_delay_lines[i].sample_count - 1]; |
|
|
|
|
|
|
|
state.decay_delay_lines[i].decay = |
|
|
|
0.5999755859375f * (1.0f - Common::FixedPoint<50, 14>::from_base(params.colouration)); |
|
|
|
|
|
|
|
auto a{(Common::FixedPoint<50, 14>(state.fdn_delay_lines[i].sample_count_max) + |
|
|
|
state.decay_delay_lines[i].sample_count_max) * |
|
|
|
-3}; |
|
|
|
auto b{a / (Common::FixedPoint<50, 14>::from_base(params.decay_time) * sample_rate)}; |
|
|
|
Common::FixedPoint<50, 14> c{0.0f}; |
|
|
|
Common::FixedPoint<50, 14> d{0.0f}; |
|
|
|
auto hf_decay_ratio{Common::FixedPoint<50, 14>::from_base(params.high_freq_decay_ratio)}; |
|
|
|
|
|
|
|
if (hf_decay_ratio > 0.99493408203125f) { |
|
|
|
int target_fdn_delay = (FdnDelayTimes[params.late_mode][i] * sample_rate).to_int(); |
|
|
|
if (target_fdn_delay < 0) target_fdn_delay = 0; |
|
|
|
if (target_fdn_delay > state.fdn_delay_lines[i].sample_count_max) target_fdn_delay = state.fdn_delay_lines[i].sample_count_max; |
|
|
|
|
|
|
|
int old_fdn = state.fdn_delay_lines[i].sample_count; |
|
|
|
state.fdn_delay_lines[i].sample_count = old_fdn + (target_fdn_delay - old_fdn) / 4; |
|
|
|
state.fdn_delay_lines[i].buffer_end = &state.fdn_delay_lines[i].buffer[state.fdn_delay_lines[i].sample_count - 1]; |
|
|
|
|
|
|
|
int target_decay_delay = (DecayDelayTimes[params.late_mode][i] * sample_rate).to_int(); |
|
|
|
if (target_decay_delay < 0) target_decay_delay = 0; |
|
|
|
if (target_decay_delay > state.decay_delay_lines[i].sample_count_max) target_decay_delay = state.decay_delay_lines[i].sample_count_max; |
|
|
|
|
|
|
|
int old_decay = state.decay_delay_lines[i].sample_count; |
|
|
|
state.decay_delay_lines[i].sample_count = old_decay + (target_decay_delay - old_decay) / 4; |
|
|
|
state.decay_delay_lines[i].buffer_end = &state.decay_delay_lines[i].buffer[state.decay_delay_lines[i].sample_count - 1]; |
|
|
|
|
|
|
|
auto colouration = Common::FixedPoint<50, 14>::from_base(params.colouration); |
|
|
|
if (colouration.to_float() < 0.0f) colouration = Common::FixedPoint<50, 14>(0.0f); |
|
|
|
if (colouration.to_float() > 1.0f) colouration = Common::FixedPoint<50, 14>(1.0f); |
|
|
|
|
|
|
|
state.decay_delay_lines[i].decay = state.decay_delay_lines[i].decay + (0.5999755859375f * (1.0f - colouration) - state.decay_delay_lines[i].decay) / 4; |
|
|
|
|
|
|
|
auto decay_time_fp = Common::FixedPoint<50, 14>::from_base(params.decay_time); |
|
|
|
if (decay_time_fp.to_float() <= 0.0f) decay_time_fp = Common::FixedPoint<50, 14>(0.0001f); |
|
|
|
|
|
|
|
auto a = (Common::FixedPoint<50, 14>(state.fdn_delay_lines[i].sample_count_max) + state.decay_delay_lines[i].sample_count_max) * -3; |
|
|
|
auto b = a / (decay_time_fp * sample_rate); |
|
|
|
|
|
|
|
auto hf_decay_ratio = Common::FixedPoint<50, 14>::from_base(params.high_freq_decay_ratio); |
|
|
|
if (hf_decay_ratio.to_float() < 0.001f) hf_decay_ratio = Common::FixedPoint<50, 14>(0.001f); |
|
|
|
if (hf_decay_ratio.to_float() > 0.999f) hf_decay_ratio = Common::FixedPoint<50, 14>(0.999f); |
|
|
|
|
|
|
|
Common::FixedPoint<50, 14> c{0.0f}, d{0.0f}; |
|
|
|
if (hf_decay_ratio.to_float() > 0.9949f) { |
|
|
|
c = 0.0f; |
|
|
|
d = 1.0f; |
|
|
|
} else { |
|
|
|
const auto e{ |
|
|
|
pow_10(((((1.0f / hf_decay_ratio) - 1.0f) * 2) / 100 * (b / 10)).to_float())}; |
|
|
|
const auto f{1.0f - e}; |
|
|
|
const auto g{2.0f - (unk_value * e * 2)}; |
|
|
|
const auto h{std::sqrt(std::pow(g.to_float(), 2.0f) - (std::pow(f, 2.0f) * 4))}; |
|
|
|
auto e = pow_10(((((1.0f / hf_decay_ratio.to_float()) - 1.0f) * 2) / 100 * (b / 10)).to_float()); |
|
|
|
if (e < 0.0001f) e = 0.0001f; |
|
|
|
if (e > 1.0f) e = 1.0f; |
|
|
|
|
|
|
|
auto f = 1.0f - e; |
|
|
|
if (f < 0.0001f) f = 0.0001f; |
|
|
|
|
|
|
|
auto g = 2.0f - (unk_value.to_float() * e * 2); |
|
|
|
|
|
|
|
auto h_sq = g * g - f * f * 4; |
|
|
|
if (h_sq < 0.0f) h_sq = 0.0f; |
|
|
|
|
|
|
|
auto h = std::sqrt(h_sq); |
|
|
|
|
|
|
|
c = (g - h) / (f * 2.0f); |
|
|
|
d = 1.0f - c; |
|
|
|
} |
|
|
|
|
|
|
|
state.hf_decay_prev_gain[i] = c; |
|
|
|
state.hf_decay_gain[i] = pow_10((b / 1000).to_float()) * d * 0.70709228515625f; |
|
|
|
state.hf_decay_prev_gain[i] = state.hf_decay_prev_gain[i] + (c - state.hf_decay_prev_gain[i]) / 4; |
|
|
|
state.hf_decay_gain[i] = state.hf_decay_gain[i] + (pow_10((b / 1000).to_float()) * d * 0.70709228515625f - state.hf_decay_gain[i]) / 4; |
|
|
|
|
|
|
|
state.prev_feedback_output[i] = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -191,6 +224,8 @@ static void InitializeReverbEffect(const ReverbInfo::ParameterVersion2& params, |
|
|
|
const auto center_delay_time{(5 * delay).to_uint_floor()}; |
|
|
|
state.center_delay_line.Initialize(center_delay_time, 1.0f); |
|
|
|
|
|
|
|
UpdateReverbEffectParameter(params, state); |
|
|
|
|
|
|
|
for (u32 i = 0; i < ReverbInfo::MaxDelayLines; i++) { |
|
|
|
std::ranges::fill(state.fdn_delay_lines[i].buffer, 0); |
|
|
|
std::ranges::fill(state.decay_delay_lines[i].buffer, 0); |
|
|
|
|