@@ -60,7 +60,7 @@ const unsigned int PLUGIN_USES_SINGLE_THREAD = 0x0040; //!< Plugin needs a singl | |||
const unsigned int PLUGIN_CAN_DRYWET = 0x0100; //!< Plugin can make use of Dry/Wet controls. | |||
const unsigned int PLUGIN_CAN_VOLUME = 0x0200; //!< Plugin can make use of Volume controls. | |||
const unsigned int PLUGIN_CAN_BALANCE = 0x0400; //!< Plugin can make use of Left & Right Balance controls. | |||
const unsigned int PLUGIN_CAN_BALANCE = 0x0800; //!< Plugin can make use of Panning controls. | |||
const unsigned int PLUGIN_CAN_PANNING = 0x0800; //!< Plugin can make use of Panning controls. | |||
const unsigned int PLUGIN_CAN_FORCE_STEREO = 0x1000; //!< Plugin can be used in forced-stereo mode. | |||
/**@}*/ | |||
@@ -146,7 +146,7 @@ enum EngineControlEventType { | |||
*/ | |||
struct EngineControlEvent { | |||
EngineControlEventType type; //!< Control-Event type. | |||
uint16_t parameter; //!< Parameter ID, midi bank or midi program. | |||
uint16_t param; //!< Parameter ID, midi bank or midi program. | |||
double value; //!< Parameter value, normalized to 0.0<->1.0. | |||
EngineControlEvent() | |||
@@ -156,8 +156,8 @@ struct EngineControlEvent { | |||
void clear() | |||
{ | |||
type = kEngineControlEventTypeNull; | |||
parameter = 0; | |||
type = kEngineControlEventTypeNull; | |||
param = 0; | |||
value = 0.0; | |||
} | |||
}; | |||
@@ -213,6 +213,42 @@ struct EngineEvent { | |||
// ----------------------------------------------------------------------- | |||
/*! | |||
* Engine devices | |||
*/ | |||
struct EngineDevices { | |||
struct Audio { | |||
uint32_t count; | |||
int32_t current; | |||
const char** names; | |||
} audio; | |||
struct Midi { | |||
uint32_t count; | |||
const char** names; | |||
bool* selected; | |||
} midi; | |||
struct Info { | |||
unsigned int* bufferSizes; // valid until 0 value reached | |||
unsigned int* sampleRates; // valid until 0 value reached | |||
} info; | |||
EngineDevices() | |||
{ | |||
audio.count = 0; | |||
audio.current = -1; | |||
audio.names = nullptr; | |||
midi.count = 0; | |||
midi.names = nullptr; | |||
midi.selected = nullptr; | |||
info.bufferSizes = nullptr; | |||
info.sampleRates = nullptr; | |||
} | |||
}; | |||
/*! | |||
* Engine options. | |||
*/ | |||
@@ -226,10 +262,10 @@ struct EngineOptions { | |||
bool useDssiVstChunks; | |||
#endif | |||
uint maxParameters; | |||
uint oscUiTimeout; | |||
uint preferredBufferSize; | |||
uint preferredSampleRate; | |||
unsigned int maxParameters; | |||
unsigned int oscUiTimeout; | |||
unsigned int preferredBufferSize; | |||
unsigned int preferredSampleRate; | |||
#ifndef BUILD_BRIDGE | |||
CarlaString bridge_native; | |||
@@ -301,15 +337,14 @@ struct EngineTimeInfo { | |||
bool playing; | |||
uint32_t frame; | |||
uint32_t time; | |||
uint64_t time; | |||
uint32_t valid; | |||
EngineTimeInfoBBT bbt; | |||
EngineTimeInfo() | |||
: playing(false), | |||
frame(0), | |||
time(0), | |||
valid(0x0) {} | |||
{ | |||
clear(); | |||
} | |||
void clear() | |||
{ | |||
@@ -337,7 +372,7 @@ public: | |||
CarlaEnginePort(const bool isInput, const ProcessMode processMode); | |||
/*! | |||
* The decontructor. | |||
* The destructor. | |||
*/ | |||
virtual ~CarlaEnginePort(); | |||
@@ -374,7 +409,7 @@ public: | |||
CarlaEngineAudioPort(const bool isInput, const ProcessMode processMode); | |||
/*! | |||
* The decontructor. | |||
* The destructor. | |||
*/ | |||
virtual ~CarlaEngineAudioPort(); | |||
@@ -421,7 +456,7 @@ public: | |||
CarlaEngineEventPort(const bool isInput, const ProcessMode processMode); | |||
/*! | |||
* The decontructor. | |||
* The destructor. | |||
*/ | |||
virtual ~CarlaEngineEventPort(); | |||
@@ -446,23 +481,39 @@ public: | |||
/*! | |||
* Get the event at \a index. | |||
** \note You must only call this for input ports. | |||
* \note You must only call this for input ports. | |||
*/ | |||
virtual const EngineEvent* getEvent(const uint32_t index); | |||
virtual const EngineEvent& getEvent(const uint32_t index); | |||
/*! | |||
* Write a control event into the buffer.\n | |||
* Arguments are the same as in the EngineControlEvent struct. | |||
** \note You must only call this for output ports. | |||
* \note You must only call this for output ports. | |||
*/ | |||
virtual void writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t parameter, const double value = 0.0); | |||
virtual void writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const double value = 0.0); | |||
/*! | |||
* Write a control event into the buffer, overloaded call. | |||
*/ | |||
void writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) | |||
{ | |||
writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value); | |||
} | |||
/*! | |||
* Write a MIDI event into the buffer.\n | |||
* Arguments are the same as in the EngineMidiEvent struct. | |||
** \note You must only call this for output ports. | |||
*/ | |||
virtual void writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t* const data, const uint8_t size); | |||
virtual void writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t* const data, const uint8_t size); | |||
/*! | |||
* Write a MIDI event into the buffer, overloaded call. | |||
*/ | |||
void writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) | |||
{ | |||
writeMidiEvent(time, channel, midi.port, midi.data, midi.size); | |||
} | |||
private: | |||
const uint32_t kMaxEventCount; | |||
@@ -480,7 +531,7 @@ private: | |||
*/ | |||
class CarlaEngineClient | |||
{ | |||
protected: | |||
public: | |||
/*! | |||
* The constructor, protected.\n | |||
* All constructor parameters are constant and will never change in the lifetime of the client.\n | |||
@@ -488,7 +539,6 @@ protected: | |||
*/ | |||
CarlaEngineClient(const CarlaBackend::EngineType engineType, const CarlaBackend::ProcessMode processMode); | |||
public: | |||
/*! | |||
* The destructor. | |||
*/ | |||
@@ -532,23 +582,23 @@ public: | |||
* Add a new port of type \a portType. | |||
* \note This function does nothing in rack processing mode since ports are static there (2 audio + 1 event for both input and output). | |||
*/ | |||
virtual const CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) = 0; | |||
virtual const CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput); | |||
protected: | |||
const EngineType kEngineType; | |||
const ProcessMode kProcessMode; | |||
private: | |||
bool fActive; | |||
uint32_t fLatency; | |||
private: | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineClient) | |||
}; | |||
// ----------------------------------------------------------------------- | |||
/*! | |||
* Private data used in CarlaEngine. | |||
* Protected data used in CarlaEngine. | |||
* Non-engine code MUST NEVER have direct access to this. | |||
*/ | |||
struct CarlaEngineProtectedData; | |||
@@ -630,7 +680,7 @@ public: | |||
virtual bool close(); | |||
/*! | |||
* Idle. | |||
* Idle engine. | |||
*/ | |||
virtual void idle(); | |||
@@ -653,36 +703,18 @@ public: | |||
* Add new engine client. | |||
* \note This must only be called within a plugin class. | |||
*/ | |||
virtual CarlaEngineClient* addClient(CarlaPlugin* const plugin) = 0; | |||
virtual CarlaEngineClient* addClient(CarlaPlugin* const plugin); | |||
// ------------------------------------------------------------------- | |||
// Plugin management | |||
/*! | |||
* Get plugin with id \a id. | |||
*/ | |||
CarlaPlugin* getPlugin(const unsigned int id) const; | |||
/*! | |||
* Get plugin with id \a id, faster unchecked version. | |||
*/ | |||
CarlaPlugin* getPluginUnchecked(const unsigned int id) const; | |||
/*! | |||
* Get a unique plugin name within the engine.\n | |||
* Returned variable must NOT be free'd. | |||
*/ | |||
const char* getNewUniquePluginName(const char* const name); | |||
/*! | |||
* Add new plugin.\n | |||
* Returns the id of the plugin, or -1 if the operation failed. | |||
* Add new plugin. | |||
*/ | |||
bool addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, const void* const extra = nullptr); | |||
/*! | |||
* Add new plugin, using native binary type.\n | |||
* Returns the id of the plugin, or -1 if the operation failed. | |||
* Add new plugin, using native binary type. | |||
*/ | |||
bool addPlugin(const PluginType ptype, const char* const filename, const char* const name, const char* const label, const void* const extra = nullptr) | |||
{ | |||
@@ -699,6 +731,22 @@ public: | |||
*/ | |||
void removeAllPlugins(); | |||
/*! | |||
* Get plugin with id \a id. | |||
*/ | |||
CarlaPlugin* getPlugin(const unsigned int id) const; | |||
/*! | |||
* Get plugin with id \a id, faster unchecked version. | |||
*/ | |||
CarlaPlugin* getPluginUnchecked(const unsigned int id) const; | |||
/*! | |||
* Get a unique plugin name within the engine.\n | |||
* Returned variable must NOT be free'd. | |||
*/ | |||
const char* getNewUniquePluginName(const char* const name); | |||
// bridge, internal use only | |||
// TODO - find a better way for this | |||
//void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin); | |||
@@ -711,8 +759,7 @@ public: | |||
/*! | |||
* Load \a filename session. | |||
* \note Already loaded plugins are not removed, but added afterwards.\n | |||
* Call removeAllPlugins() first if needed. | |||
* \note Already loaded plugins are not removed; call removeAllPlugins() first if needed. | |||
*/ | |||
void loadProject(const char* const filename); | |||
@@ -769,6 +816,9 @@ public: | |||
return fTimeInfo; | |||
} | |||
// ------------------------------------------------------------------- | |||
// Information (peaks) | |||
/*! | |||
* TODO. | |||
*/ | |||
@@ -779,17 +829,6 @@ public: | |||
*/ | |||
float getOutputPeak(const unsigned int pluginId, const unsigned short id) const; | |||
/*! | |||
* Tell the engine it's about to close.\n | |||
* This is used to prevent the engine thread(s) from reactivating. | |||
*/ | |||
void setAboutToClose(); | |||
/*! | |||
* Safely block wait until the current proccessing callback ends. | |||
*/ | |||
void waitForProccessEnd(); | |||
// ------------------------------------------------------------------- | |||
// Callback | |||
@@ -816,6 +855,20 @@ public: | |||
*/ | |||
void setLastError(const char* const error); | |||
// ------------------------------------------------------------------- | |||
// Misc | |||
/*! | |||
* Tell the engine it's about to close.\n | |||
* This is used to prevent the engine thread(s) from reactivating. | |||
*/ | |||
void setAboutToClose(); | |||
/*! | |||
* Safely block wait until the current proccessing callback ends. | |||
*/ | |||
void waitForProccessEnd(); | |||
// ------------------------------------------------------------------- | |||
// Options | |||
@@ -879,7 +932,7 @@ protected: | |||
EngineOptions fOptions; | |||
EngineTimeInfo fTimeInfo; | |||
ScopedPointer<CarlaEngineProtectedData> const fData; | |||
CarlaEngineProtectedData* const fData; | |||
/*! | |||
* Report to all plugins about buffer size change. | |||
@@ -898,20 +951,19 @@ protected: | |||
*/ | |||
void proccessPendingEvents(); | |||
public: | |||
/*! | |||
* TODO. | |||
*/ | |||
void setPeaks(const unsigned int pluginId, float* inPeaks, float* outPeaks); | |||
#ifndef BUILD_BRIDGE | |||
// Rack mode data | |||
EngineEvent* getRackEventBuffer(const bool isInput); | |||
//static const unsigned short MAX_EVENTS = 1024; | |||
//EngineEvent fRackEventsIn[MAX_EVENTS]; | |||
//EngineEvent fRackEventsOut[MAX_EVENTS]; | |||
// Rack mode data | |||
EngineEvent* getRackEventBuffer(const bool isInput); | |||
/*! | |||
* Proccess audio buffer in rack mode. | |||
*/ | |||
@@ -48,38 +48,34 @@ CarlaEngineAudioPort::CarlaEngineAudioPort(const bool isInput, const ProcessMode | |||
{ | |||
qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY) | |||
fBuffer = new float[PATCHBAY_BUFFER_SIZE]; | |||
#endif | |||
} | |||
CarlaEngineAudioPort::~CarlaEngineAudioPort() | |||
{ | |||
qDebug("CarlaEngineAudioPort::~CarlaEngineAudioPort()"); | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY) | |||
{ | |||
CARLA_ASSERT(fBuffer); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
if (fBuffer) | |||
if (fBuffer != nullptr) | |||
delete[] fBuffer; | |||
} | |||
#endif | |||
} | |||
void CarlaEngineAudioPort::initBuffer(CarlaEngine* const) | |||
{ | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY && ! kIsInput) | |||
carla_zeroFloat(fBuffer, PATCHBAY_BUFFER_SIZE); | |||
#endif | |||
} | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// Carla Engine Event port | |||
static const EngineEvent kFallbackEngineEvent; | |||
CarlaEngineEventPort::CarlaEngineEventPort(const bool isInput, const ProcessMode processMode) | |||
: CarlaEnginePort(isInput, processMode), | |||
kMaxEventCount(processMode == PROCESS_MODE_CONTINUOUS_RACK ? RACK_EVENT_COUNT : PATCHBAY_EVENT_COUNT), | |||
@@ -87,25 +83,21 @@ CarlaEngineEventPort::CarlaEngineEventPort(const bool isInput, const ProcessMode | |||
{ | |||
qDebug("CarlaEngineEventPort::CarlaEngineEventPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY) | |||
fBuffer = new EngineEvent[PATCHBAY_EVENT_COUNT]; | |||
#endif | |||
} | |||
CarlaEngineEventPort::~CarlaEngineEventPort() | |||
{ | |||
qDebug("CarlaEngineEventPort::~CarlaEngineEventPort()"); | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_PATCHBAY) | |||
{ | |||
CARLA_ASSERT(fBuffer); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
if (fBuffer) | |||
if (fBuffer != nullptr) | |||
delete[] fBuffer; | |||
} | |||
#endif | |||
} | |||
void CarlaEngineEventPort::initBuffer(CarlaEngine* const engine) | |||
@@ -115,31 +107,28 @@ void CarlaEngineEventPort::initBuffer(CarlaEngine* const engine) | |||
if (engine == nullptr) | |||
return; | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK) | |||
fBuffer = engine->getRackEventBuffer(kIsInput); | |||
else if (kProcessMode == PROCESS_MODE_PATCHBAY && ! kIsInput) | |||
carla_zeroMem(fBuffer, sizeof(EngineEvent)*PATCHBAY_EVENT_COUNT); | |||
#endif | |||
} | |||
uint32_t CarlaEngineEventPort::getEventCount() | |||
{ | |||
if (! kIsInput) | |||
return 0; | |||
CARLA_ASSERT(kIsInput); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
if (! kIsInput) | |||
return 0; | |||
if (fBuffer == nullptr) | |||
return 0; | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY) | |||
{ | |||
uint32_t count = 0; | |||
const EngineEvent* const events = fBuffer; | |||
for (unsigned short i=0; i < kMaxEventCount; i++, count++) | |||
for (uint32_t i=0; i < kMaxEventCount; i++, count++) | |||
{ | |||
if (events[i].type == kEngineEventTypeNull) | |||
break; | |||
@@ -147,46 +136,43 @@ uint32_t CarlaEngineEventPort::getEventCount() | |||
return count; | |||
} | |||
#endif | |||
return 0; | |||
} | |||
const EngineEvent* CarlaEngineEventPort::getEvent(const uint32_t index) | |||
const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) | |||
{ | |||
if (! kIsInput) | |||
return nullptr; | |||
CARLA_ASSERT(kIsInput); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
CARLA_ASSERT(index < kMaxEventCount); | |||
if (! kIsInput) | |||
return kFallbackEngineEvent; | |||
if (fBuffer == nullptr) | |||
return nullptr; | |||
return kFallbackEngineEvent; | |||
if (index >= kMaxEventCount) | |||
return nullptr; | |||
return kFallbackEngineEvent; | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY) | |||
{ | |||
const EngineEvent* const events = fBuffer; | |||
return &events[index]; | |||
return events[index]; | |||
} | |||
#endif | |||
return nullptr; | |||
return kFallbackEngineEvent; | |||
} | |||
void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t parameter, const double value) | |||
void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const double value) | |||
{ | |||
if (kIsInput) | |||
return; | |||
CARLA_ASSERT(! kIsInput); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
CARLA_ASSERT(type != kEngineControlEventTypeNull); | |||
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | |||
CARLA_ASSERT(value >= 0.0 && value <= 1.0); | |||
if (kIsInput) | |||
return; | |||
if (fBuffer == nullptr) | |||
return; | |||
if (type == kEngineControlEventTypeNull) | |||
@@ -195,15 +181,14 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||
return; | |||
if (type == kEngineControlEventTypeParameter) | |||
{ | |||
CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter)); | |||
CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param)); | |||
} | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY) | |||
{ | |||
EngineEvent* const events = fBuffer; | |||
for (unsigned short i=0; i < kMaxEventCount; i++) | |||
for (uint32_t i=0; i < kMaxEventCount; i++) | |||
{ | |||
if (events[i].type != kEngineEventTypeNull) | |||
continue; | |||
@@ -212,32 +197,27 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t | |||
events[i].time = time; | |||
events[i].channel = channel; | |||
events[i].ctrl.type = type; | |||
events[i].ctrl.parameter = parameter; | |||
events[i].ctrl.value = value; | |||
events[i].ctrl.type = type; | |||
events[i].ctrl.param = param; | |||
events[i].ctrl.value = value; | |||
return; | |||
} | |||
qWarning("CarlaEngineEventPort::writeControlEvent() - buffer full"); | |||
} | |||
#else | |||
Q_UNUSED(time); | |||
Q_UNUSED(parameter); | |||
Q_UNUSED(value); | |||
#endif | |||
} | |||
void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t* const data, const uint8_t size) | |||
void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t* const data, const uint8_t size) | |||
{ | |||
if (kIsInput) | |||
return; | |||
CARLA_ASSERT(! kIsInput); | |||
CARLA_ASSERT(fBuffer != nullptr); | |||
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | |||
CARLA_ASSERT(data != nullptr); | |||
CARLA_ASSERT(size > 0); | |||
if (kIsInput) | |||
return; | |||
if (fBuffer == nullptr) | |||
return; | |||
if (channel >= MAX_MIDI_CHANNELS) | |||
@@ -247,7 +227,6 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||
if (size == 0) | |||
return; | |||
#ifndef BUILD_BRIDGE | |||
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY) | |||
{ | |||
if (size > 3) | |||
@@ -255,7 +234,7 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||
EngineEvent* const events = fBuffer; | |||
for (unsigned short i=0; i < kMaxEventCount; i++) | |||
for (uint32_t i=0; i < kMaxEventCount; i++) | |||
{ | |||
if (events[i].type != kEngineEventTypeNull) | |||
continue; | |||
@@ -264,6 +243,7 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||
events[i].time = time; | |||
events[i].channel = channel; | |||
events[i].midi.port = port; | |||
events[i].midi.data[0] = data[0]; | |||
events[i].midi.data[1] = data[1]; | |||
events[i].midi.data[2] = data[2]; | |||
@@ -274,9 +254,6 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha | |||
qWarning("CarlaEngineEventPort::writeMidiEvent() - buffer full"); | |||
} | |||
#else | |||
Q_UNUSED(time); | |||
#endif | |||
} | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
@@ -338,6 +315,24 @@ void CarlaEngineClient::setLatency(const uint32_t samples) | |||
fLatency = samples; | |||
} | |||
const CarlaEnginePort* CarlaEngineClient::addPort(const EnginePortType portType, const char* const name, const bool isInput) | |||
{ | |||
qDebug("CarlaEngineClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
switch (portType) | |||
{ | |||
case kEnginePortTypeNull: | |||
break; | |||
case kEnginePortTypeAudio: | |||
return new CarlaEngineAudioPort(isInput, kProcessMode); | |||
case kEnginePortTypeEvent: | |||
return new CarlaEngineEventPort(isInput, kProcessMode); | |||
} | |||
qCritical("CarlaEngineClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
return nullptr; | |||
} | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// Carla Engine | |||
@@ -353,7 +348,7 @@ CarlaEngine::~CarlaEngine() | |||
{ | |||
qDebug("CarlaEngine::~CarlaEngine()"); | |||
//data = nullptr; | |||
delete fData; | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -610,102 +605,15 @@ void CarlaEngine::idle() | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Plugin management | |||
CarlaPlugin* CarlaEngine::getPlugin(const unsigned int id) const | |||
{ | |||
qDebug("CarlaEngine::getPlugin(%i) [count:%i]", id, fData->curPluginCount); | |||
CARLA_ASSERT(fData->curPluginCount > 0); | |||
CARLA_ASSERT(id < fData->curPluginCount); | |||
CARLA_ASSERT(fData->plugins != nullptr); | |||
if (id < fData->curPluginCount && fData->plugins != nullptr) | |||
return fData->plugins[id].plugin; | |||
return nullptr; | |||
} | |||
// Virtual, per-engine type calls | |||
CarlaPlugin* CarlaEngine::getPluginUnchecked(const unsigned int id) const | |||
CarlaEngineClient* CarlaEngine::addClient(CarlaPlugin* const) | |||
{ | |||
return fData->plugins[id].plugin; | |||
return new CarlaEngineClient(type(), fOptions.processMode); | |||
} | |||
const char* CarlaEngine::getNewUniquePluginName(const char* const name) | |||
{ | |||
qDebug("CarlaEngine::getNewUniquePluginName(\"%s\")", name); | |||
CARLA_ASSERT(fData->maxPluginNumber > 0); | |||
CARLA_ASSERT(fData->plugins != nullptr); | |||
CARLA_ASSERT(name != nullptr); | |||
static CarlaString sname; | |||
sname = name; | |||
if (sname.isEmpty() || fData->plugins == nullptr) | |||
return strdup("(No name)"); | |||
sname.truncate(maxClientNameSize()-5-1); // 5 = strlen(" (10)") | |||
sname.replace(':', '.'); // ':' is used in JACK1 to split client/port names | |||
for (unsigned short i=0; i < fData->curPluginCount; i++) | |||
{ | |||
CARLA_ASSERT(fData->plugins[i].plugin); | |||
// Check if unique name doesn't exist | |||
if (const char* const pluginName = fData->plugins[i].plugin->name()) | |||
{ | |||
if (sname != pluginName) | |||
continue; | |||
} | |||
// Check if string has already been modified | |||
{ | |||
const size_t len = sname.length(); | |||
// 1 digit, ex: " (2)" | |||
if (sname[len-4] == ' ' && sname[len-3] == '(' && sname.isDigit(len-2) && sname[len-1] == ')') | |||
{ | |||
int number = sname[len-2] - '0'; | |||
if (number == 9) | |||
{ | |||
// next number is 10, 2 digits | |||
sname.truncate(len-4); | |||
sname += " (10)"; | |||
//sname.replace(" (9)", " (10)"); | |||
} | |||
else | |||
sname[len-2] = char('0' + number + 1); | |||
continue; | |||
} | |||
// 2 digits, ex: " (11)" | |||
if (sname[len-5] == ' ' && sname[len-4] == '(' && sname.isDigit(len-3) && sname.isDigit(len-2) && sname[len-1] == ')') | |||
{ | |||
char n2 = sname[len-2]; | |||
char n3 = sname[len-3]; | |||
if (n2 == '9') | |||
{ | |||
n2 = '0'; | |||
n3 = char(n3 + 1); | |||
} | |||
else | |||
n2 = char(n2 + 1); | |||
sname[len-2] = n2; | |||
sname[len-3] = n3; | |||
continue; | |||
} | |||
} | |||
// Modify string if not | |||
sname += " (2)"; | |||
} | |||
return (const char*)sname; | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Plugin management | |||
bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, const char* const filename, const char* const name, const char* const label, const void* const extra) | |||
{ | |||
@@ -938,6 +846,101 @@ void CarlaEngine::removeAllPlugins() | |||
fData->thread.startNow(); | |||
} | |||
CarlaPlugin* CarlaEngine::getPlugin(const unsigned int id) const | |||
{ | |||
qDebug("CarlaEngine::getPlugin(%i) [count:%i]", id, fData->curPluginCount); | |||
CARLA_ASSERT(fData->curPluginCount > 0); | |||
CARLA_ASSERT(id < fData->curPluginCount); | |||
CARLA_ASSERT(fData->plugins != nullptr); | |||
if (id < fData->curPluginCount && fData->plugins != nullptr) | |||
return fData->plugins[id].plugin; | |||
return nullptr; | |||
} | |||
CarlaPlugin* CarlaEngine::getPluginUnchecked(const unsigned int id) const | |||
{ | |||
return fData->plugins[id].plugin; | |||
} | |||
const char* CarlaEngine::getNewUniquePluginName(const char* const name) | |||
{ | |||
qDebug("CarlaEngine::getNewUniquePluginName(\"%s\")", name); | |||
CARLA_ASSERT(fData->maxPluginNumber > 0); | |||
CARLA_ASSERT(fData->plugins != nullptr); | |||
CARLA_ASSERT(name != nullptr); | |||
static CarlaString sname; | |||
sname = name; | |||
if (sname.isEmpty() || fData->plugins == nullptr) | |||
return strdup("(No name)"); | |||
sname.truncate(maxClientNameSize()-5-1); // 5 = strlen(" (10)") | |||
sname.replace(':', '.'); // ':' is used in JACK1 to split client/port names | |||
for (unsigned short i=0; i < fData->curPluginCount; i++) | |||
{ | |||
CARLA_ASSERT(fData->plugins[i].plugin); | |||
// Check if unique name doesn't exist | |||
if (const char* const pluginName = fData->plugins[i].plugin->name()) | |||
{ | |||
if (sname != pluginName) | |||
continue; | |||
} | |||
// Check if string has already been modified | |||
{ | |||
const size_t len = sname.length(); | |||
// 1 digit, ex: " (2)" | |||
if (sname[len-4] == ' ' && sname[len-3] == '(' && sname.isDigit(len-2) && sname[len-1] == ')') | |||
{ | |||
int number = sname[len-2] - '0'; | |||
if (number == 9) | |||
{ | |||
// next number is 10, 2 digits | |||
sname.truncate(len-4); | |||
sname += " (10)"; | |||
//sname.replace(" (9)", " (10)"); | |||
} | |||
else | |||
sname[len-2] = char('0' + number + 1); | |||
continue; | |||
} | |||
// 2 digits, ex: " (11)" | |||
if (sname[len-5] == ' ' && sname[len-4] == '(' && sname.isDigit(len-3) && sname.isDigit(len-2) && sname[len-1] == ')') | |||
{ | |||
char n2 = sname[len-2]; | |||
char n3 = sname[len-3]; | |||
if (n2 == '9') | |||
{ | |||
n2 = '0'; | |||
n3 = char(n3 + 1); | |||
} | |||
else | |||
n2 = char(n2 + 1); | |||
sname[len-2] = n2; | |||
sname[len-3] = n3; | |||
continue; | |||
} | |||
} | |||
// Modify string if not | |||
sname += " (2)"; | |||
} | |||
return (const char*)sname; | |||
} | |||
#if 0 | |||
void CarlaEngine::__bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin) | |||
{ | |||
@@ -989,7 +992,7 @@ void CarlaEngine::saveProject(const char* const filename) | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Information (base) | |||
// Information (peaks) | |||
float CarlaEngine::getInputPeak(const unsigned int pluginId, const unsigned short id) const | |||
{ | |||
@@ -1007,34 +1010,6 @@ float CarlaEngine::getOutputPeak(const unsigned int pluginId, const unsigned sho | |||
return fData->plugins[pluginId].outsPeak[id]; | |||
} | |||
void CarlaEngine::setAboutToClose() | |||
{ | |||
qDebug("CarlaEngine::setAboutToClose()"); | |||
fData->aboutToClose = true; | |||
} | |||
void CarlaEngine::waitForProccessEnd() | |||
{ | |||
qDebug("CarlaEngine::waitForProccessEnd()"); | |||
fData->nextAction.pluginId = 0; | |||
fData->nextAction.opcode = EnginePostActionIdle; | |||
fData->nextAction.mutex.lock(); | |||
if (isRunning()) | |||
{ | |||
// block wait for unlock on proccessing side | |||
fData->nextAction.mutex.lock(); | |||
} | |||
else | |||
{ | |||
doIdle(fData, false); | |||
} | |||
fData->nextAction.mutex.unlock(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Callback | |||
@@ -1068,6 +1043,37 @@ void CarlaEngine::setLastError(const char* const error) | |||
fData->lastError = error; | |||
} | |||
void CarlaEngine::setAboutToClose() | |||
{ | |||
qDebug("CarlaEngine::setAboutToClose()"); | |||
fData->aboutToClose = true; | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Misc | |||
void CarlaEngine::waitForProccessEnd() | |||
{ | |||
qDebug("CarlaEngine::waitForProccessEnd()"); | |||
fData->nextAction.pluginId = 0; | |||
fData->nextAction.opcode = EnginePostActionIdle; | |||
fData->nextAction.mutex.lock(); | |||
if (isRunning()) | |||
{ | |||
// block wait for unlock on proccessing side | |||
fData->nextAction.mutex.lock(); | |||
} | |||
else | |||
{ | |||
doIdle(fData, false); | |||
} | |||
fData->nextAction.mutex.unlock(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
// Global options | |||
@@ -1433,7 +1439,6 @@ void CarlaEngine::osc_send_peaks(CarlaPlugin* const /*plugin*/) | |||
void CarlaEngine::osc_send_peaks(CarlaPlugin* const plugin, const unsigned short& id) | |||
#endif | |||
{ | |||
#if 0 | |||
// Peak values | |||
if (plugin->audioInCount() > 0) | |||
{ | |||
@@ -1455,7 +1460,6 @@ void CarlaEngine::osc_send_peaks(CarlaPlugin* const plugin, const unsigned short | |||
osc_send_control_set_output_peak_value(id, 2); | |||
#endif | |||
} | |||
#endif | |||
} | |||
#ifndef BUILD_BRIDGE | |||
@@ -1772,7 +1776,6 @@ void CarlaEngine::osc_send_control_note_off(const int32_t pluginId, const int32_ | |||
} | |||
} | |||
#if 0 | |||
void CarlaEngine::osc_send_control_set_input_peak_value(const int32_t pluginId, const int32_t portId) | |||
{ | |||
//qDebug("CarlaEngine::osc_send_control_set_input_peak_value(%i, %i)", pluginId, portId); | |||
@@ -1785,7 +1788,7 @@ void CarlaEngine::osc_send_control_set_input_peak_value(const int32_t pluginId, | |||
char target_path[strlen(fData->oscData->path)+22]; | |||
strcpy(target_path, fData->oscData->path); | |||
strcat(target_path, "/set_input_peak_value"); | |||
lo_send(fData->oscData->target, target_path, "iid", pluginId, portId, data->insPeak[pluginId*MAX_PEAKS + portId-1]); | |||
lo_send(fData->oscData->target, target_path, "iid", pluginId, portId, fData->plugins[pluginId].insPeak[portId-1]); | |||
} | |||
} | |||
@@ -1801,10 +1804,9 @@ void CarlaEngine::osc_send_control_set_output_peak_value(const int32_t pluginId, | |||
char target_path[strlen(fData->oscData->path)+23]; | |||
strcpy(target_path, fData->oscData->path); | |||
strcat(target_path, "/set_output_peak_value"); | |||
lo_send(fData->oscData->target, target_path, "iid", pluginId, portId, data->outsPeak[pluginId*MAX_PEAKS + portId-1]); | |||
lo_send(fData->oscData->target, target_path, "iid", pluginId, portId, fData->plugins[pluginId].outsPeak[portId-1]); | |||
} | |||
} | |||
#endif | |||
void CarlaEngine::osc_send_control_exit() | |||
{ | |||
@@ -86,6 +86,8 @@ private: | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// Carla Engine JACK-Event port | |||
static const EngineEvent kFallbackJackEngineEvent; | |||
class CarlaEngineJackEventPort : public CarlaEngineEventPort | |||
{ | |||
public: | |||
@@ -139,34 +141,34 @@ public: | |||
if (kPort == nullptr) | |||
return CarlaEngineEventPort::getEventCount(); | |||
if (! kIsInput) | |||
return 0; | |||
CARLA_ASSERT(kIsInput); | |||
CARLA_ASSERT(fJackBuffer != nullptr); | |||
if (! kIsInput) | |||
return 0; | |||
if (fJackBuffer != nullptr) | |||
return 0; | |||
return jackbridge_midi_get_event_count(fJackBuffer); | |||
} | |||
const EngineEvent* getEvent(const uint32_t index) | |||
const EngineEvent& getEvent(const uint32_t index) | |||
{ | |||
if (kPort == nullptr) | |||
return CarlaEngineEventPort::getEvent(index); | |||
if (! kIsInput) | |||
return nullptr; | |||
CARLA_ASSERT(kIsInput); | |||
CARLA_ASSERT(fJackBuffer != nullptr); | |||
if (fJackBuffer != nullptr) | |||
return nullptr; | |||
if (! kIsInput) | |||
return kFallbackJackEngineEvent; | |||
if (fJackBuffer == nullptr) | |||
return kFallbackJackEngineEvent; | |||
jack_midi_event_t jackEvent; | |||
if (jackbridge_midi_event_get(&jackEvent, fJackBuffer, index) != 0 || jackEvent.size > 3) | |||
return nullptr; | |||
return kFallbackJackEngineEvent; | |||
fRetEvent.clear(); | |||
@@ -179,45 +181,45 @@ public: | |||
if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus)) | |||
{ | |||
const uint8_t midiControl = jackEvent.buffer[1]; | |||
fRetEvent.type = kEngineEventTypeControl; | |||
fRetEvent.type = kEngineEventTypeControl; | |||
if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) | |||
{ | |||
const uint8_t midiBank = jackEvent.buffer[2]; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeMidiBank; | |||
fRetEvent.ctrl.parameter = midiBank; | |||
fRetEvent.ctrl.value = 0.0; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeMidiBank; | |||
fRetEvent.ctrl.param = midiBank; | |||
fRetEvent.ctrl.value = 0.0; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) | |||
{ | |||
fRetEvent.ctrl.type = kEngineControlEventTypeAllSoundOff; | |||
fRetEvent.ctrl.parameter = 0; | |||
fRetEvent.ctrl.value = 0.0; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeAllSoundOff; | |||
fRetEvent.ctrl.param = 0; | |||
fRetEvent.ctrl.value = 0.0; | |||
} | |||
else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) | |||
{ | |||
fRetEvent.ctrl.type = kEngineControlEventTypeAllNotesOff; | |||
fRetEvent.ctrl.parameter = 0; | |||
fRetEvent.ctrl.value = 0.0; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeAllNotesOff; | |||
fRetEvent.ctrl.param = 0; | |||
fRetEvent.ctrl.value = 0.0; | |||
} | |||
else | |||
{ | |||
const uint8_t midiValue = jackEvent.buffer[2]; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeParameter; | |||
fRetEvent.ctrl.parameter = midiControl; | |||
fRetEvent.ctrl.value = double(midiValue)/127; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeParameter; | |||
fRetEvent.ctrl.param = midiControl; | |||
fRetEvent.ctrl.value = double(midiValue)/127.0; | |||
} | |||
} | |||
else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus)) | |||
{ | |||
const uint8_t midiProgram = jackEvent.buffer[1]; | |||
fRetEvent.type = kEngineEventTypeControl; | |||
fRetEvent.type = kEngineEventTypeControl; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeMidiProgram; | |||
fRetEvent.ctrl.parameter = midiProgram; | |||
fRetEvent.ctrl.value = 0.0; | |||
fRetEvent.ctrl.type = kEngineControlEventTypeMidiProgram; | |||
fRetEvent.ctrl.param = midiProgram; | |||
fRetEvent.ctrl.value = 0.0; | |||
} | |||
else | |||
{ | |||
@@ -229,22 +231,22 @@ public: | |||
fRetEvent.midi.size = jackEvent.size; | |||
} | |||
return &fRetEvent; | |||
return fRetEvent; | |||
} | |||
void writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t parameter, const double value) | |||
void writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const double value) | |||
{ | |||
if (kPort == nullptr) | |||
return CarlaEngineEventPort::writeControlEvent(time, channel, type, parameter, value); | |||
if (kIsInput) | |||
return; | |||
return CarlaEngineEventPort::writeControlEvent(time, channel, type, param, value); | |||
CARLA_ASSERT(! kIsInput); | |||
CARLA_ASSERT(fJackBuffer != nullptr); | |||
CARLA_ASSERT(type != kEngineControlEventTypeNull); | |||
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | |||
CARLA_ASSERT(value >= 0.0 && value <= 1.0); | |||
if (kIsInput) | |||
return; | |||
if (fJackBuffer == nullptr) | |||
return; | |||
if (type == kEngineControlEventTypeNull) | |||
@@ -253,7 +255,7 @@ public: | |||
return; | |||
if (type == kEngineControlEventTypeParameter) | |||
{ | |||
CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter)); | |||
CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param)); | |||
} | |||
uint8_t data[3] = { 0 }; | |||
@@ -265,19 +267,19 @@ public: | |||
break; | |||
case kEngineControlEventTypeParameter: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | |||
data[1] = parameter; | |||
data[1] = param; | |||
data[2] = value * 127; | |||
size = 3; | |||
break; | |||
case kEngineControlEventTypeMidiBank: | |||
data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; | |||
data[1] = MIDI_CONTROL_BANK_SELECT; | |||
data[2] = value; | |||
size = 3; | |||
data[2] = param; | |||
size = 3; | |||
break; | |||
case kEngineControlEventTypeMidiProgram: | |||
data[0] = MIDI_STATUS_PROGRAM_CHANGE + channel; | |||
data[1] = value; | |||
data[1] = param; | |||
size = 2; | |||
break; | |||
case kEngineControlEventTypeAllSoundOff: | |||
@@ -296,24 +298,26 @@ public: | |||
jackbridge_midi_event_write(fJackBuffer, time, data, size); | |||
} | |||
void writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t* const data, const uint8_t size) | |||
void writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t* const data, const uint8_t size) | |||
{ | |||
if (kPort == nullptr) | |||
return CarlaEngineEventPort::writeMidiEvent(time, channel, data, size); | |||
if (kIsInput) | |||
return; | |||
return CarlaEngineEventPort::writeMidiEvent(time, channel, port, data, size); | |||
CARLA_ASSERT(! kIsInput); | |||
CARLA_ASSERT(fJackBuffer != nullptr); | |||
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | |||
CARLA_ASSERT(data); | |||
CARLA_ASSERT(data != nullptr); | |||
CARLA_ASSERT(size > 0); | |||
if (kIsInput) | |||
return; | |||
if (fJackBuffer == nullptr) | |||
return; | |||
if (channel >= MAX_MIDI_CHANNELS) | |||
return; | |||
if (! (data && size > 0)) | |||
if (data == nullptr) | |||
return; | |||
if (size == 0) | |||
return; | |||
uint8_t jdata[size]; | |||
@@ -370,13 +374,13 @@ public: | |||
void activate() | |||
{ | |||
qDebug("CarlaEngineClient::activate()"); | |||
qDebug("CarlaEngineJackClient::activate()"); | |||
if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
{ | |||
CARLA_ASSERT(kClient && ! isActive()); | |||
CARLA_ASSERT(kClient && ! fActive); | |||
if (kClient && ! isActive()) | |||
if (kClient && ! fActive) | |||
jackbridge_activate(kClient); | |||
} | |||
@@ -385,13 +389,13 @@ public: | |||
void deactivate() | |||
{ | |||
qDebug("CarlaEngineClient::deactivate()"); | |||
qDebug("CarlaEngineJackClient::deactivate()"); | |||
if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) | |||
{ | |||
CARLA_ASSERT(kClient && isActive()); | |||
CARLA_ASSERT(kClient && fActive); | |||
if (kClient && isActive()) | |||
if (kClient && fActive) | |||
jackbridge_deactivate(kClient); | |||
} | |||
@@ -400,7 +404,7 @@ public: | |||
bool isOk() const | |||
{ | |||
qDebug("CarlaEngineClient::isOk()"); | |||
qDebug("CarlaEngineJackClient::isOk()"); | |||
if (kUseClient) | |||
return bool(kClient); | |||
@@ -418,11 +422,11 @@ public: | |||
const CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) | |||
{ | |||
qDebug("CarlaJackEngineClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
qDebug("CarlaEngineJackClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
jack_port_t* port = nullptr; | |||
// Create Jack port if needed | |||
// Create JACK port first, if needed | |||
if (kUseClient) | |||
{ | |||
switch (portType) | |||
@@ -449,7 +453,7 @@ public: | |||
return new CarlaEngineJackEventPort(isInput, kProcessMode, kClient, port); | |||
} | |||
qCritical("CarlaJackEngineClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
qCritical("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
return nullptr; | |||
} | |||
@@ -1047,7 +1051,7 @@ private: | |||
} | |||
} | |||
if (CarlaEngine* const engine = p->getEngine()) | |||
if (CarlaEngineJack* const engine = (CarlaEngineJack*)p->getEngine()) | |||
engine->setPeaks(p->id(), inPeaks, outPeaks); | |||
} | |||
@@ -42,40 +42,6 @@ static const unsigned int paramPan = 8; | |||
static const unsigned int paramCount = sizeof(paramMap); | |||
static const unsigned int programCount = 128; | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// Plugin Engine client | |||
class CarlaEnginePluginClient : public CarlaEngineClient | |||
{ | |||
public: | |||
CarlaEnginePluginClient(const EngineType engineType, const ProcessMode processMode) | |||
: CarlaEngineClient(engineType, processMode) | |||
{ | |||
} | |||
~CarlaEnginePluginClient() | |||
{ | |||
} | |||
const CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) | |||
{ | |||
qDebug("CarlaEnginePluginClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
switch (portType) | |||
{ | |||
case kEnginePortTypeNull: | |||
break; | |||
case kEnginePortTypeAudio: | |||
return new CarlaEngineAudioPort(isInput, kProcessMode); | |||
case kEnginePortTypeEvent: | |||
return new CarlaEngineEventPort(isInput, kProcessMode); | |||
} | |||
qCritical("CarlaEnginePluginClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
return nullptr; | |||
} | |||
}; | |||
// ----------------------------------------- | |||
class CarlaEnginePlugin : public CarlaEngine, | |||
@@ -163,11 +129,6 @@ public: | |||
return kEngineTypeRtAudio; | |||
} | |||
CarlaEngineClient* addClient(CarlaPlugin* const) | |||
{ | |||
return new CarlaEnginePluginClient(kEngineTypePlugin, fOptions.processMode); | |||
} | |||
protected: | |||
// --------------------------------------------- | |||
// DISTRHO Plugin Information | |||
@@ -30,45 +30,6 @@ CARLA_BACKEND_START_NAMESPACE | |||
} // Fix editor indentation | |||
#endif | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// RtAudio Engine client | |||
class CarlaEngineRtAudioClient : public CarlaEngineClient | |||
{ | |||
public: | |||
CarlaEngineRtAudioClient(const EngineType engineType, const ProcessMode processMode) | |||
: CarlaEngineClient(engineType, processMode) | |||
{ | |||
qDebug("CarlaEngineRtAudioClient::CarlaEngineRtAudioClient(%s, %s)", EngineType2Str(engineType), ProcessMode2Str(processMode)); | |||
} | |||
~CarlaEngineRtAudioClient() | |||
{ | |||
qDebug("CarlaEngineRtAudioClient::~CarlaEngineRtAudioClient()"); | |||
} | |||
const CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) | |||
{ | |||
qDebug("CarlaEngineRtAudioClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
switch (portType) | |||
{ | |||
case kEnginePortTypeNull: | |||
break; | |||
case kEnginePortTypeAudio: | |||
return new CarlaEngineAudioPort(isInput, kProcessMode); | |||
case kEnginePortTypeEvent: | |||
return new CarlaEngineEventPort(isInput, kProcessMode); | |||
} | |||
qCritical("CarlaEngineRtAudioClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput)); | |||
return nullptr; | |||
} | |||
private: | |||
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineRtAudioClient) | |||
}; | |||
// ------------------------------------------------------------------------------------------------------------------- | |||
// RtAudio Engine | |||
@@ -248,11 +209,6 @@ public: | |||
return kEngineTypeRtAudio; | |||
} | |||
CarlaEngineClient* addClient(CarlaPlugin* const) | |||
{ | |||
return new CarlaEngineRtAudioClient(kEngineTypeRtAudio, fOptions.processMode); | |||
} | |||
// ------------------------------------- | |||
protected: | |||
@@ -1,9 +1,7 @@ | |||
# QtCreator project file | |||
QT = core gui | |||
CONFIG = debug | |||
CONFIG += link_pkgconfig qt shared warn_on | |||
CONFIG += link_pkgconfig shared warn_on | |||
DEFINES = DEBUG | |||
DEFINES += QTCREATOR_TEST | |||
@@ -27,7 +25,7 @@ TARGET = carla_plugin | |||
TEMPLATE = lib | |||
VERSION = 0.5.0 | |||
SOURCES = \ | |||
SOURCES = \ | |||
carla_plugin.cpp \ | |||
carla_plugin_thread.cpp \ | |||
carla_bridge.cpp \ | |||
@@ -39,7 +37,7 @@ SOURCES = \ | |||
fluidsynth.cpp \ | |||
linuxsampler.cpp | |||
HEADERS = \ | |||
HEADERS = \ | |||
carla_plugin_internal.hpp \ | |||
carla_plugin_thread.hpp | |||
@@ -47,6 +45,7 @@ HEADERS += \ | |||
../carla_backend.hpp \ | |||
../carla_engine.hpp \ | |||
../carla_native.h \ | |||
../carla_native.hpp \ | |||
../carla_plugin.hpp | |||
INCLUDEPATH = . .. \ | |||
@@ -54,8 +53,24 @@ INCLUDEPATH = . .. \ | |||
../../libs \ | |||
../../utils | |||
# FIXME | |||
# --------------------------------------------------------------------------------------- | |||
PKGCONFIG += QtCore QtGui | |||
# Fake includes | |||
INCLUDEPATH += \ | |||
/opt/kxstudio/include | |||
/usr/include/qt4/ \ | |||
/opt/kxstudio/include/ | |||
# System includes | |||
QMAKE_CXXFLAGS += -isystem /usr/include/qt4/ | |||
QMAKE_CXXFLAGS += -isystem /opt/kxstudio/include/ | |||
WARN_FLAGS = \ | |||
-ansi -pedantic -pedantic-errors -Wall -Wextra -Wformat=2 -Wunused-parameter -Wuninitialized \ | |||
-Wcast-qual -Wconversion -Wsign-conversion -Wlogical-op -Waggregate-return -Wno-vla \ | |||
-fipa-pure-const -Wsuggest-attribute=const #pure,const,noreturn | |||
QMAKE_CXXFLAGS *= -std=c++0x | |||
QMAKE_CFLAGS += $${WARN_FLAGS} -std=c99 -Wc++-compat -Wunsuffixed-float-constants -Wwrite-strings | |||
# QMAKE_CXXFLAGS += $${WARN_FLAGS} -std=c++0x -fPIC | |||
QMAKE_CXXFLAGS += $${WARN_FLAGS} -std=c++11 -Wzero-as-null-pointer-constant |
@@ -1595,7 +1595,7 @@ private: | |||
CARLA_BACKEND_END_NAMESPACE | |||
#else // WANT_DSSI | |||
# warning Building without DSSI support | |||
//# warning Building without DSSI support | |||
#endif | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -1318,7 +1318,7 @@ private: | |||
CARLA_BACKEND_END_NAMESPACE | |||
#else // WANT_FLUIDSYNTH | |||
# warning fluidsynth not available (no SF2 support) | |||
//# warning fluidsynth not available (no SF2 support) | |||
#endif | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -768,30 +768,26 @@ public: | |||
if (fData->event.portIn != nullptr && fData->activeBefore) | |||
{ | |||
const EngineEvent* event = nullptr; | |||
uint32_t time, nEvents = fData->event.portIn->getEventCount(); | |||
for (i=0; i < nEvents; i++) | |||
{ | |||
event = fData->event.portIn->getEvent(i); | |||
const EngineEvent& event = fData->event.portIn->getEvent(i); | |||
if (event == nullptr) | |||
continue; | |||
time = event->time - framesOffset; | |||
time = event.time - framesOffset; | |||
if (time >= frames) | |||
continue; | |||
// Control change | |||
switch (event->type) | |||
switch (event.type) | |||
{ | |||
case kEngineEventTypeNull: | |||
break; | |||
case kEngineEventTypeControl: | |||
{ | |||
const EngineControlEvent& ctrlEvent = event->ctrl; | |||
const EngineControlEvent& ctrlEvent = event.ctrl; | |||
switch (ctrlEvent.type) | |||
{ | |||
@@ -801,11 +797,11 @@ public: | |||
case kEngineControlEventTypeParameter: | |||
{ | |||
// Control backend stuff | |||
if (event->channel == fData->ctrlInChannel) | |||
if (event.channel == fData->ctrlInChannel) | |||
{ | |||
double value; | |||
if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.parameter) && (fData->hints & PLUGIN_CAN_DRYWET) > 0) | |||
if (MIDI_IS_CONTROL_BREATH_CONTROLLER(ctrlEvent.param) && (fData->hints & PLUGIN_CAN_DRYWET) > 0) | |||
{ | |||
value = ctrlEvent.value; | |||
setDryWet(value, false, false); | |||
@@ -813,7 +809,7 @@ public: | |||
continue; | |||
} | |||
if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.parameter) && (fData->hints & PLUGIN_CAN_VOLUME) > 0) | |||
if (MIDI_IS_CONTROL_CHANNEL_VOLUME(ctrlEvent.param) && (fData->hints & PLUGIN_CAN_VOLUME) > 0) | |||
{ | |||
value = ctrlEvent.value*127/100; | |||
setVolume(value, false, false); | |||
@@ -821,7 +817,7 @@ public: | |||
continue; | |||
} | |||
if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.parameter) && (fData->hints & PLUGIN_CAN_BALANCE) > 0) | |||
if (MIDI_IS_CONTROL_BALANCE(ctrlEvent.param) && (fData->hints & PLUGIN_CAN_BALANCE) > 0) | |||
{ | |||
double left, right; | |||
value = ctrlEvent.value/0.5 - 1.0; | |||
@@ -853,9 +849,9 @@ public: | |||
// Control plugin parameters | |||
for (k=0; k < fData->param.count; k++) | |||
{ | |||
if (fData->param.data[k].midiChannel != event->channel) | |||
if (fData->param.data[k].midiChannel != event.channel) | |||
continue; | |||
if (fData->param.data[k].midiCC != ctrlEvent.parameter) | |||
if (fData->param.data[k].midiCC != ctrlEvent.param) | |||
continue; | |||
if (fData->param.data[k].type != PARAMETER_INPUT) | |||
continue; | |||
@@ -889,7 +885,7 @@ public: | |||
break; | |||
case kEngineControlEventTypeAllSoundOff: | |||
if (event->channel == fData->ctrlInChannel) | |||
if (event.channel == fData->ctrlInChannel) | |||
{ | |||
if (fDescriptor->deactivate != nullptr) | |||
{ | |||
@@ -1078,7 +1074,7 @@ public: | |||
if (fData->param.data[k].midiCC > 0) | |||
{ | |||
value = fData->param.ranges[k].Value(fParamBuffers[k]); // FIXME - range 0.0-1.0 new name | |||
value = fData->param.ranges[k].normalizeValue(fParamBuffers[k]); | |||
fData->event.portOut->writeControlEvent(framesOffset, fData->param.data[k].midiChannel, kEngineControlEventTypeParameter, fData->param.data[k].midiCC, value); | |||
} | |||
} | |||
@@ -957,7 +957,7 @@ CarlaPlugin* LinuxSamplerPlugin::newLinuxSampler(const Initializer& init, bool i | |||
CARLA_BACKEND_END_NAMESPACE | |||
#else // WANT_LINUXSAMPLER | |||
# warning linuxsampler not available (no GIG and SFZ support) | |||
//# warning linuxsampler not available (no GIG and SFZ support) | |||
#endif | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -4635,7 +4635,7 @@ int CarlaEngineOsc::handleMsgLv2EventTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2) | |||
CARLA_BACKEND_END_NAMESPACE | |||
#else // WANT_LV2 | |||
# warning Building without LV2 support | |||
//# warning Building without LV2 support | |||
#endif | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -2381,7 +2381,7 @@ VstPlugin* VstPlugin::lastVstPlugin = nullptr; | |||
CARLA_BACKEND_END_NAMESPACE | |||
#else // WANT_VST | |||
# warning Building without VST support | |||
//# warning Building without VST support | |||
#endif | |||
CARLA_BACKEND_START_NAMESPACE | |||
@@ -732,6 +732,8 @@ class CarlaMainW(QMainWindow): | |||
while (self.ui.w_plugins.layout().takeAt(0)): | |||
pass | |||
self.ui.act_plugin_remove_all.setEnabled(False) | |||
for i in range(self.fPluginCount): | |||
pwidget = self.fPluginList[i] | |||
@@ -508,7 +508,7 @@ public: | |||
for (size_t i=0; i < bufferLen; i++) | |||
{ | |||
if (buffer[i] >= 'A' && buffer[i] <= 'Z') | |||
buffer[i] = char(buffer[i] + charDiff); | |||
buffer[i] += charDiff; | |||
} | |||
} | |||
@@ -519,7 +519,7 @@ public: | |||
for (size_t i=0; i < bufferLen; i++) | |||
{ | |||
if (buffer[i] >= 'a' && buffer[i] <= 'z') | |||
buffer[i] = char(buffer[i] + charDiff); | |||
buffer[i] -= charDiff; | |||
} | |||
} | |||