How can one check whether a particular key is pressed on the standard keyboard, the note on and off message (0 and 1) of that key ?
Keyboard latching
You mean the ascii keyboard, or the midi keyboard?
Yes, on the screen.
The virtual midi keyboard.
Using midiin
and disabling the normal MIDI triggering is useful for this sort of thing. The following provides a 1 or 0 if middle C (C3) is pressed:
<Cabbage>
form caption("Untitled") size(400, 300), guiMode("queue"), pluginId("def1")
keyboard bounds(8, 158, 381, 95)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -dm0 -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables.
ksmps = 32
nchnls = 2
0dbfs = 1
massign 0,0 ; disable instrument triggering
instr 1
iNote = 60 ; note to test
kFlag init 0 ; flag to indicate whether chosen not is on or off
kstatus,kchan,kdata1,kdata2 midiin
if changed:k(kstatus)==1 then
if kstatus==144 && kdata1==60 then ; if note is on
kFlag = 1
elseif kstatus==128 && kdata1==60 then ; if note is off
kFlag = 0
endif
endif
printk2 kFlag
; audio indicator
a1 poscil kFlag/10,440
outs a1,a1
endin
</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
i 1 0 z
</CsScore>
</CsoundSynthesizer>
I see,
I’ll have to try this out.
For now what I get is:
Why is it specifically 144 and 128 values for kstatus ? kchan and kdata2 seemingly aren’t used.
Would you recommend this for the entire keyboard ?
An additional route might be to make a keyboard starting from buttons, but I suppose putting in order the midi functionality will be the hassle in this one.
Thx!
144 and 128 are the status bytes for MIDI events which correspond to note on and note off. In the example they are used to determine when kFlag
should be 1 or zero.
kchan
is the MIDI channel, in the example I just ignored it but if it is important, include it in the conditional. kdata2
is key velocity and again, I decided to ignore it in the example.
Below is another approach in which flags for all notes played and held are written into an array in which the location corresponds to the note played. This might be more efficient if you intend to interrogate the status of many notes.
<Cabbage>
form caption("Untitled") size(400, 300), guiMode("queue"), pluginId("def1")
keyboard bounds(8, 158, 381, 95)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -dm0 -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables.
ksmps = 32
nchnls = 2
0dbfs = 1
massign 0,1 ; ensure all MIDI note events sent to instr 1
gkNoteOnOffs[] init 128 ; array to store on/off flags for all notes
instr 1
iNum notnum ; read in note number
kRel release ; release flag. 0 while note is held, 1 when note is released
gkNoteOnOffs[iNum] = 1-kRel ; invert logic of kRel and write to array in a location corresponding to the note number played
endin
instr 2
kFlag = gkNoteOnOffs[60] ; read status (1 or zero) of middle C
printk2 kFlag
; audio indicator
a1 poscil kFlag/10, 440
outs a1, a1
endin
</CsInstruments>
<CsScore>
i 2 0 z
</CsScore>
</CsoundSynthesizer>
Wow, that looks great.
Is there a particular reason for dividing kFlag by 10 ?
The thing is that I needed the data of the note actions controlled from a midi keyboard for other means than sound production (visuals etc.).
So regular sound production and additonal actions.
I’ll try this out and keep this post updated.
Thanks again !
The divide-by-10 was simply because I was using it to control amplitude. I didn’t want to deafen myself!
I see, you’re just using these as switches.
If you need the keyboard presses - press-release - to toggle some value, i.e. you don’t want to hold the key to keep the value at 1, you can try this UDO through which you pass kFlag
.
; UnlatchedToLatched
; ------------------
; Converts an unlatched trigger signal to a latched one
;
; kTrigOut UnlatchedToLatched kTrigIn
;
; Performance
; -----------
; kTrigIn -- input trigger
opcode UnlatchedToLatched,k,k
kTrigIn xin ; READ IN INPUT ARGUMENT
kTrigOut init 0 ; INITIALISE OUTPUT TRIGGER VALUE
kcross trigger kTrigIn,0,2 ; IF INPUT TRIGGER CHANGES FROM ZERO OR BACK TO ZERO SWITCH THE OUTPUT TRIGGER VALUE ACCORDING TO ITS CURRENT VALUE
if kcross==1 then ; IF INPUT TRIGGER HAS CHANGED FROM ZERO OR BACK TO ZERO...
kTrigOut = abs(kTrigOut-1) ; FLIP THE OUTPUT TRIGGER FROM 0 TO 1 OR FROM 1 TO 0 (DEPENDING UPON WHAT ITS CURRENT VALUE IS)
endif ; END OF CONDITIONAL BRANCH
xout kTrigOut ; SEND OUTPUT TRIGGER BACK TO CALLER INSTRUMENT
endop
I tried out your previous approach for a while and for:
“printk2 kFlag”
this doesn’t print very consistently.
Should print 1 at the attack, 0 at release.
Prints 1 of following:
- the above (as it should)
- 1 and 0 seemingly at attack
- 1 and 0 somewhere along the way
- 1 and 0 at the release
I seem to get reliable behaviour from both methods. Ultimately it’s the value of kFlag
that matters. In the video I’m using kFlag
to drive a button widget, which is easier to follow than the ones and zeroes in the terminal.
The basic script like this works fine, but once I put it in my code…
form caption(“Untitled”) size(400, 300), guiMode(“queue”), pluginId(“def1”)
keyboard bounds(8, 158, 381, 95)
-n -dm0 -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
; Initialize the global variables.
ksmps = 32
nchnls = 2
0dbfs = 1
massign 0,1 ; ensure all MIDI note events sent to instr 1
gkNoteOnOffs[] init 128 ; array to store on/off flags for all notes
opcode getNoteOn, k, 0
iNum notnum ; read in note number
kRel release ; release flag. 0 while note is held, 1 when note is released
gkNoteOnOffs[iNum] = 1-kRel ; invert logic of kRel and write to array in a location corresponding to the note number played
kFlag = gkNoteOnOffs[iNum] ; read status (1 or zero) of current note
xout kFlag
endop
instr 1
xtratim 5
kFlag getNoteOn
printk2 kFlag
; audio indicator
icps cpsmidi
a1 poscil kFlag/10, icps
outs a1, a1
endin
f0zI also have xtratim going on and both the sound block and GUI managing block still rely on p4 and p5.
All works from now on.
Now have to check the functioning of multiple notes (ASCI keyboard or midi keyboard).