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