static void runComb_c(LADSPA_Handle instance, unsigned long sample_count) { Comb_c *plugin_data = (Comb_c *)instance; /* Input (array of floats of length sample_count) */ const LADSPA_Data * const in = plugin_data->in; /* Output (array of floats of length sample_count) */ LADSPA_Data * const out = plugin_data->out; /* Max Delay (s) (float value) */ const LADSPA_Data max_delay = *(plugin_data->max_delay); /* Delay Time (s) (float value) */ const LADSPA_Data delay_time = *(plugin_data->delay_time); /* Decay Time (s) (float value) */ const LADSPA_Data decay_time = *(plugin_data->decay_time); LADSPA_Data * buffer = plugin_data->buffer; unsigned int buffer_mask = plugin_data->buffer_mask; LADSPA_Data delay_samples = plugin_data->delay_samples; LADSPA_Data feedback = plugin_data->feedback; LADSPA_Data last_decay_time = plugin_data->last_decay_time; LADSPA_Data last_delay_time = plugin_data->last_delay_time; unsigned int sample_rate = plugin_data->sample_rate; long write_phase = plugin_data->write_phase; #line 79 "comb_1887.xml" int i; i = max_delay; if (write_phase == 0) { plugin_data->last_delay_time = delay_time; plugin_data->last_decay_time = decay_time; plugin_data->delay_samples = delay_samples = CALC_DELAY (delay_time); plugin_data->feedback = feedback = calc_feedback (delay_time, decay_time); } if (delay_time == last_delay_time && decay_time == last_decay_time) { long idelay_samples = (long)delay_samples; LADSPA_Data frac = delay_samples - idelay_samples; for (i=0; i<sample_count; i++) { long read_phase = write_phase - (long)delay_samples; LADSPA_Data read = cube_interp (frac, buffer[(read_phase-1) & buffer_mask], buffer[read_phase & buffer_mask], buffer[(read_phase+1) & buffer_mask], buffer[(read_phase+2) & buffer_mask]); buffer[write_phase++ & buffer_mask] = read * feedback + in[i]; buffer_write(out[i], read); } } else { float next_delay_samples = CALC_DELAY (delay_time); float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count; float next_feedback = calc_feedback (delay_time, decay_time); float feedback_slope = (next_feedback - feedback) / sample_count; for (i=0; i<sample_count; i++) { long read_phase, idelay_samples; LADSPA_Data read, frac; delay_samples += delay_samples_slope; write_phase++; read_phase = write_phase - (long)delay_samples; idelay_samples = (long)delay_samples; frac = delay_samples - idelay_samples; read = cube_interp (frac, buffer[(read_phase-1) & buffer_mask], buffer[read_phase & buffer_mask], buffer[(read_phase+1) & buffer_mask], buffer[(read_phase+2) & buffer_mask]); buffer[write_phase & buffer_mask] = read * feedback + in[i]; buffer_write(out[i], read); feedback += feedback_slope; } plugin_data->last_delay_time = delay_time; plugin_data->last_decay_time = decay_time; plugin_data->feedback = feedback; plugin_data->delay_samples = delay_samples; } plugin_data->write_phase = write_phase; }
void DelayNode::run(ProcessContext& context) { Buffer* const delay_buf = _delay_port->buffer(0).get(); Buffer* const in_buf = _in_port->buffer(0).get(); Buffer* const out_buf = _out_port->buffer(0).get(); DelayNode* plugin_data = this; const float* const in = in_buf->samples(); float* const out = out_buf->samples(); const float delay_time = delay_buf->samples()[0]; const uint32_t buffer_mask = plugin_data->_buffer_mask; const SampleRate sample_rate = context.engine().driver()->sample_rate(); float delay_samples = plugin_data->_delay_samples; int64_t write_phase = plugin_data->_write_phase; const uint32_t sample_count = context.nframes(); if (write_phase == 0) { _last_delay_time = delay_time; _delay_samples = delay_samples = CALC_DELAY(delay_time); } if (delay_time == _last_delay_time) { const int64_t idelay_samples = (int64_t)delay_samples; const float frac = delay_samples - idelay_samples; for (uint32_t i = 0; i < sample_count; i++) { int64_t read_phase = write_phase - (int64_t)delay_samples; const float read = cube_interp(frac, buffer_at(read_phase - 1), buffer_at(read_phase), buffer_at(read_phase + 1), buffer_at(read_phase + 2)); buffer_at(write_phase++) = in[i]; out[i] = read; } } else { const float next_delay_samples = CALC_DELAY(delay_time); const float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count; for (uint32_t i = 0; i < sample_count; i++) { delay_samples += delay_samples_slope; write_phase++; const int64_t read_phase = write_phase - (int64_t)delay_samples; const int64_t idelay_samples = (int64_t)delay_samples; const float frac = delay_samples - idelay_samples; const float read = cube_interp(frac, buffer_at(read_phase - 1), buffer_at(read_phase), buffer_at(read_phase + 1), buffer_at(read_phase + 2)); buffer_at(write_phase) = in[i]; out[i] = read; } _last_delay_time = delay_time; _delay_samples = delay_samples; } _write_phase = write_phase; }
static void runAddingAllpass_l(LADSPA_Handle instance, unsigned long sample_count) { Allpass_l *plugin_data = (Allpass_l *)instance; LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; /* Input (array of floats of length sample_count) */ const LADSPA_Data * const in = plugin_data->in; /* Output (array of floats of length sample_count) */ LADSPA_Data * const out = plugin_data->out; /* Max Delay (s) (float value) */ const LADSPA_Data max_delay = *(plugin_data->max_delay); /* Delay Time (s) (float value) */ const LADSPA_Data delay_time = *(plugin_data->delay_time); /* Decay Time (s) (float value) */ const LADSPA_Data decay_time = *(plugin_data->decay_time); LADSPA_Data * buffer = plugin_data->buffer; unsigned int buffer_mask = plugin_data->buffer_mask; LADSPA_Data delay_samples = plugin_data->delay_samples; LADSPA_Data feedback = plugin_data->feedback; LADSPA_Data last_decay_time = plugin_data->last_decay_time; LADSPA_Data last_delay_time = plugin_data->last_delay_time; unsigned int sample_rate = plugin_data->sample_rate; long write_phase = plugin_data->write_phase; #line 82 "allpass_1895.xml" int i; ignore(max_delay); if (write_phase == 0) { plugin_data->last_delay_time = delay_time; plugin_data->last_decay_time = decay_time; plugin_data->delay_samples = delay_samples = CALC_DELAY (delay_time); plugin_data->feedback = feedback = calc_feedback (delay_time, decay_time); } if (delay_time == last_delay_time && decay_time == last_decay_time) { long idelay_samples = (long)delay_samples; LADSPA_Data frac = delay_samples - idelay_samples; for (i=0; i<sample_count; i++) { long read_phase = write_phase - (long)delay_samples; LADSPA_Data r1 = buffer[read_phase & buffer_mask]; LADSPA_Data r2 = buffer[(read_phase-1) & buffer_mask]; LADSPA_Data read = LIN_INTERP (frac, r1, r2); LADSPA_Data written = read * feedback + in[i]; buffer[write_phase++ & buffer_mask] = written; buffer_write(out[i], read - feedback * written); write_phase++; } } else { float next_delay_samples = CALC_DELAY (delay_time); float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count; float next_feedback = calc_feedback (delay_time, decay_time); float feedback_slope = (next_feedback - feedback) / sample_count; for (i=0; i<sample_count; i++) { long read_phase, idelay_samples; LADSPA_Data read, written, frac; delay_samples += delay_samples_slope; write_phase++; read_phase = write_phase - (long)delay_samples; idelay_samples = (long)delay_samples; frac = delay_samples - idelay_samples; read = LIN_INTERP (frac, buffer[read_phase & buffer_mask], buffer[(read_phase-1) & buffer_mask]); written = read * feedback + in[i]; buffer[write_phase & buffer_mask] = written; buffer_write(out[i], read - feedback * written); feedback += feedback_slope; } plugin_data->last_delay_time = delay_time; plugin_data->last_decay_time = decay_time; plugin_data->feedback = feedback; plugin_data->delay_samples = delay_samples; } plugin_data->write_phase = write_phase; }
static void runAddingComb_n(LADSPA_Handle instance, unsigned long sample_count) { Comb_n *plugin_data = (Comb_n *)instance; LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; /* Input (array of floats of length sample_count) */ const LADSPA_Data * const in = plugin_data->in; /* Output (array of floats of length sample_count) */ LADSPA_Data * const out = plugin_data->out; /* Max Delay (s) (float value) */ const LADSPA_Data max_delay = *(plugin_data->max_delay); /* Delay Time (s) (float value) */ const LADSPA_Data delay_time = *(plugin_data->delay_time); /* Decay Time (s) (float value) */ const LADSPA_Data decay_time = *(plugin_data->decay_time); LADSPA_Data * buffer = plugin_data->buffer; unsigned int buffer_mask = plugin_data->buffer_mask; LADSPA_Data delay_samples = plugin_data->delay_samples; LADSPA_Data feedback = plugin_data->feedback; LADSPA_Data last_decay_time = plugin_data->last_decay_time; LADSPA_Data last_delay_time = plugin_data->last_delay_time; unsigned int sample_rate = plugin_data->sample_rate; long write_phase = plugin_data->write_phase; #line 79 "comb_1887.xml" int i; i = max_delay; /* stop gcc complaining */ if (write_phase == 0) { plugin_data->last_delay_time = delay_time; plugin_data->last_decay_time = decay_time; plugin_data->delay_samples = delay_samples = CALC_DELAY (delay_time); plugin_data->feedback = feedback = calc_feedback (delay_time, decay_time); } if (delay_time == last_delay_time) { long read_phase = write_phase - (long)delay_samples; LADSPA_Data *readptr = buffer + (read_phase & buffer_mask); LADSPA_Data *writeptr = buffer + (write_phase & buffer_mask); LADSPA_Data *lastptr = buffer + buffer_mask + 1; if (decay_time == last_decay_time) { long remain = sample_count; while (remain) { long read_space = lastptr - readptr; long write_space = lastptr - writeptr; long to_process = MIN (MIN (read_space, remain), write_space); if (to_process == 0) return; // buffer not allocated. remain -= to_process; for (i=0; i<to_process; i++) { LADSPA_Data read = *(readptr++); *(writeptr++) = read * feedback + in[i]; buffer_write(out[i], read); } if (readptr == lastptr) readptr = buffer; if (writeptr == lastptr) writeptr = buffer; } } else { float next_feedback = calc_feedback (delay_time, decay_time); float feedback_slope = (next_feedback - feedback) / sample_count; long remain = sample_count; while (remain) { long read_space = lastptr - readptr; long write_space = lastptr - writeptr; long to_process = MIN (MIN (read_space, remain), write_space); if (to_process == 0) return; // buffer not allocated. remain -= to_process; for (i=0; i<to_process; i++) { LADSPA_Data read = *(readptr++); *(writeptr++) = read * feedback + in[i]; buffer_write(out[i], read); feedback += feedback_slope; } if (readptr == lastptr) readptr = buffer; if (writeptr == lastptr) writeptr = buffer; } plugin_data->last_decay_time = decay_time; plugin_data->feedback = feedback; } write_phase += sample_count; } else { float next_delay_samples = CALC_DELAY (delay_time); float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count; float next_feedback = calc_feedback (delay_time, decay_time); float feedback_slope = (next_feedback - feedback) / sample_count; for (i=0; i<sample_count; i++) { long read_phase; LADSPA_Data read; delay_samples += delay_samples_slope; write_phase++; read_phase = write_phase - (long)delay_samples; read = buffer[read_phase & buffer_mask]; buffer[write_phase & buffer_mask] = read * feedback + in[i]; buffer_write(out[i], read); feedback += feedback_slope; } plugin_data->last_delay_time = delay_time; plugin_data->last_decay_time = decay_time; plugin_data->feedback = feedback; plugin_data->delay_samples = delay_samples; } plugin_data->write_phase = write_phase; }
void DelayNode::process(ProcessContext& context) { AudioBuffer* const delay_buf = (AudioBuffer*)_delay_port->buffer(0).get(); AudioBuffer* const in_buf = (AudioBuffer*)_in_port->buffer(0).get(); AudioBuffer* const out_buf = (AudioBuffer*)_out_port->buffer(0).get(); NodeImpl::pre_process(context); DelayNode* plugin_data = this; const float* const in = in_buf->data(); float* const out = out_buf->data(); const float delay_time = delay_buf->data()[0]; const uint32_t buffer_mask = plugin_data->_buffer_mask; const unsigned int sample_rate = plugin_data->_srate; float delay_samples = plugin_data->_delay_samples; long write_phase = plugin_data->_write_phase; const uint32_t sample_count = context.nframes(); if (write_phase == 0) { _last_delay_time = delay_time; _delay_samples = delay_samples = CALC_DELAY(delay_time); } if (delay_time == _last_delay_time) { const long idelay_samples = (long)delay_samples; const float frac = delay_samples - idelay_samples; for (uint32_t i = 0; i < sample_count; i++) { long read_phase = write_phase - (long)delay_samples; const float read = cube_interp(frac, buffer_at(read_phase - 1), buffer_at(read_phase), buffer_at(read_phase + 1), buffer_at(read_phase + 2)); buffer_at(write_phase++) = in[i]; out[i] = read; } } else { const float next_delay_samples = CALC_DELAY(delay_time); const float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count; for (uint32_t i = 0; i < sample_count; i++) { delay_samples += delay_samples_slope; write_phase++; const long read_phase = write_phase - (long)delay_samples; const long idelay_samples = (long)delay_samples; const float frac = delay_samples - idelay_samples; const float read = cube_interp(frac, buffer_at(read_phase - 1), buffer_at(read_phase), buffer_at(read_phase + 1), buffer_at(read_phase + 2)); buffer_at(write_phase) = in[i]; out[i] = read; } _last_delay_time = delay_time; _delay_samples = delay_samples; } _write_phase = write_phase; NodeImpl::post_process(context); }
static void runAddingRevdelay(LADSPA_Handle instance, unsigned long sample_count) { Revdelay *plugin_data = (Revdelay *)instance; LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; /* Input (array of floats of length sample_count) */ const LADSPA_Data * const in = plugin_data->in; /* Output (array of floats of length sample_count) */ LADSPA_Data * const out = plugin_data->out; /* Delay Time (s) (float value) */ const LADSPA_Data delay_time = *(plugin_data->delay_time); /* Dry Level (dB) (float value) */ const LADSPA_Data dry_level = *(plugin_data->dry_level); /* Wet Level (dB) (float value) */ const LADSPA_Data wet_level = *(plugin_data->wet_level); /* Feedback (float value) */ const LADSPA_Data feedback = *(plugin_data->feedback); /* Crossfade samples (float value) */ const LADSPA_Data xfade_samp = *(plugin_data->xfade_samp); LADSPA_Data * buffer = plugin_data->buffer; unsigned int buffer_size = plugin_data->buffer_size; LADSPA_Data delay_samples = plugin_data->delay_samples; LADSPA_Data last_delay_time = plugin_data->last_delay_time; unsigned int sample_rate = plugin_data->sample_rate; long write_phase = plugin_data->write_phase; #line 55 "revdelay_1605.xml" int i; unsigned long delay2; float dry = DB_CO(dry_level); float wet = DB_CO(wet_level); float fadescale; unsigned long xfadesamp = xfade_samp; if (write_phase == 0) { plugin_data->last_delay_time = delay_time; plugin_data->delay_samples = delay_samples = CALC_DELAY (delay_time); } if (delay_time == last_delay_time) { long idelay_samples = (long)delay_samples; delay2 = idelay_samples * 2; if (xfadesamp > idelay_samples) { /* force it to half */ xfadesamp = idelay_samples / 2; } for (i=0; i<sample_count; i++) { long read_phase = delay2 - write_phase; LADSPA_Data read; LADSPA_Data insamp; insamp = in[i]; read = (wet * buffer[read_phase]) + (dry * insamp); if ( (write_phase % idelay_samples) < xfadesamp) { fadescale = (write_phase % idelay_samples) / (1.0 * xfadesamp); } else if ((write_phase % idelay_samples) > (idelay_samples - xfadesamp)) { fadescale = (idelay_samples - (write_phase % idelay_samples)) / (1.0 * xfadesamp); } else { fadescale = 1.0; } buffer[write_phase] = fadescale * (insamp + (feedback * read)); buffer[write_phase] = flush_to_zero(buffer[write_phase]); buffer_write(out[i], read); write_phase = (write_phase + 1) % delay2; } } else { float next_delay_samples = CALC_DELAY (delay_time); float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count; for (i=0; i<sample_count; i++) { long read_phase, idelay_samples; LADSPA_Data read; LADSPA_Data insamp; insamp = in[i]; delay_samples += delay_samples_slope; delay2 = (long) (delay_samples * 2); write_phase = (write_phase + 1) % delay2; read_phase = delay2 - write_phase; idelay_samples = (long)delay_samples; read = wet * buffer[read_phase] + (dry * insamp); if ((write_phase % idelay_samples) < xfade_samp) { fadescale = (write_phase % idelay_samples) / (1.0 * xfade_samp); } else if ((write_phase % idelay_samples) > (idelay_samples - xfade_samp)) { fadescale = (idelay_samples - (write_phase % idelay_samples)) / (1.0 * xfade_samp); } else { fadescale = 1.0; } buffer[write_phase] = fadescale * (insamp + (feedback * read)); buffer[write_phase] = flush_to_zero(buffer[write_phase]); buffer_write(out[i], read); } plugin_data->last_delay_time = delay_time; plugin_data->delay_samples = delay_samples; } plugin_data->write_phase = write_phase; }
#include <savr/optimized.h> /** * After examining the code, and some testing, adjusting by the given number of cycles accounts * for call and setup time for delays and GPIO read/writes */ #define DELAY_CALL_ADJ 4 #define MAYBE_ADJ(val, by) ((val) < (by) ? 0 : (val) - (by)) #define DELAY_FOR(x) ((0.000001*F_CPU)/4 * (x)) #define CALC_DELAY(x) MAYBE_ADJ(DELAY_FOR(x), DELAY_CALL_ADJ) #define DELAY(x) _delay_loop_2(DELAY_##x) static uint16_t DELAY_A = CALC_DELAY(6); static uint16_t DELAY_B = CALC_DELAY(64); static uint16_t DELAY_C = CALC_DELAY(60); static uint16_t DELAY_D = CALC_DELAY(10); static uint16_t DELAY_E = CALC_DELAY(9); static uint16_t DELAY_F = CALC_DELAY(55); static uint16_t DELAY_G = CALC_DELAY(0); static uint16_t DELAY_H = CALC_DELAY(480); static uint16_t DELAY_I = CALC_DELAY(70); static uint16_t DELAY_J = CALC_DELAY(410); /** * @par Implementation notes: * GCC creates two copies of the constructor and destructors. This is the 'real' * constructor code in a separate function to reduce code size.
static void runAddingDelay_c(LADSPA_Handle instance, unsigned long sample_count) { Delay_c *plugin_data = (Delay_c *)instance; LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; /* Input (array of floats of length sample_count) */ const LADSPA_Data * const in = plugin_data->in; /* Output (array of floats of length sample_count) */ LADSPA_Data * const out = plugin_data->out; /* Delay Time (s) (float value) */ const LADSPA_Data delay_time = *(plugin_data->delay_time); LADSPA_Data * buffer = plugin_data->buffer; unsigned int buffer_mask = plugin_data->buffer_mask; LADSPA_Data delay_samples = plugin_data->delay_samples; LADSPA_Data last_delay_time = plugin_data->last_delay_time; unsigned int sample_rate = plugin_data->sample_rate; long write_phase = plugin_data->write_phase; unsigned int i; if (write_phase == 0) { plugin_data->last_delay_time = delay_time; plugin_data->delay_samples = delay_samples = CALC_DELAY (delay_time); } if (delay_time == last_delay_time) { long idelay_samples = (long)delay_samples; LADSPA_Data frac = delay_samples - idelay_samples; for (i=0; i<sample_count; i++) { long read_phase = write_phase - (long)delay_samples; LADSPA_Data read = cube_interp (frac, buffer[(read_phase-1) & buffer_mask], buffer[read_phase & buffer_mask], buffer[(read_phase+1) & buffer_mask], buffer[(read_phase+2) & buffer_mask]); buffer[write_phase++ & buffer_mask] = in[i]; buffer_write(out[i], read); } } else { float next_delay_samples = CALC_DELAY (delay_time); float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count; for (i=0; i<sample_count; i++) { long read_phase, idelay_samples; LADSPA_Data frac, read; delay_samples += delay_samples_slope; write_phase++; read_phase = write_phase - (long)delay_samples; idelay_samples = (long)delay_samples; frac = delay_samples - idelay_samples; read = cube_interp (frac, buffer[(read_phase-1) & buffer_mask], buffer[read_phase & buffer_mask], buffer[(read_phase+1) & buffer_mask], buffer[(read_phase+2) & buffer_mask]); buffer[write_phase & buffer_mask] = in[i]; buffer_write(out[i], read); } plugin_data->last_delay_time = delay_time; plugin_data->delay_samples = delay_samples; } plugin_data->write_phase = write_phase; }
static void runAddingDelay_n(LADSPA_Handle instance, unsigned long sample_count) { Delay_n *plugin_data = (Delay_n *)instance; LADSPA_Data run_adding_gain = plugin_data->run_adding_gain; /* Input (array of floats of length sample_count) */ const LADSPA_Data * const in = plugin_data->in; /* Output (array of floats of length sample_count) */ LADSPA_Data * const out = plugin_data->out; /* Delay Time (s) (float value) */ const LADSPA_Data delay_time = *(plugin_data->delay_time); LADSPA_Data * buffer = plugin_data->buffer; unsigned int buffer_mask = plugin_data->buffer_mask; LADSPA_Data delay_samples = plugin_data->delay_samples; LADSPA_Data last_delay_time = plugin_data->last_delay_time; unsigned int sample_rate = plugin_data->sample_rate; long write_phase = plugin_data->write_phase; unsigned int i; if (write_phase == 0) { plugin_data->last_delay_time = delay_time; plugin_data->delay_samples = delay_samples = CALC_DELAY (delay_time); } if (delay_time == last_delay_time) { long read_phase = write_phase - (long)delay_samples; LADSPA_Data *readptr = buffer + (read_phase & buffer_mask); LADSPA_Data *writeptr = buffer + (write_phase & buffer_mask); LADSPA_Data *lastptr = buffer + buffer_mask + 1; long remain = sample_count; while (remain) { long read_space = lastptr - readptr; long write_space = lastptr - writeptr; long to_process = MIN (MIN (read_space, remain), write_space); if (to_process == 0) return; // buffer not allocated. remain -= to_process; for (i=0; i<to_process; i++) { float read = *(readptr++); *(writeptr++) = in[i]; buffer_write(out[i], read); } if (readptr == lastptr) readptr = buffer; if (writeptr == lastptr) writeptr = buffer; } write_phase += sample_count; } else { float next_delay_samples = CALC_DELAY (delay_time); float delay_samples_slope = (next_delay_samples - delay_samples) / sample_count; for (i=0; i<sample_count; i++) { long read_phase; LADSPA_Data read; delay_samples += delay_samples_slope; write_phase++; read_phase = write_phase - (long)delay_samples; read = buffer[read_phase & buffer_mask]; buffer[write_phase & buffer_mask] = in[i]; buffer_write(out[i], read); } plugin_data->last_delay_time = delay_time; plugin_data->delay_samples = delay_samples; } plugin_data->write_phase = write_phase; }