Csound - Final Project

MP3下載

這次的比較能聽了....
/*
Csound - Final Project
Author: Kong Kao
Advisor: Prof. James Ma

This project uses pre-entered chords to implement auto-composition.
Chords are stored by their roots in tables.
Instr 1 decides how the chord goes, and store the way the music would go
into a function table (giftMelody).
Instr 2 does 3 part of music:
1. The root of the chord.
2. A melody generated by an algorithm with random.
3. Accompaniment
*/
<CsoundSynthesizer>
<CsOptions>
</CsOptions>

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

; Global a-rate variabe used for reverberation
gaSig init 0

; Some constant for convenience
giSemiTone init 2^(1/12)
giLoopLength init 8 ; Seconds a period would use.

; Function tables
giftScale init 2
giftMelody ftgen 0, 0, 8192, -2, 0, 8192, 0 ; Overall roots of chords

; Function tables that stores the chords.
; The name of them is only meaningful for me, so don't mind it...XD
giftBallad init 1
giftHappy init 4
giftToDearYou init 5


instr 1
/*
No signal output, but need to have the same length with i2.
Used to assign the overall roots to the function table giftMelody
Note that only the value is neither semitones nor intervals, but the
index of the tone in giftScale.
*/
aPhasor phasor 1/giLoopLength
INIT0:
iSwitch = floor(rnd(3))
if( iSwitch == 0 ) then
iFt = giftBallad
elseif( iSwitch == 1 ) then
iFt = giftHappy
else
iFt = giftToDearYou
endif
aMelody table aPhasor, iFt, 1
timout 0, giLoopLength, CONT0
reinit INIT0
CONT0:
rireturn
aPhasor phasor 1/p3
tablew aMelody, aPhasor, giftMelody, 1
endin


instr 2
iUnit = 0.25 ; The shortest length of a note, measured in seconds
iAmp = ampdb( p4 )
iBaseFreq = p5

kPhasor phasor 1/p3
kMelody table kPhasor, giftMelody, 1
kPitch table kMelody, giftScale
kFreq = iBaseFreq * giSemiTone ^ kPitch / 2
aSig1 oscil iAmp, kFreq, 11

; ----------------------------------------------------------
iPrevPitch = 3
iPrevInterval = 0
iPosition = 0
/*
Use a variable to store the position of the current note in the period.
This is used to decide which chord it is for the note.
*/
INIT2:
/*
Decide the interval of this note with the root of the chord.
If the previous interval tends to be balanced (such as 4th tends to
3rd, and 7th tends to octave), set the interval to the tension. (Note
that this may go wrong as the chord changes)
Note that the "interval" is stored one less than what we call it.
*/
if( iPrevInterval == 3 ) then
iInterval = 2
elseif( iPrevInterval == 6 ) then
iInterval = 7
else
INTERV2:
iInterval table rnd(ftlen(3)), 3
cigoto ( iInterval < 0 ), INTERV2
endif

/*
Fetch what the chord here it is and calculate the tone to be played.
If the interval with the previous note is bigger than octave,
then choose the interval again randomly.
*/
iRootIndex table iPosition/p3, giftMelody, 1, 0, 1
iPitch table iRootIndex + iInterval, giftScale
cigoto ( abs( iPitch - iPrevPitch ) > 12 ), INTERV2

/*
Decide the length of this note.
For disonant tones (those not in the triad chord of the given root),
set the length of it short.
*/
if( iInterval != 0 \
&& iInterval != 2 \
&& iInterval != 4 \
&& iInterval != 7 \
) then
iDur = iUnit
else
iDur = (int(rnd(3))+1)*iUnit
endif

kAmp expseg 0.01, 0.1, 1, iDur-0.2, 0.25, 0.1, 0.01

iFreq = iBaseFreq * giSemiTone ^ iPitch
kVibEnv linseg 0, 0.3, 0, iDur-0.3, 0.5
kVibAmp lfo kVibEnv, 10
kFreq = iFreq * ( 1 + kVibAmp )

kForm line 600, iDur, 800
kBand line 60, iDur, 80
aSig2 fof iAmp * kAmp, kFreq, kForm, 0, kBand, \
0.005, 0.02, 0.07, 64, 14, 15, iDur


if( iDur > 0.3 ) then
gaSig = gaSig + aSig2 / 2
endif
iPosition = iPosition + iDur
iPrevPitch = iPitch
iPrevInterval = iInterval
timout 0, iDur, CONT2
reinit INIT2
CONT2:
rireturn

; ---------------------------------------------------------------------
iPosition3 = 0
iPrevPitch31 = 0
iPrevPitch32 = 0
INIT3:
/*
Decide 2 tones to play.
floor(rnd(3))*2 is used to decide the semitones with the root would be,
that is, they're deciding whether the the interval is 1st, 3rd, or 5th.
*/
iRootIndex3 table iPosition3/p3, giftMelody, 1, 0, 1
iPitch31 table iRootIndex3 + floor(rnd(3))*2, giftScale
iPitch32 table iRootIndex3 + floor(rnd(3))*2, giftScale
iFreq31 = iBaseFreq * giSemiTone ^ iPitch31 * 2 ^ floor(birnd(1))
iFreq32 = iBaseFreq * giSemiTone ^ iPitch32 * 2 ^ floor(rnd(2))

kAmp3 linseg 0, 0.2, 1, iUnit-0.2, 0
aSig31 oscil iAmp*kAmp3, iFreq31/2, 13
aSig32 oscil iAmp*kAmp3, iFreq32/2, 12

if( iFreq31 < 220 ) then
gaSig = gaSig + aSig31 * abs( 220 - iFreq31 ) / 220
endif

iPrevPitch31 = iPitch31
iPrevPitch32 = iPitch32
iPosition3 = iPosition3 + iUnit
timout 0, iUnit, CONT3
reinit INIT3
CONT3:
rireturn
aSig3 = ( aSig31 + aSig32 ) / 2


aSig sum aSig1/2, aSig2, aSig3
kAmp linseg 1, p3-4, 1, 4, 0.01
aSig = aSig * kAmp
out aSig
endin

instr 101
aSig reverb gaSig, 0.5
out aSig
gaSig = 0
endin


</CsInstruments>

<CsScore>
/*
Function table 1 and 4:
Stores the roots of the chords by the index of the note in f2.
By using GEN7 and big enough table, we can then set the chord to change
in a nonregular way, that is, chord may change not only at the 1st beat
of a bar.
*/
f 1 0 64 -7\
3 8 3 0 \
7 8 7 0 \
8 8 8 0 \
7 8 7 0 \
6 8 6 0 \
5 8 5 0 \
6 8 6 0 \
7 4 7 0 \
0 4 0

f 4 0 16 -7\
3 4 3 0 \
1 4 1 0 \
6 4 6 0 \
7 2 7 0 \
0 2 0

f 5 0 32 -7\
6 4 6 0 \
7 4 7 0 \
3 2 3 0 \
2 2 2 0 \
1 4 1 0 \
6 4 6 0 \
7 4 7 0 \
3 8 3

/*
Function table 2
Stores major scale in numbers of semitones
between the tonic and each one.
*/
f 2 0 16 -2 \
-5 -3 -1 0 2 4 5 7 \
9 11 12 14 16 17 19 21

/*
Function table 3
Stores the probability of an interval to be used.
More a number appears, more the inteval would be used.
*/
f 3 0 64 -7 \
0 5 0 0 \
1 5 1 0 \
2 10 2 0 \
3 3 3 0 \
4 7 4 0 \
5 12 5 0 \
6 2 6 0 \
7 8 7 0 \
-1 64 -1

/*
Function tables for timbre
*/
f 11 0 8193 10 1 0.5 0.25
f 12 0 8193 10 1 0.1 0.2 0.3 0.4 0.3 0.2 0.1
f 13 0 8193 10 1 0.4 0.3 0.2 0.1
f 14 0 8193 10 1
f 15 0 8192 19 0.5 0.5 260 0.5


i 1 0 16
i 2 0 16 75 220
i 101 0 17
e

</CsScore>
</CsoundSynthesizer>

沒有留言: