Browse Source

Engine API changes, several fixes

tags/1.9.4
falkTX 11 years ago
parent
commit
1f60d3701d
15 changed files with 408 additions and 420 deletions
  1. +1
    -1
      source/backend/carla_backend.hpp
  2. +117
    -65
      source/backend/carla_engine.hpp
  3. +186
    -184
      source/backend/engine/carla_engine.cpp
  4. +60
    -56
      source/backend/engine/jack.cpp
  5. +0
    -39
      source/backend/engine/plugin.cpp
  6. +0
    -44
      source/backend/engine/rtaudio.cpp
  7. +23
    -8
      source/backend/plugin/carla_plugin.pro
  8. +1
    -1
      source/backend/plugin/dssi.cpp
  9. +1
    -1
      source/backend/plugin/fluidsynth.cpp
  10. +12
    -16
      source/backend/plugin/ladspa.cpp
  11. +1
    -1
      source/backend/plugin/linuxsampler.cpp
  12. +1
    -1
      source/backend/plugin/lv2.cpp
  13. +1
    -1
      source/backend/plugin/vst.cpp
  14. +2
    -0
      source/carla.py
  15. +2
    -2
      source/utils/carla_utils.hpp

+ 1
- 1
source/backend/carla_backend.hpp View File

@@ -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_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_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 = 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. const unsigned int PLUGIN_CAN_FORCE_STEREO = 0x1000; //!< Plugin can be used in forced-stereo mode.
/**@}*/ /**@}*/




+ 117
- 65
source/backend/carla_engine.hpp View File

@@ -146,7 +146,7 @@ enum EngineControlEventType {
*/ */
struct EngineControlEvent { struct EngineControlEvent {
EngineControlEventType type; //!< Control-Event type. 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. double value; //!< Parameter value, normalized to 0.0<->1.0.


EngineControlEvent() EngineControlEvent()
@@ -156,8 +156,8 @@ struct EngineControlEvent {


void clear() void clear()
{ {
type = kEngineControlEventTypeNull;
parameter = 0;
type = kEngineControlEventTypeNull;
param = 0;
value = 0.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. * Engine options.
*/ */
@@ -226,10 +262,10 @@ struct EngineOptions {
bool useDssiVstChunks; bool useDssiVstChunks;
#endif #endif


uint maxParameters;
uint oscUiTimeout;
uint preferredBufferSize;
uint preferredSampleRate;
unsigned int maxParameters;
unsigned int oscUiTimeout;
unsigned int preferredBufferSize;
unsigned int preferredSampleRate;


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
CarlaString bridge_native; CarlaString bridge_native;
@@ -301,15 +337,14 @@ struct EngineTimeInfo {


bool playing; bool playing;
uint32_t frame; uint32_t frame;
uint32_t time;
uint64_t time;
uint32_t valid; uint32_t valid;
EngineTimeInfoBBT bbt; EngineTimeInfoBBT bbt;


EngineTimeInfo() EngineTimeInfo()
: playing(false),
frame(0),
time(0),
valid(0x0) {}
{
clear();
}


void clear() void clear()
{ {
@@ -337,7 +372,7 @@ public:
CarlaEnginePort(const bool isInput, const ProcessMode processMode); CarlaEnginePort(const bool isInput, const ProcessMode processMode);


/*! /*!
* The decontructor.
* The destructor.
*/ */
virtual ~CarlaEnginePort(); virtual ~CarlaEnginePort();


@@ -374,7 +409,7 @@ public:
CarlaEngineAudioPort(const bool isInput, const ProcessMode processMode); CarlaEngineAudioPort(const bool isInput, const ProcessMode processMode);


/*! /*!
* The decontructor.
* The destructor.
*/ */
virtual ~CarlaEngineAudioPort(); virtual ~CarlaEngineAudioPort();


@@ -421,7 +456,7 @@ public:
CarlaEngineEventPort(const bool isInput, const ProcessMode processMode); CarlaEngineEventPort(const bool isInput, const ProcessMode processMode);


/*! /*!
* The decontructor.
* The destructor.
*/ */
virtual ~CarlaEngineEventPort(); virtual ~CarlaEngineEventPort();


@@ -446,23 +481,39 @@ public:


/*! /*!
* Get the event at \a index. * 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 * Write a control event into the buffer.\n
* Arguments are the same as in the EngineControlEvent struct. * 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 * Write a MIDI event into the buffer.\n
* Arguments are the same as in the EngineMidiEvent struct. * Arguments are the same as in the EngineMidiEvent struct.
** \note You must only call this for output ports. ** \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: private:
const uint32_t kMaxEventCount; const uint32_t kMaxEventCount;
@@ -480,7 +531,7 @@ private:
*/ */
class CarlaEngineClient class CarlaEngineClient
{ {
protected:
public:
/*! /*!
* The constructor, protected.\n * The constructor, protected.\n
* All constructor parameters are constant and will never change in the lifetime of the client.\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); CarlaEngineClient(const CarlaBackend::EngineType engineType, const CarlaBackend::ProcessMode processMode);


public:
/*! /*!
* The destructor. * The destructor.
*/ */
@@ -532,23 +582,23 @@ public:
* Add a new port of type \a portType. * 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). * \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: protected:
const EngineType kEngineType; const EngineType kEngineType;
const ProcessMode kProcessMode; const ProcessMode kProcessMode;


private:
bool fActive; bool fActive;
uint32_t fLatency; uint32_t fLatency;


private:
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineClient) 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. * Non-engine code MUST NEVER have direct access to this.
*/ */
struct CarlaEngineProtectedData; struct CarlaEngineProtectedData;
@@ -630,7 +680,7 @@ public:
virtual bool close(); virtual bool close();


/*! /*!
* Idle.
* Idle engine.
*/ */
virtual void idle(); virtual void idle();


@@ -653,36 +703,18 @@ public:
* Add new engine client. * Add new engine client.
* \note This must only be called within a plugin class. * \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 // 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); 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) 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(); 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 // bridge, internal use only
// TODO - find a better way for this // TODO - find a better way for this
//void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin); //void __bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin);
@@ -711,8 +759,7 @@ public:


/*! /*!
* Load \a filename session. * 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); void loadProject(const char* const filename);


@@ -769,6 +816,9 @@ public:
return fTimeInfo; return fTimeInfo;
} }


// -------------------------------------------------------------------
// Information (peaks)

/*! /*!
* TODO. * TODO.
*/ */
@@ -779,17 +829,6 @@ public:
*/ */
float getOutputPeak(const unsigned int pluginId, const unsigned short id) const; 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 // Callback


@@ -816,6 +855,20 @@ public:
*/ */
void setLastError(const char* const error); 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 // Options


@@ -879,7 +932,7 @@ protected:
EngineOptions fOptions; EngineOptions fOptions;
EngineTimeInfo fTimeInfo; EngineTimeInfo fTimeInfo;


ScopedPointer<CarlaEngineProtectedData> const fData;
CarlaEngineProtectedData* const fData;


/*! /*!
* Report to all plugins about buffer size change. * Report to all plugins about buffer size change.
@@ -898,20 +951,19 @@ protected:
*/ */
void proccessPendingEvents(); void proccessPendingEvents();


public:
/*! /*!
* TODO. * TODO.
*/ */
void setPeaks(const unsigned int pluginId, float* inPeaks, float* outPeaks); void setPeaks(const unsigned int pluginId, float* inPeaks, float* outPeaks);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
// Rack mode data
EngineEvent* getRackEventBuffer(const bool isInput);

//static const unsigned short MAX_EVENTS = 1024; //static const unsigned short MAX_EVENTS = 1024;
//EngineEvent fRackEventsIn[MAX_EVENTS]; //EngineEvent fRackEventsIn[MAX_EVENTS];
//EngineEvent fRackEventsOut[MAX_EVENTS]; //EngineEvent fRackEventsOut[MAX_EVENTS];


// Rack mode data
EngineEvent* getRackEventBuffer(const bool isInput);

/*! /*!
* Proccess audio buffer in rack mode. * Proccess audio buffer in rack mode.
*/ */


+ 186
- 184
source/backend/engine/carla_engine.cpp View File

@@ -48,38 +48,34 @@ CarlaEngineAudioPort::CarlaEngineAudioPort(const bool isInput, const ProcessMode
{ {
qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode)); qDebug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));


#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_PATCHBAY) if (kProcessMode == PROCESS_MODE_PATCHBAY)
fBuffer = new float[PATCHBAY_BUFFER_SIZE]; fBuffer = new float[PATCHBAY_BUFFER_SIZE];
#endif
} }


CarlaEngineAudioPort::~CarlaEngineAudioPort() CarlaEngineAudioPort::~CarlaEngineAudioPort()
{ {
qDebug("CarlaEngineAudioPort::~CarlaEngineAudioPort()"); qDebug("CarlaEngineAudioPort::~CarlaEngineAudioPort()");


#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_PATCHBAY) if (kProcessMode == PROCESS_MODE_PATCHBAY)
{ {
CARLA_ASSERT(fBuffer);
CARLA_ASSERT(fBuffer != nullptr);


if (fBuffer)
if (fBuffer != nullptr)
delete[] fBuffer; delete[] fBuffer;
} }
#endif
} }


void CarlaEngineAudioPort::initBuffer(CarlaEngine* const) void CarlaEngineAudioPort::initBuffer(CarlaEngine* const)
{ {
#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_PATCHBAY && ! kIsInput) if (kProcessMode == PROCESS_MODE_PATCHBAY && ! kIsInput)
carla_zeroFloat(fBuffer, PATCHBAY_BUFFER_SIZE); carla_zeroFloat(fBuffer, PATCHBAY_BUFFER_SIZE);
#endif
} }


// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
// Carla Engine Event port // Carla Engine Event port


static const EngineEvent kFallbackEngineEvent;

CarlaEngineEventPort::CarlaEngineEventPort(const bool isInput, const ProcessMode processMode) CarlaEngineEventPort::CarlaEngineEventPort(const bool isInput, const ProcessMode processMode)
: CarlaEnginePort(isInput, processMode), : CarlaEnginePort(isInput, processMode),
kMaxEventCount(processMode == PROCESS_MODE_CONTINUOUS_RACK ? RACK_EVENT_COUNT : PATCHBAY_EVENT_COUNT), 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)); qDebug("CarlaEngineEventPort::CarlaEngineEventPort(%s, %s)", bool2str(isInput), ProcessMode2Str(processMode));


#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_PATCHBAY) if (kProcessMode == PROCESS_MODE_PATCHBAY)
fBuffer = new EngineEvent[PATCHBAY_EVENT_COUNT]; fBuffer = new EngineEvent[PATCHBAY_EVENT_COUNT];
#endif
} }


CarlaEngineEventPort::~CarlaEngineEventPort() CarlaEngineEventPort::~CarlaEngineEventPort()
{ {
qDebug("CarlaEngineEventPort::~CarlaEngineEventPort()"); qDebug("CarlaEngineEventPort::~CarlaEngineEventPort()");


#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_PATCHBAY) if (kProcessMode == PROCESS_MODE_PATCHBAY)
{ {
CARLA_ASSERT(fBuffer);
CARLA_ASSERT(fBuffer != nullptr);


if (fBuffer)
if (fBuffer != nullptr)
delete[] fBuffer; delete[] fBuffer;
} }
#endif
} }


void CarlaEngineEventPort::initBuffer(CarlaEngine* const engine) void CarlaEngineEventPort::initBuffer(CarlaEngine* const engine)
@@ -115,31 +107,28 @@ void CarlaEngineEventPort::initBuffer(CarlaEngine* const engine)
if (engine == nullptr) if (engine == nullptr)
return; return;


#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK) if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK)
fBuffer = engine->getRackEventBuffer(kIsInput); fBuffer = engine->getRackEventBuffer(kIsInput);
else if (kProcessMode == PROCESS_MODE_PATCHBAY && ! kIsInput) else if (kProcessMode == PROCESS_MODE_PATCHBAY && ! kIsInput)
carla_zeroMem(fBuffer, sizeof(EngineEvent)*PATCHBAY_EVENT_COUNT); carla_zeroMem(fBuffer, sizeof(EngineEvent)*PATCHBAY_EVENT_COUNT);
#endif
} }


uint32_t CarlaEngineEventPort::getEventCount() uint32_t CarlaEngineEventPort::getEventCount()
{ {
if (! kIsInput)
return 0;

CARLA_ASSERT(kIsInput);
CARLA_ASSERT(fBuffer != nullptr); CARLA_ASSERT(fBuffer != nullptr);


if (! kIsInput)
return 0;
if (fBuffer == nullptr) if (fBuffer == nullptr)
return 0; return 0;


#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY) if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY)
{ {
uint32_t count = 0; uint32_t count = 0;
const EngineEvent* const events = fBuffer; 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) if (events[i].type == kEngineEventTypeNull)
break; break;
@@ -147,46 +136,43 @@ uint32_t CarlaEngineEventPort::getEventCount()


return count; return count;
} }
#endif


return 0; 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(fBuffer != nullptr);
CARLA_ASSERT(index < kMaxEventCount); CARLA_ASSERT(index < kMaxEventCount);


if (! kIsInput)
return kFallbackEngineEvent;
if (fBuffer == nullptr) if (fBuffer == nullptr)
return nullptr;
return kFallbackEngineEvent;
if (index >= kMaxEventCount) if (index >= kMaxEventCount)
return nullptr;
return kFallbackEngineEvent;


#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY) if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY)
{ {
const EngineEvent* const events = fBuffer; 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(fBuffer != nullptr);
CARLA_ASSERT(type != kEngineControlEventTypeNull); CARLA_ASSERT(type != kEngineControlEventTypeNull);
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
CARLA_ASSERT(value >= 0.0 && value <= 1.0); CARLA_ASSERT(value >= 0.0 && value <= 1.0);


if (kIsInput)
return;
if (fBuffer == nullptr) if (fBuffer == nullptr)
return; return;
if (type == kEngineControlEventTypeNull) if (type == kEngineControlEventTypeNull)
@@ -195,15 +181,14 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t
return; return;
if (type == kEngineControlEventTypeParameter) 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) if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY)
{ {
EngineEvent* const events = fBuffer; 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) if (events[i].type != kEngineEventTypeNull)
continue; continue;
@@ -212,32 +197,27 @@ void CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t
events[i].time = time; events[i].time = time;
events[i].channel = channel; 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; return;
} }


qWarning("CarlaEngineEventPort::writeControlEvent() - buffer full"); 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(fBuffer != nullptr);
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
CARLA_ASSERT(data != nullptr); CARLA_ASSERT(data != nullptr);
CARLA_ASSERT(size > 0); CARLA_ASSERT(size > 0);


if (kIsInput)
return;
if (fBuffer == nullptr) if (fBuffer == nullptr)
return; return;
if (channel >= MAX_MIDI_CHANNELS) if (channel >= MAX_MIDI_CHANNELS)
@@ -247,7 +227,6 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha
if (size == 0) if (size == 0)
return; return;


#ifndef BUILD_BRIDGE
if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY) if (kProcessMode == PROCESS_MODE_CONTINUOUS_RACK || kProcessMode == PROCESS_MODE_PATCHBAY)
{ {
if (size > 3) if (size > 3)
@@ -255,7 +234,7 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha


EngineEvent* const events = fBuffer; 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) if (events[i].type != kEngineEventTypeNull)
continue; continue;
@@ -264,6 +243,7 @@ void CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t cha
events[i].time = time; events[i].time = time;
events[i].channel = channel; events[i].channel = channel;


events[i].midi.port = port;
events[i].midi.data[0] = data[0]; events[i].midi.data[0] = data[0];
events[i].midi.data[1] = data[1]; events[i].midi.data[1] = data[1];
events[i].midi.data[2] = data[2]; 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"); qWarning("CarlaEngineEventPort::writeMidiEvent() - buffer full");
} }
#else
Q_UNUSED(time);
#endif
} }


// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
@@ -338,6 +315,24 @@ void CarlaEngineClient::setLatency(const uint32_t samples)
fLatency = 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 // Carla Engine


@@ -353,7 +348,7 @@ CarlaEngine::~CarlaEngine()
{ {
qDebug("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) 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(); 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 #if 0
void CarlaEngine::__bridgePluginRegister(const unsigned short id, CarlaPlugin* const plugin) 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 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]; 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 // Callback


@@ -1068,6 +1043,37 @@ void CarlaEngine::setLastError(const char* const error)
fData->lastError = 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 // 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) void CarlaEngine::osc_send_peaks(CarlaPlugin* const plugin, const unsigned short& id)
#endif #endif
{ {
#if 0
// Peak values // Peak values
if (plugin->audioInCount() > 0) 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); osc_send_control_set_output_peak_value(id, 2);
#endif #endif
} }
#endif
} }


#ifndef BUILD_BRIDGE #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) 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); //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]; char target_path[strlen(fData->oscData->path)+22];
strcpy(target_path, fData->oscData->path); strcpy(target_path, fData->oscData->path);
strcat(target_path, "/set_input_peak_value"); 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]; char target_path[strlen(fData->oscData->path)+23];
strcpy(target_path, fData->oscData->path); strcpy(target_path, fData->oscData->path);
strcat(target_path, "/set_output_peak_value"); 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() void CarlaEngine::osc_send_control_exit()
{ {


+ 60
- 56
source/backend/engine/jack.cpp View File

@@ -86,6 +86,8 @@ private:
// ------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------------------------------
// Carla Engine JACK-Event port // Carla Engine JACK-Event port


static const EngineEvent kFallbackJackEngineEvent;

class CarlaEngineJackEventPort : public CarlaEngineEventPort class CarlaEngineJackEventPort : public CarlaEngineEventPort
{ {
public: public:
@@ -139,34 +141,34 @@ public:
if (kPort == nullptr) if (kPort == nullptr)
return CarlaEngineEventPort::getEventCount(); return CarlaEngineEventPort::getEventCount();


if (! kIsInput)
return 0;

CARLA_ASSERT(kIsInput);
CARLA_ASSERT(fJackBuffer != nullptr); CARLA_ASSERT(fJackBuffer != nullptr);


if (! kIsInput)
return 0;
if (fJackBuffer != nullptr) if (fJackBuffer != nullptr)
return 0; return 0;


return jackbridge_midi_get_event_count(fJackBuffer); return jackbridge_midi_get_event_count(fJackBuffer);
} }


const EngineEvent* getEvent(const uint32_t index)
const EngineEvent& getEvent(const uint32_t index)
{ {
if (kPort == nullptr) if (kPort == nullptr)
return CarlaEngineEventPort::getEvent(index); return CarlaEngineEventPort::getEvent(index);


if (! kIsInput)
return nullptr;

CARLA_ASSERT(kIsInput);
CARLA_ASSERT(fJackBuffer != nullptr); CARLA_ASSERT(fJackBuffer != nullptr);


if (fJackBuffer != nullptr)
return nullptr;
if (! kIsInput)
return kFallbackJackEngineEvent;
if (fJackBuffer == nullptr)
return kFallbackJackEngineEvent;


jack_midi_event_t jackEvent; jack_midi_event_t jackEvent;


if (jackbridge_midi_event_get(&jackEvent, fJackBuffer, index) != 0 || jackEvent.size > 3) if (jackbridge_midi_event_get(&jackEvent, fJackBuffer, index) != 0 || jackEvent.size > 3)
return nullptr;
return kFallbackJackEngineEvent;


fRetEvent.clear(); fRetEvent.clear();


@@ -179,45 +181,45 @@ public:
if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus)) if (MIDI_IS_STATUS_CONTROL_CHANGE(midiStatus))
{ {
const uint8_t midiControl = jackEvent.buffer[1]; const uint8_t midiControl = jackEvent.buffer[1];
fRetEvent.type = kEngineEventTypeControl;
fRetEvent.type = kEngineEventTypeControl;


if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) if (MIDI_IS_CONTROL_BANK_SELECT(midiControl))
{ {
const uint8_t midiBank = jackEvent.buffer[2]; 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) 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) 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 else
{ {
const uint8_t midiValue = jackEvent.buffer[2]; 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)) else if (MIDI_IS_STATUS_PROGRAM_CHANGE(midiStatus))
{ {
const uint8_t midiProgram = jackEvent.buffer[1]; 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 else
{ {
@@ -229,22 +231,22 @@ public:
fRetEvent.midi.size = jackEvent.size; 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) 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(fJackBuffer != nullptr);
CARLA_ASSERT(type != kEngineControlEventTypeNull); CARLA_ASSERT(type != kEngineControlEventTypeNull);
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
CARLA_ASSERT(value >= 0.0 && value <= 1.0); CARLA_ASSERT(value >= 0.0 && value <= 1.0);


if (kIsInput)
return;
if (fJackBuffer == nullptr) if (fJackBuffer == nullptr)
return; return;
if (type == kEngineControlEventTypeNull) if (type == kEngineControlEventTypeNull)
@@ -253,7 +255,7 @@ public:
return; return;
if (type == kEngineControlEventTypeParameter) if (type == kEngineControlEventTypeParameter)
{ {
CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(parameter));
CARLA_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
} }


uint8_t data[3] = { 0 }; uint8_t data[3] = { 0 };
@@ -265,19 +267,19 @@ public:
break; break;
case kEngineControlEventTypeParameter: case kEngineControlEventTypeParameter:
data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; data[0] = MIDI_STATUS_CONTROL_CHANGE + channel;
data[1] = parameter;
data[1] = param;
data[2] = value * 127; data[2] = value * 127;
size = 3; size = 3;
break; break;
case kEngineControlEventTypeMidiBank: case kEngineControlEventTypeMidiBank:
data[0] = MIDI_STATUS_CONTROL_CHANGE + channel; data[0] = MIDI_STATUS_CONTROL_CHANGE + channel;
data[1] = MIDI_CONTROL_BANK_SELECT; data[1] = MIDI_CONTROL_BANK_SELECT;
data[2] = value;
size = 3;
data[2] = param;
size = 3;
break; break;
case kEngineControlEventTypeMidiProgram: case kEngineControlEventTypeMidiProgram:
data[0] = MIDI_STATUS_PROGRAM_CHANGE + channel; data[0] = MIDI_STATUS_PROGRAM_CHANGE + channel;
data[1] = value;
data[1] = param;
size = 2; size = 2;
break; break;
case kEngineControlEventTypeAllSoundOff: case kEngineControlEventTypeAllSoundOff:
@@ -296,24 +298,26 @@ public:
jackbridge_midi_event_write(fJackBuffer, time, data, size); 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) 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(fJackBuffer != nullptr);
CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); CARLA_ASSERT(channel < MAX_MIDI_CHANNELS);
CARLA_ASSERT(data);
CARLA_ASSERT(data != nullptr);
CARLA_ASSERT(size > 0); CARLA_ASSERT(size > 0);


if (kIsInput)
return;
if (fJackBuffer == nullptr) if (fJackBuffer == nullptr)
return; return;
if (channel >= MAX_MIDI_CHANNELS) if (channel >= MAX_MIDI_CHANNELS)
return; return;
if (! (data && size > 0))
if (data == nullptr)
return;
if (size == 0)
return; return;


uint8_t jdata[size]; uint8_t jdata[size];
@@ -370,13 +374,13 @@ public:


void activate() void activate()
{ {
qDebug("CarlaEngineClient::activate()");
qDebug("CarlaEngineJackClient::activate()");


if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{ {
CARLA_ASSERT(kClient && ! isActive());
CARLA_ASSERT(kClient && ! fActive);


if (kClient && ! isActive())
if (kClient && ! fActive)
jackbridge_activate(kClient); jackbridge_activate(kClient);
} }


@@ -385,13 +389,13 @@ public:


void deactivate() void deactivate()
{ {
qDebug("CarlaEngineClient::deactivate()");
qDebug("CarlaEngineJackClient::deactivate()");


if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS) if (kProcessMode == PROCESS_MODE_MULTIPLE_CLIENTS)
{ {
CARLA_ASSERT(kClient && isActive());
CARLA_ASSERT(kClient && fActive);


if (kClient && isActive())
if (kClient && fActive)
jackbridge_deactivate(kClient); jackbridge_deactivate(kClient);
} }


@@ -400,7 +404,7 @@ public:


bool isOk() const bool isOk() const
{ {
qDebug("CarlaEngineClient::isOk()");
qDebug("CarlaEngineJackClient::isOk()");


if (kUseClient) if (kUseClient)
return bool(kClient); return bool(kClient);
@@ -418,11 +422,11 @@ public:


const CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) 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; jack_port_t* port = nullptr;


// Create Jack port if needed
// Create JACK port first, if needed
if (kUseClient) if (kUseClient)
{ {
switch (portType) switch (portType)
@@ -449,7 +453,7 @@ public:
return new CarlaEngineJackEventPort(isInput, kProcessMode, kClient, port); 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; 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); engine->setPeaks(p->id(), inPeaks, outPeaks);
} }




+ 0
- 39
source/backend/engine/plugin.cpp View File

@@ -42,40 +42,6 @@ static const unsigned int paramPan = 8;
static const unsigned int paramCount = sizeof(paramMap); static const unsigned int paramCount = sizeof(paramMap);
static const unsigned int programCount = 128; 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, class CarlaEnginePlugin : public CarlaEngine,
@@ -163,11 +129,6 @@ public:
return kEngineTypeRtAudio; return kEngineTypeRtAudio;
} }


CarlaEngineClient* addClient(CarlaPlugin* const)
{
return new CarlaEnginePluginClient(kEngineTypePlugin, fOptions.processMode);
}

protected: protected:
// --------------------------------------------- // ---------------------------------------------
// DISTRHO Plugin Information // DISTRHO Plugin Information


+ 0
- 44
source/backend/engine/rtaudio.cpp View File

@@ -30,45 +30,6 @@ CARLA_BACKEND_START_NAMESPACE
} // Fix editor indentation } // Fix editor indentation
#endif #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 // RtAudio Engine


@@ -248,11 +209,6 @@ public:
return kEngineTypeRtAudio; return kEngineTypeRtAudio;
} }


CarlaEngineClient* addClient(CarlaPlugin* const)
{
return new CarlaEngineRtAudioClient(kEngineTypeRtAudio, fOptions.processMode);
}

// ------------------------------------- // -------------------------------------


protected: protected:


+ 23
- 8
source/backend/plugin/carla_plugin.pro View File

@@ -1,9 +1,7 @@
# QtCreator project file # QtCreator project file


QT = core gui

CONFIG = debug CONFIG = debug
CONFIG += link_pkgconfig qt shared warn_on
CONFIG += link_pkgconfig shared warn_on


DEFINES = DEBUG DEFINES = DEBUG
DEFINES += QTCREATOR_TEST DEFINES += QTCREATOR_TEST
@@ -27,7 +25,7 @@ TARGET = carla_plugin
TEMPLATE = lib TEMPLATE = lib
VERSION = 0.5.0 VERSION = 0.5.0


SOURCES = \
SOURCES = \
carla_plugin.cpp \ carla_plugin.cpp \
carla_plugin_thread.cpp \ carla_plugin_thread.cpp \
carla_bridge.cpp \ carla_bridge.cpp \
@@ -39,7 +37,7 @@ SOURCES = \
fluidsynth.cpp \ fluidsynth.cpp \
linuxsampler.cpp linuxsampler.cpp


HEADERS = \
HEADERS = \
carla_plugin_internal.hpp \ carla_plugin_internal.hpp \
carla_plugin_thread.hpp carla_plugin_thread.hpp


@@ -47,6 +45,7 @@ HEADERS += \
../carla_backend.hpp \ ../carla_backend.hpp \
../carla_engine.hpp \ ../carla_engine.hpp \
../carla_native.h \ ../carla_native.h \
../carla_native.hpp \
../carla_plugin.hpp ../carla_plugin.hpp


INCLUDEPATH = . .. \ INCLUDEPATH = . .. \
@@ -54,8 +53,24 @@ INCLUDEPATH = . .. \
../../libs \ ../../libs \
../../utils ../../utils


# FIXME
# ---------------------------------------------------------------------------------------

PKGCONFIG += QtCore QtGui

# Fake includes
INCLUDEPATH += \ 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

+ 1
- 1
source/backend/plugin/dssi.cpp View File

@@ -1595,7 +1595,7 @@ private:
CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#else // WANT_DSSI #else // WANT_DSSI
# warning Building without DSSI support
//# warning Building without DSSI support
#endif #endif


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


+ 1
- 1
source/backend/plugin/fluidsynth.cpp View File

@@ -1318,7 +1318,7 @@ private:
CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#else // WANT_FLUIDSYNTH #else // WANT_FLUIDSYNTH
# warning fluidsynth not available (no SF2 support)
//# warning fluidsynth not available (no SF2 support)
#endif #endif


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


+ 12
- 16
source/backend/plugin/ladspa.cpp View File

@@ -768,30 +768,26 @@ public:


if (fData->event.portIn != nullptr && fData->activeBefore) if (fData->event.portIn != nullptr && fData->activeBefore)
{ {
const EngineEvent* event = nullptr;
uint32_t time, nEvents = fData->event.portIn->getEventCount(); uint32_t time, nEvents = fData->event.portIn->getEventCount();


for (i=0; i < nEvents; i++) 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) if (time >= frames)
continue; continue;


// Control change // Control change
switch (event->type)
switch (event.type)
{ {
case kEngineEventTypeNull: case kEngineEventTypeNull:
break; break;


case kEngineEventTypeControl: case kEngineEventTypeControl:
{ {
const EngineControlEvent& ctrlEvent = event->ctrl;
const EngineControlEvent& ctrlEvent = event.ctrl;


switch (ctrlEvent.type) switch (ctrlEvent.type)
{ {
@@ -801,11 +797,11 @@ public:
case kEngineControlEventTypeParameter: case kEngineControlEventTypeParameter:
{ {
// Control backend stuff // Control backend stuff
if (event->channel == fData->ctrlInChannel)
if (event.channel == fData->ctrlInChannel)
{ {
double value; 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; value = ctrlEvent.value;
setDryWet(value, false, false); setDryWet(value, false, false);
@@ -813,7 +809,7 @@ public:
continue; 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; value = ctrlEvent.value*127/100;
setVolume(value, false, false); setVolume(value, false, false);
@@ -821,7 +817,7 @@ public:
continue; 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; double left, right;
value = ctrlEvent.value/0.5 - 1.0; value = ctrlEvent.value/0.5 - 1.0;
@@ -853,9 +849,9 @@ public:
// Control plugin parameters // Control plugin parameters
for (k=0; k < fData->param.count; k++) 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; continue;
if (fData->param.data[k].midiCC != ctrlEvent.parameter)
if (fData->param.data[k].midiCC != ctrlEvent.param)
continue; continue;
if (fData->param.data[k].type != PARAMETER_INPUT) if (fData->param.data[k].type != PARAMETER_INPUT)
continue; continue;
@@ -889,7 +885,7 @@ public:
break; break;


case kEngineControlEventTypeAllSoundOff: case kEngineControlEventTypeAllSoundOff:
if (event->channel == fData->ctrlInChannel)
if (event.channel == fData->ctrlInChannel)
{ {
if (fDescriptor->deactivate != nullptr) if (fDescriptor->deactivate != nullptr)
{ {
@@ -1078,7 +1074,7 @@ public:


if (fData->param.data[k].midiCC > 0) 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); fData->event.portOut->writeControlEvent(framesOffset, fData->param.data[k].midiChannel, kEngineControlEventTypeParameter, fData->param.data[k].midiCC, value);
} }
} }


+ 1
- 1
source/backend/plugin/linuxsampler.cpp View File

@@ -957,7 +957,7 @@ CarlaPlugin* LinuxSamplerPlugin::newLinuxSampler(const Initializer& init, bool i
CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#else // WANT_LINUXSAMPLER #else // WANT_LINUXSAMPLER
# warning linuxsampler not available (no GIG and SFZ support)
//# warning linuxsampler not available (no GIG and SFZ support)
#endif #endif


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


+ 1
- 1
source/backend/plugin/lv2.cpp View File

@@ -4635,7 +4635,7 @@ int CarlaEngineOsc::handleMsgLv2EventTransfer(CARLA_ENGINE_OSC_HANDLE_ARGS2)
CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#else // WANT_LV2 #else // WANT_LV2
# warning Building without LV2 support
//# warning Building without LV2 support
#endif #endif


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


+ 1
- 1
source/backend/plugin/vst.cpp View File

@@ -2381,7 +2381,7 @@ VstPlugin* VstPlugin::lastVstPlugin = nullptr;
CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#else // WANT_VST #else // WANT_VST
# warning Building without VST support
//# warning Building without VST support
#endif #endif


CARLA_BACKEND_START_NAMESPACE CARLA_BACKEND_START_NAMESPACE


+ 2
- 0
source/carla.py View File

@@ -732,6 +732,8 @@ class CarlaMainW(QMainWindow):
while (self.ui.w_plugins.layout().takeAt(0)): while (self.ui.w_plugins.layout().takeAt(0)):
pass pass


self.ui.act_plugin_remove_all.setEnabled(False)

for i in range(self.fPluginCount): for i in range(self.fPluginCount):
pwidget = self.fPluginList[i] pwidget = self.fPluginList[i]




+ 2
- 2
source/utils/carla_utils.hpp View File

@@ -508,7 +508,7 @@ public:
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] = char(buffer[i] + charDiff);
buffer[i] += charDiff;
} }
} }


@@ -519,7 +519,7 @@ public:
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] = char(buffer[i] + charDiff);
buffer[i] -= charDiff;
} }
} }




Loading…
Cancel
Save