From: ramirez.Princeton.EDU!penrose (Christopher Penrose)
Subject: Re: High-Level Granular Synthesis: Code Examples?
Originator: news@nimaster
Keywords: granular synthesis, code
Organization: Princeton University
Date: Sat, 3 Oct 1992 01:41:13 GMT

John Duesenberry writes:
> Does anybody know a source of code examples (preferably in CSound or C)
> that implement granular synthesis at a higher level?

Christ Almighty, John!  Write it yourself!  :)

---

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include "crack.h"

#define allc_min 4096

typedef struct {
        int mgs;
        float *magnets;
        float *probs;
} fmg;

main(argc,argv)
int argc; char **argv;
{

        int             i,j,k,          /* loop indices */
                        ng = 100,       /* grains per window */
                        its,            /* number of windows to calculate */
                        mgs;            /* frequency magnets */

        float           mbnd = .0057,   /* magnet bandwidth */
                        wind = .1,      /* density window (seconds) */
                        freq,           /* instantaneous frequency of grain */
                        ampl,           /* grain amplitude */
                        iampl = 250.,
                        abnd,           /* amplitude bandwidth */
                        prob,           /* probability of occurrence */
                        mgunit,         /* magnets per unit duration */
                        dur,            /* total length of texture */
                        gl = .01,       /* individual grain length */
                        event = 0.,     /* instantaneous time index */
                        ctimef = 0.,    /* window time index */
                        off = .25,      /* absolute time offset */
                        frac,           /* probability fractional */
                        nprob, cprob,   /* magnet probability pairs */
                        prand(),        /* random function [0..1] */
                        rrand(),        /* random function [+-1] */
                        rtnfreq();      /* probability distribution sub */
        char            ch,             /* ch for 'crack' */
                        *space(),       /* allocation function */
                        ihead[16];      /* note statment instrument */
        fmg             *mg,            /* pointer to magnet struct */
                        *cmg;           /* current magnet struct */
                
    while( (ch=crack( argc, argv, "g|m|b|B|o|w|l|L|i|a|h", 0 )) != NULL ) {
        switch (ch) {
            case 'g':   ng = atoi(arg_option);
                        break;
            case 'm':   mgs = atoi(arg_option);
                        break;
            case 'b':   mbnd = atof(arg_option);
                        break;
            case 'B':   abnd = atof(arg_option);
                        break;
            case 'o':   off = atof(arg_option);
                        break;
            case 'w':   wind = atof(arg_option);
                        break;
            case 'l':   dur = atof(arg_option);
                        break;
            case 'L':   gl = atof(arg_option);
                        break;
            case 'i':   if ( (strcpy( ihead, arg_option )) == NULL)
                            fprintf(stderr,"Memory Fault! oOf!\n"), exit(-1);
                        break;
            case 'a':   iampl = atof(arg_option);
                        break;
            case 'h':   usage(0);
        }
    }
    mg = (fmg *) malloc( mgs * sizeof(fmg) );

    for( i=0; i < mgs; i++ ) {
        (mg+i)->magnets = (float *) malloc( 1024 );
        (mg+i)->probs = (float *) malloc( 1024 );
        j = 0;
        while ( (ch=getchar()) != '~' && ch != EOF ) {
            ungetc(ch, stdin);
            scanf("%f %f\n", (mg+i)->magnets+j, (mg+i)->probs+j);
            ++j;
        }
        (mg+i)->mgs = j;
    }

    dur = ( its = (int) (dur / wind) ) * wind;  
    mgunit = dur / (mgs - 1);

    for( i=0; i < its; i++ ) {
        for( j=0; j < ng; j++ ) {
            while ( (event = rrand() * wind + ctimef) < 0.);
            cmg = mg + ( (int) (frac = (event / mgunit) ) );
            cprob = 1. - ( frac - ((int) frac) );
            prob = prand();
            ampl = iampl * (( rrand() * abnd ) + 1.);
            if (prob < cprob) 
                freq = rtnfreq( cmg, mbnd );
            else 
                freq = rtnfreq( cmg+1, mbnd );
            printf("%s %f %f %f %f\n", ihead, event + off, gl, ampl, freq);
        }
        ctimef += wind;
    }
}

float rtnfreq( cmg, mbnd )
fmg *cmg; float mbnd;
{
        int             i = 0;

        float           prob,
                        rrand(),
                        prand();

        
        prob = prand();
        while ( (prob -= *(cmg->probs+i)) > 0. ) {
            ++i;
        }
        return ( *(cmg->magnets+i) * ( 1. + (rrand() * mbnd) ) );
}

usage(glue)
int glue;
{
fprintf(stderr, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
        "grn--granular texture gen\n",
        "% grn [flags] < data > events\n",
        "               flagi:\n",
        "       g:      grains per window\n",
        "       m:      number of frequency magnet sets\n",
        "       b:      magnet frequency bandwidth\n",
        "       B:      amplitude bandwidth\n",
        "       o:      offset time for beginning\n",
        "       l:      length of texture\n",
        "       L:      grain length\n",
        "       w:      grain window duration\n",
        "       i:      note statement instrument header\n",
        "       a:      integer amplitude of grains\n",
        "       h:      this place\n");
exit(glue);
}

static  long    randx = 1;

void srrand(x)
unsigned x;
{
    randx = x;
}

float rrand()
{
    int i = ((randx = randx*1103515245 + 12345)>>16) & 077777;
    return((float)i/16384. - 1.);
}

float prand()
{
    int i = ((randx = randx*1103515245 + 12345)>>16) & 077777;
    return((float)i/32768.);
}

---

Christopher Penrose
penrose@silvertone.princeton.edu