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.