Csound作業五 - 自動作曲??


/*
Csound Exercise 05
Author: Kong Kao
Advisor: Prof. James Ma

This exercise focuses on conditional branch, including opcodes such as
reinit, rireturn, and timout....
The basic idea of this piece is an algorithm to compose in a single mode.
The function table stores different data and may be used in different way.

For future work, I'd like to add other possibility parameters to make the
piece has a feeling of tonic and some rhythm.
*/
<CsoundSynthesizer>
<CsOptions>
</CsOptions>

<CsInstruments>
; Initialize the global variables.
sr = 44100
kr = 4410
ksmps = 10
nchnls = 2


; Some constant for convenience
giScale init 1
giInterval init 2
giSemiTone init 2^(1/12)

gaSig1 init 0

instr 1
iBaseFreq = p4
iAmp = p5
iAmp2 = p6
iAmp3 = p7
iPrevPitchIndex init 9

INIT:
;seed rnd(2^32)
; Randomly choose an interval to decide the next note
iTemp = rnd( ftlen(giInterval) )
iInterval table iTemp, giInterval
cigoto ( iInterval < 0 ), INIT

; Decide the melody would go up or down
if( birnd(1) > 0 ) then
iPitchIndex = iPrevPitchIndex + iInterval
else
iPitchIndex = iPrevPitchIndex - iInterval
endif
cigoto ( iPitchIndex < 0 ), INIT
cigoto ( iPitchIndex >= ftlen(giScale) ), INIT
iPitch table iPitchIndex, giScale

; Decide other tones
; 3rd, 4th, 5th, 6th would be consonant. Care about neither A4 nor d5.
; The 3 tones would be a triad.
iVerticalInterval = floor( rnd(4) ) + 3
if( iVerticalInterval == 3 ) then
iVerticalInterval2 = 5 + floor( rnd(2) )
elseif( iVerticalInterval == 4 ) then
iVerticalInterval2 = 6
elseif( iVerticalInterval == 5 ) then
iVerticalInterval2 = 3
elseif( iVerticalInterval == 6 ) then
iVerticalInterval2 = 3 + floor( rnd(2) )
endif

if( iPitchIndex < ftlen( giScale ) / 2 ) then
iPitch2 table iPitchIndex + iVerticalInterval, giScale
iPitch3 table iPitchIndex + iVerticalInterval2, giScale
else
iPitch2 table iPitchIndex - iVerticalInterval, giScale
iPitch3 table iPitchIndex - iVerticalInterval2, giScale
endif

iFreq = iBaseFreq * giSemiTone^iPitch
iFreq2 = iBaseFreq * giSemiTone^iPitch2 / 4 ; Bass melody
iFreq3 = iBaseFreq * giSemiTone^iPitch3

; Choose a duration
iDur = (int(rnd(4))+1)*0.25

; Amplitude
kPhase phasor 1/iDur
kTableIndex = kPhase * ftlen(21)
kAmp table3 kTableIndex, 21 + floor( rnd(4) )
kAmp2 table3 kTableIndex, 21 + floor( rnd(4) )
kAmp3 table3 kTableIndex, 21 + floor( rnd(4) )
kAmp = kAmp * iAmp
kAmp2 = kAmp2 * iAmp2
kAmp3 = kAmp3 * iAmp3

/*
Since I'd like to assign the timbre of the bass dynamically
The signal processing would be here, instead of after label CONT
*/
aSig2S oscili kAmp2, iFreq2, 12
aSig2E oscili kAmp2, iFreq2, 14 + floor(rnd(3))
kLine line 0, iDur, 1
aSig2 = aSig2S * kLine + aSig2E * ( 1 - kLine )

; Store the pitch index for next note to use.
iPrevPitchIndex = iPitchIndex
timout 0, iDur, CONT
reinit INIT
CONT:
aSig1 oscili kAmp, iFreq, 11
aSig3 oscili kAmp3, iFreq3, 13
aSig = aSig1 + aSig2 + aSig3
rireturn
kAmpOverAll linseg 0, p3/6, 0.7, p3*2/3, 0.9, p3/6, 0
aSig = aSig * kAmpOverAll

outs aSig, aSig
endin

</CsInstruments>

<CsScore>
/*
Function table 1
Stores a scale in numbers of semitones between the tonic and each one.
It must be a diatonic scale in this exercise to let the contrapound
consonant tone to go right..(in natural 3rd, 4th, 5th, 6th,
instead of any other dissonant intervals.)
For now, this table stores a harmonic minor.
*/
f 1 0 16 -2 \
-4 -1 0 2 3 5 7 8 11 12 14 15 17 19 21 22

/*
Function table 2
Stores the possibility of each interval, which would be used randomly.
For example, if the number denoting an interval has the amount of
appearance to be 6, then the possibility of the interval to be used
would be "6 / ftlen(thisTable)"
For simplicity, 0 would mean the interval to be perfect 1st, but -1 is
also used for the random procedure to goes again.
*/
f 2 0 64 -7 \
0 4 0 0 \
1 8 1 0 \
2 7 2 0 \
3 6 3 0 \
4 5 4 0 \
5 4 5 0 \
6 3 6 0 \
7 2 7 0 \
8 1 8 0 \
-1 64 -1 \

; Function tables for timbre....
f 11 0 8193 10 \
8 4 2 1
f 12 0 8193 10 \
1 2 3 4
f 13 0 8193 10 \
4 3 2 1
f 14 0 8193 11 10 1 0.5
f 15 0 8193 11 8 1 1.5
f 16 0 8193 11 12 1 -0.5

; Envelopes
f 21 0 8193 5 \
0.1 1024 1 1024 0.7 4096 0.4 2048 0.01
f 22 0 8193 8 \
0 1024 1 1024 0.7 4096 0.4 2048 0
f 23 0 8193 5 \
0.1 1024 1 6144 0.7 1024 0.01
f 24 0 8193 8 \
0.1 1024 1 6144 0.7 1024 0.01

i 1 0 60 220 12000 16000 8000
e

</CsScore>
</CsoundSynthesizer>

沒有留言: