Precision while playing soundfile with loscil

Hello Everybody!

I’m working on some ideas with destructing soundfiles that are rhythmic loops.
My idea is to play a soundfile in a loop and at every full cycle of the soundfile i want to change the conditions of the played soundfile (for example change pitch or playbackspeed).

I solved it like in the code at the end.
I track the playing position and use it like an index of the soundfile. When it is at the end i start a loop to change the playing parameters.
I have two problems:

  1. The tracking of the playing position is not very precise. I have the feeling that not every time it reaches my condition the loop is really started.
  2. When the loop is started i get a few new values from the random opcode. I want to use it on i-Rate and only get one new value every time. How can i do this?

Maybe you can help me.
Philipp

<CsoundSynthesizer>
<CsOptions>
-d -odac -W -3 
</CsOptions>
<CsInstruments>
sr = 96000
ksmps = 128
nchnls = 2
0dbfs = 1.0

seed 0
giSmp ftgen 0, 0, 0, 1, "/Users/philippneumann/Documents/Kompositionen/Funktionslust/Material/Loops/DFAM-Loops-Clean/Reverb/DFAM-FuzzNoise-Loop-Reverb-017.wav", 0, 0, 0
;-----------------------------------------------------------
instr 1
kPlaybackspeed init 1
iLoopmode init 1
kStart timeinstk
if kStart >= 100 then
	printk2 kPlaybackspeed
	aIndex, aSmp1, aSmp2 loscilphs 0.5, kPlaybackspeed, giSmp, 1, 1
	kIndex downsamp aIndex
	if kIndex >= 0.99 then
		kPlaybackspeed randomh 0.25, 2, 1000, 3
	endif
endif

outs aSmp1, aSmp2
endin
;-----------------------------------------------------------
</CsInstruments>
<CsScore>
i1 0 20
</CsScore>
</CsoundSynthesizer>

hi philipp -

you can ask the phasor value for the transition between 1 and 0. see the
code below.

(the precision depends on your ksmps setting.)

in general, it might be an idea to split the job between two
instruments: one is doing the control stuff, and calls another
instrument to play back the audio via loscil or whatever.

but perhaps the code below does what you need, as the if-condition is
now true only once for each loop.

best -
joachim

giFox = ftgen(0,0,0,1,“fox.wav”,0,0,0)

instr 1
//initialize previous phase to zero
kPreviousPhase init 0
//loscil with phase value (0-1)
aPhs, aSnd loscilphs .2, 1, giFox, 1, 1
//get phase value as k-rate variable
kThisPhase = k(aPhs)
//ask for first phase value after and of sound is reached
if kThisPhase < kPreviousPhase then
printks(“kThisPhase = %f, kPreviousPhase =
%f\n”,0,kThisPhase,kPreviousPhase)
endif
//set previous phase for next k-cycle
kPreviousPhase = kThisPhase
endin
schedule(1,0,100)

1 Like

Further to Joachim’s comments, you can also create a UDO with ksmps set to 1. This will let you check those k-rate vars at audio rate, so you won’t miss a thing.

Good Idea! I just looked at the UDO section of the floss manual today and tried this as my first UDO. But it don’t really work. Can you help?

<CsoundSynthesizer>
<CsOptions>
-d -odac -W -3 
</CsOptions>
<CsInstruments>
sr = 44100
ksmps = 128
nchnls = 2
0dbfs = 1.0

seed 0
giSmp ftgen 0, 0, 0, 1, "/Users/philippneumann/Documents/Kompositionen/Funktionslust/Material/Loops/DFAM-Loops-Clean/Reverb/DFAM-FuzzNoise-Loop-Reverb-017.wav", 0, 0, 0
opcode AintokRate, k, a
; a-Signal wird in ein k-Signal umgewandelt
; durch eine runtersetzung der ksmps geschieht dies auf Sample-Rate
; daraus folgt: SR = KR
aSnd xin
setksmps 1
kOut = k(aSnd)
xout kOut
endop
;-----------------------------------------------------------
instr 1
kPlaybackspeed init 2

kTimeinstk timeinstk
if kTimeinstk >= 100 then
	aIndex, aSmp1, aSmp2 loscilphs 0.5, kPlaybackspeed, giSmp, 1, 1
	kIndex AintokRate aIndex
	if kIndex == 1 then
		kPlaybackspeed random 0.25, .5
		printk2 kPlaybackspeed
	endif
endif

outs aSmp1, aSmp2
endin
;-----------------------------------------------------------
</CsInstruments>
<CsScore>
i1 0 20
</CsScore>
</CsoundSynthesizer>

This works perfectly! Very clever solution. I had to get my head around this solution. I will try it also with calling another instrument. Thank you!

You will need to do your k-rate checks within the UDO.

aSnd xin
setksmps 1
kOut = k(aSnd)
if kOut == kEtwas then
    do something
endif
xout kOut
endop

Ok,
now i tried to use the UDO like a Trigger: When the a-Signal is on 1 then is the kOut=1 else kOut = 0.
But it doesn’t work…Maybe the Trigger is to fast to get compared? Setting the Main-ksmps to 1 doesn’t help.

<CsoundSynthesizer>
<CsOptions>
-d -odac -W -3 
</CsOptions>
<CsInstruments>
sr = 44100
ksmps = 128
nchnls = 2
0dbfs = 1.0

seed 0
giSmp ftgen 0, 0, 0, 1, "/Users/philippneumann/Documents/Kompositionen/Funktionslust/Material/Loops/DFAM-Loops-Clean/Reverb/DFAM-FuzzNoise-Loop-Reverb-017.wav", 0, 0, 0

opcode CompareAValue, k, ap
; a-Signal wird in ein k-Signal umgewandelt
; durch eine Runtersetzung der ksmps geschieht dies auf Sample-Rate
; daraus folgt: SR = KR
; Input
aSnd, iValue xin
; ksmps auf a-Rate setzen
setksmps 1

kOut init 0
kCompare = k(aSnd)
kOut = (kCompare = iValue ? 1 : 0)
xout kOut
endop
;-----------------------------------------------------------
instr 1
kPlaybackspeed init 1

aPhs, aSmp1, aSmp2 loscilphs 0.5, kPlaybackspeed, giSmp, 1, 1
kIndex CompareAValue aPhs
if kIndex == 1 then
	kPlaybackspeed randomh 0.25, .5, 1000
	printk2 kPlaybackspeed
endif

outs aSmp1, aSmp2
endin
;-----------------------------------------------------------
</CsInstruments>
<CsScore>
i1 0 20
</CsScore>
</CsoundSynthesizer>

You’ll still comparing with the larger ksmps. And you’re doing an assignment rather than a test in this line:

(kCompare = iValue ? 1 : 0)

Something like this:

opcode UpdatePlaybackSpeed, a,k
aPhs xin
setksmps 1
kOut init 1
kPhs = k(aPhs)
if kPhs == 1 then
    kOut randomh 0.25, .5, 1000
endif
xout kOut

and then:

kPlaybackspeed UpdatePlaybackSpeed aPhs
aPhs, aSmp1, aSmp2 loscilphs 0.5, kPlaybackspeed, giSmp, 1, 1

p.s. entirely untested, I’m just making this up here, there are bound to be one or two compilation errors :slight_smile: