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.