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
#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.