After a week of heavy development on Germination X, and with a fast approaching performance, it seemed the time to dive back into Gameboy DS homebrew and get the bits and pieces of assembler code I’d been playing with together into something I could build more sounds from.
After getting the low level stuff working properly, I got busy making a bunch of audio scenes that I can trigger from Betablocker DS code.
Mostly I’m doing wavetable based things, with lots of frequency and ring modulation. I was also pleased to find this simple resonant filter thanks to the ever fabulous musicdsp archive (and thanks to Paul Kellett for originally posting it):
// set feedback amount given f and q between 0 and 1 fb = q + q/(1.0 - f); // for each sample... buf0 = buf0 + f * (in - buf0 + fb * (buf0 - buf1)); buf1 = buf1 + f * (buf0 - buf1); out = buf1;
The next step was to read Jasper Vijn’s excellent explanation of fixed point maths which I’ve used a bit on the Android but not really totally understood before. Mobile devices tend to only have integer maths at the hardware level, so if we restrict the calculations to fixed point it’s much faster and kinder to batteries than the floating point equivalent. Here is the fixed point version of the filter:
// we are using .10 fixed point (10 bits for the fractional part) #define FX_SHIFT 10 // convert an int into to it's fixed representation inline s32 fx(s32 i) { return i<<FX_SHIFT; } // multiply two fixed point numbers (returns fixed point) inline s32 fxmul(s32 a, s32 b) { return (a*b)>>FX_SHIFT; } // f is cutoff frequecy, q is resonance, s is the filter state void lpf(s16* dst, s16* src, u32 length, s16 f, s16 q, s16 *s) { u32 fb = q+fxmul(q,fx(1)-f); for (u32 i=0; i<length; ++i) { s[0]+=fxmul(f,src[i]-s[0]+fxmul(fb,s[0]-s[1])); s[1]+=fxmul(f,s[0]-s[1]); dst[i]=s[1]; } }
Leave a Reply