This would be my basic monophonic-glide template. (You need to play notes from an external MIDI keyboard or the QWERTY keyboard to hear the glides as notes need to overlap.)
<Cabbage>
form caption("Untitled") size(400, 300), guiMode("queue"), pluginId("def1")
keyboard bounds(8, 158, 381, 95)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables.
ksmps = 32
nchnls = 2
0dbfs = 1
;instrument will be triggered by keyboard widget
instr 1
icps cpsmidi
gkcps = icps ; set global variable for oscillator frequency to MIDI freq.
; coexisting notes are piled up so that the lasat note played will dictate the value of gkcps
; only turn instr 2 on for the first note of a legato phrase
if active:i(p1) == 1 then
turnon 2
endif
endin
instr 2
kport = 0.05 * linseg:k(0,0.001,1) ; change 0.05 for longer or shorter portamento times
kcps portk gkcps, kport
a1 vco2 0.2, kcps
a1 *= linsegr:a(0,0.01,1,0.01,0)
outs a1,a1
; when all MIDI notes (instr 1) have been released, turn this instrument off
if active:k(1) == 0 then
turnoff
endif
endin
</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z
</CsScore>
</CsoundSynthesizer>
instr 1
simply keeps track of MIDI notes. Only one instance of instr 2
is ever instantiated and it creates the audio.
It’s a combination of turnon
, turnoff
, active
and the use of a global variable for oscillator pitch such that multiple iterations of the instr 1
will overwrite the variable with the most recent note taking precedence when the variable is read in instr 2
.
The problem with portk that you describe can be circumvented with the linseg
trick you see here, but if you like lagud
stick with that.
Envelopes applied to an entire legato phrase should be placed in instr 2
. Envelopes that should be retriggered upon every note, whether legato or not, should be placed in instr 1
with a global variable output.
Things get more complicated if instr 2 has a long release time but can be handled.
Being able to switch between between monophonic and polyphonic while sharing most of the code is also possible but care needs to be taken in the design.