Cabbage Logo
Back to Cabbage Site

PVS opcodes - scrambling phases of bins

I posted on to the Csound list, but thought it would be worth posting the question to all the friendly faces here :slight_smile: sorry, not strictly Cabbage related, hope that’s ok!

I’m wondering how to randomise the phases of an fsig generated by pvstanal before getting resynthesised back into the audio domain. My aim it to create the effect of the Paulsynth algorithm but with more bells and whistles, but I can’t seem to penetrate the set of pvs opcodes to put me on the right track…

Any pointers please? Many thanks

Hmm, I’m not sure but pvsbin will get you all the bins from a pvsanal. Once you have them you can do as you wish with them, but it might be kind of slow, depending on how many bins you are synthesising.

Here’s a recursive UDO of the pvsynth opcode in Csound using nothing but oscillators and pvsbin.

;pvsynth UDO RW - 2019
opcode AddSyn,a,fio
fs1,inum,icnt xin
if icnt >= inum goto synth
 a1 AddSyn fs1, inum, icnt+1
synth:
 ka, kf pvsbin fs1, icnt
 ka port ka, 0.001
 kf port kf, 0.001
 asig poscil3 ka,kf
 xout asig + a1
endop

Ahh nice example thanks. I was wondering from the other opcodes how you’d mess with the bins and your example with pvsbin does just that. The pvsmooth and pvsfreeze opcodes encapsulate a lot of functionality, which makes it easier to use, which is no bad thing.

So with pvsbin I’d assume that the ‘phase’ is dictated by the resynthesis, which in your case is the poscil3?

Yeah, in this case that is correct. But, if I’m not mistaken there might be a way of extracting the phase information from the analysis stage too. In my application of this, I was adding very small fluctuations in the frequencies of each bin to create what I thought would be a a really cool effect. In the end it was interesting enough, but I’m not sure it is worth the CPU overhead.

I also use Rory’s recursive method with pvsbin - mainly for teaching and demonstrations - and it is indeed useful, but probably too CPU intensive for practical use. Using this approach you can recreate the processing of a lot of the other pvs opcodes like pvsblur, pvsfreeze. If you want to shift the phase of individual bins you could possibly do this using the spectral delay method using pvsbuffer and pvsbufread2.

Oh cool, I’ll checkout the example for Spectral delay. Cheers for the tip :wink:

Okay I seem to be getting somewhere I think. The circular buffer is something I need to workaround. Perhaps filling the whole read buffer on load, then the pointer can read as its own pace?

You actually don’t need to worry about the circular buffer too much. If you only want to add some spectral delay, use the distribution tables and just use the output pointer from pvsbuffer as the read pointer for pvsbufread2. You only need to make sure that the buffer is at least as long as the longest delay you specify in the distribution tables. Here is an example that just delays each bin by a random tiny amount:

giFFT    =           1024
iDist    =           4           ; distribution (4 = exponential)
iDel     =           0.1         ; maximum delay time
giDels   ftgen       1, 0, giFFT, -21, iDist, iDel ; delay times distribution

instr    1
aL,aR    diskin2     "AcousticGuitar.wav", 1 ; (replace with your own sound file)
fL       pvsanal     aL, giFFT, giFFT/8, giFFT, 1
iLen     =           10
iH,kTime pvsbuffer   fL, iLen 
fBuf     pvsbufread2 kTime, iH, giDels, giDels
aSig     pvsynth     fBuf
         outs        aSig, aSig
endin
2 Likes

Nice, I’d actually hacked something similar using a combination of two of your patches :grin: this is much cleaner tho. Look forward to trying it out , thanks