@@ -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__ |