File: vibro.c

package info (click to toggle)
sox 12.15-1
  • links: PTS
  • area: main
  • in suites: slink
  • size: 1,116 kB
  • ctags: 1,453
  • sloc: ansic: 16,583; sh: 241; makefile: 69
file content (134 lines) | stat: -rw-r--r-- 3,157 bytes parent folder | download
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 */
}