static void noise_gate_update(void *data, obs_data_t *s) { struct noise_gate_data *ng = data; float open_threshold_db; float close_threshold_db; float sample_rate; int attack_time_ms; int hold_time_ms; int release_time_ms; open_threshold_db = (float)obs_data_get_double(s, S_OPEN_THRESHOLD); close_threshold_db = (float)obs_data_get_double(s, S_CLOSE_THRESHOLD); attack_time_ms = (int)obs_data_get_int(s, S_ATTACK_TIME); hold_time_ms = (int)obs_data_get_int(s, S_HOLD_TIME); release_time_ms = (int)obs_data_get_int(s, S_RELEASE_TIME); sample_rate = (float)audio_output_get_sample_rate(obs_get_audio()); ng->sample_rate_i = 1.0f / sample_rate; ng->channels = audio_output_get_channels(obs_get_audio()); ng->open_threshold = db_to_mul(open_threshold_db); ng->close_threshold = db_to_mul(close_threshold_db); ng->attack_rate = 1.0f / (ms_to_secf(attack_time_ms) * sample_rate); ng->release_rate = 1.0f / (ms_to_secf(release_time_ms) * sample_rate); const float threshold_diff = ng->open_threshold - ng->close_threshold; const float min_decay_period = (1.0f / 75.0f) * sample_rate; ng->decay_rate = threshold_diff / min_decay_period; ng->hold_time = ms_to_secf(hold_time_ms); ng->is_open = false; ng->attenuation = 0.0f; ng->level = 0.0f; ng->held_time = 0.0f; }
bool obs_fader_set_db(obs_fader_t *fader, const float db) { if (!fader) return false; pthread_mutex_lock(&fader->mutex); bool clamped = false; fader->cur_db = db; if (fader->cur_db > fader->max_db) { fader->cur_db = fader->max_db; clamped = true; } if (fader->cur_db < fader->min_db) { fader->cur_db = -INFINITY; clamped = true; } fader->ignore_next_signal = true; obs_source_t *src = fader->source; const float mul = db_to_mul(fader->cur_db); pthread_mutex_unlock(&fader->mutex); if (src) obs_source_set_volume(src, mul); return !clamped; }
static void gain_update(void *data, obs_data_t *s) { struct gain_data *gf = data; double val = obs_data_get_double(s, S_GAIN_DB); gf->multiple = db_to_mul((float)val); }
static void expander_update(void *data, obs_data_t *s) { struct expander_data *cd = data; const char *presets = obs_data_get_string(s, S_PRESETS); if (strcmp(presets, "expander") == 0 && cd->is_gate) { obs_data_clear(s); obs_data_set_string(s, S_PRESETS, "expander"); expander_defaults(s); cd->is_gate = false; } if (strcmp(presets, "gate") == 0 && !cd->is_gate) { obs_data_clear(s); obs_data_set_string(s, S_PRESETS, "gate"); expander_defaults(s); cd->is_gate = true; } const uint32_t sample_rate = audio_output_get_sample_rate(obs_get_audio()); const size_t num_channels = audio_output_get_channels(obs_get_audio()); const float attack_time_ms = (float)obs_data_get_int(s, S_ATTACK_TIME); const float release_time_ms = (float)obs_data_get_int(s, S_RELEASE_TIME); const float output_gain_db = (float)obs_data_get_double(s, S_OUTPUT_GAIN); cd->ratio = (float)obs_data_get_double(s, S_RATIO); cd->threshold = (float)obs_data_get_double(s, S_THRESHOLD); cd->attack_gain = gain_coefficient(sample_rate, attack_time_ms / MS_IN_S_F); cd->release_gain = gain_coefficient(sample_rate, release_time_ms / MS_IN_S_F); cd->output_gain = db_to_mul(output_gain_db); cd->num_channels = num_channels; cd->sample_rate = sample_rate; cd->slope = 1.0f - cd->ratio; const char *detect_mode = obs_data_get_string(s, S_DETECTOR); if (strcmp(detect_mode, "RMS") == 0) cd->detector = RMS_DETECT; if (strcmp(detect_mode, "peak") == 0) cd->detector = PEAK_DETECT; if (strcmp(detect_mode, "none") == 0) cd->detector = NO_DETECT; size_t sample_len = sample_rate * DEFAULT_AUDIO_BUF_MS / MS_IN_S; if (cd->envelope_buf_len == 0) resize_env_buffer(cd, sample_len); if (cd->runaverage_len == 0) resize_runaverage_buffer(cd, sample_len); if (cd->maxspl_len == 0) resize_maxspl_buffer(cd, sample_len); if (cd->env_in_len == 0) resize_env_in_buffer(cd, sample_len); }
static float cubic_db_to_def(const float db) { if (db == 0.0f) return 1.0f; else if (db == -INFINITY) return 0.0f; return cbrtf(db_to_mul(db)); }
float obs_fader_get_mul(obs_fader_t *fader) { if (!fader) return 0.0f; pthread_mutex_lock(&fader->mutex); const float mul = db_to_mul(fader->cur_db); pthread_mutex_unlock(&fader->mutex); return mul; }
static inline void process_expansion(const struct expander_data *cd, float **samples, uint32_t num_samples) { for (size_t i = 0; i < num_samples; ++i) { float env_db = mul_to_db(cd->envelope_buf[i]); float gain = fmaxf(cd->slope * (cd->threshold - env_db), -60.0); gain = db_to_mul(fminf(0, gain)); for (size_t c = 0; c < cd->num_channels; ++c) { if (samples[c]) { samples[c][i] *= gain * cd->output_gain; } } } }