Browse Source

Misc

tags/1.9.4
falkTX 11 years ago
parent
commit
a98fb08b1b
7 changed files with 813 additions and 834 deletions
  1. +9
    -84
      source/backend/engine/CarlaEngine.cpp
  2. +686
    -247
      source/backend/engine/CarlaEngineInternal.cpp
  3. +71
    -23
      source/backend/engine/CarlaEngineInternal.hpp
  4. +26
    -28
      source/backend/engine/CarlaEngineJack.cpp
  5. +2
    -2
      source/backend/engine/CarlaEngineOsc.cpp
  6. +0
    -431
      source/backend/engine/CarlaEngineProtectedData.cpp
  7. +19
    -19
      source/backend/engine/CarlaEngineRtAudio.cpp

+ 9
- 84
source/backend/engine/CarlaEngine.cpp View File

@@ -999,7 +999,7 @@ bool CarlaEngine::removePlugin(const unsigned int id)
pData->thread.stopThread(500); pData->thread.stopThread(500);


const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS);
const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait);
const ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait);


#ifndef BUILD_BRIDGE #ifndef BUILD_BRIDGE
if (isOscControlRegistered()) if (isOscControlRegistered())
@@ -1028,7 +1028,7 @@ bool CarlaEngine::removeAllPlugins()
pData->thread.stopThread(500); pData->thread.stopThread(500);


const bool lockWait(isRunning()); const bool lockWait(isRunning());
const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, lockWait);
const ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, lockWait);


callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);


@@ -1157,7 +1157,7 @@ bool CarlaEngine::switchPlugins(const unsigned int idA, const unsigned int idB)
pData->thread.stopThread(500); pData->thread.stopThread(500);


const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS);
const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait);
const ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait);


#ifndef BUILD_BRIDGE // TODO #ifndef BUILD_BRIDGE // TODO
//if (isOscControlRegistered()) //if (isOscControlRegistered())
@@ -1702,6 +1702,7 @@ bool CarlaEngine::patchbayConnect(const int groupA, const int portA, const int g
{ {
CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false);
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false);
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.buffer != nullptr, nullptr);
carla_debug("CarlaEngine::patchbayConnect(%i, %i)", portA, portB); carla_debug("CarlaEngine::patchbayConnect(%i, %i)", portA, portB);


if (portA < 0 || portB < 0) if (portA < 0 || portB < 0)
@@ -1710,94 +1711,17 @@ bool CarlaEngine::patchbayConnect(const int groupA, const int portA, const int g
return false; return false;
} }


return pData->bufAudio.connect(this, groupA, portA, groupB, portB);
return pData->bufAudio.buffer->connect(this, groupA, portA, groupB, portB);
} }


bool CarlaEngine::patchbayDisconnect(const uint connectionId) bool CarlaEngine::patchbayDisconnect(const uint connectionId)
{ {
CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false);
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false);
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.buffer != nullptr, false);
carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId); carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId);


if (pData->bufAudio.usePatchbay)
{
// not implemented yet
return false;
}

#if 0
EngineRackBuffers* const rack(pData->bufAudio.rack);

CARLA_SAFE_ASSERT_RETURN_ERR(rack->usedConnections.count() > 0, "No connections available");

for (LinkedList<ConnectionToId>::Itenerator it=rack->usedConnections.begin(); it.valid(); it.next())
{
const ConnectionToId& connection(it.getValue());

if (connection.id == connectionId)
{
const int otherPort((connection.portOut >= 0) ? connection.portOut : connection.portIn);
const int carlaPort((otherPort == connection.portOut) ? connection.portIn : connection.portOut);

if (otherPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000)
{
CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_MIDI_IN, false);

const int portId(otherPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
disconnectRackMidiInPort(portId);
}
else if (otherPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000)
{
CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_MIDI_OUT, false);

const int portId(otherPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000);
disconnectRackMidiOutPort(portId);
}
else if (otherPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000)
{
CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2, false);

const int portId(otherPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);

rack->connectLock.enter();

if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1)
rack->connectedOut1.removeAll(portId);
else
rack->connectedOut2.removeAll(portId);

rack->connectLock.leave();
}
else if (otherPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000)
{
CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2, false);

const int portId(otherPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000);

rack->connectLock.enter();

if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1)
rack->connectedIn1.removeAll(portId);
else
rack->connectedIn2.removeAll(portId);

rack->connectLock.leave();
}
else
{
CARLA_SAFE_ASSERT_RETURN(false, false);
}

callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, 0, 0, 0.0f, nullptr);

rack->usedConnections.remove(it);
return true;
}
}
#endif

setLastError("Failed to find connection");
return false;
return pData->bufAudio.buffer->disconnect(this, connectionId);
} }


bool CarlaEngine::patchbayRefresh() bool CarlaEngine::patchbayRefresh()
@@ -2084,9 +2008,10 @@ void CarlaEngine::setPluginPeaks(const unsigned int pluginId, float const inPeak


const char* const* CarlaEngine::getPatchbayConnections() const const char* const* CarlaEngine::getPatchbayConnections() const
{ {
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.buffer != nullptr, nullptr);
carla_debug("CarlaEngine::getPatchbayConnections()"); carla_debug("CarlaEngine::getPatchbayConnections()");


return pData->bufAudio.getConnections();
return pData->bufAudio.buffer->getConnections();
} }


void CarlaEngine::restorePatchbayConnection(const char* const connSource, const char* const connTarget) void CarlaEngine::restorePatchbayConnection(const char* const connSource, const char* const connTarget)


+ 686
- 247
source/backend/engine/CarlaEngineInternal.cpp
File diff suppressed because it is too large
View File


+ 71
- 23
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -44,18 +44,66 @@ CARLA_BACKEND_START_NAMESPACE


const unsigned short kMaxEngineEventInternalCount = 512; const unsigned short kMaxEngineEventInternalCount = 512;


// -----------------------------------------------------------------------
// Rack Patchbay stuff

enum RackPatchbayGroupIds {
RACK_PATCHBAY_GROUP_CARLA = 0,
RACK_PATCHBAY_GROUP_AUDIO = 1,
RACK_PATCHBAY_GROUP_MIDI = 2,
RACK_PATCHBAY_GROUP_MAX = 3
};

enum RackPatchbayCarlaPortIds {
RACK_PATCHBAY_CARLA_PORT_NULL = 0,
RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1 = 1,
RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2 = 2,
RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1 = 3,
RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2 = 4,
RACK_PATCHBAY_CARLA_PORT_MIDI_IN = 5,
RACK_PATCHBAY_CARLA_PORT_MIDI_OUT = 6,
RACK_PATCHBAY_CARLA_PORT_MAX = 7
};

// -----------------------------------------------------------------------
// ...

struct PortNameToId {
int group, port;
char name[STR_MAX+1];
};

struct ConnectionToId {
uint id;
int groupA, portA;
int groupB, portB;
};

// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
// AbstractEngineBuffer // AbstractEngineBuffer


struct AbstractEngineBuffer { struct AbstractEngineBuffer {
AbstractEngineBuffer(const uint32_t /*bufferSize*/) {}
uint lastConnectionId;
LinkedList<ConnectionToId> usedConnections;

CarlaCriticalSection connectLock;

AbstractEngineBuffer()
: lastConnectionId(0) {}

virtual ~AbstractEngineBuffer() noexcept {} virtual ~AbstractEngineBuffer() noexcept {}


virtual void clear() noexcept = 0;
virtual void clear() noexcept
{
lastConnectionId = 0;
usedConnections.clear();
}

virtual void resize(const uint32_t bufferSize) = 0; virtual void resize(const uint32_t bufferSize) = 0;


virtual bool connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int port) noexcept = 0;
virtual bool disconnect(const uint connectionId) noexcept = 0;
virtual bool connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int portB) noexcept = 0;
virtual bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept = 0;
virtual void refresh(CarlaEngine* const engine, const LinkedList<PortNameToId>& midiIns, const LinkedList<PortNameToId>& midiOuts);


virtual const char* const* getConnections() const = 0; virtual const char* const* getConnections() const = 0;
}; };
@@ -64,7 +112,7 @@ struct AbstractEngineBuffer {
// InternalAudio // InternalAudio


struct EngineInternalAudio { struct EngineInternalAudio {
bool isPatchbay; // can only be patchbay or rack mode
bool isRack; // can only be rack or patchbay mode
bool isReady; bool isReady;


uint inCount; uint inCount;
@@ -73,7 +121,7 @@ struct EngineInternalAudio {
AbstractEngineBuffer* buffer; AbstractEngineBuffer* buffer;


EngineInternalAudio() noexcept EngineInternalAudio() noexcept
: isPatchbay(false),
: isRack(true),
isReady(false), isReady(false),
inCount(0), inCount(0),
outCount(0), outCount(0),
@@ -227,7 +275,7 @@ struct CarlaEngineProtectedData {


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


CarlaEngineProtectedData(CarlaEngine* const engine);
CarlaEngineProtectedData(CarlaEngine* const engine) noexcept;
~CarlaEngineProtectedData() noexcept; ~CarlaEngineProtectedData() noexcept;


// ------------------------------------------------------------------- // -------------------------------------------------------------------
@@ -236,9 +284,9 @@ struct CarlaEngineProtectedData {
void doPluginsSwitch() noexcept; void doPluginsSwitch() noexcept;
void doNextPluginAction(const bool unlock) noexcept; void doNextPluginAction(const bool unlock) noexcept;


#ifndef BUILD_BRIDGE
// ------------------------------------------------------------------- // -------------------------------------------------------------------


#ifndef BUILD_BRIDGE
// the base, where plugins run // the base, where plugins run
void processRack(float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline); void processRack(float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline);


@@ -248,21 +296,6 @@ struct CarlaEngineProtectedData {


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


class ScopedActionLock
{
public:
ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait) noexcept;
~ScopedActionLock() noexcept;

private:
CarlaEngineProtectedData* const fData;

CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(ScopedActionLock)
};

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

#ifdef CARLA_PROPER_CPP11_SUPPORT #ifdef CARLA_PROPER_CPP11_SUPPORT
CarlaEngineProtectedData() = delete; CarlaEngineProtectedData() = delete;
CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData) CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData)
@@ -271,6 +304,21 @@ struct CarlaEngineProtectedData {


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


class ScopedActionLock
{
public:
ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept;
~ScopedActionLock() noexcept;

private:
CarlaEngineProtectedData* const fData;

CARLA_PREVENT_HEAP_ALLOCATION
CARLA_DECLARE_NON_COPY_CLASS(ScopedActionLock)
};

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

CARLA_BACKEND_END_NAMESPACE CARLA_BACKEND_END_NAMESPACE


#endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED

+ 26
- 28
source/backend/engine/CarlaEngineJack.cpp View File

@@ -315,7 +315,7 @@ public:
uint8_t data[3] = { 0, 0, 0 }; uint8_t data[3] = { 0, 0, 0 };


EngineControlEvent ctrlEvent = { type, param, value }; EngineControlEvent ctrlEvent = { type, param, value };
ctrlEvent.dumpToMidiData(channel, size, data);
ctrlEvent.convertToMidiData(channel, size, data);


if (size == 0) if (size == 0)
return false; return false;
@@ -457,7 +457,7 @@ public:
} }
#endif #endif


CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) /*noexcept*/ override
CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) noexcept override
{ {
carla_debug("CarlaEngineJackClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput)); carla_debug("CarlaEngineJackClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput));


@@ -481,36 +481,34 @@ public:
port = jackbridge_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0); port = jackbridge_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0);
break; break;
} }
} catch(...) {}

if (port == nullptr)
{
carla_stderr("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - failed to create JACK port", EnginePortType2Str(portType), name, bool2str(isInput));
return nullptr;
} }
CARLA_SAFE_EXCEPTION_RETURN("JackClient addPort", nullptr)
} }


// Create Engine port // Create Engine port
switch (portType)
{
case kEnginePortTypeNull:
break;
case kEnginePortTypeAudio: {
CarlaEngineJackAudioPort* const enginePort(new CarlaEngineJackAudioPort(fEngine, isInput, fClient, port));
fAudioPorts.append(enginePort);
return enginePort;
}
case kEnginePortTypeCV: {
CarlaEngineJackCVPort* const enginePort(new CarlaEngineJackCVPort(fEngine, isInput, fClient, port));
fCVPorts.append(enginePort);
return enginePort;
}
case kEnginePortTypeEvent: {
CarlaEngineJackEventPort* const enginePort(new CarlaEngineJackEventPort(fEngine, isInput, fClient, port));
fEventPorts.append(enginePort);
return enginePort;
}
try {
switch (portType)
{
case kEnginePortTypeNull:
break;
case kEnginePortTypeAudio: {
CarlaEngineJackAudioPort* const enginePort(new CarlaEngineJackAudioPort(fEngine, isInput, fClient, port));
fAudioPorts.append(enginePort);
return enginePort;
}
case kEnginePortTypeCV: {
CarlaEngineJackCVPort* const enginePort(new CarlaEngineJackCVPort(fEngine, isInput, fClient, port));
fCVPorts.append(enginePort);
return enginePort;
}
case kEnginePortTypeEvent: {
CarlaEngineJackEventPort* const enginePort(new CarlaEngineJackEventPort(fEngine, isInput, fClient, port));
fEventPorts.append(enginePort);
return enginePort;
}
}
} }
CARLA_SAFE_EXCEPTION_RETURN("JackClient new Port", nullptr)


carla_stderr("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput)); carla_stderr("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput));
return nullptr; return nullptr;
@@ -1343,7 +1341,7 @@ protected:
case kEngineEventTypeControl: case kEngineEventTypeControl:
{ {
const EngineControlEvent& ctrlEvent(engineEvent.ctrl); const EngineControlEvent& ctrlEvent(engineEvent.ctrl);
ctrlEvent.dumpToMidiData(engineEvent.channel, size, data);
ctrlEvent.convertToMidiData(engineEvent.channel, size, data);
break; break;
} }




+ 2
- 2
source/backend/engine/CarlaEngineOsc.cpp View File

@@ -116,7 +116,7 @@ void CarlaEngineOsc::idle() const noexcept
if (lo_server_recv_noblock(fServerTCP, 0) == 0) if (lo_server_recv_noblock(fServerTCP, 0) == 0)
break; break;
} }
CARLA_SAFE_EXCEPTION_BREAK("OSC idle TCP")
CARLA_SAFE_EXCEPTION_CONTINUE("OSC idle TCP")
} }
} }


@@ -128,7 +128,7 @@ void CarlaEngineOsc::idle() const noexcept
if (lo_server_recv_noblock(fServerUDP, 0) == 0) if (lo_server_recv_noblock(fServerUDP, 0) == 0)
break; break;
} }
CARLA_SAFE_EXCEPTION_BREAK("OSC idle UDP")
CARLA_SAFE_EXCEPTION_CONTINUE("OSC idle UDP")
} }
} }
} }


+ 0
- 431
source/backend/engine/CarlaEngineProtectedData.cpp View File

@@ -1,431 +0,0 @@
/*
* Carla Plugin Host
* Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaEngineInternal.hpp"
#include "CarlaPlugin.hpp"
#include "CarlaMIDI.h"

#include "CarlaMathUtils.hpp"

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

CARLA_BACKEND_START_NAMESPACE

#if 0
} // Fix editor indentation
#endif

// -----------------------------------------------------------------------
// CarlaEngineProtectedData

CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine)
: osc(engine),
thread(engine),
oscData(nullptr),
callback(nullptr),
callbackPtr(nullptr),
fileCallback(nullptr),
fileCallbackPtr(nullptr),
hints(0x0),
bufferSize(0),
sampleRate(0.0),
aboutToClose(false),
curPluginCount(0),
maxPluginNumber(0),
nextPluginId(0),
plugins(nullptr) {}

CarlaEngineProtectedData::~CarlaEngineProtectedData() noexcept
{
CARLA_SAFE_ASSERT(curPluginCount == 0);
CARLA_SAFE_ASSERT(maxPluginNumber == 0);
CARLA_SAFE_ASSERT(nextPluginId == 0);
CARLA_SAFE_ASSERT(plugins == nullptr);
}

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

void CarlaEngineProtectedData::doPluginRemove() noexcept
{
CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,);
CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,);
--curPluginCount;

// move all plugins 1 spot backwards
for (unsigned int i=nextAction.pluginId; i < curPluginCount; ++i)
{
CarlaPlugin* const plugin(plugins[i+1].plugin);

CARLA_SAFE_ASSERT_BREAK(plugin != nullptr);

plugin->setId(i);

plugins[i].plugin = plugin;
plugins[i].insPeak[0] = 0.0f;
plugins[i].insPeak[1] = 0.0f;
plugins[i].outsPeak[0] = 0.0f;
plugins[i].outsPeak[1] = 0.0f;
}

const unsigned int id(curPluginCount);

// reset last plugin (now removed)
plugins[id].plugin = nullptr;
plugins[id].insPeak[0] = 0.0f;
plugins[id].insPeak[1] = 0.0f;
plugins[id].outsPeak[0] = 0.0f;
plugins[id].outsPeak[1] = 0.0f;
}

void CarlaEngineProtectedData::doPluginsSwitch() noexcept
{
CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,);

const unsigned int idA(nextAction.pluginId);
const unsigned int idB(nextAction.value);

CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,);
CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,);
CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,);

#if 0
std::swap(plugins[idA].plugin, plugins[idB].plugin);
#else
CarlaPlugin* const tmp(plugins[idA].plugin);

plugins[idA].plugin = plugins[idB].plugin;
plugins[idB].plugin = tmp;
#endif
}

void CarlaEngineProtectedData::doNextPluginAction(const bool unlock) noexcept
{
switch (nextAction.opcode)
{
case kEnginePostActionNull:
break;
case kEnginePostActionZeroCount:
curPluginCount = 0;
break;
case kEnginePostActionRemovePlugin:
doPluginRemove();
break;
case kEnginePostActionSwitchPlugins:
doPluginsSwitch();
break;
}

nextAction.opcode = kEnginePostActionNull;
nextAction.pluginId = 0;
nextAction.value = 0;

if (unlock)
nextAction.mutex.unlock();
}

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

#ifndef BUILD_BRIDGE
void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline)
{
CARLA_SAFE_ASSERT_RETURN(bufEvents.in != nullptr,);
CARLA_SAFE_ASSERT_RETURN(bufEvents.out != nullptr,);

// safe copy
float inBuf0[frames];
float inBuf1[frames];
float* inBuf[2] = { inBuf0, inBuf1 };

// initialize audio inputs
FLOAT_COPY(inBuf0, inBufReal[0], frames);
FLOAT_COPY(inBuf1, inBufReal[1], frames);

// initialize audio outputs (zero)
FLOAT_CLEAR(outBuf[0], frames);
FLOAT_CLEAR(outBuf[1], frames);

// initialize event outputs (zero)
carla_zeroStruct<EngineEvent>(bufEvents.out, kMaxEngineEventInternalCount);

bool processed = false;

uint32_t oldAudioInCount = 0;
uint32_t oldMidiOutCount = 0;

// process plugins
for (unsigned int i=0; i < curPluginCount; ++i)
{
CarlaPlugin* const plugin = plugins[i].plugin;

if (plugin == nullptr || ! plugin->isEnabled() || ! plugin->tryLock(isOffline))
continue;

if (processed)
{
// initialize audio inputs (from previous outputs)
FLOAT_COPY(inBuf0, outBuf[0], frames);
FLOAT_COPY(inBuf1, outBuf[1], frames);

// initialize audio outputs (zero)
FLOAT_CLEAR(outBuf[0], frames);
FLOAT_CLEAR(outBuf[1], frames);

// if plugin has no midi out, add previous events
if (oldMidiOutCount == 0 && bufEvents.in[0].type != kEngineEventTypeNull)
{
if (bufEvents.out[0].type != kEngineEventTypeNull)
{
// TODO: carefully add to input, sorted events
}
// else nothing needed
}
else
{
// initialize event inputs from previous outputs
carla_copyStruct<EngineEvent>(bufEvents.in, bufEvents.out, kMaxEngineEventInternalCount);

// initialize event outputs (zero)
carla_zeroStruct<EngineEvent>(bufEvents.out, kMaxEngineEventInternalCount);
}
}

oldAudioInCount = plugin->getAudioInCount();
oldMidiOutCount = plugin->getMidiOutCount();

// process
plugin->initBuffers();
plugin->process(inBuf, outBuf, frames);
plugin->unlock();

// if plugin has no audio inputs, add input buffer
if (oldAudioInCount == 0)
{
FLOAT_ADD(outBuf[0], inBuf0, frames);
FLOAT_ADD(outBuf[1], inBuf1, frames);
}

// set peaks
{
EnginePluginData& pluginData(plugins[i]);

#ifdef HAVE_JUCE
float tmpMin, tmpMax;

if (oldAudioInCount > 0)
{
FloatVectorOperations::findMinAndMax(inBuf0, static_cast<int>(frames), tmpMin, tmpMax);
pluginData.insPeak[0] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);

FloatVectorOperations::findMinAndMax(inBuf1, static_cast<int>(frames), tmpMin, tmpMax);
pluginData.insPeak[1] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
}
else
{
pluginData.insPeak[0] = 0.0f;
pluginData.insPeak[1] = 0.0f;
}

if (plugin->getAudioOutCount() > 0)
{
FloatVectorOperations::findMinAndMax(outBuf[0], static_cast<int>(frames), tmpMin, tmpMax);
pluginData.outsPeak[0] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);

FloatVectorOperations::findMinAndMax(outBuf[1], static_cast<int>(frames), tmpMin, tmpMax);
pluginData.outsPeak[1] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f);
}
else
{
pluginData.outsPeak[0] = 0.0f;
pluginData.outsPeak[1] = 0.0f;
}
#else
float peak1, peak2;

if (oldAudioInCount > 0)
{
peak1 = peak2 = 0.0f;

for (uint32_t k=0; k < frames; ++k)
{
peak1 = carla_max<float>(peak1, std::fabs(inBuf0[k]), 1.0f);
peak2 = carla_max<float>(peak2, std::fabs(inBuf1[k]), 1.0f);
}

pluginData.insPeak[0] = peak1;
pluginData.insPeak[1] = peak2;
}
else
{
pluginData.insPeak[0] = 0.0f;
pluginData.insPeak[1] = 0.0f;
}

if (plugin->getAudioOutCount() > 0)
{
peak1 = peak2 = 0.0f;

for (uint32_t k=0; k < frames; ++k)
{
peak1 = carla_max<float>(peak1, std::fabs(outBuf[0][k]), 1.0f);
peak2 = carla_max<float>(peak2, std::fabs(outBuf[1][k]), 1.0f);
}

pluginData.outsPeak[0] = peak1;
pluginData.outsPeak[1] = peak2;
}
else
{
pluginData.outsPeak[0] = 0.0f;
pluginData.outsPeak[1] = 0.0f;
}
#endif
}

processed = true;
}
}

void CarlaEngineProtectedData::processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline)
{
EngineRackBuffers* const rack(bufAudio.rack);

const CarlaCriticalSectionScope _cs2(rack->connectLock);

// connect input buffers
if (rack->connectedIn1.count() == 0)
{
FLOAT_CLEAR(rack->in[0], nframes);
}
else
{
bool first = true;

for (LinkedList<int>::Itenerator it = rack->connectedIn1.begin(); it.valid(); it.next())
{
const int& port(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(inCount));

if (first)
{
FLOAT_COPY(rack->in[0], inBuf[port], nframes);
first = false;
}
else
{
FLOAT_ADD(rack->in[0], inBuf[port], nframes);
}
}

if (first)
FLOAT_CLEAR(rack->in[0], nframes);
}

if (rack->connectedIn2.count() == 0)
{
FLOAT_CLEAR(rack->in[1], nframes);
}
else
{
bool first = true;

for (LinkedList<int>::Itenerator it = rack->connectedIn2.begin(); it.valid(); it.next())
{
const int& port(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(inCount));

if (first)
{
FLOAT_COPY(rack->in[1], inBuf[port], nframes);
first = false;
}
else
{
FLOAT_ADD(rack->in[1], inBuf[port], nframes);
}
}

if (first)
FLOAT_CLEAR(rack->in[1], nframes);
}

FLOAT_CLEAR(rack->out[0], nframes);
FLOAT_CLEAR(rack->out[1], nframes);

// process
processRack(rack->in, rack->out, nframes, isOffline);

// connect output buffers
if (rack->connectedOut1.count() != 0)
{
for (LinkedList<int>::Itenerator it = rack->connectedOut1.begin(); it.valid(); it.next())
{
const int& port(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(outCount));

FLOAT_ADD(outBuf[port], rack->out[0], nframes);
}
}

if (rack->connectedOut2.count() != 0)
{
for (LinkedList<int>::Itenerator it = rack->connectedOut2.begin(); it.valid(); it.next())
{
const int& port(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(outCount));

FLOAT_ADD(outBuf[port], rack->out[1], nframes);
}
}
}
#endif

// -----------------------------------------------------------------------
// ScopedActionLock

CarlaEngineProtectedData::ScopedActionLock::ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait) noexcept
: fData(data)
{
fData->nextAction.mutex.lock();

CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,);

fData->nextAction.opcode = action;
fData->nextAction.pluginId = pluginId;
fData->nextAction.value = value;

if (lockWait)
{
// block wait for unlock on processing side
carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId);
fData->nextAction.mutex.lock();
carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId);
}
else
{
fData->doNextPluginAction(false);
}
}

CarlaEngineProtectedData::ScopedActionLock::~ScopedActionLock() noexcept
{
fData->nextAction.mutex.unlock();
}

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

CARLA_BACKEND_END_NAMESPACE

+ 19
- 19
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -199,7 +199,7 @@ public:
return false; return false;
} }


pData->bufAudio.usePatchbay = (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY);
pData->bufAudio.isRack = (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK);


RtAudio::StreamParameters iParams, oParams; RtAudio::StreamParameters iParams, oParams;
bool deviceSet = false; bool deviceSet = false;
@@ -419,7 +419,7 @@ public:


pData->bufAudio.initPatchbay(); pData->bufAudio.initPatchbay();


if (pData->bufAudio.usePatchbay)
if (! pData->bufAudio.isRack)
{ {
// not implemented yet // not implemented yet
return false; return false;
@@ -428,7 +428,7 @@ public:
char strBuf[STR_MAX+1]; char strBuf[STR_MAX+1];
strBuf[STR_MAX] = '\0'; strBuf[STR_MAX] = '\0';


EngineRackBuffers* const rack(pData->bufAudio.rack);
AbstractEngineBuffer* const rack(pData->bufAudio.buffer);


// Main // Main
{ {
@@ -449,12 +449,12 @@ public:
else else
std::strncpy(strBuf, "Capture", STR_MAX); std::strncpy(strBuf, "Capture", STR_MAX);


callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf);
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf);


for (uint i=0; i < pData->bufAudio.inCount; ++i) for (uint i=0; i < pData->bufAudio.inCount; ++i)
{ {
std::snprintf(strBuf, STR_MAX, "capture_%i", i+1); std::snprintf(strBuf, STR_MAX, "capture_%i", i+1);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_IN, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO, 0.0f, strBuf);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO, 0.0f, strBuf);
} }
} }


@@ -465,18 +465,18 @@ public:
else else
std::strncpy(strBuf, "Playback", STR_MAX); std::strncpy(strBuf, "Playback", STR_MAX);


callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf);
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf);


for (uint i=0; i < pData->bufAudio.outCount; ++i) for (uint i=0; i < pData->bufAudio.outCount; ++i)
{ {
std::snprintf(strBuf, STR_MAX, "playback_%i", i+1); std::snprintf(strBuf, STR_MAX, "playback_%i", i+1);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_OUT, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, strBuf);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, strBuf);
} }
} }


// MIDI In // MIDI In
{ {
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Readable MIDI ports");
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Readable MIDI ports");


for (uint i=0, count=fDummyMidiIn.getPortCount(); i < count; ++i) for (uint i=0, count=fDummyMidiIn.getPortCount(); i < count; ++i)
{ {
@@ -486,13 +486,13 @@ public:
portNameToId.name[STR_MAX] = '\0'; portNameToId.name[STR_MAX] = '\0';
fUsedMidiIns.append(portNameToId); fUsedMidiIns.append(portNameToId);


callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_MIDI_IN, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_MIDI, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name);
} }
} }


// MIDI Out // MIDI Out
{ {
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Writable MIDI ports");
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Writable MIDI ports");


for (uint i=0, count=fDummyMidiOut.getPortCount(); i < count; ++i) for (uint i=0, count=fDummyMidiOut.getPortCount(); i < count; ++i)
{ {
@@ -502,7 +502,7 @@ public:
portNameToId.name[STR_MAX] = '\0'; portNameToId.name[STR_MAX] = '\0';
fUsedMidiOuts.append(portNameToId); fUsedMidiOuts.append(portNameToId);


callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_MIDI_OUT, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_MIDI, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name);
} }
} }


@@ -516,7 +516,7 @@ public:


ConnectionToId connectionToId; ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId; connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO_IN;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portOut = port; connectionToId.portOut = port;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1; connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1;
@@ -535,7 +535,7 @@ public:


ConnectionToId connectionToId; ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId; connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO_IN;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portOut = port; connectionToId.portOut = port;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2; connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2;
@@ -556,7 +556,7 @@ public:
connectionToId.id = rack->lastConnectionId; connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1; connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO_OUT;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portIn = port; connectionToId.portIn = port;


std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
@@ -575,7 +575,7 @@ public:
connectionToId.id = rack->lastConnectionId; connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2; connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO_OUT;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portIn = port; connectionToId.portIn = port;


std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
@@ -593,7 +593,7 @@ public:


ConnectionToId connectionToId; ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId; connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_MIDI_IN;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_MIDI;
connectionToId.portOut = midiPort.portId; connectionToId.portOut = midiPort.portId;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_MIDI_IN; connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_MIDI_IN;
@@ -613,7 +613,7 @@ public:
connectionToId.id = rack->lastConnectionId; connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_MIDI_OUT; connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_MIDI_OUT;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_MIDI_OUT;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_MIDI;
connectionToId.portIn = midiPort.portId; connectionToId.portIn = midiPort.portId;


std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
@@ -697,12 +697,12 @@ protected:
fMidiInEvents.mutex.unlock(); fMidiInEvents.mutex.unlock();
} }


if (pData->bufAudio.usePatchbay)
if (pData->bufAudio.isRack)
{ {
pData->processRackFull(fAudioBufIn, pData->bufAudio.inCount, fAudioBufOut, pData->bufAudio.outCount, nframes, false);
} }
else else
{ {
pData->processRackFull(fAudioBufIn, pData->bufAudio.inCount, fAudioBufOut, pData->bufAudio.outCount, nframes, false);
} }


// output audio // output audio


Loading…
Cancel
Save