p-fields:
/* FOLLOWBUTTER - a simple envelope follower
FOLLOWBUTTER maps the amplitude envelope of the modulator to the cutoff
frequency of a filter applied to the carrier. This filter works as
described in the documentation for the BUTTER instrument, except that
there is no balance parameter. The carrier is supplied as the "left"
channel, the modulator as the "right" channel. (See below.)
p0 = output start time
p1 = input start time (must be 0 for aux bus -- see below)
p2 = duration
p3 = carrier amplitude multiplier
p4 = modulator amplitude multiplier
p5 = power gauge window length (in samples; try 100)
p6 = smoothness -- how much to smooth the power gauge output (0-1; try .8)
p7 = type of filter (1: lowpass, 2: highpass, 3: bandpass, 4: bandreject)
p8 = minimum cutoff (or center) frequency
p9 = maximum cutoff (or center) frequency
p10 = steepness (> 0) [optional, default is 1]
p11 = percent to left channel [optional, default is .5]
Function table 1 is the overall amplitude envelope.
Function table 2 is the bandwidth curve, if using the bandpass or
bandreject filter types.
NOTES:
- The "left" input channel comes from the bus with the lower number;
the "right" input channel from the bus with the higher number.
- Currently in RTcmix it's not possible for an instrument to take
input from both an "in" bus and an "aux in" bus at the same time.
So, for example, if you want the modulator to come from a microphone,
which must enter via an "in" bus, and the carrier to come from a
WAVETABLE instrument via an "aux" bus, then you must route the
mic into the MIX instrument as a way to convert it from "in" to
"aux in". If you want the carrier to come from a file, then it
must first go through MIX (or some other instrument) to send it
into an aux bus. Since the instrument is usually taking input
from an aux bus, the input start time for this instrument must be
zero. The only exception would be if you're taking the carrier
and modulator signals from the left and right channels of the same
sound file.
- The envelope follower consists of a power gauge that measures the
average power of the modulator signal. The window length (p5) is
the number of samples to average. Large values (> 1000) track only
gross amplitude changes; small values (< 10) track very minute
changes. If the power level changes abruptly, as it does especially
with long windows, you'll hear zipper noise. Reduce this by
increasing the smoothness (p6). This applies a low-pass filter
to the power gauge signal, smoothing any abrupt changes.
- You'll probably always need to boost the modulator amplitude
multiplier (p4) beyond what you'd expect, because we're using
the RMS power of the modulator to affect the carrier, and this
is always lower than the peak amplitude of the modulator signal.
- Maximum cutoff (p9) is the cutoff frequency you get when the power
gauge reads 1.0. Whether the guage reaches -- or exceeds -- 1.0
depends on the modulator amplitude multiplier, and is signal
dependent. In other words, just play around with the combination
of max. cutoff and modulator amp.
- Steepness (p10) is just the number of filters to add in series.
Using more than 1 steepens the slope of the filter. You may need
to change p3 (carrier amp) to adjust for loss of power caused
by connecting several filters in series. Guard your ears!
*/
Sample scorefile:
rtsetparams(44100, 2)
load("WAVETABLE")
load("FOLLOWBUTTER")
source_listen = 0 /* set to 1 to hear carrier and modulator separately */
dur = 20
/* play carrier to bus 0 */
bus_config("WAVETABLE", "aux 0 out")
makegen(2, 10, 8000, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
amp = 15000
WAVETABLE(0, dur, amp, freq = 140)
WAVETABLE(0, dur, amp, freq * 1.002)
/* play modulator to bus 1 */
bus_config("WAVETABLE", "aux 1 out")
setline(0,0, 1,1, 2,0)
reset(20000)
srand(2)
incr = base_incr = 0.14
notedur = base_incr * 0.35
freq = 1000
for (st = 0; st < dur; st = st + incr) {
db = irand(40, 92)
WAVETABLE(st, notedur, ampdb(db), freq)
incr = base_incr * irand(0.25, 4)
}
reset(1000)
/* apply modulator's amp envelope to carrier */
bus_config("FOLLOWBUTTER", "aux 0-1 in", "out 0-1")
setline(0,0, 1,1, 19,1, 20,0)
caramp = 4.0
modamp = 1.5
winlen = 10 /* number of samples for power gauge to average */
smooth = 0.8 /* how much to smooth the power gauge curve */
type = 3 /* 1: lowpass, 2: highpass, 3: bandpass, 4: bandreject */
mincf = 120
maxcf = 12000
bw = -.3
steepness = 2
pctleft = 0.5
makegen(2, 18, 10, 0, bw, 1, bw)
if (source_listen) {
bus_config("MIX", "aux 0-1 in", "out 0-1")
MIX(0, 0, dur, 1, 0, 1)
}
else
FOLLOWBUTTER(0, inskip = 0, dur, caramp, modamp, winlen, smooth, type,
mincf, maxcf, steepness, pctleft)