| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Engine | |||
| * Copyright (C) 2012 Filipe Coelho <falktx@falktx.com> | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * 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 | |||
| @@ -15,13 +15,14 @@ | |||
| * For a full copy of the GNU General Public License see the COPYING file | |||
| */ | |||
| #ifndef CARLA_ENGINE_HPP | |||
| #define CARLA_ENGINE_HPP | |||
| #ifndef __CARLA_ENGINE_HPP__ | |||
| #define __CARLA_ENGINE_HPP__ | |||
| #include "carla_engine_osc.hpp" | |||
| #include "carla_engine_thread.hpp" | |||
| //#include "carla_engine_osc.hpp" | |||
| //#include "carla_engine_thread.hpp" | |||
| #include <QtCore/QProcessEnvironment> | |||
| //#include <QtCore/QProcessEnvironment> | |||
| class QProcessEnvironment; | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| @@ -500,6 +501,8 @@ private: | |||
| // ----------------------------------------------------------------------- | |||
| class CarlaEnginePrivateData; | |||
| /*! | |||
| * Carla Engine. | |||
| * \note This is a virtual class for all available engine types available in Carla. | |||
| @@ -645,10 +648,10 @@ public: | |||
| // bridge, internal use only | |||
| // TODO - find a better way for this | |||
| void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin) | |||
| { | |||
| m_carlaPlugins[id] = plugin; | |||
| } | |||
| void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin); | |||
| //{ | |||
| // m_carlaPlugins[id] = plugin; | |||
| //} | |||
| // ------------------------------------------------------------------- | |||
| // Information (base) | |||
| @@ -656,22 +659,34 @@ public: | |||
| /*! | |||
| * Get engine name. | |||
| */ | |||
| const char* getName() const; | |||
| const char* getName() const | |||
| { | |||
| return (const char*)name; | |||
| } | |||
| /*! | |||
| * Get current sample rate. | |||
| */ | |||
| double getSampleRate() const; | |||
| double getSampleRate() const | |||
| { | |||
| return sampleRate; | |||
| } | |||
| /*! | |||
| * Get current buffer size. | |||
| */ | |||
| uint32_t getBufferSize() const; | |||
| uint32_t getBufferSize() const | |||
| { | |||
| return bufferSize; | |||
| } | |||
| /*! | |||
| * Get current Time information. | |||
| * Get current Time information (read-only). | |||
| */ | |||
| const CarlaEngineTimeInfo* getTimeInfo() const; | |||
| const CarlaEngineTimeInfo& getTimeInfo() const | |||
| { | |||
| return timeInfo; | |||
| } | |||
| /*! | |||
| * Tell the engine it's about to close.\n | |||
| @@ -721,10 +736,10 @@ public: | |||
| /*! | |||
| * Get the engine options as process environment. | |||
| */ | |||
| const QProcessEnvironment& getOptionsAsProcessEnvironment() const | |||
| { | |||
| return m_procEnv; | |||
| } | |||
| const QProcessEnvironment& getOptionsAsProcessEnvironment() const; | |||
| //{ | |||
| // return m_procEnv; | |||
| //} | |||
| /*! | |||
| * Set the engine option \a option. | |||
| @@ -885,19 +900,19 @@ public: | |||
| * \param engine The engine to lock | |||
| * \param lock Wherever to lock the engine or not, true by default | |||
| */ | |||
| ScopedLocker(CarlaEngine* const engine, bool lock = true) | |||
| : mutex(&engine->m_procLock), | |||
| m_lock(lock) | |||
| { | |||
| if (m_lock) | |||
| mutex->lock(); | |||
| } | |||
| ScopedLocker(CarlaEngine* const engine, bool lock = true); | |||
| // : mutex(&engine->m_procLock), | |||
| // m_lock(lock) | |||
| //{ | |||
| // if (m_lock) | |||
| // mutex->lock(); | |||
| //} | |||
| ~ScopedLocker() | |||
| { | |||
| if (m_lock) | |||
| mutex->unlock(); | |||
| } | |||
| //{ | |||
| // if (m_lock) | |||
| // mutex->unlock(); | |||
| //} | |||
| private: | |||
| QMutex* const mutex; | |||
| @@ -929,6 +944,30 @@ protected: | |||
| void bufferSizeChanged(const uint32_t newBufferSize); | |||
| private: | |||
| #ifdef CARLA_ENGINE_JACK | |||
| static CarlaEngine* newJack(); | |||
| #endif | |||
| #ifdef CARLA_ENGINE_RTAUDIO | |||
| enum RtAudioApi { | |||
| RTAUDIO_DUMMY = 0, | |||
| RTAUDIO_LINUX_ALSA = 1, | |||
| RTAUDIO_LINUX_PULSE = 2, | |||
| RTAUDIO_LINUX_OSS = 3, | |||
| RTAUDIO_UNIX_JACK = 4, | |||
| RTAUDIO_MACOSX_CORE = 5, | |||
| RTAUDIO_WINDOWS_ASIO = 6, | |||
| RTAUDIO_WINDOWS_DS = 7 | |||
| }; | |||
| static CarlaEngine* newRtAudio(RtAudioApi api); | |||
| static unsigned int getRtAudioApiCount(); | |||
| static const char* getRtAudioApiName(unsigned int index); | |||
| #endif | |||
| CarlaEnginePrivateData* const data; | |||
| friend class CarlaEngineInternal; | |||
| #if 0 | |||
| private: | |||
| CarlaEngineOsc m_osc; | |||
| CarlaEngineThread m_thread; | |||
| @@ -954,25 +993,6 @@ private: | |||
| bool m_aboutToClose; | |||
| unsigned short m_maxPluginNumber; | |||
| #ifdef CARLA_ENGINE_JACK | |||
| static CarlaEngine* newJack(); | |||
| #endif | |||
| #ifdef CARLA_ENGINE_RTAUDIO | |||
| enum RtAudioApi { | |||
| RTAUDIO_DUMMY = 0, | |||
| RTAUDIO_LINUX_ALSA = 1, | |||
| RTAUDIO_LINUX_PULSE = 2, | |||
| RTAUDIO_LINUX_OSS = 3, | |||
| RTAUDIO_UNIX_JACK = 4, | |||
| RTAUDIO_MACOSX_CORE = 5, | |||
| RTAUDIO_WINDOWS_ASIO = 6, | |||
| RTAUDIO_WINDOWS_DS = 7 | |||
| }; | |||
| static CarlaEngine* newRtAudio(RtAudioApi api); | |||
| static unsigned int getRtAudioApiCount(); | |||
| static const char* getRtAudioApiName(unsigned int index); | |||
| #endif | |||
| }; | |||
| @@ -982,4 +1002,4 @@ private: | |||
| CARLA_BACKEND_END_NAMESPACE | |||
| #endif // CARLA_ENGINE_HPP | |||
| #endif // __CARLA_ENGINE_HPP__ | |||
| @@ -18,28 +18,28 @@ | |||
| #ifndef CARLA_PLUGIN_HPP | |||
| #define CARLA_PLUGIN_HPP | |||
| #include "carla_midi.h" | |||
| #include "carla_engine.hpp" | |||
| #include "carla_osc_utils.hpp" | |||
| #include "carla_plugin_thread.hpp" | |||
| //#include "carla_midi.h" | |||
| //#include "carla_engine.hpp" | |||
| //#include "carla_osc_utils.hpp" | |||
| //#include "carla_plugin_thread.hpp" | |||
| #ifdef BUILD_BRIDGE | |||
| # include "carla_bridge_osc.hpp" | |||
| #endif | |||
| //#ifdef BUILD_BRIDGE | |||
| //# include "carla_bridge_osc.hpp" | |||
| //#endif | |||
| // common includes | |||
| #include <cmath> | |||
| #include <vector> | |||
| #include <QtCore/QMutex> | |||
| #include <QtGui/QMainWindow> | |||
| #ifdef Q_WS_X11 | |||
| # include <QtGui/QX11EmbedContainer> | |||
| typedef QX11EmbedContainer GuiContainer; | |||
| #else | |||
| # include <QtGui/QWidget> | |||
| typedef QWidget GuiContainer; | |||
| #endif | |||
| //#include <cmath> | |||
| //#include <vector> | |||
| //#include <QtCore/QMutex> | |||
| //#include <QtGui/QMainWindow> | |||
| //#ifdef Q_WS_X11 | |||
| //# include <QtGui/QX11EmbedContainer> | |||
| //typedef QX11EmbedContainer GuiContainer; | |||
| //#else | |||
| //# include <QtGui/QWidget> | |||
| //typedef QWidget GuiContainer; | |||
| //#endif | |||
| typedef struct _PluginDescriptor PluginDescriptor; | |||
| @@ -176,6 +176,8 @@ struct ExternalMidiNote { | |||
| velo(0) {} | |||
| }; | |||
| class CarlaPluginPrivateData; | |||
| /*! | |||
| * \class CarlaPlugin | |||
| * | |||
| @@ -905,6 +907,10 @@ public: | |||
| // ------------------------------------------------------------------- | |||
| protected: | |||
| CarlaPluginPrivateData* const data; | |||
| friend class CarlaPluginInternal; | |||
| #if 0 | |||
| unsigned short m_id; | |||
| CarlaEngine* const x_engine; | |||
| CarlaEngineClient* x_client; | |||
| @@ -980,8 +986,10 @@ protected: | |||
| friend class CarlaEngine; // FIXME | |||
| friend class CarlaEngineJack; | |||
| #endif | |||
| }; | |||
| #if 0 | |||
| /*! | |||
| * \class CarlaPluginGUI | |||
| * | |||
| @@ -1065,6 +1073,7 @@ private: | |||
| void hideEvent(QHideEvent* const event); | |||
| void closeEvent(QCloseEvent* const event); | |||
| }; | |||
| #endif | |||
| /**@}*/ | |||
| @@ -678,10 +678,10 @@ void do_lv2_check(const char* const bundle, const bool init) | |||
| // Get & check every plugin-instance | |||
| for (int i=0; i < URIs.count(); i++) | |||
| { | |||
| const LV2_RDF_Descriptor* const rdf_descriptor = lv2_rdf_new(URIs.at(i).toUtf8().constData()); | |||
| CARLA_ASSERT(rdf_descriptor && rdf_descriptor->URI); | |||
| const LV2_RDF_Descriptor* const rdfDescriptor = lv2_rdf_new(URIs.at(i).toUtf8().constData()); | |||
| CARLA_ASSERT(rdfDescriptor && rdfDescriptor->URI); | |||
| if (! (rdf_descriptor && rdf_descriptor->URI)) | |||
| if (! (rdfDescriptor && rdfDescriptor->URI)) | |||
| { | |||
| DISCOVERY_OUT("error", "Failed to find LV2 plugin '" << URIs.at(i).toUtf8().constData() << "'"); | |||
| continue; | |||
| @@ -690,51 +690,78 @@ void do_lv2_check(const char* const bundle, const bool init) | |||
| if (init) | |||
| { | |||
| // test if DLL is loadable | |||
| void* const libHandle = lib_open(rdf_descriptor->Binary); | |||
| if (! libHandle) | |||
| { | |||
| print_lib_error(rdf_descriptor->Binary); | |||
| delete rdf_descriptor; | |||
| continue; | |||
| } | |||
| void* const libHandle = lib_open(rdfDescriptor->Binary); | |||
| if (! libHandle) | |||
| { | |||
| print_lib_error(rdfDescriptor->Binary); | |||
| delete rdfDescriptor; | |||
| continue; | |||
| } | |||
| lib_close(libHandle); | |||
| lib_close(libHandle); | |||
| } | |||
| // test if we support all required ports and features | |||
| bool supported = true; | |||
| for (uint32_t j=0; j < rdf_descriptor->PortCount; j++) | |||
| { | |||
| #if 0 | |||
| const LV2_RDF_Port* const port = &rdf_descriptor->Ports[j]; | |||
| bool validPort = (LV2_IS_PORT_CONTROL(port->Type) || LV2_IS_PORT_AUDIO(port->Type) || LV2_IS_PORT_ATOM_SEQUENCE(port->Type) /*|| LV2_IS_PORT_CV(port->Type)*/ || LV2_IS_PORT_EVENT(port->Type) || LV2_IS_PORT_LL(port->Type)); | |||
| bool supported = true; | |||
| if (! (validPort || LV2_IS_PORT_OPTIONAL(port->Properties))) | |||
| for (uint32_t j=0; j < rdfDescriptor->PortCount; j++) | |||
| { | |||
| DISCOVERY_OUT("error", "plugin requires a non-supported port type, port-name: " << port->Name); | |||
| supported = false; | |||
| break; | |||
| } | |||
| #endif | |||
| } | |||
| const LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j]; | |||
| for (uint32_t j=0; j < rdf_descriptor->FeatureCount && supported; j++) | |||
| { | |||
| const LV2_RDF_Feature* const feature = &rdf_descriptor->Features[j]; | |||
| if (LV2_IS_PORT_CONTROL(rdfPort->Types)) | |||
| { | |||
| pass(); | |||
| } | |||
| else if (LV2_IS_PORT_AUDIO(rdfPort->Types)) | |||
| { | |||
| pass(); | |||
| } | |||
| else if (LV2_IS_PORT_ATOM_SEQUENCE(rdfPort->Types)) | |||
| { | |||
| pass(); | |||
| } | |||
| //else if (LV2_IS_PORT_CV(rdfPort->Types)) | |||
| // pass(); | |||
| else if (LV2_IS_PORT_EVENT(rdfPort->Types)) | |||
| { | |||
| pass(); | |||
| } | |||
| else if (LV2_IS_PORT_MIDI_LL(rdfPort->Types)) | |||
| { | |||
| pass(); | |||
| } | |||
| else if (! LV2_IS_PORT_OPTIONAL(rdfPort->Properties)) | |||
| { | |||
| DISCOVERY_OUT("error", "plugin requires a non-supported port type, port-name: " << rdfPort->Name); | |||
| supported = false; | |||
| break; | |||
| } | |||
| } | |||
| if (LV2_IS_FEATURE_REQUIRED(feature->Type) && ! is_lv2_feature_supported(feature->URI)) | |||
| for (uint32_t j=0; j < rdfDescriptor->FeatureCount && supported; j++) | |||
| { | |||
| DISCOVERY_OUT("error", "plugin requires a non-supported feature " << feature->URI); | |||
| supported = false; | |||
| break; | |||
| const LV2_RDF_Feature* const rdfFeature = &rdfDescriptor->Features[j]; | |||
| if (is_lv2_feature_supported(rdfFeature->URI)) | |||
| { | |||
| pass(); | |||
| } | |||
| else if (LV2_IS_FEATURE_REQUIRED(rdfFeature->Type)) | |||
| { | |||
| DISCOVERY_OUT("error", "plugin requires a non-supported feature " << rdfFeature->URI); | |||
| supported = false; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| if (! supported) | |||
| { | |||
| delete rdf_descriptor; | |||
| continue; | |||
| if (! supported) | |||
| { | |||
| delete rdfDescriptor; | |||
| continue; | |||
| } | |||
| } | |||
| } | |||
| @@ -748,62 +775,72 @@ void do_lv2_check(const char* const bundle, const bool init) | |||
| int parametersIns = 0; | |||
| int parametersOuts = 0; | |||
| int parametersTotal = 0; | |||
| int programsTotal = rdfDescriptor->PresetCount; | |||
| #if 0 | |||
| for (uint32_t j=0; j < rdf_descriptor->PortCount; j++) | |||
| for (uint32_t j=0; j < rdfDescriptor->PortCount; j++) | |||
| { | |||
| const LV2_RDF_Port* const port = &rdf_descriptor->Ports[j]; | |||
| const LV2_RDF_Port* const rdfPort = &rdfDescriptor->Ports[j]; | |||
| if (LV2_IS_PORT_AUDIO(port->Type)) | |||
| if (LV2_IS_PORT_AUDIO(rdfPort->Types)) | |||
| { | |||
| if (LV2_IS_PORT_INPUT(port->Type)) | |||
| if (LV2_IS_PORT_INPUT(rdfPort->Types)) | |||
| audioIns += 1; | |||
| else if (LV2_IS_PORT_OUTPUT(port->Type)) | |||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | |||
| audioOuts += 1; | |||
| audioTotal += 1; | |||
| } | |||
| else if (LV2_IS_PORT_CONTROL(port->Type)) | |||
| else if (LV2_IS_PORT_CONTROL(rdfPort->Types)) | |||
| { | |||
| if (LV2_IS_PORT_DESIGNATION_LATENCY(port->Designation) || LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(port->Designation) || | |||
| LV2_IS_PORT_DESIGNATION_FREEWHEELING(port->Designation) || LV2_IS_PORT_DESIGNATION_TIME(port->Designation)) | |||
| if (LV2_IS_PORT_DESIGNATION_LATENCY(rdfPort->Designation)) | |||
| { | |||
| pass(); | |||
| } | |||
| else if (LV2_IS_PORT_DESIGNATION_SAMPLE_RATE(rdfPort->Designation)) | |||
| { | |||
| pass(); | |||
| } | |||
| else if (LV2_IS_PORT_DESIGNATION_FREEWHEELING(rdfPort->Designation)) | |||
| { | |||
| pass(); | |||
| } | |||
| else if (LV2_IS_PORT_DESIGNATION_TIME(rdfPort->Designation)) | |||
| { | |||
| pass(); | |||
| } | |||
| else | |||
| { | |||
| if (LV2_IS_PORT_INPUT(port->Type)) | |||
| if (LV2_IS_PORT_INPUT(rdfPort->Types)) | |||
| parametersIns += 1; | |||
| else if (LV2_IS_PORT_OUTPUT(port->Type)) | |||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | |||
| parametersOuts += 1; | |||
| parametersTotal += 1; | |||
| } | |||
| } | |||
| else if (port->Type & LV2_PORT_SUPPORTS_MIDI_EVENT) | |||
| else if (LV2_PORT_SUPPORTS_MIDI_EVENT(rdfPort->Types)) | |||
| { | |||
| if (LV2_IS_PORT_INPUT(port->Type)) | |||
| if (LV2_IS_PORT_INPUT(rdfPort->Types)) | |||
| midiIns += 1; | |||
| else if (LV2_IS_PORT_OUTPUT(port->Type)) | |||
| else if (LV2_IS_PORT_OUTPUT(rdfPort->Types)) | |||
| midiOuts += 1; | |||
| midiTotal += 1; | |||
| } | |||
| } | |||
| if (rdf_descriptor->Type & LV2_CLASS_INSTRUMENT) | |||
| if (rdfDescriptor->Type[1] & LV2_PLUGIN_INSTRUMENT) | |||
| hints |= PLUGIN_IS_SYNTH; | |||
| #endif | |||
| if (rdf_descriptor->UICount > 0) | |||
| if (rdfDescriptor->UICount > 0) | |||
| hints |= PLUGIN_HAS_GUI; | |||
| DISCOVERY_OUT("init", "-----------"); | |||
| DISCOVERY_OUT("label", rdf_descriptor->URI); | |||
| if (rdf_descriptor->Name) | |||
| DISCOVERY_OUT("name", rdf_descriptor->Name); | |||
| if (rdf_descriptor->Author) | |||
| DISCOVERY_OUT("maker", rdf_descriptor->Author); | |||
| if (rdf_descriptor->License) | |||
| DISCOVERY_OUT("copyright", rdf_descriptor->License); | |||
| DISCOVERY_OUT("unique_id", rdf_descriptor->UniqueID); | |||
| DISCOVERY_OUT("label", rdfDescriptor->URI); | |||
| if (rdfDescriptor->Name) | |||
| DISCOVERY_OUT("name", rdfDescriptor->Name); | |||
| if (rdfDescriptor->Author) | |||
| DISCOVERY_OUT("maker", rdfDescriptor->Author); | |||
| if (rdfDescriptor->License) | |||
| DISCOVERY_OUT("copyright", rdfDescriptor->License); | |||
| DISCOVERY_OUT("unique_id", rdfDescriptor->UniqueID); | |||
| DISCOVERY_OUT("hints", hints); | |||
| DISCOVERY_OUT("audio.ins", audioIns); | |||
| DISCOVERY_OUT("audio.outs", audioOuts); | |||
| @@ -814,10 +851,11 @@ void do_lv2_check(const char* const bundle, const bool init) | |||
| DISCOVERY_OUT("parameters.ins", parametersIns); | |||
| DISCOVERY_OUT("parameters.outs", parametersOuts); | |||
| DISCOVERY_OUT("parameters.total", parametersTotal); | |||
| DISCOVERY_OUT("programs.total", programsTotal); | |||
| DISCOVERY_OUT("build", BINARY_NATIVE); | |||
| DISCOVERY_OUT("end", "------------"); | |||
| delete rdf_descriptor; | |||
| delete rdfDescriptor; | |||
| } | |||
| #else | |||
| DISCOVERY_OUT("error", "LV2 support not available"); | |||
| @@ -142,8 +142,8 @@ struct LV2_Type { | |||
| #define LV2_IS_PORT_EVENT(x) ((x) & LV2_PORT_EVENT) | |||
| #define LV2_IS_PORT_MIDI_LL(x) ((x) & LV2_PORT_MIDI_LL) | |||
| #define LV2_PORT_SUPPORTS_MIDI_EVENT ((x) & LV2_PORT_DATA_MIDI_EVENT) | |||
| #define LV2_PORT_SUPPORTS_PATCH_MESSAGE ((x) & LV2_PORT_DATA_PATCH_MESSAGE) | |||
| #define LV2_PORT_SUPPORTS_MIDI_EVENT(x) ((x) & LV2_PORT_DATA_MIDI_EVENT) | |||
| #define LV2_PORT_SUPPORTS_PATCH_MESSAGE(x) ((x) & LV2_PORT_DATA_PATCH_MESSAGE) | |||
| // Port Properties | |||
| #define LV2_PORT_OPTIONAL 0x0001 | |||
| @@ -50,7 +50,7 @@ void carla_assert_int(const char* const assertion, const char* const file, const | |||
| // carla_*sleep (carla_usleep not possible in Windows) | |||
| static inline | |||
| void carla_sleep(const int secs) | |||
| void carla_sleep(const unsigned int secs) | |||
| { | |||
| CARLA_ASSERT(secs > 0); | |||
| @@ -62,7 +62,7 @@ void carla_sleep(const int secs) | |||
| } | |||
| static inline | |||
| void carla_msleep(const int msecs) | |||
| void carla_msleep(const unsigned int msecs) | |||
| { | |||
| CARLA_ASSERT(msecs > 0); | |||
| @@ -74,7 +74,7 @@ void carla_msleep(const int msecs) | |||
| } | |||
| static inline | |||
| void carla_usleep(const int usecs) | |||
| void carla_usleep(const unsigned int usecs) | |||
| { | |||
| CARLA_ASSERT(usecs > 0); | |||