示例#1
0
static void runBodeShifterCV(LADSPA_Handle instance, unsigned long sample_count) {
	BodeShifterCV *plugin_data = (BodeShifterCV *)instance;

	/* Base shift (float value) */
	const LADSPA_Data shift_b = *(plugin_data->shift_b);

	/* Mix (-1=down, +1=up) (float value) */
	const LADSPA_Data mix = *(plugin_data->mix);

	/* Input (array of floats of length sample_count) */
	const LADSPA_Data * const input = plugin_data->input;

	/* CV Attenuation (float value) */
	const LADSPA_Data atten = *(plugin_data->atten);

	/* Shift CV (array of floats of length sample_count) */
	const LADSPA_Data * const shift = plugin_data->shift;

	/* Down out (array of floats of length sample_count) */
	LADSPA_Data * const dout = plugin_data->dout;

	/* Up out (array of floats of length sample_count) */
	LADSPA_Data * const uout = plugin_data->uout;

	/* Mix out (array of floats of length sample_count) */
	LADSPA_Data * const mixout = plugin_data->mixout;
	LADSPA_Data * delay = plugin_data->delay;
	unsigned int dptr = plugin_data->dptr;
	float fs = plugin_data->fs;
	float phi = plugin_data->phi;
	float * sint = plugin_data->sint;

#line 73 "bode_shifter_cv_1432.xml"
	unsigned long pos;
	unsigned int i;
	float hilb, rm1, rm2;
	int int_p;
	float frac_p;
	const float freq_fix = (float)SIN_T_SIZE * 1000.0f * f_clamp(atten, 0.0f, 10.0f) / fs;
	const float base_ofs = (float)SIN_T_SIZE * f_clamp(shift_b, 0.0f, 10000.0f) / fs;
	const float mixc = mix * 0.5f + 0.5f;

	for (pos = 0; pos < sample_count; pos++) {
	  delay[dptr] = input[pos];

	  /* Perform the Hilbert FIR convolution
	   * (probably FFT would be faster) */
	  hilb = 0.0f;
	  for (i = 0; i < NZEROS/2; i++) {
	    hilb += (xcoeffs[i] * delay[(dptr - i*2) & (D_SIZE - 1)]);
	  }

	  /* Calcuate the table positions for the sine modulator */
	  int_p = f_round(floor(phi));

	  /* Calculate ringmod1, the transformed input modulated with a shift Hz
	   * sinewave. This creates a +180 degree sideband at source-shift Hz and
	   * a 0 degree sindeband at source+shift Hz */
	  frac_p = phi - int_p;
	  rm1 = hilb * 0.63661978f * cube_interp(frac_p, sint[int_p],
	                  sint[int_p+1], sint[int_p+2], sint[int_p+3]);

	  /* Calcuate the table positions for the cosine modulator */
	  int_p = (int_p + SIN_T_SIZE / 4) & (SIN_T_SIZE - 1);

	  /* Calculate ringmod2, the delayed input modulated with a shift Hz
	   * cosinewave. This creates a 0 degree sideband at source+shift Hz
	   * and a -180 degree sindeband at source-shift Hz */
	  rm2 = delay[(dptr - 99) & (D_SIZE - 1)] * cube_interp(frac_p,
	        sint[int_p], sint[int_p+1], sint[int_p+2], sint[int_p+3]);

	  /* Output the sum and differences of the ringmods. The +/-180 degree
	   * sidebands cancel (more of less) and just leave the shifted
	   * components */
	  buffer_write(dout[pos], (rm2 - rm1) * 0.5f);
	  buffer_write(uout[pos], (rm2 + rm1) * 0.5f);
	  buffer_write(mixout[pos], (dout[pos] - uout[pos]) * mixc + uout[pos]);

	  dptr = (dptr + 1) & (D_SIZE - 1);
	  phi += f_clamp(shift[pos], 0.0f, 10.0f) * freq_fix + base_ofs;
	  while (phi > SIN_T_SIZE) {
	    phi -= SIN_T_SIZE;
	  }
	}

	plugin_data->dptr = dptr;
	plugin_data->phi = phi;

	*(plugin_data->latency) = 99;
}
示例#2
0
static void runVynil(LADSPA_Handle instance, unsigned long sample_count) {
	Vynil *plugin_data = (Vynil *)instance;

	/* Year (float value) */
	const LADSPA_Data year = *(plugin_data->year);

	/* RPM (float value) */
	const LADSPA_Data rpm = *(plugin_data->rpm);

	/* Surface warping (float value) */
	const LADSPA_Data warp = *(plugin_data->warp);

	/* Crackle (float value) */
	const LADSPA_Data click = *(plugin_data->click);

	/* Wear (float value) */
	const LADSPA_Data wear = *(plugin_data->wear);

	/* Input L (array of floats of length sample_count) */
	const LADSPA_Data * const in_l = plugin_data->in_l;

	/* Input R (array of floats of length sample_count) */
	const LADSPA_Data * const in_r = plugin_data->in_r;

	/* Output L (array of floats of length sample_count) */
	LADSPA_Data * const out_l = plugin_data->out_l;

	/* Output R (array of floats of length sample_count) */
	LADSPA_Data * const out_r = plugin_data->out_r;
	LADSPA_Data * buffer_m = plugin_data->buffer_m;
	unsigned int buffer_mask = plugin_data->buffer_mask;
	unsigned int buffer_pos = plugin_data->buffer_pos;
	LADSPA_Data * buffer_s = plugin_data->buffer_s;
	LADSPA_Data * click_buffer = plugin_data->click_buffer;
	fixp16 click_buffer_omega = plugin_data->click_buffer_omega;
	fixp16 click_buffer_pos = plugin_data->click_buffer_pos;
	float click_gain = plugin_data->click_gain;
	float def = plugin_data->def;
	float def_target = plugin_data->def_target;
	float fs = plugin_data->fs;
	biquad * highp = plugin_data->highp;
	biquad * lowp_m = plugin_data->lowp_m;
	biquad * lowp_s = plugin_data->lowp_s;
	biquad * noise_filt = plugin_data->noise_filt;
	float phi = plugin_data->phi;
	unsigned int sample_cnt = plugin_data->sample_cnt;

//#line 90 "vynil_1905.xml"
	unsigned long pos;
	float deflec = def;
	float deflec_target = def_target;
	float src_m, src_s;

	/* angular velocity of platter * 16 */
	const float omega = 960.0f / (rpm * fs);
	const float age = (2000 - year) * 0.01f;
	const unsigned int click_prob = (age*age*(float)RAND_MAX)/10 + click * 0.02 * RAND_MAX;
	const float noise_amp = (click + wear * 0.3f) * 0.12f + (1993.0f - year) * 0.0031f;
	const float bandwidth = (year - 1880.0f) * (rpm * 1.9f);
	const float noise_bandwidth = bandwidth * (0.25 - wear * 0.02) + click * 200.0 + 300.0;
	const float stereo = f_clamp((year - 1940.0f) * 0.02f, 0.0f, 1.0f);
	const float wrap_gain = age * 3.1f + 0.05f;
	const float wrap_bias = age * 0.1f;

	lp_set_params(lowp_m, bandwidth * (1.0 - wear * 0.86), 2.0, fs);
	lp_set_params(lowp_s, bandwidth * (1.0 - wear * 0.89), 2.0, fs);
	hp_set_params(highp, (2000-year) * 8.0, 1.5, fs);
	lp_set_params(noise_filt, noise_bandwidth, 4.0 + wear * 2.0, fs);

	for (pos = 0; pos < sample_count; pos++) {
	  unsigned int o1, o2;
	  float ofs;

	  if ((sample_cnt & 15) == 0) {
	    const float ang = phi * 2.0f * M_PI;
	    const float w = warp * (2000.0f - year) * 0.01f;
	    deflec_target = w*df(ang)*0.5f + w*w*df(2.0f*ang)*0.31f +
	                       w*w*w*df(3.0f*ang)*0.129f;
	    phi += omega;
	    while (phi > 1.0f) {
	      phi -= 1.0f;
	    }
	    if ((unsigned int)rand() < click_prob) {
	      click_buffer_omega.all = ((rand() >> 6) + 1000) * rpm;
	      click_gain = noise_amp * 5.0f * noise();
	    }
	  }
	  deflec = deflec * 0.1f + deflec_target * 0.9f;

	  /* matrix into mid_side representation (this is roughly what stereo
	   * LPs do) */
	  buffer_m[buffer_pos] = in_l[pos] + in_r[pos];
	  buffer_s[buffer_pos] = in_l[pos] - in_r[pos];

	  /* cacluate the effects of the surface warping */
	  ofs = fs * 0.009f * deflec;
	  o1 = f_round(floorf(ofs));
	  o2 = f_round(ceilf(ofs));
	  ofs -= o1;
	  src_m = LIN_INTERP(ofs, buffer_m[(buffer_pos - o1 - 1) & buffer_mask], buffer_m[(buffer_pos - o2 - 1) & buffer_mask]);
	  src_s = LIN_INTERP(ofs, buffer_s[(buffer_pos - o1 - 1) & buffer_mask], buffer_s[(buffer_pos - o2 - 1) & buffer_mask]);

	  src_m = biquad_run(lowp_m, src_m + click_buffer[click_buffer_pos.part.in & (CLICK_BUF_SIZE - 1)] * click_gain);

	  /* waveshaper */
	  src_m = LIN_INTERP(age, src_m, sinf(src_m * wrap_gain + wrap_bias));

	  /* output highpass */
	  src_m = biquad_run(highp, src_m) + biquad_run(noise_filt, noise()) * noise_amp + click_buffer[click_buffer_pos.part.in & (CLICK_BUF_SIZE - 1)] * click_gain * 0.5f;

	  /* stereo seperation filter */
	  src_s = biquad_run(lowp_s, src_s) * stereo;

	  buffer_write(out_l[pos], (src_s + src_m) * 0.5f);
	  buffer_write(out_r[pos], (src_m - src_s) * 0.5f);

	  /* roll buffer indexes */
	  buffer_pos = (buffer_pos + 1) & buffer_mask;
	  click_buffer_pos.all += click_buffer_omega.all;
	  if (click_buffer_pos.part.in >= CLICK_BUF_SIZE) {
	    click_buffer_pos.all = 0;
	    click_buffer_omega.all = 0;
	  }
	  sample_cnt++;
	}
示例#3
0
static void runAddingFlanger(LADSPA_Handle instance, unsigned long sample_count) {
	Flanger *plugin_data = (Flanger *)instance;
	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;

	/* Delay base (ms) (float value) */
	const LADSPA_Data delay_base = *(plugin_data->delay_base);

	/* Max slowdown (ms) (float value) */
	const LADSPA_Data detune = *(plugin_data->detune);

	/* LFO frequency (Hz) (float value) */
	const LADSPA_Data law_freq = *(plugin_data->law_freq);

	/* Feedback (float value) */
	const LADSPA_Data feedback = *(plugin_data->feedback);

	/* 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;
	long count = plugin_data->count;
	long delay_pos = plugin_data->delay_pos;
	long delay_size = plugin_data->delay_size;
	LADSPA_Data * delay_tbl = plugin_data->delay_tbl;
	float next_law_peak = plugin_data->next_law_peak;
	int next_law_pos = plugin_data->next_law_pos;
	long old_d_base = plugin_data->old_d_base;
	float prev_law_peak = plugin_data->prev_law_peak;
	int prev_law_pos = plugin_data->prev_law_pos;
	long sample_rate = plugin_data->sample_rate;

#line 50 "flanger_1191.xml"
	unsigned long pos;
	long d_base, new_d_base;
	LADSPA_Data out;
	float delay_depth;
	float dp; // float delay position
	float dp_frac; // fractional part
	long dp_idx; // integer delay index
	long law_p; // period of law
	float frac = 0.0f, step; // Portion the way through the block
	float law; /* law amplitude */
	float n_ph, p_ph;
	const float fb = f_clamp(feedback, -0.999f, 0.999f);
	
	// Set law params
	law_p = (float)sample_rate / law_freq;
	if (law_p < 1) {
	        law_p = 1;
	}
	
	// Calculate base delay size in samples
	new_d_base = (LIMIT(f_round(delay_base), 0, 25) * sample_rate) / 1000;
	
	// Calculate delay depth in samples
	delay_depth = f_clamp(detune * (float)sample_rate * 0.001f, 0.0f, delay_size - new_d_base - 1.0f);
	
	step = 1.0f/sample_count;
	for (pos = 0; pos < sample_count; pos++) {
	        if (count % law_p == 0) {
	                // Value for amplitude of law peak
	                next_law_peak = (float)rand() / (float)RAND_MAX;
	                next_law_pos = count + law_p;
	        } else if (count % law_p == law_p / 2) {
	                // Value for amplitude of law peak
	                prev_law_peak = (float)rand() / (float)RAND_MAX;
	                prev_law_pos = count + law_p;
	        }
	
	        // Calculate position in delay table
	        d_base = LIN_INTERP(frac, old_d_base, new_d_base);
	        n_ph = (float)(law_p - abs(next_law_pos - count))/(float)law_p;
	        p_ph = n_ph + 0.5f;
	        while (p_ph > 1.0f) {
	                p_ph -= 1.0f;
	        }
	        law = f_sin_sq(3.1415926f*p_ph)*prev_law_peak +
	                f_sin_sq(3.1415926f*n_ph)*next_law_peak;
	
	        dp = (float)(delay_pos - d_base) - (delay_depth * law);
	        // Get the integer part
	        dp_idx = f_round(dp - 0.5f);
	        // Get the fractional part
	        dp_frac = dp - dp_idx;
	
	        // Accumulate into output buffer
	        out = cube_interp(dp_frac, delay_tbl[(dp_idx-1) & (delay_size-1)], delay_tbl[dp_idx & (delay_size-1)], delay_tbl[(dp_idx+1) & (delay_size-1)], delay_tbl[(dp_idx+2) & (delay_size-1)]);
	
	        // Store new delayed value
	        delay_tbl[delay_pos] = flush_to_zero(input[pos] + (fb * out));
	        // Sometimes the delay can pick up NaN values, I'm not sure why
	        // and this is easier than fixing it
	        if (isnan(delay_tbl[delay_pos])) {
	                delay_tbl[delay_pos] = 0.0f;
	        }
	
	        out = f_clamp(delay_tbl[delay_pos] * 0.707f, -1.0, 1.0);
	        buffer_write(output[pos], out);
	
	        frac += step;
	        delay_pos = (delay_pos + 1) & (delay_size-1);
	
	        count++;
	}
	
	plugin_data->count = count;
	plugin_data->prev_law_peak = prev_law_peak;
	plugin_data->next_law_peak = next_law_peak;
	plugin_data->prev_law_pos = prev_law_pos;
	plugin_data->next_law_pos = next_law_pos;
	plugin_data->delay_pos = delay_pos;
	plugin_data->old_d_base = new_d_base;
}
示例#4
0
static void runAddingBodeShifter(LADSPA_Handle instance, unsigned long sample_count) {
	BodeShifter *plugin_data = (BodeShifter *)instance;
	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;

	/* Frequency shift (float value) */
	const LADSPA_Data shift = *(plugin_data->shift);

	/* Input (array of floats of length sample_count) */
	const LADSPA_Data * const input = plugin_data->input;

	/* Down out (array of floats of length sample_count) */
	LADSPA_Data * const dout = plugin_data->dout;

	/* Up out (array of floats of length sample_count) */
	LADSPA_Data * const uout = plugin_data->uout;
	LADSPA_Data * delay = plugin_data->delay;
	unsigned int dptr = plugin_data->dptr;
	float fs = plugin_data->fs;
	float last_shift = plugin_data->last_shift;
	float phi = plugin_data->phi;
	float * sint = plugin_data->sint;

#line 80 "bode_shifter_1431.xml"
	unsigned long pos;
	unsigned int i;
	float hilb, rm1, rm2;
	float shift_i = last_shift;
	int int_p;
	float frac_p;
	const float shift_c = f_clamp(shift, 0.0f, 10000.0f);
	const float shift_inc = (shift_c - last_shift) / (float)sample_count;
	const float freq_fix = (float)SIN_T_SIZE / fs;

	for (pos = 0; pos < sample_count; pos++) {
	  delay[dptr] = input[pos];

	  /* Perform the Hilbert FIR convolution
	   * (probably FFT would be faster) */
	  hilb = 0.0f;
	  for (i = 0; i < NZEROS/2; i++) {
	      hilb += (xcoeffs[i] * delay[(dptr - i*2) & (D_SIZE - 1)]);
	  }

	  /* Calcuate the table positions for the sine modulator */
	  int_p = f_round(floor(phi));

	  /* Calculate ringmod1, the transformed input modulated with a shift Hz
	   * sinewave. This creates a +180 degree sideband at source-shift Hz and
	   * a 0 degree sindeband at source+shift Hz */
	  frac_p = phi - int_p;

	  /* the Hilbert has a gain of pi/2, which we have to correct for, thanks
	   * Fons! */
	  rm1 = hilb * 0.63661978f * cube_interp(frac_p, sint[int_p],
	                  sint[int_p+1], sint[int_p+2], sint[int_p+3]);

	  /* Calcuate the table positions for the cosine modulator */
	  int_p = (int_p + SIN_T_SIZE / 4) & (SIN_T_SIZE - 1);

	  /* Calculate ringmod2, the delayed input modulated with a shift Hz
	   * cosinewave. This creates a 0 degree sideband at source+shift Hz
	   * and a -180 degree sindeband at source-shift Hz */
	  rm2 = delay[(dptr - 99) & (D_SIZE - 1)] * cube_interp(frac_p,
	        sint[int_p], sint[int_p+1], sint[int_p+2], sint[int_p+3]);

	  /* Output the sum and differences of the ringmods. The +/-180 degree
	   * sidebands cancel (more of less) and just leave the shifted
	   * components */
	  buffer_write(dout[pos], (rm2 - rm1) * 0.5f);
	  buffer_write(uout[pos], (rm2 + rm1) * 0.5f);

	  dptr = (dptr + 1) & (D_SIZE - 1);
	  phi += shift_i * freq_fix;
	  while (phi > SIN_T_SIZE) {
	          phi -= SIN_T_SIZE;
	  }
	  shift_i += shift_inc;
	}

	plugin_data->dptr = dptr;
	plugin_data->phi = phi;
	plugin_data->last_shift = shift_c;

	*(plugin_data->latency) = 99;
}
示例#5
0
static void runAddingTapeDelay(LADSPA_Handle instance, unsigned long sample_count) {
	TapeDelay *plugin_data = (TapeDelay *)instance;
	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;

	/* Tape speed (inches/sec, 1=normal) (float value) */
	const LADSPA_Data speed = *(plugin_data->speed);

	/* Dry level (dB) (float value) */
	const LADSPA_Data da_db = *(plugin_data->da_db);

	/* Tap 1 distance (inches) (float value) */
	const LADSPA_Data t1d = *(plugin_data->t1d);

	/* Tap 1 level (dB) (float value) */
	const LADSPA_Data t1a_db = *(plugin_data->t1a_db);

	/* Tap 2 distance (inches) (float value) */
	const LADSPA_Data t2d = *(plugin_data->t2d);

	/* Tap 2 level (dB) (float value) */
	const LADSPA_Data t2a_db = *(plugin_data->t2a_db);

	/* Tap 3 distance (inches) (float value) */
	const LADSPA_Data t3d = *(plugin_data->t3d);

	/* Tap 3 level (dB) (float value) */
	const LADSPA_Data t3a_db = *(plugin_data->t3a_db);

	/* Tap 4 distance (inches) (float value) */
	const LADSPA_Data t4d = *(plugin_data->t4d);

	/* Tap 4 level (dB) (float value) */
	const LADSPA_Data t4a_db = *(plugin_data->t4a_db);

	/* 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;
	LADSPA_Data * buffer = plugin_data->buffer;
	unsigned int buffer_mask = plugin_data->buffer_mask;
	unsigned int buffer_size = plugin_data->buffer_size;
	LADSPA_Data last2_in = plugin_data->last2_in;
	LADSPA_Data last3_in = plugin_data->last3_in;
	LADSPA_Data last_in = plugin_data->last_in;
	unsigned int last_phase = plugin_data->last_phase;
	float phase = plugin_data->phase;
	int sample_rate = plugin_data->sample_rate;
	LADSPA_Data z0 = plugin_data->z0;
	LADSPA_Data z1 = plugin_data->z1;
	LADSPA_Data z2 = plugin_data->z2;

	unsigned int pos;
	float increment = f_clamp(speed, 0.0f, 40.0f);
	float lin_int, lin_inc;
	unsigned int track;
	unsigned int fph;
	LADSPA_Data out;

	const float da = DB_CO(da_db);
	const float t1a = DB_CO(t1a_db);
	const float t2a = DB_CO(t2a_db);
	const float t3a = DB_CO(t3a_db);
	const float t4a = DB_CO(t4a_db);
	const unsigned int t1d_s = f_round(t1d * sample_rate);
	const unsigned int t2d_s = f_round(t2d * sample_rate);
	const unsigned int t3d_s = f_round(t3d * sample_rate);
	const unsigned int t4d_s = f_round(t4d * sample_rate);

	for (pos = 0; pos < sample_count; pos++) {
	        fph = f_trunc(phase);
	        last_phase = fph;
	        lin_int = phase - (float)fph;

	        out = buffer[(unsigned int)(fph - t1d_s) & buffer_mask] * t1a;
	        out += buffer[(unsigned int)(fph - t2d_s) & buffer_mask] * t2a;
	        out += buffer[(unsigned int)(fph - t3d_s) & buffer_mask] * t3a;
	        out += buffer[(unsigned int)(fph - t4d_s) & buffer_mask] * t4a;

	        phase += increment;
	        lin_inc = 1.0f / (floor(phase) - last_phase + 1);
	        lin_inc = lin_inc > 1.0f ? 1.0f : lin_inc;
	        lin_int = 0.0f;
	        for (track = last_phase; track < phase; track++) {
	                lin_int += lin_inc;
	                buffer[track & buffer_mask] =
	                 cube_interp(lin_int, last3_in, last2_in, last_in, input[pos]);
	        }
	        last3_in = last2_in;
	        last2_in = last_in;
	        last_in = input[pos];
	        out += input[pos] * da;
	        buffer_write(output[pos], out);
	        if (phase >= buffer_size) {
	                phase -= buffer_size;
	        }
	}

	// Store current phase in instance
	plugin_data->phase = phase;
	plugin_data->last_phase = last_phase;
	plugin_data->last_in = last_in;
	plugin_data->last2_in = last2_in;
	plugin_data->last3_in = last3_in;
	plugin_data->z0 = z0;
	plugin_data->z1 = z1;
	plugin_data->z2 = z2;
}
示例#6
0
static void runAddingDelayorama(LADSPA_Handle instance, unsigned long sample_count) {
	Delayorama *plugin_data = (Delayorama *)instance;
	LADSPA_Data run_adding_gain = plugin_data->run_adding_gain;

	/* Random seed (float value) */
	const LADSPA_Data seed = *(plugin_data->seed);

	/* Input gain (dB) (float value) */
	const LADSPA_Data gain = *(plugin_data->gain);

	/* Feedback (%) (float value) */
	const LADSPA_Data feedback_pc = *(plugin_data->feedback_pc);

	/* Number of taps (float value) */
	const LADSPA_Data tap_count = *(plugin_data->tap_count);

	/* First delay (s) (float value) */
	const LADSPA_Data first_delay = *(plugin_data->first_delay);

	/* Delay range (s) (float value) */
	const LADSPA_Data delay_range = *(plugin_data->delay_range);

	/* Delay change (float value) */
	const LADSPA_Data delay_scale = *(plugin_data->delay_scale);

	/* Delay random (%) (float value) */
	const LADSPA_Data delay_rand_pc = *(plugin_data->delay_rand_pc);

	/* Amplitude change (float value) */
	const LADSPA_Data gain_scale = *(plugin_data->gain_scale);

	/* Amplitude random (%) (float value) */
	const LADSPA_Data gain_rand_pc = *(plugin_data->gain_rand_pc);

	/* Dry/wet mix (float value) */
	const LADSPA_Data wet = *(plugin_data->wet);

	/* 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;
	unsigned int active_set = plugin_data->active_set;
	LADSPA_Data * buffer = plugin_data->buffer;
	unsigned long buffer_pos = plugin_data->buffer_pos;
	unsigned int buffer_size = plugin_data->buffer_size;
	float last_a_rand = plugin_data->last_a_rand;
	float last_ampsc = plugin_data->last_ampsc;
	float last_d_rand = plugin_data->last_d_rand;
	float last_delaysc = plugin_data->last_delaysc;
	unsigned int last_ntaps = plugin_data->last_ntaps;
	LADSPA_Data last_out = plugin_data->last_out;
	float last_range = plugin_data->last_range;
	float last_seed = plugin_data->last_seed;
	float last_start = plugin_data->last_start;
	unsigned int next_set = plugin_data->next_set;
	unsigned int sample_rate = plugin_data->sample_rate;
	tap ** taps = plugin_data->taps;

#line 73 "delayorama_1402.xml"
	unsigned long pos;
	float coef = DB_CO(gain);
	unsigned int i;
	unsigned int recalc = 0;
	unsigned int ntaps = LIMIT(f_round(tap_count), 2, N_TAPS);
	float range = f_clamp(delay_range * sample_rate, 0.0f,
	                          (float)(buffer_size-1));
	LADSPA_Data out;
	float xfade = 0.0f;

	const float feedback = feedback_pc * 0.01f;
	const float gain_rand = gain_rand_pc * 0.01f;
	const float delay_rand = delay_rand_pc * 0.01f;


	if (ntaps != last_ntaps) {
	  recalc = 1;
	  plugin_data->last_ntaps = ntaps;
	}
	if (first_delay != last_start) {
	  recalc = 1;
	  plugin_data->last_start = first_delay;
	}
	if (range != last_range) {
	  recalc = 1;
	  plugin_data->last_range = range;
	}
	if (delay_scale != last_delaysc) {
	  recalc = 1;
	  plugin_data->last_delaysc = delay_scale;
	}
	if (gain_scale != last_ampsc) {
	  recalc = 1;
	  plugin_data->last_ampsc = gain_scale;
	}
	if (seed != last_seed) {
	  recalc = 1;
	  plugin_data->last_seed = seed;
	}
	if (gain_rand != last_a_rand) {
	  recalc = 1;
	  plugin_data->last_a_rand = gain_rand;
	}
	if (delay_rand != last_d_rand) {
	  recalc = 1;
	  plugin_data->last_d_rand = delay_rand;
	}

	if (recalc) {
	  float delay_base = first_delay * sample_rate;
	  float delay_fix;
	  float gain, delay, delay_sum;
	  float d_rand, g_rand;

	  srand(f_round(seed));
	  if (delay_base + range > buffer_size-1) {
	    delay_base = buffer_size - 1 - range;
	  }

	  if (gain_scale <= 1.0f) {
	    gain = 1.0f;
	  } else {
	    gain = 1.0f / pow(gain_scale, ntaps-1);
	  }

	  if (delay_scale == 1.0f) {
	          delay_fix = range / (ntaps - 1);
	  } else {
	          delay_fix = range * (delay_scale - 1.0f) / (pow(delay_scale, ntaps - 1) - 1.0f);
	  }
	  delay = 1.0f;
	  delay_sum = 0.0f;

	  for (i=0; i<ntaps; i++) {
	    g_rand = (1.0f-gain_rand) + (float)rand() / (float)RAND_MAX * 2.0f * gain_rand;
	    d_rand = (1.0f-delay_rand) + (float)rand() / (float)RAND_MAX * 2.0f * delay_rand;
	    taps[next_set][i].delay = LIMIT((unsigned int)(delay_base + delay_sum * delay_fix * d_rand), 0, buffer_size-1);
	    taps[next_set][i].gain = gain * g_rand;

	    delay_sum += delay;
	    delay *= delay_scale;
	    gain *= gain_scale;
	  }
	  for (; i<N_TAPS; i++) {
	    taps[next_set][i].delay = 0.0f;
	    taps[next_set][i].gain = 0.0f;
	  }
	}

	out = last_out;
	for (pos = 0; pos < sample_count; pos++) {
	  buffer[buffer_pos] = input[pos] * coef + (out * feedback);

	  out = 0.0f;
	  for (i=0; i<ntaps; i++) {
	    int p = buffer_pos - taps[active_set][i].delay;
	    if (p<0) p += buffer_size;
	    out += buffer[p] * taps[active_set][i].gain;
	  }

	  if (recalc) {
	    xfade += 1.0f / (float)sample_count;
	    out *= (1-xfade);
	    for (i=0; i<ntaps; i++) {
	      int p = buffer_pos - taps[next_set][i].delay;
	      if (p<0) p += buffer_size;
	      out += buffer[p] * taps[next_set][i].gain * xfade;
	    }
	  }

	  buffer_write(output[pos], LIN_INTERP(wet, input[pos], out));

	  if (++buffer_pos >= buffer_size) {
	    buffer_pos = 0;
	  }
	}

	if (recalc) {
	  plugin_data->active_set = next_set;
	  plugin_data->next_set = active_set;
	}

	plugin_data->buffer_pos = buffer_pos;
	plugin_data->last_out = out;
}