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 = ktrigkreGate ; 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