moved to vestige

This commit is contained in:
itsmattkc
2019-01-22 03:45:31 -08:00
parent 86464b76e4
commit 8977acde31
8 changed files with 463 additions and 29 deletions
+83 -21
View File
@@ -1,6 +1,6 @@
#include "vsthost.h"
#ifdef _WIN32
#if (defined(_WIN32) || defined(__APPLE__)) && !defined(NOVST)
// adapted from http://teragonaudio.com/article/How-to-make-your-own-VST-host.html
@@ -17,10 +17,20 @@
#define BLOCK_SIZE 512
#define CHANNEL_COUNT 2
struct VSTRect {
int16_t top;
int16_t left;
int16_t bottom;
int16_t right;
};
#define effGetChunk 23
#define effSetChunk 24
// C callbacks
extern "C" {
// Main host callback
VstIntPtr VSTCALLBACK hostCallback(AEffect* effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) {
intptr_t hostCallback(AEffect* effect, int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) {
switch(opcode) {
case audioMasterVersion:
return 2400;
@@ -44,46 +54,89 @@ extern "C" {
// Plugin's entry point
typedef AEffect *(*vstPluginFuncPtr)(audioMasterCallback host);
// Plugin's getParameter() method
typedef float (*getParameterFuncPtr)(AEffect *effect, VstInt32 index);
typedef float (*getParameterFuncPtr)(AEffect *effect, int32_t index);
// Plugin's setParameter() method
typedef void (*setParameterFuncPtr)(AEffect *effect, VstInt32 index, float value);
typedef void (*setParameterFuncPtr)(AEffect *effect, int32_t index, float value);
// Plugin's processEvents() method
typedef VstInt32 (*processEventsFuncPtr)(VstEvents *events);
typedef int32_t (*processEventsFuncPtr)(VstEvents *events);
// Plugin's process() method
typedef void (*processFuncPtr)(AEffect *effect, float **inputs, float **outputs, VstInt32 sampleFrames);
typedef void (*processFuncPtr)(AEffect *effect, float **inputs, float **outputs, int32_t sampleFrames);
void VSTHost::loadPlugin() {
QString dll_fn = file_field->get_filename(0, true);
modulePtr = LibLoad(dll_fn);
if(modulePtr == nullptr) {
DWORD dll_err = GetLastError();
qCritical() << "Failed to load VST" << dll_fn << "-" << dll_err;
#if defined(__APPLE__)
bundle = BundleLoad(dll_fn);
if (bundle == NULL) {
QMessageBox::critical(nullptr, tr("Error loading VST plugin"), tr("Failed to create VST reference"));
return;
}
vstPluginFuncPtr mainEntryPoint = NULL;
mainEntryPoint = (vstPluginFuncPtr)CFBundleGetFunctionPointerForName(bundle, CFSTR("VSTPluginMain"));
// VST plugins previous to the 2.4 SDK used main_macho for the entry point name
if(mainEntryPoint == NULL) {
mainEntryPoint = (vstPluginFuncPtr)CFBundleGetFunctionPointerForName(bundle, CFSTR("main_macho"));
}
if(mainEntryPoint == NULL) {
qCritical() << "Couldn't get a pointer to VST plugin's main()";
BundleClose(bundle);
return;
}
plugin = mainEntryPoint(hostCallback);
if(plugin == NULL) {
qCritical() << "Plugin's main() returns null";
BundleClose(bundle);
return;
}
#else
handle = LibLoad(dll_fn);
if(handle == nullptr) {
QString dll_error;
#ifdef _WIN32
QString msg_err = tr("Failed to load VST plugin \"%1\": %2").arg(dll_fn, QString::number(dll_err));
if (dll_err == 193) {
DWORD dll_err = GetLastError();
dll_error = QString::number(dll_err);
#elif __linux__
dll_error = dlerror();
#endif
qCritical() << "Failed to load VST plugin" << dll_fn << "-" << dll_error;
QString msg_err = tr("Failed to load VST plugin \"%1\": %2").arg(dll_fn, dll_error);
#ifdef _WIN32
if (dll_err == 193) {
#ifdef _WIN64
msg_err += "\n\n" + tr("NOTE: You can't load 32-bit VST plugins into a 64-bit build of Olive. Please find a 64-bit version of this plugin or switch to a 32-bit build of Olive.");
msg_err += "\n\n" + tr("NOTE: You can't load 32-bit VST plugins into a 64-bit build of Olive. Please find a 64-bit version of this plugin or switch to a 32-bit build of Olive.");
#elif _WIN32
msg_err += "\n\n" + tr("NOTE: You can't load 64-bit VST plugins into a 32-bit build of Olive. Please find a 32-bit version of this plugin or switch to a 64-bit build of Olive.");
msg_err += "\n\n" + tr("NOTE: You can't load 64-bit VST plugins into a 32-bit build of Olive. Please find a 32-bit version of this plugin or switch to a 64-bit build of Olive.");
#endif
}
#endif
}
QMessageBox::critical(mainWindow, tr("Error loading VST plugin"), msg_err);
return;
}
QMessageBox::critical(nullptr, tr("Error loading VST plugin"), msg_err);
return;
}
vstPluginFuncPtr mainEntryPoint =
reinterpret_cast<vstPluginFuncPtr>(LibAddress(modulePtr, "VSTPluginMain"));
// Instantiate the plugin
plugin = mainEntryPoint(hostCallback);
#endif
}
void VSTHost::freePlugin() {
if (plugin != nullptr) {
stopPlugin();
#if defined(__APPLE__)
CFBundleUnloadExecutable(bundle);
CFRelease(bundle);
#else
LibClose(modulePtr);
#endif
plugin = nullptr;
}
}
@@ -225,7 +278,7 @@ void VSTHost::custom_load(QXmlStreamReader &stream) {
stream.readNext();
QByteArray b = QByteArray::fromBase64(stream.text().toUtf8());
if (plugin != nullptr) {
dispatcher(plugin, effSetChunk, 0, VstInt32(b.size()), static_cast<void*>(b.data()), 0);
dispatcher(plugin, effSetChunk, 0, int32_t(b.size()), static_cast<void*>(b.data()), 0);
}
}
}
@@ -234,7 +287,7 @@ void VSTHost::save(QXmlStreamWriter &stream) {
Effect::save(stream);
if (plugin != nullptr) {
char* p = nullptr;
VstInt32 length = VstInt32(dispatcher(plugin, effGetChunk, 0, 0, &p, 0));
int32_t length = int32_t(dispatcher(plugin, effGetChunk, 0, 0, &p, 0));
QByteArray b(p, length);
stream.writeTextElement("plugindata", b.toBase64());
}
@@ -254,13 +307,22 @@ void VSTHost::change_plugin() {
if (plugin != nullptr) {
if (configurePluginCallbacks()) {
startPlugin();
#ifdef __WIN32
dispatcher(plugin, effEditOpen, 0, 0, reinterpret_cast<HWND>(dialog->winId()), 0);
ERect* eRect = nullptr;
#elif __APPLE__
dispatcher(plugin, effEditOpen, 0, 0, reinterpret_cast<NSWindow*>(dialog->winId()), 0);
#endif
VSTRect* eRect = nullptr;
plugin->dispatcher(plugin, effEditGetRect, 0, 0, &eRect, 0);
dialog->setFixedWidth(eRect->right);
dialog->setFixedHeight(eRect->bottom);
} else {
#ifdef __APPLE__
CFBundleUnloadExecutable(bundle);
CFRelease(bundle);
#else
LibClose(modulePtr);
#endif
plugin = nullptr;
}
}
+7 -4
View File
@@ -1,18 +1,17 @@
#ifndef VSTHOSTWIN_H
#define VSTHOSTWIN_H
#ifdef _WIN32
#if (defined(_WIN32) || defined(__APPLE__)) && !defined(NOVST)
#include "project/effect.h"
#include "io/crossplatformlib.h"
#include <vst/aeffectx.h>
#include "include/vestige.h"
// Plugin's dispatcher function
typedef VstIntPtr (*dispatcherFuncPtr)(AEffect *effect, VstInt32 opCode, VstInt32 index, VstInt32 value, void *ptr, float opt);
typedef intptr_t (*dispatcherFuncPtr)(AEffect *effect, int32_t opCode, int32_t index, int32_t value, void *ptr, float opt);
struct AEffect;
class QDialog;
class VSTHost : public Effect {
@@ -46,7 +45,11 @@ private:
float** outputs;
QDialog* dialog;
QPushButton* show_interface_btn;
#if defined(__APPLE__)
CFBundleRef bundle;
#else
ModulePtr modulePtr;
#endif
};
#endif
+342
View File
@@ -0,0 +1,342 @@
/*
* vestige.h - simple header to allow VeSTige compilation and eventually work
*
* Copyright (c) 2006 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
* This VeSTige header is included in this package in the good-faith
* belief that it has been cleanly and legally reverse engineered
* without reference to the official VST SDK and without its
* developer(s) having agreed to the VST SDK license agreement.
*/
#include <stdint.h>
#ifndef _VESTIGE_H
#define _VESTIGE_H
#define CCONST(a, b, c, d)( ( ( (int) a ) << 24 ) | \
( ( (int) b ) << 16 ) | \
( ( (int) c ) << 8 ) | \
( ( (int) d ) << 0 ) )
#define audioMasterAutomate 0
#define audioMasterVersion 1
#define audioMasterCurrentId 2
#define audioMasterIdle 3
#define audioMasterPinConnected 4
// unsupported? 5
#define audioMasterWantMidi 6
#define audioMasterGetTime 7
#define audioMasterProcessEvents 8
#define audioMasterSetTime 9
#define audioMasterTempoAt 10
#define audioMasterGetNumAutomatableParameters 11
#define audioMasterGetParameterQuantization 12
#define audioMasterIOChanged 13
#define audioMasterNeedIdle 14
#define audioMasterSizeWindow 15
#define audioMasterGetSampleRate 16
#define audioMasterGetBlockSize 17
#define audioMasterGetInputLatency 18
#define audioMasterGetOutputLatency 19
#define audioMasterGetPreviousPlug 20
#define audioMasterGetNextPlug 21
#define audioMasterWillReplaceOrAccumulate 22
#define audioMasterGetCurrentProcessLevel 23
#define audioMasterGetAutomationState 24
#define audioMasterOfflineStart 25
#define audioMasterOfflineRead 26
#define audioMasterOfflineWrite 27
#define audioMasterOfflineGetCurrentPass 28
#define audioMasterOfflineGetCurrentMetaPass 29
#define audioMasterSetOutputSampleRate 30
// unsupported? 31
#define audioMasterGetSpeakerArrangement 31 // deprecated in 2.4?
#define audioMasterGetVendorString 32
#define audioMasterGetProductString 33
#define audioMasterGetVendorVersion 34
#define audioMasterVendorSpecific 35
#define audioMasterSetIcon 36
#define audioMasterCanDo 37
#define audioMasterGetLanguage 38
#define audioMasterOpenWindow 39
#define audioMasterCloseWindow 40
#define audioMasterGetDirectory 41
#define audioMasterUpdateDisplay 42
#define audioMasterBeginEdit 43 //BeginGesture
#define audioMasterEndEdit 44 //EndGesture
#define audioMasterOpenFileSelector 45
#define audioMasterCloseFileSelector 46 // currently unused
#define audioMasterEditFile 47 // currently unused
#define audioMasterGetChunkFile 48 // currently unused
#define audioMasterGetInputSpeakerArrangement 49 // currently unused
#define effFlagsHasEditor 1
#define effFlagsCanReplacing (1 << 4) // very likely
#define effFlagsIsSynth (1 << 8) // currently unused
#define effOpen 0
#define effClose 1 // currently unused
#define effSetProgram 2 // currently unused
#define effGetProgram 3 // currently unused
#define effGetProgramName 5 // currently unused
#define effGetParamName 8 // currently unused
#define effSetSampleRate 10
#define effSetBlockSize 11
#define effMainsChanged 12
#define effEditGetRect 13
#define effEditOpen 14
#define effEditClose 15
#define effEditIdle 19
#define effEditTop 20
#define effProcessEvents 25
// the next one from http://asseca.com/vst-24-specs/index.html
#define effGetPlugCategory 35
#define effGetEffectName 45
#define effGetVendorString 47
#define effGetProductString 48
#define effGetVendorVersion 49
#define effCanDo 51 // currently unused
/* from http://asseca.com/vst-24-specs/efIdle.html */
#define effIdle 53
/* from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
#define effGetParameterProperties 56
#define effGetVstVersion 58 // currently unused
/* http://asseca.com/vst-24-specs/efShellGetNextPlugin.html */
#define effShellGetNextPlugin 70
/* The next two were gleaned from http://www.kvraudio.com/forum/printview.php?t=143587&start=0 */
#define effStartProcess 71
#define effStopProcess 72
#define effBeginSetProgram 67
#define effEndSetProgram 68
#ifdef WORDS_BIGENDIAN
// "VstP"
#define kEffectMagic 0x50747356
#else
// "PtsV"
#define kEffectMagic 0x56737450
#endif
#define kVstLangEnglish 1
#define kVstMidiType 1
struct RemoteVstPlugin;
#define kVstTransportChanged 1
#define kVstTransportPlaying (1 << 1)
#define kVstTransportCycleActive (1 << 2)
#define kVstTransportRecording (1 << 3)
#define kVstAutomationWriting (1 << 6)
#define kVstAutomationReading (1 << 7)
#define kVstNanosValid (1 << 8)
#define kVstPpqPosValid (1 << 9)
#define kVstTempoValid (1 << 10)
#define kVstBarsValid (1 << 11)
#define kVstCyclePosValid (1 << 12)
#define kVstTimeSigValid (1 << 13)
#define kVstSmpteValid (1 << 14)
#define kVstClockValid (1 << 15)
struct _VstMidiEvent
{
// 00
int type;
// 04
int byteSize;
// 08
int deltaSamples;
// 0c?
int flags;
// 10?
int noteLength;
// 14?
int noteOffset;
// 18
char midiData[4];
// 1c?
char detune;
// 1d?
char noteOffVelocity;
// 1e?
char reserved1;
// 1f?
char reserved2;
};
typedef struct _VstMidiEvent VstMidiEvent;
struct _VstEvent
{
char dump[sizeof (VstMidiEvent)];
};
typedef struct _VstEvent VstEvent;
struct _VstEvents
{
// 00
int numEvents;
// 04
void *reserved;
// 08
VstEvent * events[];
};
/* constants from http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?t=3740&sid=183f74631fee71a493316735e2b9f28b */
enum Vestige2StringConstants
{
VestigeMaxNameLen = 64,
VestigeMaxLabelLen = 128,
VestigeMaxShortLabelLen = 8,
VestigeMaxCategLabelLen = 24,
VestigeMaxFileNameLen = 100
};
/* constants from http://asseca.com/vst-24-specs/efGetPlugCategory.html */
enum VstPlugCategory
{
kPlugCategUnknown = 0,
kPlugCategEffect,
kPlugCategSynth,
kPlugCategAnalysis,
kPlugCategMastering,
kPlugCategSpacializer,
kPlugCategRoomFx,
kPlugSurroundFx,
kPlugCategRestoration,
kPlugCategOfflineProcess,
kPlugCategShell,
kPlugCategGenerator,
kPlugCategMaxCount
};
typedef struct _VstEvents VstEvents;
/* this struct taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
struct _VstParameterProperties
{
float stepFloat; /* float step */
float smallStepFloat; /* small float step */
float largeStepFloat; /* large float step */
char label[64]; /* parameter label */
int32_t flags; /* @see VstParameterFlags */
int32_t minInteger; /* integer minimum */
int32_t maxInteger; /* integer maximum */
int32_t stepInteger; /* integer step */
int32_t largeStepInteger; /* large integer step */
char shortLabel[VestigeMaxShortLabelLen]; /* short label, recommended: 6 + delimiter */
int16_t displayIndex; /* index where this parameter should be displayed (starting with 0) */
int16_t category; /* 0: no category, else group index + 1 */
int16_t numParametersInCategory; /* number of parameters in category */
int16_t reserved; /* zero */
char categoryLabel[VestigeMaxCategLabelLen]; /* category label, e.g. "Osc 1" */
char future[16]; /* reserved for future use */
};
typedef struct _VstParameterProperties VstParameterProperties;
/* this enum taken from http://asseca.com/vst-24-specs/efGetParameterProperties.html */
enum VstParameterFlags
{
kVstParameterIsSwitch = 1 << 0, /* parameter is a switch (on/off) */
kVstParameterUsesIntegerMinMax = 1 << 1, /* minInteger, maxInteger valid */
kVstParameterUsesFloatStep = 1 << 2, /* stepFloat, smallStepFloat, largeStepFloat valid */
kVstParameterUsesIntStep = 1 << 3, /* stepInteger, largeStepInteger valid */
kVstParameterSupportsDisplayIndex = 1 << 4, /* displayIndex valid */
kVstParameterSupportsDisplayCategory = 1 << 5, /* category, etc. valid */
kVstParameterCanRamp = 1 << 6 /* set if parameter value can ramp up/down */
};
struct _AEffect
{
// Never use virtual functions!!!
// 00-03
int magic;
// dispatcher 04-07
intptr_t (* dispatcher) (struct _AEffect *, int, int, intptr_t, void *, float);
// process, quite sure 08-0b
void (* process) (struct _AEffect *, float **, float **, int);
// setParameter 0c-0f
void (* setParameter) (struct _AEffect *, int, float);
// getParameter 10-13
float (* getParameter) (struct _AEffect *, int);
// programs 14-17
int numPrograms;
// Params 18-1b
int numParams;
// Input 1c-1f
int numInputs;
// Output 20-23
int numOutputs;
// flags 24-27
int flags;
// Fill somewhere 28-2b
void *ptr1;
void *ptr2;
// Zeroes 2c-2f 30-33 34-37 38-3b
char empty3[4 + 4 + 4];
// 1.0f 3c-3f
float unkown_float;
// An object? pointer 40-43
void *ptr3;
// Zeroes 44-47
void *user;
// Id 48-4b
int32_t uniqueID;
// Version 4c-4f
int32_t version;
// processReplacing 50-53
void (* processReplacing) (struct _AEffect *, float **, float **, int);
};
typedef struct _AEffect AEffect;
typedef struct _VstTimeInfo
{
/* info from online documentation of VST provided by Steinberg */
double samplePos;
double sampleRate;
double nanoSeconds;
double ppqPos;
double tempo;
double barStartPos;
double cycleStartPos;
double cycleEndPos;
int32_t timeSigNumerator;
int32_t timeSigDenominator;
int32_t smpteOffset;
int32_t smpteFrameRate;
int32_t samplesToNextClock;
int32_t flags;
} VstTimeInfo;
typedef intptr_t (* audioMasterCallback) (AEffect *, int32_t, int32_t, intptr_t, void *, float);
#endif
+19
View File
@@ -21,3 +21,22 @@ QStringList LibFilter() {
return {"*.so", "*.dylib"};
#endif
}
CFBundleRef BundleLoad(const QString &filename) {
CFStringRef bundle_str = CFStringCreateWithCString(NULL, filename.toUtf8(), kCFStringEncodingUTF8);
CFURLRef bundle_url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, bundle_str, kCFURLPOSIXPathStyle, true);
CFBundleRef bundle = NULL;
if (bundle_url != NULL) {
bundle = CFBundleCreate(kCFAllocatorDefault, bundle_url);
} else {
qCritical() << "Failed to create VST URL";
}
CFRelease(bundle_url);
CFRelease(bundle_str);
return bundle;
}
void BundleClose(CFBundleRef bundle) {
CFBundleUnloadExecutable(bundle);
CFRelease(bundle);
}
+8
View File
@@ -18,4 +18,12 @@
ModulePtr LibLoad(const QString& filename);
QStringList LibFilter();
#ifdef __APPLE__
#include <CoreFoundation/CoreFoundation.h>
class NSWindow;
CFBundleRef BundleLoad(const QString& filename);
void BundleClose(CFBundleRef bundle);
#endif
#endif // CROSSPLATFORMLIB_H
+1 -1
View File
@@ -244,7 +244,7 @@ win32 {
}
mac {
LIBS += -L/usr/local/lib -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample
LIBS += -L/usr/local/lib -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -framework CoreFoundation
ICON = packaging/macos/olive.icns
INCLUDEPATH = /usr/local/include
}
+2 -2
View File
@@ -28,7 +28,7 @@
#include "effects/internal/paneffect.h"
#include "effects/internal/shakeeffect.h"
#include "effects/internal/cornerpineffect.h"
#ifdef _WIN32
#if defined(_WIN32) || defined(__APPLE__)
#include "effects/internal/vsthost.h"
#endif
#include "effects/internal/fillleftrighteffect.h"
@@ -64,7 +64,7 @@ Effect* create_effect(Clip* c, const EffectMeta* em) {
case EFFECT_INTERNAL_SHAKE: return new ShakeEffect(c, em);
case EFFECT_INTERNAL_CORNERPIN: return new CornerPinEffect(c, em);
case EFFECT_INTERNAL_FILLLEFTRIGHT: return new FillLeftRightEffect(c, em);
#ifdef _WIN32
#if (defined(_WIN32) || defined(__APPLE__)) && !defined(NOVST)
case EFFECT_INTERNAL_VST: return new VSTHost(c, em);
#endif
#ifndef NOFREI0R
+1 -1
View File
@@ -34,7 +34,7 @@ void load_internal_effects() {
em.internal = EFFECT_INTERNAL_PAN;
effects.append(em);
#ifdef _WIN32
#if (defined(_WIN32) || defined(__APPLE__)) && !defined(NOVST)
em.name = "VST Plugin 2.x";
em.internal = EFFECT_INTERNAL_VST;
effects.append(em);