Index | Next Week | Previous Week |
Index
The first two steps are quite straight-forward. Each audio component should have its own envelope, and the signals should be properly balanced in the final output.
When the important controls and modifiers are added, you need to decide whether the values should be hard-wired into the instrument or passed as parameters from the score. Parameters passed from the score provide more flexibility, but require that the correct range of values be remembered by the composer. (Ranges for the parameters should be commented in your code).
The secondary and tertiary controls are used to add an extra dimension of subtlety to a sound. They are usually deal with slight alterations to existing controls. A simple vibrato:
can be modified with a linseg on the vibrato speed:
and the speed of the randh can be adjusted so that there are more random values towards the end of the sound:
Index
Index
Index
Use three slightly out of sync foscils:
Add some white noise on the pitch:
Add some random frequencies to the foscils:
Add line segments to the random frequencies:
Add individual amplitude envelopes:
Add Reverb:
Steps in Designing a CSound Instrument
At times, composers have a clear idea of what sound they want; at others times composers simply experiment until they develop something they like. In both cases, the basic procedure for designing a sound is:
When designing an instrument, you should keep your score simple, and gradually increase the complexity of the score (durations, pitches and volumes) as the instrument gets refined.
ivibw = cpspch(p5) * .01 ; vibrato width
ksig oscil ivibw, 4, 1 ; a vibrato 4 * per second
ivibw = cpspch(p5) * .01 ; vibrato width
kline linseg 5, p3*.6, 4, p3*.3, 4.5, p3*.1 ; adjust vibrato speed
ksig oscil ivibw, kline, 1 ; a vibrato
and with a random addition ( up to 1/5 of a cycle) to the vibrato width:
ivibw = cpspch(p5) * .01 ; vibrato width
krand randh .2, 3 ; range of .2 Hz .
kline linseg 5, p3*.6, 4, p3*.3, 4.5, p3*.1 ; adjust vibrato speed
ksig oscil ivibw + krand, kline, 1 ; a vibrato
ivibw = cpspch(p5) * .01 ; vibrato width
kspeed line 3, p3 * .7, 3, p3 * .3, 6 ; increase from 3 to 6
krand randh .2, kspeed ; range of .2 Hz.
kline linseg 5, p3*.6, 4, p3*.3, 4.5, p3*.1 ; adjust vibrato speed
ksig oscil ivibw + krand, kline, 1 ; a vibrato
and so on:
Filters and reverb can be added to colour the sound. Filters can be added to your instrument, but it is generally better to create separate reverb instrument and pass a global parameter to this instrument. You may want to use a parameter in the score as a flag to determine whether or not reverb should be used. In the example below, reverb is added if p6 is equal to 1 - if it is 0 there is no reverb.
if (p6 == 0) goto dry
wet:
ga1 reverb asig, 2.5 ; send to global reverb
dry:
outs asig, asig ; output audio signal
Associating parameters to the pitch
Once an instrument has been designed, it is useful to ensure that certain aspects of the sound be linked to the pitch being passed from the score. Aspects such as tremolo or vibrato speed and depth, noise band width, filter frequencies etc. should be linked to the pitch. In the example below, an instrument has been designed with a noise bandwith of 20 Hz - the pitch used to test the instrument was 8.00.
kband randh 20, kr ; band width 20 Hz
asig oscil kenv * p4, cpspch(p5)+kband, 1 ; makes noise
The band of 20 will work at 8.00, but with other pitches, the fixed 20 Hz band will be perceived as being either larger or smaller than at 8.00. The bandwidth should be associated with p5:
iwidth = cpspch(p5)/cpspch(8.00) * 10 ; calculate the width
kband randh iwidth kr ; band width 20 Hz
asig oscil kenv * p4, cpspch(p5)+kband, 1 ; makes noise
The scaling of one parameter by another need not be linear. It could involve a more complex arithmetic expression, or it could index a function table (perhaps containing exponential segments).
iwidth = sqrt(cpspch(p5)) ; width is square root of pitch
OR
iwidth table cpspch(p5), 4 ; get width from table 4
Reassigning p3
At times it is useful to reassign p3 within the instrument. The reasons for doing this are:
The reassignment of p3 can be done through a conditional statement, or simply through an assignment statement:
p3 = (p3 < .25 ? .25 : p3)
OR
p3 = 11.888*(cpspch(p5)/cpspch(8.00)
Designing an instrument step-by-step
Begin with one foscil and a two part envelope
instr 1
ipitch = cpspch(p5) ; convert the pitch
kenv linseg 0, .05, 1.2, .03, 1, p3-.08, 2.4 ; a two part envelope
kmult expseg 1, .08, 1, p3 -.08, .0001
kenv = kenv * kmult
asig foscili kenv * p4, ipitch, 1, 1.005, 1, 1 ;slightly inharmonic
outs asig, asig
endin
instr 2
ipitch = cpspch(p5) ; convert the pitch
kenv linseg 0, .05, 1.2, .03, 1, p3-.08, 2.4 ; a two part envelope
kmult expseg 1, .08, 1, p3 -.08, .0001
kenv = kenv * kmult
asig1 foscili kenv*p4, ipitch, 1, 1.005, 1, 1 ;slightly inharmonic
asig2 foscili kenv*p4, ipitch, 1, 1.002, 1, 1 ;slightly inharmonic
asig3 foscili kenv*p4, ipitch, 1, 1.009, 1, 1 ;slightly inharmonic
asig = (asig1 + asig2 + asig3)/3
outs asig, asig
endin
instr 3
ipitch = cpspch(p5) ; convert the pitch
kenv linseg 0, .05, 1.2, .03, 1, p3-.08, 2.4 ; a two part envelope
kmult expseg 1, .08, 1, p3 -.08, .0001
kenv = kenv * kmult
asig1 foscili kenv * p4, ipitch, 1, 1.005, 1, 1 ;slightly inharmonic
asig2 foscili kenv * p4, ipitch, 1, 1.002, 1, 1 ;slightly inharmonic
asig3 foscili kenv * p4, ipitch, 1, 1.009, 1, 1 ;slightly inharmonic
knenv linseg .032, .06, .022, p3-.06, .022 ; bandwidth multiplier
knoise randi knenv*ipitch, kr ; generate rand freq
anoise oscili kenv*p4, knoise+ipitch, 1 ; generate noise
asig = (asig1 + asig2 + asig3 + anoise) / 4 ; balance outputs
outs asig, asig
endin
instr 4
ipitch = cpspch(p5) ; convert the pitch
kenv linseg 0, .05, 1.2, .03, 1, p3-.08, 2.4 ; a two part envelope
kmult expseg 1, .08, 1, p3 -.08, .0001
kenv = kenv * kmult
krand1 randi ipitch *.007, 8, .1 ; randi with seed
krand2 randi ipitch *.008, 9, .2 ; randi with seed
krand3 randi ipitch *.009, 6, .3 ; randi with seed
asig1 foscili kenv * p4, ipitch+krand1, 1, 1.005, 1, 1
asig2 foscili kenv * p4, ipitch+krand2, 1, 1.002, 1, 1
asig3 foscili kenv * p4, ipitch+krand3, 1, 1.009, 1, 1
knenv linseg .032, .06, .022, p3-.06, .022 ; bandwidth multiplier
knoise randi knenv*ipitch, kr ; generate rand freq
anoise oscili kenv*p4, knoise+ipitch, 1 ; generate noise
asig = (asig1 + asig2 + asig3 + anoise) / 4 ; balance outputs
outs asig, asig
endin
instr 5
ipitch = cpspch(p5) ; convert the pitch
kenv linseg 0, .05, 1.2, .03, 1, p3-.08, 2.4 ; a two part envelope
kmult expseg 1, .08, 1, p3 -.08, .0001
kenv = kenv * kmult
kline1 linseg .08, .07, .0109, p3-.07, .006 ; line for rand1
kline2 linseg .09, .07, .0095, p3-.07, .0055 ; line for rand2
kline3 linseg .1, .07, .0086, p3-.07, .0035 ; line for rand3
kline4 linseg .1, .07, .0086, p3-.07, .0055 ; line for rand speed
kline4 = kline4 * ipitch ; set rand speed
krand1 randi ipitch*kline1, kline4, .1 ; randi with seed
krand2 randi ipitch*kline2, kline4+1, .2 ; randi with seed
krand3 randi ipitch*kline3, kline4-1, .3 ; randi with seed
asig1 foscili kenv*p4, ipitch+krand1, 1, 1.005, 1, 1
asig2 foscili kenv*p4, ipitch+krand2, 1, 1.002, 1, 1
asig3 foscili kenv*p4, ipitch+krand3, 1, 1.009, 1, 1
knenv linseg .032, .06, .022, p3-.06, .022 ; bandwidth multiplier
knoise randi knenv*ipitch, kr ; generate rand freq
anoise oscili kenv*p4, knoise+ipitch, 1 ; generate noise
asig = (asig1+asig2+asig3+anoise)/4 ; balance outputs
outs asig, asig
endin
instr 6
ipitch = cpspch(p5) ; convert the pitch
kenv1 linseg 0, .05, 1.2, .03, 1, p3-.08, 2.4 ; a two part envelope
kenv2 linseg 0, .045, 1.2, .032, 1, p3-.077, 2.4
kenv3 linseg 0, .052, 1.2, .032, 1, p3-.084, 2.4
kmult expseg 1, .08, 1, p3 -.88, .0001
kenv1 = kenv1 * kmult
kenv2 = kenv2 * kmult
kenv3 = kenv3 * kmult
kline1 linseg .08, .07, .0109, p3-.07, .006 ; line for rand1
kline2 linseg .09, .07, .0095, p3-.07, .0055 ; line for rand2
kline3 linseg .1, .07, .0086, p3-.07, .0035 ; line for rand3
kline4 linseg .1, .07, .0086, p3-.07, .0055 ; line for rand speed
kline4 = kline4*ipitch ; set rand speed
krand1 randi ipitch*kline1, kline4, .1 ; randi with seed
krand2 randi ipitch*kline2, kline4+1, .2 ; randi with seed
krand3 randi ipitch*kline3, kline4-1, .3 ; randi with seed
asig1 foscili kenv1*p4, ipitch+krand1, 1, 1.005, 1, 1
asig2 foscili kenv2*p4, ipitch+krand2, 1, 1.002, 1, 1
asig3 foscili kenv3*p4, ipitch+krand3, 1, 1.009, 1, 1
knenv linseg .032, .06, .022, p3-.06, .022 ; bandwidth multiplier
knoise randi knenv*ipitch, kr ; generate rand freq
anoise oscili kenv1*p4, knoise+ipitch, 1 ; generate noise
asig = (asig1+asig2+asig3+anoise)/4 ; balance outputs
outs asig, asig
endin
instr 7
ipitch = cpspch(p5) ; convert the pitch
kenv1 linseg 0, .05, 1.2, .03, 1, p3-.08, 2.4 ; a two part envelope
kenv2 linseg 0, .045, 1.2, .032, 1, p3-.077, 2.4
kenv3 linseg 0, .052, 1.2, .032, 1, p3-.084, 2.4
kmult expseg 1, .08, 1, p3 -.08, .0001
kenv1 = kenv1*kmult
kenv2 = kenv2*kmult
kenv3 = kenv3*kmult
kline1 linseg .08, .07, .0109, p3-.07, .006 ; line for rand1
kline2 linseg .09, .07, .0095, p3-.07, .0055 ; line for rand2
kline3 linseg .1, .07, .0086, p3-.07, .0035 ; line for rand3
kline4 linseg .1, .07, .0086, p3-.07, .0055 ; line for rand speed
kline4 = kline4*ipitch ; set rand speed
krand1 randi ipitch*kline1, kline4, .1 ; randi with seed
krand2 randi ipitch*kline2, kline4+1, .2 ; randi with seed
krand3 randi ipitch*kline3, kline4-1, .3 ; randi with seed
asig1 foscili kenv1*p4, ipitch+krand1, 1, 1.005, 1, 1
asig2 foscili kenv2*p4, ipitch+krand2, 1, 1.002, 1, 1
asig3 foscili kenv3*p4, ipitch+krand3, 1, 1.009, 1, 1
knenv linseg .032, .06, .022, p3-.06, .022 ; bandwidth multiplier
knoise randi knenv*ipitch, kr ; generate rand freq
anoise oscili kenv*p4, knoise+ipitch, 1 ; generate noise
asig = (asig1+asig2+asig3+anoise)/4 ; balance outputs
ga1 = ga1 + asig ; send to global reverb
outs asig, asig
endin
instr 8 ; REVERB
ga1 init 0
asig reverb ga1, 0.8
outs asig, asig
ga1 = 0
endin
Index | Next Week | Previous Week |