<div dir="ltr">
















<p class="MsoNormal"><span lang="EN-GB">Hi,</span></p>

<p class="MsoNormal"><span lang="EN-GB">I created a
plugin that loads Pure Data patches so I had to use several instances of Pure
Data in a multi thread context. I managed to solve the problems using
t_pdinstance and locks (so I needed to create my own wrapper like libpd). I think
it would be great to integrate some of these improvements to libpd. Before
sending a pull request or opening another issue on the repository about it, I
thought that it would be better to present how I did this here.</span></p>

<p class="MsoNormal"><span lang="EN-GB"> </span></p>

<p class="MsoNormal"><span lang="EN-GB">I'm
assuming that several instances can't run in parallel for 3 main reasons:</span></p><p class="MsoNormal"><span lang="EN-GB"><br></span></p>

<p class="MsoNormal"><span lang="EN-GB">1 - The
clocks can be created on the fly, so if the current instance is not the right
one, the clocks can be integrated in a wrong list. This problem implies that
all the methods that can create a clock (so potentially all the messages sent
to Pure Data) and the sched_tick method must be called sequentially. I tried to
find a solution (<a href="https://sourceforge.net/p/pure-data/patches/559/" target="_blank">https://sourceforge.net/p/pure-data/patches/559/</a>) but there
are always some specific cases that can’t be thread safe. The only real
solution is (by a way or another) to set up the instance of the clock at its creation
but this implies to change the interface of Pure Data and potentially (surely)
a lot of externals would be deprecated.</span></p><p class="MsoNormal"><span lang="EN-GB"><br></span></p>

<p class="MsoNormal"><span lang="EN-GB">2 - The
vectors of audio input and output are global and the dsp_add method is global.
So the DSP method must be called with the right instance. Here again, the only
real solution would be to change the interface of Pure Data, to receive the
instance in the dsp method and to add the perform methods to this instance. The
dac and adc objects would also be able to retrieve the the vector of audio
input and output specific to the instance.</span></p><p class="MsoNormal"><span lang="EN-GB"><br></span></p>

<p class="MsoNormal"><span lang="EN-GB">3 - The
MIDI methods are global. That implies that most the methods must be called
sequentially if you don’t want to receive or send MIDI events to the wrong
instance.</span></p>

<p class="MsoNormal"><span lang="EN-GB"> </span></p>

<p class="MsoNormal"><span lang="EN-GB">So the best
solution is simply to use t_pdinstance. If the interface is opaque and before
calling any method you set the instance and lock it, you should not have any
problem. Basically, my interface is like this: First, initialize Pure Data and
after you can call</span></p>

<p><span lang="EN-GB">-<span style="font-stretch:normal;font-size:7pt;font-family:'Times New Roman'">  </span></span><span lang="EN-GB">Create
an instance (lock – create the instance – unlock). Each instance has its own vectors
of audio input and output, MIDI methods, print method.</span></p>

<p><span lang="EN-GB">-<span style="font-stretch:normal;font-size:7pt;font-family:'Times New Roman'"> </span></span><span lang="EN-GB">Create
a patch (lock, set the instance, create the patch, unlock).</span></p>

<p><span lang="EN-GB">-<span style="font-stretch:normal;font-size:7pt;font-family:'Times New Roman'"> </span></span><span lang="EN-GB">Prepare
the dsp (lock, set the instance, reallocate the vectors of audio if the sample
rate or the number of inputs or outputs changed, send dsp start message,
unlock). In the DAWs like Reaper you must be able to have two instances running
with two different sample rates. </span></p>

<p><span lang="EN-GB">-<span style="font-stretch:normal;font-size:7pt;font-family:'Times New Roman'">  </span></span><span lang="EN-GB">All
the other methods are called like this:</span></p><p><span>    - Lock and set the instance</span></p><p><span>   - Send the MIDI events, </span>send the messages, process the DSP</p><p><span lang="EN-GB"></span></p><p><span>   - Unlock</span></p><p>When you
set the instance it also sets the current vectors of audio, the print method
and the MIDI methods so the instance receives all the MIDI output event, output
messages, posts, etc. It seems better to gather the methods for the messages,
MIDI and DSP together. You can avoid this but in practise, I don’t see any
reason.</p>

<p class="MsoNormal"><span lang="EN-GB">The
instance management is mostly in the c wrapper and the lock feature is in the
C++ wrapper. Here the code: (<a href="https://github.com/pierreguillot/Camomile/tree/master/Source/Pd)" target="_blank">https://github.com/pierreguillot/Camomile/tree/master/Source/Pd)</a>.  Most of the important stuff are in z_pd.c/.h
(and PdInstance.cpp/.hpp). Of course, I have my own programming style, if you
are interested I'll submit merge requests trying to respect the libPD
programming style. </span></p><p class="MsoNormal"><span lang="EN-GB"><br></span></p>

<p class="MsoNormal"><span lang="EN-GB">Cheers</span></p>

</div>