Browse Source

More DISTRHO work, full VST support

tags/1.9.4
falkTX 12 years ago
parent
commit
5dd88088e2
13 changed files with 334 additions and 247 deletions
  1. +0
    -2
      source/modules/carla_native/nekobi/DistrhoPluginInfo.h
  2. +1
    -1
      source/modules/carla_native/nekobi/DistrhoPluginNekobi.cpp
  3. +3
    -0
      source/modules/carla_native/nekobi/DistrhoPluginNekobi.hpp
  4. +2
    -2
      source/modules/carla_native/nekobi/DistrhoUINekobi.cpp
  5. +8
    -3
      source/modules/carla_native/nekobi/DistrhoUINekobi.hpp
  6. +2
    -0
      source/modules/carla_native/nekobi/NekoWidget.hpp
  7. +0
    -69
      source/modules/distrho/DistrhoUIExternal.hpp
  8. +0
    -46
      source/modules/distrho/DistrhoUIOpenGL.hpp
  9. +0
    -69
      source/modules/distrho/DistrhoUIQt.hpp
  10. +12
    -0
      source/modules/distrho/src/DistrhoPluginInternal.hpp
  11. +6
    -2
      source/modules/distrho/src/DistrhoPluginLV2.cpp
  12. +299
    -52
      source/modules/distrho/src/DistrhoPluginVST.cpp
  13. +1
    -1
      source/tests/Makefile

+ 0
- 2
source/modules/carla_native/nekobi/DistrhoPluginInfo.h View File

@@ -33,6 +33,4 @@


#define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/Nekobi" #define DISTRHO_PLUGIN_URI "http://distrho.sf.net/plugins/Nekobi"


#define DISTRHO_UI_OPENGL

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED

+ 1
- 1
source/modules/carla_native/nekobi/DistrhoPluginNekobi.cpp View File

@@ -121,7 +121,7 @@ DistrhoPluginNekobi::DistrhoPluginNekobi()
fSynth->voice = nekobee_voice_new(); fSynth->voice = nekobee_voice_new();
fSynth->voicelist_mutex_grab_failed = 0; fSynth->voicelist_mutex_grab_failed = 0;
pthread_mutex_init(&fSynth->voicelist_mutex, NULL);
pthread_mutex_init(&fSynth->voicelist_mutex, nullptr);
fSynth->channel_pressure = 0; fSynth->channel_pressure = 0;
fSynth->pitch_wheel_sensitivity = 0; fSynth->pitch_wheel_sensitivity = 0;


+ 3
- 0
source/modules/carla_native/nekobi/DistrhoPluginNekobi.hpp View File

@@ -48,6 +48,9 @@ public:
DistrhoPluginNekobi(); DistrhoPluginNekobi();
~DistrhoPluginNekobi() override; ~DistrhoPluginNekobi() override;
void d_initStateKey(uint32_t, d_string&) override {}
void d_setState(const char*, const char*) override {}
protected: protected:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Information // Information


+ 2
- 2
source/modules/carla_native/nekobi/DistrhoUINekobi.cpp View File

@@ -17,14 +17,14 @@


#include "DistrhoUINekobi.hpp" #include "DistrhoUINekobi.hpp"


#include "dgl/ImageAboutWindow.hpp"
using DGL::Point;


START_NAMESPACE_DISTRHO START_NAMESPACE_DISTRHO


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


DistrhoUINekobi::DistrhoUINekobi() DistrhoUINekobi::DistrhoUINekobi()
: OpenGLUI(),
: UI(),
fAboutWindow(this) fAboutWindow(this)
{ {
// FIXME // FIXME


+ 8
- 3
source/modules/carla_native/nekobi/DistrhoUINekobi.hpp View File

@@ -18,7 +18,7 @@
#ifndef DISTRHO_UI_NEKOBI_HPP_INCLUDED #ifndef DISTRHO_UI_NEKOBI_HPP_INCLUDED
#define DISTRHO_UI_NEKOBI_HPP_INCLUDED #define DISTRHO_UI_NEKOBI_HPP_INCLUDED


#include "DistrhoUIOpenGL.hpp"
#include "DistrhoUI.hpp"


#include "dgl/ImageAboutWindow.hpp" #include "dgl/ImageAboutWindow.hpp"
#include "dgl/ImageButton.hpp" #include "dgl/ImageButton.hpp"
@@ -29,11 +29,16 @@
#include "DistrhoPluginNekobi.hpp" #include "DistrhoPluginNekobi.hpp"
#include "NekoWidget.hpp" #include "NekoWidget.hpp"


using DGL::ImageAboutWindow;
using DGL::ImageButton;
using DGL::ImageKnob;
using DGL::ImageSlider;

START_NAMESPACE_DISTRHO START_NAMESPACE_DISTRHO


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


class DistrhoUINekobi : public OpenGLUI,
class DistrhoUINekobi : public UI,
public ImageButton::Callback, public ImageButton::Callback,
public ImageKnob::Callback, public ImageKnob::Callback,
public ImageSlider::Callback public ImageSlider::Callback
@@ -60,7 +65,7 @@ protected:
// DSP Callbacks // DSP Callbacks


void d_parameterChanged(uint32_t index, float value) override; void d_parameterChanged(uint32_t index, float value) override;
void d_noteReceived(bool, uint8_t, uint8_t, uint8_t) override {}
void d_stateChanged(const char*, const char*) override {}


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// UI Callbacks // UI Callbacks


+ 2
- 0
source/modules/carla_native/nekobi/NekoWidget.hpp View File

@@ -25,6 +25,8 @@


#include "DistrhoArtworkNekobi.hpp" #include "DistrhoArtworkNekobi.hpp"


using DGL::Image;

USE_NAMESPACE_DGL; USE_NAMESPACE_DGL;


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


+ 0
- 69
source/modules/distrho/DistrhoUIExternal.hpp View File

@@ -1,69 +0,0 @@
/*
* DISTRHO Plugin Toolkit (DPT)
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DISTRHO_UI_EXTERNAL_HPP_INCLUDED
#define DISTRHO_UI_EXTERNAL_HPP_INCLUDED

#include "DistrhoUI.hpp"

//#include <lo/lo.h>

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------
// External UI

class ExternalUI : public UI
{
public:
ExternalUI();
virtual ~ExternalUI() override;

protected:
// -------------------------------------------------------------------
// Information (External)

virtual const char* d_getExternalFilename() const = 0;

private:
// -------------------------------------------------------------------
// Implement stuff not needed for external UIs

unsigned int d_getWidth() const noexcept override { return 0; }
unsigned int d_getHeight() const noexcept override { return 0; }

void d_parameterChanged(uint32_t, float) override {}
#if DISTRHO_PLUGIN_WANT_PROGRAMS
void d_programChanged(uint32_t) override {}
#endif
#if DISTRHO_PLUGIN_WANT_STATE
void d_stateChanged(const char*, const char*) override {}
#endif
#if DISTRHO_PLUGIN_IS_SYNTH
void d_noteReceived(bool, uint8_t, uint8_t, uint8_t) override {}
#endif

void d_uiIdle() override {}

friend class UIInternal;
};

// -----------------------------------------------------------------------


END_NAMESPACE_DISTRHO

#endif // DISTRHO_UI_EXTERNAL_HPP_INCLUDED

+ 0
- 46
source/modules/distrho/DistrhoUIOpenGL.hpp View File

@@ -1,46 +0,0 @@
/*
* DISTRHO Plugin Toolkit (DPT)
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DISTRHO_UI_OPENGL_HPP_INCLUDED
#define DISTRHO_UI_OPENGL_HPP_INCLUDED

#include "DistrhoUI.hpp"

#include "dgl/Widget.hpp"

using namespace DGL;

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------
// OpenGL UI

class OpenGLUI : public UI,
public Widget
{
public:
OpenGLUI();
virtual ~OpenGLUI() override;

private:
friend class UIInternal;
};

// -----------------------------------------------------------------------

END_NAMESPACE_DISTRHO

#endif // DISTRHO_UI_OPENGL_HPP_INCLUDED

+ 0
- 69
source/modules/distrho/DistrhoUIQt.hpp View File

@@ -1,69 +0,0 @@
/*
* DISTRHO Plugin Toolkit (DPT)
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
*
* Permission to use, copy, modify, and/or distribute this software for any purpose with
* or without fee is hereby granted, provided that the above copyright notice and this
* permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#ifndef DISTRHO_UI_QT_HPP_INCLUDED
#define DISTRHO_UI_QT_HPP_INCLUDED

#include "DistrhoUI.hpp"

#include <QtCore/Qt>

#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
# include <QtWidgets/QWidget>
#else
# include <QtGui/QWidget>
#endif

START_NAMESPACE_DISTRHO

// -----------------------------------------------------------------------
// Qt UI

class QtUI : public UI,
public QWidget
{
public:
QtUI();
virtual ~QtUI() override;

// -------------------------------------------------------------------
// UI Helpers

void setSize(unsigned int width, unsigned int height);

protected:
// -------------------------------------------------------------------
// Information (Qt)

virtual bool d_isResizable() const noexcept { return false; }
virtual uint d_getMinimumWidth() const noexcept { return 100; }
virtual uint d_getMinimumHeight() const noexcept { return 100; }

private:
// -------------------------------------------------------------------
// Implemented internally

unsigned int d_getWidth() const noexcept override { return width(); }
unsigned int d_getHeight() const noexcept override { return height(); }

friend class UIInternal;
};

// -----------------------------------------------------------------------

END_NAMESPACE_DISTRHO

#endif // DISTRHO_UI_QT_HPP_INCLUDED

+ 12
- 0
source/modules/distrho/src/DistrhoPluginInternal.hpp View File

@@ -278,6 +278,18 @@ public:
} }
#endif #endif


#if DISTRHO_PLUGIN_WANT_TIMEPOS
void setTimePos(const bool playing, const uint64_t frame, const double bpm)
{
if (fData != nullptr)
{
fData->timePos.playing = playing;
fData->timePos.frame = frame;
fData->timePos.bpm = bpm;
}
}
#endif

// ------------------------------------------------------------------- // -------------------------------------------------------------------


void activate() void activate()


+ 6
- 2
source/modules/distrho/src/DistrhoPluginLV2.cpp View File

@@ -403,8 +403,12 @@ public:
if (type != fURIDs.atomString) if (type != fURIDs.atomString)
continue; continue;


//const char* value = (const char*)data;
//setState(key, value);
const char* const value((const char*)data);

if (std::strlen(value)+1 != size)
continue;

setState(key, value);
} }


return LV2_STATE_SUCCESS; return LV2_STATE_SUCCESS;


+ 299
- 52
source/modules/distrho/src/DistrhoPluginVST.cpp View File

@@ -24,14 +24,37 @@
# define __cdecl # define __cdecl
#endif #endif


#ifdef noexcept
# undef noexcept
#endif

#define VESTIGE_HEADER
#define VST_FORCE_DEPRECATED 0 #define VST_FORCE_DEPRECATED 0


//#if VESTIGE_HEADER
//# include "vestige/aeffectx.h"
//# define effSetProgramName 4
//#else
#include "aeffectx.h"
//#endif
#include <map>
#include <string>

#ifdef VESTIGE_HEADER
# include "vestige/aeffectx.h"
#define effFlagsProgramChunks (1 << 5)
#define effGetParamLabel 6
#define effGetParamDisplay 7
#define effGetChunk 23
#define effSetChunk 24
#define effCanBeAutomated 26
#define effGetProgramNameIndexed 29
#define effGetPlugCategory 35
#define kPlugCategEffect 1
#define kPlugCategSynth 2
#define kVstVersion 2400
struct ERect {
int16_t top, left, bottom, right;
};
#else
# include "vst/aeffectx.h"
#endif

typedef std::map<d_string,d_string> StringMap;


START_NAMESPACE_DISTRHO START_NAMESPACE_DISTRHO


@@ -45,14 +68,22 @@ void strncpy(char* const dst, const char* const src, const size_t size)


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


class StateHelper
{
public:
virtual ~StateHelper() {}
virtual void setSharedState(const char* const newKey, const char* const newValue) = 0;
};

#if DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_HAS_UI
class UIVst class UIVst
{ {
public: public:
UIVst(const audioMasterCallback audioMaster, AEffect* const effect, PluginExporter* const plugin, const intptr_t winId)
UIVst(const audioMasterCallback audioMaster, AEffect* const effect, PluginExporter* const plugin, StateHelper* const stateHelper, const intptr_t winId)
: fAudioMaster(audioMaster), : fAudioMaster(audioMaster),
fEffect(effect), fEffect(effect),
fPlugin(plugin), fPlugin(plugin),
fStateHelper(stateHelper),
fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback), fUI(this, winId, editParameterCallback, setParameterCallback, setStateCallback, sendNoteCallback, uiResizeCallback),
fParameterChecks(nullptr), fParameterChecks(nullptr),
fParameterValues(nullptr) fParameterValues(nullptr)
@@ -128,14 +159,14 @@ public:
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// functions called from the plugin side, RT no block // functions called from the plugin side, RT no block


void setParameterValueFromPlugin(const uint32_t index, const float perValue)
void setParameterValueFromPlugin(const uint32_t index, const float perValue) noexcept
{ {
fParameterChecks[index] = true; fParameterChecks[index] = true;
fParameterValues[index] = perValue; fParameterValues[index] = perValue;
} }


#if DISTRHO_PLUGIN_WANT_PROGRAMS #if DISTRHO_PLUGIN_WANT_PROGRAMS
void setProgramFromPlugin(const uint32_t index)
void setProgramFromPlugin(const uint32_t index) noexcept
{ {
fNextProgram = index; fNextProgram = index;


@@ -146,6 +177,16 @@ public:
#endif #endif


// ------------------------------------------------------------------- // -------------------------------------------------------------------
// functions called from the plugin side, block

#if DISTRHO_PLUGIN_WANT_STATE
void setStateFromPlugin(const char* const key, const char* const value)
{
fUI.stateChanged(key, value);
}
#endif

// -------------------------------------------------------------------


protected: protected:
intptr_t hostCallback(const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) intptr_t hostCallback(const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
@@ -173,7 +214,7 @@ protected:
void setState(const char* const key, const char* const value) void setState(const char* const key, const char* const value)
{ {
#if DISTRHO_PLUGIN_WANT_STATE #if DISTRHO_PLUGIN_WANT_STATE
fPlugin->setState(key, value);
fStateHelper->setSharedState(key, value);
#else #else
return; // unused return; // unused
(void)key; (void)key;
@@ -183,7 +224,7 @@ protected:


void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity) void sendNote(const uint8_t channel, const uint8_t note, const uint8_t velocity)
{ {
#if DISTRHO_PLUGIN_IS_SYNTH
#if 0 //DISTRHO_PLUGIN_IS_SYNTH
// TODO // TODO
#else #else
return; // unused return; // unused
@@ -204,6 +245,7 @@ private:
const audioMasterCallback fAudioMaster; const audioMasterCallback fAudioMaster;
AEffect* const fEffect; AEffect* const fEffect;
PluginExporter* const fPlugin; PluginExporter* const fPlugin;
StateHelper* const fStateHelper;


// Plugin UI // Plugin UI
UIExporter fUI; UIExporter fUI;
@@ -251,10 +293,10 @@ private:


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


class PluginVst
class PluginVst : public StateHelper
{ {
public: public:
PluginVst(const audioMasterCallback audioMaster, AEffect* const effect)
PluginVst(const audioMasterCallback audioMaster, AEffect* const effect) noexcept
: fAudioMaster(audioMaster), : fAudioMaster(audioMaster),
fEffect(effect) fEffect(effect)
{ {
@@ -273,8 +315,25 @@ public:
fVstRect.bottom = 0; fVstRect.bottom = 0;
fVstRect.right = 0; fVstRect.right = 0;
#endif #endif

#if DISTRHO_PLUGIN_WANT_STATE
fStateChunk = nullptr;
#endif
} }


#if DISTRHO_PLUGIN_WANT_STATE
~PluginVst()
{
if (fStateChunk != nullptr)
{
delete[] fStateChunk;
fStateChunk = nullptr;
}

fStateMap.clear();
}
#endif

intptr_t vst_dispatcher(const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt) intptr_t vst_dispatcher(const int32_t opcode, const int32_t index, const intptr_t value, void* const ptr, const float opt)
{ {
int32_t ret = 0; int32_t ret = 0;
@@ -301,14 +360,14 @@ public:
ret = fCurProgram; ret = fCurProgram;
break; break;


case effSetProgramName:
// unsupported
break;
//case effSetProgramName:
// unsupported
// break;


case effGetProgramName: case effGetProgramName:
if (ptr != nullptr && fCurProgram >= 0 && fCurProgram < static_cast<int32_t>(fPlugin.getProgramCount())) if (ptr != nullptr && fCurProgram >= 0 && fCurProgram < static_cast<int32_t>(fPlugin.getProgramCount()))
{ {
DISTRHO::strncpy((char*)ptr, fPlugin.getProgramName(fCurProgram), kVstMaxProgNameLen);
DISTRHO::strncpy((char*)ptr, fPlugin.getProgramName(fCurProgram), 24);
ret = 1; ret = 1;
} }
break; break;
@@ -318,8 +377,8 @@ public:
if (ptr != nullptr && index < static_cast<int32_t>(fPlugin.getParameterCount())) if (ptr != nullptr && index < static_cast<int32_t>(fPlugin.getParameterCount()))
{ {
char* buf = (char*)ptr; char* buf = (char*)ptr;
std::snprintf((char*)ptr, kVstMaxParamStrLen, "%f", fPlugin.getParameterValue(index));
buf[kVstMaxParamStrLen] = '\0';
std::snprintf((char*)ptr, 8, "%f", fPlugin.getParameterValue(index));
buf[8] = '\0';
ret = 1; ret = 1;
} }
break; break;
@@ -333,10 +392,17 @@ public:
break; break;


case effMainsChanged: case effMainsChanged:
if (value == 0)
fPlugin.deactivate();
else
if (value != 0)
{
fPlugin.activate(); fPlugin.activate();
#if DISTRHO_PLUGIN_IS_SYNTH
fMidiEventCount = 0;
#endif
}
else
{
fPlugin.deactivate();
}
break; break;


#if DISTRHO_PLUGIN_HAS_UI #if DISTRHO_PLUGIN_HAS_UI
@@ -362,7 +428,7 @@ public:
{ {
d_lastUiSampleRate = fAudioMaster(fEffect, audioMasterGetSampleRate, 0, 0, nullptr, 0.0f); d_lastUiSampleRate = fAudioMaster(fEffect, audioMasterGetSampleRate, 0, 0, nullptr, 0.0f);


fVstUi = new UIVst(fAudioMaster, fEffect, &fPlugin, (intptr_t)ptr);
fVstUi = new UIVst(fAudioMaster, fEffect, &fPlugin, this, (intptr_t)ptr);


# if DISTRHO_PLUGIN_WANT_PROGRAMS # if DISTRHO_PLUGIN_WANT_PROGRAMS
if (fCurProgram >= 0) if (fCurProgram >= 0)
@@ -373,6 +439,20 @@ public:


fVstUi->idle(); fVstUi->idle();


#if DISTRHO_PLUGIN_WANT_STATE
if (fStateMap.size() > 0)
{
for (auto it = fStateMap.begin(), end = fStateMap.end(); it != end; ++it)
{
const d_string& key = it->first;
const d_string& value = it->second;

fVstUi->setStateFromPlugin((const char*)key, (const char*)value);
}

fVstUi->idle();
}
#endif
ret = 1; ret = 1;
} }
break; break;
@@ -394,17 +474,114 @@ public:


#if DISTRHO_PLUGIN_WANT_STATE #if DISTRHO_PLUGIN_WANT_STATE
case effGetChunk: case effGetChunk:
if (ptr == nullptr)
return 0;

if (fStateChunk != nullptr)
delete[] fStateChunk;

if (fStateMap.size() == 0)
{
fStateChunk = new char[1];
fStateChunk[0] = '\0';
ret = 1;
}
else
{
std::string tmpStr;

for (auto it = fStateMap.begin(), end = fStateMap.end(); it != end; ++it)
{
const d_string& key = it->first;
const d_string& value = it->second;

tmpStr += (const char*)key;
tmpStr += "\xff";
tmpStr += (const char*)value;
tmpStr += "\xff";
}

const size_t size(tmpStr.size());
fStateChunk = new char[size];
std::memcpy(fStateChunk, tmpStr.c_str(), size*sizeof(char));

for (size_t i=0; i < size; ++i)
{
if (fStateChunk[i] == '\xff')
fStateChunk[i] = '\0';
}

ret = size;
}

*(void**)ptr = fStateChunk;
break;

case effSetChunk: case effSetChunk:
// TODO
if (value <= 0)
return 0;
if (value == 1)
return 1;

if (const char* const state = (const char*)ptr)
{
const size_t stateSize = value;
const char* stateKey = state;
const char* stateValue = nullptr;

for (size_t i=0; i < stateSize; ++i)
{
// find next null char
if (state[i] != '\0')
continue;

// found, set value
stateValue = &state[i+1];
setSharedState(stateKey, stateValue);

if (fVstUi != nullptr)
fVstUi->setStateFromPlugin(stateKey, stateValue);

// increment text position
i += std::strlen(stateValue) + 2;

// check if end of data
if (i >= stateSize)
break;

// get next key
stateKey = &state[i];
}

ret = 1;
}

break; break;
#endif #endif


#if DISTRHO_PLUGIN_IS_SYNTH #if DISTRHO_PLUGIN_IS_SYNTH
case effProcessEvents: case effProcessEvents:
if (ptr)
if (const VstEvents* const events = (const VstEvents*)ptr)
{ {
//VstEvents* events = (VstEvents*)ptr;
// TODO
if (events->numEvents == 0)
break;

for (int i=0, count=events->numEvents; i < count; ++i)
{
const VstMidiEvent* const vstMidiEvent((const VstMidiEvent*)events->events[i]);

if (vstMidiEvent == nullptr)
break;
if (vstMidiEvent->type != kVstMidiType)
continue;
if (fMidiEventCount >= kMaxMidiEvents)
break;

MidiEvent& midiEvent(fMidiEvents[fMidiEventCount++]);
midiEvent.frame = vstMidiEvent->deltaFrames;
midiEvent.size = 3;
std::memcpy(midiEvent.buf, vstMidiEvent->midiData, 3*sizeof(uint8_t));
}
} }
break; break;
#endif #endif
@@ -420,21 +597,28 @@ public:
} }
break; break;


#if (DISTRHO_PLUGIN_IS_SYNTH || DISTRHO_PLUGIN_WANT_TIMEPOS)
case effCanDo: case effCanDo:
#if DISTRHO_PLUGIN_IS_SYNTH
if (const char* const canDo = (const char*)ptr) if (const char* const canDo = (const char*)ptr)
{ {
# if DISTRHO_PLUGIN_IS_SYNTH
if (std::strcmp(canDo, "receiveVstEvents") == 0) if (std::strcmp(canDo, "receiveVstEvents") == 0)
ret = 1;
else if (std::strcmp(canDo, "receiveVstMidiEvent") == 0)
ret = 1;
return 1;
if (std::strcmp(canDo, "receiveVstMidiEvent") == 0)
return 1;
# endif
# if DISTRHO_PLUGIN_WANT_TIMEPOS
if (std::strcmp(canDo, "receiveVstTimeInfo") == 0)
return 1;
# endif
} }
#endif
break; break;
#endif


case effStartProcess:
case effStopProcess:
break;
//case effStartProcess:
//case effStopProcess:
// unused
// break;
} }


return ret; return ret;
@@ -460,8 +644,14 @@ public:


void vst_processReplacing(float** const inputs, float** const outputs, const int32_t sampleFrames) void vst_processReplacing(float** const inputs, float** const outputs, const int32_t sampleFrames)
{ {
#if DISTRHO_PLUGIN_WANT_TIMEPOS
if (const VstTimeInfo* const timeInfo = (const VstTimeInfo*)fEffect->dispatcher(fEffect, audioMasterGetTime, 0, kVstTempoValid, nullptr, 0.0f))
fPlugin.setTimePos((timeInfo->flags & kVstTransportPlaying) != 0, timeInfo->samplePos, timeInfo->tempo);
#endif

#if DISTRHO_PLUGIN_IS_SYNTH #if DISTRHO_PLUGIN_IS_SYNTH
fPlugin.run(inputs, outputs, sampleFrames, fMidiEventCount, fMidiEvents);
fPlugin.run(inputs, outputs, sampleFrames, fMidiEvents, fMidiEventCount);
fMidiEventCount = 0;
#else #else
fPlugin.run(inputs, outputs, sampleFrames); fPlugin.run(inputs, outputs, sampleFrames);
#endif #endif
@@ -469,6 +659,8 @@ public:


// ------------------------------------------------------------------- // -------------------------------------------------------------------


friend class UIVst;

private: private:
// VST stuff // VST stuff
const audioMasterCallback fAudioMaster; const audioMasterCallback fAudioMaster;
@@ -490,11 +682,43 @@ private:
UIVst* fVstUi; UIVst* fVstUi;
ERect fVstRect; ERect fVstRect;
#endif #endif

#if DISTRHO_PLUGIN_WANT_STATE
char* fStateChunk;
StringMap fStateMap;

void setSharedState(const char* const newKey, const char* const newValue) override
{
fPlugin.setState(newKey, newValue);

// check if key already exists
for (auto it = fStateMap.begin(), end = fStateMap.end(); it != end; ++it)
{
const d_string& key = it->first;

if (key == newKey)
{
it->second = newValue;
return;
}
}

// add a new one then
d_string d_key(newKey);
fStateMap[d_key] = newValue;
}
#endif
}; };


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------


#define handlePtr ((PluginVst*)effect->resvd2)
#ifdef VESTIGE_HEADER
# define handlePtr ((PluginVst*)effect->ptr2)
# define validEffect effect != nullptr && effect->ptr2 != nullptr
#else
# define handlePtr ((PluginVst*)effect->resvd2)
# define validEffect effect != nullptr && effect->resvd2 != 0
#endif


static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt)
{ {
@@ -525,23 +749,39 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
switch (opcode) switch (opcode)
{ {
case effOpen: case effOpen:
if (effect != nullptr && effect->object != nullptr /*&& dynamic_cast<audioMasterCallback>(effect->object)*/)
#ifdef VESTIGE_HEADER
if (effect != nullptr && effect->ptr3 != nullptr)
{
audioMasterCallback audioMaster = (audioMasterCallback)effect->ptr3;
#else
if (effect != nullptr && effect->object != nullptr)
{ {
audioMasterCallback audioMaster = (audioMasterCallback)effect->object; audioMasterCallback audioMaster = (audioMasterCallback)effect->object;
#endif
d_lastBufferSize = audioMaster(effect, audioMasterGetBlockSize, 0, 0, nullptr, 0.0f); d_lastBufferSize = audioMaster(effect, audioMasterGetBlockSize, 0, 0, nullptr, 0.0f);
d_lastSampleRate = audioMaster(effect, audioMasterGetSampleRate, 0, 0, nullptr, 0.0f); d_lastSampleRate = audioMaster(effect, audioMasterGetSampleRate, 0, 0, nullptr, 0.0f);
PluginVst* const plugin(new PluginVst(audioMaster, effect)); PluginVst* const plugin(new PluginVst(audioMaster, effect));
#ifdef VESTIGE_HEADER
effect->ptr2 = plugin;
#else
effect->resvd2 = (intptr_t)plugin; effect->resvd2 = (intptr_t)plugin;
#endif
return 1; return 1;
} }
return 0; return 0;


case effClose: case effClose:
if (effect != nullptr && effect->resvd2 != 0)
if (validEffect)
{ {
#ifdef VESTIGE_HEADER
delete (PluginVst*)effect->ptr2;
effect->ptr2 = nullptr;
effect->ptr3 = nullptr;
#else
delete (PluginVst*)effect->resvd2; delete (PluginVst*)effect->resvd2;
effect->object = nullptr;
effect->resvd2 = 0; effect->resvd2 = 0;
effect->object = nullptr;
#endif
delete effect; delete effect;
return 1; return 1;
} }
@@ -550,7 +790,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
case effGetParamLabel: case effGetParamLabel:
if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount())) if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount()))
{ {
DISTRHO::strncpy((char*)ptr, plugin.getParameterUnit(index), kVstMaxParamStrLen);
DISTRHO::strncpy((char*)ptr, plugin.getParameterUnit(index), 8);
return 1; return 1;
} }
return 0; return 0;
@@ -558,7 +798,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
case effGetParamName: case effGetParamName:
if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount())) if (ptr != nullptr && index < static_cast<int32_t>(plugin.getParameterCount()))
{ {
DISTRHO::strncpy((char*)ptr, plugin.getParameterName(index), kVstMaxParamStrLen);
DISTRHO::strncpy((char*)ptr, plugin.getParameterName(index), 8);
return 1; return 1;
} }
return 0; return 0;
@@ -567,7 +807,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
case effGetProgramNameIndexed: case effGetProgramNameIndexed:
if (ptr != nullptr && index < static_cast<int32_t>(plugin.getProgramCount())) if (ptr != nullptr && index < static_cast<int32_t>(plugin.getProgramCount()))
{ {
DISTRHO::strncpy((char*)ptr, plugin.getProgramName(index), kVstMaxProgNameLen);
DISTRHO::strncpy((char*)ptr, plugin.getProgramName(index), 24);
return 1; return 1;
} }
return 0; return 0;
@@ -583,7 +823,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
case effGetEffectName: case effGetEffectName:
if (ptr != nullptr) if (ptr != nullptr)
{ {
DISTRHO::strncpy((char*)ptr, plugin.getName(), kVstMaxProductStrLen);
DISTRHO::strncpy((char*)ptr, plugin.getName(), 64);
return 1; return 1;
} }
return 0; return 0;
@@ -591,7 +831,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
case effGetVendorString: case effGetVendorString:
if (ptr != nullptr) if (ptr != nullptr)
{ {
DISTRHO::strncpy((char*)ptr, plugin.getMaker(), kVstMaxVendorStrLen);
DISTRHO::strncpy((char*)ptr, plugin.getMaker(), 64);
return 1; return 1;
} }
return 0; return 0;
@@ -599,7 +839,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
case effGetProductString: case effGetProductString:
if (ptr != nullptr) if (ptr != nullptr)
{ {
DISTRHO::strncpy((char*)ptr, plugin.getLabel(), kVstMaxEffectNameLen);
DISTRHO::strncpy((char*)ptr, plugin.getLabel(), 32);
return 1; return 1;
} }
return 0; return 0;
@@ -612,7 +852,7 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t
}; };


// handle advanced opcodes // handle advanced opcodes
if (effect != nullptr && effect->resvd2 != 0)
if (validEffect)
return handlePtr->vst_dispatcher(opcode, index, value, ptr, opt); return handlePtr->vst_dispatcher(opcode, index, value, ptr, opt);


return 0; return 0;
@@ -620,26 +860,26 @@ static intptr_t vst_dispatcherCallback(AEffect* effect, int32_t opcode, int32_t


static float vst_getParameterCallback(AEffect* effect, int32_t index) static float vst_getParameterCallback(AEffect* effect, int32_t index)
{ {
if (effect != nullptr && effect->resvd2 != 0)
if (validEffect)
return handlePtr->vst_getParameter(index); return handlePtr->vst_getParameter(index);
return 0.0f; return 0.0f;
} }


static void vst_setParameterCallback(AEffect* effect, int32_t index, float value) static void vst_setParameterCallback(AEffect* effect, int32_t index, float value)
{ {
if (effect != nullptr && effect->resvd2 != 0)
if (validEffect)
handlePtr->vst_setParameter(index, value); handlePtr->vst_setParameter(index, value);
} }


static void vst_processCallback(AEffect* effect, float** inputs, float** outputs, int32_t sampleFrames) static void vst_processCallback(AEffect* effect, float** inputs, float** outputs, int32_t sampleFrames)
{ {
if (effect != nullptr && effect->resvd2 != 0)
if (validEffect)
handlePtr->vst_processReplacing(inputs, outputs, sampleFrames); handlePtr->vst_processReplacing(inputs, outputs, sampleFrames);
} }


static void vst_processReplacingCallback(AEffect* effect, float** inputs, float** outputs, int32_t sampleFrames) static void vst_processReplacingCallback(AEffect* effect, float** inputs, float** outputs, int32_t sampleFrames)
{ {
if (effect != nullptr && effect->resvd2 != 0)
if (validEffect)
handlePtr->vst_processReplacing(inputs, outputs, sampleFrames); handlePtr->vst_processReplacing(inputs, outputs, sampleFrames);
} }


@@ -668,7 +908,11 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster)
// vst fields // vst fields
effect->magic = kEffectMagic; effect->magic = kEffectMagic;
effect->uniqueID = plugin->getUniqueId(); effect->uniqueID = plugin->getUniqueId();
#ifdef VESTIGE_HEADER
*(int32_t*)&effect->unknown1 = plugin->getVersion();
#else
effect->version = plugin->getVersion(); effect->version = plugin->getVersion();
#endif


// plugin fields // plugin fields
effect->numParams = plugin->getParameterCount(); effect->numParams = plugin->getParameterCount();
@@ -696,10 +940,13 @@ const AEffect* VSTPluginMain(audioMasterCallback audioMaster)
effect->getParameter = vst_getParameterCallback; effect->getParameter = vst_getParameterCallback;
effect->setParameter = vst_setParameterCallback; effect->setParameter = vst_setParameterCallback;
effect->processReplacing = vst_processReplacingCallback; effect->processReplacing = vst_processReplacingCallback;
effect->processDoubleReplacing = nullptr;


// pointers // pointers
#ifdef VESTIGE_HEADER
effect->ptr3 = (void*)audioMaster;
#else
effect->object = (void*)audioMaster; effect->object = (void*)audioMaster;
#endif


return effect; return effect;
} }

+ 1
- 1
source/tests/Makefile View File

@@ -61,7 +61,7 @@ DISTRHO: DISTRHO.cpp ../modules/distrho/*.hpp ../modules/distrho/src/*.cpp
./DISTRHO ./DISTRHO


DISTRHO.so: DISTRHO.cpp ../modules/distrho/*.hpp ../modules/distrho/src/*.cpp DISTRHO.so: DISTRHO.cpp ../modules/distrho/*.hpp ../modules/distrho/src/*.cpp
$(CXX) $< ../modules/dgl.a $(BUILD_CXX_FLAGS) -I../modules/distrho -DSHARED_DLL $(LINK_FLAGS) $(DGL_LIBS) -shared -Wl,--no-undefined -o $@
$(CXX) $< ../modules/dgl.a $(BUILD_CXX_FLAGS) -I../modules/distrho -I../modules/carla_native/nekobi -DSHARED_DLL $(LINK_FLAGS) $(DGL_LIBS) -lpthread -shared -Wl,--no-undefined -o $@


DGL: DGL.cpp ../modules/distrho/dgl/src/Window.cpp DGL: DGL.cpp ../modules/distrho/dgl/src/Window.cpp
$(CXX) $< $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) -o $@ $(CXX) $< $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) -o $@


Loading…
Cancel
Save