如何在 Csound 的乐器定义中包含持续时间
How to include durations in an instrument definition in Csound
使用函数 oscil
,我定义了一个具有给定频率和振幅的振荡器组:
instr 1
a1 oscil .3, 110
outs a1,a1
a2 oscil .2, 220
outs a2,a2
a3 oscil .1, 330
outs a3,a3
endin
我知道我可以在 orchestra
部分设置持续时间。但是我怎样才能为不同的振荡提供不同的持续时间呢?我可以在 instrument
定义中这样做吗?因为我希望能够在 orchestra
:
中用一行调用仪器(3 个振荡器)
;instr start duration
i 1 0 ;duration of oscils defined under instr 1
e
仪器实例中的操作码实例都共享相同的处理上下文(即 p3/duration)。这里有几种不同的策略可以用来获得不同的持续时间:
- 使用多个仪器实例,每个仪器有一个振荡器。这可能是最灵活但最冗长的。
使用某种形式的包络并将其与每个振荡器的输出相乘。例如:
instr 1
p3 = 4
a1 oscil .3, 110
aenv1 linseg 1, 3, 1, 0.01, 0, 0.99, 0
a1 *= aenv1
outs a1,a1
...
endin
在#2 中,持续时间由仪器设置。 linseg 用作信封并写入持续时间。然后可以使用多个 linseg/oscil 对并手写每个部分的持续时间。
我想到的是对您在乐器中创建的每个正弦曲线应用不同的包络:
0dbfs = 1
instr 1
kFirstEnvelope line 0, p3, 1
kSecondEnvelope line 0.5, p3, 0.5
kThirdEnvelope line 1, p3, 0
aFirstSine oscili 1, 440
aSecondSine oscili 1, 660
aThirdSine oscili 1, 880
aMix balance aFirstSine * kFirstEnvelope + aSecondSine * kSecondEnvelope + aThirdSine * kThirdEnvelope, a(0.15)
outs aMix, aMix
endin
然后您可以使用一行代码从乐谱中调用 instr 1
,您可能会想出比上面的信封更有趣的信封。
i 1 0 10
但是,如果您正在进行加法合成,更优雅的方法是在 [=16] 中使用 event_i
从 单独的 乐器触发多个乐谱事件=]循环。
instr 2
seed 0
iNoteIndex = 0
iNoteCount = 30
until iNoteIndex == iNoteCount do
iRandomStart = random(0, p3)
iRandomDuration = random(1.2, 0.5 * p3)
event_i "i", 3, iRandomStart, iRandomDuration
iNoteIndex += 1
enduntil
endin
instr 3
iAttack = .2
iDecay = .2
iSustain = .4
iRelease = 0.6
aSineWave oscili 0.1, random(200, 4000)
kEnvelope adsr iAttack, iDecay, iSustain, iRelease
outs aSineWave * kEnvelope
endin
然后您可以从乐谱调用 instr 2
,这将负责调用 instr 3
。
i 2 0 10
干杯
使用函数 oscil
,我定义了一个具有给定频率和振幅的振荡器组:
instr 1
a1 oscil .3, 110
outs a1,a1
a2 oscil .2, 220
outs a2,a2
a3 oscil .1, 330
outs a3,a3
endin
我知道我可以在 orchestra
部分设置持续时间。但是我怎样才能为不同的振荡提供不同的持续时间呢?我可以在 instrument
定义中这样做吗?因为我希望能够在 orchestra
:
;instr start duration
i 1 0 ;duration of oscils defined under instr 1
e
仪器实例中的操作码实例都共享相同的处理上下文(即 p3/duration)。这里有几种不同的策略可以用来获得不同的持续时间:
- 使用多个仪器实例,每个仪器有一个振荡器。这可能是最灵活但最冗长的。
使用某种形式的包络并将其与每个振荡器的输出相乘。例如:
instr 1 p3 = 4 a1 oscil .3, 110 aenv1 linseg 1, 3, 1, 0.01, 0, 0.99, 0 a1 *= aenv1 outs a1,a1 ... endin
在#2 中,持续时间由仪器设置。 linseg 用作信封并写入持续时间。然后可以使用多个 linseg/oscil 对并手写每个部分的持续时间。
我想到的是对您在乐器中创建的每个正弦曲线应用不同的包络:
0dbfs = 1
instr 1
kFirstEnvelope line 0, p3, 1
kSecondEnvelope line 0.5, p3, 0.5
kThirdEnvelope line 1, p3, 0
aFirstSine oscili 1, 440
aSecondSine oscili 1, 660
aThirdSine oscili 1, 880
aMix balance aFirstSine * kFirstEnvelope + aSecondSine * kSecondEnvelope + aThirdSine * kThirdEnvelope, a(0.15)
outs aMix, aMix
endin
然后您可以使用一行代码从乐谱中调用 instr 1
,您可能会想出比上面的信封更有趣的信封。
i 1 0 10
但是,如果您正在进行加法合成,更优雅的方法是在 [=16] 中使用 event_i
从 单独的 乐器触发多个乐谱事件=]循环。
instr 2
seed 0
iNoteIndex = 0
iNoteCount = 30
until iNoteIndex == iNoteCount do
iRandomStart = random(0, p3)
iRandomDuration = random(1.2, 0.5 * p3)
event_i "i", 3, iRandomStart, iRandomDuration
iNoteIndex += 1
enduntil
endin
instr 3
iAttack = .2
iDecay = .2
iSustain = .4
iRelease = 0.6
aSineWave oscili 0.1, random(200, 4000)
kEnvelope adsr iAttack, iDecay, iSustain, iRelease
outs aSineWave * kEnvelope
endin
然后您可以从乐谱调用 instr 2
,这将负责调用 instr 3
。
i 2 0 10
干杯