How to create a loop with midi-input

I’m testing a midi-instrument doing a sequence of notes while
triggered by a midi note.
Although the code is very straightforward I can’t make it loop while the midi note is pressed.
The loop should be going in a ‘until condition do’ construction, but fails to do so. Testing on kEnd release == 1, or midinoteoff key, key == currentkey doesn’t seem to do nothing at all.
I suppose it’s something very basic that I’m forgetting, but it is annoying. I tried to make it work for a couple of days now without any success.
My code is as follows:

sr = 44100
ksmps = 8
nchnls = 2
0dbfs = 1

giSine ftgen 0, 0 , 2048, 10, 1, 0, .5, 0, -.25, 0, .125, 0, - 0.0625
massign 0, “arpeggiator”

instr arpeggiator

iNoteNr notnum

kEnd release ; should return 1 when the key is released
kkey init 0 ; initializing k-values for midinoteoff
kvel init 0
midinoteoff kkey, kvel ;kkey should return the current, running midinote

ipch1 cpsmidinn iNoteNr
ipch2 cpsmidinn iNoteNr - 1
ipch3 cpsmidinn iNoteNr - 2
ipch4 cpsmidinn iNoteNr - 3

iamp ampmidi .6
iNoteDur = 0.26

until kkey == iNoteNr do
; Or until kEnd == 1 do

schedule	"playNote", 0, iNoteDur, ipch1, 0.6
schedule	"playNote", 0.25, iNoteDur, ipch2, 0.4
schedule	"playNote", 0.5, iNoteDur, ipch3, 0.4
schedule 	"playNote", 0.75, iNoteDur, ipch4, 0.5
schedule	"playNote", 1.0, iNoteDur,ipch3, 0.4
schedule	"playNote", 1.25, iNoteDur, ipch2, 0.4


instr playNote
iDur = p3
iPitch = p4
iAmp = p5
aEnv adsr p30.05, p30.5, 0.5, p3*0.45

aMid poscil iAmpaEnv, iPitch, giSine
aLft poscil iAmp
aEnv, iPitch1.03, giSine
aRgt poscil iAmp
aEnv, iPitch*0.97, giSine

aLeft = (aMid + aLft) /2
aRight = (aMid + aRgt)/2

outs aLeft, aRight

the problem is that you use “schedule” which is only calling the events
once, at init-time
(The Csound FLOSS Manual).

i am not sure how to do best what you want to achieve. (there are
several possibilities.) do you always want to restart the arpeggio
after 1.5 seconds?

Thank you for answering.

The whole instrument is a test case in which I try to make the loop going. The way I coded it now is musically not really interesting, so if I can make it run a lot of randomization of variables, including interval times, pitch, amplitude etc. will be made. But essentially the sequence has to restart every time it’s finished.
For now I get several problems. Testing with kkey == iNoteNr, kkey NEVER gives a printed TRUE-value. Testing with kEnd == 1 freezes CSound completely and I have to Force-Quit it.
So, apart from the looping problem there are several other issues that I apparently don’t understand.
I’m not a novice to programming, but I am sure that somehow I mix up i-time, k-time and a-time events.

If I can get even a hint on how to proceed I think I can figure out a lot of it on my own.

ok i have an idea about what you try to do, and which issues arise. to
quote john’s nice monthly email: we have all been there.

this is a program which

  1. waits for a midi note-on event
  2. loops a sequence of sounds as long as the midi key is pressed

i hope it helps; otherwise please feel free to get back here and send
some code which you tried but did not work. (i could have avoided the
use of an array but i think it offers more potential for future changes.)


//send all midi note events to instrument “Midi”

instr Midi
//get the note number
iNoteNum = notnum()
//get the note velocity and convert it to dB
iVelDb = veloc(-40,0)
//create array with pitches to add
kPitchesToAdd[] = fillarray(0,3,-1,2,5)
//initialize an index to point to array elements
kIndx init 0
//metro ticks twice a second
kTrigger = metro(2)
//if metro ticks
if (kTrigger==1) then
//calculate note to send to the sound producing instrument
kMidiPitch = iNoteNum + kPitchesToAdd[kIndx]
//call the instrument to produce sound
//increase index
kIndx = (kIndx+1) % lenarray(kPitchesToAdd)

instr Play
iMidiNote = p4
iDb = p5
aSound = pluck(ampdb(iDb),mtof:i(iMidiNote),mtof:i(iMidiNote),0,1)
aSound = linen:a(aSound,0,p3,p3/2)