ftp.nice.ch/pub/next/unix/audio/cmusic.bs.N.tar.gz#/NeXT_updates/new_cmusic/cmusic_src_reverb/mm.sndout.play.c

This is mm.sndout.play.c in view mode; [Download] [Up]

#include "mm.head.h"
#include "m.exts.h"
#include <carl/carl.h>
#include <carl/defaults.h>
#include <math.h>
#include <sys/file.h>

#ifdef nextsf
#import <sound/sound.h>
SNDSoundStruct *snd ;
int fd = -1 ;
#endif

sndout(){
     static int otty;
     register long i,n;
     register float *Fout;
     register short *Sout;
     static long scount = 0, dcount = 0, lastclipped= 0, dclipped = 0;
     static float dmax = 0.0, aval;
     static char first;

    otty = isatty(1);
    n = Ngen*Nchan;
    if( (scount += Ngen) >= Srate)scount -= Srate;
    if(scount < Ngen){
	dcount++;
	PROUT(":%d",dcount);
	PROUT("(%f)",dmax);
	if(Timer)fprintf(stderr, ":%d(%f)",dcount,dmax);
	dmax = 0.0;
	dclipped = Clipped - lastclipped;
	if(dclipped)PROUT("[%d]", dclipped);
	lastclipped = Clipped;
	if(!(dcount%5))PROUT("\n",stderr);
    }

    if(Spaceon && Revscale > 0.0)Greverb();
#ifdef nextsf
	if( Outfilename != 0 && !first ) {
	    first++;
	    SNDAlloc(&snd,0,SND_FORMAT_LINEAR_16,Srate,Nchan,4);

	    if((fd = open(Outfilename, O_CREAT | O_WRONLY | O_TRUNC, 0644 )) < 0) {
		fprintf(stderr,"Unable to write '%s'\n", Outfilename) ;
		exit(-1) ;
	    }
	    SNDWriteHeader(fd,snd);
	}
#else
	if(Header && !otty) {
	    if (!first && strlen( Outfilename ) > 0 ) {
		    char srate[32], nchan[32];

		    first++;
		    sprintf(srate, "%d", Srate);
		    sprintf(nchan, "%d", Nchan);
		    if (!Floatout)
			    set_sample_size(sizeof(short));
		    if (stdheader(stdout, Infilename, srate, nchan, 
			    Floatout ? H_FLOATSAM : H_SHORTSAM))
				    fprintf(stderr, "can't create header\n");
		    if (putheader(stdout))
			    fprintf(stderr, "can't write header\n");
	    }
	}
#endif
    Fout = Outblock; Sout = Sampout;
    for(i=0; i<n; i++,Sout++,Fout++){
	aval = *Fout >= 0 ? *Fout : -( *Fout) ;
	if(aval > Maxamp) Maxamp = aval;
	if(aval > dmax) dmax = aval;
	if(*Fout > 1.0 && Clip){*Fout = 1.0; Clipped++;}
	if(*Fout < -1.0 && Clip){*Fout = -1.0; Clipped++;}
	if(!Floatout) *Sout = *Fout * 32767.0;
    }
	if(Nooutput) return ;

#ifdef nextsf
    if(fd >= 0)		write(fd,Sampout, n << 1);

    else {
	if(otty){
	    if(Floatout)	for(i=0; i<n; i++) printf("%8.8f\n",*(Outblock+i));

	    else		for(i=0; i<n; i++)printf("%d\n",*(Sampout+i));
	}
	else {
	    if(Floatout)	fputfbuf(Outblock,n,stdout);

	    else		fputsbuf(Sampout,n,stdout);
	}
    }
#else
    if(otty){
	if(Floatout)for(i=0; i<n; i++) printf("%8.8f\n",*(Outblock+i));
	 else for(i=0; i<n; i++)printf("%d\n",*(Sampout+i));
    }
    else {
	if(Floatout) fputfbuf(Outblock,n,stdout);
	 else fputsbuf(Sampout,n,stdout);
    }
#endif
}
/*
 * the cmusic global reverberator (input produced by space unit generator)
 */
#define NCF 18 /* Number of parallel comb filters (note comb routine setup) */
Greverb(){
 register float *Out = Outblock, *Grev = Grevblock, gout;
 register int i,f;
 float allpass(), comb();
 float val, aval;
 static long tailcount = 0;

    for(i=0; i<Ngen; i++, Grev++){
	for(gout=0., f=0; f<NCF; f++) gout += comb(f,*Grev);
	for(f=0; f<Nchan; f++){
	    val = allpass(f,gout);
	    val *= Revscale;
	    aval = val >= 0 ? val : -val ;
	    if(aval > Maxreverb)Maxreverb = aval;
	    if(aval > Revthresh)tailcount = 0;
	    if(Spacereset){Spacereset = Spaceon = 0; return;}
	    if(++tailcount > Srate){Spacereset = 1; tailcount = 0;}
	    *Out++ += val;
	}
    }
}
/*
 * comb filters with lowpass loops
 */
float comb(n,x) int n; float x; {
 static long dlen[] = {43, 215, 225, 268, 270, 298, 458, 485, 572, 587, 595, 612, 707, 708, 726, 714, 753, 797};		/* delays in milliseconds */

// static float g1[] = {.58, .75, .75, .81, .81, .82, .86, .86, .91, .9, .89, .91, .91, .91, .91, .93, .92, .93};

// 18 
static float g1[] = {.5795, .748, .7545, .8105, .81, .822, .8555, .864, .905, .9035, .8915, .9095, .91, .9095, .912, .929, .9165, .933};

// static float g1[] = {.841, .504, .491, .379, .38, .346, .289, .272, .192, .193, .217, .181, .18, .181, .176, .142, .167, .134};

 static long now[NCF], first = 1;
 static float *dbuf[NCF], g2[NCF], zm1[NCF];
 register float t, y;
 register int i, j;
    
    if(first) for(i=0; i<NCF; i++){
	dlen[i] = Srate*dlen[i]/10000.;			// JS -- was 1000
	g1[i] = (Srate*g1[i]/25000.) / 2;		// JS -- added "/ 2"
	g2[i] = T60mult*(1. - g1[i]);
	zm1[i] = now[i] = 0;
	dbuf[i] = (float *) calloc(dlen[i], sizeof(float));
	first = 0;
    }
    if(Spacereset){
	for(i=0; i<NCF; i++){
	    for(j=0; j<dlen[i]; j++)dbuf[i][j] = 0.0;
	    zm1[i] = 0.0;
	    now[i] = 0;
	}
	return(0.0);
    }
    y = dbuf[n][now[n]];
    t = y + zm1[n]*g1[n];
    zm1[n] = t;
    dbuf[n][now[n]] = x + t*g2[n];
    if( (now[n] += 1) >= dlen[n]) now[n] = 0;
    return( (float) y);
}
/*
 * the famous one-multiply allpass filter
 */
float allpass(n,x) int n; float x; {
 static int dlen[] = {6,7,8,9}; /* delay lengths */
 static float g[] = {.7,.71,.72,.73}; /* loog gains */
 static int now[NCF], first = 1;
 static float *dbuf[NCF];
 register float t1, t2;
 register int i, j;
    
    if(first) for(i=0; i<Nchan; i++){
/* make delays slightly different */
	dlen[i] = Srate*dlen[i]/1000. + 3*i; 
	now[i] = 0;
	dbuf[i] = (float *) calloc(dlen[i], sizeof(float));
	first = 0;
    }
    if(Spacereset){
	for(i=0; i<Nchan; i++){
	    for(j=0; j<dlen[i]; j++)dbuf[i][j] = 0.0;
	    now[i] = 0;
	}
	return(0.0);
    }
    t1 = dbuf[n][now[n]];
    dbuf[n][now[n]] = (t2 = (x - t1)*g[n]) + x;
    if( (now[n] += 1) >= dlen[n]) now[n] = 0;
    return( (float) (t1 + t2) );
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.