WIGGLE

wavetable oscillator with frequency modulation and filter (in package insts.jg)

WIGGLE does a whole lot of fun synthesis things. The instrument is like WAVETABLE, except that it lets you change the pitch with a glissando curve and/or frequency modulation. The modulation can be subaudio rate (for vibrato) or audio rate (for basic Chowning FM). There is an optional filter, either lowpass or highpass. Many of the parameters are time-varying, specified by makegen for function table slots.

There is a lot to this instrument -- we've included a number of sample scorefiles below.

p-fields:

/* WIGGLE - wavetable oscillator with frequency modulation and filter

   p0 = output start time
   p1 = duration
   p2 = carrier amplitude
   p3 = carrier oscillator frequency (or oct.pc if < 15)
   p4 = modulator depth control type (0: no modulation at all, 1: percent
        of carrier frequency, 2: modulation index) [optional, default is 0]
   p5 = type of filter (0: no filter, 1: low-pass, 2: high-pass)
        [optional, default is 0]
   p6 = steepness (> 0) [optional, default is 1]
   p7 = balance output and input signals (0:no, 1:yes) [optional, default is 0]

   p4 (modulator depth control type) tells the instrument how to interpret
   the values in the modulator depth function table.  You can express these
   as a percentage of the carrier (useful for subaudio rate modulation) or
   as a modulation index (useful for audio rate FM).  If you don't want
   to use the modulating oscillator at all, pass 0 for this pfield.  Then
   you don't need to create function tables 4-6.

   p6 (steepness) is just the number of filters to add in series.  Using more
   than 1 steepens the slope of the filter.  If you don't set p7 (balance)
   to 1, you'll need to change p2 (carrier amp) to adjust for loss of power
   caused by connecting several filters in series.

   p7 (balance) tries to adjust the output of the filter so that it has
   the same power as the input.  This means there's less fiddling around
   with p2 (amp) to get the right amplitude when steepness is > 1.  However,
   it has drawbacks: it can introduce a click at the start of the sound, it
   can cause the sound to pump up and down a bit, and it eats extra CPU time.

   Here are the function table assignments:

      1: amplitude curve (setline)
      2: carrier oscillator waveform (e.g., gen 9 or 10)
      3: carrier glissando curve (linear octave offsets from p3 frequency)
      4: modulator oscillator waveform
      5: modulator frequency (in Hz)
      6: modulator depth (p4 determines how these values are interpreted)
      7: filter cutoff frequency
      8: pan curve (from 0 to 1)

   NOTE: The glissando table is read without interpolation.  This was done
   on purpose, to permit sub-audio modulation with "jagged edges."
   For example, if you say
      makegen(3, 20, 1, 10)
   you'll get audible random stairsteps (with no transitions between the
   steps).
*/
Sample scorefile 1:
rtsetparams(44100, 2)
load("WIGGLE")

dur = 12
amp = 10000
pitch = 8.00
mod_depth_type = 1      /* % of car freq */

setline(0,0, 1,1, 2,1, 5,0)

makegen(2, 10, 8000, 1,1/2,1/3,1/4,1/5,1/6,1/7,1/8)  /* car waveform */
makegen(3, 18, 1000, 0,-0.02, 1,0.07)                /* car gliss */
makegen(4, 10, 8000, 1)                              /* mod waveform */
makegen(5, 18, 1000, 0,20, 1,3, 2,0)                 /* mod freq */
makegen(6, 18, 1000, 0,1, 1,20, 2,5)                 /* mod depth */
makegen(8, 18, 5000, 0,1, 1,.9, 5,0)                 /* pan */

WIGGLE(st=0.00, dur, amp, pitch, mod_depth_type)

amp = amp * 0.4
makegen(2, 10, 8000, 1,0,1/9,0,1/25,0,1/49)          /* car waveform */
makegen(3, 18, 1000, 0,0.02, 3,-0.10, 4,-2.05)       /* car gliss */
makegen(5, 18, 1000, 0,21, 1,1, 2,0)                 /* mod freq */
makegen(6, 18, 1000, 0,1, 1,20, 2,8)                 /* mod depth */
makegen(8, 18, 5000, 0,0, 2,.1, 5,1)                 /* pan */

WIGGLE(st=0.05, dur, amp, pitch+2.005, mod_depth_type)
Sample scorefile 2:
rtsetparams(44100, 2)
load("WIGGLE")

dur = 10
two_layers = 1  /* 0: one layer, 1: two layers */
amp = 800
pitch = 11.00

setline(0,1, dur-.1,1, dur,0)

makegen(2, 10, 8000, 1,.3,.1)       /* car waveform */

/* -------------------------------------------------------------------------- */
/* Use gliss function, created with gen 20, to provide random "vibrato."
   This shows how to compute gen size to get the vibrato rate you want.
   Note that WIGGLE doesn't interpolate between values of the gliss
   function, so you get a clear stair-step effect, like an old analog
   sequencer.  If you want smooth transitions between the steps, use
   the mod oscillator instead.  Then you could also have varying speed,
   which can do with the gliss function.
*/
vib_speed = 10 /* in Hz */
dist_type = 0  /* 0=even, 1=low, 2=high, 3=triangle, 4=gaussian, 5=cauchy */
seed = 1

/* down as much as a perfect fifth, up as much as an octave */
min = -0.07    /* in oct.pc */
max = 1.00

gen_size = vib_speed * dur

/* gliss function values are in linear octaves, thus the octpch conversions. */
makegen(3, 20, gen_size, dist_type, seed, octpch(min), octpch(max))

WIGGLE(st=0, dur, amp, pitch)

/* -------------------------------------------------------------------------- */
if (two_layers) {
   /* same as above, but different seed */
   makegen(3, 20, gen_size, dist_type, seed+1, octpch(min), octpch(max))
   pitch = pitch - 3  /* 3 octaves below */
   WIGGLE(st=0, dur, amp, pitch)
}
Sample scorefile 3:
rtsetparams(44100, 2)
load("WIGGLE")
load("FREEVERB")
bus_config("WIGGLE", "aux 0-1 out")
bus_config("FREEVERB", "aux 0-1 in", "out 0-1")

dur = 18

/* --------------------------------------------------------------- wiggle --- */
amp = 7000
pitch = 7.00
mfreq = cpspch(pitch+1)

setline(0,0, 1,1, 6,1, 8,0)

makegen(2, 10, 8000, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1) /* car wave */
makegen(3, 18, 10, 0,0,1,0)                        /* car gliss */
makegen(4, 10, 80, 1, 1, .4)                       /* mod wave */
makegen(5, 18, 20, 0,mfreq, 1,mfreq, 2,mfreq-18)   /* mod freq */
makegen(6, 18, 2000, 0,1.5, 1,1.8)                 /* mod depth */
makegen(7, 18, 2000, 0,4000, 1,10000, 2,100)       /* filt cf */
makegen(8, 18, 2000, 0,0, 1,.5)                    /* pan */

depth_type = 2  /* mod index */
filt_type = 1
filt_steep = 5

WIGGLE(st=0, dur, amp, pitch, depth_type, filt_type, filt_steep)

makegen(3, 20, 250, 4, 1, -.04,.04)                /* car gliss */
makegen(8, 18, 2000, 0,1, 1,0)                     /* pan */
WIGGLE(st=0.01, dur, amp, pitch, depth_type, filt_type, filt_steep)


/* --------------------------------------------------------------- reverb --- */
roomsize = 0.85
predelay = 0.02
ringdur = 1.0
damp = 50
dry = 80
wet = 30
stwid = 100

FREEVERB(0, 0, dur, amp=1, roomsize, predelay, ringdur, damp, dry, wet, stwid)
Sample scorefile 4:
rtsetparams(44100, 2)
load("WIGGLE")

dur = 25
amp = 3000
pitch = 10.00

makegen(1, 4, 2000, 0,0,2, dur*.1,1,0, dur*.4,1,-3, dur,0)

makegen(2, 10, 8000, 1)                /* car wave */
makegen(3, 20, 300, 2, 0, -1.00,2.00)  /* random gliss */

makegen(4, 10, 1000, 1)                /* mod waveform */
makegen(5, 18, 20, 0,200, 1,200)       /* mod pitch */
makegen(6, 18, 2000, 0,20, 1,20)       /* mod depth */

makegen(-7, 4, 2000, 0,1000,-4, 1,1)   /* filter cf */
makegen(8, 18, 2000, 0,.2, 1,.5, 2,1)  /* pan */

filt_type = 2                          /* highpass */
filt_steep = 20

WIGGLE(st=0, dur, amp, pitch, 2, filt_type, filt_steep)

makegen(8, 18, 2000, 0,1, 1,0)         /* pan */
WIGGLE(st=0.1, dur, amp, pitch+.01, 2, filt_type, filt_steep)