Monthly Archives: August 2011

Free software projects are not products

One of the best things to happen if you are a free software developer is to see your code cropping up in other projects. Recently I’ve been helping Till Bovermann reuse the Betablocker DS virtual machine and integrate it into Supercollider, where it can be run at audio rate to create sound directly. The fact that the code was written to run on Gameboy means that Till’s also able to run 20 of them at audio rate at the same time.

In other news, the Fluxus editor is now being used as a way of livecoding Open Frameworks. This has a nice symmetry to it, as Fluxus uses some code from Open Frameworks for it’s camera input.

To me this highlights how thinking about free software in terms of being products (in a consumer capitalist sense) is an ill fit. This kind of cross pollination is really “the point” of free software, and would be, by necessity full of barriers if these projects were proprietary.

The problem is that it’s very hard for us to see outside of these ideas when they are so ingrained in our world and our thinking. It’s sometimes valuable to try and outline these assumptions, and become more aware of them.

The popularity in terms of raw market share is an interesting metric for a free software project as it has a kind of irrelevance or is even an obstruction when users are not supporting the project somehow. In the same way, the definition of “user” and “developer” seem a hangover from the same kind of producer/consumer thinking we are interested in finding the edges of.

What we want to know is what kind of people are using the project, are they curious, will they fiddle with things, do they blog about the work they are doing, can they translate the documentation? Most of all, will they increase the energy surrounding the work? People that do that are precious.

If we want a good metric of a project’s success in terms of cross pollination, perhaps we can borrow from scientific methods – where citations are a major metric for how influential a paper, individual or group is. Is there a way of tracking the movement of code and ideas in free software?

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:

Colourful emotions

We’re currently putting the new plant spirit characters in Germination X and thinking more about how to use colour changes as part of the expression of the many emotions the FAtiMA agents contain.

I made this chart quickly, deliberately avoiding thinking about potential reasons for my choices. Interestingly I found I needed to start with the motion curves first (which describe how the colours are blended between over time) and these seemed much less arbitrary than the actual colours I chose. The reason could be that there is a closer connection between movement (however simple) and gestural expressions.

GX companion planting diagnosis

Finally the spirits in Germination X can provide some kind of help by diagnosing what is wrong with your plants if they get ill, and sending you a hint via a small message. They also look for other players who can plant seeds and ask them to help you. All the actions being driven by the FAtiMA modular AI system.

Visually we’ve also been experimenting with increasing the size of everything and allowing you to look around the world by dragging (which is quite jumpy at the moment). I still need to update the graphics to this higher resolution and fix the jumpiness, but I think it could be a better way of exploring the larger world than the separate “tiles” approach we have now.

PS2 vu1 rendering

Some more work on upcycling second hand PS2’s into cheap fluxus machines. The next step is to embrace the vector units – strange little processors for doing things with points lines and colours extremely fast.

This is quite a daunting task for various reasons, not only can you run floating point and integer calculations in parallel, the VU’s also have instruction pipelining where a calculation can take a number of instructions to finish. The advantage of this is that you can interleave work that you are doing while you wait for things to complete, and make extremely fast programs – but it takes some time to get your head around.

Luckily it’s made a whole lot easier by a free software tool called OpenVCL. This lets you write fairly straight forward assembler and it at least makes sure it should run correctly by spacing it out for you – future versions may also start optimising the code automatically.

This is my first very basic renderer, which simply applies the world->screen transform to each vertex in an object. It’s job is to load data put in it’s memory by the CPU, process and send it to the “graphics synthesizer” to draw the gouraud shaded triangles. It’s not only much faster than doing the same job on the CPU, but it leaves it free for other processing (such as running a Scheme interpreter).

        .syntax new
        .name vu1_unlit        
        .vu
        .init_vf_all
        .init_vi_all
        --enter
        --endenter
        ; load the matrix row by row
        lq      world_screen_row0, 0(vi00)
        lq      world_screen_row1, 1(vi00)
        lq      world_screen_row2, 2(vi00)
        lq      world_screen_row3, 3(vi00)
        ; load the params and set the addresses for
        ; the giftag and vertex data
        lq      params, 4(vi00)
        iaddiu  giftag_addr, vi00, 5
        iaddiu  vertex_data, vi00, 6
        ; move the vertex count to an integer 
        ; register so we can loop over it
        mtir    vertex_index, params[x]
vertex_loop:
        ; load the colour (just increments vertex_data)
        lqi     colour, (vertex_data++)
        ; load vertex position
        lq      vertex, 0(vertex_data)
        ; apply the transformation
        mul     acc, world_screen_row0, vertex[x]
        madd    acc, world_screen_row1, vertex[y]
        madd    acc, world_screen_row2, vertex[z]
        madd    vertex, world_screen_row3, vertex[w]
        div     q, vf00[w], vertex[w]
        mul.xyz vertex, vertex, q
        ; convert to fixed point
        ftoi4   vertex, vertex
        ; overwrite the old vertex with the transformed one
        sqi     vertex, (vertex_data++)
        ; decrement and loop
        iaddi   vertex_index, vertex_index, -1
        ibne    vertex_index, vi00, vertex_loop
        ; send to gs
        xgkick  giftag_addr
        --exit
        --endexit

Splinterfields: Mathematickal Arts #3

A third and final update on the Mathematickal Arts Workshop – following the previous outline, some more detail on the process of going from software to textile using plain weave.

First create a program and choose the colours:

Axiom: O
Rule: O => : O O :
Repeat 5 generations

: = Green
0 = Orange

Then “compile” the code to expand the pattern:

1= O
2= : O O :
3= : : O O : : O O : :
4= : : : O O : : O O : : : : O O : : O O : : :
5= : : : : O O : : O O : : : : O O : : O O : : : : : : O O : : O O : : : : O O : : O O : : : :

The resulting weave can be previewed in ASCII as described earlier. This was useful to discover the range of patterns possible. When done, install the compiled code on the loom as a warp thread colour sequence.

Then you follow the same sequence for the weft threads, choosing the colour based on the code generated. In this way you become a mere part of the process yourself.

This is another, more complex program with 2 rules. This expands rather quicker than the last one, so only three generations are required:

Axiom: O
Rule 1: O => O : O :
Rule 2: : => : O :
Run for 3 generations

This technique draws comparisons with Jacquard looms, but obviously it’s far simpler as the weave itself is the same, we are only changing between 2 colours (and a human is very much required to do the weaving in this case). However, one of the activities I would have tried with more time available would have been reverse engineering Jacquard woven fabric – to attempt to decode the rules used.

During the workshop it was also suggested that a woven quine may be possible – where the pattern somehow contains the instructions for it’s own manufacture.