This is RVB.c in view mode; [Download] [Up]
#include <stdio.h>
#include <math.h>
#include "ugens.h"
#include "sfheader.h"
#include "nobug.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.