This is RVB.c in view mode; [Download] [Up]
#include <stdio.h> #include <math.h> #include "ugens.h" #include "sfheader.h" #include "debug.h" #define MACH1 1080.0 #define IWRAP(x,y) (((x)>=(y))?(x)-(y):(((x)<0)?(x)+(y):(x))) /* This file contains the routines directly associated with reverb, which is called by move. */ /* delpipe is a delay with a variable interpolated tap, used by reverb. */ double delpipe (sig, counter, nsdel, delay) long counter; double sig, nsdel, *delay; { extern int rvbdelsize; register int intap, tap1, tap2, del1, imd1; double frac; intap = counter % rvbdelsize; delay[intap] = sig; /* put samp into delay */ del1 = nsdel; /* truncate to int. */ frac = nsdel - del1; imd1 = intap - del1; tap1 = IWRAP(imd1, rvbdelsize); /* upper tap */ tap2 = IWRAP(tap1 - 1, rvbdelsize); /* lower tap */ return (delay[tap1] + (delay[tap2] - delay[tap1]) * frac); } /* Allpass is the allpass filter used by reverb */ double Allpass (sig, counter, delay) long counter; double sig, *delay; { double gain, gsig; register int nsdel, intap, length, outtap; gain = delay[0]; nsdel = delay[1]; length = nsdel + 1; intap = counter % length + 2; outtap = intap - nsdel; if (outtap < 2) outtap += length; /* Input = sig + gain * (sig - delayed out) */ gsig = gain * (sig - delay[outtap]); delay[intap] = sig + gsig; /* Output = delayed out + gain * (sig - delayed out) */ return (delay[outtap] + gsig); } /* matrix_mix distributes the outputs from the delays (in reverb) back into the inputs according to the signal routing matrix set up by the matrix routine. */ matrix_mix (input, output) double **input, **output; { register int i, j, m, n, inloc, outloc; double *outptr; extern double Matrix[12][12]; static double *pMatrix[12] = { Matrix[0],Matrix[1],Matrix[2],Matrix[3],Matrix[4],Matrix[5], Matrix[6],Matrix[7],Matrix[8],Matrix[9],Matrix[10],Matrix[11] }; outloc = 0; for (i = 0; i < 2; ++i) { for (j = 0; j < 6; ++j) { inloc = 0; outptr = &output[i][j]; *outptr = 0.0; for (m = 0; m < 2; ++m) { for (n = 0; n < 6; ++n) { if (pMatrix[outloc][inloc]) *outptr += input[m][n] * pMatrix[outloc][inloc]; ++inloc; } } ++outloc; } } } /* This is the main routine, RVB. It is a bank of 2x6 randomly varying delays which feed back into themselves in a tricky way. */ extern double *Rvb_del[2][6]; static double **pRvb_del[2] = { Rvb_del[0],Rvb_del[1] }; RVB (input, output, counter) double *input; double *output; long counter; { static double xdelout[2][6] = {{0.0,0.0,0.0,0.0,0.0,0.0}, {0.0,0.0,0.0,0.0,0.0,0.0}}; static double *delout[2] = { xdelout[0],xdelout[1] }; static double xdelin[2][6] = {{0.0,0.0,0.0,0.0,0.0,0.0}, {0.0,0.0,0.0,0.0,0.0,0.0}}; static double *delin[2] = { xdelin[0],xdelin[1] }; register int i, j; double sig, delay, delsig; double randi(), tone(); extern int Nsdelay[2][6]; static int *pNsdelay[2] = { Nsdelay[0],Nsdelay[1] }; extern double Allpass_del[2][502]; extern double Rvb_air[2][6][3]; static double *pRvb_air[2][6] = { Rvb_air[0][0],Rvb_air[0][1],Rvb_air[0][2], Rvb_air[0][3],Rvb_air[0][4],Rvb_air[0][5], Rvb_air[1][0],Rvb_air[0][1],Rvb_air[0][2], Rvb_air[0][3],Rvb_air[0][4],Rvb_air[0][5] }; static double **ppRvb_air[2] = { pRvb_air[0], pRvb_air[1] }; extern double Rand_info[2][6][6]; static double *pRand_info[2][6] = { Rand_info[0][0],Rand_info[0][1],Rand_info[0][2], Rand_info[0][3],Rand_info[0][4],Rand_info[0][5], Rand_info[1][0],Rand_info[0][1],Rand_info[0][2], Rand_info[0][3],Rand_info[0][4],Rand_info[0][5] }; static double **ppRand_info[2] = { pRand_info[0], pRand_info[1] }; for (i = 0; i < 2; ++i) /* loop for 2 output chans */ { output[i] = 0.0; for (j = 0; j < 6; ++j) /* loop for 6 delays per chan */ { sig = input[i] + delin[i][j]; /* combine input w/ delay return */ /* get new delay length (random) then put samp into delay & get new delayed samp out */ delay = pNsdelay[i][j] + randi(ppRand_info[i][j]); delsig = delpipe(sig, counter, delay, pRvb_del[i][j]); /* filter with air simulation filters, set gains */ delout[i][j] = tone(delsig, ppRvb_air[i][j]); /* sum outputs of all delays for 2 channels */ output[i] += delout[i][j]; } /* run outputs through Allpass filter */ output[i] = Allpass (output[i], counter, Allpass_del[i]); } /* redistribute delpipe outs into delpipe ins */ matrix_mix (delout, delin); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.