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; }
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++; }
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; }
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; }
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; }
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; }