Example implementation of a delay effect with feedback and filtering using WorkBench.This file provides an example of implementing a delay effect with feedback and filtering in an audio processing application. It uses PortAudio for audio input and output, and includes MIDI control for adjusting delay parameters.
The delay effect is implemented using a circular buffer, and the pitch can be adjusted by changing the playback speed. Feedback and filtering are also applied to the delayed signal.
#include <stdlib.h>
#define DELAY_CC 48
#define FEEDBACK_CC 49
#define FILTER_CC 50
#define BUFFER_SIZE_SEC 2
#define BUFFER_SIZE_SAMPLES (cfg->sample_rate * BUFFER_SIZE_SEC)
#define FILTER_ORDER 4
#define MIDI2DOUBLE(x) (double)(x) / 128.0
typedef struct {
size_t write;
size_t length;
double delay;
double delay_target;
double feedback;
double filter_coefficient;
void audio_cb(const void *input_buffer, void *output_buffer,
unsigned long block_size, void *user_data);
int midi_cb(const void *in, void *out, unsigned long length, void *user_data);
int main(int argc, char **argv) {
cfg =
config_init(argc, argv, audio_cb, midi_cb, &del);
delay_init(&del);
while (true) {
Pa_Sleep(1000);
}
free_delay_buffer(&del);
return 0;
}
void audio_cb(const void *input_buffer, void *output_buffer,
unsigned long block_size, void *user_data) {
if (del == NULL) {
return;
}
for (unsigned long i = 0; i < block_size; ++i) {
int channels = cfg->out_channel_count;
while (channels--) {
*out++ = out_sample;
}
}
}
int midi_cb(const void *in, void *out, unsigned long length, void *user_data) {
if (del == NULL) {
return 0;
}
const PmEvent *in_buffer = (const PmEvent *)in;
for (unsigned long i = 0; i < length; ++i) {
PmEvent event = in_buffer[i];
PmMessage message = event.message;
uint8_t data1 = Pm_MessageData1(message);
uint8_t data2 = Pm_MessageData2(message) + 1;
switch (data1) {
case DELAY_CC:
break;
case FEEDBACK_CC:
break;
case FILTER_CC:
break;
}
}
}
return 0;
}
del->
length = BUFFER_SIZE_SAMPLES;
}
}
}
#define lerp(a, b, t) (a + t * (b - a))
cfg->block_size;
if (read_idx < 0) {
}
size_t idx0 = (size_t)read_idx;
size_t idx1 = (idx0 + 1) % del->
length;
double frac = read_idx - idx0;
AudioSample_t interpolated_sample = lerp(sample0, sample1, frac);
for (size_t i = 0; i < FILTER_ORDER; ++i) {
}
return filtered_sample;
}
SAMPLE AudioSample_t
Defines AudioSample_t as the type for audio samples.
Definition: workbench.h:41
Config * config_init(int argc, char **argv, AudioCallback audio_cb, MidiCallback midi_cb, void *user_data)
Initializes the configuration with the specified audio and MIDI callbacks.
Definition: workbench_config.c:41
Defines the structure for configuration settings.
Definition: workbench.h:287
double filter_coefficient
Definition: delay.c:39
double delay
Definition: delay.c:36
AudioSample_t * filter_buffer
Definition: delay.c:33
double delay_target
Definition: delay.c:37
size_t length
Definition: delay.c:35
size_t write
Definition: delay.c:34
double feedback
Definition: delay.c:38
AudioSample_t * buffer
Definition: delay.c:32
#define MIDI_CTRL
MIDI Control Change message.
Definition: workbench_midi.h:24
#define MIDI_CODE_MASK
Mask to extract the MIDI message type.
Definition: workbench_midi.h:12