Hi,
I have been playing around with CSound 5.10 and realtime MIDI, using Terminal on Mac OSX4.11 - and am in need of some help. I've worked mainly by trying out and then adapting examples from the canonical manual such as midion_simple.csd.
I've been able to make an instrument which, when you play in a series of chords on a MIDI keyboard, tells you how many notes there were in each of them. As soon as you play the 2nd chord, it tells you how many notes there were in the 1st, and so on. It does this by measuring the time between the start of each note, and treating each pair of notes that are within 0.03 secs of each other as being part of the same chord:
<CsoundSynthesizer>
<CsOptions>
-odac -iadc -d -M1
</CsOptions>
<CsInstruments>
sr = 44100
kr = 4410
ksmps = 10
nchnls = 2
; Tells you how many notes there are in the chord you played
ginotecount init 0
instr 1 ;Triggered by MIDI notes
ginotecount = ginotecount+1
if ginotecount=1 then
gitime1 times
else
gitime2 times
igap = gitime2-gitime1
if (igap>0.03) then
prints "%d notes in last chord\\n", ginotecount-1
ginotecount = 1
endif
gitime1 = gitime2
endif
endin
</CsInstruments>
<CsScore>
f0 45
</CsScore>
</CsoundSynthesizer>
What I want to do now is get it to react as soon as the chord is played - ie as soon as 0.03 seconds have passed without another note-on message being received. My best guess for this is given below, but it doesn't work - just hangs, regardless of MIDI input (there may be something wrong with my k's and i's?). I want Instrument 2 just to sit there and wait until 0.03secs has passed since ginotecount last increased. Any advice much appreciated.
<CsoundSynthesizer>
<CsOptions>
-odac -iadc -d -M1
</CsOptions>
<CsInstruments>
sr = 44100
kr = 4410
ksmps = 10
nchnls = 2
; Tells you how many notes there are in the chord you played (straight away)
massign 0,1
ginotecount init 0
instr 1 ;Triggered by MIDI notes
ginotecount = ginotecount+1
if ginotecount=1 then
gitime1 times
else
gitime2 times
igap = gitime2-gitime1
if (igap>0.03) then
ginotecount = 1
endif
gitime1 = gitime2
endif
endin
instr 2 ;runs for 45 seconds
start_waiting:
itime times
icount = ginotecount
check_time:
if (ginotecount=0 || ginotecount>icount) goto start_waiting
ktime times
kgap = ktime-itime
if (kgap>0.03) then
prints "There were %d notes in that chord\\n", ginotecount
goto start_waiting
else
goto check_time
endif
endin
</CsInstruments>
<CsScore>
i 2 0 45
</CsScore>
</CsoundSynthesizer>



Another way...
I took a quick look at your code, and I can point out some things.
For the first thing, "massign 0,1" doesn't make much sense (and gave me an error) as there is no channel "0".
Your "instr 2" mixes up init-time and perf-time variables and conditionals far too much. Your run it for 45 secs, but the 'i' variables only get set to anything right at start-up, and the if statements that test them (and the 'prints') are only meaningful at that time also. So it will never see any changes in ginotecount.
I couldn't find any simple way of changing instr 2 to make it work, but I suggest a much simpler way! Look at the 'active' opcode, and then reset your thinking a bit (:-)) to a more straightforward approach. I did what you want in about 10 lines (two simple instruments). I won't post the code here now [for the sake of your own discovery! (:-)] but if you get stuck I will later.
active
Thanks for your thoughts Pete.
You might have to show me what you have in mind with
active. I've tried making a simpler instr 1, as follows, which is intended just to count the number of held notes that are played, and then to print the total once the notes start to be released...ginotecount = ginotecount+1kcount active 1
if (ginotecount>kcount) then
prints "%d notes in that chord\\n", ginotecount
ginotecount = 0
endif
... however this just displays '1 notes in that chord' upon every note-on.
By the way I understand
massign 0,1to mean that instr 1 is set to receive MIDI input on all channels - works fine for me.Using 'active'
Ahh... massign -- my bad. I should check current docs before I spout! I have to confess to usually staying with Csound4 (as I haven't yet built 5 on the alternative OS I mostly use), and that ability of massign seems to have been added since.
Anyway, here's how I used 'active' to get chord size:
instr 1 ;Triggered by MIDI notes
; but otherwise does nuthin at all
endin
instr 2 ;runs for 45 seconds
kchord init 0
kactv active 1
if kactv > kchord then
kchord = kactv
elseif kactv = 0 && kchord > 0 then
printks "chord had %d note(s)\\n", 1, kchord
kchord = 0
endif
endin
I thought later it might be possible to do it in one instrument by using 'xtratim' and 'release' to check when the last key was lifted, but I couldn't make that work.
HTH
Progress
Thanks for this.
The whole k vs. i concept is now starting to sink in and I'm moving forward. The last time I wrote any code it was in BASIC so there's a certain amount of adjustment going on!