1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/*
* Sound Tools Vibro effect file.
*
* Modeled on world-famous Fender(TM) Amp Vibro knobs.
*
* Algorithm: generate a sine wave ranging from
* 0 + depth to 1.0, where signal goes from -1.0 to 1.0.
* Multiply signal with sine wave. I think.
*
* July 5, 1991
* Copyright 1991 Lance Norskog And Sundry Contributors
* This source code is freely redistributable and may be used for
* any purpose. This copyright notice must be maintained.
* Lance Norskog And Sundry Contributors are not responsible for
* the consequences of using this software.
*
* April 28, 1998 - Chris Bagwell (cbagwell@sprynet.com)
*
* Rearranged some functions so that they are declared before they are
* used. Clears up some compiler warnings. Because this functions passed
* foats, it helped out some dump compilers pass stuff on the stack
* correctly.
*
*/
#include <math.h>
#include <stdlib.h>
#include "st.h"
/* Private data for Vibro effect */
typedef struct vibrostuff {
float speed;
float depth;
short *sinetab; /* sine wave to apply */
int mult; /* multiplier */
unsigned length; /* length of table */
int counter; /* current counter */
} *vibro_t;
/*
* Process options
*/
void vibro_getopts(effp, n, argv)
eff_t effp;
int n;
char **argv;
{
vibro_t vibro = (vibro_t) effp->priv;
vibro->depth = 0.5;
if ((n == 0) || !sscanf(argv[0], "%f", &vibro->speed) ||
((n == 2) && !sscanf(argv[1], "%f", &vibro->depth)))
fail("Usage: vibro speed [ depth ]");
if ((vibro->speed <= 0.001) || (vibro->speed > 30.0) ||
(vibro->depth < 0.0) || (vibro->depth > 1.0))
fail("Vibro: speed must be < 30.0, 0.0 < depth < 1.0");
}
/* This was very painful. We need a sine library. */
void sine(buf, len, depth)
short *buf;
int len;
float depth;
{
int i;
int scale = depth * 128;
int base = (1.0 - depth) * 128;
double val;
for (i = 0; i < len; i++) {
val = sin((float)i/(float)len * 2.0 * M_PI);
buf[i] = (val + 1.0) * scale + base * 2;
}
}
/*
* Prepare processing.
*/
void vibro_start(effp)
eff_t effp;
{
vibro_t vibro = (vibro_t) effp->priv;
vibro->length = effp->ininfo.rate / vibro->speed;
if (! (vibro->sinetab = (short*) malloc(vibro->length * sizeof(short))))
fail("Vibro: Cannot malloc %d bytes",
vibro->length * sizeof(short));
sine(vibro->sinetab, vibro->length, vibro->depth);
vibro->counter = 0;
}
/*
* Processed signed long samples from ibuf to obuf.
* Return number of samples processed.
*/
void vibro_flow(effp, ibuf, obuf, isamp, osamp)
eff_t effp;
LONG *ibuf, *obuf;
int *isamp, *osamp;
{
vibro_t vibro = (vibro_t) effp->priv;
register counter, tablen;
int len, done;
short *sinetab;
LONG l;
len = ((*isamp > *osamp) ? *osamp : *isamp);
sinetab = vibro->sinetab;
counter = vibro->counter;
tablen = vibro->length;
for(done = 0; done < len; done++) {
l = *ibuf++;
/* 24x8 gives 32-bit result */
*obuf++ = ((l / 256) * sinetab[counter++ % tablen]);
}
vibro->counter = counter;
/* processed all samples */
}
/*
* Do anything required when you stop reading samples.
* Don't close input file!
*/
void vibro_stop(effp)
eff_t effp;
{
/* nothing to do */
}
|