Timewarp With Diskin2

Hey guys, I’m trying to timewarp using Diskin2 opcode but I ran into an issue. The speed and pitch seem to change together and I want to control them independently. Does anyone have an idea of how to do this? Here’s my code.

form caption("Untitled") size(400, 300), guiMode("queue") pluginId("def1") rslider bounds(296, 162, 100, 100), channel("gain"), range(0, 1, 1, 1, .01), text("Gain"), trackerColour("lime"), outlineColour(0, 0, 0, 50), textColour("black") rslider bounds(146, 162, 100, 100), channel("speed"), range(-10, 50, 1, 1, 0.01), text("Speed"), trackerColour(0, 255, 0, 255), outlineColour(0, 0, 0, 50), textColour(0, 0, 0, 255)

bundle(“long.wav”)

-odac ; activate real-time audio output

sr = 44100
ksmps = 32
nchnls = 1

instr 1 ; play audio from disk
kSpeed cabbageGetValue “speed” ; playback speed
iSkip init 0 ; inskip into file (in seconds)
iLoop init 1 ; looping switch (0=off 1=on)

iformat init 0
isize init 0

; read audio from disk using diskin2 opcode
a1, a2 diskin2 “long.wav”, kSpeed, iSkip, iLoop, iformat, isize
out a1, a2 ; send audio to outputs
endin

r1000
i 1 0 450
e

Sorry it pasted weird here it is again

<Cabbage>
form caption(“Untitled”) size(400, 300), guiMode(“queue”) pluginId(“def1”)
rslider bounds(296, 162, 100, 100), channel(“gain”), range(0, 1, 1, 1, .01), text(“Gain”), trackerColour(“lime”), outlineColour(0, 0, 0, 50), textColour(“black”)
rslider bounds(146, 162, 100, 100), channel(“speed”), range(-10, 50, 1, 1, 0.01), text(“Speed”), trackerColour(0, 255, 0, 255), outlineColour(0, 0, 0, 50), textColour(0, 0, 0, 255)

bundle(“long.wav”)

</Cabbage>

<CsoundSynthesizer>
<CsOptions>
-odac ; activate real-time audio output
</CsOptions>
<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 1

instr 1 ; play audio from disk
kSpeed cabbageGetValue “speed” ; playback speed
iSkip init 0 ; inskip into file (in seconds)
iLoop init 1 ; looping switch (0=off 1=on)

iformat init 0
isize init 0

; read audio from disk using diskin2 opcode
a1, a2 diskin2 “long.wav”, kSpeed, iSkip, iLoop, iformat, isize
out a1, a2 ; send audio to outputs
endin
</CsInstruments>

<CsScore>

r1000
i 1 0 450
e
</CsScore>
</CsoundSynthesizer>

You can’t do this with diskin2. Take a look at the sndwarp or sndwarpst. There are also ways of doing this with the pvs opcodes too.

I see. What about with mincer? I tried it with that and it almost works. The only problem is that it doesn’t update the audio until after the entire sample plays. Do you know of any solutions to that? Here’s my code.

<Cabbage> bounds(0, 0, 0, 0)
form caption(“Untitled”) size(400, 300), guiMode(“queue”) pluginId(“def1”)
;rslider bounds(8, 194, 100, 100), channel(“gain”), range(0, 1, 1, 1, 0.01), text(“Gain”), trackerColour(0, 255, 0, 255), outlineColour(0, 0, 0, 50), textColour(0, 0, 0, 255)
rslider bounds(106, 2, 100, 100), channel(“pitch”), range(-12, 12, 1, 1, 0.01), text(“Pitch”), trackerColour(0, 255, 0, 255), outlineColour(0, 0, 0, 50), textColour(0, 0, 0, 255)
rslider bounds(0, 2, 100, 100), channel(“speed”), range(0.01, 10, 1, 1, 0.01), text(“Speed”), trackerColour(0, 255, 0, 255), outlineColour(0, 0, 0, 50), textColour(0, 0, 0, 255)

bundle(“long.wav”)
;pvoc
</Cabbage>

<CsoundSynthesizer>
<CsOptions>
; Select audio/midi flags here according to platform
-odac ;;;realtime audio out
;-iadc ;;;uncomment -iadc if realtime audio input is needed too
; For Non-realtime ouput leave only the line below:
; -o mincer.wav -W ;;; for file output any platform
</CsOptions>
<CsInstruments>

sr = 44100
ksmps = 32
nchnls = 2
0dbfs = 1

;giSoundFile ftgen 0, 0, 0, 1, “long.wav”, 0, 0, 0

instr 1

;idur line 0, nsamp(giSoundFile)/sr, nsamp(giSoundFile)/sr
idur = p3
ilock = 2 ; 1=locked, 2=unlocked
ipitch chnget “pitch”
itimescale chnget “speed”

;itimescale = 1.1
iamp = 0.8

atime line 0, idur, idur*(itimescale)
a1, a2 mincer atime, iamp, ipitch, 1, ilock
outs a1, a2

endin
</CsInstruments>
<CsScore>
f 1 0 0 1 “long.wav” 0 0 0

r1000
i 1 0 3
e

</CsScore>
</CsoundSynthesizer>

Few things here that don’t make sense:

  • You are using i-rate variables for things that should be able to change during performance. ipitch, itimerate for example.
  • the reason it seems that mincer only updates after each sample playback is because that is how you have instructed it to behave. You keep playing the instruments on 3 second cycles over and over again. because you are using i-rate vars for things that should be k-rate, you only hear the difference each time the instrument repeats itself. If you are going to use Cabbage, I’d recommend avoiding r statement in the score entirely.

Here is a simple .csd that will do what you want. Just swap out the name of the sound file. Don’t be afraid to to quiz me on the details. :wink:

<Cabbage>
form caption("Untitled") size(400, 300), guiMode("queue") pluginId("def1")
rslider bounds(296, 162, 100, 100), channel("speed"), range(-1, 2, 1, 1, .01), text("Speed"), trackerColour("lime"), outlineColour(0, 0, 0, 50), textColour("black")
rslider bounds(100, 162, 100, 100), channel("pitch"), range(-1, 2, 1, 1, .01), text("Pitch"), trackerColour("lime"), outlineColour(0, 0, 0, 50), textColour("black")
</Cabbage>
<CsoundSynthesizer>
<CsOptions>
-n -d -+rtmidi=NULL -M0 -m0d 
</CsOptions>
<CsInstruments>
ksmps = 32
nchnls = 2
0dbfs  = 1

instr 1
    ilock = p4
    iamp  = 0.8
    iLen = ftlen(1)
    atime phasor (sr/iLen)*chnget:k("speed")
    aL, aR  mincer atime*iLen/sr, iamp, chnget:k("pitch"), 1, ilock
    outs aL, aR
endin
</CsInstruments>
<CsScore>
f 1 0 0 1 "pianoMood.wav" 0 0 0
i1 0 z
</CsScore>
</CsoundSynthesizer>

Thank you, this is very clean and concise! I do have a couple questions about it.

  1. I see that idur, ipitch, and itimescale are only referenced once. How does the program understand what they’re referring to?
  2. Why is phasor opcode necessary? Wouldn’t it still work if it were replaced with
    line 0,idur,idur*itimescale? I guess you would have to convert that itimescale to a k.

They were just left over from the Manuel example. I’ve edited my previous post now as they were not being used.[quote=“rcohen, post:6, topic:435”]
Why is phasor opcode necessary? Wouldn’t it still work if it were replaced with
[/quote]

You can use a line if you only want the sample to play once. Using a phasor will cause the sample to loop. It just depends on what you want to do. :+1:

That makes a lot of sense. Thank you!