Перейти к содержимому

Building Digital Guitar Effects - Using the Hothouse, Daisy Seed, STM32. Part 4 Delay and Reverb

CalSonics

0:00 / 0:00

Building Digital Guitar Effects - Using the Hothouse, Daisy Seed, STM32. Part 4 Delay and Reverb

447 просмотров · 1 мес. назад
CalSonics
4,38 тыс. подписчиков
447 просмотров · 1 мес. назад
In this tutorial I provide step-by-step instruction using the digital signal processing (DSP) principles needed to build delay and reverb pedals from scratch using the Daisy Seed microcontroller. The video starts by demonstrating how sample buffers and read/write pointers generate simple audio echoes, explores feedback behavior and comb filtering, and progresses to configuring series and parallel delay lines, used by David Gilmore and the Edge. I conclude by using an all-pass filter for phase dispersion, culminating in a functioning, 2112 style cave-like rudimentary reverb network How to Add Daisy Support to Arduino IDE    • How to Add Daisy Support to Arduino IDE   Daisy Seed Setup and Install - Arduino, Daisy & STM32    • Daisy Seed Setup and Install - Arduino, Da...   Hothouse Schematic (pdf) https://github.com/clevelandmusicco/o... Hothouse GitHub https://github.com/clevelandmusicco/H... 00:00 Introduction 00:11 How to code delay 01:07 Simple delay code review 03:31 Comb filter and All-pass filters 07:11 Stacking multiple delay code blocks in series 09:03 Stacking multiple delay code blocks in parallel 10:22 Turning delay into reverb 11:20 Phase dispersion and All-pass filters 13:10 Conclusion References Paper form Stanford https://ccrma.stanford.edu/software/c... Phils Lab (Best resource for STM32)    • Delay-Based Audio FX Software Implementati...   Sonic State - Algorithmic Reverb    • How It Works: Algorithmic Reverbs With Yoa...   Code examples (Replace GT & LT with greater or less than sign) The complete digital reverb (play with his to create delays and reverbs) #include "DaisyDuino.h" static DaisyHardware hw; #define MAX_DELAY_SAMPLES 48000 static float DSY_SDRAM_BSS buffer[MAX_DELAY_SAMPLES]; static float DSY_SDRAM_BSS buffer1[MAX_DELAY_SAMPLES]; // Second delay static float DSY_SDRAM_BSS buffer2[MAX_DELAY_SAMPLES]; // Third delay // Pointers and delay times size_t write_ptr = 0; size_t write_ptr1 = 0; size_t write_ptr2 = 0; // Change delay times here size_t delay_samples = 1103; // ~22.98 ms (Prime) size_t delay_samples1 = 1399; // ~29.15 ms (Prime) size_t delay_samples2 = 241; // ~5.02 ms (Prime) // this is the APF //Change the feedback (never exceed one, even 0.9 in the video was messy) float feedback = 0.82f; float feedback1 = 0.82f; float feedback2 = 0.4f; float mix = 0.3f; void AudioCallback(float **in, float **out, size_t size) { for (size_t i = 0; i LT size; i++) { float dry_in = in[0][i]; // 1. Calculate read position wrapped to the buffer size size_t read_ptr = (write_ptr + MAX_DELAY_SAMPLES - delay_samples) % MAX_DELAY_SAMPLES; // 2. Read the delayed sample float delayed_sample_val = buffer[read_ptr]; // 3. Write incoming audio + feedback into current buffer position buffer[write_ptr] = dry_in + (delayed_sample_val * feedback); // 4. Advance and wrap the write pointer write_ptr = (write_ptr + 1) % MAX_DELAY_SAMPLES; // And just do it again using the second buffer float dry_in1 = in[0][i]; size_t read_ptr1 = (write_ptr1 + MAX_DELAY_SAMPLES - delay_samples1) % MAX_DELAY_SAMPLES; float delayed_sample_val1 = buffer1[read_ptr1]; buffer1[write_ptr1] = dry_in1 + (delayed_sample_val1 * feedback1); write_ptr1 = (write_ptr1 + 1) % MAX_DELAY_SAMPLES; //Sum delay one and two float early_sum = (delayed_sample_val + delayed_sample_val1) * 0.5f; // set the read pointer size_t read_ptr2 = (write_ptr2 + MAX_DELAY_SAMPLES - delay_samples2) % MAX_DELAY_SAMPLES; float delayed_sample_val2 = buffer2[read_ptr2]; // Allpass // Feedback float ap_node = early_sum + (delayed_sample_val2 * feedback2); buffer2[write_ptr2] = ap_node; write_ptr2 = (write_ptr2 + 1) % MAX_DELAY_SAMPLES; //Feed forward float wet_mix = delayed_sample_val2 - (feedback2 * ap_node); // Master Dry / Wet mix float output_sample = (dry_in * (1.0f - (mix))) + (wet_mix * (mix)); out[0][i] = output_sample; out[1][i] = output_sample; } } void setup() { hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K); // Clear SDRAM buffer to prevent startup noise for (size_t i = 0; i LT MAX_DELAY_SAMPLES; i++) { buffer[i] = 0.0f; buffer1[i] = 0.0f; buffer2[i] = 0.0f; } DAISY.begin(AudioCallback); } void loop() {}