VOCODE

channel-vocoder (in package insts.jg)

VOCODE performs a filter-bank analysis of the input soundfile, and uses the time- varying energy measured in the filter bands to control a corresponding filter bank that processes an excitation signal. This signal comes either from a regular sound file or from a noise oscillator. The two filter banks have identical characteristics. There are two ways to configure the banks; the meanings of pfields 4-6 are different for the two ways.

The analysis soundfile is opened using the rtinput scorefile command.

To use a sound file as the excitation, call the excitationfile() Minc function, which takes the file name as its argument. (Call this before calling VOCODE.) If you don't specify an excitation file, then VOCODE uses noise instead. The meanings of pfields 9 and 10 change depending on whether you use a file or noise.

This instrument is similar in some respects to PVOC, but it is a channel vocoder using a bank of band-pass filters instead of an FFT analysis (like with phase vocoders). This kind of instrument was originally designed for cross-synthesis work -- see also VOCODE2 and VOCODESYNTH.


p-fields:

/* VOCODE - old-fashioned channel vocoder.

   p0  = output start time
   p1  = analysis input file start time
   p2  = duration
   p3  = amplitude multiplier (post-processing)

   Two ways to specify filter bank center frequencies:

    (1) Spread evenly above a given center frequency:
          p4 = number of filters (greater than 0)
          p5 = lowest filter center frequency (in Hz or oct.pc)
          p6 = center frequency spacing multiplier (greater than 1)
               (multiplies each cf by this to get next higher cf)

    (2) A list of center frequencies, given in function table 2 (Use gen 2.)
          p4 = 0 (must be zero: tells program to look for function table)
          p5 = transposition of function table, in oct.pc
          p6 = (ignored)
        Number of filters determined by length of function table.

   p7  = filter bandwidth proportion of center frequency (greater than 0)
   p8  = filter response time (seconds) [optional; default is 0.5]
         Determines how often changes in analysis file power are measured.

   Two ways to specify excitation function:

    (1) To use a sound file, first call excitationfile(), then:
          p9  = excitation file start time
          p10 = excitation file channel  [optional; default is 0]

    (2) To use noise, call excitationfile(""), or don't call it at all, then:
          p9  = seed for random number generator (any positive integer --
                   0 takes seed from system clock)
          p10 = specifies how often (in samples) to get new random values
                from the noise generator. Default is a new value every sample.

   p11 = analysis input file channel  [optional; default is 0]
   p12 = stereo spread (0 - 1)  [optional; default is 0.5]

   Assumes function table 1 is an amplitude curve for the note. (Try gen 18.)
   Or you can just call setline. If no setline or function table 1, uses a
   flat amplitude curve. This curve, combined with the amplitude multiplier,
   affect the signal after processing by the filter bank.

   NOTES:

     -  If using first method for specifying center frequencies...
           p6 = 2.0 will make a stack of octaves
           p6 = 1.5 will make a stack of perfect (Pythagorian) fifths
        Use this to get stacks of an equal tempered interval (in oct.pc):
           p6 = cpspch(interval) / cpspch(0.0)

     - If using second method for specifying center frequencies...
       Make function table 2, using gen 2. For example, to make cf's
       from a list of pitches in oct.pc notation:
          num_filters = 5
          makegen(2, 2, num_filters, 0)
          8.00, 8.07, 9.00, 9.07, 10.02
       You can transpose these by the number of semitones given in p5.
       Or, to specify cf's in Hz:
          makegen(2, 2, 12, 0)
          100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200
       Transposition (still specified as oct.pc) works here also, and it
       preserves harmonic structure.

     - If you want to use noise as excitation after having used a file,
       just say excitationfile("").

     - More about p10 (subsample interval) when using noise as excitation:
       When the interval is greater than 1, successive noise samples are
       connected using linear interpolation. This acts as a low-pass filter;
       the higher the interval, the lower the cutoff frequency. Above an
       interval of about 10 samples, the noise starts to sound gritty.
*/
Sample scorefile:
rtsetparams(44100, 2)
load("VOCODE")

/* analysis file */
rtinput("file1.snd")
dur = DUR()
analinskip = 0.0

/* excitation file */
excitationfile("file2.snd")
exciteinskip = 0.0

numfilts = 10
lowestcf = 300
bwpct = 0.04
interval = 0.07
spacemult = cpspch(interval) / cpspch(0.0)

amp = 1.20
responsetime = 0.5
outskip = 0.0

VOCODE(outskip, analinskip, dur, amp, numfilts, lowestcf, spacemult,
       bwpct, responsetime, exciteinskip)
Another sample scorefile:
rtsetparams(44100, 2)
load("VOCODE")

/* analysis file */
rtinput("file1.snd")
dur = DUR()
analchan = 0
analinskip = 0.0

/* excitation (using noise) */
seed = 1
subsample = 25

num_filters = 11
makegen(2, 2, num_filters, 0)
7.07, 8.00, 8.02, 8.03, 8.07, 9.00, 9.05, 9.07, 9.08, 10.02, 10.07
bwpct = 0.0008
transp = -0.05

amp = 10.0
responsetime = 0.002

/* stereo */
outskip = 0.0
VOCODE(outskip, analinskip, dur, amp, 0, transp, ignored=0,
       bwpct, responsetime, seed, subsample, analchan, spread=1)
outskip = 0.20
VOCODE(outskip, analinskip, dur, amp, 0, transp, ignored=0,
       bwpct, responsetime, seed, subsample, analchan, spread=0)
And one more sample scorefile just for fun:
rtsetparams(44100, 2)
load("VOCODE")

writeit = 0
if (writeit) {
   set_option("audio_off")
   set_option("clobber_on")
   rtoutput("VOCODE3.snd", "sun", "float")
}

outskip = 0.0
amp = 1.20
responsetime = 0.5

file1 = stringify("a_stereo_file.snd")
file2 = stringify("another_stereo_file.snd")

/* analysis file */
rtinput(file1)
dur = DUR()
analinskip = 0.0

/* excitation file */
excitationfile(file2)
exinskip = 0.0

makegen(2, 2, 10, 0)
100, 200, 300, 400, 500, 600, 700, 800, 900, 1000

usegen = 0           /* toggle this to try the two cf specification methods */
if (usegen) {
   numfilts = 0
   lowestcf = 1.02   /* actually, transposition of gen freqs */
   bwpct = 0.05
}
else {
   numfilts = 10
   lowestcf = cpspch(7.07)
   interval = 0.07
   spacemult = cpspch(interval) / cpspch(0.0)
   bwpct = 0.04
}

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

chan = 0
VOCODE(outskip, analinskip, dur, amp, numfilts, lowestcf, spacemult,
       bwpct, responsetime, exinskip, chan, chan, spread=1)
chan = 1
VOCODE(outskip, analinskip, dur, amp, numfilts, lowestcf, spacemult,
       bwpct, responsetime, exinskip, chan, chan, spread=0)