mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-20 21:13:04 +02:00
obs-filters: Refactor expander filter expansion code
Things were a bit unoptimal and were squished together, making the code much more difficult to work with. Instead, separate the code for processing individual samples into its own function.
This commit is contained in:
parent
89006716b4
commit
56cfaf792d
@ -304,59 +304,80 @@ static void analyze_envelope(struct expander_data *cd, float **samples,
|
||||
}
|
||||
}
|
||||
|
||||
static inline void process_sample(size_t idx, float *samples, float *env_buf,
|
||||
float *gain_db, float channel_gain,
|
||||
float threshold, float slope,
|
||||
float attack_gain, float inv_attack_gain,
|
||||
float release_gain, float inv_release_gain,
|
||||
float output_gain)
|
||||
{
|
||||
/* --------------------------------- */
|
||||
/* gain stage of expansion */
|
||||
|
||||
float env_db = mul_to_db(env_buf[idx]);
|
||||
float diff = threshold - env_db;
|
||||
float gain = diff > 0.0f ? fmaxf(slope * diff, -60.0f) : 0.0f;
|
||||
float prev_gain = gain_db[idx - 1];
|
||||
|
||||
/* --------------------------------- */
|
||||
/* ballastics (attack/release) */
|
||||
|
||||
if (idx > 0) {
|
||||
if (gain > prev_gain)
|
||||
gain_db[idx] = attack_gain * prev_gain +
|
||||
inv_attack_gain * gain;
|
||||
else
|
||||
gain_db[idx] = release_gain * prev_gain +
|
||||
inv_release_gain * gain;
|
||||
} else {
|
||||
if (gain > channel_gain)
|
||||
gain_db[idx] = attack_gain * channel_gain +
|
||||
inv_attack_gain * gain;
|
||||
else
|
||||
gain_db[idx] = release_gain * channel_gain +
|
||||
inv_release_gain * gain;
|
||||
}
|
||||
|
||||
/* --------------------------------- */
|
||||
/* output */
|
||||
|
||||
gain = db_to_mul(fminf(0.0f, gain_db[idx]));
|
||||
samples[idx] *= gain * output_gain;
|
||||
}
|
||||
|
||||
// gain stage and ballistics in dB domain
|
||||
static inline void process_expansion(struct expander_data *cd, float **samples,
|
||||
uint32_t num_samples)
|
||||
{
|
||||
const float attack_gain = cd->attack_gain;
|
||||
const float release_gain = cd->release_gain;
|
||||
const float inv_attack_gain = 1.0f - attack_gain;
|
||||
const float inv_release_gain = 1.0f - release_gain;
|
||||
const float threshold = cd->threshold;
|
||||
const float slope = cd->slope;
|
||||
const float output_gain = cd->output_gain;
|
||||
|
||||
if (cd->gain_db_len < num_samples)
|
||||
resize_gain_db_buffer(cd, num_samples);
|
||||
for (int i = 0; i < MAX_AUDIO_CHANNELS; i++)
|
||||
|
||||
for (size_t i = 0; i < cd->num_channels; i++)
|
||||
memset(cd->gain_db[i], 0,
|
||||
num_samples * sizeof(cd->gain_db[i][0]));
|
||||
|
||||
for (size_t chan = 0; chan < cd->num_channels; chan++) {
|
||||
for (size_t i = 0; i < num_samples; ++i) {
|
||||
// gain stage of expansion
|
||||
float env_db = mul_to_db(cd->envelope_buf[chan][i]);
|
||||
float gain =
|
||||
cd->threshold - env_db > 0.0f
|
||||
? fmaxf(cd->slope * (cd->threshold -
|
||||
env_db),
|
||||
-60.0f)
|
||||
: 0.0f;
|
||||
// ballistics (attack/release)
|
||||
if (i > 0) {
|
||||
if (gain > cd->gain_db[chan][i - 1])
|
||||
cd->gain_db[chan][i] =
|
||||
attack_gain *
|
||||
cd->gain_db[chan][i - 1] +
|
||||
(1.0f - attack_gain) * gain;
|
||||
else
|
||||
cd->gain_db[chan][i] =
|
||||
release_gain *
|
||||
cd->gain_db[chan][i - 1] +
|
||||
(1.0f - release_gain) * gain;
|
||||
} else {
|
||||
if (gain > cd->gain_db_buf[chan])
|
||||
cd->gain_db[chan][i] =
|
||||
attack_gain *
|
||||
cd->gain_db_buf[chan] +
|
||||
(1.0f - attack_gain) * gain;
|
||||
else
|
||||
cd->gain_db[chan][i] =
|
||||
release_gain *
|
||||
cd->gain_db_buf[chan] +
|
||||
(1.0f - release_gain) * gain;
|
||||
}
|
||||
float *channel_samples = samples[chan];
|
||||
float *env_buf = cd->envelope_buf[chan];
|
||||
float *gain_db = cd->gain_db[chan];
|
||||
float channel_gain = cd->gain_db_buf[chan];
|
||||
|
||||
gain = db_to_mul(fminf(0, cd->gain_db[chan][i]));
|
||||
if (samples[chan])
|
||||
samples[chan][i] *= gain * cd->output_gain;
|
||||
for (size_t i = 0; i < num_samples; ++i) {
|
||||
process_sample(i, channel_samples, env_buf, gain_db,
|
||||
channel_gain, threshold, slope,
|
||||
attack_gain, inv_attack_gain,
|
||||
release_gain, inv_release_gain,
|
||||
output_gain);
|
||||
}
|
||||
cd->gain_db_buf[chan] = cd->gain_db[chan][num_samples - 1];
|
||||
cd->gain_db_buf[chan] = gain_db[num_samples - 1];
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user