Csound Csound-dev Csound-tekno Search About

[Csnd] Midi output from csound through channels

Date2023-06-19 21:23
FromPrent Rodgers
Subject[Csnd] Midi output from csound through channels
I'm calling csound from Ctcsound to read Midi notes. I assumed I could pass the notes read back to ctcsound using channels. But what comes back from playing a chord is only a single note value. 

Here is the csound .csd file I'm using:
-----------------------------------
massign 1, 1	; set MIDI channel 1 to play instr 1 -.
instr   1 ; 
chn_k "iNum", 2 ; set the channel "iNum" to send data outbound to ctcsound
iNum notnum ;  Get the MIDI byte value (0 - 127) 
; make these available for reading from python through a channel
chnset iNum, "iNum"  ; send the data to ctcsound on the output channel called iNum
printf  "csound ch 1. (iNum) note: '%i' \n", 1, iNum ; print the values of the midi notes. If it's a chord, all the notes appear here.
---------------------------
csound output:
csound ch 1. (iNum) note: '55' 
csound ch 1. (iNum) note: '64' 
csound ch 1. (iNum) note: '60' 
csound ch 1. (iNum) note: '67' 
csound ch 1. (iNum) note: '48' 
csound ch 1. (iNum) note: '52' 
-------------------------
In ctcsound python I can read data through the channel:
# process the csound csd file:
cs = ctcsound.Csound()
ret = cs.compileCsd(csd_file)
if ret == ctcsound.CSOUND_SUCCESS:
  cs.start()
pt = ctcsound.CsoundPerformanceThread(cs.csound())
pt.play()
# set up the channel called iNum
iNum, error_msg = cs.channelPtr('iNum', ctcsound.CSOUND_CONTROL_CHANNEL | ctcsound.CSOUND_OUTPUT_CHANNEL)
# loop listening on the channel
prev_note = iNum[0]
while (cs.performKsmps() == 0): 
    print(f'{prev_note = }, {iNum = }') # see if the note value has changed. If I don't press any note, it continues to return 0.
    # Fead from csound channels:
   if iNum[0] > 0 : print(f'{int(iNum) = } 
        pt.scoreEvent(False, 'i', (2,  0,  1,  iNum[0], 100) 
        prev_note = iNum[0]
------------------------
Output of the pyhon call to ctcsound:
int(iNum) = 67 keys[int(iNum[0] % 12)] = 'G ', oct 5, int(iVel[0]) = 73
prev_note = 67.0, iNum = array([52.])
int(iNum) = 52 keys[int(iNum[0] % 12)] = 'E ', oct 4, int(iVel[0]) = 53
prev_note = 52.0, iNum = array([52.])
--------------------------------------------------
When I press a key, it gets returned successfully to ctcsound. If I slowly press several keys, they all get returned over the course of a few seconds, as expected. 
But if I press several notes at once as in a chord, only one note gets returned to ctcsound over the channel. All the notes are shown in the csound csd file print as being received in instrument 1.  Is there something to be done while reading from the channel to allow multiple notes? I expected that perhaps they would show up as an array on the channel, but no more than one note ever comes over the channels even if I press every key on the keyboard. Only one gets through.

Prent Rodgers

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here

Date2023-06-20 00:15
FromVictor Lazzarini
SubjectRe: [Csnd] [EXTERNAL] [Csnd] Midi output from csound through channels
If all notes happen in the same kcycle, the channel will only hold the last note. Maybe the best thing would be to store the notes in a function table and then read however many have been stored in one kcycle. You can keep a global count and pass that in a channel. Clearing the global count every kcycle so you can start again every time.

Prof. Victor Lazzarini
Maynooth University
Ireland

> On 19 Jun 2023, at 21:23, Prent Rodgers  wrote:
>
> *Warning*
>
> This email originated from outside of Maynooth University's Mail System. Do not reply, click links or open attachments unless you recognise the sender and know the content is safe.
>
> I'm calling csound from Ctcsound to read Midi notes. I assumed I could pass the notes read back to ctcsound using channels. But what comes back from playing a chord is only a single note value.
>
> Here is the csound .csd file I'm using:
> -----------------------------------
> massign 1, 1    ; set MIDI channel 1 to play instr 1 -.
> instr   1 ;
> chn_k "iNum", 2 ; set the channel "iNum" to send data outbound to ctcsound
> iNum notnum ;  Get the MIDI byte value (0 - 127)
> ; make these available for reading from python through a channel
> chnset iNum, "iNum"  ; send the data to ctcsound on the output channel called iNum
> printf  "csound ch 1. (iNum) note: '%i' \n", 1, iNum ; print the values of the midi notes. If it's a chord, all the notes appear here.
> ---------------------------
> csound output:
> csound ch 1. (iNum) note: '55'
> csound ch 1. (iNum) note: '64'
> csound ch 1. (iNum) note: '60'
> csound ch 1. (iNum) note: '67'
> csound ch 1. (iNum) note: '48'
> csound ch 1. (iNum) note: '52'
> -------------------------
> In ctcsound python I can read data through the channel:
> # process the csound csd file:
> cs = ctcsound.Csound()
> ret = cs.compileCsd(csd_file)
> if ret == ctcsound.CSOUND_SUCCESS:
>  cs.start()
> pt = ctcsound.CsoundPerformanceThread(cs.csound())
> pt.play()
> # set up the channel called iNum
> iNum, error_msg = cs.channelPtr('iNum', ctcsound.CSOUND_CONTROL_CHANNEL | ctcsound.CSOUND_OUTPUT_CHANNEL)
> # loop listening on the channel
> prev_note = iNum[0]
> while (cs.performKsmps() == 0):
>    print(f'{prev_note = }, {iNum = }') # see if the note value has changed. If I don't press any note, it continues to return 0.
>    # Fead from csound channels:
>   if iNum[0] > 0 : print(f'{int(iNum) = }
>        pt.scoreEvent(False, 'i', (2,  0,  1,  iNum[0], 100)
>        prev_note = iNum[0]
> ------------------------
> Output of the pyhon call to ctcsound:
> int(iNum) = 67 keys[int(iNum[0] % 12)] = 'G ', oct 5, int(iVel[0]) = 73
> prev_note = 67.0, iNum = array([52.])
> int(iNum) = 52 keys[int(iNum[0] % 12)] = 'E ', oct 4, int(iVel[0]) = 53
> prev_note = 52.0, iNum = array([52.])
> --------------------------------------------------
> When I press a key, it gets returned successfully to ctcsound. If I slowly press several keys, they all get returned over the course of a few seconds, as expected.
> But if I press several notes at once as in a chord, only one note gets returned to ctcsound over the channel. All the notes are shown in the csound csd file print as being received in instrument 1.  Is there something to be done while reading from the channel to allow multiple notes? I expected that perhaps they would show up as an array on the channel, but no more than one note ever comes over the channels even if I press every key on the keyboard. Only one gets through.
>
> Prent Rodgers
>
> Csound mailing list
> Csound@listserv.heanet.ie
> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
> Send bugs reports to
>        https://github.com/csound/csound/issues
> Discussions of bugs and features can be posted here

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here