next up previous contents
Next: music2.c: For producing chaotic Up: Lorenz Attractor Source Code Previous: Makefile

music.c: For producing chaotic music

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);
}



Mike Andrews
Wed Oct 23 01:18:29 EDT 1996