Table of Contents CHAPTER 1 -- CHAPTER 2 -- CHAPTER 3 -- CHAPTER 4 -- CHAPTER 5 -- CHAPTER 6 -- APPENDIX 1 -- APPENDIX 2
In this chapter we will look at
6.1 Preprocessing of orchestra and score files, illustrated primarily with the Unix m4 utilityAt some point you likely will begrudge the tedium sometimes involved in preparing Csound orchestra and score files, and wish for shortcuts and more powerful, easier-to-use tools. Preprocessing programs sometimes can provide such tools. Aleck Brinkman's score11 program is one example of a pre-processor. Advanced Csound users sometimes write their own preprocessing procgrams to simplify repetitive, complex or irksome tasks.
Ultimately, the best source of preprocessing tools is a knowledge of a high level computer programming language such as C. This enables a user to write front-end utility programs, custom tailored to her specific requirements and preferences, which generate input used by other programs, such as Csound. Unix shells themselves provide many programming commands, similar to those of C, that can be patched together within an executable shell script file to facilitate some tasks. (For examples, you might look at a few local utility scripts in /usr/local/bin that you have already used, such as pitchshift, mko or runsfcompress.)
The rub, of course, is that programming languages have a learning curve of their own, and may require a digression from from making music into the less appealing realm (for most musicians) of computer programming techniques. Obviously, a survey of C or shell script programming syntax and procedures is beyond the scope of this tutorial, and also beyond the needs of beginning users.
Instead, to illustrate a few types of preprocessing techniques employed by many advanced users, we will survey some operations that can be performed with the Unix preprocessing program m4. While rather limited, and much less powerful than a full fledged programming environment such as C, m4 has relatively few syntactic conventions, and its tools can be put to use fairly quickly, "right out of the box."
A copy of the Unix documentation on m4 is available in the SGI studio. We will survey three types of m4 operations -- define, include and conditional statements -- which, once mastered, can sometimes simplify Csound orchestra and score file preparation. In addition, these operations also can provide us with some rudimentary computer-assisted algorithmic compositional tools.
Throughout this discussion, bear in mind the distinction between the standard Unix m4 preprocessor and ECMC utilities such as m4orch, m4expand and mko that incorporate m4 operations. It is more likely that ECMC users will want to use the Eastman utility programs, which require a slightly different (and, for most of our purposes, easier-to-use) syntax than "straight" m4. In particular, the ECMC utilities substitute left and right square bracket symbols
[ and ] in place of the standard m4 quote symbols ' and '
All m4 operations are enclosed within balanced left and right parentheses:
( and )Arguments to these operations that are longer than a few characters, or that include newlines (carriage returns) or characters that can have a special meaning (such as parenthesis symbols) should be enclosed within balanced left and right square brackets:
[ and ]
A define command is used to define a macro -- a (short) string of characters used to represent another (usually longer) string. A macro character string can consist of almost any combination of alphnumeric characters, but many users employ UPPER CASE characters so that occurrences of macros can be spotted quickly. In the following score file, macros N1, N2 and N3 are defined as particular pitch motives, while macros R1 and R2 are defined as rhythmic motives. These macros are then permuted in the score:
When this file is run through score11, the resulting sout file is :
---- i1 0.000 0.200 8.00 --- | i1 0.200 0.200 8.04 | N1 | i1 0.400 0.200 8.06 -- R1 | i1 0.600 0.200 8.11 -- (p4) (p2)| i1 0.800 0.200 8.10 | N2 | ;i1 1.000 0.500 9.01<rest> | --- i1 1.500 1.000 8.04 -- --- i1 2.500 0.250 9.09 -- | i1 2.750 0.125 9.08 | N3 R2 | i1 2.875 0.125 9.11 | --- i1 3.000 1.500 9.00 --- --- i1 4.500 0.250 8.11 --- | i1 4.750 0.125 8.10 | N2 R2 | i1 4.875 0.125 9.01 | --- i1 5.000 1.500 8.04 --- --- i1 6.500 0.200 8.11 --- | i1 6.700 0.200 8.10 | N2 | i1 6.900 0.200 9.01 | R1 | i1 7.100 0.200 8.04 --- | i1 7.300 0.200 8.00 --- | ;i1 7.500 0.500 8.04<rest> | N1 --- i1 8.000 1.000 8.06 --- end of score%
On the ECMC SGI systems, all files submitted to score11 actually take a detour, and are first passed through m4orch for macro preprocessing. What score11 actually "sees" is the output of m4orch. Thus, it is not necessary to process score11 input files through m4orch yourself.
Of course, macro definitions must be defined before they can be used in a file. Usually, all macro definitions are placed at the very beginning of a file, as in the example above. Remember that what score11 "sees" is the expanded version of these macros. When using define macros, visualize the expanded output on each line, or else run the file through m4expand or m4expandsc :
Do not put so many macros on one line of a score file that the line length of the expanded code will be too long (greater than 80 characters) for score11 to process.
Define statements and other m4 operations often result in the inclusion of newline characters and resulting blank lines which can result in gaping "holes" in the m4 output. Most of these blank lines can be suppressed by including the delete newline keyword dnl immediately (no blank spaces intervening) after the concluding ")" right parenthesis of the statement, like this:
Orchestra files containing such m4 macros must first be run manually through m4orch (m4o), which writes its output to file orch.orc (which can be abbreviated orc). Your Csound job should then have the following syntax :
The following skeletal orchestra file :
after being run through m4orch or mko would look like this :
By itself, the example above is not all that useful, since the macro OUTPUT will always be expanded to out a1. However, ifelse and ifdef constructions can be included within macro definitions to provide alternative expansions, based upon some evaluation.
ifelse conditionals have the following format :
This is interpreted : "If character string a is identical to string b, then return string c; if they are not identical, return string d." The following definition of OUTPUT is an ifelse construction that provides two alternative expansions, depending on whether the orchestra header specifies mono or stereo output:
It may be easier to follow the logic of this nasty looking line if we "explode" the arguments:
ifelse (a, b, c, d ) define(OUTPUT, [ifelse (NCHNLS, 1, [out a1], [outs sqrt(p10)*a1, sqrt(1-p10)*a1])])
m4orch (or m4expand) "reads" this line as follows: "Define OUTPUT on the basis of the following comparison. If NCHNLS has been defined as 1 in the SETUP header macro, return out a1; otherwise (for stereo) return outs p10*a1,(1-p10)*a1.
With this definition of OUTPUT in place, our instrument algorithm can be used, without further editing, to create either mono or stereo soundfiles, simply by changing the NCHNLS (number of channels) argument in the SETUP header at the top of an orchestra file.
ifdef statements, too, return a string based on an evaluation. The simple form is :
which means : if a has already been defined, return value b. Otherwise, do nothing.
In many cases, b is another define statement.
More often, ifdef statements contain three arguments :
Here, if a has been defined, argument b is returned. If a has NOT been defined, argument c is returned. Arguments b and c may be define statements, ifelse constructions, or further (nested) ifdef operations. Consider the following ifdef statement:
Here is how this complex statement is evaluated :
With this macro in place, we can use the default mono and stereo instrument outputs in creating most soundfiles. However, if we wish to include additional postprocessing, we can provide a new definition of OUTPUT, which will override these defaults. The new definition must precede the ifdef statement above.
The most common problem with nested constructions like the one above (other than their repugnant ugliness) is failure to balance left and right parentheses and square brackets. To illustrate the necessary balancing of the preceding example, we have labeled the four matching sets of parentheses "1" through "4" below, and the four sets of square brackets "W," "X," "Y" and "Z."
1W W 2 X 3 Y Y || | | | | | | ifdef([OUTPUT],,define(OUTPUT,[ifelse(NCHNLS,1,[out a1], [outs p10*a1,(1-p10)*a1])]))dnl | | | ||||| Z 4 4 Z3X21
Those with experience in such programming languages as C, or with Unix shell scripts, already will be familiar with include statements, which allow us to include the complete contents of one file at some point within another file. Includes are also possible within m4. Here is a sample orchestra file:
After this file is processed by m4orch, file orch.orc will include file flute.orc from the our current directory, and file strings.orc from subdirectory ins.
If you want to include files from directories that do NOT branch from your current working directory, you must include the complete path name for these files. The tilde sign (~) is a useful abbreviation for your home Unix directory.If file flute.orc includes a macro output definition of the ifdef type previously discussed:
but you want to override the default output within this particular orchestra file, you could create a new output definition before the include call to flute.orc:
define(OUTFLUTE,[ ; add a moving stereo pan kpan oscili p22-p21, 1/p3 , p23 kpan = kpan+p21 outs sqrt(kpan)*a1, sqrt(1-kpan) * a1])dnl SETUP(44100,2205,2) include(flute.orc) include(/ins/strings.orc)
If this output panning module works well, and you might wish to use it again, either with flute.orc or with other instrument algorithms, you could copy it to another file, and, perhaps, put this new file in a directory that contains only such post-processing modules of Csound code. In this case, we will observe the convention, and type our panning module code into a file called pan.defs. We will then place pan.defs in a directory called m4stuff.
define(PAN,[ ; add a moving stereo pan kpan oscili p22-p21, 1/p3 , p23 kpan = kpan+p21 outs sqrt(kpan)*a1, sqrt(1-kpan) * a1])dnl
Actually, we might wish to include macro definitions for several types of panning operations within this file, and give these definitions names such as PAN1, PAN2, RANDOMPAN, FASTPAN and so on. Now, we can append any of several types of panning operations, defined in our pan.defs file, to our flute algorithm:
include(~/m4stuff/pan.defs) define(OUTFLUTE,[RANDOMPAN])dnl SETUP(44100,2205,2) include(flute.orc) include(/ins/strings.orc)
Similar macro definitions can be useful in score preparation. Here, we will first create a file, called motives, that contains definitions for various rhythmic and pitch motives. A simple file of this type might look something like this:
define(RH1,[4./16//2./ 32 * 4/])dnl define(RH2,[16// -2/ 8*4/ 24 * 3/])dnl define(TREBLE,[c4/b/fs/f5/af/])dnl define(BASS,[df2/bf0/g1/a2/])dnlA more usable file might contain 10 or more lengthy define statements, rather than only four short rhythmic and pitch "motives" as in the example above.
Now we can create several score files that that access these motives. One such score might look like this:
include(motives) i1 0 12; p3 rh RH1/-2/RH1; p4 no df3/ TREBLE / g5/bf4; p5 mx 5 2000 1000/2 12000/ 5 12000 2000; end; i2 0 12; p3 rh RH2/8/32//RH2/-2; p4 no BASS/b3/f2/BASS; p5 1. 5000 12000; end;
These examples are merely illustrative, and hint at some of the many ways in which we can preprocess Csound orchestra and score files. Advanced users often employ such procedures not only to speed up score and orchestra file preparation, but also as compositional tools to derive a lot of mileage from a limited amount of initial source material. Synthesis and score generating algorithmic procedures thus can become modules that can be patched together in various configurations and combinations to permute, develop, vary and extend ideas, and which can enable us to go back and forth between "top down" and "bottom up" compositional approaches at various stages in the realization of a work.
Obviously, prepreprocessing procedures such as those we have surveyed above are not limited to our work with Csound, but rather can be applied as well to the creation of input files or data for other sound processing programs as well.
Beginning with version 3.48 Csound itself has included simple
orchestra macro
and
score macro
systems that permit the use
of #define and #include statements within orchestra and score
files. Here is a simple example. First we create a file of
macro function definitions, which we will call defs, that we might use
within several score files:
# /* file of macro function definitions */
#define SINE # f1 0 1024 10 1.#
#define TRIANGLE # f31 0 64 7 -1. 32 1. 32 -1.#
#define SAW # f32 0 64 7 -1 64 1 #
#define SQUARE #f33 0 64 7 1. 16 1. 0 -1. 32 -1. 0 1. 16 1. #
Next we create a Csound score file that includes some of the macro definitions
from file defs as well some additional macros unique to this score:
#include #/u/staff/allan/SEC1/defs# $SINE $TRIANGLE $SAW $SQUARE #define RISEFALL # .005 .25# f50 0 65 7 0 64 1. i31 0.000 1.200 100 6000 0.004 0.850 i31 0.119 0.924 130 6883 $RISEFALL i31 0.240 0.712 168 7897 $RISEFALL i31 0.982 2.000 60 22000 0.002 .350 eThe score file above would be equivalent to this:
f 1 0 0 1024 1024 10 1. f 31 0 0 64 64 7 -1. 32 1. 32 -1. f 32 0 0 64 64 7 -1 64 1 f 33 0 0 64 64 7 1. 16 1. 0 -1. 32 -1. 0 1. 16 1. f 50 0 0 65 65 7 0 64 1. i31 0.000 1.200 100 6000 0.004 0.850 i31 0.119 0.924 130 6883 0.005 0.250 i31 0.240 0.712 168 7897 0.005 0.250 i31 0.982 2.000 60 22000 0.002 .350 e
This section presents a few concluding orchestra/score11 file (and resulting /sflib/x soundfile) examples that illustrate some additional Csound opcodes and procedures that you may find useful.
Orchestra file ex6-1 uses
; ############################################################# ; orchestra file example ex6-1 : harmonizer : ECMC Csound Tutorial ; ############################################################# ; csound header 1 sr=44100 2 kr=2205 3 ksmps=20 4 nchnls=1 5 instr 1 6 ;----- SOUNDFILE INPUT -------------------- 7 ifunc = p4 ; gen1 function number of input soundfile 8 iampscale = (p5 = 0 ? 1. : p5) ; adjust input amplitude 9 irise = (p6 = 0 ? .001 : p6) ; fade-in time 10 idecay =( p7 = 0 ? .001 : p7) ; fade-out time 11 ; loscil arguments 12 ibasepitch = (p8 < 13. ? cpspch(p8) : p8) ; base pitch of soundfile in pch or cps 13 ioutpitch = (p9 < 13. ? cpspch(p9) : p9) ; output pitch in pch or cps 14 ioutpitch = (p9 < 3 ? p9 * ibasepitch :ioutpitch) ; or as multiplier of basepitch 15 ; output amplitude envelope 16 kamp expseg .005 ,irise , iampscale , p3 - (irise + idecay) , iampscale , idecay , .005 17 asource loscil kamp, ioutpitch, ifunc, ibasepitch 18 ;----- HARMONIZER -------------------- 19 imin init 0 20 imin = (p10 < 1. ? p10 * ioutpitch : imin) 21 imin = (p10 > 1. && p10 < 13. ? cpspch(p10) : imin) 22 imin = (p10 > 13 ? p10 : imin) 23 ; max. freq. variance 24 ; as % of output source pitch or in pch or cps 25 imaxvar = (p11 < 1. ? p11 : p11 / ioutpitch) 26 imode = p12 ; if 0, iharm1 & iharm2 are ratios * ioutpitch 27 ; if 1, iharm1 & iharm2 are notes in pch or cps 28 iprd = p15 ; pitch analysis window size 29 iharm1 init p13 30 iharm2 init p14 31 if imode = 0 igoto doit 32 if p13 = 0 igoto harm2 33 iharm1 = (p13 < 13. ? cpspch(p13) : p13) 34 harm2: if p14 = 0 igoto doit 35 iharm2 = (p14 < 13. ? cpspch(p14) : p14) 36 doit: 37 aharm harmon asource, ioutpitch, imaxvar, iharm1, iharm2, imode, imin, iprd 38 ; print ioutpitch, imaxvar, iharm1, iharm2, imode, imin, iprd 39 ;----- SIGNAL OUTPUTS {source/harmonizer mix} --------------- 40 out (p16 * asource) + (p17 * aharm) 41 endinThe important lines within this code are the calls to loscil on line 17 and to harmon on line 37.
Companion score11 input file ex6-1 represents an initial test of this instrument algorithm, creating three-part harmonies in succession from three sflib soundfiles all pitched at b3: a soprano tone (sflib/voice/sop1.b3), a violin tone (/sflib/string/vln.b3) and a trumpet tone (sflib/wind/trp.b3).
< Score file used to create "ex6-1" : * f1 0 524288 -1 "/sflib/voice/sop1.b3" 0 0 0 ; < dur = 6.37 * f2 0 262144 -1 "/sflib/string/vln.b3" 0 0 0 ; < dur = 3.62 * f3 0 524288 -1 "/sflib/wind/trp.b3" 0 0 0 ; < dur = 6.31 i1 0 0 3; < create 3 output "notes" p3 4; du 303; < each output note lasts 3 seconds p4 nu 1/2/3; < gen 1 func number of input soundfile : sop/vln/trp < p5,6,7 : amplitude envelope p5 nu .6/.4//; < input amplitude multiplier p6 0 ; < optional fade-in time p7 .2; < optional fade-out time < p8 no b3; < base pitch of input soundfile in pch or cps p9 no b3//c4; < output pitch in pch or cps < harmonizer p-fields: p10 no a3; < iminfrq , in cps or as % of p9 base pitch p11 .5; < kmaxvar : fraction p12 1; < imode : if 0, p13 & p14 are ratios * p8 pitch < IMPORTANT: p12 & p13 cannot BOTH be > p8 p13 no gs3; < harmonizer output note or ratio 1 p14 no cs4; < harmonizer output note or ratio 2 p15 .04; < iprd : normally between .02 & .05 < source/harmopnizer output mix p16 nu .5/0/.2; < amp. multiplier for source signal output p17 nu 1; < amp. multiplier for harmonizer output end; <<<<<<<<<<<<<< end of ex6-1 score file >>>>>>>>>>>>>>
Within the opening SOUNDFILE INPUT section of this instrument algorithm (lines 6 through 17) we first define several initialization values, mostly be means of conditional evaluations of score p-fields 4 through 9, so that for each score11 input file we create for this instrument we can employ the most convenient of two or more alternative ways to set these parameter values.
6 ;----- SOUNDFILE INPUT -------------------- 7 ifunc = p4 ; gen1 function number of input soundfile 8 iampscale = (p5 = 0 ? 1. : p5) ; adjust input amplitude 9 irise = (p6 = 0 ? .001 : p6) ; fade-in time 10 idecay =( p7 = 0 ? .001 : p7) ; fade-out time 11 ; loscil arguments 12 ibasepitch = (p8 < 13. ? cpspch(p8) : p8) ; base pitch of soundfile in pch or cps 13 ioutpitch = (p9 < 13. ? cpspch(p9) : p9) ; output pitch in pch or cps 14 ioutpitch = (p9 < 3 ? p9 * ibasepitch :ioutpitch) ; or as multiplier of basepitch 15 ; output amplitude envelope 16 kamp expseg .005 ,irise , iampscale , p3 - (irise + idecay) , iampscale , idecay , .005
With the iampscale init value derived from p5 we can scale (adjust) the amplitude of the input soundfile (since harmonization will increase the output amplitude, possibly resulting in clipping if we do not attenuate the input signal). The irise and idecay values derived from score p-fields 6 and 7 allow us to apply fade-ins and fade-outs to the input soundfiles within the output amplitude envelope created by expseg on line 16.
In order to transpose the pitch of a soundfile by resampling (a process that also will alter the duration of the sound), loscil must determine the ratio between the input and output frequencies. The ibasepitch (input pitch) conditional evaluation of p8, and the corresponding ioutpitch (output pitch) evaluation of p9, allow us to use either the score11 keyword notes in p8 and p9, which will output pch values less than 13., or else, if we prefer, provide these values in herz. (The latter method could be useful if we wish to pitch shift a soundfile by only a few herz.)
Harmonization: The harmon unit generator
ar harmon asig, kestfrq, kmaxvar, kgenfreq1, kgenfreq2, imode, iminfrq, iprd or, in ex6-1, aharm harmon asource, ioutpitch, imaxvar, iharm1, iharm2, imode, imin, iprdcan create either one or two pitch shifted copies of an input audio signal (which, in ex6-1, is the signal it receives from loscil). However, only one of these copies can be pitched higher than the input signal, and only the copies (and not the input signal) are included in the audio output of harmon. Unlike loscil, harmon performs time correction when pitch shifting. This can make the unit generator useful, apart from its typical "harmonization" applications, for pitch shifting a source sound without altering its duration, and for correcting the inaccurate pitch of a sound.
However, while the input pitch tracking within harmon (and within many of today's hardware harmonizers) generally is accurate, the audio input signal often suffers some degradation from the process of harmonization . (This is one of the reasons why harmonizers most often are used on "background," tracks in pop music.) This degradation may be just a little grunge, or may result in audible distortion or other artifacts. Input signals with wide vibratos or tremolos, or with complex timbres, or which lack a well-defined fundamental pitch, are especially prone to distortion.
To help the pitch tracking algorithm within harmon perform its rather complex task we must provide it with several arguments:
--> if p10 is less than 1., it specifies a ratio between the lowest possible frequency and the estimated center frequency Example: A p10 value of .8 thus specifies .8 times the ioutputpitch value derived from p9 --> if p10 is between 1. and 13., we can use the score11 keyword notes to specify imin Example: p10 no a3 (and a resulting Csound score value of 7.09) would set the imin value to 220 herz --> if p10 is greater than 13., we can specify this value directly in herz
The remaining three arguments to harmon specify
In ex6-1 we have included two final mixer p-fields, p 15 and p 16, to control the output balance between the source tone, from loscil, and the harmonizer-generated tones. In the trumpet tone harmonization the source signal from loscil is suppressed:
p16 nu .5/ 0 /.2; < amp. multiplier for source signal output p17 nu 1; < amp. multiplier for harmonizer output
The results of our ex6-1 score are mixed. The soprano harmonization is clean, but the violin harmonization suffers distortion (possibly caused by the wide tremolo) and the attack of the trumpet tone harmonization also is distorted. By tweaking the iprd and input amplitude values we might be able to clean up the violin and trumpet harmonizations, or we might spend a lot of time fussing to little gain.
In ex6-2 we employ the same orchestra file, but a (hopefully) more interesting
score, employing a multisample collection of short soprano tones as source
sounds.
; #############################################################
< Score file used to create "ex6-2" :
; #############################################################
< **** sop3 {soprano, short tones sung loudly }function tables ***
*f1 0 32768 -1 "/sflib/voice/sop3.b3" 0 0 0; < dur = .44
*f2 0 32768 -1 "/sflib/voice/sop3.ds4" 0 0 0; < dur = .47
*f3 0 32768 -1 "/sflib/voice/sop3.fs4" 0 0 0; < dur = .448
*f4 0 32768 -1 "/sflib/voice/sop3.as4" 0 0 0; < dur = .45
*f5 0 32768 -1 "/sflib/voice/sop3.cs5" 0 0 0; < dur = .43
*f6 0 32768 -1 "/sflib/voice/sop3.e5" 0 0 0; < dur = .475
*f7 0 32768 -1 "/sflib/voice/sop3.gs5" 0 0 0; < dur = .52
*f8 0 32768 -1 "/sflib/voice/sop3.b5" 0 0 0; < dur = .50
<; f99 = input soundfile function numbers & split points {in MIDI note numbers}
*f99 0 128 -17 0 1 61 2 65 3 68 4 72 5 75 6 78 7 82 8 ;
<; f98 = base pitches of input soundfiles {expressed in MIDI note numbers}
*f98 0 16 -2 0 59 63 66 70 73 76 80 83 ;
< -------------End of SOP3 functions ---------
te x 3.5 60 90/4.5 90 60;
i1 0 8;
rs 999;
rd .03;
p3 .33; < mx 4. .45 .25 .18 .3/3. .18 .3 .5;
du mo 3.5 300.3 300.5 300.3/4.5 300.25 300.4 300.5 300.3;
p4 nu 1/3/5/7/ < gen 1 func number of input soundfile
8/6/4/2;
< p5,6,7 : amplitude envelope
p5 mx 3. .03 .5/4. .5 .02; < input amplitude multiplier
p6 mx 3. .1 .06 .005 .02/ < optional fade-in time
4. .005 .01 .1;
p7 mx 4 .24 .12 .1 .18/3. .18 .1 .2 .25; < optional fade-out time
<
p8 no b3/fs4/cs5/gs5/ < base pitch of input soundfile in pch or cps
b5/e5/as4/ds4;
p9 1. .89 1.12; < output pitch in pch or cps or * p8
< harmonizer p-fields:
p10 .9; < iminfrq , in cps or as % of p9 base pitch
p11 .3; < kmaxvar : fraction
p12 0; < imode : if 0, p13 & p14 are ratios * p8 pitch
< IMPORTANT: p12 & p13 cannot BOTH be > p8
p13 1. .67 .94; < harmonizer output note or ratio 1
p14 1. 1.05 1.33; < harmonizer output note or ratio 2
p15 .03; < iprd : normally between .02 & .05
< source/harmopnizer output mix
p16 1. .3 .5; < amp. multiplier for source signal output
p17 1. .8 1.; < amp. multiplier for harmonizer output
end; <<< End of ex6-2 score >>>>>
The recently introduced DAM unit generator
aout dam ain, kthreshold, icomp1, icomp2, rtime, ftime
Similarly, if we set the icomp2 paramter to a value less than 1., low intensity (usually "soft" or "decaying" ) signals, below the threshold level, can be further attenuated, similar to the manner in which noise gate circuits are used to reduce background noise, or to exaggerate the decays of tones to produce a more staccato," "punchier" performance quality. Alternatively, if icomp2 is set to a value greater than 1., signal levels below the threshhold can be boosted, to reduce the difference between high and low intensity levels and compress the dynamic range. The quickness with which adjustments are applied to the output amplitude is controlled by the rtime ("rise time") and ftime ("fall time") paramters.
In ex6-3 amplitude compression/expansion is applied first to an sflib wire brush snare drum roll soundfile, and then to a portion of the much (and, to my mind, unjustly) maligned voicetest soundfile.
; ########################################### ; orchestra file for examples ex6-3 ; amplitude compression/expansion with dam ; ########################################## ; csound header sr=44100 kr=2205 ksmps=20 nchnls=1 instr 1 asig soundin p4, p6 ; read in soundfile ; input amplitude scaling and optional fade-in and fade-out iamp = p5 irise = (p7 = 0 ? .001 : p7) idecay = (p8 = 0 ? .001 : p8) kamp expseg .005, irise, iamp, p3 - (irise + idecay), iamp, idecay, .005 asig = kamp * asig ; apply amplitude compression/expansion: asig dam asig, p9, p10, p11, p12, p13 out asig endin ---------------------------------------- < Score file used to create ex6-3 : i1 0 0 4; < 4 output "notes" p3 3; du nu 301.63 * 3/304.; p4 nu 17 * 3/16 ; < soundin.# number < 17 = /sflib/perc/sdrum1.broll , 16 = /sflib/x/voicetest p5 nu 1./ .005/2.4/2.4 ; < scale input amplitude p6 0 ; < optional skip time off front of soundfile p7 0; < optional fade-in time p8 nu 0 * 3/.3; < optional fade-out time < "dam" compression/expansion parameters: p9 nu 10000/10000/10000/8000; < amp. threshold for compression/expansion p10 nu 1./.002/ 1.5/1.7/ ; < compress/espand ratio 1 for high levels p11 nu 1./12./ .2/.15/; < compress/espand ratio 2 for low levels p12 nu .1 * 3/ .03; < gain raise time p13 nu .1 * 3/ .03; < gain fall time end; <<< End of ex6-3 score >>>
The four output "notes" produced by this score illustrate
The CPS2PCH pitch converter enables us to create scales that divide the octave into less than, or more than, 12 equal tempered pitch classes. (The companion cpsxpch pitch converter allows us to create equal tempered scales with any number of scale steps, that repeat at any interval -- not just at the octave.)
Orchestra file ex6-4 is designed to play in such unusual equal tempered tunings, which are defined by score p-fields 4 and 6, and to employ multisample collections of instrumental or vocal tones as sound sources. For each score note, the instrument consults score function tables 99 and 98 to determine which multisampled soundfile is closest in pitch to the desired output pitch, and then, with loscil, resamples this soundfile to produce the correct frequency.
; ############################################################# ; orchestra file examples ex6-4-1, 6-4-2 and 6-4-3 ; non-12 tone tuning examples ; ############################################################# sr=44100 kr=2205 ksmps=20 nchnls=1 instr 1 icps cps2pch p4, p6 ; convert pch to midi note number imidinote = int((p4) - 3) * 12 imidinote = int(imidinote + ((frac(p4) * (12/p6)) * 100)) ; ------------------------------------------ ; use function tables 99 & 98 to get closest multisample soundfile ifno table imidinote, 99 ;keyboard mapping to gen1 function tables ibasno table ifno, 98 ; returns midi notes of the sonudfile samples ibasoct = ibasno/12. + 3. ibasepitch = cpsoct(ibasoct) ; ------------------------------------------ iendloop = 1 ; dummy end loop point for loscil ; csound aborts without an end loop value, even ; if no looping is specified asig loscil 1, icps , ifno, ibasepitch , 0, 0, iendloop ;print icps, imidinote, ifno, ibasepitch ; ------------------------------------------ ; AMPLITUDE SCALING and OPTIONAL NEW AMPLITUDE ENVELOPE iamp = p5 irise = (p7 = 0? .0001 : p7) idec = (p8 = 0? .0001 : p8) kamp expseg .005, irise, iamp, p3 - (irise + idec), iamp , idec, .005 asig = asig * kamp ; ------------------------------------------ out asig endin
Three simple score files are provided here for this instrument, each presenting a one octave ascending chromatic scale:
< Score11 file used to create soundfile example ex6-4-1 < 11 tone equal tempered chromatic chromatic scale < ****** CELLO PIZZ FUNCTIONS : ******* * f1 0 262144 -1 "/sflib/string/vc.p.c2" 0 0 0 ; < dur = 3.25 * f2 0 131072 -1 "/sflib/string/vc.p.e2" 0 0 0 ; < dur = 2.32 * f3 0 131072 -1 "/sflib/string/vc.p.gs2" 0 0 0 ; < dur = 1.86 * f4 0 131072 -1 "/sflib/string/vc.p.c3" 0 0 0 ; < dur = 2.29 * f5 0 131072 -1 "/sflib/string/vc.p.e3" 0 0 0 ; < dur = 2.41 * f6 0 65536 -1 "/sflib/string/vc.p.gs3" 0 0 0 ; < dur = 0.86 * f7 0 131072 -1 "/sflib/string/vc.p.c4" 0 0 0 ; < dur = 1.93 * f8 0 65536 -1 "/sflib/string/vc.p.e4" 0 0 0 ; < dur = 1.08 * f9 0 65536 -1 "/sflib/string/vc.p.gs4" 0 0 0 ; < dur = 0.975 * f10 0 65536 -1 "/sflib/string/vc.p.b4" 0 0 0 ; < dur = 0.882 * f11 0 65536 -1 "/sflib/string/vc.p.d5" 0 0 0 ; < dur = 0.882 <; f99 = input soundfile function numbers & split points {in MIDI note numbers} *f99 0 128 -17 0 1 38 2 42 3 46 4 50 5 54 6 58 7 62 8 66 9 70 10 73 11 ; <; f98 = base pitches of input soundfiles {expressed in MIDI note numbers} *f98 0 16 -2 0 36 40 44 48 52 56 60 64 68 71 74 ; < **** End of cello pizzicato functions ***** i1 0 0 13; p3 nu .5 * 10/ .9/ .007; du 300.7; < p4 = PITCH p4 nu 7.00/ 7.01/ 7.02/ 7.03/7.04/ 7.05/ 7.06/ 7.07/ 7.08/7.09/7.10/ 7.11/ 7.00; < ends with octave 7.11/7.00 p6 11; < iequal {number of tones in scale } p5 .5; < amplitude multiplier < p7 = optional fade-in time p7 < p8 = optional fade-out time p8 1. .35 .25; end; <<< End of ### exex6-4-1 ### score >>> ; ------------------------------------------ < Score11 file used to create soundfile example ex6-4-2 < 13 tone equal tempered chromatic chromatic scale < flute multisamples *f1 0 0 -1 "/sflib/wind/fl.c4" 0 0 0; < dur = 3.472 *f2 0 0 -1 "/sflib/wind/fl.e4" 0 0 0; < dur = 3.479 *f3 0 0 -1 "/sflib/wind/fl.gs4" 0 0 0; < dur = 3.854 *f4 0 0 -1 "/sflib/wind/fl.c5" 0 0 0; < dur = 3.534 *f5 0 0 -1 "/sflib/wind/fl.e5" 0 0 0; < dur = 3.614 *f6 0 0 -1 "/sflib/wind/fl.gs5" 0 0 0; < dur = 4.233 *f7 0 0 -1 "/sflib/wind/fl.c6" 0 0 0; < dur = 3.515 *f8 0 0 -1 "/sflib/wind/fl.e6" 0 0 0; < dur = 3.564 *f9 0 0 -1 "/sflib/wind/fl.gs6" 0 0 0; < dur = 3.295 *f10 0 0 -1 "/sflib/wind/fl.c7" 0 0 0; < dur = 3.595 <; f99 = input soundfile function numbers & split points {in MIDI note numbers} *f99 0 128 -17 0 1 62 2 66 3 70 4 74 5 78 6 82 7 86 8 90 9 94 10; <; f98 = base pitches of input soundfiles {expressed in MIDI note numbers} *f98 0 16 -2 0 60 64 68 72 76 80 84 88 92 99; < -------------End of Flute gen 01 functions --------- i1 0 0 15; p3 nu .5 * 12/ .75/ .007; du 300.6; < p4 = PITCH p4 nu 8.00/ 8.01/ 8.02/ 8.03/8.04/ 8.05/ 8.06/ 8.07/ 8.08/8.09/8.10/ 8.11/ 8.12/ 8.13/ 8.00; p6 13; < iequal {number of tones in scale } p5 .5; < amplitude multiplier < p7 = optional fade-in time p7 < p8 = optional fade-out time p8 1. .2 .15; end; <<< End of ### exex6-4-2 ### score >>> ; ------------------------------------------ < Score11 file used to create soundfile example ex6-4-3 < 19 tone equal tempered chromatic chromatic scale < **** VLN ARCO ORD. function tables ****** < 11 soundfile(s) sorted by pitch abbreviation: * f1 0 262144 -1 "/sflib/string/vln.g3" 0 0 0 ; < dur = 3.83 * f2 0 262144 -1 "/sflib/string/vln.b3" 0 0 0 ; < dur = 3.62 * f3 0 262144 -1 "/sflib/string/vln.ds4" 0 0 0 ; < dur = 3.63 * f4 0 262144 -1 "/sflib/string/vln.g4" 0 0 0 ; < dur = 3.83 * f5 0 262144 -1 "/sflib/string/vln.b4" 0 0 0 ; < dur = 3.34 * f6 0 131072 -1 "/sflib/string/vln.ds5" 0 0 0 ; < dur = 2.88 * f7 0 262144 -1 "/sflib/string/vln.g5" 0 0 0 ; < dur = 3.68 * f8 0 131072 -1 "/sflib/string/vln.b5" 0 0 0 ; < dur = 2.88 * f9 0 131072 -1 "/sflib/string/vln.ds6" 0 0 0 ; < dur = 2.93 * f10 0 131072 -1 "/sflib/string/vln.g6" 0 0 0 ; < dur = 2.94 * f11 0 262144 -1 "/sflib/string/vln.c7" 0 0 0 ; < dur = 3.37 <; f99 = input soundfile function numbers & split points {in MIDI note numbers} *f99 0 128 -17 0 1 57 2 61 3 65 4 69 5 73 6 77 7 81 8 85 9 89 10 93 11; <; f98 = base pitches of input soundfiles {expressed in MIDI note numbers} *f98 0 16 -2 0 55 59 63 67 71 75 79 83 87 91 96 ;< midi notes of samples < -------------End of VLN Arco Ord. functions --------- i1 0 0 21; rd p3 nu .4 * 18/ .7/ .007; du 300.5; < p4 = PITCH p4 nu 8.00/ 8.01/ 8.02/ 8.03/8.04/ 8.05/ 8.06/ 8.07/ 8.08/8.09/8.10/ 8.11/ 8.12/ 8.13/ 8.14/ 8.15/8.16/8.17/8.18/8.19/8.00; p6 19; < iequal p5 .5; < amplitude scalar < p7 = optional fade-in time p7 < p8 = optional fade-out time p8 1. .3 .38; end; <<< End of ### exex6-4-3 ### score >>>
Obviously this tutorial has surveyed only a very limited sampling of the total resources of Csound. Some of the more interesting resources we have not touched upon but which you may wish to explore at this point include:
The collective wisdom of many Csound users from many parts of the world is available online to assist you in understanding and applying particular facets of Csound. This information ranges from getting-started tutorials, like this present document, through advanced algorithmic design and coding techniques to broader topics that extend beyond the specifics of Csound to include new procedures of sound synthesis, audio signal processing, algorithmic composition and so on. Here are a few initial pointers:
The Csound distribution itself includes tutorials by Barry Vercoe and Richard Boulanger, and also a directory containing sample Csound orchestra and score files. Most of these orc/sco pairs are simple tutorial examples, but some are more advanced. To jump into this directory (/usr/local/lib/csoundexamples on the ECMC SGI systems), simply type the alias
If you list the contents of this directory, you will find several subdirectories. The ECMC README file contains information about the contents of these subdirectories. The testfiles subdirectory contains the simplest examples, many of which illustrate usage of a single unit generator. The other subdirectory also includes many simple examples, as well as a few more sophisticated algorithms. Do a cd into one of these subdirectories, list its contents, and take a look at some of the orchestra and score files. You cannot compile these orc/sco pairs directly into a soundfile from within these directories because you do not have directory write permission to create necessary temporary files, such as score.srt. To copy one of these files into your own home Unix directory, type
When you are ready to return to your home Unix directory, simply type: cd
Richard Boulanger's The Csound Books, due for publication in June 1999 by the MIT Press, likely will become the definitive text on Csound resources when it becomes available. The text will be accompanied by two companion cd-rom discs containing additional Csound-related utilities and documentation, including this Eastman Csound Tutorial.
The starting point for any web search of Csound-related information currently is the Csound Front Page
There is an active internet Csound users' group to which expert and novice users post technical questions and answers, samples orchestra and score files, and and other discussions related to Csound, sound synthesis and signal processing. Currently, you can subscribe to this group, receiving e-mail copies of all postings, by sending an e-mail message to:
On the first line of this message, type
where UID is your user ID (login name) and host is the machine name and domain where you wish to receive your mail from this group (for example, wozzeck.esm.rochester.edu).This is a very active group, and currently no encapsulated digest version of its postings is available (although one is expected soon), so you can anticipate receiving many messages each day.
Table of Contents CHAPTER 1 -- CHAPTER 2 -- CHAPTER 3 -- CHAPTER 4 -- CHAPTER 5 -- CHAPTER 6 -- APPENDIX 1 -- APPENDIX 2