@@ -26,7 +26,7 @@ | |||||
#define CARLA_BACKEND_END_NAMESPACE } | #define CARLA_BACKEND_END_NAMESPACE } | ||||
#define CARLA_BACKEND_USE_NAMESPACE using namespace CarlaBackend; | #define CARLA_BACKEND_USE_NAMESPACE using namespace CarlaBackend; | ||||
#define STR_MAX 0xFF+1 | |||||
#define STR_MAX 0xFF | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -40,7 +40,7 @@ CARLA_BACKEND_START_NAMESPACE | |||||
const unsigned int MAX_DEFAULT_PLUGINS = 99; //!< Maximum default number of loadable plugins | const unsigned int MAX_DEFAULT_PLUGINS = 99; //!< Maximum default number of loadable plugins | ||||
const unsigned int MAX_RACK_PLUGINS = 16; //!< Maximum number of loadable plugins in rack mode | const unsigned int MAX_RACK_PLUGINS = 16; //!< Maximum number of loadable plugins in rack mode | ||||
const unsigned int MAX_PATCHBAY_PLUGINS = 999; //!< Maximum number of loadable plugins in patchbay mode | |||||
const unsigned int MAX_PATCHBAY_PLUGINS = 255; //!< Maximum number of loadable plugins in patchbay mode | |||||
const unsigned int MAX_DEFAULT_PARAMETERS = 200; //!< Maximum default number of parameters allowed.\see OPTION_MAX_PARAMETERS | const unsigned int MAX_DEFAULT_PARAMETERS = 200; //!< Maximum default number of parameters allowed.\see OPTION_MAX_PARAMETERS | ||||
/*! | /*! | ||||
@@ -64,9 +64,8 @@ const unsigned int PLUGIN_CAN_PANNING = 0x800; //!< Plugin can make use of | |||||
/*! | /*! | ||||
* @defgroup PluginOptions Plugin Options | * @defgroup PluginOptions Plugin Options | ||||
* | * | ||||
* Various plugin options.\n | |||||
* ON or OFF defines the default plugin value. | |||||
* \see CarlaPlugin::options() | |||||
* Various plugin options. | |||||
* \see CarlaPlugin::availableOptions() and CarlaPlugin::options() | |||||
* @{ | * @{ | ||||
*/ | */ | ||||
const unsigned int PLUGIN_OPTION_FIXED_BUFFER = 0x001; //!< Use a constant, fixed-size audio buffer | const unsigned int PLUGIN_OPTION_FIXED_BUFFER = 0x001; //!< Use a constant, fixed-size audio buffer | ||||
@@ -77,7 +76,7 @@ const unsigned int PLUGIN_OPTION_SEND_CONTROL_CHANGES = 0x010; //!< Send MIDI C | |||||
const unsigned int PLUGIN_OPTION_SEND_CHANNEL_PRESSURE = 0x020; //!< Send MIDI channel pressure events | const unsigned int PLUGIN_OPTION_SEND_CHANNEL_PRESSURE = 0x020; //!< Send MIDI channel pressure events | ||||
const unsigned int PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH = 0x040; //!< Send MIDI note aftertouch events | const unsigned int PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH = 0x040; //!< Send MIDI note aftertouch events | ||||
const unsigned int PLUGIN_OPTION_SEND_PITCHBEND = 0x080; //!< Send MIDI pitchbend events | const unsigned int PLUGIN_OPTION_SEND_PITCHBEND = 0x080; //!< Send MIDI pitchbend events | ||||
const unsigned int PLUGIN_OPTION_SEND_ALL_SOUND_OFF = 0x100; //!< Send MIDI ALL_SOUND_OFF / ALL_NOTES_OFF events | |||||
const unsigned int PLUGIN_OPTION_SEND_ALL_SOUND_OFF = 0x100; //!< Send MIDI all sounds/notes off events, single-note offs otherwise | |||||
/**@}*/ | /**@}*/ | ||||
/*! | /*! | ||||
@@ -87,13 +86,13 @@ const unsigned int PLUGIN_OPTION_SEND_ALL_SOUND_OFF = 0x100; //!< Send MIDI A | |||||
* \see CarlaPlugin::parameterData() | * \see CarlaPlugin::parameterData() | ||||
* @{ | * @{ | ||||
*/ | */ | ||||
const unsigned int PARAMETER_IS_BOOLEAN = 0x01; //!< Parameter value is always a boolean (always at minimum or maximum range). | |||||
const unsigned int PARAMETER_IS_INTEGER = 0x02; //!< Parameter value is always an integer. | |||||
const unsigned int PARAMETER_IS_BOOLEAN = 0x01; //!< Parameter value is a boolean (always at minimum or maximum values). | |||||
const unsigned int PARAMETER_IS_INTEGER = 0x02; //!< Parameter value is an integer. | |||||
const unsigned int PARAMETER_IS_LOGARITHMIC = 0x04; //!< Parameter is logarithmic. | const unsigned int PARAMETER_IS_LOGARITHMIC = 0x04; //!< Parameter is logarithmic. | ||||
const unsigned int PARAMETER_IS_ENABLED = 0x08; //!< Parameter is enabled and will be shown in the host built-in editor. | const unsigned int PARAMETER_IS_ENABLED = 0x08; //!< Parameter is enabled and will be shown in the host built-in editor. | ||||
const unsigned int PARAMETER_IS_AUTOMABLE = 0x10; //!< Parameter is automable (realtime safe) | const unsigned int PARAMETER_IS_AUTOMABLE = 0x10; //!< Parameter is automable (realtime safe) | ||||
const unsigned int PARAMETER_USES_SAMPLERATE = 0x20; //!< Parameter needs sample rate to work (value and ranges are multiplied by SR, and must be divided by SR on save). | const unsigned int PARAMETER_USES_SAMPLERATE = 0x20; //!< Parameter needs sample rate to work (value and ranges are multiplied by SR, and must be divided by SR on save). | ||||
const unsigned int PARAMETER_USES_SCALEPOINTS = 0x40; //!< Parameter uses scalepoints to define internal values in a meaninful way. | |||||
const unsigned int PARAMETER_USES_SCALEPOINTS = 0x40; //!< Parameter uses scalepoints to define internal values in a meaningful way. | |||||
const unsigned int PARAMETER_USES_CUSTOM_TEXT = 0x80; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText() | const unsigned int PARAMETER_USES_CUSTOM_TEXT = 0x80; //!< Parameter uses custom text for displaying its value.\see CarlaPlugin::getParameterText() | ||||
/**@}*/ | /**@}*/ | ||||
@@ -159,15 +158,15 @@ enum BinaryType { | |||||
*/ | */ | ||||
enum PluginType { | enum PluginType { | ||||
PLUGIN_NONE = 0, //!< Null plugin type. | PLUGIN_NONE = 0, //!< Null plugin type. | ||||
PLUGIN_INTERNAL = 1, //!< Internal plugin.\see NativePlugin | |||||
PLUGIN_LADSPA = 2, //!< LADSPA plugin.\see LadspaPlugin | |||||
PLUGIN_DSSI = 3, //!< DSSI plugin.\see DssiPlugin | |||||
PLUGIN_LV2 = 4, //!< LV2 plugin.\see Lv2Plugin | |||||
PLUGIN_VST = 5, //!< VST1/2 plugin.\see VstPlugin | |||||
PLUGIN_VST3 = 6, //!< VST3 plugin.\see VstPlugin | |||||
PLUGIN_GIG = 7, //!< GIG sound kit, implemented via LinuxSampler.\see LinuxSamplerPlugin | |||||
PLUGIN_SF2 = 8, //!< SF2 sound kit (aka SoundFont), implemented via FluidSynth.\see FluidSynthPlugin | |||||
PLUGIN_SFZ = 9 //!< SFZ sound kit, implemented via LinuxSampler.\see LinuxSamplerPlugin | |||||
PLUGIN_INTERNAL = 1, //!< Internal plugin. | |||||
PLUGIN_LADSPA = 2, //!< LADSPA plugin. | |||||
PLUGIN_DSSI = 3, //!< DSSI plugin. | |||||
PLUGIN_LV2 = 4, //!< LV2 plugin. | |||||
PLUGIN_VST = 5, //!< VST1/2 plugin. | |||||
PLUGIN_VST3 = 6, //!< VST3 plugin. | |||||
PLUGIN_GIG = 7, //!< GIG sound kit, implemented via LinuxSampler. | |||||
PLUGIN_SF2 = 8, //!< SF2 sound kit (aka SoundFont), implemented via FluidSynth. | |||||
PLUGIN_SFZ = 9 //!< SFZ sound kit, implemented via LinuxSampler. | |||||
}; | }; | ||||
/*! | /*! | ||||
@@ -219,7 +218,7 @@ enum InternalParametersIndex { | |||||
/*! | /*! | ||||
* Options used in the CarlaEngine::setOption() and set_option() calls.\n | * Options used in the CarlaEngine::setOption() and set_option() calls.\n | ||||
* These options must be set before initiliazing or after closing the engine. | |||||
* All options except paths must be set before initiliazing or after closing the engine. | |||||
*/ | */ | ||||
enum OptionsType { | enum OptionsType { | ||||
/*! | /*! | ||||
@@ -250,8 +249,7 @@ enum OptionsType { | |||||
/*! | /*! | ||||
* Use plugin bridges whenever possible.\n | * Use plugin bridges whenever possible.\n | ||||
* Default is no, and not recommended at this point!. | |||||
* EXPERIMENTAL AND INCOMPLETE! | |||||
* Default is no, EXPERIMENTAL. | |||||
*/ | */ | ||||
OPTION_PREFER_PLUGIN_BRIDGES = 4, | OPTION_PREFER_PLUGIN_BRIDGES = 4, | ||||
@@ -391,8 +389,7 @@ enum OptionsType { | |||||
/*! | /*! | ||||
* Opcodes sent from the engine callback to the GUI, as defined by CallbackFunc. | * Opcodes sent from the engine callback to the GUI, as defined by CallbackFunc. | ||||
* | * | ||||
* \see CarlaEngine::setCallback() | |||||
* \see set_callback_function() | |||||
* \see CarlaEngine::setCallback() and set_callback_function() | |||||
*/ | */ | ||||
enum CallbackType { | enum CallbackType { | ||||
/*! | /*! | ||||
@@ -403,6 +400,7 @@ enum CallbackType { | |||||
/*! | /*! | ||||
* A plugin has been added. | * A plugin has been added. | ||||
* \param valueStr Plugin name | |||||
*/ | */ | ||||
CALLBACK_PLUGIN_ADDED = 1, | CALLBACK_PLUGIN_ADDED = 1, | ||||
@@ -413,6 +411,7 @@ enum CallbackType { | |||||
/*! | /*! | ||||
* A plugin has been renamed. | * A plugin has been renamed. | ||||
* \param valueStr New name | |||||
*/ | */ | ||||
CALLBACK_PLUGIN_RENAMED = 3, | CALLBACK_PLUGIN_RENAMED = 3, | ||||
@@ -425,10 +424,10 @@ enum CallbackType { | |||||
CALLBACK_PARAMETER_VALUE_CHANGED = 4, | CALLBACK_PARAMETER_VALUE_CHANGED = 4, | ||||
/*! | /*! | ||||
* A parameter default has been changed. | |||||
* A parameter default has changed. | |||||
* | * | ||||
* \param value1 Parameter index | * \param value1 Parameter index | ||||
* \param value3 Default value | |||||
* \param value3 New default value | |||||
*/ | */ | ||||
CALLBACK_PARAMETER_DEFAULT_CHANGED = 5, | CALLBACK_PARAMETER_DEFAULT_CHANGED = 5, | ||||
@@ -518,31 +517,32 @@ enum CallbackType { | |||||
/*! | /*! | ||||
* Canvas client added | * Canvas client added | ||||
* | * | ||||
* \param value1 Client ID | |||||
* \param valueStr Client Name | |||||
* \param value1 Client Id | |||||
* \param valueStr Client name | |||||
*/ | */ | ||||
CALLBACK_PATCHBAY_CLIENT_ADDED = 18, | CALLBACK_PATCHBAY_CLIENT_ADDED = 18, | ||||
/*! | /*! | ||||
* Canvas client removed | * Canvas client removed | ||||
* | * | ||||
* \param value1 Client ID | |||||
* \param value1 Client Id | |||||
*/ | */ | ||||
CALLBACK_PATCHBAY_CLIENT_REMOVED = 19, | CALLBACK_PATCHBAY_CLIENT_REMOVED = 19, | ||||
/*! | /*! | ||||
* Canvas client renamed | * Canvas client renamed | ||||
* | * | ||||
* \param value1 Client ID | |||||
* \param valueStr New Client name | |||||
* \param value1 Client Id | |||||
* \param valueStr New client name | |||||
*/ | */ | ||||
CALLBACK_PATCHBAY_CLIENT_RENAMED = 20, | CALLBACK_PATCHBAY_CLIENT_RENAMED = 20, | ||||
/*! | /*! | ||||
* Canvas port added | * Canvas port added | ||||
* | * | ||||
* \param value1 Client ID | |||||
* \param value2 Port ID | |||||
* \param value1 Client Id | |||||
* \param value2 Port Id | |||||
* \param value3 Port flags | |||||
* \param valueStr Port name | * \param valueStr Port name | ||||
*/ | */ | ||||
CALLBACK_PATCHBAY_PORT_ADDED = 21, | CALLBACK_PATCHBAY_PORT_ADDED = 21, | ||||
@@ -550,31 +550,31 @@ enum CallbackType { | |||||
/*! | /*! | ||||
* Canvas port remvoed | * Canvas port remvoed | ||||
* | * | ||||
* \param value1 Port ID | |||||
* \param value1 Port Id | |||||
*/ | */ | ||||
CALLBACK_PATCHBAY_PORT_REMOVED = 22, | CALLBACK_PATCHBAY_PORT_REMOVED = 22, | ||||
/*! | /*! | ||||
* Canvas port renamed | * Canvas port renamed | ||||
* | * | ||||
* \param value1 Port ID | |||||
* \param valueStr New Port name | |||||
* \param value1 Port Id | |||||
* \param valueStr New port name | |||||
*/ | */ | ||||
CALLBACK_PATCHBAY_PORT_RENAMED = 23, | CALLBACK_PATCHBAY_PORT_RENAMED = 23, | ||||
/*! | /*! | ||||
* Canvas port connection added | * Canvas port connection added | ||||
* | * | ||||
* \param value1 Output port ID | |||||
* \param value2 Input port ID | |||||
* \param value1 Output port Id | |||||
* \param value2 Input port Id | |||||
*/ | */ | ||||
CALLBACK_PATCHBAY_CONNECTION_ADDED = 24, | CALLBACK_PATCHBAY_CONNECTION_ADDED = 24, | ||||
/*! | /*! | ||||
* Canvas port connection removed | * Canvas port connection removed | ||||
* | * | ||||
* \param value1 Output port ID | |||||
* \param value2 Input port ID | |||||
* \param value1 Output port Id | |||||
* \param value2 Input port Id | |||||
*/ | */ | ||||
CALLBACK_PATCHBAY_CONNECTION_REMOVED = 25, | CALLBACK_PATCHBAY_CONNECTION_REMOVED = 25, | ||||
@@ -617,7 +617,7 @@ enum CallbackType { | |||||
enum ProcessMode { | enum ProcessMode { | ||||
PROCESS_MODE_SINGLE_CLIENT = 0, //!< Single client mode (dynamic input/outputs as needed by plugins) | PROCESS_MODE_SINGLE_CLIENT = 0, //!< Single client mode (dynamic input/outputs as needed by plugins) | ||||
PROCESS_MODE_MULTIPLE_CLIENTS = 1, //!< Multiple client mode (1 master client + 1 client per plugin) | PROCESS_MODE_MULTIPLE_CLIENTS = 1, //!< Multiple client mode (1 master client + 1 client per plugin) | ||||
PROCESS_MODE_CONTINUOUS_RACK = 2, //!< Single client, 'rack' mode. Processes plugins in order of id, with forced stereo. | |||||
PROCESS_MODE_CONTINUOUS_RACK = 2, //!< Single client, 'rack' mode. Processes plugins in order of Id, with forced stereo. | |||||
PROCESS_MODE_PATCHBAY = 3, //!< Single client, 'patchbay' mode. | PROCESS_MODE_PATCHBAY = 3, //!< Single client, 'patchbay' mode. | ||||
PROCESS_MODE_BRIDGE = 4 //!< Special mode, used in plugin-bridges only. | PROCESS_MODE_BRIDGE = 4 //!< Special mode, used in plugin-bridges only. | ||||
}; | }; | ||||
@@ -651,7 +651,7 @@ struct ParameterData { | |||||
ParameterData() | ParameterData() | ||||
: type(PARAMETER_UNKNOWN), | : type(PARAMETER_UNKNOWN), | ||||
index(-1), | |||||
index(PARAMETER_NULL), | |||||
rindex(-1), | rindex(-1), | ||||
hints(0x0), | hints(0x0), | ||||
midiChannel(0), | midiChannel(0), | ||||
@@ -1,232 +0,0 @@ | |||||
/* | |||||
* Carla Bridge API | |||||
* Copyright (C) 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 GNU General Public License see the GPL.txt file | |||||
*/ | |||||
#ifndef __CARLA_BRIDGE_HPP__ | |||||
#define __CARLA_BRIDGE_HPP__ | |||||
#include "CarlaUtils.hpp" | |||||
#include <semaphore.h> | |||||
#define BRIDGE_SHM_RING_BUFFER_SIZE 2048 | |||||
#ifndef BUILD_BRIDGE | |||||
/*! | |||||
* TODO. | |||||
*/ | |||||
enum PluginBridgeInfoType { | |||||
kPluginBridgeAudioCount, | |||||
kPluginBridgeMidiCount, | |||||
kPluginBridgeParameterCount, | |||||
kPluginBridgeProgramCount, | |||||
kPluginBridgeMidiProgramCount, | |||||
kPluginBridgePluginInfo, | |||||
kPluginBridgeParameterInfo, | |||||
kPluginBridgeParameterData, | |||||
kPluginBridgeParameterRanges, | |||||
kPluginBridgeProgramInfo, | |||||
kPluginBridgeMidiProgramInfo, | |||||
kPluginBridgeConfigure, | |||||
kPluginBridgeSetParameterValue, | |||||
kPluginBridgeSetDefaultValue, | |||||
kPluginBridgeSetProgram, | |||||
kPluginBridgeSetMidiProgram, | |||||
kPluginBridgeSetCustomData, | |||||
kPluginBridgeSetChunkData, | |||||
kPluginBridgeUpdateNow, | |||||
kPluginBridgeError | |||||
}; | |||||
#endif | |||||
enum PluginBridgeOpcode { | |||||
kPluginBridgeOpcodeNull = 0, | |||||
kPluginBridgeOpcodeReadyWait = 1, | |||||
kPluginBridgeOpcodeBufferSize = 2, | |||||
kPluginBridgeOpcodeSampleRate = 3, | |||||
kPluginBridgeOpcodeProcess = 4 | |||||
}; | |||||
/*! | |||||
* TODO. | |||||
*/ | |||||
struct BridgeRingBuffer { | |||||
int head; | |||||
int tail; | |||||
int written; | |||||
bool invalidateCommit; | |||||
char buf[BRIDGE_SHM_RING_BUFFER_SIZE]; | |||||
}; | |||||
/*! | |||||
* TODO. | |||||
*/ | |||||
struct BridgeShmControl { | |||||
// 32 and 64-bit binaries align semaphores differently. | |||||
// Let's make sure there's plenty of room for either one. | |||||
union { | |||||
sem_t runServer; | |||||
char _alignServer[64]; | |||||
}; | |||||
union { | |||||
sem_t runClient; | |||||
char _alignClient[64]; | |||||
}; | |||||
BridgeRingBuffer ringBuffer; | |||||
}; | |||||
// --------------------------------------------------------------------------------------------- | |||||
static inline | |||||
void rdwr_tryRead(BridgeRingBuffer* const ringbuf, void* const buf, const size_t size) | |||||
{ | |||||
char* const charbuf = static_cast<char*>(buf); | |||||
size_t tail = ringbuf->tail; | |||||
size_t head = ringbuf->head; | |||||
size_t wrap = 0; | |||||
if (head <= tail) { | |||||
wrap = BRIDGE_SHM_RING_BUFFER_SIZE; | |||||
} | |||||
if (head - tail + wrap < size) { | |||||
return; | |||||
} | |||||
size_t readto = tail + size; | |||||
if (readto >= BRIDGE_SHM_RING_BUFFER_SIZE) | |||||
{ | |||||
readto -= BRIDGE_SHM_RING_BUFFER_SIZE; | |||||
size_t firstpart = BRIDGE_SHM_RING_BUFFER_SIZE - tail; | |||||
std::memcpy(charbuf, ringbuf->buf + tail, firstpart); | |||||
std::memcpy(charbuf + firstpart, ringbuf->buf, readto); | |||||
} | |||||
else | |||||
{ | |||||
std::memcpy(charbuf, ringbuf->buf + tail, size); | |||||
} | |||||
ringbuf->tail = readto; | |||||
} | |||||
static inline | |||||
void rdwr_tryWrite(BridgeRingBuffer* const ringbuf, const void* const buf, const size_t size) | |||||
{ | |||||
const char* const charbuf = static_cast<const char*>(buf); | |||||
size_t written = ringbuf->written; | |||||
size_t tail = ringbuf->tail; | |||||
size_t wrap = 0; | |||||
if (tail <= written) | |||||
{ | |||||
wrap = BRIDGE_SHM_RING_BUFFER_SIZE; | |||||
} | |||||
if (tail - written + wrap < size) | |||||
{ | |||||
carla_stderr2("Operation ring buffer full! Dropping events."); | |||||
ringbuf->invalidateCommit = true; | |||||
return; | |||||
} | |||||
size_t writeto = written + size; | |||||
if (writeto >= BRIDGE_SHM_RING_BUFFER_SIZE) | |||||
{ | |||||
writeto -= BRIDGE_SHM_RING_BUFFER_SIZE; | |||||
size_t firstpart = BRIDGE_SHM_RING_BUFFER_SIZE - written; | |||||
std::memcpy(ringbuf->buf + written, charbuf, firstpart); | |||||
std::memcpy(ringbuf->buf, charbuf + firstpart, writeto); | |||||
} | |||||
else | |||||
{ | |||||
std::memcpy(ringbuf->buf + written, charbuf, size); | |||||
} | |||||
ringbuf->written = writeto; | |||||
} | |||||
static inline | |||||
void rdwr_commitWrite(BridgeRingBuffer* const ringbuf) | |||||
{ | |||||
if (ringbuf->invalidateCommit) | |||||
{ | |||||
ringbuf->written = ringbuf->head; | |||||
ringbuf->invalidateCommit = false; | |||||
} | |||||
else | |||||
{ | |||||
ringbuf->head = ringbuf->written; | |||||
} | |||||
} | |||||
// --------------------------------------------------------------------------------------------- | |||||
static inline | |||||
bool rdwr_dataAvailable(BridgeRingBuffer* const ringbuf) | |||||
{ | |||||
return (ringbuf->tail != ringbuf->head); | |||||
} | |||||
static inline | |||||
PluginBridgeOpcode rdwr_readOpcode(BridgeRingBuffer* const ringbuf) | |||||
{ | |||||
PluginBridgeOpcode code = kPluginBridgeOpcodeNull; | |||||
rdwr_tryRead(ringbuf, &code, sizeof(PluginBridgeOpcode)); | |||||
return code; | |||||
} | |||||
static inline | |||||
int rdwr_readInt(BridgeRingBuffer* const ringbuf) | |||||
{ | |||||
int i = 0; | |||||
rdwr_tryRead(ringbuf, &i, sizeof(int)); | |||||
return i; | |||||
} | |||||
static inline | |||||
float rdwr_readFloat(BridgeRingBuffer* const ringbuf) | |||||
{ | |||||
float f = 0.0f; | |||||
rdwr_tryRead(ringbuf, &f, sizeof(float)); | |||||
return f; | |||||
} | |||||
// --------------------------------------------------------------------------------------------- | |||||
static inline | |||||
void rdwr_writeOpcode(BridgeRingBuffer* const ringbuf, const PluginBridgeOpcode opcode) | |||||
{ | |||||
rdwr_tryWrite(ringbuf, &opcode, sizeof(PluginBridgeOpcode)); | |||||
} | |||||
static inline | |||||
void rdwr_writeInt(BridgeRingBuffer* const ringbuf, const int value) | |||||
{ | |||||
rdwr_tryWrite(ringbuf, &value, sizeof(int)); | |||||
} | |||||
static inline | |||||
void rdwr_writeFloat(BridgeRingBuffer* const ringbuf, const float value) | |||||
{ | |||||
rdwr_tryWrite(ringbuf, &value, sizeof(float)); | |||||
} | |||||
// --------------------------------------------------------------------------------------------- | |||||
#endif // __CARLA_BRIDGE_HPP__ |
@@ -119,7 +119,7 @@ enum EngineControlEventType { | |||||
/*! | /*! | ||||
* Parameter event type.\n | * Parameter event type.\n | ||||
* \note Value uses a range of 0.0<->1.0. | |||||
* \note Value uses a normalized range of 0.0<->1.0. | |||||
*/ | */ | ||||
kEngineControlEventTypeParameter = 1, | kEngineControlEventTypeParameter = 1, | ||||
@@ -222,7 +222,7 @@ struct EngineEvent { | |||||
// ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
/*! | /*! | ||||
* Engine devices | |||||
* Engine devices (unused). | |||||
*/ | */ | ||||
struct EngineDevices { | struct EngineDevices { | ||||
struct Audio { | struct Audio { | ||||
@@ -284,18 +284,18 @@ struct EngineOptions { | |||||
CarlaString bridge_win64; | CarlaString bridge_win64; | ||||
#endif | #endif | ||||
#ifdef WANT_LV2 | #ifdef WANT_LV2 | ||||
CarlaString bridge_lv2gtk2; | |||||
CarlaString bridge_lv2gtk3; | |||||
CarlaString bridge_lv2qt4; | |||||
CarlaString bridge_lv2qt5; | |||||
CarlaString bridge_lv2cocoa; | |||||
CarlaString bridge_lv2win; | |||||
CarlaString bridge_lv2x11; | |||||
CarlaString bridge_lv2Gtk2; | |||||
CarlaString bridge_lv2Gtk3; | |||||
CarlaString bridge_lv2Qt4; | |||||
CarlaString bridge_lv2Qt5; | |||||
CarlaString bridge_lv2Cocoa; | |||||
CarlaString bridge_lv2Win; | |||||
CarlaString bridge_lv2X11; | |||||
#endif | #endif | ||||
#ifdef WANT_VST | #ifdef WANT_VST | ||||
CarlaString bridge_vstcocoa; | |||||
CarlaString bridge_vsthwnd; | |||||
CarlaString bridge_vstx11; | |||||
CarlaString bridge_vstCocoa; | |||||
CarlaString bridge_vstHWND; | |||||
CarlaString bridge_vstX11; | |||||
#endif | #endif | ||||
EngineOptions() | EngineOptions() | ||||
@@ -102,7 +102,7 @@ CarlaEngineEventPort::CarlaEngineEventPort(const bool isInput, const ProcessMode | |||||
carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | ||||
if (kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE) | if (kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE) | ||||
fBuffer = new EngineEvent[PATCHBAY_EVENT_COUNT]; | |||||
fBuffer = new EngineEvent[kMaxEventCount]; | |||||
} | } | ||||
CarlaEngineEventPort::~CarlaEngineEventPort() | CarlaEngineEventPort::~CarlaEngineEventPort() | ||||
@@ -131,7 +131,7 @@ void CarlaEngineEventPort::initBuffer(CarlaEngine* const engine) | |||||
else | else | ||||
#endif | #endif | ||||
if ((kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE) && ! kIsInput) | if ((kProcessMode == PROCESS_MODE_PATCHBAY || kProcessMode == PROCESS_MODE_BRIDGE) && ! kIsInput) | ||||
carla_zeroMem(fBuffer, sizeof(EngineEvent)*PATCHBAY_EVENT_COUNT); | |||||
carla_zeroStruct<EngineEvent>(fBuffer, kMaxEventCount); | |||||
} | } | ||||
uint32_t CarlaEngineEventPort::getEventCount() | uint32_t CarlaEngineEventPort::getEventCount() | ||||
@@ -1064,7 +1064,7 @@ bool CarlaEngine::saveProject(const char* const filename) | |||||
out << "<CARLA-PROJECT VERSION='1.0'>\n"; | out << "<CARLA-PROJECT VERSION='1.0'>\n"; | ||||
bool firstPlugin = true; | bool firstPlugin = true; | ||||
char strBuf[STR_MAX]; | |||||
char strBuf[STR_MAX+1]; | |||||
for (unsigned int i=0; i < kData->curPluginCount; i++) | for (unsigned int i=0; i < kData->curPluginCount; i++) | ||||
{ | { | ||||
@@ -73,7 +73,6 @@ HEADERS = \ | |||||
HEADERS += \ | HEADERS += \ | ||||
../CarlaBackend.hpp \ | ../CarlaBackend.hpp \ | ||||
../CarlaBridge.hpp \ | |||||
../CarlaEngine.hpp \ | ../CarlaEngine.hpp \ | ||||
../CarlaPlugin.hpp | ../CarlaPlugin.hpp | ||||
@@ -85,6 +84,7 @@ HEADERS += \ | |||||
../../utils/CarlaThread.hpp \ | ../../utils/CarlaThread.hpp \ | ||||
../../utils/CarlaUtils.hpp \ | ../../utils/CarlaUtils.hpp \ | ||||
../../utils/CarlaBackendUtils.hpp \ | ../../utils/CarlaBackendUtils.hpp \ | ||||
../../utils/CarlaBridgeUtils.hpp \ | |||||
../../utils/CarlaJuceUtils.hpp \ | ../../utils/CarlaJuceUtils.hpp \ | ||||
../../utils/CarlaOscUtils.hpp \ | ../../utils/CarlaOscUtils.hpp \ | ||||
../../utils/CarlaStateUtils.hpp | ../../utils/CarlaStateUtils.hpp | ||||
@@ -358,7 +358,24 @@ const char* ProcessMode2Str(const ProcessMode& mode) | |||||
return "PROCESS_MODE_BRIDGE"; | return "PROCESS_MODE_BRIDGE"; | ||||
} | } | ||||
carla_stderr("CarlaBackend::ProcessModeType2Str(%i) - invalid type", mode); | |||||
carla_stderr("CarlaBackend::ProcessMode2Str(%i) - invalid type", mode); | |||||
return nullptr; | |||||
} | |||||
static inline | |||||
const char* TransportMode2Str(const TransportMode& mode) | |||||
{ | |||||
switch (mode) | |||||
{ | |||||
case TRANSPORT_MODE_INTERNAL: | |||||
return "TRANSPORT_MODE_INTERNAL"; | |||||
case TRANSPORT_MODE_JACK: | |||||
return "TRANSPORT_MODE_JACK"; | |||||
case TRANSPORT_MODE_BRIDGE: | |||||
return "TRANSPORT_MODE_BRIDGE"; | |||||
} | |||||
carla_stderr("CarlaBackend::TransportMode2Str(%i) - invalid type", mode); | |||||
return nullptr; | return nullptr; | ||||
} | } | ||||
@@ -140,7 +140,7 @@ unsigned int carla_base64_decode(const char* const encoded, uint8_t* const raw) | |||||
continue; | continue; | ||||
} | } | ||||
if (padCount) | |||||
if (padCount > 0) | |||||
{ | { | ||||
carla_debug("Base64-encoded string \"%s\" has invalid pad sequence", encoded); | carla_debug("Base64-encoded string \"%s\" has invalid pad sequence", encoded); | ||||
return 0; | return 0; | ||||
@@ -1,5 +1,5 @@ | |||||
/* | /* | ||||
* Carla common utils | |||||
* Carla Mutex | |||||
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | ||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla Backend utils | |||||
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||||
* Carla State utils | |||||
* Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -19,9 +19,10 @@ | |||||
#define __CARLA_STATE_UTILS_HPP__ | #define __CARLA_STATE_UTILS_HPP__ | ||||
#include "CarlaBackendUtils.hpp" | #include "CarlaBackendUtils.hpp" | ||||
#include "CarlaMIDI.h" | |||||
#include <QtXml/QDomNode> | |||||
#include <QtCore/QVector> | #include <QtCore/QVector> | ||||
#include <QtXml/QDomNode> | |||||
CARLA_BACKEND_START_NAMESPACE | CARLA_BACKEND_START_NAMESPACE | ||||
@@ -40,7 +41,7 @@ struct StateParameter { | |||||
name(nullptr), | name(nullptr), | ||||
symbol(nullptr), | symbol(nullptr), | ||||
value(0.0f), | value(0.0f), | ||||
midiChannel(1), | |||||
midiChannel(0), | |||||
midiCC(-1) {} | midiCC(-1) {} | ||||
~StateParameter() | ~StateParameter() | ||||
@@ -97,7 +98,7 @@ struct SaveState { | |||||
int32_t currentMidiProgram; | int32_t currentMidiProgram; | ||||
const char* chunk; | const char* chunk; | ||||
StateParameterVector parameters; | |||||
StateParameterVector parameters; | |||||
StateCustomDataVector customData; | StateCustomDataVector customData; | ||||
SaveState() | SaveState() | ||||
@@ -176,13 +177,13 @@ struct SaveState { | |||||
for (auto it = parameters.begin(); it != parameters.end(); ++it) | for (auto it = parameters.begin(); it != parameters.end(); ++it) | ||||
{ | { | ||||
StateParameter* stateParameter = *it; | |||||
StateParameter* const stateParameter(*it); | |||||
delete stateParameter; | delete stateParameter; | ||||
} | } | ||||
for (auto it = customData.begin(); it != customData.end(); ++it) | for (auto it = customData.begin(); it != customData.end(); ++it) | ||||
{ | { | ||||
StateCustomData* stateCustomData = *it; | |||||
StateCustomData* const stateCustomData(*it); | |||||
delete stateCustomData; | delete stateCustomData; | ||||
} | } | ||||
@@ -231,8 +232,8 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
while (! xmlInfo.isNull()) | while (! xmlInfo.isNull()) | ||||
{ | { | ||||
const QString tag = xmlInfo.toElement().tagName(); | |||||
const QString text = xmlInfo.toElement().text().trimmed(); | |||||
const QString tag(xmlInfo.toElement().tagName()); | |||||
const QString text(xmlInfo.toElement().text().trimmed()); | |||||
if (tag.compare("Type", Qt::CaseInsensitive) == 0) | if (tag.compare("Type", Qt::CaseInsensitive) == 0) | ||||
saveState.type = xmlSafeStringChar(text, false); | saveState.type = xmlSafeStringChar(text, false); | ||||
@@ -262,8 +263,8 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
while (! xmlData.isNull()) | while (! xmlData.isNull()) | ||||
{ | { | ||||
const QString tag = xmlData.toElement().tagName(); | |||||
const QString text = xmlData.toElement().text().trimmed(); | |||||
const QString tag(xmlData.toElement().tagName()); | |||||
const QString text(xmlData.toElement().text().trimmed()); | |||||
// ---------------------------------------------- | // ---------------------------------------------- | ||||
// Internal Data | // Internal Data | ||||
@@ -345,14 +346,14 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
else if (tag.compare("Parameter", Qt::CaseInsensitive) == 0) | else if (tag.compare("Parameter", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
StateParameter* stateParameter(new StateParameter); | |||||
StateParameter* const stateParameter(new StateParameter()); | |||||
QDomNode xmlSubData(xmlData.toElement().firstChild()); | QDomNode xmlSubData(xmlData.toElement().firstChild()); | ||||
while (! xmlSubData.isNull()) | while (! xmlSubData.isNull()) | ||||
{ | { | ||||
const QString pTag = xmlSubData.toElement().tagName(); | |||||
const QString pText = xmlSubData.toElement().text().trimmed(); | |||||
const QString pTag(xmlSubData.toElement().tagName()); | |||||
const QString pText(xmlSubData.toElement().text().trimmed()); | |||||
if (pTag.compare("Index", Qt::CaseInsensitive) == 0) | if (pTag.compare("Index", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
@@ -378,21 +379,21 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
{ | { | ||||
bool ok; | bool ok; | ||||
ushort channel = pText.toUShort(&ok); | ushort channel = pText.toUShort(&ok); | ||||
if (ok && channel < 16) | |||||
stateParameter->midiChannel = static_cast<uint8_t>(channel); | |||||
if (ok && channel > 0 && channel < MAX_MIDI_CHANNELS) | |||||
stateParameter->midiChannel = static_cast<uint8_t>(channel-1); | |||||
} | } | ||||
else if (pTag.compare("MidiCC", Qt::CaseInsensitive) == 0) | else if (pTag.compare("MidiCC", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
bool ok; | bool ok; | ||||
int cc = pText.toInt(&ok); | int cc = pText.toInt(&ok); | ||||
if (ok && cc < INT16_MAX) | |||||
if (ok && cc > 0 && cc < INT16_MAX) | |||||
stateParameter->midiCC = static_cast<int16_t>(cc); | stateParameter->midiCC = static_cast<int16_t>(cc); | ||||
} | } | ||||
xmlSubData = xmlSubData.nextSibling(); | xmlSubData = xmlSubData.nextSibling(); | ||||
} | } | ||||
saveState.parameters.push_back(stateParameter); | |||||
saveState.parameters.append(stateParameter); | |||||
} | } | ||||
// ---------------------------------------------- | // ---------------------------------------------- | ||||
@@ -400,14 +401,14 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
else if (tag.compare("CustomData", Qt::CaseInsensitive) == 0) | else if (tag.compare("CustomData", Qt::CaseInsensitive) == 0) | ||||
{ | { | ||||
StateCustomData* stateCustomData(new StateCustomData); | |||||
StateCustomData* const stateCustomData(new StateCustomData()); | |||||
QDomNode xmlSubData(xmlData.toElement().firstChild()); | QDomNode xmlSubData(xmlData.toElement().firstChild()); | ||||
while (! xmlSubData.isNull()) | while (! xmlSubData.isNull()) | ||||
{ | { | ||||
const QString cTag = xmlSubData.toElement().tagName(); | |||||
const QString cText = xmlSubData.toElement().text().trimmed(); | |||||
const QString cTag(xmlSubData.toElement().tagName()); | |||||
const QString cText(xmlSubData.toElement().text().trimmed()); | |||||
if (cTag.compare("Type", Qt::CaseInsensitive) == 0) | if (cTag.compare("Type", Qt::CaseInsensitive) == 0) | ||||
stateCustomData->type = xmlSafeStringChar(cText, false); | stateCustomData->type = xmlSafeStringChar(cText, false); | ||||
@@ -419,7 +420,7 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
xmlSubData = xmlSubData.nextSibling(); | xmlSubData = xmlSubData.nextSibling(); | ||||
} | } | ||||
saveState.customData.push_back(stateCustomData); | |||||
saveState.customData.append(stateCustomData); | |||||
} | } | ||||
// ---------------------------------------------- | // ---------------------------------------------- | ||||
@@ -447,9 +448,10 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) | |||||
// ------------------------------------------------- | // ------------------------------------------------- | ||||
static inline | static inline | ||||
QString getXMLFromSaveState(const SaveState& saveState) | |||||
const QString& getXMLFromSaveState(const SaveState& saveState) | |||||
{ | { | ||||
QString content; | |||||
static QString content; | |||||
content.clear(); | |||||
{ | { | ||||
QString info(" <Info>\n"); | QString info(" <Info>\n"); | ||||
@@ -521,22 +523,22 @@ QString getXMLFromSaveState(const SaveState& saveState) | |||||
for (auto it = saveState.parameters.begin(); it != saveState.parameters.end(); ++it) | for (auto it = saveState.parameters.begin(); it != saveState.parameters.end(); ++it) | ||||
{ | { | ||||
StateParameter* stateParameter = *it; | |||||
StateParameter* const stateParameter(*it); | |||||
QString parameter("\n"" <Parameter>\n"); | QString parameter("\n"" <Parameter>\n"); | ||||
parameter += QString(" <Index>%1</Index>\n").arg(stateParameter->index); | parameter += QString(" <Index>%1</Index>\n").arg(stateParameter->index); | ||||
parameter += QString(" <Name>%1</Name>\n").arg(xmlSafeString(stateParameter->name, true)); | parameter += QString(" <Name>%1</Name>\n").arg(xmlSafeString(stateParameter->name, true)); | ||||
if (stateParameter->symbol != nullptr && *stateParameter->symbol != 0) | |||||
if (stateParameter->symbol != nullptr && *stateParameter->symbol != '\0') | |||||
parameter += QString(" <Symbol>%1</Symbol>\n").arg(xmlSafeString(stateParameter->symbol, true)); | parameter += QString(" <Symbol>%1</Symbol>\n").arg(xmlSafeString(stateParameter->symbol, true)); | ||||
parameter += QString(" <Value>%1</Value>\n").arg(stateParameter->value); | parameter += QString(" <Value>%1</Value>\n").arg(stateParameter->value); | ||||
if (stateParameter->midiCC > 0) | |||||
if (stateParameter->midiCC > 0 && stateParameter->midiChannel >= 0) | |||||
{ | { | ||||
parameter += QString(" <MidiCC>%1</MidiCC>\n").arg(stateParameter->midiCC); | parameter += QString(" <MidiCC>%1</MidiCC>\n").arg(stateParameter->midiCC); | ||||
parameter += QString(" <MidiChannel>%1</MidiChannel>\n").arg(stateParameter->midiChannel); | |||||
parameter += QString(" <MidiChannel>%1</MidiChannel>\n").arg(stateParameter->midiChannel+1); | |||||
} | } | ||||
parameter += " </Parameter>\n"; | parameter += " </Parameter>\n"; | ||||
@@ -544,13 +546,21 @@ QString getXMLFromSaveState(const SaveState& saveState) | |||||
content += parameter; | content += parameter; | ||||
} | } | ||||
if (saveState.currentProgramIndex >= 0) | |||||
if (saveState.currentProgramIndex >= 0 && saveState.currentProgramName != nullptr) | |||||
{ | { | ||||
QString program("\n"); | |||||
program += QString(" <CurrentProgramIndex>%1</CurrentProgramIndex>\n").arg(saveState.currentProgramIndex+1); | |||||
program += QString(" <CurrentProgramName>%1</CurrentProgramName>\n").arg(xmlSafeString(saveState.currentProgramName, true)); | |||||
// ignore 'default' program | |||||
#ifdef __USE_GNU | |||||
if ((saveState.currentProgramIndex > 0 || strcasecmp(saveState.currentProgramName, "Default") != 0)) | |||||
#else | |||||
if ((saveState.currentProgramIndex > 0 || std::strcmp(saveState.currentProgramName, "Default") != 0) | |||||
#endif | |||||
{ | |||||
QString program("\n"); | |||||
program += QString(" <CurrentProgramIndex>%1</CurrentProgramIndex>\n").arg(saveState.currentProgramIndex+1); | |||||
program += QString(" <CurrentProgramName>%1</CurrentProgramName>\n").arg(xmlSafeString(saveState.currentProgramName, true)); | |||||
content += program; | |||||
content += program; | |||||
} | |||||
} | } | ||||
if (saveState.currentMidiBank >= 0 && saveState.currentMidiProgram >= 0) | if (saveState.currentMidiBank >= 0 && saveState.currentMidiProgram >= 0) | ||||
@@ -564,7 +574,7 @@ QString getXMLFromSaveState(const SaveState& saveState) | |||||
for (auto it = saveState.customData.begin(); it != saveState.customData.end(); ++it) | for (auto it = saveState.customData.begin(); it != saveState.customData.end(); ++it) | ||||
{ | { | ||||
StateCustomData* stateCustomData = *it; | |||||
StateCustomData* const stateCustomData(*it); | |||||
QString customData("\n"" <CustomData>\n"); | QString customData("\n"" <CustomData>\n"); | ||||
customData += QString(" <Type>%1</Type>\n").arg(xmlSafeString(stateCustomData->type, true)); | customData += QString(" <Type>%1</Type>\n").arg(xmlSafeString(stateCustomData->type, true)); | ||||
@@ -584,7 +594,7 @@ QString getXMLFromSaveState(const SaveState& saveState) | |||||
content += customData; | content += customData; | ||||
} | } | ||||
if (saveState.chunk != nullptr && *saveState.chunk != 0) | |||||
if (saveState.chunk != nullptr && *saveState.chunk != '\0') | |||||
{ | { | ||||
QString chunk("\n"" <Chunk>\n"); | QString chunk("\n"" <Chunk>\n"); | ||||
chunk += QString("%1\n").arg(saveState.chunk); | chunk += QString("%1\n").arg(saveState.chunk); | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla common utils | |||||
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||||
* Carla String | |||||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -116,7 +116,7 @@ public: | |||||
} | } | ||||
// --------------------------------------------- | // --------------------------------------------- | ||||
// deconstructor | |||||
// destructor | |||||
~CarlaString() | ~CarlaString() | ||||
{ | { | ||||
@@ -187,9 +187,9 @@ public: | |||||
truncate(0); | truncate(0); | ||||
} | } | ||||
size_t find(const char c) | |||||
size_t find(const char c) const | |||||
{ | { | ||||
for (size_t i=0; i < bufferLen; i++) | |||||
for (size_t i=0; i < bufferLen; ++i) | |||||
{ | { | ||||
if (buffer[i] == c) | if (buffer[i] == c) | ||||
return i; | return i; | ||||
@@ -198,11 +198,11 @@ public: | |||||
return 0; | return 0; | ||||
} | } | ||||
size_t rfind(const char c) | |||||
size_t rfind(const char c) const | |||||
{ | { | ||||
size_t pos = 0; | size_t pos = 0; | ||||
for (size_t i=0; i < bufferLen; i++) | |||||
for (size_t i=0; i < bufferLen; ++i) | |||||
{ | { | ||||
if (buffer[i] == c) | if (buffer[i] == c) | ||||
pos = i; | pos = i; | ||||
@@ -216,7 +216,7 @@ public: | |||||
if (after == '\0') | if (after == '\0') | ||||
return; | return; | ||||
for (size_t i=0; i < bufferLen; i++) | |||||
for (size_t i=0; i < bufferLen; ++i) | |||||
{ | { | ||||
if (buffer[i] == before) | if (buffer[i] == before) | ||||
buffer[i] = after; | buffer[i] = after; | ||||
@@ -230,7 +230,7 @@ public: | |||||
if (n >= bufferLen) | if (n >= bufferLen) | ||||
return; | return; | ||||
for (size_t i=n; i < bufferLen; i++) | |||||
for (size_t i=n; i < bufferLen; ++i) | |||||
buffer[i] = '\0'; | buffer[i] = '\0'; | ||||
bufferLen = n; | bufferLen = n; | ||||
@@ -238,7 +238,7 @@ public: | |||||
void toBasic() | void toBasic() | ||||
{ | { | ||||
for (size_t i=0; i < bufferLen; 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; | ||||
@@ -257,7 +257,7 @@ public: | |||||
{ | { | ||||
static const char charDiff = 'a' - 'A'; | static const char charDiff = 'a' - 'A'; | ||||
for (size_t i=0; i < bufferLen; 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] += charDiff; | buffer[i] += charDiff; | ||||
@@ -268,7 +268,7 @@ public: | |||||
{ | { | ||||
static const char charDiff = 'a' - 'A'; | static const char charDiff = 'a' - 'A'; | ||||
for (size_t i=0; i < bufferLen; 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] -= charDiff; | buffer[i] -= charDiff; | ||||
@@ -1,6 +1,6 @@ | |||||
/* | /* | ||||
* Carla common utils | |||||
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||||
* Carla Thread | |||||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||||
* | * | ||||
* This program is free software; you can redistribute it and/or | * This program is free software; you can redistribute it and/or | ||||
* modify it under the terms of the GNU General Public License as | * modify it under the terms of the GNU General Public License as | ||||
@@ -175,7 +175,7 @@ public: | |||||
if (fStarted && ! fFinished) | if (fStarted && ! fFinished) | ||||
return true; | return true; | ||||
// take the change to clear data | |||||
// take the chance to clear data | |||||
#ifdef CPP11_THREAD | #ifdef CPP11_THREAD | ||||
if (cthread != nullptr) | if (cthread != nullptr) | ||||
{ | { | ||||
@@ -56,9 +56,13 @@ void carla_debug(const char* const fmt, ...) | |||||
{ | { | ||||
va_list args; | va_list args; | ||||
va_start(args, fmt); | va_start(args, fmt); | ||||
#ifndef CARLA_OS_WIN | |||||
std::fprintf(stdout, "\x1b[30;1m"); | std::fprintf(stdout, "\x1b[30;1m"); | ||||
#endif | |||||
std::vfprintf(stdout, fmt, args); | std::vfprintf(stdout, fmt, args); | ||||
#ifndef CARLA_OS_WIN | |||||
std::fprintf(stdout, "\x1b[0m\n"); | std::fprintf(stdout, "\x1b[0m\n"); | ||||
#endif | |||||
va_end(args); | va_end(args); | ||||
} | } | ||||
#endif | #endif | ||||
@@ -88,9 +92,13 @@ void carla_stderr2(const char* const fmt, ...) | |||||
{ | { | ||||
va_list args; | va_list args; | ||||
va_start(args, fmt); | va_start(args, fmt); | ||||
#ifndef CARLA_OS_WIN | |||||
std::fprintf(stderr, "\x1b[31m"); | std::fprintf(stderr, "\x1b[31m"); | ||||
#endif | |||||
std::vfprintf(stderr, fmt, args); | std::vfprintf(stderr, fmt, args); | ||||
#ifndef CARLA_OS_WIN | |||||
std::fprintf(stderr, "\x1b[0m\n"); | std::fprintf(stderr, "\x1b[0m\n"); | ||||
#endif | |||||
va_end(args); | va_end(args); | ||||
} | } | ||||
@@ -197,7 +205,7 @@ const char* carla_strdup(const char* const strBuf) | |||||
CARLA_ASSERT(strBuf != nullptr); | CARLA_ASSERT(strBuf != nullptr); | ||||
const size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0; | const size_t bufferLen = (strBuf != nullptr) ? std::strlen(strBuf) : 0; | ||||
char* const buffer = new char [bufferLen+1]; | |||||
char* const buffer = new char[bufferLen+1]; | |||||
std::strcpy(buffer, strBuf); | std::strcpy(buffer, strBuf); | ||||
@@ -253,7 +261,7 @@ void carla_copy(T* dataDst, T* dataSrc, const size_t size) | |||||
if (dataDst == nullptr || dataSrc == nullptr || size == 0) | if (dataDst == nullptr || dataSrc == nullptr || size == 0) | ||||
return; | return; | ||||
for (size_t i=0; i < size; i++) | |||||
for (size_t i=0; i < size; ++i) | |||||
*dataDst++ = *dataSrc++; | *dataDst++ = *dataSrc++; | ||||
} | } | ||||
@@ -268,7 +276,7 @@ void carla_copy(T* dataDst, const T* dataSrc, const size_t size) | |||||
if (dataDst == nullptr || dataSrc == nullptr || size == 0) | if (dataDst == nullptr || dataSrc == nullptr || size == 0) | ||||
return; | return; | ||||
for (size_t i=0; i < size; i++) | |||||
for (size_t i=0; i < size; ++i) | |||||
*dataDst++ = *dataSrc++; | *dataDst++ = *dataSrc++; | ||||
} | } | ||||
@@ -282,7 +290,7 @@ void carla_fill(T* data, const size_t size, const T v) | |||||
if (data == nullptr || size == 0) | if (data == nullptr || size == 0) | ||||
return; | return; | ||||
for (size_t i=0; i < size; i++) | |||||
for (size_t i=0; i < size; ++i) | |||||
*data++ = v; | *data++ = v; | ||||
} | } | ||||
@@ -346,6 +354,13 @@ void carla_zeroStruct(T& structure) | |||||
std::memset(&structure, 0, sizeof(T)); | std::memset(&structure, 0, sizeof(T)); | ||||
} | } | ||||
template <typename T> | |||||
static inline | |||||
void carla_zeroStruct(T& structure, const size_t count) | |||||
{ | |||||
std::memset(&structure, 0, sizeof(T)*count); | |||||
} | |||||
// ------------------------------------------------- | // ------------------------------------------------- | ||||
#endif // __CARLA_UTILS_HPP__ | #endif // __CARLA_UTILS_HPP__ |