NEXT CHAPTER (Chapter 5) -- Table of Contents CHAPTER 1 -- CHAPTER 2 -- CHAPTER 3 -- CHAPTER 4 -- CHAPTER 5 -- CHAPTER 6 -- APPENDIX 1 -- APPENDIX 2
[ See the discussion of BUZZ and GBUZZ in the Csound reference manual ]
buzz and gbuzz can be used in place of oscillators in situations where we wish to create audio signal waveforms with exactly harmonic partials.[1] In the case of buzz, these harmonics will be equal in amplitude, and the lowest frequency will be the fundamental.
[1] Advanced users also may wish to investigate gen11. Functions created with gen11 produce similar waveforms, and can be read by standard oscillators.
The arguments to buzz are :
Like oscillators, buzz requires an audio function table in the score. This function must be a sine wave, and a large table size is recommended. (The Csound manual suggests 8192 points, although I generally have found little audible difference when using smaller table sizes, such as 4096 or 2048.) Below is a sample orchestra and score, in which the number of harmonics increases from 3 to 50 (p5). To see the five waveforms while playing the soundfile, turn the oscilloscope on and turn up the intensity. (The oscilloscope may also be useful to you in "looking at" waveforms produced by your own instruments.) Be sure to turn the intensity knob down (counterclockwise) when you are done.
; ######################################################## ; soundfile ex4-1 : buzz Csound Tutorial ; ####################################################### ; Orchestra file used to create this soundfile example: ----------------------------------------------------------- sr = 44100 kr = 2205 ksmps = 20 nchnls = 1 instr 1 kamp expseg 1, .2, 8000, p3-.4, 5000, .2, 1 ipitch = cpspch(p4) a1 buzz kamp, ipitch , p5, 1 out a1 endin ----------------------------------------------------------- < score11 file used to create soundfile example "ex4-1" : *f1 0 8192 10 1.; < large sine wave table for buzz i1 0 0 5; p3 rh 4; p4 no a3; p5 nu 3/ 10/ 20/ 35/ 50; < number of harmonics end; -----------------------------------------------------------
Appendix Csound score file examples : Chapter 4
When you hear the result, you will know why the unit generator is called "buzz." You may also wonder, "Why bother with this thing?". In fact, the output of buzz is usually filtered, or otherwise post-processed, to produce a timbre with greater musical interest than we hear in this didactic example.
Like buzz, gbuzz produces an audio waveform consisting of (exactly) harmonic partials. However, gbuzz provides us with greater control over this set of harmonics. Whereas buzz will always produce harmonics of equal strength, beginning with the fundamental, gbuzz enables us to specify both the lowest harmonic number (which need not be the fundamental), and a "brightness factor" (kr). The arguments to gbuzz are :
Here's a simple orchestra and score, in which all of the input arguments to gbuzz remain fixed throughout each note:
; ############################################################# ; soundfile ex4-2 : gbuzz Csound Tutorial ; ############################################################# sr = 44100 kr = 2205 ksmps = 20 nchnls = 1 instr 1 kamp expseg 1, .2, 8000, p3-.4, 5000, .2, 1 ipitch = cpspch(p4) a1 gbuzz kamp, ipitch, p5, p6, p7, 1 out a1 endin --------------------------------------------------------- < score11 file used to create soundfile "ex4-2" : * f1 0 4096 9 1 1 90; < gbuzz audio function i1 0 0 5; p3 rh 4; p4 no a3; p5 16; < knh ( # of harmonics) p6 1; < klh lowest harmonic # (1 = fundamental) p7 nu 1./ 2./ .5/ 5./ .2; < kr (brightness) end; -----------------------------------------------------------
In determining the number of harmonics to use with buzz or gbuzz, one must consider the sampling rate, the fundamental frequency, and number of harmonics, and exercise care that the highest harmonics specified do not exceed the Nyquist frequency and alias. To relieve ourselves of these bookeeping duties, we might build a subroutine into our algorithm that provides the maximum number of harmonics below the Nyquist frequency, as in the next example. This example also includes a simple envelope to vary the kr argument to gbuzz (and thus the brightness of the timbre) within each note:
; ############################################################# ; soundfile ex4-3 : gbuzz : variable kr Csound Tutorial ; ############################################################# Orchestra file used to create this soundfile: ----------------------------------------------------------- 1 sr = 44100 2 kr = 2205 3 ksmps = 20 4 nchnls = 1 5 instr 1 6 kamp expseg 1, .2, 8000, p3-.4, 5000, .2, 1 ; amplitude envelope 7 ipitch = cpspch(p4) 8 kbright expon p6, p3, p7 ; envelope of gbuzz timbral brightness 9 iharmonics = int((.5 * sr) / ipitch) 10 ; "iharmonics" returns the maximum number of harmonics below Nyquist 11 print ipitch, iharmonics ; print these values in the sterr output 12 a1 gbuzz kamp, ipitch, iharmonics, p5, kbright, 1 13 out a1 14 endin ----------------------------------------------------------- < score11 file for ex4-3 * f1 0 4096 9 1 1 90; < gbuzz audio function i1 0 0 8; p3 rh 2; p4 no c3*4/ d6*4; p5 1; < lowest harmonic (1=fundamental) p6 nu .05/ .99/ .3/ 1.2/ < kr1 ( brightness at beginning of note) .05/ .99/ .01/ 2.; p7 nu .9/ .1/ 1.3/ .5/ < kr2 ( brightness at end of note) .9/ .1/ 2. / .1; end; -----------------------------------------------------------
Comments on ex4-3 : On line 9 we have created a variable called iharmonics, which returns the maximum number of harmonics below the Nyquist frequency for the pitch specified in p4. First, we divide the Nyquist frequency (.5*SR, or, here, 22050) by the fundamental frequency (ipitch). For the first four notes (c3) the fundamental is 130.8 herz. For the next four notes (d6) it is 1174.65 herz. The first step of this operation, then, gives the following values:
formula : .5*SR / ipitch result notes 1-4 (c3) : 22050 / 130.8 168.577 notes 5-8 (d6) : 22050 / 1174.65 18.771
The value converter int then returns only the integer portion of these values (168 and 18), and assigns this integer to the variable iharmonics. Since we may be curious as to how many harmonics will result for different notes, we include a call to unit generator print on line 11, to print out (within the sterr message) the values ipitch and iharmonics for each note.
Since the c3 notes have many more harmonics than the d6 notes, the changes in kr (and thus in timbre) are much more noticeable, even though we have exaggerated the difference between the first and second kr envelope values for the last two notes.
kr values greater than "1." generally will produce buzzy, "steely-edged" or "brittle-sounding" timbres. In our orchestra, low pitched tones will include many harmonics. In fact, at high sampling rates (such as the customary 44.1 k rate in our example orchestra file), the formula on line 9 probably will produce more harmonics than we want or need, including frequencies (between about 15 kHz and 22.05 kHz) that exceed our range of hearing. Therefore, we might wish to modify this iharmonics formula, perhaps limiting the number of harmonics to a maximum of 30, like this:
Alternatively, we might band-limit the harmonics, so that no frequency exceeds 8000 herz :
Perhaps you remain unimpressed with the timbral possibilities of gbuzz. Our final gbuzz example, ex4-4, is more fun. The fundamental frequency is very low. In fact, it is below the audible range for the first two notes. The lowest harmonic is not the fundamental, and glissandos have been included.
; ############################################################# ; soundfile ex4-4 : gbuzz : sub-audio fundamental & glissando ; ############################################################# Orchestra file used to create this soundfile : sr = 44100 kr = 4410 ksmps = 10 nchnls = 1 instr 1 amp expseg 1,.2*p3,8000,.7*p3,3000,.3*p3,1 ; amplitude envelope ; glissando : ipitch1 = (p4 > 0 ? cpspch(p4) : abs(p4)) ; negative values = cps ipitch2 = (p5 > 0 ? cpspch(p5) : abs(p5)) ; negative values = cps kgliss expseg ipitch1 ,.2*p3, ipitch1, .6*p3, ipitch2, .2*p3, ipitch2 krenv expseg p8, .5*p3, p9, .5*p3, p8 ; gbuzz kr brightness envelope a1 gbuzz amp, kgliss, p7, p6, krenv, 1 a1 tone a1, 1500 ; filter out spurious high frequncies out a1 endin ----------------------------------------------------------- <score11 file used to create soundfile "ex4-4" : * f1 0 8192 9 1 1 90; < gbuzz audio function i1 0 0 3; p3 5.; du 304.5; p4 nu -16/ -8.5/ -53; < 1st fundmental p5 nu -14.5/ -9/ -49; < 2nd fundmental p6 nu 3/ 42/ 13; < lowest harmonic (1=fundamental) p7 nu 50/ 10/ 40; < number of harmonics p8 nu .5/ .8/ .3; < kr1 (brightness multiplier) 1 (start & end) p9 nu .9/ 1.4/ .9; < kr2 (brightness multiplier) 1 (middle) end; -----------------------------------------------------------
Comments on ex4-41 : The init variables ipitch1 and ipitch2 allow us to use "notes" for our score11 pitch input, but also, if p4 and/or p5 are negative, to use cps values. In this score, we are using cps values for both pitch levels of the glissando (negative p4 and p5 values, which are converted to positive by the value converter abs). By using subaudio or very low fundamental frequencies, here with the lower harmonics missing from the waveform, and by changing amplitude ratios for the harmonics (the krenv envelope), we can create various kinds of birdcall, motor-like, and other "humming" and "throbbing" types of timbres.
The signals produced in this example are acoustically complex. To assure maximum signal resolution, we have (1) used a high control rate (4410) ; (2) run the amplitude envelope generator at the audio rate; and (3) used a very large table (of 8192 numbers) for the gbuzz function. Still, some unwanted high frequency noise artifacts result. We have included a low-pass filter (tone, covered in Chapter 5), to reduce this unwanted debris, but a trace survives in the second "note."
[ See the discussion of RAND, RANDH and RANDI in the Csound reference manual ]
Natural sounds change in three ways :
Gradual, non-repeating changes can be created synthetically by means of envelope generators, or by oscillators that read a function once per note. Periodic changes are produced by oscillators that read a function many times. The rand family of pseudo-random number generators enable us to create aperiodic variations in amplitude, pitch, timbre, and other parameters. (Pseudo-random number generators actually create exactly the same series of numbers every time a job is run, but these numbers to not follow a perceptible pattern.)
rand is simply a white-noise generator. Its only argument is amplitude, which can vary at any rate. (An optional reseed argument is provided so that one could replace the default seed, or starting, value of .5 with any other between 0 and 1., but this would make no audible difference. The output of rand, then, is a stream of aperiodic numbers lying somewhere between +/- its current amplitude input value.
; ############################################################# ; soundfile ex4-5 : White noise Csound Tutorial ; ############################################################# Orchetsra file used to create this soundfile : ----------------------------------------------------------- sr = 22050 kr = 2205 ksmps = 10 nchnls = 1 instr 1 kenv envlpx p5, p6, p3, p7, 60, p8, .01 , p9 ; amplitude envelope ; amplitude tremolo : ktremrate line p10, p3 , p11 ; tremolo rate envelope ktremolo oscil p12 , ktremrate, 1 ; amplitude modulation signal ; add non-modulated & modulated amplitude signals kamp = ( (1. - p12) * kenv) + (ktremolo * kenv) anoise rand kamp out anoise endin ----------------------------------------------------------- < Score11 file used to create soundfile "ex4-5" : * f1 0 1024 10 1.; < sine wave, used for amplitude tremolo * f60 0 65 5 .01 64 1.; < exponential rise i1 0 0 2; p3 4; du .95; p4 0; < dummy p-field, (not used ) < amplitude envelope : p5 15000; p6 nu 1.5 / .05; < attack time p7 nu .5 / 1.5; < decay time p8 nu .3 / .05; < atss p9 nu 0 / .9; < xmod < tremolo : p10 nu 1. / 11. ; < beginning tremolo rate p11 nu 6. / 4.; < end tremolo rate p12 nu .2 / .5 ; < tremolo % end; -----------------------------------------------------------
randh and randi are similar in basic operation to rand, but with the following differences :
k1 randh 5, 10Result: A new integer value lying between +5 and -5 will be created 10 times per second. Each value will be "held" (repeated at the k-rate) for 1/10 second
a1 randi .2, .25Result: A breakpoint value between +.2 and -.2 will be generated once every 4 seconds (.25 herz). On every sample pass, a new number will be output which lies along a line connecting successive breakpoint values.
randi is particularly useful in the creation of band-limited noise, illustrated in ex4-6:
; ############################################################# ; soundfile ex4-6 : band-limited noise or frequency flutter ; ############################################################# sr = 44100 kr = 2205 ksmps = 20 nchnls = 1 instr 2 ipitch = ( p4 < 15 ? cpspch(p4) : p4) ; p4 can be in cps or pch inoisewidth = (p9 < 15 ? p9 * ipitch : p9) inoiserate = (p10 = 0 ? kr-1 : p10) ; for maximum rate, use 0 in p10 kenv envlpx p5, p6, p3, p7, 60, p8,.01 ; amplitude envelope knoise randi inoisewidth, inoiserate ; for p10 any value up to kr-1 is OK audio oscili kenv , ipitch + knoise, 100 out audio endin ----------------------------------------------------------- < Score11 file for "ex4-6" : Band limited noise < Score for ex4-6 : Band limited noise * f60 0 65 5 .01 64 1.; < exponential rise. up * f100 0 256 10 1.; < SINE WAVE < 1st note : 1.5 octave noise; 2nd note : 80 hz. noise < 3rd note : 4 % frequency "jitter" i2 0 0 3; p3 2; du .99; p4 no a4; < no pitch p5 15000; p6 .2; < attack time p7 .3; < decay time p8 .5; < atss p9 nu 1.2 / 80/ .04; < noise bandwidth ; if < 15,then = multiplier * p4 p10 nu 0/ 800/ 13; < rate of random frequency change end; -----------------------------------------------------------
Here, knoise is a band-limited stream of numbers between +/- the value the variable we have named inoisewidth. For the three notes in the score, the inoisewidth values are 660, 80 and 17.6 herz. Within the audio oscillator, this control signal is added to a base frequency of 440, herz. The resulting noise bands for the three "notes" have the following properties :
Center Highest Lowest Noise Noise Frequency Frequency Frequency Bandwidth Rate 1st note: 440 1100 -200 1100 2204 2nd note: 440 520 360 160 800 3rd note: 440 457.6 423.4 34.2 13
Note that because the random number generator outputs both positive and negative numbers within the range of its amplitude argument, we are actually specifying half-bandwidth, rather than the full noise bandwidth, in p9. This bothers some people. If it annoys you, the amplitude argument to randi could easily be changed to
so that p9 in our score will indicate the full noise bandwidth.
######################## soundfile ex4-7 : randh #######################
Soundfile example ex4-7 is identical to ex4-6 in all respects, except that in the orchestra file, randi has been replaced by randh. The audible difference is most apparent on the third note, where we now hear stepped pitch deviations.
randi is frequently used to add small random deviations to various control signals, as in the following skeletal orchestra file:
1 (orchestra header values) 2 instr 1 ;AMPLITUDE : 3 kenv envlpx --,--,--,--,--,--,-- ; amplitude envelope 4 krandamp randi .1*k1, 9 ; +/-10 % random amp. deviation 5 kamp = kenv + krandamp ; final amplitude control signal ; PITCH : 6 ipitch = cpspch(p4) ; center pitch 7 krandpitch randi .01*i1, 7. ; +/-1 % random pitch deviation 8 kpitch = ipitch + krandpitch ; final pitch control signal ; F M INDEX : 9 kindex expseg --,--,--,--,--, ; fm index envelope 10 krandindex randi .2*k4,5.5 ; +/-20 % random deviation 11 kindex = kindex + krandindex ; final index control signal 12 a1 foscili kamp, kpitch, 1, 2.005, kindex, 100 ;audio signal ; SPATIAL PLACEMENT : 13 krandspace randi .24, 4. ; random spatial movement 14 kspace = krandspace + .25 15 outs1 sqrt(kspace) * a1 ; left channel 16 outs2 sqrt(1-kspace) * a1 ; right channel 17 endin
In this example, randi control signals are created to introduce irregularities in amplitude, pitch, F.M. index, and spatial placement :
Were we to substitute randh for randi anywhere in the preceding example, the resulting stepped (rather than gradual) changes in level would be audibly more obvious. In natural sounds, random fluctuations are usually gradual rather than abrupt, but there are some musical gestures or sounds in which discontinuities can be used to good effect.
In all of the examples so far the arguments to the random number generators have been constants. It is often useful, however, to vary the amplitude and/or rate argument values by means of envelope, oscillator, or even other random signals.
The pitch of many acoustic sounds varies widely, and aperiodically, at the very onset of a tone, before gradually settling in to a quasi-periodic pattern. Many additional noise-like frequencies (associated with the scrape of the bow, the slap of the tongue against a reed, and so on) also are present during the prefix (attack) of the tone, but die away quickly. During the "steady-state" and decay, the frequency often includes much smaller random fluctuations.
To simulate the attack noise of acoustic sounds, we can create a randi control signal that begins with high input values for both amplitude (range) and rate, then reduce these values so that they level off at a much lower plateau by the end of the attack. A beginning frequency deviation of 100 % (+/- 50 %) is not uncommon for pitches around middle C or above. To produce a similar result for lower frequencies, even greater initial random deviation is necessary. (A 50 herz tone, varied randomly by +/- 50 %, will produce only a 50 herz band of noise, whereas a 440 herz tone will produce a 440 herz band of noise.)
; ############################################################# ; soundfile ex4-8 : Frequency Modulation instrument with attack noise ; ############################################################# Orchestra file used to create this soundfile: ----------------------------------------------------------- sr = 44100 kr = 2205 ksmps = 20 nchnls = 1 ; p9 = attack hardness; p10 = fm c:m ratio ; p11 = fm index instr 3 ipitch = (p4<15? cpspch(p4) : p4) ; p4 can be in cps or pch iscale = octcps(ipitch) iscale = (18-iscale)*.1 ; scalar : c4 = 1., c5 = .9, c3 = 1.1, etc. iscale = .5*iscale*p9 kamp envlpx p5, p6, p3, p7, 60, p8, .01 ; Pitch skew k1 expseg iscale, p9*p6, .005,p3-p6, .005 ; envelope for % pitch skew k2 expseg kr - 1, p9*p6, p9*30, p3-p6, 20 ; envelope for pitch skew rate knoise randi k1*ipitch, k2 ; pitch skew ; f.m. index envelope kindex expseg p9*p11, p9*p6, p11, p3-(p9*p6),.6*p11 asound foscili kamp, knoise + ipitch, 1, p10, kindex, 100 out asound endin ----------------------------------------------------------- < Score for ex4-8 : FM instrument with attack noise * f60 0 65 5 .01 64 1.; <expo. up * f100 0 256 10 1.; < SINE WAVE i3 0 0 3; p3 2; du .99; p4 no a4; < amplitude envelope : p5 15000; p6 nu .07/ .25/ .06; < attack time p7 .3; < decay time p8 nu .65/ .85/ .25; < atss < attack hardness & f.m. values : p9 nu 1./.6/1.7; < attack hardness, 1. = ord., > 1 = harder p10 1.006; < c:m ratio p11 nu 1.9/ 1./ 2.6; < f.m. index end; -----------------------------------------------------------
Similar attack hardness subroutines have been built into many of the Eastman Csound Library instruments, so that we can apply accents and other types of phrasing articulations to a series of melodic notes or chords. In this manner, a single score p-field can modify the amplitude, pitch and timbral arguments passed to audio signal generators.
Combining oscillator and randi or randh signals within a single subroutine can provide us with the means to create a control signal that lies anywhere along a continuum from total periodicity to total randomness. The cost is about six p-fields. The example below is one possible realization of such an all-purpose periodic/random control signal generator. This module could be used for the generation of tremolo, vibrato, filter bandwidth or panning signals, or for many other types of signal processing operations that might occur to you :
ALL-PURPOSE PERIODIC/RANDOM CONTROL SIGNAL GENERATOR : ; p fields : (beginning arbitrarily with p6) ; p6 = 1st value p7 = 2nd value ; p8 = rate of change between p6 & p7 ; p9 = function table number for change between p6 & p7 values ; p10 = random deviation % p11 = random deviation rate (optional p8 flags might be inserted here -- see see discussion below) kperiodic oscil p7-p6, p8, p9 ; this output is the DIFFERENCE between p6 & p7 kperiodic = kperiodic + p6 ; add this DIFFERENCE to p6 krandom randi p10 * kperiodic, p11 ; random deviation ( +/- % variance in k1) ksignal = kperiodic + krandom ; add random deviation to periodic variation ----------------------------------------------------------- Score p-fields for this module : p6 < value 1 p7 < value 2 p8 < rate of change between p1 & p2 (with optional flags) p9 < function for change between p6 & p7 p10 < random deviation % p11 < random deviation rate
With low values for p10, the resulting control signal will be mostly periodic, with small deviations. With high values for p10, the signal will be mostly random, with a smaller periodic component. When using high p10 values, however, we would frequently need to choose our p6 and p7 values carefully, so that the total signal level produced by adding the periodic and random components would not exceed "1." or "0" at any point. This would be necessary, for example, if the signal were controlling spatial placement.
Additional flag values for p8 could be included within this module to enable us to specify rates at which is the oscillator function is read in alternative formats to herz. The sub-routine below, for example, includes :
; -- optional flags for p8 rate of change -- p8 = (p8 = 0 ? 1/p3 : p8) ; if p8 is 0, the function is read once ; per note p8 = (p8>100 ? (p8-100)/p3: p8) ; if p8 is > 100, the function will be ; read p8-100 times per note ( if p8 is ; is 102.5, the function will be read 2.5 ; times per note) p8 = (p8 < 0? 1/abs(p8) : p8 ) ; if p8 is negative, it will indicate ; the PERIOD of oscillation ( if p8 = -2.5, ; the function will be read once every ; 2.5 seconds
In addition to the basic rand, randh and randi opcodes Csound also provides eleven x-class noise generators", most of which produce particular weighted distributions of pseudo-random number streams. Two additional "global" pseudo-random number opcodes, rnd and birnd, can be useful in introducing random components within init and control signals. In the following example, rnd is used to random vary the output amplitude of a series of monophonic input soundfiles, and also to vary the stereo output location:
instr 1 asample diskin p4, p5, p6 iamp = rnd(.49) + .5 ; vary output amplitude multiplier between .5 and .99 asample = asample * iamp ispace = rnd (1.) ; create random left-right stereo locations between 0 and 1. outs sqrt(ispace) * asample, sqrt(1. - ispace) * asample endin
Try out buzz and gbuzz, and the random number generators rand, randh and randi. Try adding attack chiffs, and random deviation in amplitude, pitch, panning and other variables, within one or more of your existing algorithms.
Random number generators, which are not available (or not available in sufficient quantity) on most hardware synthesizers, provide an extremely useful means of introducing added "life" and "interest" to sounds. The pitch, amplitude and timbre of most acoustic sounds include random components, typically quite large during attacks, generally much smaller during the "steady state" and decay of tones. Vibrato (especially) and tremolo tend to be much more "interesting" and "lifelike" if the modulation rate and depth include a small random component.
NEXT CHAPTER (Chapter 5) -- Table of Contents CHAPTER 1 -- CHAPTER 2 -- CHAPTER 3 -- CHAPTER 4 -- CHAPTER 5 -- CHAPTER 6 -- APPENDIX 1 -- APPENDIX 2