


                             - 52 -





                         4. GEN ROUTINES





     The GEN subroutines are function-drawing  procedures  called
by  f statements to construct stored wavetables.  They are avail-
able throughout orchestra performance, and can be invoked at  any
point  in  the  score as given by p2.  p1 assigns a table number,
and p3 the table size (see f statement).  p4  specifies  the  GEN
routine to be called;  each GEN routine will assign special mean-
ing to the pfield values that follow.



GEN01, GEN02

Transfer data from a soundfile (GEN01) or from immediate  pfields
(GEN02) into a function table.

      f  #  time  size  1  filno  skiptime  format
      f  #  time  size  2  v1  v2  v3  .  .  .

size - number of points in the table.  Must be a power of 2 or  a
power-of-2  plus  1  (see f statement).  The maximum tablesize is
16777216 (2**24) points.

filno,  skiptime,  format  -   directs   GEN01   to   read   from
soundin.filno,  beginning at skiptime seconds into the file.  The
parameter format specifies the audio data-file format:
      1  -  8-bit signed character        4  -  16-bit short integers
      2  -  8-bit A-law bytes       5  -  32-bit long integers
      3  -  8-bit U-law bytes       6  -  32-bit floats
If format = 0 the sample  format  is  taken  from  the  soundfile
header,  or  by  default  from  the  csound -o command flag.  The
soundfile is assumed to be in the directory SFDIR (see also soun-
din).   Reading  stops  at end-of-file or when the table is full.
Any table locations not filled will contain zeros.

v1, v2, v3, ...  - for GEN02 these values will be copied directly
into  the  table  space.   The number of values is limited by the
compile-time variable PMAX, which controls  the  maximum  pfields
(currently  150).   The values copied may include the table guard
point; any table locations not filled will contain zeros.

Note:

If p4 is positive, the table will be post-normalized (rescaled to
a  maximum  absolute value of 1 after generation).  A negative p4
will cause rescaling to be skipped.



                        February 20, 1991





                             - 53 -


Example:

f  1  0  16  -2  0  1  2  3  4  5  6  7  8  9  10  11  0

This calls upon GEN02 to place 12 values plus an  explicit  wrap-
around  guard value into a table of size next-highest power of 2.
Rescaling is inhibited.


















































                        February 20, 1991





                             - 54 -


GEN03

This subroutine generates a stored function table by evaluating a
polynomial  in x over a fixed interval and with specified coeffi-
cients.

      f  #  time  size  3  xval1  xval2  c0  c1  c2  .  .  .  cn

size - number of points in the table.  Must be a power of 2 or  a
power-of-2 plus 1 (see f statement).

xval1, xval2 - left and right values of the x interval over which
the  polynomial  is  defined (xval1 < xval2).  These will produce
the 1st stored value and the (power-of-2 plus 1)th  stored  value
respectively in the generated function table.

c0, c1, c2, .... cn - coefficients of the nth-order polynomial

              c0 + c1x + c2x
                            2
                              + c3x
                                   3
                                     +  . . .  + cnx
                                                    n


Coefficients may be positive or negative real  numbers;   a  zero
denotes  a  missing term in the polynomial.  The coefficient list
begins in p7, providing an upper limit of 44 terms.


Note:

The defined segment [fn(xval1),fn(xval2)] is evenly  distributed.
Thus  a  512-point  table  over the interval [-1,1] will have its
origin at location 257 (at the start of the 2nd half).   Provided
the extended guard point is requested, both fn(-1) and fn(1) will
exist in the table.

GEN03 is useful in conjunction with table  or  tablei  for  audio
waveshaping (sound modification by non-linear distortion).  Coef-
ficients to produce a particular formant from a sinusoidal lookup
index  of known amplitude can be determined at preprocessing time
using algorithms such as Chebyshev formulae.  See also GEN13.


Example:

      f  1  0  1025  3  -1  1  5  4  3  2  1

This calls GEN03 to fill a table  with  a  4th  order  polynomial
function  over the x-interval -1 to 1.  The origin will be at the
offset position 512.  The function is post-normalized.










                        February 20, 1991





                             - 55 -


GEN04

This subroutine generates a normalizing function by examining the
contents of an existing table.

      f  #  time  size  4  source#  sourcemode

size - number of points in the table.  Should be power-of-2  plus
1.   Must  not  exceed (except by 1) the size of the source table
being examined; limited to just half that size if the  sourcemode
is of type offset (see below).

source# - table number of stored function to be examined.

sourcemode - a coded value, specifying how the source table is to
be  scanned  to  obtain the normalizing function.  Zero indicates
that the source is to be scanned from left  to  right.   Non-zero
indicates  that the source has a bipolar structure; scanning will
begin at the mid-point and progress outwards, looking at pairs of
points equidistant from the center.


Note:

The normalizing function derives from  the  progressive  absolute
maxima  of  the  source  table  being  scanned.  The new table is
created left-to-right, with stored values  equal  to  1/(absolute
maximum  so  far  scanned).   Stored  values will thus begin with
1/(first value scanned), then get progressively  smaller  as  new
maxima  are  encountered.  For a source table which is normalized
(values <= 1), the derived values will range from 1/(first  value
scanned)  down  to  1.   If the first value scanned is zero, that
inverse will be set to 1.

The normalizing function from GEN04 is not itself normalized.

GEN04 is useful for scaling a table-derived signal so that it has
a  consistent peak amplitude.  A particular application occurs in
waveshaping when the carrier (or indexing) signal  is  less  than
full amplitude.


Example:

      f  2  0  512  4  1  1

This creates a normalizing function for use  in  connection  with
the GEN03 table 1 example.  Midpoint bipolar offset is specified.









                        February 20, 1991





                             - 56 -


GEN05, GEN07

These subroutines are used to construct functions  from  segments
of exponential curves (GEN05) or straight lines (GEN07).

      f #  time  size  5  a  n1  b  n2  c  .  .  .
      f #  time  size  7  a  n1  b  n2  c  .  .  .

size - number of points in the table.  Must be a power  of  2  or
power-of-2 plus 1 (see f statement).

a, b, c, etc. - ordinate values, in odd-numbered pfields p5,  p7,
p9,  ...   For  GEN05 these must be non-zero and must be alike in
sign.  No such restrictions exist for GEN07.

n1, n2, etc. - length of segment (no. of storage  locations),  in
even-numbered  pfields.   Cannot be negative, but a zero is mean-
ingful for specifying discontinuous waveforms (e.g. in the  exam-
ple  below).  The sum n1 + n2 + .... will normally equal size for
fully specified functions.  If the sum is smaller,  the  function
locations  not  included  will  be  set  to  zero;  if the sum is
greater, only the first size locations will be stored.


Note:

If p4 is positive, functions are post-normalized (rescaled  to  a
maximum  absolute  value  of  1 after generation).  A negative p4
will cause rescaling to be skipped.

Discrete-point  linear  interpolation  implies  an  increase   or
decrease  along  a  segment by equal differences between adjacent
locations; exponential interpolation implies that the progression
is  by  equal ratio.  In both forms the interpolation from a to b
is such as to assume that the value b will be attained in the n+1
th  location.   For  discontinuous functions, and for the segment
encompassing the end location, this value will  not  actually  be
reached,  although  it may eventually appear as a result of final
scaling.




Example:

f  1  0  256  7  0  128  1  0  -1  128  0

This describes a single-cycle  sawtooth  whose  discontinuity  is
mid-way in the stored function.








                        February 20, 1991





                             - 57 -


GEN06

This subroutine will generate a function comprised of segments of
cubic  polynomials,  spanning  specified  points  just three at a
time.

      f  #  time  size  6  a  n1  b  n2  c  n3  d  .  .  .

size - number of points in the table.  Must be a power  of  2  or
power-of-2 plus 1 (see f statement).

a, c, e ... - local maxima  or  minima  of  successive  segments,
depending on the relation of these points to adjacent inflexions.
May be either positive or negative.

b, d, f ... - ordinate values of points of inflexion at the  ends
of successive curved segments.  May be positive or negative.

n1, n2, n3 ...  -  number  of  stored  values  between  specified
points.   Cannot be negative, but a zero is meaningful for speci-
fying discontinuities.  The sum n1 + n2 + ... will normally equal
size for fully specified functions. (for details, see GEN05).



Note:

GEN06 constructs a stored function from segments of cubic polyno-
mial  functions.   Segments  link ordinate values in groups of 3:
point of inflexion, maximum/minimum,  point  of  inflexion.   The
first  complete  segment  encompasses b,c,d and has length n2+n3,
the next encompasses d,e,f and has length n4+n5, etc.  The  first
segment  (a,b with length n1) is partial with only one inflexion;
the last segment may be  partial  too.   Although  the  inflexion
points  b,d,f..  each  figure  in  two  segments (to the left and
right), the slope of the two segments remains independent at that
common  point (i.e. the 1st derivative will likely be discontinu-
ous).  When a,c,e... are alternately  maximum  and  minimum,  the
inflexion joins will be relatively smooth;  for successive maxima
or successive minima the inflexions will be comb-like.



Example:

f  1  0  65  6  0  16  .5  16  1  16  0  16  -1

This creates a curve running 0 to 1 to -1, with a  minimum,  max-
imum and minimum at these values respectively.  Inflexions are at
.5 and 0, and are relatively smooth.







                        February 20, 1991





                             - 58 -


GEN08

This subroutine will generate a piecewise cubic spline curve, the
smoothest possible through all specified points.

      f #  time  size  8  a  n1  b  n2  c  n3  d  .  .  .

size - number of points in the table.  Must be a power  of  2  or
power-of-2 plus 1 (see f statement).

a, b, c ... ordinate values of the function.

n1, n2, n3 ... length of each segment measured in stored  values.
May not be zero, but may be fractional.  A particular segment may
or may not actually store any values; stored values will be  gen-
erated  at  integral  points  from the beginning of the function.
The sum n1 + n2 + ... will normally equal "size" for fully speci-
fied functions.


Note:

GEN08 constructs a stored table from segments of cubic polynomial
functions.   Each  segment  runs between two specified points but
depends as well on their neighbors  on  each  side.   Neighboring
segments  will  agree  in  both  value  and slope at their common
point. (The common slope is that of a parabola through that point
and  its  two neighbors).  The slope at the two ends of the func-
tion is constrained to be zero (flat).

Hint: to make a discontinuity in slope or value in  the  function
as stored, arrange a series of points in the interval between two
stored values;  likewise for a non-zero boundary slope.



Examples:

f  1  0  65  8  0  16  0  16  1  16  0  16  0

This example creates a curve with a smooth hump  in  the  middle,
going briefly negative outside the hump then flat at its ends.


f  2  0  65  8  0  16  0  .1  0  15.9  1  15.9  0  .1  0  16  0

This example is similar, but does not go negative.










                        February 20, 1991





                             - 59 -


GEN09, GEN10

These  subroutines  generate  composite  waveforms  made  up   of
weighted  sums  of  simple  sinusoids.  The specification of each
contributing partial requires 3 pfields using GEN09  but  just  1
using GEN10.

      f #  time  size   9   pna  stra  phsa   pnb  strb  phsb  .  .  .
      f #  time  size  10  str1  str2  str3  str4  .  .  .  .

size - number of points in the table.  Must be  a power of  2  or
power-of-2 plus 1 (see f statement).

pna, pnb, etc. - partial no.  (relative  to  a  fundamental  that
would occupy size locations per cycle) of sinusoid a, sinusoid b,
etc.  Must be positive, but need not be  a  whole  number,  i.e.,
non-harmonic  partials  are  permitted.   Partials  may be in any
order.

stra, strb, etc. - strength of partials pna, pnb, etc.  These are
relative strengths, since the composite waveform will be rescaled
later.  Negative values are permitted  and  imply  a  180  degree
phase shift.

phsa, phsb, etc. - inital  phase  of  partials  pna,  pnb,  etc.,
expressed in degrees.

str1, str2, str3, etc. - relative strengths of the fixed harmonic
partial  numbers  1,2,3,etc.,  beginning  in  p5.   Partials  not
required should be given a strength of zero.


Note:

Both subroutines generate stored functions as sums  of  sinusoids
of different frequencies.  The two major restrictions on GEN10 --
that the partials be harmonic and in phase --  do  not  apply  to
GEN09.

In either case the composite wave, once drawn, is  then  rescaled
to  unity if p4 was positive.  A negative p4 will cause rescaling
to be skipped.



Example:

f  1  0  512  9  1  3  0  3  1  0  9  .3333  180

This combines partials 1, 3 and 9 in the relative strengths  with
which they are present in a square wave, except that partial 9 is
"upside down."





                        February 20, 1991





                             - 60 -


GEN11

This subroutine generates an additive set of cosine partials,  in
the manner of csound generators buzz and gbuzz.

      f  #  time  size  11  nh  lh  r

size - number of points in the table.  Must be a power  of  2  or
power-of-2 plus 1 (see f statement).

nh - number of harmonics requested.  Must be positive.

lh (optional) - lowest harmonic partial present.   Can  be  posi-
tive,  zero  or  negative.   The set of partials can begin at any
partial number and proceeds upwards;  if lh is negative, all par-
tials  below  zero  will reflect in zero to produce positive par-
tials without phase change (since cosine is  an  even  function),
and  will add constructively to any positive partials in the set.
The default value is 1.

r (optional) - multiplier in  an  amplitude  coefficient  series.
This  is a power series: if the lhth partial has a strength coef-
ficient of A, the (lh+n)th partial will have a coefficient of A *
r**n, i.e.  strength values trace an exponential curve.  r may be
positive, zero or negative, and is not  restricted  to  integers.
The default value is 1.


Note:

This subroutine is a non-time-varying version of the csound  buzz
and  gbuzz generators, and is similarly useful as a complex sound
source in subtractive synthesis.  With lh and r present it paral-
lels  gbuzz;   with  both absent or equal to 1. it reduces to the
simpler buzz (i.e. nh equal-strength harmonic partials  beginning
with the fundamental).

Sampling the stored waveform with an oscillator is more efficient
than  using dynamic buzz units.  However, the spectral content is
invariant, and care is necessary lest the higher partials  exceed
the Nyquist during sampling to produce foldover.



Examples:

f  1  0  2049  11  4
f  2  0  2049  11  4  1  1
f  3  0  2049 -11  7  3  .5

The first two tables will contain  identical  band-limited  pulse
waves of four equal-strength harmonic partials beginning with the
fundamental.  The third table will sum seven  consective  harmon-
ics,  beginning  with  the  third,  and  at  progressively weaker
strengths  (1,  .5,  .25,  .125  ...).   It  will  not  be  post-


                        February 20, 1991





                             - 61 -


normalized.
























































                        February 20, 1991





                             - 62 -


GEN12

This generates the log of  a  modified  Bessel  function  of  the
second kind, order 0, suitable for use in amplitude-modulated FM.

      f  #  time  size  -12  xint

size - number of points in the table.  Must be a power of 2 or  a
power-of-2  plus 1 (see f statement).  The normal value is power-
of-2 plus 1.

xint - specifies the x interval [0 to +xint] over which the func-
tion is defined.


Note:

This subroutine draws the natural log of a modified Bessel  func-
tion of the second kind, order 0 (commonly written as I subscript
0), over the x-interval requested.  The call should have  rescal-
ing inhibited.

The function is useful as an amplitude scaling factor  in  cycle-
synchronous  amplitude-modulated  FM.  (See Palamin & Palamin, J.
Audio Eng. Soc., 36/9, Sept. 1988, pp. 671-684.)   The  algorithm
is interesting because it permits the normally symmetric FM spec-
trum to be made asymmetric around a frequency other than the car-
rier,  and is thereby useful for formant positioning.  By using a
table lookup index of I(r - 1/r), where I is  the  FM  modulation
index  and  r  is  an  exponential  parameter  affecting  partial
strengths, the Palamin algorithm  becomes  relatively  efficient,
requiring only oscil's, table lookups, and a single exp call.


Example:

f  1  0  2049  -12  20

This draws an unscaled ln(I0(x)) from 0 to 20.


















                        February 20, 1991





                             - 63 -


GEN13, GEN14

These subroutines use Chebyshev coefficients to  generate  stored
polynomial  functions  which,  under  waveshaping, can be used to
split a sinusoid into harmonic  partials  having  a  predefinable
spectrum.

      f  #  time  size  13  xint  xamp  h0  h1  h2  . . . hn
      f  #  time  size  14  xint  xamp  h0  h1  h2  . . . hn

size - number of points in the table.  Must be a power of 2 or  a
power-of-2  plus 1 (see f statement).  The normal value is power-
of-2 plus 1.

xint - provides the left and right values [-xint,+xint] of the  x
interval over which the polynomial is to be drawn.  These subrou-
tines both call GEN03 to draw their functions; the p5 value  here
is  therefor  expanded  to  a negative-positive p5,p6 pair before
GEN03 is actually called.  The normal value is 1.

xamp - amplitude scaling factor of the  sinusoid  input  that  is
expected to produce the following spectrum.

h0, h1, h2, .... hn - relative strength of  partials  0  (DC),  1
(fundamental),  2  ... that will result when a sinusoid of ampli-
tude xamp * int(size/2)/xint is waveshaped  using  this  function
table.   These  values thus describe a frequency spectrum associ-
ated with a particular factor xamp of the input signal.


Note:

GEN13 is the function generator  normally  employed  in  standard
waveshaping.   It  stores  a polynomial whose coefficients derive
from the Chebyshev polynomials of the first kind, so that a driv-
ing sinusoid of strength xamp will exhibit the specified spectrum
at output. Note that the evolution of this spectrum is  generally
not  linear  with  varying xamp.  However, it is bandlimited (the
only partials to appear will be  those  specified  at  generation
time);   and  the  partials  will tend to occur and to develop in
ascending order (the lower partials dominating at low  xamp,  and
the  spectral  richness increasing for higher values of xamp).  A
negative hn value implies a 180 degree phase shift of  that  par-
tial;  the requested full-amplitude spectrum will not be affected
by this shift, although the evolution of several of its component
partials  may  be.   The pattern +,+,-,-,+,+, ... for h0,h1,h2...
will minimize the normalization problem for low xamp values  (see
above), but does not necessarily provide the smoothest pattern of
evolution.

GEN14 stores a polynomial whose  coefficients  derive  from  Che-
byshevs of the second kind.


Example:


                        February 20, 1991





                             - 64 -


f  1  0  1025  13  1  1  0  5  0  3  0  1

This creates a function which, under waveshaping,  will  split  a
sinusoid into 3 odd-harmonic partials of relative strength 5:3:1.





















































                        February 20, 1991





                             - 65 -


GEN15

This subroutine creates two tables  of  stored  polynomial  func-
tions, suitable for use in phase quadrature operations.

      f  #  time  size  15  xint  xamp  h0  phs0  h1  phs1  h2  phs2 . .

size - number of points in the table.  Must be a power of 2 or  a
power-of-2  plus 1 (see f statement).  The normal value is power-
of-2 plus 1.

xint - provides the left and right values [-xint,+xint] of the  x
interval  over which the polynomial is to be drawn.  This subrou-
tine will eventually call GEN03 to draw both functions;  this  p5
value  is  therefor  expanded  to  a negative-positive p5,p6 pair
before GEN03 is actually called.  The normal value is 1.

xamp - amplitude scaling factor of the  sinusoid  input  that  is
expected to produce the following spectrum.

h0, h1, h2, .... hn - relative strength of  partials  0  (DC),  1
(fundamental),  2  ... that will result when a sinusoid of ampli-
tude xamp * int(size/2)/xint is waveshaped  using  this  function
table.   These  values thus describe a frequency spectrum associ-
ated with a particular factor xamp of the input signal.

phs0, phs1, ... - phase in degrees of desired harmonics  h0,  h1,
...   when the two functions of GEN15 are used with phase quadra-
ture.





Note:

GEN15 creates two tables of equal size, labelled f # and  f  #+1.
Table  #  will  contain  a  Chebyshev function of the first kind,
drawn   using   GEN13   with   partial   strengths   h0cos(phs0),
h1cos(phs1),  ...  Table #+1 will contain a Chebyshev function of
the  2nd  kind  by  calling  GEN14  with  partials   h1sin(phs1),
h2sin(phs2),  ...   (note  the  harmonic  displacement).  The two
tables can be used in conjunction in a waveshaping  network  that
exploits phase quadrature.













                        February 20, 1991


