ftp.nice.ch/pub/next/unix/audio/Cmix.N.s.tar.gz#/cmix/rooms/move/RVB.c

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.