Hi list,
Excuse me for this little technical OT :)
The problem is about processing audio stream in real time, but let me put it in the context od PD in order to fix the ideas.
When you want to write a PD external that process audio stream, the scenario is: 1- PD passes chunked audio stream to the inlet of the external and read an audio chunk from the outlet of that external. Each input and output chunk is of fixed length of, say, Nc samples. Each chunk is a NON-overlapped adjacent chunk of the audiostream to be processed.
2- The external, read this chunk and trigger the processing method that process the input chunk and return the processed output chunk.
Now, if my processing routine requires overlapped (with an overlap of o%) chunks and a chunk length Nf that, in general, is Nf >= Nb. At this point, id the programmer of the external that is in charge of manage the data structure and the overlapping scheme.
My question is: There is a standard way, a "design pattern", to manage this kind of processing? In the past I've written my own routines that manages a the simple case of real time processing in the case of Nf = Nb, and with an overlap of 50%. It is clear that, in general, this kind of process introduce a delay of one frame (Nb) or more.
If I know Nb, Nf and o% (or equivalent hop-size h). There is a standard way to design my internal processing routine? By standard way I mean a common mode of operation that is formally correct and optimized (it is clear that, potentially, there are tons of methods to do this).
Thank you, and excuse me again for this OT
I don't really have an answer to your question but there are some externals like rfft~ that have a parameter to set the overlap. I would look at this external and others to see how they do it and if there is a common programming pattern. Good luck and please tell us about your findings ;)
On Fri, Jan 16, 2015 at 6:30 AM, Alessio Degani alessio.degani@ymail.com wrote:
Sorry, there is a typo...
On 16/01/2015 12:23, Alessio Degani wrote:
[CUT] say, _Nc_ samples. Each chunk is a NON-overlapped adjacent chunk of the audiostream to be processed.
Here I mean _Nb_ samples! :)
-- a.
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/ listinfo/pd-list
On 01/16/2015 12:23 PM, Alessio Degani wrote:
Hi list,
[...]
When you want to write a PD external that process audio stream, the scenario is: 1- PD passes chunked audio stream to the inlet of the external and read an audio chunk from the outlet of that external. Each input and output chunk is of fixed length of, say, Nc samples. Each chunk is a NON-overlapped adjacent chunk of the audiostream to be processed.
i hope you are aware that this is a simplification on your side, and not how Pd handles audio streams (when it comes to overlapping)
My question is: There is a standard way, a "design pattern", to manage this kind of processing?
i don't know of a standard "design pattern" but there are two ways that come to my mind:
Pd, and read/use them whenever you have collected enough data. overlapping is very simple to implement (as long as you don't overwrite the data :-))
this should be the preferred way, but obviously only works if you can live with Pd's constraints regarding overlap (overlap-factor mus be a power-of-two). you should make your algorithm accept any block-size that Pd accepts (any power-of-two); if this does not work for whatever reasons, you could simply check whether the user has set the correct blocksize/overlap when DSP is turned on, and refuse to work if the settings do not match your expectations (and print an error() so the user knows why it's not working). (the main drawback with this approach is, that there is currently no entirely sane way to uniquely identify the overlap factor. as long as now re-sampling is used, it's fairly easy though)
gfmdar IOhannes
On 16/01/2015 19:33, IOhannes m zmölnig wrote:
On 01/16/2015 12:23 PM, Alessio Degani wrote:
Hi list,
[...]
When you want to write a PD external that process audio stream, the scenario is: 1- PD passes chunked audio stream to the inlet of the external and read an audio chunk from the outlet of that external. Each input and output chunk is of fixed length of, say, Nc samples. Each chunk is a NON-overlapped adjacent chunk of the audiostream to be processed.
i hope you are aware that this is a simplification on your side, and not how Pd handles audio streams (when it comes to overlapping)
Humm... I didn't know that there are different way to handle audio stream in PD. Can PD directly manage overlapp and stuff like that? Where I can read something about that? (I've already read your very useful guide: HOWTO write an External for Pure Data)
My question is: There is a standard way, a "design pattern", to manage this kind of processing?
i don't know of a standard "design pattern" but there are two ways that come to my mind:
- implement a ring-buffer where you put the sample chunks delivered by
Pd, and read/use them whenever you have collected enough data. overlapping is very simple to implement (as long as you don't overwrite the data :-))
Yes... I think that [out/in] ring-buffer is a good practice!
- let Pd do the partitioning and overlapping.
this should be the preferred way, but obviously only works if you can live with Pd's constraints regarding overlap (overlap-factor mus be a power-of-two). [CUT]
Ok... as I said before, I would like to learn more about this! :) It seems a useful facility!
Thank you
gfmdar IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management ->http://lists.puredata.info/listinfo/pd-list
On 01/17/2015 01:25 PM, Alessio Degani wrote:
On 16/01/2015 19:33, IOhannes m zmölnig wrote:
i hope you are aware that this is a simplification on your side, and not how Pd handles audio streams (when it comes to overlapping)
Humm... I didn't know that there are different way to handle audio stream in PD. Can PD directly manage overlapp and stuff like that? Where I can read something about that?
putting a [block~ 128 2] anywhere in your canvas will make it use signal vectors of 128 samples length with an overlap factor of 2 (read: the last 64 samples of the old signal vector are the same as the first 64 samples of the new one).
the objects themselves are not notified of this, they just get 128 sample chunks to process. inspecting the signal-vector's samplerate (sic!, it's really a data-rate) will reveal that it has now the double samplerate as when using [block~ 128].
fgmsar IOhannes
On 17/01/2015 13:54, IOhannes m zmölnig wrote:
the objects themselves are not notified of this, they just get 128 sample chunks to process. inspecting the signal-vector's samplerate (sic!, it's really a data-rate) will reveal that it has now the double samplerate as when using [block~ 128].
That means that, for example, If I need overlapp-add for filtering, in my external's code I can avoid it because PD manage OLA by itself?
fgmsar IOhannes
On 01/17/2015 08:41 PM, Alessio Degani wrote:
On 17/01/2015 13:54, IOhannes m zmölnig wrote:
the objects themselves are not notified of this, they just get 128 sample chunks to process. inspecting the signal-vector's samplerate (sic!, it's really a data-rate) will reveal that it has now the double samplerate as when using [block~ 128].
That means that, for example, If I need overlapp-add for filtering, in my external's code I can avoid it because PD manage OLA by itself?
yes¹
gfmdsar IOhannes
¹ but it also means that the *user* needs to take care about the correct settings for OLA, and the dev cannot do much to enforce it (apart from trying to find out whether the settings are correct and refuse to process otherwise)
On 18/01/2015 18:17, IOhannes m zmölnig wrote:
That means that, for example, If I need overlapp-add for filtering, in my external's code I can avoid it because PD manage OLA by itself?
yes¹
gfmdsar IOhannes
¹ but it also means that the *user* needs to take care about the correct settings for OLA, and the dev cannot do much to enforce it (apart from trying to find out whether the settings are correct and refuse to process otherwise)
Goot to know! :) Thanks IOhannes!
On 17/01/2015 13:54, IOhannes m zmölnig wrote:
On 01/17/2015 01:25 PM, Alessio Degani wrote:
On 16/01/2015 19:33, IOhannes m zmölnig wrote:
i hope you are aware that this is a simplification on your side, and not how Pd handles audio streams (when it comes to overlapping)
Humm... I didn't know that there are different way to handle audio stream in PD. Can PD directly manage overlapp and stuff like that? Where I can read something about that?
putting a [block~ 128 2] anywhere in your canvas will make it use signal vectors of 128 samples length with an overlap factor of 2 (read: the last 64 samples of the old signal vector are the same as the first 64 samples of the new one).
the objects themselves are not notified of this, they just get 128 sample chunks to process. inspecting the signal-vector's samplerate (sic!, it's really a data-rate) will reveal that it has now the double samplerate as when using [block~ 128].
Just to be sure: using [block~ 128 2] means that the dsp routine of the external is called each 64 samples, and a vector of 128 samples is passed to the dsp routine? And plus, the first half of the vector si the same as the second half of the previous buffer?
Now... another question is coming up. Your output is 64 or 128 samples? If 128, Pd will use the overlap-add policy (second half of the previous ouput buffer + first half of the actual)? If so, the programmer of the external needs to know how to deal with that! For example, if I have no need of overlap-add, I've to set second half of my output buffer to zero! It's not a good practice :) so I think that I've missed something hehehe :)
Thank you
fgmsar IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
On 01/20/2015 10:21 AM, Alessio Degani wrote:
Now... another question is coming up. Your output is 64 or 128 samples? If 128, Pd will use the overlap-add policy (second half of the previous ouput buffer + first half of the actual)? If so, the programmer of the external needs to know how to deal with that!
the signal specs are fixed with a canvas. that is: ALL signals in your subpatch will have a size of 128 samples and an overlap factor of 2. if you only consider a single object with one input and one output, this means that both input and output will have the same length and overlap factor and samplerate.
overlap-adding is applied at the patch boundaries (e.g. the [outlet~] of your subpatch to the parent patch running at the nominal specs [block~ 64 1].
mgfrdsa IOhannes
On 20/01/2015 13:00, IOhannes m zmölnig wrote:
On 01/20/2015 10:21 AM, Alessio Degani wrote:
Now... another question is coming up. Your output is 64 or 128 samples? If 128, Pd will use the overlap-add policy (second half of the previous ouput buffer + first half of the actual)? If so, the programmer of the external needs to know how to deal with that!
the signal specs are fixed with a canvas. that is: ALL signals in your subpatch will have a size of 128 samples and an overlap factor of 2. if you only consider a single object with one input and one output, this means that both input and output will have the same length and overlap factor and samplerate.
overlap-adding is applied at the patch boundaries (e.g. the [outlet~] of your subpatch to the parent patch running at the nominal specs [block~ 64 1].
mgfrdsa IOhannes
Thanks IOhannes! Do you know any on-line resources where I can read about how PD engine works at low level? This things are "hidden" to the PD users :)
Cheers
On 01/20/2015 02:31 PM, Alessio Degani wrote:
Thanks IOhannes! Do you know any on-line resources where I can read about how PD engine works at low level?
i'm not aware of a low-level documentation on this.
This things are "hidden" to the PD users :)
hmm, [block~] is well documented, so the *users* should definitely be aware of it (at least, if they are familiar with the Pd-documentation). the *developers* might not be aware of it, since usually the entire overlap/add is done in the background and there's no need to be aware of it. when weird things happen (e.g. because you are doing things across signal block boundaries), i found that things become pretty much self-explanatory (at least this is how i learned :-))
gfmadsr IOhannes
On 20/01/2015 16:09, IOhannes m zmölnig wrote:
On 01/20/2015 02:31 PM, Alessio Degani wrote:
Thanks IOhannes! Do you know any on-line resources where I can read about how PD engine works at low level?
i'm not aware of a low-level documentation on this.
This things are "hidden" to the PD users :)
hmm, [block~] is well documented, so the *users* should definitely be aware of it (at least, if they are familiar with the Pd-documentation).
Yes... in fact [block~] is "user-exposed" (humm, I'm not sure about this term :D )
the *developers* might not be aware of it, since usually the entire overlap/add is done in the background and there's no need to be aware of it. when weird things happen (e.g. because you are doing things across signal block boundaries), i found that things become pretty much self-explanatory (at least this is how i learned :-))
Good! :) Thank you IOhannes
Cheers
gfmadsr IOhannes