Csound Csound-dev Csound-tekno Search About

[Csnd] FileToPvsBuf - Floss UDO for writing into a circular fft buffer

Date2022-12-01 15:18
FromPhilipp Neumann
Subject[Csnd] FileToPvsBuf - Floss UDO for writing into a circular fft buffer
Hello Everybody!
I’m digging into the FFT department of Csound right now and i’m still trying to understand some Stuff out of the Floss Manual.
I try to get my head around this UDO:

opcode FileToPvsBuf, iik, kSoop
kTrig, Sfile, iFFTsize, iOverlap, iWinsize, iWinshape xin

iFFTsize = (iFFTsize == 0 ? 1024 : iFFTsize)
iOverlap = (iOverlap == 0 ? 256 : iOverlap)
iWinsize = (iWinsize == 0 ? iFFTsize : iWinsize)

if kTrig == 1 then
	iLen filelen Sfile
	kNumCycles = iLen*kr
	kCycle init 0
	while 	kCycle < kNumCycles do
			aIn soundin Sfile
			fftin pvsanal aIn, iFFTsize, iOverlap, iWinsize, iWinshape
			iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr)
			kCycle += 1
	od
endif

xout iBuf, iLen, kTim
endop
;--------

Especially these lines:
kNumCycles = iLen*kr
iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr)

I try to explain what i understand and maybe you can correct me or explain it with your words? This would definitiv help me with understanding this.

kNumCycles = iLenkr → setting the length / duration of the loop to read the whole soundfile into the buffer. iLenkr is the Length of the Soundfile in kCycles?

iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr) → iLen+(iFFTsize/sr) i don’t get this at all. Is just adding something to make the buffer circular and the first value is overwritten?

Maybe someone can help me.

All the best,
Philipp
Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here

Date2022-12-01 17:33
FromRichard Knight
SubjectRe: [Csnd] FileToPvsBuf - Floss UDO for writing into a circular fft buffer
Hi
FileToPvsBuf is a really interesting example as it can perform audio 
processing ahead of realtime, which is a 'neat trick' and has influenced 
quite a few things I've made.

> kNumCycles = iLenkr → setting the length / duration of the loop to
> read the whole soundfile into the buffer. iLenkr is the Length of the
> Soundfile in kCycles?
Yes, that's right -so the UDO gets the length of the file in seconds 
(iLen) and then multiplies that by the orchestra's k-rate (kr) to 
determine how many k-cycles are required in the loop to process the 
entire length of it.
Basically a k-cycle in the loop is a chunk of processing, and the number 
of samples processed in (ksmps) that is determined by the rate (kr) that 
Csound is running at. Ie if sr is 44100 and kr is 4410, then ten samples 
of audio are created in each k-cycle, and it would take 4410 k-cycles to 
generate a second of audio.



> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr) → iLen+(iFFTsize/sr) i
> don’t get this at all. Is just adding something to make the buffer
> circular and the first value is overwritten?
FFT processing incurs a slight delay during analysis (which corresponds 
to the FFTsize divided by sample rate) so iFFTsize/sr is that delay in 
seconds. This is used to ensure the buffer has sufficient space for the 
entire sound file and the additional delay caused by the analysis done 
by pvsanal.
  pvsbuffer does write circularly to a buffer, but in the UDO it is only 
filled when kTrig == 1, which I believe is intended to only happen once. 
There is a slightly different version of this UDO in the manual, which 
uses the timeinstk opcode to trigger the filling of the buffer the first 
time it is run (the last example on this page 
http://www.csounds.com/manual/html/pvsbufread.html ).
Hope that helps!


On 2022-12-01 15:18, Philipp Neumann wrote:
> Hello Everybody!
> I’m digging into the FFT department of Csound right now and i’m still
> trying to understand some Stuff out of the Floss Manual.
> I try to get my head around this UDO:
> 
> opcode FileToPvsBuf, iik, kSoop
> kTrig, Sfile, iFFTsize, iOverlap, iWinsize, iWinshape xin
> 
> iFFTsize = (iFFTsize == 0 ? 1024 : iFFTsize)
> iOverlap = (iOverlap == 0 ? 256 : iOverlap)
> iWinsize = (iWinsize == 0 ? iFFTsize : iWinsize)
> 
> if kTrig == 1 then
> 	iLen filelen Sfile
> 	kNumCycles = iLen*kr
> 	kCycle init 0
> 	while 	kCycle < kNumCycles do
> 			aIn soundin Sfile
> 			fftin pvsanal aIn, iFFTsize, iOverlap, iWinsize, iWinshape
> 			iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr)
> 			kCycle += 1
> 	od
> endif
> 
> xout iBuf, iLen, kTim
> endop
> ;--------
> 
> Especially these lines:
> kNumCycles = iLen*kr
> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr)
> 
> I try to explain what i understand and maybe you can correct me or
> explain it with your words? This would definitiv help me with
> understanding this.
> 
> kNumCycles = iLenkr → setting the length / duration of the loop to
> read the whole soundfile into the buffer. iLenkr is the Length of the
> Soundfile in kCycles?
> 
> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr) → iLen+(iFFTsize/sr) i
> don’t get this at all. Is just adding something to make the buffer
> circular and the first value is overwritten?
> 
> Maybe someone can help me.
> 
> All the best,
> Philipp
> Csound mailing list
> Csound@listserv.heanet.ie
> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
> Send bugs reports to
>         https://github.com/csound/csound/issues
> Discussions of bugs and features can be posted here

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here

Date2022-12-04 10:39
FromPhilipp Neumann
SubjectRe: [Csnd] FileToPvsBuf - Floss UDO for writing into a circular fft buffer
Thank you, Richard!
That helps a lot!

Maybe one last question to this UDO:

Because of the delay caused by the analysis isn’t there a free space/silence in the beginning of the buffer of the size of the delay? Maybe for this soundfile it is not important. But when i use a soundfile that has no silence in the beginning and the end of it i wan’t the buffer to be completely filled with it.
Do you understand what i mean?

Greetings, 
Philipp

> Am 01.12.2022 um 18:33 schrieb Richard Knight :
> 
> Hi
> FileToPvsBuf is a really interesting example as it can perform audio processing ahead of realtime, which is a 'neat trick' and has influenced quite a few things I've made.
> 
>> kNumCycles = iLenkr → setting the length / duration of the loop to
>> read the whole soundfile into the buffer. iLenkr is the Length of the
>> Soundfile in kCycles?
> Yes, that's right -so the UDO gets the length of the file in seconds (iLen) and then multiplies that by the orchestra's k-rate (kr) to determine how many k-cycles are required in the loop to process the entire length of it.
> Basically a k-cycle in the loop is a chunk of processing, and the number of samples processed in (ksmps) that is determined by the rate (kr) that Csound is running at. Ie if sr is 44100 and kr is 4410, then ten samples of audio are created in each k-cycle, and it would take 4410 k-cycles to generate a second of audio.
> 
> 
> 
>> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr) → iLen+(iFFTsize/sr) i
>> don’t get this at all. Is just adding something to make the buffer
>> circular and the first value is overwritten?
> FFT processing incurs a slight delay during analysis (which corresponds to the FFTsize divided by sample rate) so iFFTsize/sr is that delay in seconds. This is used to ensure the buffer has sufficient space for the entire sound file and the additional delay caused by the analysis done by pvsanal.
> pvsbuffer does write circularly to a buffer, but in the UDO it is only filled when kTrig == 1, which I believe is intended to only happen once. There is a slightly different version of this UDO in the manual, which uses the timeinstk opcode to trigger the filling of the buffer the first time it is run (the last example on this page http://www.csounds.com/manual/html/pvsbufread.html ).
> Hope that helps!
> 
> 
> On 2022-12-01 15:18, Philipp Neumann wrote:
>> Hello Everybody!
>> I’m digging into the FFT department of Csound right now and i’m still
>> trying to understand some Stuff out of the Floss Manual.
>> I try to get my head around this UDO:
>> opcode FileToPvsBuf, iik, kSoop
>> kTrig, Sfile, iFFTsize, iOverlap, iWinsize, iWinshape xin
>> iFFTsize = (iFFTsize == 0 ? 1024 : iFFTsize)
>> iOverlap = (iOverlap == 0 ? 256 : iOverlap)
>> iWinsize = (iWinsize == 0 ? iFFTsize : iWinsize)
>> if kTrig == 1 then
>> 	iLen filelen Sfile
>> 	kNumCycles = iLen*kr
>> 	kCycle init 0
>> 	while 	kCycle < kNumCycles do
>> 			aIn soundin Sfile
>> 			fftin pvsanal aIn, iFFTsize, iOverlap, iWinsize, iWinshape
>> 			iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr)
>> 			kCycle += 1
>> 	od
>> endif
>> xout iBuf, iLen, kTim
>> endop
>> ;--------
>> Especially these lines:
>> kNumCycles = iLen*kr
>> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr)
>> I try to explain what i understand and maybe you can correct me or
>> explain it with your words? This would definitiv help me with
>> understanding this.
>> kNumCycles = iLenkr → setting the length / duration of the loop to
>> read the whole soundfile into the buffer. iLenkr is the Length of the
>> Soundfile in kCycles?
>> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr) → iLen+(iFFTsize/sr) i
>> don’t get this at all. Is just adding something to make the buffer
>> circular and the first value is overwritten?
>> Maybe someone can help me.
>> All the best,
>> Philipp
>> Csound mailing list
>> Csound@listserv.heanet.ie
>> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
>> Send bugs reports to
>>        https://github.com/csound/csound/issues
>> Discussions of bugs and features can be posted here
> 
> Csound mailing list
> Csound@listserv.heanet.ie
> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
> Send bugs reports to
>       https://github.com/csound/csound/issues
> Discussions of bugs and features can be posted here
> 

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here

Date2022-12-05 15:19
FromRichard Knight
SubjectRe: [Csnd] FileToPvsBuf - Floss UDO for writing into a circular fft buffer
Hi
Glad it helps. Yes, as far as I understand, the start of the buffer will 
have a silence which will be the length of the FFT delay. Any process 
using FFT analysis will have such a delay. Depending on sample rate, the 
delay/silence are usually unperceivably short (eg, 44.1khz sr and 512 
FFT size will result in 0.01 seconds), so may not be discernable by the 
ear in most circumstances.

a couple of things maybe worth thinking about and techniques I sometimes 
use:
- increase sample rate if possible. A 512 point FFT at 44.1khz has a 
0.01s delay, but at a 96khz sample rate, it is 0.005s.
- delay all the rest (the non-FFT audio) of the audio output by the 
corresponding time
- if the pvsbufread output is not needed immediately in realtime, it 
could be written to another audio buffer of the same length, and then 
read when required, with the delay length offsetting the start time. I 
use this quite often for non-realtime things.

all the best
Richard

On 2022-12-04 10:39, Philipp Neumann wrote:
> Thank you, Richard!
> That helps a lot!
> 
> Maybe one last question to this UDO:
> 
> Because of the delay caused by the analysis isn’t there a free
> space/silence in the beginning of the buffer of the size of the delay?
> Maybe for this soundfile it is not important. But when i use a
> soundfile that has no silence in the beginning and the end of it i
> wan’t the buffer to be completely filled with it.
> Do you understand what i mean?
> 
> Greetings,
> Philipp
> 
>> Am 01.12.2022 um 18:33 schrieb Richard Knight :
>> 
>> Hi
>> FileToPvsBuf is a really interesting example as it can perform audio 
>> processing ahead of realtime, which is a 'neat trick' and has 
>> influenced quite a few things I've made.
>> 
>>> kNumCycles = iLenkr → setting the length / duration of the loop to
>>> read the whole soundfile into the buffer. iLenkr is the Length of the
>>> Soundfile in kCycles?
>> Yes, that's right -so the UDO gets the length of the file in seconds 
>> (iLen) and then multiplies that by the orchestra's k-rate (kr) to 
>> determine how many k-cycles are required in the loop to process the 
>> entire length of it.
>> Basically a k-cycle in the loop is a chunk of processing, and the 
>> number of samples processed in (ksmps) that is determined by the rate 
>> (kr) that Csound is running at. Ie if sr is 44100 and kr is 4410, then 
>> ten samples of audio are created in each k-cycle, and it would take 
>> 4410 k-cycles to generate a second of audio.
>> 
>> 
>> 
>>> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr) → iLen+(iFFTsize/sr) i
>>> don’t get this at all. Is just adding something to make the buffer
>>> circular and the first value is overwritten?
>> FFT processing incurs a slight delay during analysis (which 
>> corresponds to the FFTsize divided by sample rate) so iFFTsize/sr is 
>> that delay in seconds. This is used to ensure the buffer has 
>> sufficient space for the entire sound file and the additional delay 
>> caused by the analysis done by pvsanal.
>> pvsbuffer does write circularly to a buffer, but in the UDO it is only 
>> filled when kTrig == 1, which I believe is intended to only happen 
>> once. There is a slightly different version of this UDO in the manual, 
>> which uses the timeinstk opcode to trigger the filling of the buffer 
>> the first time it is run (the last example on this page 
>> http://www.csounds.com/manual/html/pvsbufread.html ).
>> Hope that helps!
>> 
>> 
>> On 2022-12-01 15:18, Philipp Neumann wrote:
>>> Hello Everybody!
>>> I’m digging into the FFT department of Csound right now and i’m still
>>> trying to understand some Stuff out of the Floss Manual.
>>> I try to get my head around this UDO:
>>> opcode FileToPvsBuf, iik, kSoop
>>> kTrig, Sfile, iFFTsize, iOverlap, iWinsize, iWinshape xin
>>> iFFTsize = (iFFTsize == 0 ? 1024 : iFFTsize)
>>> iOverlap = (iOverlap == 0 ? 256 : iOverlap)
>>> iWinsize = (iWinsize == 0 ? iFFTsize : iWinsize)
>>> if kTrig == 1 then
>>> 	iLen filelen Sfile
>>> 	kNumCycles = iLen*kr
>>> 	kCycle init 0
>>> 	while 	kCycle < kNumCycles do
>>> 			aIn soundin Sfile
>>> 			fftin pvsanal aIn, iFFTsize, iOverlap, iWinsize, iWinshape
>>> 			iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr)
>>> 			kCycle += 1
>>> 	od
>>> endif
>>> xout iBuf, iLen, kTim
>>> endop
>>> ;--------
>>> Especially these lines:
>>> kNumCycles = iLen*kr
>>> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr)
>>> I try to explain what i understand and maybe you can correct me or
>>> explain it with your words? This would definitiv help me with
>>> understanding this.
>>> kNumCycles = iLenkr → setting the length / duration of the loop to
>>> read the whole soundfile into the buffer. iLenkr is the Length of the
>>> Soundfile in kCycles?
>>> iBuf, kTim pvsbuffer fftin, iLen+(iFFTsize/sr) → iLen+(iFFTsize/sr) i
>>> don’t get this at all. Is just adding something to make the buffer
>>> circular and the first value is overwritten?
>>> Maybe someone can help me.
>>> All the best,
>>> Philipp
>>> Csound mailing list
>>> Csound@listserv.heanet.ie
>>> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
>>> Send bugs reports to
>>>        https://github.com/csound/csound/issues
>>> Discussions of bugs and features can be posted here
>> 
>> Csound mailing list
>> Csound@listserv.heanet.ie
>> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
>> Send bugs reports to
>>       https://github.com/csound/csound/issues
>> Discussions of bugs and features can be posted here
>> 
> 
> Csound mailing list
> Csound@listserv.heanet.ie
> https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
> Send bugs reports to
>         https://github.com/csound/csound/issues
> Discussions of bugs and features can be posted here

Csound mailing list
Csound@listserv.heanet.ie
https://listserv.heanet.ie/cgi-bin/wa?A0=CSOUND
Send bugs reports to
        https://github.com/csound/csound/issues
Discussions of bugs and features can be posted here