Cabbage Logo
Back to Cabbage Site

Polyphonic variables in Csound: how to pick one value?

Hi! I’m working on a granular instrument with a visual pointer showing the sample playback position. Everything works fine sonically, but there’s an ambiguity in polyphonic mode: when multiple instances of the same instrument play different notes simultaneously, the values of certain variables—like the playback rate, which depends on the note’s frequency in one of my instrument’s modes—are stored in the same variable. This isn’t a problem for sound, but it becomes unpredictable if I want to use that variable for something that requires a single value (the visual pointer in my case).

I want to access the highest note when two MIDI notes are pressed perfectly simultaneously (for example, entered in a DAW). My initial approach was to store the pressed notes in an array and then find the maximum using a loop, but this has some issues.

Is there a better or more reliable way in Csound to get the highest note in such polyphonic situations?

My (failed) attemp:

form caption("Untitled") size(400, 300), guiMode("queue"), pluginId("pol1") keyboard bounds(6, 188, 381, 95) csoundoutput bounds(32, 16, 330, 159) channel("csoundoutput10001") -n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5 -m0d ksmps = 32 nchnls = 2 0dbfs = 1

; Global array to register active notes (adjust size according to note range)
gkp4_array[] init 32

; Main instrument
instr 1
kEnv madsr .1, .2, .6, .4

kP4 init 0
kP5 init 0

midinoteonkey kP4, kP5 ; Get midi note number.   

; Store kp4 in the array using a simple index (adjust according to note range)
kIdx = kP4 - 60  ; assuming MIDI notes from 60 to 91
gkp4_array[kIdx] = kP4

; Find the highest note in the array
kIndex init 0
kMax init 0
while kIndex < 32 do
    if gkp4_array[kIndex] > kMax then
        kMax = gkp4_array[kIndex]
    endif
    kIndex += 1
od

; Print the highest note
printk2 kMax

; Generate the sound
aOut vco2 p5, p4
outs aOut*kEnv*0.2, aOut*kEnv*0.2

endin

f0 z

I’m not sure there is a more ellegant solution, although you could replace your loop with a maxarray opcode.

Thanks, I’ll try. It seems there’s no easy way.