This program outputs the Lorenz attractor ``chaos music'' that I used
in my own composition. It uses a simple small-increment timestepping
scheme to numerically output the state of the x, y, z and t variables
at each timestep. For the purposes of generating appropriate
``musical'' output, the x axis is scaled to approximately an octave
and a half and the waveform is sampled at an interval determined by
the #define QUANTIZE
line (currently every 5 timesteps). The
following very-pseudo pseudocode is a brief outline of
music.c.
01. Define variables.
02. Open output file ``output''
03. Prompt user for initial conditions, and set them.
-- Main Loop --
04. Check to see if we're done, if so goto 09.
05. Calculate x, y and z using previous (or initial) conditions.
06. Check QUANTIZE to see if we should output, if so, goto 08.
07. Repeat to 04.
08. Save current state in array, loop to 04.
09. Set melody equal to the X variable.
10. Set duration as constant (1).
11. Output melody.
12. END.
/* * Lorenz attractor chaotic music generator * $Id: music.c,v 1.2 1996/10/15 02:15:08 rocko Exp $ * Mike Andrews * */ #include <stdio.h> #include <stdlib.h> #include <math.h> #define DATASIZE 100 /* Number of data points in output */ #define TIMESTEP 0.0001 /* Numerical timestep for dt */ #define XSCALE 0.65 /* Appropriate scaling factors for */ #define YSCALE 0.65 /* each axis. */ #define ZSCALE 0.65 #define TSCALE 20 /* Scaling factor for the time axis */ #define QUANTIZE 3 /* Quantization interval for the time axis */ void main() { double x1, y1, z1, x, y, z, t; /* Double precision floating points for current and previous x, y, z and t variables */ double dt, dx, dy, dz, initial; /* Intermediate numerical differential components, and the initial conditions */ int xdat[DATASIZE]; /* Integer arrays for storing the */ int ydat[DATASIZE]; /* scaled and rounded result */ int zdat[DATASIZE]; /* for each quantized unit of time */ int dxdat[DATASIZE]; /* Integer arrays for the */ int dydat[DATASIZE]; /* differential components */ int dzdat[DATASIZE]; int duration[DATASIZE]; /* Array for note duration values */ int melody[DATASIZE]; /* Array for pitch values */ int tp=0, tpo=-1, tmp=0, i=0; /* Miscellaneous variables */ FILE *song; song=fopen("output", "w"); printf("\nEnter initial conditions (x1=y1=z1=t= ?):"); scanf("%lf", &initial); x1=(y1=(z1=(t=initial))); /* Set initial conditions */ melody[i]=(duration[i]=0); dt=TIMESTEP; while(tp<((DATASIZE*QUANTIZE)-1)) { /* Numerically "solve" the system of equations */ x=x1 + ( -10.0*x1 + 10.0*y1 ) * dt; y=y1 + ( 28.0*x1 - y1 - x1*z1 ) * dt; z=z1 + ( -(8/3)*z1 + x1*y1 ) * dt; t=t + dt; dx= -10.0*x + 10.0*y; dy= 28.0*x - y - x*z; dz= -(8/3)*z + x*y; tp=(int)floor(TSCALE*t); x1=x; y1=y; z1=z; if ((!(tp%QUANTIZE))&&(tp!=tpo)) /* Store appropriately quantized results */ { tpo=tp; xdat[i]=(int)floor(XSCALE*x); ydat[i]=(int)floor(YSCALE*y); zdat[i]=(int)floor(ZSCALE*z); dxdat[i]= (int)floor(dx); dydat[i]= (int)floor(dy); dzdat[i]= (int)floor(dz); i++; } } for (i=0; i<DATASIZE; i++) { melody[i]=xdat[i]; /* The melody pitch information will come from the x variable */ duration[i]=1; /* Equal durations for each note */ } tmp=0; for (i=0; i<DATASIZE; i++) { fprintf(song, "%d %d\n", tmp, melody[i]); /* Write output */ tmp+=duration[i]; } fclose(song); }