Csound Csound-dev Csound-tekno Search About

[Csnd-dev] ctcsound, api channel_ptr

Date2026-07-05 00:14
FromJames Hearon
Subject[Csnd-dev] ctcsound, api channel_ptr
Enjoying looking at changes to csound7 since csound6.  Trying some of the new array features, but a bit stuck on getting a ARRAYDAT_p returned from
ctcsound.  I'm not sure I'm going about it the right way, using channel_ptr to directly retrieve chnset array data from csd.
      ....
            result = cs.compile_csd('arraydat.csd', 0) 
      ....
            ptr, _ = csound.channel_ptr("python_array_channel", ctcsound.CSOUND_ARRAY_CHANNEL | ctcsound.CSOUND_OUTPUT_CHANNEL)
            print("ptr type:", type(ptr)) 

Seems to ever only return: ctypes.c_void_p, the pvs type instead of an ndarray

    ...from ctcsound
    def channel_ptr(self, name, type_):
        #Get a pointer to the specified channel and an error message.

        length = 1  # default buf length for CSOUND_CONTROL_CHANNEL:
        ptr = ct.c_void_p()
        chan_type = type_ & CSOUND_CHANNEL_TYPE_MASK
        err = ''
        ret = libcsound.csoundGetChannelPtr(self.cs, ct.byref(ptr), cstring(name), type_)
        if ret == CSOUND_SUCCESS:
            if chan_type == CSOUND_STRING_CHANNEL:
                return ct.cast(ptr, STRINGDAT_p), err
            elif chan_type == CSOUND_ARRAY_CHANNEL:
                return ct.cast(ptr, ARRAYDAT_p), err
            elif chan_type == CSOUND_PVS_CHANNEL:
                return ct.cast(ptr, PVSDAT_p), err
            elif chan_type == CSOUND_AUDIO_CHANNEL:
                length = libcsound.csoundGetKsmps(self.cs)
            array_type = np.ctypeslib.ndpointer(MYFLT, 1, (length,), 'C_CONTIGUOUS')
            p = ct.cast(ptr, array_type)
            return array_from_pointer(p), err
====================
arraydat.csd

<CsoundSynthesizer>
<CsOptions>
-csound -s -d -+rtaudio=ALSA -odevaudio -b1024 -B1024
</CsOptions>
<CsInstruments>
sr     = 48000
ksmps = 32
nchnls = 2
0dbfs = 1

gi_array_size init 1024

instr 1
  k_index init 0
  k_trigger init 1
  k_out_array[] init gi_array_size
  
  ; Generate some data (e.g., sine wave values)
  k_val oscili 1, 1
  
  ; Fill the array
  k_out_array[k_index] = k_val
  k_index += 1
  
  kcnt init 0
  
  if k_index == gi_array_size then
      chnset k_out_array, "python_array_channel"
    k_index = 0
    
        ;test print some array contents
        ;while kcnt < 10 do
        ;printks2 "%f\n", k_out_array[kcnt]
        ;kcnt +=1
        ;od
  
  endif
endin
    
 instr 2; get k-values as proof working
     kcnt init 0
    k_out_array[] init gi_array_size

    kVals[] chngetk "python_array_channel"

      while kcnt < 10 do
        printks2 "%f\n", kVals[kcnt]
        kcnt +=1
       od
           
    ;if metro(1) == 1 then
        ;printarray kVals, 1
    ;endif 

endin

</CsInstruments>
<CsScore>
i 1 1 2
;i 2 2 2
</CsScore>
</CsoundSynthesizer>

Date2026-07-05 21:03
FromFrancois PINOT
SubjectRe: [Csnd-dev] ctcsound, api channel_ptr
The channel_ptr method returns an opaque pointer to one of the data structures describing the type of the data in the channel. This pointer can then be used as an argument to the different access methods for getting the channel features and/or data.

Here is a python script with your csd:

arraydat.csd:

<CsoundSynthesizer>
<CsOptions>
-s -d -+rtaudio=ALSA -odevaudio -b1024 -B1024
</CsOptions>
<CsInstruments>
sr = 48000
ksmps = 32
nchnls = 2
0dbfs = 1

array_size@global:i = init(1024)

instr 1
ndx:k = init(0)
;trig:k = init(1)
out_array:k[] = init(array_size)
// Generate some data (e.g., sine wave values)
val:k = oscili(1, 1)
; Fill the array
out_array[ndx] = val
ndx += 1
cnt:k = init(0)
if ndx == array_size then
chnset(out_array, "python_array_channel")
ndx = 0
// test print some array contents
while cnt < 10 do
printks2("%f\n", out_array[cnt])
cnt +=1
od
endif
endin
instr 2 // get k-values as proof working
cnt:k init 0
out_array:k[] = init(array_size)

vals:k[] = chngetk("python_array_channel")

while cnt < 10 do
printks2("%f\n", vals[cnt])
cnt +=1
od
;if metro(1) == 1 then
; printarray(vals, 1)
;endif
endin

</CsInstruments>
<CsScore>
i 1 1 2
;i 2 2 2
</CsScore>
</CsoundSynthesizer>



arraydat.py:

import ctcsound

cs = ctcsound.Csound()
cs.start()
res = cs.compile_csd("arraydat.csd", 0)
if res == 0:
cs.event_string("i1 0 1", 0)
cs.perform_ksmps()
ptr, err = cs.channel_ptr("python_array_channel",
ctcsound.CSOUND_ARRAY_CHANNEL |
ctcsound.CSOUND_OUTPUT_CHANNEL)
if err == '':
dim = cs.array_data_dimensions(ptr)
data_type = cs.array_data_type(ptr)
sizes = cs.array_data_sizes(ptr)
# We can read the array dim, data type, and shape
# Using API methods
print("\n", "Data array features read from API methods:")
print(f"dim: {dim}, data type: {data_type}, sizes: {sizes}\n")

data = cs.array_data(ptr)
# But we can read the same array features than above
# directly from the numpy array returned by array_data()
print("\n", "Data array features read from numpy array:")
print(f"dim: {data.ndim}, data type: {data.dtype}, shape: {data.shape}\n")
print("Data printed by csd")
for i in range(sizes[0]):
cs.perform_ksmps()
print("\nData printed by python script")
for i in range(10):
print(f"{i}: {data[i]:f}")


the command python arraydat.py will generate this output:

--Csound version 7.0 (double samples) Jun 26 2026
[commit: 6579dd1bba88fe97a65a9ae73231e1f1a5e23523]
using libsndfile-1.2.2
graphics suppressed, ascii substituted
sr = 44100.0, kr = 4410.000, ksmps = 10
0dBFS level = 32768.0, A4 tuning = 440.0
audio buffered in 256 sample-frame blocks
writing 512-byte blks of shorts to /home/pinot/csound/sfdir/test.wav (WAV)
SECTION 1:
Skipping <CsOptions>
new alloc for instr 1:

 Data array features read from API methods:
dim: 1, data type: k, sizes: [1024]


 Data array features read from numpy array:
dim: 1, data type: float64, shape: (1024,)

Data printed by csd
0.000000
0.001425
0.002850
0.004274
0.005699
0.007124
0.008548
0.009973
0.011398
0.012822

Data printed by python script
0: 0.000000
1: 0.001425
2: 0.002850
3: 0.004274
4: 0.005699
5: 0.007124
6: 0.008548
7: 0.009973
8: 0.011398
9: 0.012822
inactive allocs returned to freespace
  overall amps:      0.0
  overall samples out of range:        0
0 errors in performance
Elapsed time at end of performance: real: 0.011s, CPU: 0.040s
256 512 sample blks of shorts written to /home/pinot/csound/sfdir/test.wav (WAV)

Nota Bene: to get this to work you need to use the last updated version of ctcsound.py:

Hope this helps

François


Le dim. 5 juil. 2026 à 01:14, James Hearon <j_hearon@hotmail.com> a écrit :
Enjoying looking at changes to csound7 since csound6.  Trying some of the new array features, but a bit stuck on getting a ARRAYDAT_p returned from
ctcsound.  I'm not sure I'm going about it the right way, using channel_ptr to directly retrieve chnset array data from csd.
      ....
            result = cs.compile_csd('arraydat.csd', 0) 
      ....
            ptr, _ = csound.channel_ptr("python_array_channel", ctcsound.CSOUND_ARRAY_CHANNEL | ctcsound.CSOUND_OUTPUT_CHANNEL)
            print("ptr type:", type(ptr)) 

Seems to ever only return: ctypes.c_void_p, the pvs type instead of an ndarray

    ...from ctcsound
    def channel_ptr(self, name, type_):
        #Get a pointer to the specified channel and an error message.

        length = 1  # default buf length for CSOUND_CONTROL_CHANNEL:
        ptr = ct.c_void_p()
        chan_type = type_ & CSOUND_CHANNEL_TYPE_MASK
        err = ''
        ret = libcsound.csoundGetChannelPtr(self.cs, ct.byref(ptr), cstring(name), type_)
        if ret == CSOUND_SUCCESS:
            if chan_type == CSOUND_STRING_CHANNEL:
                return ct.cast(ptr, STRINGDAT_p), err
            elif chan_type == CSOUND_ARRAY_CHANNEL:
                return ct.cast(ptr, ARRAYDAT_p), err
            elif chan_type == CSOUND_PVS_CHANNEL:
                return ct.cast(ptr, PVSDAT_p), err
            elif chan_type == CSOUND_AUDIO_CHANNEL:
                length = libcsound.csoundGetKsmps(self.cs)
            array_type = np.ctypeslib.ndpointer(MYFLT, 1, (length,), 'C_CONTIGUOUS')
            p = ct.cast(ptr, array_type)
            return array_from_pointer(p), err
====================
arraydat.csd

<CsoundSynthesizer>
<CsOptions>
-csound -s -d -+rtaudio=ALSA -odevaudio -b1024 -B1024
</CsOptions>
<CsInstruments>
sr     = 48000
ksmps = 32
nchnls = 2
0dbfs = 1

gi_array_size init 1024

instr 1
  k_index init 0
  k_trigger init 1
  k_out_array[] init gi_array_size
  
  ; Generate some data (e.g., sine wave values)
  k_val oscili 1, 1
  
  ; Fill the array
  k_out_array[k_index] = k_val
  k_index += 1
  
  kcnt init 0
  
  if k_index == gi_array_size then
      chnset k_out_array, "python_array_channel"
    k_index = 0
    
        ;test print some array contents
        ;while kcnt < 10 do
        ;printks2 "%f\n", k_out_array[kcnt]
        ;kcnt +=1
        ;od
  
  endif
endin
    
 instr 2; get k-values as proof working
     kcnt init 0
    k_out_array[] init gi_array_size

    kVals[] chngetk "python_array_channel"

      while kcnt < 10 do
        printks2 "%f\n", kVals[kcnt]
        kcnt +=1
       od
           
    ;if metro(1) == 1 then
        ;printarray kVals, 1
    ;endif 

endin

</CsInstruments>
<CsScore>
i 1 1 2
;i 2 2 2
</CsScore>
</CsoundSynthesizer>