Category Archives: livecoding
slub in Paris
Some random pictures from some excellent (and at times very loud) few days in Paris. Thanks to Sony Computer Science Labs and also the Paris contingent of the TPOLM demo crew for coming out to support us.
The gig was extensively recorded, so hopefully more about this soon.
BetaBlocker DS test tones
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]; } }
Missile Command machinima in São Paulo
Some images of the Machinima exhibition at FILE 2011 in São Paulo, featuring a movie of a livecoded abstractification of a Missile Command game written/performed/destroyed/recorded in Fluxus.
Betablocker DS: Table feedback after Claudius Maximus
After getting some dates for gigs with Betablocker DS, I am spending some time looking into audio algorithms, and implementing them on the Gameboy DS. Last Thursday I spent some time at the TAI studio/bunker with Till Bovermann investigating these PD patches by Claudius Maximus:
The algorithm uses feedback to create sounds that take some time to play through a wide range of frequencies. It works by writing into the same buffer it’s playing, but at a different rate/position – the resulting ugliness suits the style of BBDS very much. As an aid to our understanding Till converted the algorithm to Supercollider, then over the next couple of days I managed to get it running with an inner loop of 9 instructions on the DS (could probably be optimised further, but I’m still a beginner):
@ ----------------------------------------------------
@ qrz_maximus: *dst, length, readpos, writepos [freq, *tab]
@ ----------------------------------------------------
.global qrz_maximus
.type qrz_maximus, %function
qrz_maximus:
push {r4,r5,r6,r7} @ push the registers we need
ldr r4, [r13,#20] @ load freq from stack into r4
ldr r5, [r13,#24] @ load *tab from stack into r5
ldr r6, .tablength @ load the tablen into r6
.maximus_loop:
ldrh r7, [r5,r2] @ load the sample into r7
strh r7, [r0], #2 @ write output: *dst=r7 dst++
strh r7, [r5,r3] @ feedback into tab[writepos]=r7
add r2, r2, r4 @ readpos+=freq
and r2, r2, r6 @ mask readpos into range
add r3, r3, #2 @ writepos++
and r3, r3, r6 @ mask writepos into range
subs r1, r1, #1 @ length--
bne .maximus_loop @ repeat until length zero
mov r0, r2 @ return readpos
pop {r4,r5,r6,r7}
bx lr @ exit
.tablength:
.word 0x00003FF
And here it is running on autopilot with a test program in Betablocker:
Golden Medallions and in-game programming
Once the low level code for a Naked on Pluto bot is written in Scheme, it’s added by the game using secret commands which program the game inside itself, while it’s running. This means the game can be changed while people are playing it – which makes it much easier to add new things without worrying about the disruption caused by restarting the server. We can also work on the game collaboratively, at the same time this way.

(Programming a spybot with it’s behaviour)
Eventually the plan is to be able to program the bots fully within the game client – this is still a long term goal, but there are of course some fairly complex security problems with this idea.

(dressing a AudienceBot with another object)
Not all players have the ability to use these secret commands right now, in order to access them a player has to be carrying a special object (also known as a “Golden Medallion”). This allows you access to all areas of the game, including an “administration room” and various other secret powers.
Rainy sunday
A rainy Sunday, with only the dog for company, so in between walks I thought I’d try and learn some assembler. I’ve been unhappy with triggering samples with Betablocker DS (I prefer synthesis) and I’ve heard good things about ARM asm – so it seemed like a good opportunity to attempt a small, fast and dirty synth.
I found some really nice tutorials here and here. I’ve done a tiny bit of this sort of thing before with microcontrollers, but this is a more of a respectable flavour of assembler, on a decent RISC processor (which derives from the Acorn Archimedes and is now used on IPhones, Androids and Gameboys). Here is a white noise generator:
; white_noise(r0=*dst, r1=clock, r2=length, r3=freq) white_noise: push {r4,r5,r6} ; need to restore registers we use mov r4, r1 ; r4 is the rand state (start with clock) ldr r5, .rnd_data ; r5 is the multiplier value ldr r6, .rnd_data+1 ; r6 is the addition value .noise_loop: mla r4, r5, r4, r6 ; the maths bit: r4 = (r6 + (r5 * r4)) strh r4, [r0], #2 ; *dst++ = clock; subs r2, r2, #1 ; length--; bne .noise_loop ; branch if length not zero pop {r4,r5,r6} bx lr ; return .rnd_data: .word 0x000343FD ; nicked from ansi c rand() .word 0x00269EC3 ; need to keep large numbers (>8bit) as data
This code is based on the ansi C rand() function that basically looks like this:
randnum = randnum * 214013 + 2531011;
Which we can do in a single instruction – mla (multiply with accumulate). Of course, gcc would presumably optimise much better code than mine from C++, but there is something more satisfying about doing it this way. I certainly prefer the sound – and over half the cpu usage remains unused with 5 voices and the interface running. The rest of the code is here.
Betablocker machine running on Supercollider
Is seems our meetings at the TAI studio are bearing fruit already, Till Bovermann has ported the Betablocker machine as a Supercollider UGen. What’s interesting is rather than taking a similar approach to music making, this version is running at audio rate and the processes directly generate sample data. He can also run lots of them at the same time and control them from SCLang. It’s great when people use your code, but even better when it gets used in ways you didn’t think about.
New Betablocker DS video
I made a possible candidate for the TOPLAP dvd project – I took some time to get the audio visual sync working properly, which makes it (possibly) a little clearer what’s going on.
Video from 4for8 event
TAI Studio Opening Documentary from LFSaw.de on Vimeo.
More context on the tai studio webpage. Includes my first gameboy ds livecoding performance with webcamera screen/fingers/stylus projection.
0






