moved vst to cross platform defs (still untested on other platforms

This commit is contained in:
itsmattkc
2019-01-21 12:34:36 +11:00
parent 22791f16ba
commit e2ceda74db
4 changed files with 330 additions and 326 deletions
@@ -1,9 +1,7 @@
#include "vsthostwin.h" #include "vsthost.h"
// adapted from http://teragonaudio.com/article/How-to-make-your-own-VST-host.html // adapted from http://teragonaudio.com/article/How-to-make-your-own-VST-host.html
#include <Windows.h>
#include <QPushButton> #include <QPushButton>
#include <QDialog> #include <QDialog>
#include <QMessageBox> #include <QMessageBox>
@@ -52,20 +50,22 @@ typedef VstInt32 (*processEventsFuncPtr)(VstEvents *events);
// Plugin's process() method // Plugin's process() method
typedef void (*processFuncPtr)(AEffect *effect, float **inputs, float **outputs, VstInt32 sampleFrames); typedef void (*processFuncPtr)(AEffect *effect, float **inputs, float **outputs, VstInt32 sampleFrames);
void VSTHostWin::loadPlugin() { void VSTHost::loadPlugin() {
QString dll_fn = file_field->get_filename(0, true); QString dll_fn = file_field->get_filename(0, true);
LPCWSTR dll_fn_w = reinterpret_cast<const wchar_t*>(dll_fn.utf16());
modulePtr = LoadLibrary(dll_fn_w); modulePtr = LibLoad(dll_fn);
if(modulePtr == nullptr) { if(modulePtr == nullptr) {
DWORD dll_err = GetLastError(); DWORD dll_err = GetLastError();
qCritical() << "Failed to load VST" << dll_fn_w << "-" << dll_err; qCritical() << "Failed to load VST" << dll_fn << "-" << dll_err;
#ifdef _WIN32
QString msg_err = tr("Failed to load VST plugin \"%1\": %2").arg(dll_fn, QString::number(dll_err)); QString msg_err = tr("Failed to load VST plugin \"%1\": %2").arg(dll_fn, QString::number(dll_err));
if (dll_err == 193) { if (dll_err == 193) {
#ifdef _WIN64 #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 #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 #endif
} }
QMessageBox::critical(mainWindow, tr("Error loading VST plugin"), msg_err); QMessageBox::critical(mainWindow, tr("Error loading VST plugin"), msg_err);
@@ -73,20 +73,20 @@ void VSTHostWin::loadPlugin() {
} }
vstPluginFuncPtr mainEntryPoint = vstPluginFuncPtr mainEntryPoint =
reinterpret_cast<vstPluginFuncPtr>(GetProcAddress(modulePtr, "VSTPluginMain")); reinterpret_cast<vstPluginFuncPtr>(LibAddress(modulePtr, "VSTPluginMain"));
// Instantiate the plugin // Instantiate the plugin
plugin = mainEntryPoint(hostCallback); plugin = mainEntryPoint(hostCallback);
} }
void VSTHostWin::freePlugin() { void VSTHost::freePlugin() {
if (plugin != nullptr) { if (plugin != nullptr) {
stopPlugin(); stopPlugin();
FreeLibrary(modulePtr); LibClose(modulePtr);
plugin = nullptr; plugin = nullptr;
} }
} }
bool VSTHostWin::configurePluginCallbacks() { bool VSTHost::configurePluginCallbacks() {
// Check plugin's magic number // Check plugin's magic number
// If incorrect, then the file either was not loaded properly, is not a // If incorrect, then the file either was not loaded properly, is not a
// real VST plugin, or is otherwise corrupt. // real VST plugin, or is otherwise corrupt.
@@ -107,7 +107,7 @@ bool VSTHostWin::configurePluginCallbacks() {
return true; return true;
} }
void VSTHostWin::startPlugin() { void VSTHost::startPlugin() {
dispatcher(plugin, effOpen, 0, 0, nullptr, 0.0f); dispatcher(plugin, effOpen, 0, 0, nullptr, 0.0f);
// Set some default properties // Set some default properties
@@ -117,25 +117,25 @@ void VSTHostWin::startPlugin() {
resumePlugin(); resumePlugin();
} }
void VSTHostWin::stopPlugin() { void VSTHost::stopPlugin() {
suspendPlugin(); suspendPlugin();
dispatcher(plugin, effClose, 0, 0, nullptr, 0); dispatcher(plugin, effClose, 0, 0, nullptr, 0);
} }
void VSTHostWin::resumePlugin() { void VSTHost::resumePlugin() {
dispatcher(plugin, effMainsChanged, 0, 1, nullptr, 0.0f); dispatcher(plugin, effMainsChanged, 0, 1, nullptr, 0.0f);
} }
void VSTHostWin::suspendPlugin() { void VSTHost::suspendPlugin() {
dispatcher(plugin, effMainsChanged, 0, 0, nullptr, 0.0f); dispatcher(plugin, effMainsChanged, 0, 0, nullptr, 0.0f);
} }
bool VSTHostWin::canPluginDo(char *canDoString) { bool VSTHost::canPluginDo(char *canDoString) {
return (dispatcher(plugin, effCanDo, 0, 0, static_cast<void*>(canDoString), 0.0f) > 0); return (dispatcher(plugin, effCanDo, 0, 0, static_cast<void*>(canDoString), 0.0f) > 0);
} }
void VSTHostWin::initializeIO() { void VSTHost::initializeIO() {
// inputs and outputs are assumed to be float** and are declared elsewhere, // inputs and outputs are assumed to be float** and are declared elsewhere,
// most likely the are fields owned by this class. numChannels and blocksize // most likely the are fields owned by this class. numChannels and blocksize
// are also fields, both should be size_t (or unsigned int, if you prefer). // are also fields, both should be size_t (or unsigned int, if you prefer).
@@ -147,7 +147,7 @@ void VSTHostWin::initializeIO() {
} }
} }
void VSTHostWin::processAudio(long numFrames) { void VSTHost::processAudio(long numFrames) {
// Always reset the output array before processing. // Always reset the output array before processing.
for (int i=0;i<CHANNEL_COUNT;i++) { for (int i=0;i<CHANNEL_COUNT;i++) {
memset(outputs[i], 0, BLOCK_SIZE*sizeof(float)); memset(outputs[i], 0, BLOCK_SIZE*sizeof(float));
@@ -156,7 +156,7 @@ void VSTHostWin::processAudio(long numFrames) {
plugin->processReplacing(plugin, inputs, outputs, numFrames); plugin->processReplacing(plugin, inputs, outputs, numFrames);
} }
VSTHostWin::VSTHostWin(Clip* c, const EffectMeta *em) : Effect(c, em) { VSTHost::VSTHost(Clip* c, const EffectMeta *em) : Effect(c, em) {
plugin = nullptr; plugin = nullptr;
initializeIO(); initializeIO();
@@ -178,11 +178,11 @@ VSTHostWin::VSTHostWin(Clip* c, const EffectMeta *em) : Effect(c, em) {
connect(dialog, SIGNAL(finished(int)), this, SLOT(uncheck_show_button())); connect(dialog, SIGNAL(finished(int)), this, SLOT(uncheck_show_button()));
} }
VSTHostWin::~VSTHostWin() { VSTHost::~VSTHost() {
freePlugin(); freePlugin();
} }
void VSTHostWin::process_audio(double, double, quint8* samples, int nb_bytes, int) { void VSTHost::process_audio(double, double, quint8* samples, int nb_bytes, int) {
if (plugin != nullptr) { if (plugin != nullptr) {
int interval = BLOCK_SIZE*4; int interval = BLOCK_SIZE*4;
for (int i=0;i<nb_bytes;i+=interval) { for (int i=0;i<nb_bytes;i+=interval) {
@@ -218,7 +218,7 @@ void VSTHostWin::process_audio(double, double, quint8* samples, int nb_bytes, in
} }
} }
void VSTHostWin::custom_load(QXmlStreamReader &stream) { void VSTHost::custom_load(QXmlStreamReader &stream) {
if (stream.name() == "plugindata") { if (stream.name() == "plugindata") {
stream.readNext(); stream.readNext();
QByteArray b = QByteArray::fromBase64(stream.text().toUtf8()); QByteArray b = QByteArray::fromBase64(stream.text().toUtf8());
@@ -228,7 +228,7 @@ void VSTHostWin::custom_load(QXmlStreamReader &stream) {
} }
} }
void VSTHostWin::save(QXmlStreamWriter &stream) { void VSTHost::save(QXmlStreamWriter &stream) {
Effect::save(stream); Effect::save(stream);
if (plugin != nullptr) { if (plugin != nullptr) {
char* p = nullptr; char* p = nullptr;
@@ -238,15 +238,15 @@ void VSTHostWin::save(QXmlStreamWriter &stream) {
} }
} }
void VSTHostWin::show_interface(bool show) { void VSTHost::show_interface(bool show) {
dialog->setVisible(show); dialog->setVisible(show);
} }
void VSTHostWin::uncheck_show_button() { void VSTHost::uncheck_show_button() {
show_interface_btn->setChecked(false); show_interface_btn->setChecked(false);
} }
void VSTHostWin::change_plugin() { void VSTHost::change_plugin() {
freePlugin(); freePlugin();
loadPlugin(); loadPlugin();
if (plugin != nullptr) { if (plugin != nullptr) {
@@ -258,7 +258,7 @@ void VSTHostWin::change_plugin() {
dialog->setFixedWidth(eRect->right); dialog->setFixedWidth(eRect->right);
dialog->setFixedHeight(eRect->bottom); dialog->setFixedHeight(eRect->bottom);
} else { } else {
FreeLibrary(modulePtr); LibClose(modulePtr);
plugin = nullptr; plugin = nullptr;
} }
} }
@@ -3,6 +3,8 @@
#include "project/effect.h" #include "project/effect.h"
#include "io/crossplatformlib.h"
#include <vst/aeffectx.h> #include <vst/aeffectx.h>
// Plugin's dispatcher function // Plugin's dispatcher function
@@ -11,11 +13,11 @@ typedef VstIntPtr (*dispatcherFuncPtr)(AEffect *effect, VstInt32 opCode, VstInt3
struct AEffect; struct AEffect;
class QDialog; class QDialog;
class VSTHostWin : public Effect { class VSTHost : public Effect {
Q_OBJECT Q_OBJECT
public: public:
VSTHostWin(Clip* c, const EffectMeta* em); VSTHost(Clip* c, const EffectMeta* em);
~VSTHostWin(); ~VSTHost();
void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count); void process_audio(double timecode_start, double timecode_end, quint8* samples, int nb_bytes, int channel_count);
void custom_load(QXmlStreamReader& stream); void custom_load(QXmlStreamReader& stream);
@@ -43,7 +45,7 @@ private:
float** outputs; float** outputs;
QDialog* dialog; QDialog* dialog;
QPushButton* show_interface_btn; QPushButton* show_interface_btn;
HMODULE modulePtr; ModulePtr modulePtr;
}; };
#endif // VSTHOSTWIN_H #endif // VSTHOSTWIN_H
+6 -4
View File
@@ -131,7 +131,8 @@ SOURCES += \
project/projectfilter.cpp \ project/projectfilter.cpp \
effects/internal/frei0reffect.cpp \ effects/internal/frei0reffect.cpp \
project/effectloaders.cpp \ project/effectloaders.cpp \
io/crossplatformlib.cpp io/crossplatformlib.cpp \
effects/internal/vsthost.cpp
HEADERS += \ HEADERS += \
mainwindow.h \ mainwindow.h \
@@ -230,7 +231,8 @@ HEADERS += \
project/projectfilter.h \ project/projectfilter.h \
effects/internal/frei0reffect.h \ effects/internal/frei0reffect.h \
project/effectloaders.h \ project/effectloaders.h \
io/crossplatformlib.h io/crossplatformlib.h \
effects/internal/vsthost.h
FORMS += FORMS +=
@@ -238,8 +240,8 @@ win32 {
RC_FILE = packaging/windows/resources.rc RC_FILE = packaging/windows/resources.rc
LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lopengl32 -luser32 LIBS += -lavutil -lavformat -lavcodec -lavfilter -lswscale -lswresample -lopengl32 -luser32
SOURCES += effects/internal/vsthostwin.cpp SOURCES +=
HEADERS += effects/internal/vsthostwin.h HEADERS +=
} }
mac { mac {
+2 -2
View File
@@ -29,7 +29,7 @@
#include "effects/internal/shakeeffect.h" #include "effects/internal/shakeeffect.h"
#include "effects/internal/cornerpineffect.h" #include "effects/internal/cornerpineffect.h"
#ifdef _WIN32 #ifdef _WIN32
#include "effects/internal/vsthostwin.h" #include "effects/internal/vsthost.h"
#endif #endif
#include "effects/internal/fillleftrighteffect.h" #include "effects/internal/fillleftrighteffect.h"
#include "effects/internal/frei0reffect.h" #include "effects/internal/frei0reffect.h"
@@ -65,7 +65,7 @@ Effect* create_effect(Clip* c, const EffectMeta* em) {
case EFFECT_INTERNAL_CORNERPIN: return new CornerPinEffect(c, em); case EFFECT_INTERNAL_CORNERPIN: return new CornerPinEffect(c, em);
case EFFECT_INTERNAL_FILLLEFTRIGHT: return new FillLeftRightEffect(c, em); case EFFECT_INTERNAL_FILLLEFTRIGHT: return new FillLeftRightEffect(c, em);
#ifdef _WIN32 #ifdef _WIN32
case EFFECT_INTERNAL_VST: return new VSTHostWin(c, em); case EFFECT_INTERNAL_VST: return new VSTHost(c, em);
#endif #endif
#ifndef NOFREI0R #ifndef NOFREI0R
case EFFECT_INTERNAL_FREI0R: return new Frei0rEffect(c, em); case EFFECT_INTERNAL_FREI0R: return new Frei0rEffect(c, em);