How to debug csound code?

Hello there !

Are there routines or special opcodes to facilitate debugging of Csound code ? Like a gdb-like for Csound ? :smile:
I’m really having trouble knowing what’s wrong in this .csd file…
I’d appreciate some help.

Thank you!

<CsoundSynthesizer>
<CsOptions>
-o dac2 -+rtmidi=portmidi -+rtaudio=portaudio -M0
</CsOptions>
; ==============================================
<CsInstruments>
sr = 44100
ksmps = 16  ; toujours une puissance de 2 et un multiple de -b
nchnls = 2
0dbfs = 1

gi_nombrePartiels = 10
gi_freqMult[] fillarray 1/4, 1/3, 1/3, 1/2,   1,    1, 1/2, 1/3, 1/4, 1/2
gi_ampMult[] fillarray    1, 1/2, 1/3,   1, 1.5,  1.2, 0.8,   1, 1/2, 1/3
gi_pan[] fillarray   .3,  .4,  .5,  .1,  .9,   .8,  .2,  .5,  .4,  .3
ga_L = 0
ga_R = 0

massign     0, "BasicSynth" 	        ; assign all MIDI channels to instr

; basic harmonic sine synth
instr BasicSynth

    k_freq 	cpsmidib    4               ; note + p-bend
    i_amp 	ampmidi 	0.2             ; amp
    k_cc    midictrl    1, 1., 1.5      ; control change for amp of lfo

    a_lfo lfo  0.02, 3*k_cc, 0
    
    index = 0
    while index < gi_nombrePartiels do
        aL = 0
        aR = 0
        a_out oscil3    (i_amp * gi_ampMult[index % gi_nombrePartiels]) + a_lfo, k_freq * gi_freqMult[index % gi_nombrePartiels]
        aL, aR pan2 a_out, gi_pan[index % gi_nombrePartiels]

        ga_L += aL
        ga_R += aR
        index += 1
    od
	
    a_env	mxadsr	.05, .1, .4, .4
    ga_L = a_env*ga_L
    ga_R = a_env*ga_R

    outs 	ga_L, ga_R
endin

</CsInstruments>
<CsScore>
</CsScore>
</CsoundSynthesizer>

The problem here is that you can’t use an oscil in a loop like this1. If you want to program something like this you should do it in a recursive UDO, or use Eduardo’s poly opcode.

1 Some opcodes have internal state, preventing them from being called in this function-like manner. To do this you need several unique instances of oscil3

1 Like

I see, thank you for your answer!

So for a few hours I tried recursive UDO… But the output was weird and I didn’t understand why, so I tried with the great poly opcode and indeed it seems quite simple and elegant… but yet again I’m stuck with no sound…

<CsoundSynthesizer>
<CsOptions>
-o dac -+rtmidi=portmidi -+rtaudio=portaudio -M0
</CsOptions>
; ==============================================
<CsInstruments>
sr = 44100
ksmps = 16 
nchnls = 2
0dbfs = 1

#define NB_PARTIELS # 3 #

gi_freqs[] fillarray 1/3,  1, 2
gi_amps[] fillarray  1/2,  1, 1/2
gi_pans[] fillarray   .7, .5, .3

ga_L[] init $NB_PARTIELS
ga_R[] init $NB_PARTIELS

massign     0, "BasicSynth" 

; basic harmonic sine synth
instr BasicSynth
    k_freqs[] init $NB_PARTIELS
    k_amps[]  init $NB_PARTIELS
    a_outs[]   init $NB_PARTIELS


    k_freq   cpsmidib    4               ; note + p-bend
    i_amp    ampmidi   0.1               ; amp
    k_cc     midictrl    1, 1., 4.       ; control change for lfo

    a_lfo lfo  0.02, k_cc, 0
    
    index = 0
    while (index < $NB_PARTIELS) do
        k_freqs[index] = gi_freqs[index] * k_freq
        k_amps[index] = (gi_amps[index] * i_amp) + a_lfo
        index += 1
    od
    a_outs[] poly $NB_PARTIELS, "oscil3", k_amps, k_freqs

    a_env  mxadsr .05, .1, .4, .4

    index = 0
    while index < $NB_PARTIELS do
        ga_L[index] = a_outs[index] * a_env
        ga_R[index] = a_outs[index] * a_env
        index += 1
    od
    poly0 $NB_PARTIELS, "outs", ga_L, ga_R
endin

</CsInstruments>
<CsScore>
</CsScore>
</CsoundSynthesizer>

I am getting a weird error message :

INIT ERROR in instr 1 (opcode poly0) line 52: handle_set_inputs: failed to parse signature (y),char failed: 'y', index 0
 from file /tmp/tryin.csd (1)
	poly0	3	"outs"	ga_L	ga_R

Also printf doesn’t diplay anything in the loop, which makes no sense to me.

I can’t say for the poly opcode as I’ve never used it, but here is a simple UDO for a super saw type of instrument. Not exactly what you are trying to do, but simple enough to get the picture:

opcode SuperSaw,a,kkiO 
   iDetune random 0, 1
   aVcoBank init 0
   kAmp, kFreq, iNum, iCnt xin 
   aSig vco2 kAmp/iNum,kFreq+iDetune
   iCount = iCnt+1 
   if iCount < iNum then 
      aVcoBank SuperSaw 1/iNum,kFreq+iDetune,iNum,iCount
   endif 
   xout aSig + aVcoBank
endop 

;instrument will be triggered by keyboard widget
instr 1
    aOut SuperSaw p5, p4, 10
    outs aOut, aOut
endin
1 Like

Thank you Rory.
So I didn’t manage to get your code to work but I finally found the problem in my previous attempt (apparently turning index to a k-variable solved it) and also I removed the erroneous poly0 call as it’s not actually needed.

<CsoundSynthesizer>
<CsOptions>
-o dac -+rtmidi=portmidi -+rtaudio=portaudio -M0
</CsOptions>
; ==============================================
<CsInstruments>
sr = 44100
ksmps = 16  ; toujours une puissance de 2 et un multiple de -b
nchnls = 2
0dbfs = 1


#define NB_PARTIELS # lenarray(gi_freqs) #

gi_freqs[] fillarray 1/16, 1/8, 1/5, 1/4,  1/3,
                     1/2,   1,    2,   4,    8
gi_amps[] fillarray  1,   1/2,  1/3,   1,   1,
                     1,   1.5,  1/4, 1/2, 1/3
gi_pans[] fillarray  .3,   .4,   .5,  .1,  .9,
                     .4,   .5,   .6,  .4,  .3

massign     0, "BasicSynth" 	        

instr BasicSynth
    k_amps[]  init $NB_PARTIELS

	k_freq 	cpsmidib    4               ; note + p-bend
	i_amp 	ampmidi 	0.1             ; amp
    k_cc    midictrl    1, 1., 6.       ; control change for lfo

    a_lfo lfo  0.01, k_cc, 0
	a_env	mxadsr	.05, .1, .4, .8
    
    kindex = 0
    while (kindex < $NB_PARTIELS) do
        k_amps[kindex] = (gi_amps[kindex] * i_amp) + a_lfo
        kindex += 1
    od
    a_outs[] poly $NB_PARTIELS, "oscil3", k_amps, (gi_freqs * k_freq)

    kindex = 0
    while kindex < $NB_PARTIELS do
        a_L, a_R pan2 a_outs[kindex] * a_env, gi_pans[kindex]
        outs a_L, a_R
        kindex += 1
    od
    ;DO NOT WORK
    ;poly0 $NB_PARTIELS, "outs", ga_L, ga_R
endin

</CsInstruments>
<CsScore>
</CsScore>
</CsoundSynthesizer>

Thanks a lot !

I guess I should check my code before posting :roll_eyes: I’ve updated it now, for future visitors. I’m glad you got it sorted. Eduardo’s opcode is nice. It would be even nicer if Csound could handle this without the next of an external opcode. I think it might be on the Csound 7 roadmap.

1 Like