diff --git a/CMakeLists.txt b/CMakeLists.txt index ea03d8a..ef4ebed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,8 @@ project(${PROJECT_NAME}) # Project version set(VERSION_MAJOR 1) -set(VERSION_MINOR 0) -set(VERSION_PATCH 2) +set(VERSION_MINOR 1) +set(VERSION_PATCH 0) # Set plugin shared library base name set(PLUGIN_BASENAME ${PROJECT_NAME}-plugin) diff --git a/README b/README index 28a02d4..769eada 100644 --- a/README +++ b/README @@ -33,7 +33,7 @@ Building the source mkdir build && cd build cmake -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX=/opt/airwave -DVSTSDK_PATH=${HOME}/VST3\ SDK .. make - make install + sudo make install Of course, you can change the CMAKE_INSTALL_PREFIX as you like. diff --git a/README.md b/README.md index 8471d08..64b6a30 100644 --- a/README.md +++ b/README.md @@ -2,48 +2,6 @@ Airwave is a [WINE](https://www.winehq.org/)-based VST bridge, that allows for the use of Windows 32- and 64-bit VST 2.4 audio plugins with Linux VST hosts. Due to the use of shared memory, only one extra copying is made for each data transfer. Airwave also uses the XEMBED protocol to correctly embed the plugin editor into the host window. -## Compatibility -The following list is not complete. It contains only plugins, that have been tested by me or by people, who sent me a report. - - VST-Plugins | works? | Notes | -------------:|:----------:|:-------| - Blue Cat Audio Oscilloscope Multi | no | doesn't work with wine - Credland Audio BigKick | no | doesn't work with wine - FabFilter Total bundle | yes | haven't tested them all - Image-Line Harmless | yes | - Image-Line Sytrus | yes | - LennarDigital Sylenth1 | no | doesn't work with wine - LePou Plugins | yes | LeCab2 has slight GUI redrawing issues - NI Absynth | yes | - NI FM8 | yes | - NI Guitar Rig 5 | yes | activation doesn't work - NI Kontakt 5 | mostly | up to v5.3.1, can import libraries only in Windows XP mode - NI Massive | yes | only 32-bit - NI Reaktor 5 | yes | - Peavey Revalver Mark III.V | yes | - ReFX Nexus2 | yes | - ReFX Vanguard | yes | - Reveal Sound Spire | yes | starting form 1.0.19 the GUI doesn't appear (wine issue) - Sonic Academy A.N.A. | yes | - Sonic Academy KICK | yes | - Smartelectronix s(M)exoscope | yes | - Synth1 by Ichiro Toda | yes | - Tone2 FireBird | yes | - Tone2 Nemesis | yes | - Tone2 Saurus | yes | - u-he A.C.E. | yes | Linux version is also available - u-he Bazille | yes | Linux version is also available - u-he Diva | yes | Linux version is also available - u-he Hive | yes | Linux version is also available - u-he Presswerk | yes | Linux version is also available - u-he Satin | yes | Linux version is also available - u-he Uhbik | yes | Linux version is also available - u-he Zebra2 | yes | Linux version is also available - Variety of Sound plugins | yes | - Voxengo SPAN | yes | - Voxengo SPAN Pro | mostly | inter plugin routing doesn't work (architecture issue) - Xfer Serum | partly | the GUI doesn't appear (wine issue), but audio works - ## Requirements - WINE, supporting XEMBED protocol (versions greater than 1.7.19 were tested, but earlier versions also may work) @@ -83,7 +41,7 @@ but earlier versions also may work) mkdir build && cd build cmake -DCMAKE_BUILD_TYPE="Release" -DCMAKE_INSTALL_PREFIX=/opt/airwave -DVSTSDK_PATH=${HOME}/VST3\ SDK .. make - make install + sudo make install ``` Of course, you can change the CMAKE_INSTALL_PREFIX as you like. @@ -102,8 +60,8 @@ Of course, you can change the CMAKE_INSTALL_PREFIX as you like. ## Under the hood The bridge consists of four components: -- Plugin endpoint (airwave-plugin-.so) -- Host endpoint (airwave-host-.exe.so and airwave-host-.exe launcher script) +- Plugin endpoint (airwave-plugin.so) +- Host endpoint (airwave-host-{arch}.exe.so and airwave-host-{arch}.exe launcher script) - Configuration file (${XDG_CONFIG_PATH}/airwave/airwave.conf) - GUI configurator (airwave-manager) @@ -111,3 +69,56 @@ When the airwave-plugin is loaded by the VST host, it obtains its absolute path ## Known issues - Due to a bug in WINE, there is some hacking involved when embedding the editor window. There is a chance that you get a black window instead of the plugin GUI. Also some areas might not update correctly when increasing the window size. On some hosts (Bitwig Studio for example) this can be solved by closing and re-opening the plugin window. + +## Compatibility +The following list is not complete. It contains only plugins, that have been tested by me or by people, who sent me a report. + + VST-Plugins | works? | Notes | +------------:|:----------:|:-------| + AlgoMusic CZythia | yes | + Aly James LAB OB-Xtreme | yes | + Blue Cat Audio Oscilloscope Multi | no | doesn't work with wine + Credland Audio BigKick | no | doesn't work with wine + FabFilter Total bundle | yes | haven't tested them all + Green Oak Software Crystal | yes | + Image-Line Harmless | yes | + Image-Line Sytrus | yes | + LennarDigital Sylenth1 | no | doesn't work with wine + LePou Plugins | yes | LeCab2 has slight GUI redrawing issues + NI Absynth | yes | + NI FM8 | yes | + NI Guitar Rig 5 | yes | activation doesn't work + NI Kontakt 5 | mostly | up to v5.3.1, can import libraries only in Windows XP mode + NI Massive | yes | only 32-bit + NI Reaktor 5 | yes | + Magnus Choir | yes | + Martin Lüders pg8x | yes | + Meesha Damatriks | yes | + Odo Synths Double Six | partly | GUI doesn't show, but presets are available and functional + Peavey Revalver Mark III.V | yes | + ReFX Nexus2 | yes | + ReFX Vanguard | yes | + Reveal Sound Spire | yes | starting form 1.0.19 the GUI doesn't appear (wine issue) + Sonic Academy A.N.A. | yes | + Sonic Academy KICK | yes | + Sonic Cat LFX-1310 | yes | + Sonic Charge Cyclone | yes | + Smartelectronix s(M)exoscope | yes | + SQ8L by Siegfried Kullmann | yes | + SuperWave P8 | yes | + Synth1 by Ichiro Toda | yes | + Tone2 FireBird | yes | + Tone2 Nemesis | yes | + Tone2 Saurus | yes | + u-he A.C.E. | yes | Linux version is also available + u-he Bazille | yes | Linux version is also available + u-he Diva | yes | Linux version is also available + u-he Hive | yes | Linux version is also available + u-he Presswerk | yes | Linux version is also available + u-he Satin | yes | Linux version is also available + u-he Uhbik | yes | Linux version is also available + u-he Zebra2 | yes | Linux version is also available + Variety of Sound plugins | yes | + Voxengo SPAN | yes | + Voxengo SPAN Pro | mostly | inter plugin routing doesn't work (architecture issue) + Xfer Serum | no | the GUI doesn't appear (wine issue), but audio works diff --git a/src/common/dataport.cpp b/src/common/dataport.cpp index 1928e5a..fdb1ef8 100644 --- a/src/common/dataport.cpp +++ b/src/common/dataport.cpp @@ -47,9 +47,7 @@ bool DataPort::create(size_t frameSize) return false; } - ControlBlock* control = controlBlock(); - sem_init(&control->request, 1, 0); - sem_init(&control->response, 1, 0); + new (controlBlock()) ControlBlock; frameSize_ = frameSize; return true; @@ -89,9 +87,9 @@ void DataPort::disconnect() { if(!isNull()) { if(!isConnected()) { - ControlBlock* control = controlBlock(); - sem_destroy(&control->request); - sem_destroy(&control->response); +// ControlBlock* control = controlBlock(); +// sem_destroy(&control->request); +// sem_destroy(&control->response); } shmdt(buffer_); @@ -142,31 +140,27 @@ void* DataPort::frameBuffer() void DataPort::sendRequest() { - if(!isNull()) { - if(sem_post(&controlBlock()->request) != 0) - ERROR("sem_post() call failed: %s", strerror(errno)); - } + if(!isNull()) + controlBlock()->request.post(); } void DataPort::sendResponse() { - if(!isNull()) { - if(sem_post(&controlBlock()->response) != 0) - ERROR("sem_post() call failed: %s", strerror(errno)); - } + if(!isNull()) + controlBlock()->response.post(); } bool DataPort::waitRequest(int msecs) { - return waitForReady(&controlBlock()->request, msecs); + return controlBlock()->request.wait(msecs); } bool DataPort::waitResponse(int msecs) { - return waitForReady(&controlBlock()->response, msecs); + return controlBlock()->response.wait(msecs); } @@ -176,41 +170,4 @@ DataPort::ControlBlock* DataPort::controlBlock() } -bool DataPort::waitForReady(sem_t* semaphore, int msecs) -{ - if(isNull()) - return false; - - if(msecs < 0) { - if(sem_wait(semaphore) != 0) { - ERROR("sem_wait() call failed: %d", errno); - return false; - } - } - else { - int seconds = msecs / 1000; - msecs %= 1000; - - timespec tm; - clock_gettime(CLOCK_REALTIME, &tm); - tm.tv_sec += seconds; - tm.tv_nsec += msecs * 1000000; - - if(tm.tv_nsec >= 1000000000L) { - tm.tv_sec++; - tm.tv_nsec -= 1000000000L; - } - - if(sem_timedwait(semaphore, &tm) != 0) { - if(errno != ETIMEDOUT) - ERROR("sem_timedwait() call failed: %d", errno); - - return false; - } - } - - return true; -} - - } // namespace Airwave diff --git a/src/common/dataport.h b/src/common/dataport.h index 17ffb51..0c3671c 100644 --- a/src/common/dataport.h +++ b/src/common/dataport.h @@ -1,7 +1,7 @@ #ifndef COMMON_DATAPORT_H #define COMMON_DATAPORT_H -#include +#include "common/event.h" #include "common/types.h" @@ -35,16 +35,15 @@ class DataPort { private: struct ControlBlock { - sem_t request; - sem_t response; - } __attribute__((packed)); + Event request; + Event response; + }; int id_; size_t frameSize_; void* buffer_; ControlBlock* controlBlock(); - bool waitForReady(sem_t* semaphore, int msecs = -1); }; diff --git a/src/common/event.cpp b/src/common/event.cpp new file mode 100644 index 0000000..1ae8a8d --- /dev/null +++ b/src/common/event.cpp @@ -0,0 +1,59 @@ +#include "event.h" + +#include +#include +#include +#include +#include + + +#define futex_wait(futex, count, timeout) \ + (syscall(SYS_futex, futex, FUTEX_WAIT, count, timeout, nullptr, 0) == 0) + +#define futex_post(futex, count) \ + (syscall(SYS_futex, futex, FUTEX_WAKE, count, nullptr, nullptr, 0) == 0) + + +Event::Event() : + count_(0) +{ +} + + +Event::~Event() +{ + // FIXME The current implementation is not correct as it wakes only the one waiter. + futex_post(&count_, 1); +} + + +bool Event::wait(int msecs) +{ + timespec* timeout = nullptr; + timespec tm; + + if(msecs >= 0) { + int seconds = msecs / 1000; + msecs %= 1000; + + tm.tv_sec = seconds; + tm.tv_nsec = msecs * 1000000; + + timeout = &tm; + } + + while(count_ == 0) { + if(!futex_wait(&count_, 0, timeout) && errno != EWOULDBLOCK) + return false; + } + + count_--; + return true; +} + + +void Event::post() +{ + count_++; + futex_post(&count_, 1); +} diff --git a/src/common/event.h b/src/common/event.h new file mode 100644 index 0000000..34114f7 --- /dev/null +++ b/src/common/event.h @@ -0,0 +1,26 @@ +#ifndef COMMON_EVENT_H +#define COMMON_EVENT_H + +#include + +#ifdef bool +#undef bool +#endif + + +class Event { +public: + static const int kInfinite = -1; + + Event(); + ~Event(); + + bool wait(int msecs = kInfinite); + void post(); + +private: + std::atomic count_; +}; + + +#endif // COMMON_EVENT_H diff --git a/src/common/eventsignal.cpp b/src/common/eventsignal.cpp deleted file mode 100644 index 10a629a..0000000 --- a/src/common/eventsignal.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include "eventsignal.h" - -#include -#include -#include -#include "common/logger.h" - - -namespace Airwave { - - -EventSignal::EventSignal() -{ - sem_init(&sem_, 1, 0); -} - - -EventSignal::~EventSignal() -{ - sem_destroy(&sem_); -} - - -bool EventSignal::wait(int msecs) -{ - if(msecs < 0) { - if(sem_wait(&sem_) != 0) { - ERROR("sem_wait() call failed: %d", errno); - return false; - } - } - else { - int seconds = msecs / 1000; - msecs %= 1000; - - timespec tm; - clock_gettime(CLOCK_REALTIME, &tm); - tm.tv_sec += seconds; - tm.tv_nsec += msecs * 1000000; - - if(tm.tv_nsec >= 1000000000L) { - tm.tv_sec++; - tm.tv_nsec -= 1000000000L; - } - - if(sem_timedwait(&sem_, &tm) != 0) { - if(errno != ETIMEDOUT) - ERROR("sem_timedwait() call failed: %d", errno); - - return false; - } - } - - return true; -} - - -void EventSignal::post() -{ - if(sem_post(&sem_) != 0) - ERROR("sem_post() call failed: %s", strerror(errno)); -} - - -} // namespace Airwave diff --git a/src/common/eventsignal.h b/src/common/eventsignal.h deleted file mode 100644 index d458e24..0000000 --- a/src/common/eventsignal.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef COMMON_EVENTSIGNAL_H -#define COMMON_EVENTSIGNAL_H - -#include - - -namespace Airwave { - - -class EventSignal { -public: - EventSignal(); - ~EventSignal(); - - bool wait(int msecs = -1); - void post(); - -private: - sem_t sem_; -}; - - -} // namespace Airwave - - -#endif // COMMON_EVENTSIGNAL_H diff --git a/src/manager/core/moduleinfo.cpp b/src/common/moduleinfo.cpp similarity index 57% rename from src/manager/core/moduleinfo.cpp rename to src/common/moduleinfo.cpp index bf187fa..f630978 100644 --- a/src/manager/core/moduleinfo.cpp +++ b/src/common/moduleinfo.cpp @@ -1,4 +1,3 @@ -#include #include "moduleinfo.h" @@ -7,12 +6,10 @@ ModuleInfo::ModuleInfo() : { magic_ = magic_open(MAGIC_NONE); if(!magic_) { - qDebug("Unable to initialize libmagic."); return; } if(magic_load(magic_, nullptr) != 0) { - qDebug("libmagic error: %s", magic_error(magic_)); magic_close(magic_); return; } @@ -34,18 +31,18 @@ ModuleInfo* ModuleInfo::instance() } -ModuleInfo::Arch ModuleInfo::getArch(const QString& fileName) const +ModuleInfo::Arch ModuleInfo::getArch(const std::string& fileName) const { if(isInitialized_) { - const char* buffer = magic_file(magic_, fileName.toUtf8().data()); + const char* buffer = magic_file(magic_, fileName.c_str()); if(buffer) { - QString string = buffer; + std::string string = buffer; - if(string.indexOf("80386") != -1) { + if(string.find("80386") != std::string::npos) { return kArch32; } - else if(string.indexOf("x86-64") != -1) { + else if(string.find("x86-64") != std::string::npos) { return kArch64; } } diff --git a/src/manager/core/moduleinfo.h b/src/common/moduleinfo.h similarity index 68% rename from src/manager/core/moduleinfo.h rename to src/common/moduleinfo.h index 778abb8..47249b1 100644 --- a/src/manager/core/moduleinfo.h +++ b/src/common/moduleinfo.h @@ -1,12 +1,10 @@ -#ifndef CORE_MODULEINFO_H -#define CORE_MODULEINFO_H +#ifndef COMMON_MODULEINFO_H +#define COMMON_MODULEINFO_H +#include #include -class QString; - - class ModuleInfo { public: enum Arch { @@ -22,7 +20,7 @@ class ModuleInfo { ~ModuleInfo(); - Arch getArch(const QString& fileName) const; + Arch getArch(const std::string& fileName) const; private: bool isInitialized_; @@ -32,4 +30,4 @@ class ModuleInfo { }; -#endif // CORE_MODULEINFO_H +#endif // COMMON_MODULEINFO_H diff --git a/src/common/protocol.h b/src/common/protocol.h index 97082db..55505d2 100644 --- a/src/common/protocol.h +++ b/src/common/protocol.h @@ -27,7 +27,7 @@ struct DataFrame { Command command; i32 opcode; i32 index; - intptr value; + i64 value; // The 64-bit value is used here to avoid 64->32 bridging issues float opt; u8 data[]; } __attribute__((packed)); diff --git a/src/common/types.h b/src/common/types.h index 83e369f..49fe755 100644 --- a/src/common/types.h +++ b/src/common/types.h @@ -35,7 +35,6 @@ using i64 = int64_t; using u64 = uint64_t; using f32 = float; using f64 = double; -using intptr = intptr_t; template diff --git a/src/common/vst24.h b/src/common/vst24.h index 93b6650..48ecd91 100644 --- a/src/common/vst24.h +++ b/src/common/vst24.h @@ -9,7 +9,7 @@ namespace Airwave { -//using AudioMasterProc = intptr (VSTCALLBACK*)(AEffect*, i32, i32, intptr, void*, float); +//using AudioMasterProc = intptr_t (VSTCALLBACK*)(AEffect*, i32, i32, intptr_t, void*, float); //using VstPluginMainProc = AEffect* (VSTCALLBACK*)(AudioMasterProc); typedef intptr_t (VSTCALLBACK *AudioMasterProc)(AEffect*, i32, i32, intptr_t, void*, diff --git a/src/host/CMakeLists.txt b/src/host/CMakeLists.txt index 06ad1ac..bc85ced 100644 --- a/src/host/CMakeLists.txt +++ b/src/host/CMakeLists.txt @@ -28,7 +28,7 @@ endif() # Sources set(SOURCES ../common/dataport.cpp - ../common/eventsignal.cpp + ../common/event.cpp ../common/filesystem.cpp ../common/logger.cpp ../common/vsteventkeeper.cpp diff --git a/src/host/host.cpp b/src/host/host.cpp index ef91701..e17aeab 100644 --- a/src/host/host.cpp +++ b/src/host/host.cpp @@ -281,7 +281,7 @@ bool Host::handleDispatch(DataFrame* frame) FLOOD("handleDispatch: %s", kDispatchEvents[frame->opcode]); if(isEditorOpen_ && frame->opcode != effEditIdle) { - // Delay delay the effEditIdle event by 100 milliseconds + // Postpone the effEditIdle event by 100 milliseconds SetTimer(hwnd_, timerId_, 100, nullptr); } @@ -526,9 +526,8 @@ void Host::handleProcessDouble() intptr_t Host::audioMaster(i32 opcode, i32 index, intptr_t value, void* ptr, float opt) { - if(opcode != audioMasterGetTime && opcode != audioMasterIdle) { + if(opcode != audioMasterGetTime && opcode != audioMasterIdle) FLOOD("handleAudioMaster(%s)", kAudioMasterEvents[opcode]); - } DataFrame* frame = callbackPort_.frame(); frame->command = Command::AudioMaster; diff --git a/src/host/host.h b/src/host/host.h index 00e671b..721d4a9 100644 --- a/src/host/host.h +++ b/src/host/host.h @@ -7,7 +7,7 @@ #include #include "common/config.h" #include "common/dataport.h" -#include "common/eventsignal.h" +#include "common/event.h" #include "common/vst24.h" #include "common/vsteventkeeper.h" @@ -44,7 +44,7 @@ class Host { DataPort callbackPort_; DataPort audioPort_; - EventSignal condition_; + Event condition_; HANDLE audioThread_; std::atomic_flag runAudio_; diff --git a/src/manager/CMakeLists.txt b/src/manager/CMakeLists.txt index fed4fb8..5aaf99c 100644 --- a/src/manager/CMakeLists.txt +++ b/src/manager/CMakeLists.txt @@ -19,10 +19,10 @@ set(SOURCES main.cpp ../common/filesystem.cpp ../common/json.cpp + ../common/moduleinfo.cpp ../common/storage.cpp core/application.cpp core/logsocket.cpp - core/moduleinfo.cpp core/singleapplication.cpp forms/filedialog.cpp forms/folderdialog.cpp diff --git a/src/manager/airwave-manager.desktop b/src/manager/airwave-manager.desktop index 5844939..68623c8 100644 --- a/src/manager/airwave-manager.desktop +++ b/src/manager/airwave-manager.desktop @@ -1,6 +1,6 @@ [Desktop Entry] Type=Application -Version=1.0 +Version=1.1.0 Name=Airwave manager Comment=A tool for managing the Airwave VST bridge Exec=airwave-manager diff --git a/src/manager/core/application.cpp b/src/manager/core/application.cpp index 003be65..8c81256 100644 --- a/src/manager/core/application.cpp +++ b/src/manager/core/application.cpp @@ -67,10 +67,9 @@ QStringList Application::checkMissingBinaries(const QString& path) const QStringList fileList; fileList += HOST_BASENAME "-32.exe"; - fileList += PLUGIN_BASENAME "-32.so"; + fileList += PLUGIN_BASENAME ".so"; #ifdef PLATFORM_64BIT fileList += HOST_BASENAME "-64.exe"; - fileList += PLUGIN_BASENAME "-64.so"; #endif QStringList result; diff --git a/src/manager/forms/linkdialog.cpp b/src/manager/forms/linkdialog.cpp index 63378ce..4a40978 100644 --- a/src/manager/forms/linkdialog.cpp +++ b/src/manager/forms/linkdialog.cpp @@ -9,7 +9,6 @@ #include #include "common/config.h" #include "core/application.h" -#include "core/moduleinfo.h" #include "forms/filedialog.h" #include "models/linksmodel.h" #include "models/loadersmodel.h" @@ -237,7 +236,7 @@ void LinkDialog::accept() return; } - QString pluginPath = pluginPathFor(vstInfo.absoluteFilePath()); + QString pluginPath = getPluginPath(); if(pluginPath.isEmpty()) { QMessageBox::critical(this, "Error", "VST plugin is corrupted."); return; @@ -328,20 +327,8 @@ QString LinkDialog::currentPrefix() const } -QString LinkDialog::pluginPathFor(const QString& vstPath) const +QString LinkDialog::getPluginPath() const { QString pluginPath = QString::fromStdString(qApp->storage()->binariesPath()); - pluginPath += "/" PLUGIN_BASENAME; - - ModuleInfo* moduleInfo = ModuleInfo::instance(); - ModuleInfo::Arch arch = moduleInfo->getArch(vstPath); - - if(arch == ModuleInfo::kArch32) { - return pluginPath + "-32.so"; - } - else if(arch == ModuleInfo::kArch64) { - return pluginPath + "-64.so"; - } - - return QString(); + return pluginPath + "/" PLUGIN_BASENAME ".so"; } diff --git a/src/manager/forms/linkdialog.h b/src/manager/forms/linkdialog.h index 14ef5b1..e3d93be 100644 --- a/src/manager/forms/linkdialog.h +++ b/src/manager/forms/linkdialog.h @@ -30,7 +30,7 @@ class LinkDialog : public QDialog { void setupUi(); QString currentPrefix() const; - QString pluginPathFor(const QString& vstPath) const; + QString getPluginPath() const; private slots: void browsePlugin(); diff --git a/src/manager/forms/mainform.cpp b/src/manager/forms/mainform.cpp index 83a4f93..92f9090 100644 --- a/src/manager/forms/mainform.cpp +++ b/src/manager/forms/mainform.cpp @@ -321,31 +321,11 @@ void MainForm::updateLinks() LinkItem* item = qApp->links()->root()->firstChild(); while(item) { - auto prefix = qApp->storage()->prefix(item->prefix().toStdString()); - if(!prefix) - continue; - - QString prefixPath = QString::fromStdString(prefix.path()); - QFileInfo vstInfo(prefixPath + '/' + item->target()); - - ModuleInfo* moduleInfo = ModuleInfo::instance(); - ModuleInfo::Arch arch = moduleInfo->getArch(vstInfo.absoluteFilePath()); - - QString pluginName; - if(arch == ModuleInfo::kArch32) { - pluginName = PLUGIN_BASENAME "-32.so"; - } - else if(arch == ModuleInfo::kArch64) { - pluginName = PLUGIN_BASENAME "-64.so"; - } - else { - continue; - } - QFileInfo linkInfo(item->path()); QDir dir(linkInfo.absoluteDir()); dir.remove(linkInfo.fileName()); + QString pluginName = PLUGIN_BASENAME ".so"; QFile::copy(pluginPath + '/' + pluginName, linkInfo.absoluteFilePath()); item = item->nextSibling(); diff --git a/src/manager/forms/settingsdialog.cpp b/src/manager/forms/settingsdialog.cpp index 13de096..8c733ee 100644 --- a/src/manager/forms/settingsdialog.cpp +++ b/src/manager/forms/settingsdialog.cpp @@ -189,7 +189,7 @@ void SettingsDialog::browseForBinariesPath() QStringList nameFilters; nameFilters << HOST_BASENAME "-32.exe" << HOST_BASENAME "-64.exe"; - nameFilters << PLUGIN_BASENAME "-32.so" << PLUGIN_BASENAME "-64.so"; + nameFilters << PLUGIN_BASENAME ".so"; dialog.setNameFilters(nameFilters); dialog.setWindowTitle("Select directory containing airwave binaries"); diff --git a/src/manager/models/linksmodel.cpp b/src/manager/models/linksmodel.cpp index 31458bf..b709db7 100644 --- a/src/manager/models/linksmodel.cpp +++ b/src/manager/models/linksmodel.cpp @@ -13,7 +13,7 @@ LinkItem::LinkItem(Storage::Link link) : QString prefix = QString::fromStdString(storage->prefix(link_.prefix()).path()); QFileInfo info(QDir(prefix), QString::fromStdString(link_.target())); - arch_ = ModuleInfo::instance()->getArch(info.absoluteFilePath()); + arch_ = ModuleInfo::instance()->getArch(info.absoluteFilePath().toStdString()); } } diff --git a/src/manager/models/linksmodel.h b/src/manager/models/linksmodel.h index 98499a1..76d990d 100644 --- a/src/manager/models/linksmodel.h +++ b/src/manager/models/linksmodel.h @@ -2,8 +2,8 @@ #define MODELS_LINKSMODEL_H #include "common/logger.h" +#include "common/moduleinfo.h" #include "common/storage.h" -#include "core/moduleinfo.h" #include "models/generictreemodel.h" diff --git a/src/plugin/CMakeLists.txt b/src/plugin/CMakeLists.txt index 6ddad2d..068ccd6 100644 --- a/src/plugin/CMakeLists.txt +++ b/src/plugin/CMakeLists.txt @@ -3,6 +3,7 @@ set(TARGET_NAME ${PLUGIN_BASENAME}) project(${TARGET_NAME}) find_package(LibDl REQUIRED) +find_package(LibMagic REQUIRED) find_package(Threads REQUIRED) find_package(X11 REQUIRED) @@ -27,10 +28,11 @@ set(SOURCES main.cpp plugin.cpp ../common/dataport.cpp - ../common/eventsignal.cpp + ../common/event.cpp ../common/filesystem.cpp ../common/json.cpp ../common/logger.cpp + ../common/moduleinfo.cpp ../common/storage.cpp ../common/vsteventkeeper.cpp ) @@ -44,39 +46,15 @@ set(HEADERS # Configure library base name set(CMAKE_SHARED_LIBRARY_PREFIX "") -if(PLATFORM_64BIT) - # Set target - add_library(${TARGET_NAME}-64 SHARED ${SOURCES} ${HEADERS}) - - set_target_properties(${TARGET_NAME}-64 PROPERTIES - COMPILE_FLAGS "-m64" - LINK_FLAGS "-m64" - ) - - # Link with libraries - target_link_libraries(${TARGET_NAME}-64 - ${LIBDL_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT} - ${X11_X11_LIB} - ) - - install(TARGETS ${TARGET_NAME}-64 LIBRARY DESTINATION bin) -endif() - - # Set target -add_library(${TARGET_NAME}-32 SHARED ${SOURCES}) - -set_target_properties(${TARGET_NAME}-32 PROPERTIES - COMPILE_FLAGS "-m32" - LINK_FLAGS "-m32" -) +add_library(${TARGET_NAME} SHARED ${SOURCES}) # Link with libraries -target_link_libraries(${TARGET_NAME}-32 +target_link_libraries(${TARGET_NAME} ${LIBDL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${X11_X11_LIB} + ${LIBMAGIC_LIBRARY} ) -install(TARGETS ${TARGET_NAME}-32 LIBRARY DESTINATION bin) +install(TARGETS ${TARGET_NAME} LIBRARY DESTINATION bin) diff --git a/src/plugin/main.cpp b/src/plugin/main.cpp index e25b4f2..a65804d 100644 --- a/src/plugin/main.cpp +++ b/src/plugin/main.cpp @@ -5,6 +5,7 @@ #include "common/config.h" #include "common/filesystem.h" #include "common/logger.h" +#include "common/moduleinfo.h" #include "common/storage.h" @@ -69,23 +70,6 @@ AEffect* VSTPluginMain(AudioMasterProc audioMasterProc) TRACE("Initializing plugin endpoint %s", VERSION_STRING); TRACE("Plugin binary: %s", selfPath.c_str()); - // Find host binary path - std::string hostName; - if(sizeof(void*) == 8) { - hostName = HOST_BASENAME "-64.exe"; - } - else { - hostName = HOST_BASENAME "-32.exe"; - } - - std::string hostPath = FileSystem::realPath(storage.binariesPath() + '/' + hostName); - if(!FileSystem::isFileExists(hostPath)) { - ERROR("Host binary '%s' doesn't exists", hostPath.c_str()); - return nullptr; - } - - TRACE("Host binary: %s", hostPath.c_str()); - std::string winePrefix = link.prefix(); Storage::Prefix prefix = storage.prefix(winePrefix); if(!prefix) { @@ -124,6 +108,29 @@ AEffect* VSTPluginMain(AudioMasterProc audioMasterProc) TRACE("VST binary: %s", vstPath.c_str()); + // Find host binary path + ModuleInfo::Arch arch = ModuleInfo::instance()->getArch(vstPath); + + std::string hostName; + if(arch == ModuleInfo::kArch64) { + hostName = HOST_BASENAME "-64.exe"; + } + else if(arch == ModuleInfo::kArch32) { + hostName = HOST_BASENAME "-32.exe"; + } + else { + ERROR("Unable to determine VST plugin architecture"); + return nullptr; + } + + std::string hostPath = FileSystem::realPath(storage.binariesPath() + '/' + hostName); + if(!FileSystem::isFileExists(hostPath)) { + ERROR("Host binary '%s' doesn't exists", hostPath.c_str()); + return nullptr; + } + + TRACE("Host binary: %s", hostPath.c_str()); + // We process only two cases, because messages with log levels lower than 'trace' // wouldn't be logged anyway. if(level == LogLevel::kTrace) { diff --git a/src/plugin/plugin.h b/src/plugin/plugin.h index 5ef048f..e7f59d7 100644 --- a/src/plugin/plugin.h +++ b/src/plugin/plugin.h @@ -8,7 +8,7 @@ #include #include #include "common/dataport.h" -#include "common/eventsignal.h" +#include "common/event.h" #include "common/vst24.h" #include "common/vsteventkeeper.h" @@ -47,7 +47,7 @@ class Plugin { DataPort callbackPort_; DataPort audioPort_; - EventSignal condition_; + Event condition_; int childPid_;