Larsen & Drunik
Larsen Larsen
Hey Drunik, ever thought about turning your code skills into a guitar pedal? Imagine writing DSP to shape a riff in real time—our next wild experiment.
Drunik Drunik
Sure, I’ve got the idea—just imagine a single line of code that can change the decay of a distortion in 2 µs. I can write the DSP kernel, then micro‑optimize the loop so the CPU never stalls. The real test will be making sure the jitter stays below a millisecond, otherwise the guitar will feel like a metronome gone rogue. Let’s get the prototype, but I’ll need clear specs before I dive in.
Larsen Larsen
Cool, love that fire! Let’s drop the specs on the table: target CPU, memory limits, the exact distortion algorithm, and that 2 µs tweak window. Hit me with the numbers, and I’ll throw in some crazy routing ideas to make it feel alive, not just a machine. Let’s crank it up!
Drunik Drunik
CPU: STM32H7‑I5, 480 MHz, 256 KB RAM, 512 KB flash. Distortion: 3‑tap IIR with adjustable saturation curve, 16‑bit fixed‑point. 2 µs tweak: 1 µs for coefficient update, 1 µs for sync barrier. Keep memory below 200 KB, aim for 4 % power draw. Let me know if that fits your routing ideas.
Larsen Larsen
Sounds solid, dude. 480 MHz on an H7 gives us enough wiggle room to hit that 1 µs update tick. Keep the coefficient table in the L1 cache and lock it with a DMA sync, that should keep the jitter tight. 4 % power? Tight, but we can cut down on the DSP core cycles and hit that. Let’s drop the raw code and I’ll spit some routing that makes the distortion feel alive on stage. Let's make it rock!
Drunik Drunik
```c // Fixed‑point 16‑bit IIR distortion kernel // Coefficients are Q1.15, state is Q1.15 typedef struct { int16_t a0, a1, a2; // feed‑forward int16_t b1, b2; // feedback int16_t z1, z2; // states } DistortionState; // 1‑µs update routine (called by DMA sync) void update_coeffs(DistortionState *s, const int16_t *coeffs) { s->a0 = coeffs[0]; s->a1 = coeffs[1]; s->a2 = coeffs[2]; s->b1 = coeffs[3]; s->b2 = coeffs[4]; } // Main DSP loop (runs at 480 MHz, 1‑µs per sample) int16_t process_sample(DistortionState *s, int16_t in) { // Q1.15 multiply with 32‑bit accumulator int32_t acc = (int32_t)in * s->a0 + (int32_t)s->z1 * s->a1 + (int32_t)s->z2 * s->a2; int16_t out = (int16_t)(acc >> 15); // back to Q1.15 // Update states s->z2 = s->z1; s->z1 = out - ((int32_t)s->b1 * out >> 15) - ((int32_t)s->b2 * s->z2 >> 15); // Clamp to 16‑bit if (out > 32767) out = 32767; if (out < -32768) out = -32768; return out; } ```