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

Building Digital Guitar Effects - Using the Hothouse, Daisy Seed, STM32. Part 2 Impulse Response IR

CalSonics

0:00 / 0:00

Building Digital Guitar Effects - Using the Hothouse, Daisy Seed, STM32. Part 2 Impulse Response IR

2 848 просмотров · 1 мес. назад
CalSonics
4,37 тыс. подписчиков
2 848 просмотров · 1 мес. назад
Do you want to build your own IR pedal? In this tutorial series on building digital guitar effects, we explores how to design a custom cabinet simulator (Cab Sim) using an STM32-powered Electro-Smith Daisy Seed inside the Hothouse pedal platform. So we have a reference we extract a 1,024-tap impulse response from a Sonicake pedal, upsample and scale the audio data in Python to 48 kHz, and implementing a direct time-domain FIR convolution filter in the Arduino framework. The project demonstrates how an IR captures both speaker frequency curves and physical room reflections. Ultimately, the custom implementation significantly out performs commercial hardware latency—dropping throughput delay from approximately 9 ms down to roughly 1.2 ms, similar to the Friedman IR-X — we validate the design with real-time oscilloscope benchmarks and guitar tone tests. 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:16 What is IR (Impulse Response) 00:41 What is an impulse? 02:28 Sonicake frequency response analysis 04:00 Convert, resample, rescale and analyze the Sonicake IR 07:02 Room response, what does 22ms means? 09:13 Understanding convolution 12:50 Code review 13:35 Measuring and analyzing latency 17:21 Tone test 19:36 Conclusion Corrections 07:35 Distance = 343 x 0.022​ 09:34 Sample Time = 1 / 48kHz or a 20us slice of time. 11:54 Multiply Accumulate per second 49,152,000 MACs/sec (49.152 MMACs/sec) Code Examples ------------------------- Scale and Resample Python code 1. Read native audio file native_sr, data = wavfile.read(input_wav) 2. Scale and Convert integer PCM formats to float64 (-1.0 to 1.0) max_val = np.iinfo(data.dtype).max data = data.astype(np.float64) / max_val 3. Resample to target rate (e.g., 44100 to 48000) target_sr: int = 48000 Simplify the ratio: 48000 / 44100 reduces to 160 / 147 reduce itterations gcd = math.gcd(native_sr, target_sr) # Greatest common factor up = target_sr // gcd # 160 down = native_sr // gcd # 147 Resample along time axis (axis 0) data = resample_poly(data, up, down, axis=0) Convolution Code (Replace 'LT' with 'Less Than' symbol) void audioCallback(float **in, float **out, size_t size) { for (size_t i = 0; i LT size; i++) { // Insert new sample into circular buffer history[write_idx] = in[0][i]; // Direct convolution: sum of products float acc = 0.0f; size_t read_idx = write_idx; for (size_t k = 0; k LT NUM_TAPS; k++) { acc += history[read_idx] * fir_coeffs[k]; // Step backward in time through circular history if (read_idx == 0) { read_idx = NUM_TAPS - 1; } else { read_idx--; } } // Advance circular write index write_idx = (write_idx + 1) % NUM_TAPS; // Output results to both channels out[0][i] = acc; out[1][i] = acc; } } void setup() { hw = DAISY.init(DAISY_SEED, AUDIO_SR_48K); DAISY.SetAudioBlockSize(BLOCK_SIZE); // Initialize circular history buffer for (int i = 0; i LT NUM_TAPS; i++) { history[i] = 0.0f; } DAISY.begin(audioCallback); } void loop() { // Background tasks can be run here }