wigwamjam : a genetic programming synthesiser
copyleft (C) 2004 nebogeo noise research inc
wigwamjam grows sounds using your decisions to drive the evolution of genetically programmed synth functions.

wigwamjam is proof of concept for the moment, and not a fully blown audio tool yet.

libspiralcore (core midi and audio code)
guile (script interface)
jack (audio i/o)
alsa (midi input - not yet implemented)

make install


growing sounds

the idea behind genetic interfaces is to grow complex functions merely by choosing from a range of options (or a population of genomes). each genome represents a function to create a sound, each iteration of the process of growing a sound, you choose the best one from the population which is then reseeded with mutants of that sound.

example jams
not very good quality, but an example of some jams with wwj here.


the main interface is currently in the form of a guile interpreter, on startup wigwamjam will generate and play you 6 random sounds. your commands are as follows:

(pick n) : pick the nth sound, and regenerate population with mutations of this sound.

(reset_all) : reload the population with random functions.

quite often the first generation may not consist of any audible sounds - use (reset_all) until a usable start sound is generated. at the moment wigwamjam is just about navigating the genomes and playing with generating sound.

there are also some globals that you can easily tweak:

(define sample_length 40960) : length of the sound in samples
(define popsize 5) : number of genomes in the population
(define mutation_strength 0.1) : affects difference between the genomes
(define init_program_complexity 100) : number of atomic function in genomes

a bit more detail

each genome consists of a scheme function, such as:
(+(*(-(+(* time 0.727902)(*(cos 0.032947)(+(* 0.891066(cos(* 0.056036 0.289760))) 0.427992)))(-(+ 0.263786(cos(cos 0.909516)))(+(+ 0.615768(* 0.784860 0.310357))(* 0.152533(+ 0.544825 0.759177)))))(cos(+(*(- 0.931440(+ 0.481277(cos 0.719695)))(+(+ 0.900367 0.068418)(+ 0.527956 time)))(+(*(- 0.076711 0.088166)(cos(+(cos 0.966168)(+(+ 0.265101 0.983890) 0.029167))))(* time time)))))(cos(cos(*(cos(+(+(*(+ 0.559870 time) 0.035169)(+(* 0.170070 0.413048) 0.696704))(+(*(- 0.916113(+ 0.709545 0.823073)) 0.346340)(+(+ 0.457896 0.444882)(* 0.838784(+ 0.396876 0.140069))))))(-(+(* 0.850137 0.426382)(* time(* 0.488472(cos 0.126733))))(cos(-(+ 0.536100(- 0.892301(* 0.535034 time)))(cos 0.434305))))))))

pretty unreadable huh? :) well, you don't need to read or write these functions, or even look at them - you decide which stay or go on the sound it makes.

there are very few atomic functions in wigwamjam's genomes, namely:

*,+,-,sin and cos

which if my simple dsp knowledge serves correctly is technically enough to create any sound (as being a sum of sine wave harmonics) but don't expect to be able to synthesize real instruments with this thing, as it isn't going to happen...

low level function api (a bit more detail still)

as rendering these functions in scheme is quite slow, wigwamjam uses a sampler to playback the sounds in a realtime capable jack process thread. the interpreter is running in a different thread so it should mean smooth playback when midi is implemented.

the simple wigwamjam interface detailed above is actually a script running api binding calls into the main app (see wigwamjam.scm) these are the low level calls:

(clear_all) : clears population and sample banks
(genome_new) : add a new genome (returns id)
(genome_add_function genome function args) : add a function to the genome with args arguments
(genome_create genome size) : build a random genome with size functions
(genome_mutate genome strength) : mutates genome
(genome_get genome) : returns function string
(genome_eval genome functionname) : evaluates genome into functionname function
(genome_program genome function) : sets function string into genome function (copy)
(play sample) : plays sample play id
(sample_new size) : make new sample with size samples storage, returns sample id
(sample_write sample pos value) : writes value into sample at position pos.
(sample_upload sample) : uploads sample to sampler for playing, returns play id
(sampler_clear) : erase all samples in the sampler

released under the GPL, see COPYING for more info