Cabbage Logo
Back to Cabbage Site

Stutter when using sndwarp as sampler

Hello. I have an issue when using the sndwarp-opcode with longer files. There is a noticeable stutter when pressing a new key. I was wondering if anyone has any tips on how to avoid this :slightly_smiling_face:. Attached is a 1-minute mp3-file for testing.

<Cabbage>
form caption("Untitled") size(600, 500), guiMode("queue"), pluginId("def1")
soundfiler bounds(110, 52, 300, 200), channel("Soundfiler1", "Soundfiler2"), colour(188, 188, 188), tableBackgroundColour(62, 71, 86), showScrubber(1), displayType("mono")
keyboard bounds(108, 358, 381, 95)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

giSine ftgen 0, 0, 2^10, 9, .5, 1, 0 ; half-sine wave

instr 98
    gSfile cabbageGet "LAST_FILE_DROPPED"

    if (changed(gSfile) == 1) then
        cabbageSet 1, "Soundfiler1", "file", gSfile
    endif
endin

;instrument will be triggered by keyboard widget
instr 1
    // Table upload
    iFileSr filesr gSfile 
    iCh filenchnls gSfile
    iSampleLengthSeconds filelen gSfile 
    iSampleLengthOriginalSr = iSampleLengthSeconds * iFileSr

    iSoundFileL ftgen 0, 0, iSampleLengthOriginalSr, 1, gSfile, 0, 0, 1

    ktimewarp line 0, iSampleLengthSeconds, iSampleLengthSeconds
    kresample init 1	
    ibeg = 0			
    iwsize = 4410		
    irandw = 882		
    itimemode = 1			
    ioverlap = 10

    asig sndwarp .5, ktimewarp, kresample, iSoundFileL, ibeg, iwsize, irandw, ioverlap, giSine, itimemode
    outs asig, asig
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z

i98 0 z
</CsScore>
</CsoundSynthesizer>

The problem is that the code for creating the function table that holds the audio material for granulation is in instr 1, triggered by MIDI notes. This means that when you play a second note, the function table is rewritten and this disturbs the note that is already sustaining. The solution is to only create the function table when the file is loaded. Hereโ€™s a quick suggestion. Iโ€™ve also added a release envelope to prevent clicks upon note release and note-based transposition so I can hear the different layers.

<Cabbage>
form caption("Untitled") size(600, 500), guiMode("queue"), pluginId("def1")
soundfiler bounds(110, 52, 300, 200), channel("Soundfiler1", "Soundfiler2"), colour(188, 188, 188), tableBackgroundColour(62, 71, 86), showScrubber(1), displayType("mono")
keyboard bounds(108, 358, 381, 95)
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 --midi-key-cps=4 --midi-velocity-amp=5
</CsOptions>
<CsInstruments>
; Initialize the global variables. 
ksmps = 32
nchnls = 2
0dbfs = 1

giSine ftgen 0, 0, 2^10, 9, .5, 1, 0 ; half-sine wave
massign 0,1

instr 98
    gSfile cabbageGet "LAST_FILE_DROPPED"
    // Table upload

    if (changed(gSfile) == 1) then
        cabbageSet 1, "Soundfiler1", "file", gSfile
        event "i",99,0,0
    endif
endin

instr 99
    iFileSr filesr gSfile 
    iCh filenchnls gSfile
    giSampleLengthSeconds filelen gSfile 
    iSampleLengthOriginalSr = giSampleLengthSeconds * iFileSr
    giSoundFileL ftgen 0, 0, iSampleLengthOriginalSr, 1, gSfile, 0, 0, 1

endin

;instrument will be triggered by keyboard widget
instr 1
    ktimewarp line 0, giSampleLengthSeconds, giSampleLengthSeconds
    iratio  =  cpsmidi()/cpsmidinn(60)
    kresample init iratio	
    ibeg = 0			
    iwsize = 4410		
    irandw = 882		
    itimemode = 1			
    ioverlap = 10
    asig sndwarp .5, ktimewarp, kresample, giSoundFileL, ibeg, iwsize, irandw, ioverlap, giSine, itimemode
    aenv expsegr 1,0.5,0.001
    asig *=   aenv
    outs asig, asig
endin

</CsInstruments>
<CsScore>
;causes Csound to run for about 7000 years...
f0 z

i98 0 z
</CsScore>
</CsoundSynthesizer>
2 Likes

Amazing!

Thank you! :smile: