Beispiel #1
0
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;
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
    
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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;
    
}