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
}