[PD-dev] Libpd multi instance on a VST host

Paul-Arthur Sauvageot via Pd-dev pd-dev at lists.iem.at
Tue Jul 8 10:54:42 CEST 2014


Hello,

I'm currently trying to make a VST that uses libpd and the pd update
allowing multi instances (via pd_instance). But it's not working, for some
reason that I can't find, pthread seems to crash randomly after the second
VST is loaded.

Here is what I added to libpd to be able to sync the VSTs :

*z_libpd.h*

EXTERN void libpd_lock(void);
> EXTERN void libpd_unlock(void);


z_libpd.c

static pthread_mutex_t libpd_mutex = PTHREAD_MUTEX_INITIALIZER;
>


> void libpd_lock() {
>   pthread_mutex_lock(&libpd_mutex);
> }
>


> void libpd_unlock() {
>   pthread_mutex_unlock(&libpd_mutex);
> }



And here is the code of my VST that I made using the JUCE framework (I wont
paste the functions I let as the ones generated by JUCE)

PluginProcessor.h

#ifndef PLUGINPROCESSOR_H_INCLUDED
> #define PLUGINPROCESSOR_H_INCLUDED
>


> #include "../JuceLibraryCode/JuceHeader.h"
>


> extern "C"
> {
> #include "z_libpd.h"
> #include "m_imp.h"
> }
>
> class TestMultiInstanceAudioProcessor  : public AudioProcessor
> {
> public:
>
>     TestMultiInstanceAudioProcessor();
>     ~TestMultiInstanceAudioProcessor();
>
>     void prepareToPlay (double sampleRate, int samplesPerBlock);
>     void releaseResources();
>     void processBlock (AudioSampleBuffer& buffer, MidiBuffer&
> midiMessages);
>


>     /*

       Other auto-generated functions
>
        ----
>      */



> private:
>


>     t_pdinstance *_pdInstance;
>
>     float **_juceIn;
>     float **_juceOut;
>     float *_pdIn;
>     float *_pdOut;
>     float _ticks;
>     float _blockSize;
>     void *_patchHandle;
>


> };
>


> #endif  // PLUGINPROCESSOR_H_INCLUDED



PluginProcessor.cpp

#include "PluginProcessor.h"
> #include "PluginEditor.h"
>
> TestMultiInstanceAudioProcessor::TestMultiInstanceAudioProcessor()
> {
>   //Initializing pd instance
>   _pdInstance = pdinstance_new();
>
>
>   /// Init pd and enable dsp
>   libpd_lock();
>   pd_setinstance(_pdInstance);
>   libpd_init();
>   libpd_start_message(1);
>   libpd_add_float(1.0f);
>   libpd_finish_message("pd", "dsp");
>   libpd_unlock();
>   //Init pd buffers
>   _juceIn = NULL;
>   _juceOut = NULL;
>   _pdIn = NULL;
>   _pdOut = NULL;
> }
>


> TestMultiInstanceAudioProcessor::~TestMultiInstanceAudioProcessor()
> {
>   if (_juceIn)
>   {
>     for (int i = 0; i < getNumInputChannels(); ++i)
>       delete _juceIn[i];
>     delete _juceIn;
>     for (int i = 0; i < getNumOutputChannels(); ++i)
>       delete _juceOut[i];
>     delete _juceOut;
>     delete _pdIn;
>     delete _pdOut;
>   }
>   delete _pdInstance;
> }
>
> void TestMultiInstanceAudioProcessor::prepareToPlay (double sampleRate,
> int samplesPerBlock)
> {
>   //Init libpd audio
>   libpd_lock();
>   pd_setinstance(_pdInstance);
>   libpd_init_audio(getNumInputChannels(),
>                    getNumOutputChannels(),
>                    sampleRate);
>   juce::String patchPath =
> juce::File::getSpecialLocation(juce::File::currentApplicationFile).getParentDirectory().getFullPathName();
>   _patchHandle = libpd_openfile("440.pd",
>                                 patchPath.toRawUTF8());
>   libpd_unlock();
>   //Init buffers
>   _juceIn = new float*[getNumInputChannels()];
>   for (int i = 0; i < getNumInputChannels(); ++i)
>     _juceIn[i] = new float[samplesPerBlock];
>   _juceOut = new float*[getNumOutputChannels()];
>   for (int i = 0; i < getNumOutputChannels(); ++i)
>     _juceOut[i] = new float[samplesPerBlock];
>   _pdIn = new float[getNumInputChannels() * samplesPerBlock];
>   _pdOut = new float[getNumOutputChannels() * samplesPerBlock];
>   //Settings ticks
>   _ticks = samplesPerBlock / libpd_blocksize();
>   _blockSize = samplesPerBlock;
> }
>


> void TestMultiInstanceAudioProcessor::releaseResources()
> {
>   if (_juceIn)
>   {
>     for (int i = 0; i < getNumInputChannels(); ++i)
>       delete _juceIn[i];
>     delete _juceIn;
>     for (int i = 0; i < getNumOutputChannels(); ++i)
>       delete _juceOut[i];
>     delete _juceOut;
>     delete _pdIn;
>     delete _pdOut;
>     _juceIn = NULL;
>     _juceOut = NULL;
>     _pdIn = NULL;
>     _pdOut = NULL;
>   }
>   if (_patchHandle) {
>     libpd_lock();
>     pd_setinstance(_pdInstance);
>     libpd_closefile(_patchHandle);
>     libpd_unlock();
>   }
> }
>


> void TestMultiInstanceAudioProcessor::processBlock (AudioSampleBuffer&
> buffer, MidiBuffer& midiMessages)
> {
>   libpd_lock();
>   pd_setinstance(_pdInstance);
>   libpd_process_float(_ticks, _pdIn, _pdOut);
>   libpd_unlock();
>   for (int i = 0; i < _blockSize * getNumOutputChannels(); ++i)
>     for (int channel = 0; channel < getNumOutputChannels(); ++channel)
>       _juceOut[channel][i / getNumOutputChannels()] = _pdOut[i];
>   for (int channel = 0; channel < getNumOutputChannels(); ++channel)
>     buffer.copyFrom(channel, 0, _juceOut[channel], _blockSize);
> }


/*

  Other autogenerated functions

  ...

*/



According to my logs and my debugger, it never crashes in the VST
functions, it seems to crash on some pthread functions like pthread_kill
but I never use these functions...

Does someone has any idea of where it could come from ?

Regards

-- 
SAUVAGEOT Paul-Arthur.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puredata.info/pipermail/pd-dev/attachments/20140708/84b5b9da/attachment-0001.html>


More information about the Pd-dev mailing list