void * volume_thread(void * arg) { volume_t * vol = (volume_t *)arg; GList * node; float * samples = NULL; unsigned long numread; float chunk_power = 0.0f; float rms; unsigned long i; AQUALUNG_THREAD_DETACH(); for (node = vol->queue; node; node = node->next) { vol->item = (vol_item_t *)node->data; if (process_volume_setup(vol)) { continue; } if ((samples = (float *)malloc(vol->chunk_size * vol->fdec->fileinfo.channels * sizeof(float))) == NULL) { fprintf(stderr, "volume_thread(): malloc() error\n"); file_decoder_close(vol->fdec); file_decoder_delete(vol->fdec); free(vol->rms); break; } do { numread = file_decoder_read(vol->fdec, samples, vol->chunk_size); vol->chunks_read++; /* calculate signal power of chunk and feed it in the rms envelope */ if (numread > 0) { for (i = 0; i < numread * vol->fdec->fileinfo.channels; i++) { chunk_power += samples[i] * samples[i]; } chunk_power /= numread * vol->fdec->fileinfo.channels; rms = rms_env_process(vol->rms, chunk_power); if (rms > vol->result) { vol->result = rms; } } while (vol->paused && !vol->cancelled) { g_usleep(500000); } } while (numread == vol->chunk_size && !vol->cancelled); if (!vol->cancelled) { vol->result = 20.0f * log10f(vol->result); #ifdef HAVE_MPEG /* compensate for anti-clip vol.reduction in dec_mpeg.c/mpeg_output() */ if (vol->fdec->file_lib == MAD_LIB) { vol->result += 1.8f; } #endif /* HAVE_MPEG */ if (vol->type == VOLUME_SEPARATE) { AQUALUNG_MUTEX_LOCK(vol->wait_mutex); aqualung_idle_add(vol_store_result_sep, vol); AQUALUNG_COND_WAIT(vol->thread_wait, vol->wait_mutex); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); } else if (vol->type == VOLUME_AVERAGE) { vol->n_volumes++; if ((vol->volumes = realloc(vol->volumes, vol->n_volumes * sizeof(float))) == NULL) { fprintf(stderr, "volume_thread(): realloc error\n"); return NULL; } vol->volumes[vol->n_volumes - 1] = vol->result; } } file_decoder_close(vol->fdec); file_decoder_delete(vol->fdec); free(vol->rms); free(samples); if (vol->cancelled) { break; } } if (!vol->cancelled && vol->type == VOLUME_AVERAGE) { AQUALUNG_MUTEX_LOCK(vol->wait_mutex); aqualung_idle_add(vol_store_result_avg, vol); AQUALUNG_COND_WAIT(vol->thread_wait, vol->wait_mutex); AQUALUNG_MUTEX_UNLOCK(vol->wait_mutex); } for (node = vol->queue; node; node = node->next) { vol_item_free((vol_item_t *)node->data); } aqualung_idle_add(volume_finalize, vol); return NULL; }
static void runAddingSc4m(LADSPA_Handle instance, unsigned long sample_count) { Sc4m *plugin_data = (Sc4m *)instance; LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; /* RMS/peak (float value) */ const LADSPA_Data rms_peak = *(plugin_data->rms_peak); /* Attack time (ms) (float value) */ const LADSPA_Data attack = *(plugin_data->attack); /* Release time (ms) (float value) */ const LADSPA_Data release = *(plugin_data->release); /* Threshold level (dB) (float value) */ const LADSPA_Data threshold = *(plugin_data->threshold); /* Ratio (1:n) (float value) */ const LADSPA_Data ratio = *(plugin_data->ratio); /* Knee radius (dB) (float value) */ const LADSPA_Data knee = *(plugin_data->knee); /* Makeup gain (dB) (float value) */ const LADSPA_Data makeup_gain = *(plugin_data->makeup_gain); /* Input (array of floats of length sample_count) */ const LADSPA_Data * const input = plugin_data->input; /* Output (array of floats of length sample_count) */ LADSPA_Data * const output = plugin_data->output; float amp = plugin_data->amp; float * as = plugin_data->as; unsigned int count = plugin_data->count; float env = plugin_data->env; float env_peak = plugin_data->env_peak; float env_rms = plugin_data->env_rms; float gain = plugin_data->gain; float gain_t = plugin_data->gain_t; rms_env * rms = plugin_data->rms; float sum = plugin_data->sum; unsigned long pos; const float ga = attack < 2.0f ? 0.0f : as[f_round(attack * 0.001f * (float)(A_TBL-1))]; const float gr = as[f_round(release * 0.001f * (float)(A_TBL-1))]; const float rs = (ratio - 1.0f) / ratio; const float mug = db2lin(makeup_gain); const float knee_min = db2lin(threshold - knee); const float knee_max = db2lin(threshold + knee); const float ef_a = ga * 0.25f; const float ef_ai = 1.0f - ef_a; for (pos = 0; pos < sample_count; pos++) { const float lev_in = input[pos]; sum += lev_in * lev_in; if (amp > env_rms) { env_rms = env_rms * ga + amp * (1.0f - ga); } else { env_rms = env_rms * gr + amp * (1.0f - gr); } round_to_zero(&env_rms); if (lev_in > env_peak) { env_peak = env_peak * ga + lev_in * (1.0f - ga); } else { env_peak = env_peak * gr + lev_in * (1.0f - gr); } round_to_zero(&env_peak); if ((count++ & 3) == 3) { amp = rms_env_process(rms, sum * 0.25f); sum = 0.0f; env = LIN_INTERP(rms_peak, env_rms, env_peak); if (env <= knee_min) { gain_t = 1.0f; } else if (env < knee_max) { const float x = -(threshold - knee - lin2db(env)) / knee; gain_t = db2lin(-knee * rs * x * x * 0.25f); } else { gain_t = db2lin((threshold - lin2db(env)) * rs); } } gain = gain * ef_a + gain_t * ef_ai; buffer_write(output[pos], input[pos] * gain * mug); } plugin_data->sum = sum; plugin_data->amp = amp; plugin_data->gain = gain; plugin_data->gain_t = gain_t; plugin_data->env = env; plugin_data->env_rms = env_rms; plugin_data->env_peak = env_peak; plugin_data->count = count; *(plugin_data->amplitude) = lin2db(env); *(plugin_data->gain_red) = lin2db(gain); }
static void runSc3(LV2_Handle instance, uint32_t sample_count) { Sc3 *plugin_data = (Sc3 *)instance; const float attack = *(plugin_data->attack); const float release = *(plugin_data->release); const float threshold = *(plugin_data->threshold); const float ratio = *(plugin_data->ratio); const float knee = *(plugin_data->knee); const float makeup_gain = *(plugin_data->makeup_gain); const float chain_bal = *(plugin_data->chain_bal); const float * const sidechain = plugin_data->sidechain; const float * const left_in = plugin_data->left_in; const float * const right_in = plugin_data->right_in; float * const left_out = plugin_data->left_out; float * const right_out = plugin_data->right_out; rms_env * rms = plugin_data->rms; float * as = plugin_data->as; float sum = plugin_data->sum; float amp = plugin_data->amp; float gain = plugin_data->gain; float gain_t = plugin_data->gain_t; float env = plugin_data->env; unsigned int count = plugin_data->count; unsigned long pos; const float ga = as[f_round(attack * 0.001f * (float)(A_TBL-1))]; const float gr = as[f_round(release * 0.001f * (float)(A_TBL-1))]; const float rs = (ratio - 1.0f) / ratio; const float mug = db2lin(makeup_gain); const float knee_min = db2lin(threshold - knee); const float knee_max = db2lin(threshold + knee); const float chain_bali = 1.0f - chain_bal; const float ef_a = ga * 0.25f; const float ef_ai = 1.0f - ef_a; for (pos = 0; pos < sample_count; pos++) { const float lev_in = chain_bali * (left_in[pos] + right_in[pos]) * 0.5f + chain_bal * sidechain[pos]; sum += lev_in * lev_in; if (amp > env) { env = env * ga + amp * (1.0f - ga); } else { env = env * gr + amp * (1.0f - gr); } if (count++ % 4 == 3) { amp = rms_env_process(rms, sum * 0.25f); sum = 0.0f; if (isnan(env)) { // This can happen sometimes, but I dont know why env = 0.0f; } else if (env <= knee_min) { gain_t = 1.0f; } else if (env < knee_max) { const float x = -(threshold - knee - lin2db(env)) / knee; gain_t = db2lin(-knee * rs * x * x * 0.25f); } else { gain_t = db2lin((threshold - lin2db(env)) * rs); } } gain = gain * ef_a + gain_t * ef_ai; buffer_write(left_out[pos], left_in[pos] * gain * mug); buffer_write(right_out[pos], right_in[pos] * gain * mug); } plugin_data->sum = sum; plugin_data->amp = amp; plugin_data->gain = gain; plugin_data->gain_t = gain_t; plugin_data->env = env; plugin_data->count = count; }
static void runAddingSc3(LADSPA_Handle instance, unsigned long sample_count) { Sc3 *plugin_data = (Sc3 *)instance; LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; /* Attack time (ms) (float value) */ const LADSPA_Data attack = *(plugin_data->attack); /* Release time (ms) (float value) */ const LADSPA_Data release = *(plugin_data->release); /* Threshold level (dB) (float value) */ const LADSPA_Data threshold = *(plugin_data->threshold); /* Ratio (1:n) (float value) */ const LADSPA_Data ratio = *(plugin_data->ratio); /* Knee radius (dB) (float value) */ const LADSPA_Data knee = *(plugin_data->knee); /* Makeup gain (dB) (float value) */ const LADSPA_Data makeup_gain = *(plugin_data->makeup_gain); /* Chain balance (float value) */ const LADSPA_Data chain_bal = *(plugin_data->chain_bal); /* Sidechain (array of floats of length sample_count) */ const LADSPA_Data * const sidechain = plugin_data->sidechain; /* Left input (array of floats of length sample_count) */ const LADSPA_Data * const left_in = plugin_data->left_in; /* Right input (array of floats of length sample_count) */ const LADSPA_Data * const right_in = plugin_data->right_in; /* Left output (array of floats of length sample_count) */ LADSPA_Data * const left_out = plugin_data->left_out; /* Right output (array of floats of length sample_count) */ LADSPA_Data * const right_out = plugin_data->right_out; float amp = plugin_data->amp; float * as = plugin_data->as; unsigned int count = plugin_data->count; float env = plugin_data->env; float gain = plugin_data->gain; float gain_t = plugin_data->gain_t; rms_env * rms = plugin_data->rms; float sum = plugin_data->sum; #line 49 "sc3_1427.xml" unsigned long pos; const float ga = as[f_round(attack * 0.001f * (float)(A_TBL-1))]; const float gr = as[f_round(release * 0.001f * (float)(A_TBL-1))]; const float rs = (ratio - 1.0f) / ratio; const float mug = db2lin(makeup_gain); const float knee_min = db2lin(threshold - knee); const float knee_max = db2lin(threshold + knee); const float chain_bali = 1.0f - chain_bal; const float ef_a = ga * 0.25f; const float ef_ai = 1.0f - ef_a; for (pos = 0; pos < sample_count; pos++) { const float lev_in = chain_bali * (left_in[pos] + right_in[pos]) * 0.5f + chain_bal * sidechain[pos]; sum += lev_in * lev_in; if (amp > env) { env = env * ga + amp * (1.0f - ga); } else { env = env * gr + amp * (1.0f - gr); } if (count++ % 4 == 3) { amp = rms_env_process(rms, sum * 0.25f); sum = 0.0f; if (isnan(env)) { // This can happen sometimes, but I dont know why env = 0.0f; } else if (env <= knee_min) { gain_t = 1.0f; } else if (env < knee_max) { const float x = -(threshold - knee - lin2db(env)) / knee; gain_t = db2lin(-knee * rs * x * x * 0.25f); } else { gain_t = db2lin((threshold - lin2db(env)) * rs); } } gain = gain * ef_a + gain_t * ef_ai; buffer_write(left_out[pos], left_in[pos] * gain * mug); buffer_write(right_out[pos], right_in[pos] * gain * mug); } plugin_data->sum = sum; plugin_data->amp = amp; plugin_data->gain = gain; plugin_data->gain_t = gain_t; plugin_data->env = env; plugin_data->count = count; }
static void runSc4(LADSPA_Handle instance, unsigned long sample_count) { Sc4 *plugin_data = (Sc4 *)instance; /* RMS/peak (float value) */ const LADSPA_Data rms_peak = *(plugin_data->rms_peak); /* Attack time (ms) (float value) */ const LADSPA_Data attack = *(plugin_data->attack); /* Release time (ms) (float value) */ const LADSPA_Data release = *(plugin_data->release); /* Threshold level (dB) (float value) */ const LADSPA_Data threshold = *(plugin_data->threshold); /* Ratio (1:n) (float value) */ const LADSPA_Data ratio = *(plugin_data->ratio); /* Knee radius (dB) (float value) */ const LADSPA_Data knee = *(plugin_data->knee); /* Makeup gain (dB) (float value) */ const LADSPA_Data makeup_gain = *(plugin_data->makeup_gain); /* Left input (array of floats of length sample_count) */ const LADSPA_Data * const left_in = plugin_data->left_in; /* Right input (array of floats of length sample_count) */ const LADSPA_Data * const right_in = plugin_data->right_in; /* Left output (array of floats of length sample_count) */ LADSPA_Data * const left_out = plugin_data->left_out; /* Right output (array of floats of length sample_count) */ LADSPA_Data * const right_out = plugin_data->right_out; float amp = plugin_data->amp; float * as = plugin_data->as; unsigned int count = plugin_data->count; float env = plugin_data->env; float env_peak = plugin_data->env_peak; float env_rms = plugin_data->env_rms; float gain = plugin_data->gain; float gain_t = plugin_data->gain_t; rms_env * rms = plugin_data->rms; float sum = plugin_data->sum; #line 51 "sc4_1434.xml" unsigned long pos; const float ga = attack < 2.0f ? 0.0f : as[f_round(attack * 0.001f * (float)(A_TBL-1))]; const float gr = as[f_round(release * 0.001f * (float)(A_TBL-1))]; const float rs = (ratio - 1.0f) / ratio; const float mug = db2lin(makeup_gain); const float knee_min = db2lin(threshold - knee); const float knee_max = db2lin(threshold + knee); const float ef_a = ga * 0.25f; const float ef_ai = 1.0f - ef_a; for (pos = 0; pos < sample_count; pos++) { const float la = fabs(left_in[pos]); const float ra = fabs(right_in[pos]); const float lev_in = f_max(la, ra); sum += lev_in * lev_in; if (amp > env_rms) { env_rms = env_rms * ga + amp * (1.0f - ga); } else { env_rms = env_rms * gr + amp * (1.0f - gr); } if (lev_in > env_peak) { env_peak = env_peak * ga + lev_in * (1.0f - ga); } else { env_peak = env_peak * gr + lev_in * (1.0f - gr); } if ((count++ & 3) == 3) { amp = rms_env_process(rms, sum * 0.25f); sum = 0.0f; if (isnan(env_rms)) { // This can happen sometimes, but I don't know why env_rms = 0.0f; } env = LIN_INTERP(rms_peak, env_rms, env_peak); if (env <= knee_min) { gain_t = 1.0f; } else if (env < knee_max) { const float x = -(threshold - knee - lin2db(env)) / knee; gain_t = db2lin(-knee * rs * x * x * 0.25f); } else { gain_t = db2lin((threshold - lin2db(env)) * rs); } } gain = gain * ef_a + gain_t * ef_ai; buffer_write(left_out[pos], left_in[pos] * gain * mug); buffer_write(right_out[pos], right_in[pos] * gain * mug); } plugin_data->sum = sum; plugin_data->amp = amp; plugin_data->gain = gain; plugin_data->gain_t = gain_t; plugin_data->env = env; plugin_data->env_rms = env_rms; plugin_data->env_peak = env_peak; plugin_data->count = count; *(plugin_data->amplitude) = lin2db(env); *(plugin_data->gain_red) = lin2db(gain); }
static void runSc2(LV2_Handle instance, uint32_t sample_count) { Sc2 *plugin_data = (Sc2 *)instance; const float attack = *(plugin_data->attack); const float release = *(plugin_data->release); const float threshold = *(plugin_data->threshold); const float ratio = *(plugin_data->ratio); const float knee = *(plugin_data->knee); const float makeup_gain = *(plugin_data->makeup_gain); const float * const sidechain = plugin_data->sidechain; const float * const input = plugin_data->input; float * const output = plugin_data->output; rms_env * rms = plugin_data->rms; float * as = plugin_data->as; float sum = plugin_data->sum; float amp = plugin_data->amp; float gain = plugin_data->gain; float gain_t = plugin_data->gain_t; float env = plugin_data->env; unsigned int count = plugin_data->count; unsigned long pos; const float ga = as[f_round(attack * 0.001f * (float)(A_TBL-1))]; const float gr = as[f_round(release * 0.001f * (float)(A_TBL-1))]; const float rs = (ratio - 1.0f) / ratio; const float mug = db2lin(makeup_gain); const float knee_min = db2lin(threshold - knee); const float knee_max = db2lin(threshold + knee); const float ef_a = ga * 0.25f; const float ef_ai = 1.0f - ef_a; for (pos = 0; pos < sample_count; pos++) { sum += sidechain[pos] * sidechain[pos]; if (amp > env) { env = env * ga + amp * (1.0f - ga); } else { env = env * gr + amp * (1.0f - gr); } if (count++ % 4 == 3) { amp = rms_env_process(rms, sum * 0.25f); sum = 0.0f; if (env <= knee_min) { gain_t = 1.0f; } else if (env < knee_max) { const float x = -(threshold - knee - lin2db(env)) / knee; gain_t = db2lin(-knee * rs * x * x * 0.25f); } else { gain_t = db2lin((threshold - lin2db(env)) * rs); } } gain = gain * ef_a + gain_t * ef_ai; buffer_write(output[pos], input[pos] * gain * mug); } plugin_data->sum = sum; plugin_data->amp = amp; plugin_data->gain = gain; plugin_data->gain_t = gain_t; plugin_data->env = env; plugin_data->count = count; }