The other day, I was trying to remember how to generate some simple sounds with minimal amounts of code. I remembered vaguely something called the Karplus-Strong algorithm, and it has been floating around in my head that I should look it up again. I mentioned it to Tom, and he spent 15 seconds drawing something on his whiteboard to remind me how the rudiments of it worked. I spent two or three minutes in a break typing in this small chunk of C to try it out:
#include <stdio.h> #include <stdlib.h> #include <sndfile.h> /* * ks.c * a small implementation of the karplus-strong synthesis algorithm * as described to me in 15 seconds or less by Tom Duff, and implemented * in the two or three minutes that it took to type in. */ #define SAMPLE_RATE 44100 #define TONE 440 /* * BUFSIZE is essentially the period of the sound in samples. */ #define BUFSIZE (SAMPLE_RATE/TONE) double buf[BUFSIZE] ; main() { int sample ; int i, j ; double s ; SNDFILE * sf ; SF_INFO sfinfo ; sfinfo.channels = 1 ; sfinfo.samplerate = SAMPLE_RATE ; sfinfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ; sf = sf_open("test.wav", SFM_WRITE, &sfinfo) ; for (i=0; i<BUFSIZE; i++) buf[i] = 2.0 * drand48() - 1.0 ; for (sample=i=0; sample<5*SAMPLE_RATE; sample++) { j = i + 1 ; if (j >= BUFSIZE) j = 0 ; s = (buf[i] + buf[j]) / 2 ; /* simplest filter imaginable */ buf[i] = s ; sf_write_double(sf, &s, 1) ; i = j ; } sf_close(sf) ; }
Here is link to the single note that the above code generated. Sure, it’s not all that impressive by itself, but consider how simple the code is. It takes a small buffer of random numbers and a simple averaging operation, and generates something which isn’t a completely unpleasant plucked-string sound. I find that rather remarkable. I’ll probably use this in a little programming project that I’ve been mulling over which involves Christmas music. Stay tuned.