Cabbage Logo
Back to Cabbage Site

Cabbage crashes with my csd

I am trying to Cabbagize my csd for notes reversals in an audio file, but it crashes right away.
Maybe it is ksmps=1, or the file or UDO not found. How can I debug this?

Actually Cabbage becomes unresponsive after I save (Command S). The next time I start it it seems OK and the Csound output shows me last time it was run (after the save), so I get some info from that…

Can you post a simplified example? KSMPS to 1 shouldn’t be an issue? Can you also confrim that you are using the latest package?

I am using version 1.1.0 on OS X. Here’e the csd. I still have a python exception in pyruni. I also noted that Cabbage is using Csound 6.07, while I have already 6.08 on my system. Can I change that?
Richard
BTW, I could not attach the file? Here’s the code (sorry, don’t have a simplified version)

form caption(“Reversal”) size(1025, 500), pluginID(“DkPl”)
image bounds(0, 0, 1025, 500), shape(“sharp”), colour(70, 30, 30, 255),

soundfiler bounds(5, 5, 1015, 140), channel(“beg”,“len”), identchannel(“filer1”), colour(0, 255, 255, 255), fontcolour(160, 160, 160, 255)
label bounds(6, 4, 560, 14), text(""), align(left), colour(0,0,0,0), fontcolour(200,200,200), identchannel(“stringbox”)

soundfiler bounds(5, 150 , 1015, 140), tableconfig(3), tablenumber(3), colour(0, 255, 255, 255),
label bounds(6, 4, 560, 14), text(“reversed table”), align(left), colour(0,0,0,0), fontcolour(200,200,200)

image bounds(0, 300, 1025, 80), colour(0, 0, 0, 0), plant(“controls”){
filebutton bounds(5, 5, 80, 25), text(“Open File”,“Open File”), fontcolour(“white”) channel(“filename”), shape(“ellipse”)
checkbox bounds( 5, 40, 120, 25), channel(“PlayStop”), text(“Play+analize/Stop”), colour(“lime”), fontcolour(“white”)
rslider bounds(215, 5, 70, 70), channel(“response”), range(0, 10.0, 6, .5), colour( 90, 50, 50), trackercolour(“silver”), text(“ReponseTime”), textcolour(“white”)
rslider bounds(280, 5, 70, 70), channel(“threshold”), range( 0, 6.00, 6, 0.5), colour( 90, 50, 50), trackercolour(“silver”), text(“Threshold”), textcolour(“white”)
rslider bounds(345, 5, 70, 70), channel(“lowtresh”), range( 0, 80.0, 60, 1), colour( 90, 50, 50), trackercolour(“silver”), text(“LowTresh”), textcolour(“white”)
rslider bounds(410, 5, 70, 70), channel(“doublelimit”), range( 0, 0.02, 0.02, 0.01), colour( 90, 50, 50), trackercolour(“silver”), text(“DblLimit”), textcolour(“white”)
rslider bounds(475, 5, 70, 70), channel(“dectresh”), range( 0, 1.0, .4, 0.01), colour( 90, 50, 50), trackercolour(“silver”), text(“DecayTresh”), textcolour(“white”)
rslider bounds(540, 5, 70, 70), channel(“AttTim”), range(0, 5, 0, 0.5, 0.01), colour( 90, 50, 50), trackercolour(“silver”), text(“Att.Tim”), textcolour(“white”)
rslider bounds(605, 5, 70, 70), channel(“RelTim”), range(0.01, 5, 0.05, 0.5, 0.01), colour( 90, 50, 50), trackercolour(“silver”), text(“Rel.Tim”), textcolour(“white”)
rslider bounds(670, 5, 70, 70), channel(“level”), range( 0, 3.00, 1, 0.5), colour( 90, 50, 50), trackercolour(“silver”), text(“Level”), textcolour(“white”)
}

-odac pyinit pyruni {{ ;import ctcsound }} /* INITIALIZATION gifn1 - table to be used to hold the recorded audio track. gifn2 - index table that holds the start points (sample nrs of the different sections) these are the onsets of the notes in table 1. If this table holds 2 points, say a and b, the first section to be reversed is from a to b, the second section is from b to the end of the table gifn3 - target table (same size as ifn1) to write the reversed sections to */ ; Initialize the global variables. sr = 44100 ksmps = 44100 ksmps = 1 nchnls = 2 0dbfs = 1

gkindx init 0 ; index in fn1
gindxx init 0 ; index in index table
giduration init 0
gkthreshold init 0
gkdecthresh init 0
gklowthresh init 0

; Transient detection udo, Oeyvind Brandtsegg
opcode TransientDetect, kk,kikkkk
kin, iresponse, ktthresh, klowThresh, kdecThresh, kdoubleLimit xin
/*
iresponse = 10 ; response time in milliseconds
ktthresh = 6 ; transient trig threshold
klowThresh = -60 ; lower threshold for transient detection
kdoubleLimit = 0.02 ; minimum duration between events, (double trig limit)
kdecThresh = 6 ; retrig threshold, how much must the level decay from its local max before allowing new transient trig
/
kinDel delayk kin, iresponse/1000 ; delay with response time for comparision of levels
ktrig = ((kin > kinDel + ktthresh) ? 1 : 0) ; if current rms plus threshold is larger than previous rms, set trig signal to current rms
klowGate = (kin < klowThresh? 0 : 1) ; gate to remove transient of low level signals
ktrig = ktrig * klowGate ; activate gate on trig signal
ktransLev init 0
ktransLev samphold kin, 1-ktrig ; read amplitude at transient
kreGate init 1 ; retrigger gate, to limit transient double trig before signal has decayed (decThresh) from its local max
ktrig = ktrig
kreGate ; activate gate
kmaxAmp init -99999
kmaxAmp max kmaxAmp, kin ; find local max amp
kdiff = kmaxAmp-kin ; how much the signal has decayed since its local max value
kreGate limit kreGate-ktrig, 0, 1 ; mute when trig detected
kreGate = (kdiff > kdecThresh ? 1 : kreGate) ; re-enable gate when signal has decayed sufficiently
kmaxAmp = (kreGate == 1 ? -99999 : kmaxAmp) ; reset max amp gauge

; avoid closely spaced transient triggers (first trig priority)
kdouble init 1
ktrig = ktrig*kdouble
if ktrig > 0 then
reinit double
endif
double:
idoubleLimit = i(kdoubleLimit)
idoubleLimit limit idoubleLimit, 1/kr, 5
kdouble linseg 0, idoubleLimit, 0, 0, 1, 1, 1
rireturn

xout ktrig, kdiff
endop

giInterpArr[] array 1, 2, 4, 8
gSfilepath init “”

opcode FileNameFromPath,S,S ; Extract a file name (as a string) from a full path (also as a string)
Ssrc xin ; Read in the file path string
icnt strlen Ssrc ; Get the length of the file path string
LOOP: ; Loop back to here when checking for a backslash
iasc strchar Ssrc, icnt ; Read ascii value of current letter for checking
if iasc==92 igoto ESCAPE ; If it is a backslash, escape from loop
loop_gt icnt,1,0,LOOP ; Loop back and decrement counter which is also used as an index into the string
ESCAPE: ; Escape point once the backslash has been found
Sname strsub Ssrc, icnt+1, -1 ; Create a new string of just the file name
xout Sname ; Send it back to the caller instrument
endop

instr 1
gkPlayStop chnget “PlayStop” ; read in widgets
gkresponse chnget “response”
gkthreshold chnget “threshold”
gSfilepath chnget “filename” ; read in file path string from filebutton widget
gklowthresh chnget “lowtresh”
gkdecthresh chnget “dectresh”
gkdblLimit chnget “doublelimit”

if changed:k(gSfilepath)==1 then ; call instrument to update waveform viewer
event “i”,99,0,0
endif

ktrig trigger gkPlayStop,0.5,0 ; if play/stop button toggles from low (0) to high (1) generate a ‘1’ trigger
schedkwhen ktrig,0,0,2,0,-1 ; start instrument 2

if changed:k(gkresponse)== 1 then
reinit RESTART
endif
RESTART:
giresponse = i(gkresponse)

endin

instr 2

if gkPlayStop==0 then ; if play/stop is off (stop)…
turnoff ; turn off this instrument
endif
iStrLen strlen gSfilepath ; derive string length
if iStrLen > 0 then ; if string length is greater than zero (i.e. a file has been selected) then…
iAttTim chnget “AttTim” ; read in amplitude envelope attack time widget
iRelTim chnget “RelTim” ; read in amplitude envelope attack time widget
if iAttTim>0 then ;
kenv linsegr 0,iAttTim,1,iRelTim,0
else
kenv linsegr 1,iRelTim,0 ; attack time is zero so ignore this segment of the envelope (a segment of duration zero is not permitted
endif
kenv expcurve kenv,8 ; remap amplitude value with a more natural curve
aenv interp kenv ; interpolate and create a-rate envelope
iFileLen filelen gSfilepath ; derive chosen sound file length
iNChns filenchnls gSfilepath ; derive the number of channels (mono=1 / stereo=2) from the chosen sound file

gifn1 ftgen 1, 0, 0, 1, gSfilepath, 0, 4, 0 ;deferred-size table
gisize = ftlen(gifn1)
gifn2 ftgen 2, 0, 1024, 2, 0 ; empty table to hold start/end pairs
gindxlen = ftlen(gifn2)
gifn3 ftgen 3, 0, gisize, 2, 0 ;empty table of the same size
endif
endin

instr 10
print giduration
;schedule 1, 0, (giduration + .5)
endin

; Instrument #20 - play an audio file, record transitions
instr 20
prints “playing and analysing audio file”
;iresponse = 5 ; response time in milliseconds (was 10)
;ktthresh = .2 ; transient trig threshold was 6
;klowThresh = -75 ; lower threshold for transient detection (was 60)
;kdoubleLimit = 0.002 ; minimum duration between events, (double trig limit) was 0.02
;kdecThresh = .4 ; retrig threshold, how much must the level decay from its local max before allowing new transient trig

kAttack 	init	0.01
kRelease	init	2

isize tableng 1					;length of table?
andx  phasor 1 / (isize / sr) 
asig  tab andx, gifn1, 1				;has a 0 to 1 range for the index
a_env follow2 asig, kAttack, kRelease
k_env  downsamp a_env
ktransient, kdiff TransientDetect dbfsamp(k_env), giresponse, gkthreshold, gklowthresh, gkdecthresh, gkdblLimit

if ktransient == 1 then
	k1 timeinstk
	printk2 k1
	tablew k1, gkindx, gifn2, 0				; write sample start to index table 
	gkindx += 1
endif

outs asig, asig
;schedule 2, p3, 1

endin

instr 30
prints “finalizing…”
tablew gisize, gkindx, gifn2, 0 ; write audio end as final index
;schedule 3, p3, 6
endin

instr 40
prints “creating reversed table…”
pyruni {{
from numpy import array, append
cs = ctcsound.Csound(None,CSOUND)

def getTable(t): # get table n contents
table = cs.table(int(t))
return table

track = getTable(1) # get audio table
idxtab = getTable(2) # get index table
print idxtab[0:10]
newtrack = array(0)
idx = 0
while idxtab[idx] <> 0:
print idxtab[idx]
if idx == 0:
startp = 0 # always from start of track
else:
startp = idxtab[idx] - 1 # start pointer is start of note section
endp = idxtab[idx + 1] - 2 # end pointer is start of next note
idx += 1
print idx, startp, endp
section = track[startp:endp]
reverse = section[::-1]
newtrack = append(newtrack, reverse)

cs.tableCopyIn(3, newtrack)
}}
print giduration
;schedule 5, p3, (giduration + .5)
endin

instr 50
prints “playing reversed table”
print p3
ftsave “copy3.txt”, 1, 3
isize tableng 1 ;length of table
andx phasor 1 / (isize / sr)
asigl tab andx, gifn3, 1 ;play reversed table
asigr tab andx, gifn1, 1 ;play original table
outs asigl, asigr
endin

instr 99
Smessage sprintfk “file(%s)”, gSfilepath ; print sound file image to fileplayer
chnset Smessage, “filer1”

/* write file name to GUI */
Sname FileNameFromPath gSfilepath ; Call UDO to extract file name from the full path
Smessage sprintfk “text(%s)”,Sname ; create string to update text() identifier for label widget
chnset Smessage, “stringbox” ; send string to widget

endin

i 1 0 10000 e

Can you try with the latest beta package? I posted a link in my first message. In the meantime, maybe you can try to identify what is causing the crash? I’d start by commenting out lines of Cabbage code to see if the problem lies there. If not, move on to the Csound code to see if you can find the problem there. A simplified .csd would help.

The latest beta version works fine. The crash is gone and pyruni does not complain. Looks promising…

Great. I really have to update the main release!