| @@ -55,8 +55,6 @@ BUILD_CXX_FLAGS += -DVESTIGE_HEADER | |||||
| # -------------------------------------------------------------- | # -------------------------------------------------------------- | ||||
| ifeq ($(CARLA_PLUGIN_SUPPORT),true) | ifeq ($(CARLA_PLUGIN_SUPPORT),true) | ||||
| BUILD_C_FLAGS += -DWANT_LV2 | |||||
| BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST | |||||
| HAVE_SUIL = $(shell pkg-config --exists suil-0 && echo true) | HAVE_SUIL = $(shell pkg-config --exists suil-0 && echo true) | ||||
| endif | endif | ||||
| @@ -71,3 +69,14 @@ HAVE_PULSEAUDIO = $(shell pkg-config --exists libpulse-simple && echo true) | |||||
| endif | endif | ||||
| HAVE_ZYN_DEPS = $(shell pkg-config --exists fftw3 mxml && echo true) | HAVE_ZYN_DEPS = $(shell pkg-config --exists fftw3 mxml && echo true) | ||||
| # -------------------------------------------------------------- | |||||
| ifeq ($(CARLA_PLUGIN_SUPPORT),true) | |||||
| BUILD_C_FLAGS += -DWANT_LV2 | |||||
| BUILD_CXX_FLAGS += -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST | |||||
| endif | |||||
| ifeq ($(HAVE_ZYN_DEPS),true) | |||||
| BUILD_CXX_FLAGS += -DWANT_ZYNADDSUBFX | |||||
| endif | |||||
| @@ -19,7 +19,7 @@ | |||||
| #define __CARLA_ENGINE_HPP__ | #define __CARLA_ENGINE_HPP__ | ||||
| #include "carla_backend.hpp" | #include "carla_backend.hpp" | ||||
| #include "carla_utils.hpp" | |||||
| #include "carla_juce_utils.hpp" | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| class QProcessEnvironment; | class QProcessEnvironment; | ||||
| @@ -27,6 +27,10 @@ class QProcessEnvironment; | |||||
| CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
| #if 0 | |||||
| } // Fix editor indentation | |||||
| #endif | |||||
| /*! | /*! | ||||
| * @defgroup CarlaBackendEngine Carla Backend Engine | * @defgroup CarlaBackendEngine Carla Backend Engine | ||||
| * | * | ||||
| @@ -45,19 +49,17 @@ enum CarlaEngineType { | |||||
| /*! | /*! | ||||
| * JACK engine type.\n | * JACK engine type.\n | ||||
| * Provides single, multi-client, and rack processing modes. | |||||
| * Provides all processing modes. | |||||
| */ | */ | ||||
| CarlaEngineTypeJack = 1, | CarlaEngineTypeJack = 1, | ||||
| /*! | /*! | ||||
| * RtAudio engine type, used to provide Native Audio and Midi support.\n | |||||
| * Provides rack mode processing only. | |||||
| * RtAudio engine type, used to provide Native Audio and MIDI support. | |||||
| */ | */ | ||||
| CarlaEngineTypeRtAudio = 2, | CarlaEngineTypeRtAudio = 2, | ||||
| /*! | /*! | ||||
| * Plugin engine type, used to export the engine as a plugin (DSSI, LV2 and VST) via the DISTRHO Plugin Toolkit.\n | |||||
| * Works in rack mode only. | |||||
| * Plugin engine type, used to export the engine as a plugin (DSSI, LV2 and VST) via the DISTRHO Plugin Toolkit. | |||||
| */ | */ | ||||
| CarlaEngineTypePlugin = 3 | CarlaEngineTypePlugin = 3 | ||||
| }; | }; | ||||
| @@ -89,39 +91,39 @@ enum CarlaEnginePortType { | |||||
| }; | }; | ||||
| /*! | /*! | ||||
| * The type of a control event. | |||||
| * The type of an engine control event. | |||||
| */ | */ | ||||
| enum CarlaEngineControlEventType { | enum CarlaEngineControlEventType { | ||||
| /*! | /*! | ||||
| * Null event type. | |||||
| * Null control event type. | |||||
| */ | */ | ||||
| CarlaEngineNullEvent = 0, | |||||
| CarlaEngineControlEventTypeNull = 0, | |||||
| /*! | /*! | ||||
| * Parameter change event.\n | * Parameter change event.\n | ||||
| * \note Value uses a range of 0.0<->1.0. | * \note Value uses a range of 0.0<->1.0. | ||||
| */ | */ | ||||
| CarlaEngineParameterChangeEvent = 1, | |||||
| CarlaEngineControlEventTypeParameterChange = 1, | |||||
| /*! | /*! | ||||
| * MIDI Bank change event. | * MIDI Bank change event. | ||||
| */ | */ | ||||
| CarlaEngineMidiBankChangeEvent = 2, | |||||
| CarlaEngineControlEventTypeMidiBankChange = 2, | |||||
| /*! | /*! | ||||
| * MIDI Program change event. | * MIDI Program change event. | ||||
| */ | */ | ||||
| CarlaEngineMidiProgramChangeEvent = 3, | |||||
| CarlaEngineControlEventTypeMidiProgramChange = 3, | |||||
| /*! | /*! | ||||
| * All sound off event. | * All sound off event. | ||||
| */ | */ | ||||
| CarlaEngineAllSoundOffEvent = 4, | |||||
| CarlaEngineControlEventTypeAllSoundOff = 4, | |||||
| /*! | /*! | ||||
| * All notes off event. | * All notes off event. | ||||
| */ | */ | ||||
| CarlaEngineAllNotesOffEvent = 5 | |||||
| CarlaEngineControlEventTypeAllNotesOff = 5 | |||||
| }; | }; | ||||
| /*! | /*! | ||||
| @@ -132,18 +134,16 @@ struct CarlaEngineControlEvent { | |||||
| uint32_t time; //!< frame offset | uint32_t time; //!< frame offset | ||||
| uint8_t channel; //!< channel, used for MIDI-related events and ports | uint8_t channel; //!< channel, used for MIDI-related events and ports | ||||
| uint16_t parameter; //!< parameter, used for parameter changes only | uint16_t parameter; //!< parameter, used for parameter changes only | ||||
| double value; //!< value | |||||
| double value; | |||||
| CarlaEngineControlEvent() | CarlaEngineControlEvent() | ||||
| : type(CarlaEngineNullEvent), | |||||
| time(0), | |||||
| channel(0), | |||||
| parameter(0), | |||||
| value(0.0) {} | |||||
| { | |||||
| clear(); | |||||
| } | |||||
| void clear() | void clear() | ||||
| { | { | ||||
| type = CarlaEngineNullEvent; | |||||
| type = CarlaEngineControlEventTypeNull; | |||||
| time = 0; | time = 0; | ||||
| channel = 0; | channel = 0; | ||||
| parameter = 0; | parameter = 0; | ||||
| @@ -160,9 +160,9 @@ struct CarlaEngineMidiEvent { | |||||
| uint8_t data[3]; | uint8_t data[3]; | ||||
| CarlaEngineMidiEvent() | CarlaEngineMidiEvent() | ||||
| : time(0), | |||||
| size(0), | |||||
| data{0} {} | |||||
| { | |||||
| clear(); | |||||
| } | |||||
| void clear() | void clear() | ||||
| { | { | ||||
| @@ -172,8 +172,6 @@ struct CarlaEngineMidiEvent { | |||||
| } | } | ||||
| }; | }; | ||||
| // LATER - CarlaEngineExtendedMidiEvent | |||||
| /*! | /*! | ||||
| * Engine options. | * Engine options. | ||||
| */ | */ | ||||
| @@ -221,9 +219,9 @@ struct CarlaEngineOptions { | |||||
| forceStereo(false), | forceStereo(false), | ||||
| preferPluginBridges(false), | preferPluginBridges(false), | ||||
| preferUiBridges(true), | preferUiBridges(true), | ||||
| #ifdef WANT_DSSI | |||||
| #ifdef WANT_DSSI | |||||
| useDssiVstChunks(false), | useDssiVstChunks(false), | ||||
| #endif | |||||
| #endif | |||||
| maxParameters(MAX_DEFAULT_PARAMETERS), | maxParameters(MAX_DEFAULT_PARAMETERS), | ||||
| oscUiTimeout(4000), | oscUiTimeout(4000), | ||||
| preferredBufferSize(512), | preferredBufferSize(512), | ||||
| @@ -287,7 +285,7 @@ public: | |||||
| /*! | /*! | ||||
| * The contructor.\n | * The contructor.\n | ||||
| * Param \a isInput defines wherever this is an input port or not (output otherwise).\n | * Param \a isInput defines wherever this is an input port or not (output otherwise).\n | ||||
| * Input/output state and process mode is constant for the lifetime of the port. | |||||
| * Input/output state and process mode are constant for the lifetime of the port. | |||||
| */ | */ | ||||
| CarlaEnginePort(const bool isInput, const ProcessMode processMode); | CarlaEnginePort(const bool isInput, const ProcessMode processMode); | ||||
| @@ -310,6 +308,9 @@ protected: | |||||
| const bool isInput; | const bool isInput; | ||||
| const ProcessMode processMode; | const ProcessMode processMode; | ||||
| void* buffer; | void* buffer; | ||||
| private: | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEnginePort) | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -343,6 +344,9 @@ public: | |||||
| * Initialize the port's internal buffer for \a engine. | * Initialize the port's internal buffer for \a engine. | ||||
| */ | */ | ||||
| virtual void initBuffer(CarlaEngine* const engine); | virtual void initBuffer(CarlaEngine* const engine); | ||||
| private: | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineAudioPort) | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -398,6 +402,8 @@ public: | |||||
| private: | private: | ||||
| const uint32_t m_maxEventCount; | const uint32_t m_maxEventCount; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineControlPort) | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -453,6 +459,8 @@ public: | |||||
| private: | private: | ||||
| const uint32_t m_maxEventCount; | const uint32_t m_maxEventCount; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineMidiPort) | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -525,6 +533,8 @@ protected: | |||||
| private: | private: | ||||
| bool m_active; | bool m_active; | ||||
| uint32_t m_latency; | uint32_t m_latency; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineClient) | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -1007,10 +1017,13 @@ private: | |||||
| static const char* getRtAudioApiName(unsigned int index); | static const char* getRtAudioApiName(unsigned int index); | ||||
| #endif | #endif | ||||
| CarlaEnginePrivateData* const data; | |||||
| ScopedPointer<CarlaEnginePrivateData> const data; | |||||
| friend class CarlaEngineControlPort; | friend class CarlaEngineControlPort; | ||||
| friend class CarlaEngineMidiPort; | friend class CarlaEngineMidiPort; | ||||
| private: | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngine) | |||||
| }; | }; | ||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| @@ -1,6 +1,6 @@ | |||||
| /* | /* | ||||
| * Carla Native Plugin API | * Carla Native Plugin API | ||||
| * 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 | * 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 | * it under the terms of the GNU General Public License as published by | ||||
| @@ -9,24 +9,25 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| */ | */ | ||||
| #ifndef CARLA_NATIVE_H | |||||
| #define CARLA_NATIVE_H | |||||
| #ifndef __CARLA_NATIVE_H__ | |||||
| #define __CARLA_NATIVE_H__ | |||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||
| # include <cstddef> | |||||
| # include <cstdint> | |||||
| extern "C" { | extern "C" { | ||||
| #else | #else | ||||
| # include <stdbool.h> | # include <stdbool.h> | ||||
| # include <stddef.h> | |||||
| # include <stdint.h> | |||||
| #endif | #endif | ||||
| #include <stddef.h> | |||||
| #include <stdint.h> | |||||
| /*! | /*! | ||||
| * @defgroup CarlaNativeAPI Carla Native API | * @defgroup CarlaNativeAPI Carla Native API | ||||
| * | * | ||||
| @@ -38,9 +39,10 @@ extern "C" { | |||||
| typedef void* HostHandle; | typedef void* HostHandle; | ||||
| typedef void* PluginHandle; | typedef void* PluginHandle; | ||||
| const uint32_t PLUGIN_IS_SYNTH = 1 << 0; | |||||
| const uint32_t PLUGIN_HAS_GUI = 1 << 1; | |||||
| const uint32_t PLUGIN_USES_SINGLE_THREAD = 1 << 2; | |||||
| const uint32_t PLUGIN_IS_RTSAFE = 1 << 0; | |||||
| const uint32_t PLUGIN_IS_SYNTH = 1 << 1; | |||||
| const uint32_t PLUGIN_HAS_GUI = 1 << 2; | |||||
| const uint32_t PLUGIN_USES_SINGLE_THREAD = 1 << 3; | |||||
| const uint32_t PARAMETER_IS_OUTPUT = 1 << 0; | const uint32_t PARAMETER_IS_OUTPUT = 1 << 0; | ||||
| const uint32_t PARAMETER_IS_ENABLED = 1 << 1; | const uint32_t PARAMETER_IS_ENABLED = 1 << 1; | ||||
| @@ -106,14 +108,17 @@ typedef struct _MidiProgram { | |||||
| typedef struct _TimeInfoBBT { | typedef struct _TimeInfoBBT { | ||||
| bool valid; | bool valid; | ||||
| int32_t bar; | |||||
| int32_t beat; | |||||
| int32_t tick; | |||||
| double bar_start_tick; | |||||
| float beats_per_bar; | |||||
| float beat_type; | |||||
| double ticks_per_beat; | |||||
| double beats_per_minute; | |||||
| int32_t bar; //!< current bar | |||||
| int32_t beat; //!< current beat-within-bar | |||||
| int32_t tick; //!< current tick-within-beat | |||||
| double barStartTick; | |||||
| float beatsPerBar; //!< time signature "numerator" | |||||
| float beatType; //!< time signature "denominator" | |||||
| double ticksPerBeat; | |||||
| double beatsPerMinute; | |||||
| } TimeInfoBBT; | } TimeInfoBBT; | ||||
| typedef struct _TimeInfo { | typedef struct _TimeInfo { | ||||
| @@ -129,12 +134,13 @@ typedef struct _HostDescriptor { | |||||
| uint32_t (*get_buffer_size)(HostHandle handle); | uint32_t (*get_buffer_size)(HostHandle handle); | ||||
| double (*get_sample_rate)(HostHandle handle); | double (*get_sample_rate)(HostHandle handle); | ||||
| const TimeInfo* (*get_time_info)(HostHandle handle); | const TimeInfo* (*get_time_info)(HostHandle handle); | ||||
| bool (*write_midi_event)(HostHandle handle, MidiEvent* event); | |||||
| bool (*write_midi_event)(HostHandle handle, const MidiEvent* event); | |||||
| void (*ui_parameter_changed)(HostHandle handle, uint32_t index, float value); | void (*ui_parameter_changed)(HostHandle handle, uint32_t index, float value); | ||||
| void (*ui_midi_program_changed)(HostHandle handle, uint32_t bank, uint32_t program); | void (*ui_midi_program_changed)(HostHandle handle, uint32_t bank, uint32_t program); | ||||
| void (*ui_custom_data_changed)(HostHandle handle, const char* key, const char* value); | void (*ui_custom_data_changed)(HostHandle handle, const char* key, const char* value); | ||||
| void (*ui_closed)(HostHandle handle); | void (*ui_closed)(HostHandle handle); | ||||
| } HostDescriptor; | } HostDescriptor; | ||||
| typedef struct _PluginDescriptor { | typedef struct _PluginDescriptor { | ||||
| @@ -152,6 +158,7 @@ typedef struct _PluginDescriptor { | |||||
| const char* const copyright; | const char* const copyright; | ||||
| PluginHandle (*instantiate)(const struct _PluginDescriptor* _this_, HostDescriptor* host); | PluginHandle (*instantiate)(const struct _PluginDescriptor* _this_, HostDescriptor* host); | ||||
| void (*cleanup)(PluginHandle handle); | |||||
| uint32_t (*get_parameter_count)(PluginHandle handle); | uint32_t (*get_parameter_count)(PluginHandle handle); | ||||
| const Parameter* (*get_parameter_info)(PluginHandle handle, uint32_t index); | const Parameter* (*get_parameter_info)(PluginHandle handle, uint32_t index); | ||||
| @@ -174,7 +181,6 @@ typedef struct _PluginDescriptor { | |||||
| void (*activate)(PluginHandle handle); | void (*activate)(PluginHandle handle); | ||||
| void (*deactivate)(PluginHandle handle); | void (*deactivate)(PluginHandle handle); | ||||
| void (*cleanup)(PluginHandle handle); | |||||
| void (*process)(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | void (*process)(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents); | ||||
| } PluginDescriptor; | } PluginDescriptor; | ||||
| @@ -206,4 +212,4 @@ void carla_register_native_plugin_zynaddsubfx(); | |||||
| } // extern "C" | } // extern "C" | ||||
| #endif | #endif | ||||
| #endif // CARLA_NATIVE_H | |||||
| #endif // __CARLA_NATIVE_H__ | |||||
| @@ -135,7 +135,7 @@ uint32_t CarlaEngineControlPort::getEventCount() | |||||
| for (unsigned short i=0; i < m_maxEventCount; i++, count++) | for (unsigned short i=0; i < m_maxEventCount; i++, count++) | ||||
| { | { | ||||
| if (events[i].type == CarlaEngineNullEvent) | |||||
| if (events[i].type == CarlaEngineControlEventTypeNull) | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -179,14 +179,14 @@ void CarlaEngineControlPort::writeEvent(const CarlaEngineControlEventType type, | |||||
| return; | return; | ||||
| CARLA_ASSERT(buffer); | CARLA_ASSERT(buffer); | ||||
| CARLA_ASSERT(type != CarlaEngineNullEvent); | |||||
| CARLA_ASSERT(type != CarlaEngineControlEventTypeNull); | |||||
| CARLA_ASSERT(channel < 16); | CARLA_ASSERT(channel < 16); | ||||
| if (! buffer) | if (! buffer) | ||||
| return; | return; | ||||
| if (type == CarlaEngineNullEvent) | |||||
| if (type == CarlaEngineControlEventTypeNull) | |||||
| return; | return; | ||||
| if (type == CarlaEngineParameterChangeEvent) | |||||
| if (type == CarlaEngineControlEventTypeParameterChange) | |||||
| CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter)); | CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter)); | ||||
| if (channel >= 16) | if (channel >= 16) | ||||
| return; | return; | ||||
| @@ -198,7 +198,7 @@ void CarlaEngineControlPort::writeEvent(const CarlaEngineControlEventType type, | |||||
| for (unsigned short i=0; i < m_maxEventCount; i++) | for (unsigned short i=0; i < m_maxEventCount; i++) | ||||
| { | { | ||||
| if (events[i].type != CarlaEngineNullEvent) | |||||
| if (events[i].type != CarlaEngineControlEventTypeNull) | |||||
| continue; | continue; | ||||
| events[i].type = type; | events[i].type = type; | ||||
| @@ -49,7 +49,8 @@ HEADERS += \ | |||||
| HEADERS += \ | HEADERS += \ | ||||
| ../../utils/carla_utils.hpp \ | ../../utils/carla_utils.hpp \ | ||||
| ../../utils/carla_backend_utils.hpp | |||||
| ../../utils/carla_backend_utils.hpp \ | |||||
| ../../utils/carla_juce_utils.hpp | |||||
| # HEADERS += \ | # HEADERS += \ | ||||
| # plugin/DistrhoPluginInfo.h | # plugin/DistrhoPluginInfo.h | ||||
| @@ -77,18 +77,18 @@ const char* CarlaEngineControlEventType2Str(const CarlaEngineControlEventType ty | |||||
| { | { | ||||
| switch (type) | switch (type) | ||||
| { | { | ||||
| case CarlaEngineNullEvent: | |||||
| case CarlaEngineControlEventTypeNull: | |||||
| return "CarlaEngineNullEvent"; | return "CarlaEngineNullEvent"; | ||||
| case CarlaEngineParameterChangeEvent: | |||||
| return "CarlaEngineParameterChangeEvent"; | |||||
| case CarlaEngineMidiBankChangeEvent: | |||||
| return "CarlaEngineMidiBankChangeEvent"; | |||||
| case CarlaEngineMidiProgramChangeEvent: | |||||
| return "CarlaEngineMidiProgramChangeEvent"; | |||||
| case CarlaEngineAllSoundOffEvent: | |||||
| return "CarlaEngineAllSoundOffEvent"; | |||||
| case CarlaEngineAllNotesOffEvent: | |||||
| return "CarlaEngineAllNotesOffEvent"; | |||||
| case CarlaEngineControlEventTypeParameterChange: | |||||
| return "CarlaEngineControlEventTypeParameterChange"; | |||||
| case CarlaEngineControlEventTypeMidiBankChange: | |||||
| return "CarlaEngineControlEventTypeMidiBankChange"; | |||||
| case CarlaEngineControlEventTypeMidiProgramChange: | |||||
| return "CarlaEngineControlEventTypeMidiProgramChange"; | |||||
| case CarlaEngineControlEventTypeAllSoundOff: | |||||
| return "CarlaEngineControlEventTypeAllSoundOff"; | |||||
| case CarlaEngineControlEventTypeAllNotesOff: | |||||
| return "CarlaEngineControlEventTypeAllNotesOff"; | |||||
| } | } | ||||
| qWarning("CarlaBackend::CarlaEngineControlEventType2Str(%i) - invalid type", type); | qWarning("CarlaBackend::CarlaEngineControlEventType2Str(%i) - invalid type", type); | ||||
| @@ -141,7 +141,7 @@ struct CarlaEnginePrivateData { | |||||
| CarlaEngineOsc osc; | CarlaEngineOsc osc; | ||||
| CarlaEngineThread thread; | CarlaEngineThread thread; | ||||
| const CarlaOscData* oscData; | |||||
| ScopedPointer<const CarlaOscData> oscData; | |||||
| CallbackFunc callback; | CallbackFunc callback; | ||||
| void* callbackPtr; | void* callbackPtr; | ||||
| @@ -19,6 +19,7 @@ | |||||
| #define __CARLA_ENGINE_OSC_HPP__ | #define __CARLA_ENGINE_OSC_HPP__ | ||||
| #include "carla_backend.hpp" | #include "carla_backend.hpp" | ||||
| #include "carla_juce_utils.hpp" | |||||
| #include "carla_osc_utils.hpp" | #include "carla_osc_utils.hpp" | ||||
| #define CARLA_ENGINE_OSC_HANDLE_ARGS1 CarlaPlugin* const plugin | #define CARLA_ENGINE_OSC_HANDLE_ARGS1 CarlaPlugin* const plugin | ||||
| @@ -162,6 +163,8 @@ private: | |||||
| return _this_->handleMessage(path, argc, argv, types, msg); | return _this_->handleMessage(path, argc, argv, types, msg); | ||||
| return 1; | return 1; | ||||
| } | } | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineOsc) | |||||
| }; | }; | ||||
| CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
| @@ -19,7 +19,7 @@ | |||||
| #define __CARLA_ENGINE_THREAD_HPP__ | #define __CARLA_ENGINE_THREAD_HPP__ | ||||
| #include "carla_backend.hpp" | #include "carla_backend.hpp" | ||||
| #include "carla_utils.hpp" | |||||
| #include "carla_juce_utils.hpp" | |||||
| #include <QtCore/QThread> | #include <QtCore/QThread> | ||||
| @@ -72,6 +72,8 @@ private: | |||||
| CarlaMutex* const mutex; | CarlaMutex* const mutex; | ||||
| }; | }; | ||||
| #endif | #endif | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineThread) | |||||
| }; | }; | ||||
| CARLA_BACKEND_END_NAMESPACE | CARLA_BACKEND_END_NAMESPACE | ||||
| @@ -25,6 +25,10 @@ | |||||
| CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
| #if 0 | |||||
| } // Fix editor indentation | |||||
| #endif | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| // Engine port (JackAudio) | // Engine port (JackAudio) | ||||
| @@ -76,6 +80,8 @@ public: | |||||
| private: | private: | ||||
| jack_client_t* const m_client; | jack_client_t* const m_client; | ||||
| jack_port_t* const m_port; | jack_port_t* const m_port; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackAudioPort) | |||||
| }; | }; | ||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -173,22 +179,22 @@ public: | |||||
| { | { | ||||
| const uint8_t midiBank = jackEvent.buffer[2]; | const uint8_t midiBank = jackEvent.buffer[2]; | ||||
| m_retEvent.type = CarlaEngineMidiBankChangeEvent; | |||||
| m_retEvent.type = CarlaEngineControlEventTypeMidiBankChange; | |||||
| m_retEvent.value = midiBank; | m_retEvent.value = midiBank; | ||||
| } | } | ||||
| else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | ||||
| { | { | ||||
| m_retEvent.type = CarlaEngineAllSoundOffEvent; | |||||
| m_retEvent.type = CarlaEngineControlEventTypeAllSoundOff; | |||||
| } | } | ||||
| else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | ||||
| { | { | ||||
| m_retEvent.type = CarlaEngineAllNotesOffEvent; | |||||
| m_retEvent.type = CarlaEngineControlEventTypeAllNotesOff; | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| const uint8_t midiValue = jackEvent.buffer[2]; | const uint8_t midiValue = jackEvent.buffer[2]; | ||||
| m_retEvent.type = CarlaEngineParameterChangeEvent; | |||||
| m_retEvent.type = CarlaEngineControlEventTypeParameterChange; | |||||
| m_retEvent.parameter = midiControl; | m_retEvent.parameter = midiControl; | ||||
| m_retEvent.value = double(midiValue)/127; | m_retEvent.value = double(midiValue)/127; | ||||
| } | } | ||||
| @@ -200,7 +206,7 @@ public: | |||||
| { | { | ||||
| const uint8_t midiProgram = jackEvent.buffer[1]; | const uint8_t midiProgram = jackEvent.buffer[1]; | ||||
| m_retEvent.type = CarlaEngineMidiProgramChangeEvent; | |||||
| m_retEvent.type = CarlaEngineControlEventTypeMidiProgramChange; | |||||
| m_retEvent.value = midiProgram; | m_retEvent.value = midiProgram; | ||||
| return &m_retEvent; | return &m_retEvent; | ||||
| @@ -218,14 +224,14 @@ public: | |||||
| return; | return; | ||||
| CARLA_ASSERT(buffer); | CARLA_ASSERT(buffer); | ||||
| CARLA_ASSERT(type != CarlaEngineNullEvent); | |||||
| CARLA_ASSERT(type != CarlaEngineControlEventTypeNull); | |||||
| CARLA_ASSERT(channel < 16); | CARLA_ASSERT(channel < 16); | ||||
| if (! buffer) | if (! buffer) | ||||
| return; | return; | ||||
| if (type == CarlaEngineNullEvent) | |||||
| if (type == CarlaEngineControlEventTypeNull) | |||||
| return; | return; | ||||
| if (type == CarlaEngineParameterChangeEvent) | |||||
| if (type == CarlaEngineControlEventTypeParameterChange) | |||||
| CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter)); | CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter)); | ||||
| if (channel >= 16) | if (channel >= 16) | ||||
| return; | return; | ||||
| @@ -235,31 +241,31 @@ public: | |||||
| switch (type) | switch (type) | ||||
| { | { | ||||
| case CarlaEngineNullEvent: | |||||
| case CarlaEngineControlEventTypeNull: | |||||
| break; | break; | ||||
| case CarlaEngineParameterChangeEvent: | |||||
| case CarlaEngineControlEventTypeParameterChange: | |||||
| data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | ||||
| data[1] = parameter; | data[1] = parameter; | ||||
| data[2] = value * 127; | data[2] = value * 127; | ||||
| size = 3; | size = 3; | ||||
| break; | break; | ||||
| case CarlaEngineMidiBankChangeEvent: | |||||
| case CarlaEngineControlEventTypeMidiBankChange: | |||||
| data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | ||||
| data[1] = MIDI_CONTROL_BANK_SELECT; | data[1] = MIDI_CONTROL_BANK_SELECT; | ||||
| data[2] = value; | data[2] = value; | ||||
| size = 3; | size = 3; | ||||
| break; | break; | ||||
| case CarlaEngineMidiProgramChangeEvent: | |||||
| case CarlaEngineControlEventTypeMidiProgramChange: | |||||
| data[0] = MIDI_STATUS_PROGRAM_CHANGE + channel; | data[0] = MIDI_STATUS_PROGRAM_CHANGE + channel; | ||||
| data[1] = value; | data[1] = value; | ||||
| size = 2; | size = 2; | ||||
| break; | break; | ||||
| case CarlaEngineAllSoundOffEvent: | |||||
| case CarlaEngineControlEventTypeAllSoundOff: | |||||
| data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | ||||
| data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | ||||
| size = 2; | size = 2; | ||||
| break; | break; | ||||
| case CarlaEngineAllNotesOffEvent: | |||||
| case CarlaEngineControlEventTypeAllNotesOff: | |||||
| data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | ||||
| data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | data[1] = MIDI_CONTROL_ALL_NOTES_OFF; | ||||
| size = 2; | size = 2; | ||||
| @@ -275,6 +281,8 @@ private: | |||||
| jack_port_t* const m_port; | jack_port_t* const m_port; | ||||
| CarlaEngineControlEvent m_retEvent; | CarlaEngineControlEvent m_retEvent; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackControlPort) | |||||
| }; | }; | ||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -385,6 +393,8 @@ private: | |||||
| jack_port_t* const m_port; | jack_port_t* const m_port; | ||||
| CarlaEngineMidiEvent m_retEvent; | CarlaEngineMidiEvent m_retEvent; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackMidiPort) | |||||
| }; | }; | ||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -504,6 +514,8 @@ public: | |||||
| private: | private: | ||||
| jack_client_t* const m_client; | jack_client_t* const m_client; | ||||
| const bool m_usesClient; | const bool m_usesClient; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJackClient) | |||||
| }; | }; | ||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -567,6 +579,7 @@ public: | |||||
| { | { | ||||
| qDebug("CarlaEngineJack::init(\"%s\")", clientName); | qDebug("CarlaEngineJack::init(\"%s\")", clientName); | ||||
| #if 0 | |||||
| m_state = JackTransportStopped; | m_state = JackTransportStopped; | ||||
| m_freewheel = false; | m_freewheel = false; | ||||
| @@ -637,6 +650,8 @@ public: | |||||
| CarlaEngine::init(name); | CarlaEngine::init(name); | ||||
| return true; | return true; | ||||
| #endif | #endif | ||||
| #endif | |||||
| return false; | |||||
| } | } | ||||
| bool close() | bool close() | ||||
| @@ -644,6 +659,7 @@ public: | |||||
| qDebug("CarlaEngineJack::close()"); | qDebug("CarlaEngineJack::close()"); | ||||
| CarlaEngine::close(); | CarlaEngine::close(); | ||||
| #if 0 | |||||
| #ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
| hasQuit = true; | hasQuit = true; | ||||
| m_client = nullptr; | m_client = nullptr; | ||||
| @@ -675,6 +691,7 @@ public: | |||||
| setLastError("Failed to deactivate the JACK client"); | setLastError("Failed to deactivate the JACK client"); | ||||
| m_client = nullptr; | m_client = nullptr; | ||||
| #endif | |||||
| #endif | #endif | ||||
| return false; | return false; | ||||
| } | } | ||||
| @@ -702,6 +719,7 @@ public: | |||||
| { | { | ||||
| jack_client_t* client = nullptr; | jack_client_t* client = nullptr; | ||||
| #if 0 | |||||
| #ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
| client = m_client = jackbridge_client_open(plugin->name(), JackNullOption, nullptr); | client = m_client = jackbridge_client_open(plugin->name(), JackNullOption, nullptr); | ||||
| @@ -726,11 +744,12 @@ public: | |||||
| jackbridge_set_latency_callback(client, carla_jack_latency_callback_plugin, plugin); | jackbridge_set_latency_callback(client, carla_jack_latency_callback_plugin, plugin); | ||||
| } | } | ||||
| #endif | #endif | ||||
| #endif | |||||
| #ifdef BUILD_BRIDGE | #ifdef BUILD_BRIDGE | ||||
| return new CarlaEngineJackClient(client, CarlaEngineTypeJack, PROCESS_MODE_MULTIPLE_CLIENTS); | |||||
| return new CarlaEngineJackClient(CarlaEngineTypeJack, PROCESS_MODE_MULTIPLE_CLIENTS, client); | |||||
| #else | #else | ||||
| return new CarlaEngineJackClient(client, CarlaEngineTypeJack, options.processMode); | |||||
| return new CarlaEngineJackClient(CarlaEngineTypeJack, options.processMode, client); | |||||
| #endif | #endif | ||||
| } | } | ||||
| @@ -1190,6 +1209,8 @@ private: | |||||
| latencyPlugin(plugin, mode); | latencyPlugin(plugin, mode); | ||||
| } | } | ||||
| #endif | #endif | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJack) | |||||
| }; | }; | ||||
| // ----------------------------------------- | // ----------------------------------------- | ||||
| @@ -26,6 +26,10 @@ | |||||
| CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
| #if 0 | |||||
| } // Fix editor indentation | |||||
| #endif | |||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| // RtAudio Engine client | // RtAudio Engine client | ||||
| @@ -60,6 +64,9 @@ public: | |||||
| qCritical("CarlaEngineRtAudioClient::addPort(%i, \"%s\", %s) - invalid type", portType, name, bool2str(isInput)); | qCritical("CarlaEngineRtAudioClient::addPort(%i, \"%s\", %s) - invalid type", portType, name, bool2str(isInput)); | ||||
| return nullptr; | return nullptr; | ||||
| } | } | ||||
| private: | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineRtAudioClient) | |||||
| }; | }; | ||||
| // ------------------------------------------------------------------------------------------------------------------- | // ------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -9,13 +9,14 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| */ | */ | ||||
| #include "carla_backend.hpp" | #include "carla_backend.hpp" | ||||
| #include "carla_juce_utils.hpp" | |||||
| #include "carla_lib_utils.hpp" | #include "carla_lib_utils.hpp" | ||||
| #include "carla_midi.h" | #include "carla_midi.h" | ||||
| @@ -1242,7 +1243,8 @@ void do_linuxsampler_check(const char* const filename, const char* const stype, | |||||
| using namespace LinuxSampler; | using namespace LinuxSampler; | ||||
| class LinuxSamplerScopedEngine { | |||||
| class LinuxSamplerScopedEngine | |||||
| { | |||||
| public: | public: | ||||
| LinuxSamplerScopedEngine(const char* const filename, const char* const stype) | LinuxSamplerScopedEngine(const char* const filename, const char* const stype) | ||||
| { | { | ||||
| @@ -1325,6 +1327,8 @@ void do_linuxsampler_check(const char* const filename, const char* const stype, | |||||
| private: | private: | ||||
| Engine* engine; | Engine* engine; | ||||
| InstrumentManager* ins; | InstrumentManager* ins; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(LinuxSamplerScopedEngine) | |||||
| }; | }; | ||||
| if (init) | if (init) | ||||
| @@ -28,6 +28,7 @@ HEADERS = \ | |||||
| ../includes/lv2_rdf.hpp \ | ../includes/lv2_rdf.hpp \ | ||||
| ../backend/carla_backend.hpp \ | ../backend/carla_backend.hpp \ | ||||
| ../utils/carla_utils.hpp \ | ../utils/carla_utils.hpp \ | ||||
| ../utils/carla_juce_utils.hpp \ | |||||
| ../utils/carla_lib_utils.hpp \ | ../utils/carla_lib_utils.hpp \ | ||||
| ../utils/carla_ladspa_utils.hpp \ | ../utils/carla_ladspa_utils.hpp \ | ||||
| ../utils/carla_lv2_utils.hpp \ | ../utils/carla_lv2_utils.hpp \ | ||||
| @@ -9,7 +9,7 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| @@ -9,7 +9,7 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| @@ -9,7 +9,7 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the GNU General Public License see the COPYING file | * For a full copy of the GNU General Public License see the COPYING file | ||||
| @@ -0,0 +1 @@ | |||||
| ../libs/pugl/ | |||||
| @@ -18,7 +18,7 @@ | |||||
| #ifndef __DISTRHO_UTILS_H__ | #ifndef __DISTRHO_UTILS_H__ | ||||
| #define __DISTRHO_UTILS_H__ | #define __DISTRHO_UTILS_H__ | ||||
| #include "src/DistrhoDefines.h" | |||||
| #include "src/DistrhoMacros.h" | |||||
| #if DISTRHO_OS_WINDOWS | #if DISTRHO_OS_WINDOWS | ||||
| # include <windows.h> | # include <windows.h> | ||||
| @@ -9,48 +9,14 @@ | |||||
| * | * | ||||
| * This program is distributed in the hope that it will be useful, | * This program is distributed in the hope that it will be useful, | ||||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| * GNU General Public License for more details. | * GNU General Public License for more details. | ||||
| * | * | ||||
| * For a full copy of the license see the GPL.txt file | * For a full copy of the license see the GPL.txt file | ||||
| */ | */ | ||||
| #ifndef __DISTRHO_DEFINES_H__ | |||||
| #define __DISTRHO_DEFINES_H__ | |||||
| #include "DistrhoPluginInfo.h" | |||||
| #ifndef DISTRHO_PLUGIN_NAME | |||||
| # error DISTRHO_PLUGIN_NAME undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_HAS_UI | |||||
| # error DISTRHO_PLUGIN_HAS_UI undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_IS_SYNTH | |||||
| # error DISTRHO_PLUGIN_IS_SYNTH undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_NUM_INPUTS | |||||
| # error DISTRHO_PLUGIN_NUM_INPUTS undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_NUM_OUTPUTS | |||||
| # error DISTRHO_PLUGIN_NUM_OUTPUTS undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_WANT_LATENCY | |||||
| # error DISTRHO_PLUGIN_WANT_LATENCY undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_WANT_PROGRAMS | |||||
| # error DISTRHO_PLUGIN_WANT_PROGRAMS undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_WANT_STATE | |||||
| # error DISTRHO_PLUGIN_WANT_STATE undefined! | |||||
| #endif | |||||
| #ifndef __DISTRHO_DEFINES_HPP__ | |||||
| #define __DISTRHO_DEFINES_HPP__ | |||||
| #if defined(__WIN32__) || defined(__WIN64__) | #if defined(__WIN32__) || defined(__WIN64__) | ||||
| # define DISTRHO_PLUGIN_EXPORT extern "C" __declspec (dllexport) | # define DISTRHO_PLUGIN_EXPORT extern "C" __declspec (dllexport) | ||||
| @@ -87,10 +53,4 @@ | |||||
| # define USE_NAMESPACE_DISTRHO | # define USE_NAMESPACE_DISTRHO | ||||
| #endif | #endif | ||||
| #ifndef DISTRHO_UI_QT4 | |||||
| # define DISTRHO_UI_OPENGL | |||||
| #endif | |||||
| #define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI" | |||||
| #endif // __DISTRHO_DEFINES_H__ | |||||
| #endif // __DISTRHO_DEFINES_HPP__ | |||||
| @@ -0,0 +1,62 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Toolkit (DPT) | |||||
| * 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 the Free Software Foundation; either version 2 of | |||||
| * the License, or 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. | |||||
| * | |||||
| * For a full copy of the license see the GPL.txt file | |||||
| */ | |||||
| #ifndef __DISTRHO_MACROS_HPP__ | |||||
| #define __DISTRHO_MACROS_HPP__ | |||||
| #include "DistrhoDefines.h" | |||||
| #include "DistrhoPluginInfo.h" | |||||
| #ifndef DISTRHO_PLUGIN_NAME | |||||
| # error DISTRHO_PLUGIN_NAME undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_HAS_UI | |||||
| # error DISTRHO_PLUGIN_HAS_UI undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_IS_SYNTH | |||||
| # error DISTRHO_PLUGIN_IS_SYNTH undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_NUM_INPUTS | |||||
| # error DISTRHO_PLUGIN_NUM_INPUTS undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_NUM_OUTPUTS | |||||
| # error DISTRHO_PLUGIN_NUM_OUTPUTS undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_WANT_LATENCY | |||||
| # error DISTRHO_PLUGIN_WANT_LATENCY undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_WANT_PROGRAMS | |||||
| # error DISTRHO_PLUGIN_WANT_PROGRAMS undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_PLUGIN_WANT_STATE | |||||
| # error DISTRHO_PLUGIN_WANT_STATE undefined! | |||||
| #endif | |||||
| #ifndef DISTRHO_UI_QT4 | |||||
| # define DISTRHO_UI_OPENGL | |||||
| #endif | |||||
| #define DISTRHO_UI_URI DISTRHO_PLUGIN_URI "#UI" | |||||
| #endif // __DISTRHO_MACROS_HPP__ | |||||
| @@ -213,7 +213,7 @@ public: | |||||
| const ParameterRanges& parameterRanges(uint32_t index) const | const ParameterRanges& parameterRanges(uint32_t index) const | ||||
| { | { | ||||
| assert(data && index < data->parameterCount); | assert(data && index < data->parameterCount); | ||||
| return (data && index < data->parameterCount) ? &data->parameters[index].ranges : fallbackRanges; | |||||
| return (data && index < data->parameterCount) ? data->parameters[index].ranges : fallbackRanges; | |||||
| } | } | ||||
| float parameterValue(uint32_t index) | float parameterValue(uint32_t index) | ||||
| @@ -0,0 +1 @@ | |||||
| ../../pugl/ | |||||
| @@ -0,0 +1,30 @@ | |||||
| /* | |||||
| * DISTRHO Plugin Toolkit (DPT) | |||||
| * 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 the Free Software Foundation; either version 2 of | |||||
| * the License, or 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. | |||||
| * | |||||
| * For a full copy of the license see the GPL.txt file | |||||
| */ | |||||
| #include "DistrhoDefines.h" | |||||
| #if DISTRHO_OS_WINDOWS | |||||
| # include "pugl/pugl_win.cpp" | |||||
| #elif DISTRHO_OS_MAC | |||||
| # include "pugl/pugl_osx.m" | |||||
| #elif DISTRHO_OS_LINUX | |||||
| extern "C" { | |||||
| # include "pugl/pugl_x11.c" | |||||
| } | |||||
| #else | |||||
| # error Unsupported platform! | |||||
| #endif | |||||
| @@ -0,0 +1,358 @@ | |||||
| /* | |||||
| * Carla misc utils imported from Juce source code | |||||
| * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
| * Copyright (C) 2004-11 Raw Material Software Ltd. | |||||
| * | |||||
| * 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 | |||||
| * 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. | |||||
| * | |||||
| * For a full copy of the GNU General Public License see the COPYING file | |||||
| */ | |||||
| #ifndef __CARLA_JUCE_UTILS_HPP__ | |||||
| #define __CARLA_JUCE_UTILS_HPP__ | |||||
| #include "carla_defines.hpp" | |||||
| #include <cassert> | |||||
| #define CARLA_DECLARE_NON_COPYABLE(className) \ | |||||
| className (const className&);\ | |||||
| className& operator= (const className&); | |||||
| /** This is a shorthand way of writing both a CARLA_DECLARE_NON_COPYABLE and | |||||
| CARLA_LEAK_DETECTOR macro for a class. | |||||
| */ | |||||
| #define CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(className) \ | |||||
| CARLA_DECLARE_NON_COPYABLE(className) \ | |||||
| CARLA_LEAK_DETECTOR(className) | |||||
| /** This macro can be added to class definitions to disable the use of new/delete to | |||||
| allocate the object on the heap, forcing it to only be used as a stack or member variable. | |||||
| */ | |||||
| #define CARLA_PREVENT_HEAP_ALLOCATION \ | |||||
| private: \ | |||||
| static void* operator new (size_t); \ | |||||
| static void operator delete (void*); | |||||
| /** A good old-fashioned C macro concatenation helper. | |||||
| This combines two items (which may themselves be macros) into a single string, | |||||
| avoiding the pitfalls of the ## macro operator. | |||||
| */ | |||||
| #define CARLA_JOIN_MACRO_HELPER(a, b) a ## b | |||||
| #define CARLA_JOIN_MACRO(item1, item2) CARLA_JOIN_MACRO_HELPER (item1, item2) | |||||
| //============================================================================== | |||||
| /** | |||||
| Embedding an instance of this class inside another class can be used as a low-overhead | |||||
| way of detecting leaked instances. | |||||
| This class keeps an internal static count of the number of instances that are | |||||
| active, so that when the app is shutdown and the static destructors are called, | |||||
| it can check whether there are any left-over instances that may have been leaked. | |||||
| To use it, use the CARLA_LEAK_DETECTOR macro as a simple way to put one in your | |||||
| class declaration. Have a look through the juce codebase for examples, it's used | |||||
| in most of the classes. | |||||
| */ | |||||
| template <class OwnerClass> | |||||
| class LeakedObjectDetector | |||||
| { | |||||
| public: | |||||
| //============================================================================== | |||||
| LeakedObjectDetector() | |||||
| { | |||||
| ++(getCounter().numObjects); | |||||
| } | |||||
| LeakedObjectDetector(const LeakedObjectDetector&) | |||||
| { | |||||
| ++(getCounter().numObjects); | |||||
| } | |||||
| ~LeakedObjectDetector() | |||||
| { | |||||
| if (--(getCounter().numObjects) < 0) | |||||
| { | |||||
| qWarning("*** Dangling pointer deletion! Class: '%s'", getLeakedObjectClassName()); | |||||
| /** If you hit this, then you've managed to delete more instances of this class than you've | |||||
| created.. That indicates that you're deleting some dangling pointers. | |||||
| Note that although this assertion will have been triggered during a destructor, it might | |||||
| not be this particular deletion that's at fault - the incorrect one may have happened | |||||
| at an earlier point in the program, and simply not been detected until now. | |||||
| Most errors like this are caused by using old-fashioned, non-RAII techniques for | |||||
| your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays, | |||||
| ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs! | |||||
| */ | |||||
| assert(false); | |||||
| } | |||||
| } | |||||
| private: | |||||
| //============================================================================== | |||||
| class LeakCounter | |||||
| { | |||||
| public: | |||||
| LeakCounter() | |||||
| { | |||||
| numObjects = 0; | |||||
| } | |||||
| ~LeakCounter() | |||||
| { | |||||
| if (numObjects > 0) | |||||
| { | |||||
| qWarning("*** Leaked objects detected: %i instance(s) of class '%s'", numObjects, getLeakedObjectClassName()); | |||||
| /** If you hit this, then you've leaked one or more objects of the type specified by | |||||
| the 'OwnerClass' template parameter - the name should have been printed by the line above. | |||||
| If you're leaking, it's probably because you're using old-fashioned, non-RAII techniques for | |||||
| your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays, | |||||
| ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs! | |||||
| */ | |||||
| assert(false); | |||||
| } | |||||
| } | |||||
| int numObjects; | |||||
| }; | |||||
| static const char* getLeakedObjectClassName() | |||||
| { | |||||
| return OwnerClass::getLeakedObjectClassName(); | |||||
| } | |||||
| static LeakCounter& getCounter() | |||||
| { | |||||
| static LeakCounter counter; | |||||
| return counter; | |||||
| } | |||||
| }; | |||||
| #define CARLA_LEAK_DETECTOR(OwnerClass) \ | |||||
| friend class LeakedObjectDetector<OwnerClass>; \ | |||||
| static const char* getLeakedObjectClassName() { return #OwnerClass; } \ | |||||
| LeakedObjectDetector<OwnerClass> CARLA_JOIN_MACRO (leakDetector, __LINE__); | |||||
| //============================================================================== | |||||
| /** | |||||
| This class holds a pointer which is automatically deleted when this object goes | |||||
| out of scope. | |||||
| Once a pointer has been passed to a ScopedPointer, it will make sure that the pointer | |||||
| gets deleted when the ScopedPointer is deleted. Using the ScopedPointer on the stack or | |||||
| as member variables is a good way to use RAII to avoid accidentally leaking dynamically | |||||
| created objects. | |||||
| A ScopedPointer can be used in pretty much the same way that you'd use a normal pointer | |||||
| to an object. If you use the assignment operator to assign a different object to a | |||||
| ScopedPointer, the old one will be automatically deleted. | |||||
| Important note: The class is designed to hold a pointer to an object, NOT to an array! | |||||
| It calls delete on its payload, not delete[], so do not give it an array to hold! For | |||||
| that kind of purpose, you should be using HeapBlock or Array instead. | |||||
| A const ScopedPointer is guaranteed not to lose ownership of its object or change the | |||||
| object to which it points during its lifetime. This means that making a copy of a const | |||||
| ScopedPointer is impossible, as that would involve the new copy taking ownership from the | |||||
| old one. | |||||
| If you need to get a pointer out of a ScopedPointer without it being deleted, you | |||||
| can use the release() method. | |||||
| Something to note is the main difference between this class and the std::auto_ptr class, | |||||
| which is that ScopedPointer provides a cast-to-object operator, wheras std::auto_ptr | |||||
| requires that you always call get() to retrieve the pointer. The advantages of providing | |||||
| the cast is that you don't need to call get(), so can use the ScopedPointer in pretty much | |||||
| exactly the same way as a raw pointer. The disadvantage is that the compiler is free to | |||||
| use the cast in unexpected and sometimes dangerous ways - in particular, it becomes difficult | |||||
| to return a ScopedPointer as the result of a function. To avoid this causing errors, | |||||
| ScopedPointer contains an overloaded constructor that should cause a syntax error in these | |||||
| circumstances, but it does mean that instead of returning a ScopedPointer from a function, | |||||
| you'd need to return a raw pointer (or use a std::auto_ptr instead). | |||||
| */ | |||||
| template <class ObjectType> | |||||
| class ScopedPointer | |||||
| { | |||||
| public: | |||||
| //============================================================================== | |||||
| /** Creates a ScopedPointer containing a null pointer. */ | |||||
| ScopedPointer() | |||||
| : object(nullptr) | |||||
| { | |||||
| } | |||||
| /** Creates a ScopedPointer that owns the specified object. */ | |||||
| ScopedPointer(ObjectType* const objectToTakePossessionOf) | |||||
| : object(objectToTakePossessionOf) | |||||
| { | |||||
| } | |||||
| /** Creates a ScopedPointer that takes its pointer from another ScopedPointer. | |||||
| Because a pointer can only belong to one ScopedPointer, this transfers | |||||
| the pointer from the other object to this one, and the other object is reset to | |||||
| be a null pointer. | |||||
| */ | |||||
| ScopedPointer(ScopedPointer& objectToTransferFrom) | |||||
| : object(objectToTransferFrom.object) | |||||
| { | |||||
| objectToTransferFrom.object = nullptr; | |||||
| } | |||||
| /** Destructor. | |||||
| This will delete the object that this ScopedPointer currently refers to. | |||||
| */ | |||||
| ~ScopedPointer() | |||||
| { | |||||
| delete object; | |||||
| } | |||||
| /** Changes this ScopedPointer to point to a new object. | |||||
| Because a pointer can only belong to one ScopedPointer, this transfers | |||||
| the pointer from the other object to this one, and the other object is reset to | |||||
| be a null pointer. | |||||
| If this ScopedPointer already points to an object, that object | |||||
| will first be deleted. | |||||
| */ | |||||
| ScopedPointer& operator=(ScopedPointer& objectToTransferFrom) | |||||
| { | |||||
| if (this != objectToTransferFrom.getAddress()) | |||||
| { | |||||
| // Two ScopedPointers should never be able to refer to the same object - if | |||||
| // this happens, you must have done something dodgy! | |||||
| assert(object == nullptr || object != objectToTransferFrom.object); | |||||
| ObjectType* const oldObject = object; | |||||
| object = objectToTransferFrom.object; | |||||
| objectToTransferFrom.object = nullptr; | |||||
| delete oldObject; | |||||
| } | |||||
| return *this; | |||||
| } | |||||
| /** Changes this ScopedPointer to point to a new object. | |||||
| If this ScopedPointer already points to an object, that object | |||||
| will first be deleted. | |||||
| The pointer that you pass in may be a nullptr. | |||||
| */ | |||||
| ScopedPointer& operator=(ObjectType* const newObjectToTakePossessionOf) | |||||
| { | |||||
| if (object != newObjectToTakePossessionOf) | |||||
| { | |||||
| ObjectType* const oldObject = object; | |||||
| object = newObjectToTakePossessionOf; | |||||
| delete oldObject; | |||||
| } | |||||
| return *this; | |||||
| } | |||||
| //============================================================================== | |||||
| /** Returns the object that this ScopedPointer refers to. */ | |||||
| operator ObjectType*() const { return object; } | |||||
| /** Returns the object that this ScopedPointer refers to. */ | |||||
| ObjectType* get() const { return object; } | |||||
| /** Returns the object that this ScopedPointer refers to. */ | |||||
| ObjectType& operator*() const { return *object; } | |||||
| /** Lets you access methods and properties of the object that this ScopedPointer refers to. */ | |||||
| ObjectType* operator->() const { return object; } | |||||
| //============================================================================== | |||||
| /** Removes the current object from this ScopedPointer without deleting it. | |||||
| This will return the current object, and set the ScopedPointer to a null pointer. | |||||
| */ | |||||
| ObjectType* release() | |||||
| { | |||||
| ObjectType* const o = object; | |||||
| object = nullptr; | |||||
| return o; | |||||
| } | |||||
| //============================================================================== | |||||
| /** Swaps this object with that of another ScopedPointer. | |||||
| The two objects simply exchange their pointers. | |||||
| */ | |||||
| void swapWith(ScopedPointer<ObjectType>& other) | |||||
| { | |||||
| // Two ScopedPointers should never be able to refer to the same object - if | |||||
| // this happens, you must have done something dodgy! | |||||
| assert(object != other.object || this == other.getAddress()); | |||||
| std::swap(object, other.object); | |||||
| } | |||||
| private: | |||||
| //============================================================================== | |||||
| ObjectType* object; | |||||
| // (Required as an alternative to the overloaded & operator). | |||||
| const ScopedPointer* getAddress() const | |||||
| { | |||||
| return this; | |||||
| } | |||||
| #if ! defined(Q_CC_MSVC) // (MSVC can't deal with multiple copy constructors) | |||||
| /* These are private to stop people accidentally copying a const ScopedPointer (the compiler | |||||
| would let you do so by implicitly casting the source to its raw object pointer). | |||||
| A side effect of this is that you may hit a puzzling compiler error when you write something | |||||
| like this: | |||||
| ScopedPointer<MyClass> m = new MyClass(); // Compile error: copy constructor is private. | |||||
| Even though the compiler would normally ignore the assignment here, it can't do so when the | |||||
| copy constructor is private. It's very easy to fix though - just write it like this: | |||||
| ScopedPointer<MyClass> m (new MyClass()); // Compiles OK | |||||
| It's good practice to always use the latter form when writing your object declarations anyway, | |||||
| rather than writing them as assignments and assuming (or hoping) that the compiler will be | |||||
| smart enough to replace your construction + assignment with a single constructor. | |||||
| */ | |||||
| ScopedPointer(const ScopedPointer&); | |||||
| ScopedPointer& operator=(const ScopedPointer&); | |||||
| #endif | |||||
| }; | |||||
| //============================================================================== | |||||
| /** Compares a ScopedPointer with another pointer. | |||||
| This can be handy for checking whether this is a null pointer. | |||||
| */ | |||||
| template <class ObjectType> | |||||
| bool operator==(const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept | |||||
| { | |||||
| return static_cast<ObjectType*>(pointer1) == pointer2; | |||||
| } | |||||
| /** Compares a ScopedPointer with another pointer. | |||||
| This can be handy for checking whether this is a null pointer. | |||||
| */ | |||||
| template <class ObjectType> | |||||
| bool operator!=(const ScopedPointer<ObjectType>& pointer1, ObjectType* const pointer2) noexcept | |||||
| { | |||||
| return static_cast<ObjectType*>(pointer1) != pointer2; | |||||
| } | |||||
| #endif // __CARLA_JUCE_UTILS_HPP__ | |||||
| @@ -18,7 +18,7 @@ | |||||
| #ifndef __CARLA_LV2_UTILS_HPP__ | #ifndef __CARLA_LV2_UTILS_HPP__ | ||||
| #define __CARLA_LV2_UTILS_HPP__ | #define __CARLA_LV2_UTILS_HPP__ | ||||
| #include "carla_utils.hpp" | |||||
| #include "carla_juce_utils.hpp" | |||||
| #include "lv2/lv2.h" | #include "lv2/lv2.h" | ||||
| #include "lv2/atom.h" | #include "lv2/atom.h" | ||||
| @@ -375,6 +375,8 @@ public: | |||||
| private: | private: | ||||
| bool needInit; | bool needInit; | ||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Lv2WorldClass) | |||||
| }; | }; | ||||
| // ----------------------------------------------------- | // ----------------------------------------------------- | ||||
| @@ -18,7 +18,7 @@ | |||||
| #ifndef __CARLA_UTILS_HPP__ | #ifndef __CARLA_UTILS_HPP__ | ||||
| #define __CARLA_UTILS_HPP__ | #define __CARLA_UTILS_HPP__ | ||||
| #include "carla_defines.hpp" | |||||
| #include "carla_juce_utils.hpp" | |||||
| #include <cstdio> | #include <cstdio> | ||||
| #include <cstdlib> | #include <cstdlib> | ||||
| @@ -164,6 +164,24 @@ void carla_zeroFloat(float* data, const unsigned size) | |||||
| carla_fill<float>(data, size, 0.0f); | carla_fill<float>(data, size, 0.0f); | ||||
| } | } | ||||
| // ------------------------------------------------- | |||||
| // memory functions | |||||
| static inline | |||||
| void carla_zeroMem(void* const memory, const size_t numBytes) | |||||
| { | |||||
| CARLA_ASSERT(memory); | |||||
| memset(memory, 0, numBytes); | |||||
| } | |||||
| template <typename T> | |||||
| static inline | |||||
| void carla_zeroStruct(T& structure) | |||||
| { | |||||
| memset(&structure, 0, sizeof(T)); | |||||
| } | |||||
| // ------------------------------------------------- | // ------------------------------------------------- | ||||
| // other misc functions | // other misc functions | ||||
| @@ -241,6 +259,9 @@ public: | |||||
| private: | private: | ||||
| CarlaMutex* const mutex; | CarlaMutex* const mutex; | ||||
| CARLA_PREVENT_HEAP_ALLOCATION | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ScopedLocker) | |||||
| }; | }; | ||||
| private: | private: | ||||
| @@ -249,11 +270,16 @@ private: | |||||
| #else | #else | ||||
| pthread_mutex_t pmutex; | pthread_mutex_t pmutex; | ||||
| #endif | #endif | ||||
| CARLA_PREVENT_HEAP_ALLOCATION | |||||
| CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaMutex) | |||||
| }; | }; | ||||
| // ------------------------------------------------- | // ------------------------------------------------- | ||||
| // CarlaString class | // CarlaString class | ||||
| // TODO - use "size_t bufferLen" | |||||
| class CarlaString | class CarlaString | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -263,16 +289,35 @@ public: | |||||
| explicit CarlaString() | explicit CarlaString() | ||||
| { | { | ||||
| buffer = ::strdup(""); | buffer = ::strdup(""); | ||||
| bufferLen = 0; | |||||
| } | } | ||||
| explicit CarlaString(char* const strBuf) | explicit CarlaString(char* const strBuf) | ||||
| { | { | ||||
| buffer = ::strdup(strBuf ? strBuf : ""); | |||||
| if (strBuf) | |||||
| { | |||||
| buffer = ::strdup(strBuf); | |||||
| bufferLen = ::strlen(buffer); | |||||
| } | |||||
| else | |||||
| { | |||||
| buffer = ::strdup(""); | |||||
| bufferLen = 0; | |||||
| } | |||||
| } | } | ||||
| explicit CarlaString(const char* const strBuf) | explicit CarlaString(const char* const strBuf) | ||||
| { | { | ||||
| buffer = ::strdup(strBuf ? strBuf : ""); | |||||
| if (strBuf) | |||||
| { | |||||
| buffer = ::strdup(strBuf); | |||||
| bufferLen = ::strlen(buffer); | |||||
| } | |||||
| else | |||||
| { | |||||
| buffer = ::strdup(""); | |||||
| bufferLen = 0; | |||||
| } | |||||
| } | } | ||||
| explicit CarlaString(const int value) | explicit CarlaString(const int value) | ||||
| @@ -282,6 +327,7 @@ public: | |||||
| ::snprintf(strBuf, strBufSize, "%d", value); | ::snprintf(strBuf, strBufSize, "%d", value); | ||||
| buffer = ::strdup(strBuf); | buffer = ::strdup(strBuf); | ||||
| bufferLen = ::strlen(buffer); | |||||
| } | } | ||||
| explicit CarlaString(const unsigned int value, const bool hexadecimal = false) | explicit CarlaString(const unsigned int value, const bool hexadecimal = false) | ||||
| @@ -291,6 +337,7 @@ public: | |||||
| ::snprintf(strBuf, strBufSize, hexadecimal ? "%u" : "0x%x", value); | ::snprintf(strBuf, strBufSize, hexadecimal ? "%u" : "0x%x", value); | ||||
| buffer = ::strdup(strBuf); | buffer = ::strdup(strBuf); | ||||
| bufferLen = ::strlen(buffer); | |||||
| } | } | ||||
| explicit CarlaString(const long int value) | explicit CarlaString(const long int value) | ||||
| @@ -300,6 +347,7 @@ public: | |||||
| ::snprintf(strBuf, strBufSize, "%ld", value); | ::snprintf(strBuf, strBufSize, "%ld", value); | ||||
| buffer = ::strdup(strBuf); | buffer = ::strdup(strBuf); | ||||
| bufferLen = ::strlen(buffer); | |||||
| } | } | ||||
| explicit CarlaString(const unsigned long int value, const bool hexadecimal = false) | explicit CarlaString(const unsigned long int value, const bool hexadecimal = false) | ||||
| @@ -309,6 +357,7 @@ public: | |||||
| ::snprintf(strBuf, strBufSize, hexadecimal ? "%lu" : "0x%lx", value); | ::snprintf(strBuf, strBufSize, hexadecimal ? "%lu" : "0x%lx", value); | ||||
| buffer = ::strdup(strBuf); | buffer = ::strdup(strBuf); | ||||
| bufferLen = ::strlen(buffer); | |||||
| } | } | ||||
| explicit CarlaString(const float value) | explicit CarlaString(const float value) | ||||
| @@ -317,6 +366,7 @@ public: | |||||
| ::snprintf(strBuf, 0xff, "%f", value); | ::snprintf(strBuf, 0xff, "%f", value); | ||||
| buffer = ::strdup(strBuf); | buffer = ::strdup(strBuf); | ||||
| bufferLen = ::strlen(buffer); | |||||
| } | } | ||||
| explicit CarlaString(const double value) | explicit CarlaString(const double value) | ||||
| @@ -325,6 +375,7 @@ public: | |||||
| ::snprintf(strBuf, 0xff, "%g", value); | ::snprintf(strBuf, 0xff, "%g", value); | ||||
| buffer = ::strdup(strBuf); | buffer = ::strdup(strBuf); | ||||
| bufferLen = ::strlen(buffer); | |||||
| } | } | ||||
| // --------------------------------------------- | // --------------------------------------------- | ||||
| @@ -333,6 +384,7 @@ public: | |||||
| CarlaString(const CarlaString& str) | CarlaString(const CarlaString& str) | ||||
| { | { | ||||
| buffer = ::strdup(str.buffer); | buffer = ::strdup(str.buffer); | ||||
| bufferLen = ::strlen(buffer); | |||||
| } | } | ||||
| // --------------------------------------------- | // --------------------------------------------- | ||||
| @@ -349,53 +401,53 @@ public: | |||||
| size_t length() const | size_t length() const | ||||
| { | { | ||||
| return ::strlen(buffer); | |||||
| return bufferLen; | |||||
| } | } | ||||
| bool isEmpty() const | bool isEmpty() const | ||||
| { | { | ||||
| return (*buffer == 0); | |||||
| return (bufferLen == 0); | |||||
| } | } | ||||
| bool isNotEmpty() const | bool isNotEmpty() const | ||||
| { | { | ||||
| return (*buffer != 0); | |||||
| return (bufferLen != 0); | |||||
| } | } | ||||
| #ifdef __USE_GNU | |||||
| bool contains(const char* const strBuf, const bool ignoreCase = false) const | |||||
| #else | |||||
| bool contains(const char* const strBuf) const | bool contains(const char* const strBuf) const | ||||
| #endif | |||||
| { | { | ||||
| if (! strBuf) | if (! strBuf) | ||||
| return false; | return false; | ||||
| if (*strBuf == 0) | |||||
| if (bufferLen == 0) | |||||
| return false; | return false; | ||||
| // FIXME - use strstr | |||||
| size_t thisLen = ::strlen(buffer); | |||||
| size_t thatLen = ::strlen(strBuf)-1; | |||||
| for (size_t i=0, j=0; i < thisLen; i++) | |||||
| { | |||||
| if (buffer[i] == strBuf[j]) | |||||
| j++; | |||||
| else | |||||
| j = 0; | |||||
| if (j == thatLen) | |||||
| return true; | |||||
| } | |||||
| return false; | |||||
| #ifdef __USE_GNU | |||||
| if (ignoreCase) | |||||
| return (::strcasestr(buffer, strBuf) != nullptr); | |||||
| else | |||||
| #endif | |||||
| return (::strstr(buffer, strBuf) != nullptr); | |||||
| } | } | ||||
| #ifdef __USE_GNU | |||||
| bool contains(const CarlaString& str, const bool ignoreCase = false) const | |||||
| { | |||||
| return contains(str.buffer, ignoreCase); | |||||
| } | |||||
| #else | |||||
| bool contains(const CarlaString& str) const | bool contains(const CarlaString& str) const | ||||
| { | { | ||||
| return contains(str.buffer); | return contains(str.buffer); | ||||
| } | } | ||||
| #endif | |||||
| bool isDigit(const size_t pos) const | bool isDigit(const size_t pos) const | ||||
| { | { | ||||
| if (pos >= length()) | |||||
| if (pos >= bufferLen) | |||||
| return false; | return false; | ||||
| return (buffer[pos] >= '0' && buffer[pos] <= '9'); | return (buffer[pos] >= '0' && buffer[pos] <= '9'); | ||||
| @@ -408,22 +460,27 @@ public: | |||||
| void replace(const char before, const char after) | void replace(const char before, const char after) | ||||
| { | { | ||||
| for (size_t i=0, len = ::strlen(buffer); i < len; i++) | |||||
| if (after == 0) | |||||
| return; | |||||
| for (size_t i=0; i < bufferLen; i++) | |||||
| { | { | ||||
| if (buffer[i] == before) | if (buffer[i] == before) | ||||
| buffer[i] = after; | buffer[i] = after; | ||||
| else if (buffer[i] == 0) | |||||
| break; | |||||
| } | } | ||||
| } | } | ||||
| void truncate(const unsigned int n) | |||||
| void truncate(const size_t n) | |||||
| { | { | ||||
| for (size_t i=n, len = ::strlen(buffer); i < len; i++) | |||||
| for (size_t i=n; i < bufferLen; i++) | |||||
| buffer[i] = 0; | buffer[i] = 0; | ||||
| } | } | ||||
| void toBasic() | void toBasic() | ||||
| { | { | ||||
| for (size_t i=0, len = ::strlen(buffer); i < len; i++) | |||||
| for (size_t i=0; i < bufferLen; i++) | |||||
| { | { | ||||
| if (buffer[i] >= '0' && buffer[i] <= '9') | if (buffer[i] >= '0' && buffer[i] <= '9') | ||||
| continue; | continue; | ||||
| @@ -440,7 +497,7 @@ public: | |||||
| void toLower() | void toLower() | ||||
| { | { | ||||
| for (size_t i=0, len = ::strlen(buffer); i < len; i++) | |||||
| for (size_t i=0; i < bufferLen; i++) | |||||
| { | { | ||||
| if (buffer[i] >= 'A' && buffer[i] <= 'Z') | if (buffer[i] >= 'A' && buffer[i] <= 'Z') | ||||
| buffer[i] += 32; | buffer[i] += 32; | ||||
| @@ -449,7 +506,7 @@ public: | |||||
| void toUpper() | void toUpper() | ||||
| { | { | ||||
| for (size_t i=0, len = ::strlen(buffer); i < len; i++) | |||||
| for (size_t i=0; i < bufferLen; i++) | |||||
| { | { | ||||
| if (buffer[i] >= 'a' && buffer[i] <= 'z') | if (buffer[i] >= 'a' && buffer[i] <= 'z') | ||||
| buffer[i] -= 32; | buffer[i] -= 32; | ||||
| @@ -464,7 +521,7 @@ public: | |||||
| return buffer; | return buffer; | ||||
| } | } | ||||
| char& operator[](const unsigned int pos) | |||||
| char& operator[](const size_t pos) | |||||
| { | { | ||||
| return buffer[pos]; | return buffer[pos]; | ||||
| } | } | ||||
| @@ -493,7 +550,16 @@ public: | |||||
| { | { | ||||
| ::free(buffer); | ::free(buffer); | ||||
| buffer = ::strdup(strBuf ? strBuf : ""); | |||||
| if (strBuf) | |||||
| { | |||||
| buffer = ::strdup(strBuf); | |||||
| bufferLen = ::strlen(buffer); | |||||
| } | |||||
| else | |||||
| { | |||||
| buffer = ::strdup(""); | |||||
| bufferLen = 0; | |||||
| } | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| @@ -513,6 +579,7 @@ public: | |||||
| ::free(buffer); | ::free(buffer); | ||||
| buffer = ::strdup(newBuf); | buffer = ::strdup(newBuf); | ||||
| bufferLen = ::strlen(buffer); | |||||
| return *this; | return *this; | ||||
| } | } | ||||
| @@ -541,7 +608,16 @@ public: | |||||
| // --------------------------------------------- | // --------------------------------------------- | ||||
| private: | private: | ||||
| char* buffer; | |||||
| char* buffer; | |||||
| size_t bufferLen; | |||||
| void _recalcLen() | |||||
| { | |||||
| bufferLen = ::strlen(buffer); | |||||
| } | |||||
| CARLA_LEAK_DETECTOR(CarlaString) | |||||
| CARLA_PREVENT_HEAP_ALLOCATION | |||||
| }; | }; | ||||
| static inline | static inline | ||||
| @@ -22,13 +22,11 @@ | |||||
| #include "lv2/atom.h" | #include "lv2/atom.h" | ||||
| #include <cstring> // memcpy, memset | #include <cstring> // memcpy, memset | ||||
| #include <pthread.h> | |||||
| class Lv2AtomQueue | class Lv2AtomQueue | ||||
| { | { | ||||
| public: | public: | ||||
| Lv2AtomQueue() | Lv2AtomQueue() | ||||
| : mutex(PTHREAD_MUTEX_INITIALIZER) | |||||
| { | { | ||||
| index = indexPool = 0; | index = indexPool = 0; | ||||
| empty = true; | empty = true; | ||||
| @@ -77,17 +75,17 @@ public: | |||||
| bool lock() | bool lock() | ||||
| { | { | ||||
| return (pthread_mutex_lock(&mutex) == 0); | |||||
| return mutex.lock(); | |||||
| } | } | ||||
| bool tryLock() | bool tryLock() | ||||
| { | { | ||||
| return (pthread_mutex_trylock(&mutex) == 0); | |||||
| return mutex.tryLock(); | |||||
| } | } | ||||
| bool unlock() | bool unlock() | ||||
| { | { | ||||
| return (pthread_mutex_unlock(&mutex) == 0); | |||||
| return mutex.unlock(); | |||||
| } | } | ||||
| void put(const uint32_t portIndex, const LV2_Atom* const atom) | void put(const uint32_t portIndex, const LV2_Atom* const atom) | ||||
| @@ -186,7 +184,7 @@ private: | |||||
| unsigned short index, indexPool; | unsigned short index, indexPool; | ||||
| bool empty, full; | bool empty, full; | ||||
| pthread_mutex_t mutex; | |||||
| CarlaMutex mutex; | |||||
| }; | }; | ||||
| #endif // __LV2_ATOM_QUEUE_HPP__ | #endif // __LV2_ATOM_QUEUE_HPP__ | ||||
| @@ -24,6 +24,7 @@ extern "C" { | |||||
| } | } | ||||
| #include <cassert> | #include <cassert> | ||||
| #include <cstring> | |||||
| typedef struct list_head k_list_head; | typedef struct list_head k_list_head; | ||||
| @@ -34,9 +35,9 @@ public: | |||||
| RtList(const size_t minPreallocated, const size_t maxPreallocated) | RtList(const size_t minPreallocated, const size_t maxPreallocated) | ||||
| { | { | ||||
| qcount = 0; | qcount = 0; | ||||
| INIT_LIST_HEAD(&queue); | |||||
| ::INIT_LIST_HEAD(&queue); | |||||
| rtsafe_memory_pool_create(&mempool, nullptr, sizeof(RtListData), minPreallocated, maxPreallocated); | |||||
| ::rtsafe_memory_pool_create(&mempool, nullptr, sizeof(RtListData), minPreallocated, maxPreallocated); | |||||
| assert(mempool); | assert(mempool); | ||||
| } | } | ||||
| @@ -45,15 +46,15 @@ public: | |||||
| { | { | ||||
| clear(); | clear(); | ||||
| rtsafe_memory_pool_destroy(mempool); | |||||
| ::rtsafe_memory_pool_destroy(mempool); | |||||
| } | } | ||||
| void resize(const size_t minPreallocated, const size_t maxPreallocated) | void resize(const size_t minPreallocated, const size_t maxPreallocated) | ||||
| { | { | ||||
| clear(); | clear(); | ||||
| rtsafe_memory_pool_destroy(mempool); | |||||
| rtsafe_memory_pool_create(&mempool, nullptr, sizeof(RtListData), minPreallocated, maxPreallocated); | |||||
| ::rtsafe_memory_pool_destroy(mempool); | |||||
| ::rtsafe_memory_pool_create(&mempool, nullptr, sizeof(RtListData), minPreallocated, maxPreallocated); | |||||
| assert(mempool); | assert(mempool); | ||||
| } | } | ||||
| @@ -68,12 +69,12 @@ public: | |||||
| list_for_each(entry, &queue) | list_for_each(entry, &queue) | ||||
| { | { | ||||
| data = list_entry(entry, RtListData, siblings); | data = list_entry(entry, RtListData, siblings); | ||||
| rtsafe_memory_pool_deallocate(mempool, data); | |||||
| ::rtsafe_memory_pool_deallocate(mempool, data); | |||||
| } | } | ||||
| } | } | ||||
| qcount = 0; | qcount = 0; | ||||
| INIT_LIST_HEAD(&queue); | |||||
| ::INIT_LIST_HEAD(&queue); | |||||
| } | } | ||||
| size_t count() const | size_t count() const | ||||
| @@ -92,14 +93,14 @@ public: | |||||
| RtListData* data; | RtListData* data; | ||||
| if (sleepy) | if (sleepy) | ||||
| data = (RtListData*)rtsafe_memory_pool_allocate_sleepy(mempool); | |||||
| data = (RtListData*)::rtsafe_memory_pool_allocate_sleepy(mempool); | |||||
| else | else | ||||
| data = (RtListData*)rtsafe_memory_pool_allocate_atomic(mempool); | |||||
| data = (RtListData*)::rtsafe_memory_pool_allocate_atomic(mempool); | |||||
| if (data) | if (data) | ||||
| { | { | ||||
| memcpy(&data->value, &value, sizeof(T)); | |||||
| list_add_tail(&data->siblings, &queue); | |||||
| ::memcpy(&data->value, &value, sizeof(T)); | |||||
| ::list_add_tail(&data->siblings, &queue); | |||||
| qcount++; | qcount++; | ||||
| } | } | ||||
| @@ -137,8 +138,8 @@ public: | |||||
| if (data->value == value) | if (data->value == value) | ||||
| { | { | ||||
| qcount--; | qcount--; | ||||
| list_del(entry); | |||||
| rtsafe_memory_pool_deallocate(mempool, data); | |||||
| ::list_del(entry); | |||||
| ::rtsafe_memory_pool_deallocate(mempool, data); | |||||
| return true; | return true; | ||||
| } | } | ||||
| } | } | ||||
| @@ -159,8 +160,8 @@ public: | |||||
| if (data->value == value) | if (data->value == value) | ||||
| { | { | ||||
| qcount--; | qcount--; | ||||
| list_del(entry); | |||||
| rtsafe_memory_pool_deallocate(mempool, data); | |||||
| ::list_del(entry); | |||||
| ::rtsafe_memory_pool_deallocate(mempool, data); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -186,7 +187,7 @@ private: | |||||
| if (reset) | if (reset) | ||||
| { | { | ||||
| reset = false; | reset = false; | ||||
| memset(&value, 0, sizeof(T)); | |||||
| ::memset(&value, 0, sizeof(T)); | |||||
| } | } | ||||
| return value; | return value; | ||||
| @@ -200,8 +201,8 @@ private: | |||||
| if (data && doDelete) | if (data && doDelete) | ||||
| { | { | ||||
| qcount--; | qcount--; | ||||
| list_del(entry); | |||||
| rtsafe_memory_pool_deallocate(mempool, data); | |||||
| ::list_del(entry); | |||||
| ::rtsafe_memory_pool_deallocate(mempool, data); | |||||
| } | } | ||||
| return ret; | return ret; | ||||
| @@ -210,6 +211,10 @@ private: | |||||
| // Non-copyable | // Non-copyable | ||||
| RtList(const RtList&); | RtList(const RtList&); | ||||
| RtList& operator= (const RtList&); | RtList& operator= (const RtList&); | ||||
| // Prevent heap allocation | |||||
| static void* operator new (size_t); | |||||
| static void operator delete (void*); | |||||
| }; | }; | ||||
| #endif // __RT_LIST_HPP__ | #endif // __RT_LIST_HPP__ | ||||