[PD-dev] dynamic patching - is iemguts the way to go?
Nick Porcaro
nick at ccrma.stanford.edu
Thu Sep 12 12:09:19 CEST 2019
Miller, et. al:
I think I see the problem, this code would appear to tick ALL the patches
in the pd instance:
for (each buffer from the audio callback) {
for (a smaller buffer that’s the pd block size (eg 64)) {
pd->processFloat (oneTick, smallBufferIn, smallBufferOut);
}
}
So maybe it should be like this:
for (each buffer from the audio callback) {
for (a smaller buffer that’s the pd block size (eg 64)) {
// Do something here to disable the patches that are not active
// eg :
for (patches that are not this one) {
pd->sendFloat(“/patchName/enable",0);
}
pd->processFloat (oneTick, smallBufferIn, smallBufferOut);
}
}
The code above is a member function of a C++ class that encapsulates a patch.
I just realized as I was falling asleep for the night that this line is NOT specific
to any patch!
pd->processFloat (oneTick, smallBufferIn, smallBufferOut);
I’ll try something first thing tomorrow and I’ll let you all know what happens.
- Nick
> On Sep 12, 2019, at 4:56 AM, Nick Porcaro <nick at ccrma.Stanford.EDU> wrote:
>
> Hi Miller-
>
>> On Aug 20, 2019, at 7:08 PM, Miller Puckette <msp at ucsd.edu> wrote:
>>
>> actually I wrote that before I thought the whole thing out :)
>>
>> No, if you "tick" a pdlib instance you tick all the patches in it - so teh
>> way to get different patches in different orders is to call up a separate
>> Pd instance for each of them, and use "adc~" and "dac~" objects to get
>> audio in and out - that incurs zero latency (once you've buffered 64
>> samples in the first place).
>
> I tried this two ways:
>
> - Create separate Pd instances for each patch wrapped in adc~ and dac~
>
> - Use a single Pd instance with multiple patches, with each patch wrapped in adc~ and dac~
>
> Then I have a simple JUCE app (based on the sampler example) that drives
> these pd patches.
>
> There is no problem with doing switch~ and such, but I am
> getting distortion that seems like clipping in both cases (one pd instance with many patches
> or multiple pd instances with one patch)
>
> To be more clear these wrapper patches are like:
>
> Patch 1: [adc~] -> [lop~ 200] -> [dac~]
> Patch 2: [adc~] -> [hip~ 200] -> [dac~]
>
> These wrapper patches also have a loadbang to pd dsp 1;
>
> Then the code that calls these patches does something like this calling libpd:
>
> for (each buffer from the audio callback) {
> for (a smaller buffer that’s the pd block size (eg 64)) {
> pd->processFloat (oneTick, smallBufferIn, smallBufferOut);
> }
> }
>
> I tried scaling the input and output to these wrapper patches after the adc~ and before the dac~
> and that does not solve the distortion/clipping problem either.
>
> There are a couple of more things I can try:
>
> - make the wrapper patches even simpler, just scaling instead of the filters.
> - dump the samples to a file and maybe that will shed some light on the problem.
> - making a much simpler example program that I can share will you all.
>
> I have libpd and pd source directly compiled into my example
>
> Any other ideas would be greatly appreciated!
>
>
>>
>> OR, within one pd instance, in libpd or in Pd, you can use switch~ objects,
>> switched off, to control each sub-patch. Send the switch~ objects bangs in
>> whatever orders you wish. In this scenario, tabsend~ and tabreceive~ would
>> be the simplemt way to pass signals between them. In libpd you can do this
>> zero-latency (just stuff your inpuits into arrays before sending all the
>> tick messages and copy the results out afterward).
>
> This approach works well, but the problem is I can’t insert non-Pd signal processing
> anywhere I’d like in the Pd patch so that’s why I went with the first approach.
>
>>
>> Within the Pd app, you can do teh same thing but you incur one tick extra
>> latency, because copying the autio into the tables has to happen on the
>> previous tick form the one on which you get the outputs back.
>>
>> If you like danger, you can write an external tilde object that, for its
>> "dsp" action, sends a message to teh patch that can "tick" the switch~
>> objects right in the middle of Pd/s DSP tick. This is not part of Pd
>> because it could cause major confusion if general-purpose Pd messages
>> got sent around in mid-tick.
>>
>> cheers
>> Miller
>>
>> On Tue, Aug 20, 2019 at 11:55:58PM +0200, Roman Haefeli wrote:
>>> On Tue, 2019-08-20 at 12:09 -0700, Miller Puckette wrote:
>>>> I think the way to do this in libpd is to open them all as separate
>>>> patches
>>>> within one instance of Pd (so that symbols are shared) and use
>>>> "tabsend"
>>>> and "tabreceive" to route signals to/from them, using shared names
>>>> like
>>>> "channel1" as both inputs and outputs so you can rearrange them in
>>>> any
>>>> order.
>>>>
>>>> (Beware of allowing patches to _write_ andy of their output channels
>>>> before
>>>> reading all the input channels, if you're re-using the same channels
>>>> as
>>>> inputs and outputs :)
>>>
>>> Do I understand right: When loading them as separate patches, you can
>>> dynamically re-order the signal flow by using [tabsend~]/[tabreceive~]
>>> (which you could with abstractions, too) _without_ adding latency?
>>>
>>> And: When changing the symbol of [tabsend~] or [tabreceive~], is the
>>> DSP graph re-calculated?
>>>
>>> Roman
>>
>>
>>
>>> _______________________________________________
>>> Pd-dev mailing list
>>> Pd-dev at lists.iem.at
>>> https://lists.puredata.info/listinfo/pd-dev
>>
>>
>>
>>
>> _______________________________________________
>> Pd-dev mailing list
>> Pd-dev at lists.iem.at
>> https://lists.puredata.info/listinfo/pd-dev
>>
>>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-dev/attachments/20190912/4701470c/attachment.html>
More information about the Pd-dev
mailing list