A FOF Synthesis Tutorial

by J. M. Clarke, University of Huddersfield

The fof synthesis generator in Csound has more parameter fields than other modules. To help the user become familiar with these parameters this tutorial will take a simple orchestra file using just one fof unit-generator and demonstrate the effect of each parameter in turn. To produce a good vocal imitation, or a sound of similar sophistication, an orchestra containing five or more fof generators is required and other refinements (use of random variation of pitch etc.) must be made. The sounds produced in these initial explorations will be much simpler and consequently less interesting but they will help to show clearly the basic elements of fof synthesis. This tutorial assumes a basic working knowledge of Csound itself. The specification of the fof unit-generator (as found in the reference section of this manual) is:

ar fof xamp, xfund, xform, koct, kband, kris, kdur,\\ kdec, iolaps, ifna, ifnb, itotdur, [iphs,\\ [ifmode]]


xamp, xfund, xform — can receive any rate (constant, control or audio)
koct, kband, kdris, kdur, kdec
— can receive only constants or control rates
iolaps, ifna, ifnb, itotdur
— must be given a fixed value at initialization
iphs, ifmode
— are optional, defaulting to 0.

The following orchestra contains a simple instrument we will use for exploring each parameter in turn. On the faster machines (DECstation, SparcStation, SGI Indigo) it will run in real time.

sr = 44100
kr = 4410
ksmps = 10

instr 1
a1 fof 15000, 200, 650, 0, 0, .003, .02, .007, 5, 1, 2, p3
out a1

It should be run with the following score:

f1 0 4096  10  1
f2  0 1024  19  .5  .5  270  .5
i1  0 3

The result is very basic. This is not surprising since we have created only one formant region (a vocal imitation would need at least five) and have no vibrato or random variation of the parameters. By varying one parameter at a time we will help the reader learn how the unit-generator works. Each of the following "variations" starts from the model. Parameters not specified remain as given.

 xamp — amplitude

The first input parameter controls the amplitude of the generator. At present our model uses a constant amplitude, this can be changed so that the amplitude varies according to a line function:

a2 linseg 0,  p3*.3,  20000,  p3*.4,  15000,  p3*.3,  0
a1 fof a2, ......(as before)...

The amplitude of a fof generator needs care. xamp does not necessarily indicate the maximum output, which can also depend on the rise pattern, bandwidth, and the presence of any "overlaps." 

xfund — fundamental frequency

This parameter controls the pitch of the fundamental of the unit generator. Starting again from the original model this example demonstrates an exaggerated vibrato:

a2 oscil 20,  5,  1
a1 fof 15000,  200+a2,  etc........

fof synthesis produces a rapid succession of (normally) overlapping excitations or granules. The fundamental is in fact the speed at which new excitations are formed and if the fundamental is very low, these excitations are heard as separate granules. In this case the fundamental is not so much a pitch as a pulse speed. The possibility of moving between pitch and pulse, between timbre and granular texture is one of the most interesting aspects of fof. For a simple demonstration try the following variation. It will be especially clear if the score note is lengthened to about 10 seconds.

a2 expseg 5,  p3*.8,  200,  p3*.2,  150
a1 fof 15000,  a2  etc........

koct — octaviation coefficient

Skipping a parameter, we come to an unusual means of controlling the fundamental: octaviation. This parameter is normally set to 0. For each unit increase in koct the fundamental pitch will drop by one octave. The change of pitch is not by the normal means of glissando, but by gradually fading out alternate excitations (leaving half the original number). Try the following (again with the longer note duration):

k1 linseg 0, p3*.1, 0, p3*.8, 6, p3*.1, 6
a1 fof 15000, 200, 650, k1, etc........

This produces a drop of six octaves; if the note is sufficiently long you should be able to hear the fading out of alternate excitations towards the end.

xform — formant frequency
— formant mode (0 = striated, non-0 = smooth)

The spectral output of a fof unit-generator resembles that of an impulse generator filtered by a band pass filter. It is a set of partials above a fundamental xfund with a spectral peak at the formant frequency xform. Motion of the formant can be implemented in two ways. If ifmode = 0, data sent to xform has effect only at the start of a new excitation. That is, each excitation gets the current value of this parameter at the time of creation and holds it until the excitation ends. Successive overlapping excitations can have different formant frequencies, creating a richly varied sound. This is the mode of the original CHANT program. If ifmode is non-zero, the frequency of each excitation varies continuously with xform. This allows glissandi of the formant frequency. To demonstrate these differences we take a very low fundamental, so that the granules can be heard separately and the formant frequency is audible not as the center frequency of a "band" but as a pitch in its own right. Compare the following in which only ifmode is changed:

a2 line 400,  p3,  800
a1 fof 15000, 5, a2, 0, 1, .003, .5, .1, 3, 1, 2, p3, 0, 0

a2 line 400,  p3,  800
a1 fof 15000, 5, a2, 0, 1, .003, .5, .1, 3, 1, 2, p3, 0, 1

In the first case, the formant frequency moves by step at the start of each excitation, whereas in the second it changes smoothly. A more subtle difference is perceived with higher fundamental frequencies. (Note that the later fof parameters were changed in this example to lengthen the excitations so that their pitch could be heard easily.)

xform also permits frequency modulation of the formant frequency. Applying FM to an already complex sound can lead to strange results, but here is a simple example:

acarr line 400, p3, 800
index = 2.0
imodfr = 400
idev = index * imodfr
amodsig oscil idev, imodfr, 1
a1 fof 15000, 5, acarr+amodsig, 0, 1, .003, .5, .1, 3, 1,  2,  p3,  0,  1

kband — formant bandwidth

kris, kdur, kdec — rise time, duration and decay time (in seconds) of the excitation envelope

These parameters control the shape and length of the fof granules. They are shaped in three segments: a rise, a middle decay, and a terminating decay. For very low fundamentals, these are perceived as an amplitude envelope, but with higher fundamentals (above 30 Hz), the granules merge together and these parameters effect the timbre of the sound. Note that these four parameters influence a new granule only at the time of its initialization and are fixed for its duration; later changes will affect only subsequent granules. We begin our examination with low frequencies.

k1 line .003, p3, .1 ; kris
a1 fof 15000, 2, 300, 0, 0, k1, .5, .1, 2, 1, 2, p3

Run this with a note length of 10 seconds. Notice how the attack of the envelope of the granules lengthens. The shape of this attack is determined by the forward shape of ifnb (here a sigmoid).

Now try changing kband:

k1 linseg 0, p3, 10 ; kband
a1 fof 15000, 2, 300, 0, k1, .003, .5, .1, 2, 1, 2, p3

Following its rise, an excitation has a built-in exponential decay and kband determines its rate. The bigger kband the steeper the decay; zero means no decay. In the above example, the successive granules had increasingly fast decays.

k1 linseg 3, p3, .003
a1 fof 15000, 2, 300, 0, 0, .003, .4, k1, 2, 1, 2, p3

This demonstrates the operation of kdec. Because an exponential decay never reaches zero, it must be terminated gracefully. kdur is the overall duration (in seconds from the start of the excitation), and kdec is the length of the terminating decay. In the above example, the terminating decay starts very early in the first granules and then becomes progressively later. Note that kband is set to zero so that only the terminating decay is evident.

In the next example, the start time of the termination remains constant, but its length gets shorter:

k1 expon .3, p3, .003
a1 fof 15000, 2, 300, 0, 0, .003, .01 + k1, k1, 2, 1, , p3

It may be surprising to find that, for higher fundamentals, the local envelope determines the spectral shape of the sound. Electronic and computer music has often shown how features of music we normally consider independent, such as pitch, timbre, rhythm, are, in fact, different aspects of the same thing. In general, the longer the local envelope segment, the narrower the band of partials around that frequency. kband determines the bandwidth of the formant region at -6dB, and kris controls the skirt width at -40dB. Increasing kband increases the local envelope's exponential decay rate, thus shortening it and increasing the —6 dB spectral region. Increasing kris (the envelope attack time)

inversely makes the —40 dB spectral region smaller.

The next example changes first the bandwidth, then the skirt width. You should be able to hear the difference.

k1 linseg 100, p3/4, 0, p3/4, 100, p3/2, 100 ; kband
k2 linseg .003, p3/2, .003, p3/4, .01, p3/4, .003 ; kris
a1 fof 15000, 100, 440, 0, k1, k2, .02, .007, 3, 1, 2, p3

In the first half of the note, kris remains constant while kband broadens, then narrows again. In the second half, kband is fixed while kris lengthens (narrowing the spectrum), then returns again.

Note that kdur and kdec don't really shape the spectrum, they simply tidy up the decay so as to prevent unwanted discontinuities which would distort the sound. For vocal imitations these parameters are typically set at .017 and .007 and left unchanged. With high ("soprano") fundamentals it is possible to shorten these values and save computation time (reduce overlaps).

iolaps — number of overlap spaces

Granules are created at the rate of the fundamental frequency, and new granules are often created before earlier ones have finished, resulting in overlaps. The number of overlaps at any one time is given by xfund * kdur. For a typical bass note the calculation might be 200 * .018 = 3.6, and for a soprano note 660 * .015 = 9.9. fof needs at least this number (rounded up) of spaces in which to operate. The number can be over-estimated at no computation cost, and at only a small space cost. If there are insufficient overlap spaces during operation, the note will terminate.

ifna, ifnb — stored function tables

Identification numbers of two function tables (see the fof entry).

itotdur — total duration within which all granules in a note must be completed

So that incomplete granules are not cut off at the end of a note fof will not create new granules if they will not be completed by the time specified. Normally, given the value p3 (the note length), this parameter can be changed for special effect; fof will output zero after time itotdur.

iphs — initial phase (optional, defaulting to 0).

Specifies the initial phase of the fundamental. Normally zero, but giving different fof generators different initial phases can be helpful in avoiding "zeros" in the spectrum.