Eastman Csound Tutorial
Table of Contents CHAPTER 1 -- CHAPTER 2 -- CHAPTER 3 -- CHAPTER 4 -- CHAPTER 5 -- CHAPTER 6

APPENDIX 2

Extensions to F.M. Procedures : Multiple Carrier and Modulator Algorithms

Our survey of Csound unit generators and of synthesis algorithms is necessarily at an introductory level. More sophisticated implementations of many of these procedures are possible, and sometimes are necessary to achieve desired results. To illustrate somewhat more advanced applications of some basic procedures we have examined, we will look at two extensions to "classical" frequency modulation technique. Both of these extensions can be applied to amplitude modulation techniques as well.

"Simple" F.M., in which a carrier sine wave is phase modulated by another sine wave, is but one of many possible available waveshaping techniques, in which one or more periodic control signals are applied to a waveform, reshaping it over time, and thereby varying the frequency spectrum and resulting timbre. Frequency modulation is conceptually fairly simple and computationally very efficient, but also suffers from several limitations. These include :

  1. the symmetry of the upper and lower sidebands around the carrier: (natural acoustic sounds rarely produce such sym- metry in spectral components)
  2. the limited number of significant frequency components produced by any given modulation index;
  3. difficulties in band-limiting upper sidebands to avoid aliasing; and, most importantly,
  4. frequent inability to create particular frequency and amplitude ratios with sufficient precision. With F.M., one must often settle for ball-park approximations, and hope to "like what we get" rather than "getting what we want."

Various alternative waveshaping procedures have been devised and implemented to address some of these problems.

For some examples, see the discussions of gen13, gen14 and gen15 in the the Csound reference manual, and articles by such authors as Marc LeBrun, Daniel Arfib and J. A. Moorer in back issues of Computer Music Journal and the yearly Proceedings of the International Computer Music Conference. For a good introductory article on alternative waveshaping techniques see "A Tutorial on Nonlinear Distortion or Waveshaping Synthesis" by Curtis Roads, on pages 83-94 in Foundations of Computer Music, edited by Roads and Strawn.

In addition, various types of extensions to "classical" F.M. have been explored, by John Chowning, Barry Truax and many others, Chowning's "vocal" F. M. timbres, for example, include front-end programs to calculate modulation indices, so that frequencies in pre-defined formant regions will be emphasized, regardless of fundamental frequency. The most widely used extensions to classical F.M., however, involve :

  1. The use of two or more carrier oscillators, each with its own modulator(s) and index envelope, which produce different portions of a complex timbral spectrum. For example, one carrier might produce lower frequency components within a timbral spectrum, the other carrier higher frequencies. Or the two carriers could receive similar arguments, but be detuned slightly.
  2. The use of two, three or more modulating oscillators, all modulating a single carrier. In this case, sets of upper and lower sidebands are created for every combination of modulating and carrier frequencies. Because so many sidebands are generated, modulation indices are usually much lower than in "simple" F.M. synthesis algorithms.
    The article "The Simulation of Natural Instrument Tones Using Frequency Modulation with a Complex Modulating Wave" by Bill Schottstaedt , reprinted in Foundations of Computer Music, edited by Roads and Strawn, provides pertinent technical and background information on these two procedures.

    This appendix provides an example of each of these procedures in Csound code. Soundfile example exapp2-1 was created by means to the following double-carrier instrument:

  ;  #############################################################
  ;  soundfile exapp2-1  : Double carrier F.M. instrument with formant
  ;  #############################################################
  Orchestra file used to create this soundfile:

  ; fm instrument with 2 carriers
;  NORMALLY THIS WOULD BE A MONO INSTRUMENT. THE TWO CARRIER OUTPUTS
; ARE SENT TO THE LEFT AND RIGHT CHANNELS IN THIS EXAMPLE ONLY SO THAT THE
; OUTPUT OF EACH CARRIER CAN BE HEARD INDIVIDUALLY. TO HEAR THE 2 CHANNELS
; (CARRIERS) INDIVIDUALLY, MOVE THE BALANCE POT BACK ON THE CS-115 BACK &
; FORTH BETWEEN LEFT & RIGHT CHANNEL OUTPUTS
  ; p-fields :
  ; p3 = duration ;  p4 = pitch        ;p5  = amplitude   ;p6 = attack time
  ; p7 = decay time  ; p8 = atss       ;p9 = rise function
  ; FM p-fields :
  ; p10  = 1st carrier freq. (*p4)  ;  p11 = 1st mod. freq. (*p4)
  ; p12  = 2nd carrier freq. (*p4)  ;  p13  2nd mod. freq. (*p4)
  ; Modulation index envelope:
  ;  p14 = opening index; p15  = index after p6; p16 = index before p7
  ; Amplitude % for 2nd carrier : p17 = opening ; p18 = after p6 ; p19 = before p7
  ; p20 = attack hardness (1. ord)

  sr = 44100
  kr = 2205
  ksmps = 20
  nchnls = 2

  instr 2
  ipitch = cpspch(p4)
  amp envlpx p5,  p6,  p3,  p7,  p9,  p8,  .005  ; amplitude envelope

  ; Random frequency deviation ( for attack noise)
   iscale =  octcps(ipitch)
   iscale =  (18-iscale) * .1     ; scalar : c4 = 1.,c5 =.9, c3 = 1.1, etc.
  k1 expseg .5*p20,  p20*p6,  .003,  p3,  .002
  k2 expseg 999,  p20*p6,  15
  krandpitch  randi  k1*ipitch ,  k2
  kpitch = ipitch + krandpitch            ; pitch

  ; Fm index:
  k2 expseg p14,p6,p15,p3-(p6+p7),p16,p7,.5*p7

  acar1 foscili amp, kpitch, p10, p11, k2, 100  ; 1st carrier
  acar2 foscili amp, kpitch, p12, p13, k2, 100  ; 2nd carrier
   ; The  2nd carrier usually produces  (usually higher frequencies)

   ; signal "kmix" is an envelope that determines the mix of the 2 carriers
  kmix expseg  p17, p6, p18, p3-(p6+p7), p19, p7, .5*p19

  ;  COMMENT The next five lines are the normal output of this algorithm :
  ;  COMMENT audio  = (kmix * acar2) + ((1-kmix) * acar1)
  ;  COMMENT afilt  reson audio , p21, p22, 1        ; provide a formant
  ;  COMMENT   ;  restore amplitude lost in filtering :
  ;  COMMENT audio balance (.5 * afilt) +( .5 * audio) , audio ; restore gain
  ;  COMMENT out audio

  ; COMMENT The following lines send the output of carrier 1 to the left channel
  ; COMMENT and the output of carrier two to the right channel, so that these
  ; COMMENT two signals can be auditioned independently
  afilt1 reson acar1, p21, p22, 1        ; formant for carrier 1
  afilt2 reson acar2, p21, p22, 1        ; same formant for carrier 2
  audio1 balance (.5 * acar1) +(.5 * afilt1) , acar1
  ;  restore gain to filtered carrier 1 & carrier 2 signals
  audio2 balance (.5 * acar2) +(.5 * afilt2) , acar2
  outs  (1. - kmix) * audio1 , kmix * audio2
  endin
  -----------------------------------------------------------


   < score11 file used to create soundfile "exapp2-1":
   * f60 0 65 5 .005 64 1. ;   <exponential rise ( envlpx rise function)
   * f70 0 65 9 .25 1. 0;      < another rise function (1st quarter of sine wave)
   * f100 0 512 10 1.;         < SINE WAVE

   i2 0 0 5;   < play  5  notes
   p3 nu 2*4/ 4.;
   p4 no b3;
   p5 7000;
   p6 nu .075/ .08/ .015/ .085/ .8;        < rise time
   p7 nu .3/ .2/ .5/ .15/ 1.1;             < decay time
   p8 nu .9/ .94/ .7/ .82/ .3;             < atss
   p9 nu 60/ 70/  60///;                   < rise function
   < f, m, parameters :
   p10 nu     1./ 1.002/ 1.996/ .998/ 1.4; < carrier 1 freq. (*p4)
   p11 nu 1.998/ .998 / 3.002/ 1.008/ 3.1; < mod. freq. for car. 1 (*p4)
   < 2nd carrier
   p12 nu 2.001/ 6.  / 3.005/ 2.003/ 1.;   < carrier 2 freq.(*p4)
   p13 nu 2.003/ 1.002/ 2.996/ .997 / 2.4; < mod. freq.for car. 2 (*p4)
   < modulation index
   p14 nu 1.7 / 3. /  1./  1.6 / .25;      < opening value
   p15 nu 1.4 / 2.2/ .8 / 1.3/  .8;        < value after p6
   p16 nu 1.1/ 1.9/  .6/  1. / 1.5;        < value before p7
   < % of amplitude of 2nd carrier
   p17 nu   .6/ .6/ .7 / .5 / .05;         < opening decimal %
   p18 nu .49/  .4/ .55/ .52/ .1;          < decimal % after p6
   p19 nu .44/ .36/  .4/  .43/ .95 ;       < % before p7
 
   p20 nu  1./ 1.2/  1. /  .9/ .5;         < attack hardness
   p21 nu 420/ 500/ 900/ 600/ 300;         < formant center freq.
   p22 nu 200/ 350/ 60/ 400/ 700;          < formant bandwidth
   end;

As noted in the comments within exapp2-1, the "normal" output of this instrument has been commented out, and replaced by code which sends the output of carrier 1 to the left channel and the output of carrier 2 to the right channel, so that the outpus of these carriers can be heard separately.

In exapp2-2, the outputs of three modulators are passed to a single carrier. If the frequency of the third modulator is set to 0 in p12, only two modulators will be used. Notice that the characteristic F.M. "signiture" ("color," or "twang") is much less apparent when multiple modulators are used than with "simple FM."

   ;  #############################################################
   ;  soundfile exapp2-2 : F.M. instrument with 2 or 3 modulators
   ;  #############################################################
   Orchestra file :

   ; Functions needed: 50 51 52 100
   ;  p6 = attack time (.001-.01) ;        p7 = % tremolo (.2 - .33)
   ;  p8 = 1st tremolo (2. - 5.);          p9 = 2nd tremolo rate
   ;  p10 = c:m1                           p11 = c:m2
   ;  p12 = c:m3                           p13 = modulation indx
   ;  p14 = function to vary tremolo rate (usually 50; also 52,51)
   ;  p15 = attack hardness        ; p16 atss for mod. indx


   sr = 22050
   kr = 2205
   ksmps = 10
   nchnls = 1

   instr 3
   ipitch = (p 4 <15 ? cpspch(p4) : p4)    ; pch or cps input
   iscale = octcps(ipitch)
   iscale = (18-iscale) * .1                 ; scalar

   ; ENVELOPE
   amp linseg 0,p6,1.,.05/p15-p6,(p15+iscale+1)/3*.56,.1*p3,.3,.15*p3,.12,.25*p3,.06,.5*p3-(.05/p15),0
   p5 = iscale * ((p15+1)/2) * p5
   amp = amp * p5

   ; TREMOLO
     k1 randi p15*.07,2.2/p15
     k2 oscil p9-p8,1/p3,p14               ;varies rate of tremolo
   ktrem oscili p7+k1*p7,p8+k2,100         ;tremolo
   ; Random Amplitude Deviation
     k1 expseg p15*.2,p15*p6,p15*.05,p3,p15*.04
   krandamp randi k1,50/p15
   amp = amp + ((ktrem+krandamp)*amp)        ;TOTAL AMPLITUDE

   ; RANDOM FREQUENCY DEVIATION
   k1 expseg p15*.9*iscale,p6,p15*.003,p3,.002
   i4 = 800/(iscale>1?iscale:(1/iscale))
   k2 expseg 750/(iscale>1?iscale:1/iscale),p6,45/iscale,p3,60/iscale
   krandpitch randi k1*.5*ipitch,k2
   kpitch = ipitch + krandpitch              ; FREQUENCY

   ; FREQUENCY  MODULATION - 3 oscillators
   kindex expseg p15,p15*iscale*.055,p15*.6,.1*p3,.3,.15*p3,.12,.25*p3,.06,.5*p3-.055,.01
   kindex = kindex * p13 * iscale            ; MODULATION INDEX
   ; modulating oscillator 1
     kmod1 = p10*kpitch
   amod1 oscili kindex * kmod1, kmod1, 100
   ; Freq. Modulation oscillator 2
     kmod2 = p11 * kpitch
   amod2 oscili kindex * kmod2, kmod2, 100
   if p12=0 goto ready
   ; Freq. Modulation oscillator 3
       kmod3 = p12 * kpitch
       amod3 oscili kindex * kmod3, kmod3, 100
    amod2 = amod2+amod3

   ready:
   kdepth expon  p15, p3, iscale * p16 * p13      ; modulation depth
   a1 oscili amp, kpitch + (kdepth*(amod1+amod2)), 100  ; carrier

   out a1
   endin
   -----------------------------------------------------------



  < score11 file used to create  "exapp2-2" : f.m. instrument with 2 or 3 modulators
  * f50 0 65 7 0 64 1.;          < linear rise
  * f52 0 65 7 0 32 1. 32 0;     < linear pyramid: up & down
  * f100 0 256 10 1.;            < SINE WAVE
 
  i3 0 0 3;   < play 3 notes
  p3 4.5;
  du 305.5;
  < 3 sounds : 1 is "gong-like' ; 2 is "harp-like" ; 3 is like a  high bell
  p4 no f3/  fs3/  d8;           < pch or cps
  p5 6000;
  p6 nu .005/ .017/ .008;        < rise time .003-.02
  p7  nu .2/ .11/ .35;           < tremolo %  (.1-.2 ord)
  p8 nu 5.5/ 4./ 7.;             < 1st tremolo rate  (c.6)
  p9 nu 4./ 2.5/ 3.3;            < 2nd "     "   (c. 4.5)

  p10 nu 2.7/ 3.05/ 1.05;        < c:m 1
  p11 nu 8.1/ 4.08/ 1.4;         < c:m 2
  p12 nu 11.3/ 9.15/ .65;        < c:m 3
  p13 nu .4/ .11/ .3;            < modulation index (.2-1.2 ord.)
  p14 nu 50/ 52/ 50;             < function to vary tremolo rate
  p15 nu 1.2/ .9/ 1.1;           < attack hardness(.8-1.2)
  p16 nu .1/ .2/ .3;             < index atss(c. .2 ord.)
  end;
 -----------------------------------------------------------

Eastman Csound Tutorial: End of Appendix 2

Table of Contents CHAPTER 1 -- CHAPTER 2 -- CHAPTER 3 -- CHAPTER 4 -- CHAPTER 5 -- CHAPTER 6