Browse Source

More work

tags/1.9.4
falkTX 10 years ago
parent
commit
94ac5581e1
9 changed files with 582 additions and 658 deletions
  1. +6
    -6
      source/backend/CarlaEngine.hpp
  2. +273
    -32
      source/backend/engine/CarlaEngine.cpp
  3. +246
    -35
      source/backend/engine/CarlaEngineInternal.cpp
  4. +4
    -17
      source/backend/engine/CarlaEngineInternal.hpp
  5. +3
    -3
      source/backend/engine/CarlaEngineJack.cpp
  6. +15
    -101
      source/backend/engine/CarlaEngineJuce.cpp
  7. +6
    -6
      source/backend/engine/CarlaEngineNative.cpp
  8. +0
    -216
      source/backend/engine/CarlaEnginePort.cpp
  9. +29
    -242
      source/backend/engine/CarlaEngineRtAudio.cpp

+ 6
- 6
source/backend/CarlaEngine.hpp View File

@@ -232,12 +232,12 @@ struct EngineOptions {
bool preferUiBridges;
bool uisAlwaysOnTop;

unsigned int maxParameters;
unsigned int uiBridgesTimeout;
unsigned int audioNumPeriods;
unsigned int audioBufferSize;
unsigned int audioSampleRate;
const char* audioDevice;
uint maxParameters;
uint uiBridgesTimeout;
uint audioNumPeriods;
uint audioBufferSize;
uint audioSampleRate;
const char* audioDevice;

const char* binaryDir;
const char* resourceDir;


+ 273
- 32
source/backend/engine/CarlaEngine.cpp View File

@@ -48,6 +48,11 @@ CARLA_BACKEND_START_NAMESPACE
} // Fix editor indentation
#endif

// -----------------------------------------------------------------------
// Fallback data

static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} };

// -----------------------------------------------------------------------
// EngineControlEvent

@@ -300,6 +305,217 @@ bool EngineTimeInfo::operator!=(const EngineTimeInfo& timeInfo) const noexcept
return !operator==(timeInfo);
}

// -----------------------------------------------------------------------
// Carla Engine port (Abstract)

CarlaEnginePort::CarlaEnginePort(const CarlaEngine& engine, const bool isInputPort) noexcept
: fEngine(engine),
fIsInput(isInputPort)
{
carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInputPort));
}

CarlaEnginePort::~CarlaEnginePort() noexcept
{
carla_debug("CarlaEnginePort::~CarlaEnginePort()");
}

// -----------------------------------------------------------------------
// Carla Engine Audio port

CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngine& engine, const bool isInputPort) noexcept
: CarlaEnginePort(engine, isInputPort),
fBuffer(nullptr)
{
carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInputPort));
}

CarlaEngineAudioPort::~CarlaEngineAudioPort() noexcept
{
carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()");
}

void CarlaEngineAudioPort::initBuffer() noexcept
{
}

// -----------------------------------------------------------------------
// Carla Engine CV port

CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInputPort) noexcept
: CarlaEnginePort(engine, isInputPort),
fBuffer(nullptr)
{
carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInputPort));
}

CarlaEngineCVPort::~CarlaEngineCVPort() noexcept
{
carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()");
}

void CarlaEngineCVPort::initBuffer() noexcept
{
}

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

CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInputPort) noexcept
: CarlaEnginePort(engine, isInputPort),
fBuffer(nullptr),
fProcessMode(engine.getProccessMode())
{
carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInputPort));

if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
fBuffer = new EngineEvent[kMaxEngineEventInternalCount];
}

CarlaEngineEventPort::~CarlaEngineEventPort() noexcept
{
carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()");

if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
{
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);

delete[] fBuffer;
fBuffer = nullptr;
}
}

void CarlaEngineEventPort::initBuffer() noexcept
{
if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE)
fBuffer = fEngine.getInternalEventBuffer(fIsInput);
else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput)
carla_zeroStruct<EngineEvent>(fBuffer, kMaxEngineEventInternalCount);
}

uint32_t CarlaEngineEventPort::getEventCount() const noexcept
{
CARLA_SAFE_ASSERT_RETURN(fIsInput, 0);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0);
CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0);

uint32_t i=0;

for (; i < kMaxEngineEventInternalCount; ++i)
{
if (fBuffer[i].type == kEngineEventTypeNull)
break;
}

return i;
}

const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent);
CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent);
CARLA_SAFE_ASSERT_RETURN(index < kMaxEngineEventInternalCount, kFallbackEngineEvent);

return fBuffer[index];
}

const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) const noexcept
{
return fBuffer[index];
}

bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) noexcept
{
CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false);
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);

if (type == kEngineControlEventTypeParameter) {
CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
}

// FIXME? should not fix range if midi-program
const float fixedValue(carla_fixValue<float>(0.0f, 1.0f, value));

for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
{
EngineEvent& event(fBuffer[i]);

if (event.type != kEngineEventTypeNull)
continue;

event.type = kEngineEventTypeControl;
event.time = time;
event.channel = channel;

event.ctrl.type = type;
event.ctrl.param = param;
event.ctrl.value = fixedValue;

return true;
}

carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full");
return false;
}

bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) noexcept
{
return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value);
}

bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) noexcept
{
CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false);
CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);

for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
{
EngineEvent& event(fBuffer[i]);

if (event.type != kEngineEventTypeNull)
continue;

event.type = kEngineEventTypeMidi;
event.time = time;
event.channel = channel;

event.midi.port = port;
event.midi.size = size;

event.midi.data[0] = uint8_t(MIDI_GET_STATUS_FROM_DATA(data));

uint8_t j=1;
for (; j < size; ++j)
event.midi.data[j] = data[j];
for (; j < EngineMidiEvent::kDataSize; ++j)
event.midi.data[j] = 0;

return true;
}

carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full");
return false;
}

bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) noexcept
{
return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), 0, size, data);
}

bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) noexcept
{
return writeMidiEvent(time, channel, midi.port, midi.size, midi.data);
}

// -----------------------------------------------------------------------
// Carla Engine client (Abstract)

@@ -510,44 +726,61 @@ CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)
if (std::strcmp(driverName, "JACK") == 0)
return newJack();

// -------------------------------------------------------------------
// common

if (std::strncmp(driverName, "JACK ", 5) == 0)
return newRtAudio(AUDIO_API_JACK);

// -------------------------------------------------------------------
// linux
#if 0//def HAVE_JUCE
if (std::strcmp(driverName, "ALSA") == 0)
{
#if 0//def HAVE_JUCE
return newJuce(AUDIO_API_ALSA);
#else
if (std::strcmp(driverName, "ALSA") == 0)
return newRtAudio(AUDIO_API_ALSA);
#endif
}

if (std::strcmp(driverName, "OSS") == 0)
return newRtAudio(AUDIO_API_OSS);
if (std::strcmp(driverName, "PulseAudio") == 0)
return newRtAudio(AUDIO_API_PULSE);

// -------------------------------------------------------------------
// macos
#if 0//def HAVE_JUCE
if (std::strcmp(driverName, "CoreAudio") == 0)
{
#if 0//def HAVE_JUCE
return newJuce(AUDIO_API_CORE);
#else
if (std::strcmp(driverName, "CoreAudio") == 0)
return newRtAudio(AUDIO_API_CORE);
#endif
}

// -------------------------------------------------------------------
// windows
#if 0//def HAVE_JUCE
if (std::strcmp(driverName, "ASIO") == 0)
{
#if 0//def HAVE_JUCE
return newJuce(AUDIO_API_ASIO);
if (std::strcmp(driverName, "DirectSound") == 0)
return newJuce(AUDIO_API_DS);
#else
if (std::strcmp(driverName, "ASIO") == 0)
return newRtAudio(AUDIO_API_ASIO);
#endif
}

if (std::strcmp(driverName, "DirectSound") == 0)
{
#if 0//def HAVE_JUCE
return newJuce(AUDIO_API_DS);
#else
return newRtAudio(AUDIO_API_DS);
#endif
}

carla_stderr("CarlaEngine::newDriverByName(\"%s\") - invalid driver name", driverName);
return nullptr;
@@ -603,8 +836,8 @@ bool CarlaEngine::init(const char* const clientName)

case ENGINE_PROCESS_MODE_CONTINUOUS_RACK:
pData->maxPluginNumber = MAX_RACK_PLUGINS;
pData->events.in = new EngineEvent[kMaxEngineEventInternalCount];
pData->events.out = new EngineEvent[kMaxEngineEventInternalCount];
pData->events.in = new EngineEvent[kMaxEngineEventInternalCount];
pData->events.out = new EngineEvent[kMaxEngineEventInternalCount];
break;

case ENGINE_PROCESS_MODE_PATCHBAY:
@@ -613,8 +846,8 @@ bool CarlaEngine::init(const char* const clientName)

case ENGINE_PROCESS_MODE_BRIDGE:
pData->maxPluginNumber = 1;
pData->events.in = new EngineEvent[kMaxEngineEventInternalCount];
pData->events.out = new EngineEvent[kMaxEngineEventInternalCount];
pData->events.in = new EngineEvent[kMaxEngineEventInternalCount];
pData->events.out = new EngineEvent[kMaxEngineEventInternalCount];
break;
}

@@ -633,8 +866,15 @@ bool CarlaEngine::init(const char* const clientName)
pData->plugins[i].clear();

pData->osc.init(clientName);

#ifndef BUILD_BRIDGE
pData->oscData = pData->osc.getControlData();

if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
{
pData->graph.isRack = (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK);
pData->graph.create();
}
#endif

pData->nextAction.ready();
@@ -662,9 +902,15 @@ bool CarlaEngine::close()
pData->nextAction.ready();

#ifndef BUILD_BRIDGE
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
{
pData->graph.clear();
}

if (pData->osc.isControlRegistered())
oscSend_control_exit();
#endif

pData->osc.close();
pData->oscData = nullptr;

@@ -1710,18 +1956,15 @@ bool CarlaEngine::patchbayConnect(const int groupA, const int portA, const int g
return false;
}

if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
if (pData->graph.isRack)
{
CARLA_SAFE_ASSERT_RETURN(pData->graph.rack != nullptr, nullptr);

return pData->graph.rack->connect(this, groupA, portA, groupB, portB);
}
else
{
CARLA_SAFE_ASSERT_RETURN(pData->graph.patchbay != nullptr, nullptr);

setLastError("Not implemented yet");
return false;
return pData->graph.patchbay->connect(this, groupA, portA, groupB, portB);
}
}

@@ -1729,17 +1972,17 @@ 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->audio.isReady, false);
CARLA_SAFE_ASSERT_RETURN(pData->audio.buffer != nullptr, false);
carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId);

if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
if (pData->graph.isRack)
{
return pData->audio.rack->disconnect(this, connectionId);
CARLA_SAFE_ASSERT_RETURN(pData->graph.rack != nullptr, nullptr);
return pData->graph.rack->disconnect(this, connectionId);
}
else
{
setLastError("Not implemented yet");
return false;
CARLA_SAFE_ASSERT_RETURN(pData->graph.patchbay != nullptr, nullptr);
return pData->graph.patchbay->disconnect(this, connectionId);
}
}

@@ -2029,17 +2272,15 @@ const char* const* CarlaEngine::getPatchbayConnections() const
{
carla_debug("CarlaEngine::getPatchbayConnections()");

if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
if (pData->graph.isRack)
{
CARLA_SAFE_ASSERT_RETURN(pData->audio.rack != nullptr, nullptr);
return pData->audio.rack->getConnections();
CARLA_SAFE_ASSERT_RETURN(pData->graph.rack != nullptr, nullptr);
return pData->graph.rack->getConnections();
}
else
{
CARLA_SAFE_ASSERT_RETURN(pData->audio.patchbay != nullptr, nullptr);

setLastError("Not implemented yet");
return nullptr;
CARLA_SAFE_ASSERT_RETURN(pData->graph.patchbay != nullptr, nullptr);
return pData->graph.patchbay->getConnections();
}
}

@@ -2049,13 +2290,13 @@ void CarlaEngine::restorePatchbayConnection(const char* const connSource, const
CARLA_SAFE_ASSERT_RETURN(connTarget != nullptr && connTarget[0] != '\0',);
carla_debug("CarlaEngine::restorePatchbayConnection(\"%s\", \"%s\")", connSource, connTarget);

#if 0
if (pData->audio.usePatchbay)
if (pData->graph.isRack)
{
// TODO
}
else
{
#if 0
int sourceGroup, targetGroup;
int sourcePort, targetPort;

@@ -2125,8 +2366,8 @@ void CarlaEngine::restorePatchbayConnection(const char* const connSource, const
CARLA_SAFE_ASSERT_RETURN(targetGroup == RACK_PATCHBAY_GROUP_MAX || targetPort == RACK_PATCHBAY_PORT_MAX,);

patchbayConnect(targetGroup, targetPort, sourceGroup, sourcePort);
}
#endif
}
}
#endif



+ 246
- 35
source/backend/engine/CarlaEngineInternal.cpp View File

@@ -237,9 +237,222 @@ bool RackGraph::disconnect(CarlaEngine* const engine, const uint connectionId) n
return false;
}

void RackGraph::refresh(CarlaEngine* const engine) noexcept
void RackGraph::refresh(CarlaEngine* const engine, const LinkedList<PortNameToId>& /*midiIns*/, const LinkedList<PortNameToId>& /*midiOuts*/) noexcept
{
CARLA_SAFE_ASSERT_RETURN(engine != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(engine != nullptr,);

#if 0
CARLA_SAFE_ASSERT_RETURN(pData->audio.isReady, false);

fUsedMidiIns.clear();
fUsedMidiOuts.clear();

pData->audio.initPatchbay();

if (! pData->audio.isRack)
{
// not implemented yet
return false;
}

char strBuf[STR_MAX+1];
strBuf[STR_MAX] = '\0';

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

// Main
{
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_CARLA, PATCHBAY_ICON_CARLA, -1, 0.0f, getName());

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in1");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in2");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out1");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out2");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_MIDI_IN, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, "midi-in");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_MIDI_OUT, PATCHBAY_PORT_TYPE_MIDI, 0.0f, "midi-out");
}

// Audio In
{
if (fDeviceName.isNotEmpty())
std::snprintf(strBuf, STR_MAX, "Capture (%s)", fDeviceName.buffer());
else
std::strncpy(strBuf, "Capture", STR_MAX);

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

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

// Audio Out
{
if (fDeviceName.isNotEmpty())
std::snprintf(strBuf, STR_MAX, "Playback (%s)", fDeviceName.buffer());
else
std::strncpy(strBuf, "Playback", STR_MAX);

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

for (uint i=0; i < pData->audio.outCount; ++i)
{
std::snprintf(strBuf, STR_MAX, "playback_%i", i+1);
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
{
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)
{
PortNameToId portNameToId;
portNameToId.portId = static_cast<int>(i);
std::strncpy(portNameToId.name, fDummyMidiIn.getPortName(i).c_str(), STR_MAX);
portNameToId.name[STR_MAX] = '\0';
fUsedMidiIns.append(portNameToId);

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

// MIDI Out
{
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)
{
PortNameToId portNameToId;
portNameToId.portId = static_cast<int>(i);
std::strncpy(portNameToId.name, fDummyMidiOut.getPortName(i).c_str(), STR_MAX);
portNameToId.name[STR_MAX] = '\0';
fUsedMidiOuts.append(portNameToId);

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

// Connections
rack->connectLock.enter();

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>(pData->audio.inCount));

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portOut = port;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

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>(pData->audio.inCount));

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portOut = port;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

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>(pData->audio.outCount));

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portIn = port;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

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>(pData->audio.outCount));

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portIn = port;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

pData->audio.rack->connectLock.leave();

for (LinkedList<MidiPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next())
{
const MidiPort& midiPort(it.getValue());

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_MIDI;
connectionToId.portOut = midiPort.portId;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_MIDI_IN;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

for (LinkedList<MidiPort>::Itenerator it=fMidiOuts.begin(); it.valid(); it.next())
{
const MidiPort& midiPort(it.getValue());

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_MIDI_OUT;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_MIDI;
connectionToId.portIn = midiPort.portId;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}
#endif
}

const char* const* RackGraph::getConnections() const
@@ -339,9 +552,9 @@ bool PatchbayGraph::disconnect(CarlaEngine* const engine, const uint /*connectio
return false;
}

void PatchbayGraph::refresh(CarlaEngine* const engine) noexcept
void PatchbayGraph::refresh(CarlaEngine* const engine, const LinkedList<PortNameToId>& /*midiIns*/, const LinkedList<PortNameToId>& /*midiOuts*/) noexcept
{
CARLA_SAFE_ASSERT_RETURN(engine != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(engine != nullptr,);
}

const char* const* PatchbayGraph::getConnections() const
@@ -463,8 +676,8 @@ void CarlaEngineProtectedData::doNextPluginAction(const bool unlock) noexcept
#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,);
CARLA_SAFE_ASSERT_RETURN(events.in != nullptr,);
CARLA_SAFE_ASSERT_RETURN(events.out != nullptr,);

// safe copy
float inBuf0[frames];
@@ -480,7 +693,7 @@ void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2]
FLOAT_CLEAR(outBuf[1], frames);

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

bool processed = false;

@@ -506,9 +719,9 @@ void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2]
FLOAT_CLEAR(outBuf[1], frames);

// if plugin has no midi out, add previous events
if (oldMidiOutCount == 0 && bufEvents.in[0].type != kEngineEventTypeNull)
if (oldMidiOutCount == 0 && events.in[0].type != kEngineEventTypeNull)
{
if (bufEvents.out[0].type != kEngineEventTypeNull)
if (events.out[0].type != kEngineEventTypeNull)
{
// TODO: carefully add to input, sorted events
}
@@ -517,10 +730,10 @@ void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2]
else
{
// initialize event inputs from previous outputs
carla_copyStruct<EngineEvent>(bufEvents.in, bufEvents.out, kMaxEngineEventInternalCount);
carla_copyStruct<EngineEvent>(events.in, events.out, kMaxEngineEventInternalCount);

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

@@ -622,93 +835,91 @@ void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2]

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((EngineRackBuffers*)bufAudio.buffer);

const CarlaCriticalSectionScope _cs2(rack->connectLock);
const CarlaCriticalSectionScope _cs(graph.rack->connectLock);

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

for (LinkedList<int>::Itenerator it = rack->connectedIn1.begin(); it.valid(); it.next())
for (LinkedList<int>::Itenerator it = graph.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);
FLOAT_COPY(audio.inBuf[0], inBuf[port], nframes);
first = false;
}
else
{
FLOAT_ADD(rack->in[0], inBuf[port], nframes);
FLOAT_ADD(audio.inBuf[0], inBuf[port], nframes);
}
}

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

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

for (LinkedList<int>::Itenerator it = rack->connectedIn2.begin(); it.valid(); it.next())
for (LinkedList<int>::Itenerator it = graph.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);
FLOAT_COPY(audio.inBuf[1], inBuf[port], nframes);
first = false;
}
else
{
FLOAT_ADD(rack->in[1], inBuf[port], nframes);
FLOAT_ADD(audio.inBuf[1], inBuf[port], nframes);
}
}

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

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

// process
processRack(rack->in, rack->out, nframes, isOffline);
processRack(audio.inBuf, audio.outBuf, nframes, isOffline);

// connect output buffers
if (rack->connectedOut1.count() != 0)
if (graph.rack->connectedOut1.count() != 0)
{
for (LinkedList<int>::Itenerator it = rack->connectedOut1.begin(); it.valid(); it.next())
for (LinkedList<int>::Itenerator it = graph.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);
FLOAT_ADD(outBuf[port], audio.outBuf[0], nframes);
}
}

if (rack->connectedOut2.count() != 0)
if (graph.rack->connectedOut2.count() != 0)
{
for (LinkedList<int>::Itenerator it = rack->connectedOut2.begin(); it.valid(); it.next())
for (LinkedList<int>::Itenerator it = graph.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);
FLOAT_ADD(outBuf[port], audio.outBuf[1], nframes);
}
}
}


+ 4
- 17
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -45,6 +45,7 @@ CARLA_BACKEND_START_NAMESPACE

const unsigned short kMaxEngineEventInternalCount = 512;

#ifndef BUILD_BRIDGE
// -----------------------------------------------------------------------
// Rack Graph stuff

@@ -141,6 +142,7 @@ struct PatchbayGraph {

const char* const* getConnections() const;
};
#endif

// -----------------------------------------------------------------------
// InternalAudio
@@ -281,6 +283,7 @@ struct EngineInternalEvents {
CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalEvents)
};

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

@@ -329,25 +332,9 @@ struct EngineInternalGraph {
}
}

void init() noexcept
{
if (isRack)
{
CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);

rack->lastConnectionId = 0;
rack->usedConnections.clear();
}
else
{
CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);

// TODO
}
}

CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalGraph)
};
#endif

// -----------------------------------------------------------------------
// InternalTime


+ 3
- 3
source/backend/engine/CarlaEngineJack.cpp View File

@@ -1294,7 +1294,7 @@ protected:
float* outBuf[2] = { audioOut1, audioOut2 };

// initialize input events
carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kMaxEngineEventInternalCount);
carla_zeroStruct<EngineEvent>(pData->events.in, kMaxEngineEventInternalCount);
{
uint32_t engineEventIndex = 0;

@@ -1308,7 +1308,7 @@ protected:

CARLA_SAFE_ASSERT_CONTINUE(jackEvent.size <= 0xFF /* uint8_t max */);

EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);
EngineEvent& engineEvent(pData->events.in[engineEventIndex++]);

engineEvent.time = jackEvent.time;
engineEvent.fillFromMidiData(static_cast<uint8_t>(jackEvent.size), jackEvent.buffer);
@@ -1327,7 +1327,7 @@ protected:

for (unsigned short i=0; i < kMaxEngineEventInternalCount; ++i)
{
const EngineEvent& engineEvent(pData->bufEvents.out[i]);
const EngineEvent& engineEvent(pData->events.out[i]);

uint8_t size = 0;
uint8_t data[3] = { 0, 0, 0 };


+ 15
- 101
source/backend/engine/CarlaEngineJuce.cpp View File

@@ -100,8 +100,6 @@ public:
return false;
}

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

String deviceName;

if (pData->options.audioDevice != nullptr && pData->options.audioDevice[0] != '\0')
@@ -152,12 +150,12 @@ public:
pData->bufferSize = static_cast<uint32_t>(fDevice->getCurrentBufferSizeSamples());
pData->sampleRate = fDevice->getCurrentSampleRate();

pData->bufAudio.inCount = static_cast<uint32_t>(inputChannels.countNumberOfSetBits());
pData->bufAudio.outCount = static_cast<uint32_t>(outputChannels.countNumberOfSetBits());
pData->audio.inCount = static_cast<uint32_t>(inputChannels.countNumberOfSetBits());
pData->audio.outCount = static_cast<uint32_t>(outputChannels.countNumberOfSetBits());

CARLA_SAFE_ASSERT(pData->bufAudio.outCount > 0);
CARLA_SAFE_ASSERT(pData->audio.outCount > 0);

pData->bufAudio.create(pData->bufferSize);
pData->audio.create(pData->bufferSize);

fDevice->start(this);

@@ -171,7 +169,7 @@ public:
{
carla_debug("CarlaEngineJuce::close()");

pData->bufAudio.isReady = false;
pData->audio.isReady = false;

bool hasError = !CarlaEngine::close();

@@ -186,7 +184,7 @@ public:
fDevice = nullptr;
}

pData->bufAudio.clear();
pData->audio.clear();

return !hasError;
}
@@ -216,91 +214,7 @@ public:

bool patchbayRefresh() override
{
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false);

pData->bufAudio.initPatchbay();

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

char strBuf[STR_MAX+1];
strBuf[STR_MAX] = '\0';

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

// Main
{
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_CARLA, PATCHBAY_ICON_CARLA, -1, 0.0f, getName());

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_PORT_AUDIO_IN1, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in1");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_PORT_AUDIO_IN2, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in2");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_PORT_AUDIO_OUT1, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out1");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_PORT_AUDIO_OUT2, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out2");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_PORT_MIDI_IN, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, "midi-in");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_PORT_MIDI_OUT, PATCHBAY_PORT_TYPE_MIDI, 0.0f, "midi-out");
}

const String& deviceName(fDevice->getName());

// Audio In
{
if (deviceName.isNotEmpty())
std::snprintf(strBuf, STR_MAX, "Capture (%s)", deviceName.toRawUTF8());
else
std::strncpy(strBuf, "Capture", STR_MAX);

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

StringArray inputNames(fDevice->getInputChannelNames());
CARLA_SAFE_ASSERT(inputNames.size() == static_cast<int>(pData->bufAudio.inCount));

for (uint i=0; i < pData->bufAudio.inCount; ++i)
{
String inputName(inputNames[static_cast<int>(i)]);

if (inputName.trim().isNotEmpty())
std::snprintf(strBuf, STR_MAX, "%s", inputName.toRawUTF8());
else
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);
}
}

// Audio Out
{
if (deviceName.isNotEmpty())
std::snprintf(strBuf, STR_MAX, "Playback (%s)", deviceName.toRawUTF8());
else
std::strncpy(strBuf, "Playback", STR_MAX);

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

StringArray outputNames(fDevice->getOutputChannelNames());
CARLA_SAFE_ASSERT(outputNames.size() == static_cast<int>(pData->bufAudio.outCount));

for (uint i=0; i < pData->bufAudio.outCount; ++i)
{
String outputName(outputNames[static_cast<int>(i)]);

if (outputName.trim().isNotEmpty())
std::snprintf(strBuf, STR_MAX, "%s", outputName.toRawUTF8());
else
std::snprintf(strBuf, STR_MAX, "playback_%i", i+1);

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_OUT, static_cast<int>(i), static_cast<int>(PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT), 0.0f, strBuf);
}
}

// MIDI In

// MIDI Out

// Connections

// const String& deviceName(fDevice->getName());
return true;
}

@@ -310,28 +224,28 @@ protected:
void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) override
{
// assert juce buffers
CARLA_SAFE_ASSERT_RETURN(numInputChannels == static_cast<int>(pData->bufAudio.inCount),);
CARLA_SAFE_ASSERT_RETURN(numOutputChannels == static_cast<int>(pData->bufAudio.outCount),);
CARLA_SAFE_ASSERT_RETURN(numInputChannels == static_cast<int>(pData->audio.inCount),);
CARLA_SAFE_ASSERT_RETURN(numOutputChannels == static_cast<int>(pData->audio.outCount),);
CARLA_SAFE_ASSERT_RETURN(outputChannelData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(numSamples == static_cast<int>(pData->bufferSize),);

if (numOutputChannels == 0 || ! pData->bufAudio.isReady)
if (numOutputChannels == 0 || ! pData->audio.isReady)
return runPendingRtEvents();

// initialize input events
carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kMaxEngineEventInternalCount);
carla_zeroStruct<EngineEvent>(pData->events.in, kMaxEngineEventInternalCount);

// TODO - get events from juce

if (pData->bufAudio.usePatchbay)
{
}
else
if (pData->graph.isRack)
{
pData->processRackFull(const_cast<float**>(inputChannelData), static_cast<uint32_t>(numInputChannels),
outputChannelData, static_cast<uint32_t>(numOutputChannels),
static_cast<uint32_t>(numSamples), false);
}
else
{
}

// output events
{


+ 6
- 6
source/backend/engine/CarlaEngineNative.cpp View File

@@ -1067,8 +1067,8 @@ protected:
// ---------------------------------------------------------------
// initialize events

carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kMaxEngineEventInternalCount);
carla_zeroStruct<EngineEvent>(pData->bufEvents.out, kMaxEngineEventInternalCount);
carla_zeroStruct<EngineEvent>(pData->events.in, kMaxEngineEventInternalCount);
carla_zeroStruct<EngineEvent>(pData->events.out, kMaxEngineEventInternalCount);

// ---------------------------------------------------------------
// events input (before processing)
@@ -1079,7 +1079,7 @@ protected:
for (uint32_t i=0; i < midiEventCount && engineEventIndex < kMaxEngineEventInternalCount; ++i)
{
const NativeMidiEvent& midiEvent(midiEvents[i]);
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);
EngineEvent& engineEvent(pData->events.in[engineEventIndex++]);

engineEvent.time = midiEvent.time;
engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data);
@@ -1120,14 +1120,14 @@ protected:
// ---------------------------------------------------------------
// events output (after processing)

carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kMaxEngineEventInternalCount);
carla_zeroStruct<EngineEvent>(pData->events.in, kMaxEngineEventInternalCount);

{
NativeMidiEvent midiEvent;

for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
{
const EngineEvent& engineEvent(pData->bufEvents.out[i]);
const EngineEvent& engineEvent(pData->events.out[i]);

if (engineEvent.type == kEngineEventTypeNull)
break;
@@ -1137,7 +1137,7 @@ protected:
if (engineEvent.type == CarlaBackend::kEngineEventTypeControl)
{
midiEvent.port = 0;
engineEvent.ctrl.dumpToMidiData(engineEvent.channel, midiEvent.size, midiEvent.data);
engineEvent.ctrl.convertToMidiData(engineEvent.channel, midiEvent.size, midiEvent.data);
}
else if (engineEvent.type == kEngineEventTypeMidi)
{


+ 0
- 216
source/backend/engine/CarlaEnginePort.cpp View File

@@ -28,222 +28,6 @@ CARLA_BACKEND_START_NAMESPACE
} // Fix editor indentation
#endif

// -----------------------------------------------------------------------
// Fallback data

static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} };

// -----------------------------------------------------------------------
// Carla Engine port (Abstract)

CarlaEnginePort::CarlaEnginePort(const CarlaEngine& engine, const bool isInputPort) noexcept
: fEngine(engine),
fIsInput(isInputPort)
{
carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInputPort));
}

CarlaEnginePort::~CarlaEnginePort() noexcept
{
carla_debug("CarlaEnginePort::~CarlaEnginePort()");
}

// -----------------------------------------------------------------------
// Carla Engine Audio port

CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngine& engine, const bool isInputPort) noexcept
: CarlaEnginePort(engine, isInputPort),
fBuffer(nullptr)
{
carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInputPort));
}

CarlaEngineAudioPort::~CarlaEngineAudioPort() noexcept
{
carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()");
}

void CarlaEngineAudioPort::initBuffer() noexcept
{
}

// -----------------------------------------------------------------------
// Carla Engine CV port

CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInputPort) noexcept
: CarlaEnginePort(engine, isInputPort),
fBuffer(nullptr)
{
carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInputPort));
}

CarlaEngineCVPort::~CarlaEngineCVPort() noexcept
{
carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()");
}

void CarlaEngineCVPort::initBuffer() noexcept
{
}

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

CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInputPort) noexcept
: CarlaEnginePort(engine, isInputPort),
fBuffer(nullptr),
fProcessMode(engine.getProccessMode())
{
carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInputPort));

if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
fBuffer = new EngineEvent[kMaxEngineEventInternalCount];
}

CarlaEngineEventPort::~CarlaEngineEventPort() noexcept
{
carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()");

if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY)
{
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,);

delete[] fBuffer;
fBuffer = nullptr;
}
}

void CarlaEngineEventPort::initBuffer() noexcept
{
if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE)
fBuffer = fEngine.getInternalEventBuffer(fIsInput);
else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput)
carla_zeroStruct<EngineEvent>(fBuffer, kMaxEngineEventInternalCount);
}

uint32_t CarlaEngineEventPort::getEventCount() const noexcept
{
CARLA_SAFE_ASSERT_RETURN(fIsInput, 0);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0);
CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0);

uint32_t i=0;

for (; i < kMaxEngineEventInternalCount; ++i)
{
if (fBuffer[i].type == kEngineEventTypeNull)
break;
}

return i;
}

const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent);
CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent);
CARLA_SAFE_ASSERT_RETURN(index < kMaxEngineEventInternalCount, kFallbackEngineEvent);

return fBuffer[index];
}

const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) const noexcept
{
return fBuffer[index];
}

bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) noexcept
{
CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false);
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f);

if (type == kEngineControlEventTypeParameter) {
CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param));
}

// FIXME? should not fix range if midi-program
const float fixedValue(carla_fixValue<float>(0.0f, 1.0f, value));

for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
{
EngineEvent& event(fBuffer[i]);

if (event.type != kEngineEventTypeNull)
continue;

event.type = kEngineEventTypeControl;
event.time = time;
event.channel = channel;

event.ctrl.type = type;
event.ctrl.param = param;
event.ctrl.value = fixedValue;

return true;
}

carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full");
return false;
}

bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) noexcept
{
return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value);
}

bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) noexcept
{
CARLA_SAFE_ASSERT_RETURN(! fIsInput, false);
CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false);
CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false);
CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false);
CARLA_SAFE_ASSERT_RETURN(data != nullptr, false);

for (uint32_t i=0; i < kMaxEngineEventInternalCount; ++i)
{
EngineEvent& event(fBuffer[i]);

if (event.type != kEngineEventTypeNull)
continue;

event.type = kEngineEventTypeMidi;
event.time = time;
event.channel = channel;

event.midi.port = port;
event.midi.size = size;

event.midi.data[0] = uint8_t(MIDI_GET_STATUS_FROM_DATA(data));

uint8_t j=1;
for (; j < size; ++j)
event.midi.data[j] = data[j];
for (; j < EngineMidiEvent::kDataSize; ++j)
event.midi.data[j] = 0;

return true;
}

carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full");
return false;
}

bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) noexcept
{
return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), 0, size, data);
}

bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) noexcept
{
return writeMidiEvent(time, channel, midi.port, midi.size, midi.data);
}

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

CARLA_BACKEND_END_NAMESPACE

+ 29
- 242
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -199,8 +199,6 @@ public:
return false;
}

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

RtAudio::StreamParameters iParams, oParams;
bool deviceSet = false;

@@ -271,28 +269,28 @@ public:
pData->bufferSize = bufferFrames;
pData->sampleRate = fAudio.getStreamSampleRate();

pData->bufAudio.inCount = iParams.nChannels;
pData->bufAudio.outCount = oParams.nChannels;
pData->audio.inCount = iParams.nChannels;
pData->audio.outCount = oParams.nChannels;

CARLA_SAFE_ASSERT(pData->bufAudio.outCount > 0);
CARLA_SAFE_ASSERT(pData->audio.outCount > 0);

if (pData->bufAudio.inCount > 0)
if (pData->audio.inCount > 0)
{
fAudioBufIn = new float*[pData->bufAudio.inCount];
fAudioBufIn = new float*[pData->audio.inCount];

for (uint i=0; i < pData->bufAudio.inCount; ++i)
for (uint i=0; i < pData->audio.inCount; ++i)
fAudioBufIn[i] = new float[pData->bufferSize];
}

if (pData->bufAudio.outCount > 0)
if (pData->audio.outCount > 0)
{
fAudioBufOut = new float*[pData->bufAudio.outCount];
fAudioBufOut = new float*[pData->audio.outCount];

for (uint i=0; i < pData->bufAudio.outCount; ++i)
for (uint i=0; i < pData->audio.outCount; ++i)
fAudioBufOut[i] = new float[pData->bufferSize];
}

pData->bufAudio.create(pData->bufferSize);
pData->audio.create(pData->bufferSize);

try {
fAudio.startStream();
@@ -315,7 +313,7 @@ public:
CARLA_SAFE_ASSERT(fAudioBufOut != nullptr);
carla_debug("CarlaEngineRtAudio::close()");

pData->bufAudio.isReady = false;
pData->audio.isReady = false;

bool hasError = !CarlaEngine::close();

@@ -341,7 +339,7 @@ public:

if (fAudioBufIn != nullptr)
{
for (uint i=0; i < pData->bufAudio.inCount; ++i)
for (uint i=0; i < pData->audio.inCount; ++i)
delete[] fAudioBufIn[i];

delete[] fAudioBufIn;
@@ -350,14 +348,14 @@ public:

if (fAudioBufOut != nullptr)
{
for (uint i=0; i < pData->bufAudio.outCount; ++i)
for (uint i=0; i < pData->audio.outCount; ++i)
delete[] fAudioBufOut[i];

delete[] fAudioBufOut;
fAudioBufOut = nullptr;
}

pData->bufAudio.clear();
pData->audio.clear();

fDeviceName.clear();

@@ -412,217 +410,6 @@ public:

bool patchbayRefresh() override
{
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false);

fUsedMidiIns.clear();
fUsedMidiOuts.clear();

pData->bufAudio.initPatchbay();

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

char strBuf[STR_MAX+1];
strBuf[STR_MAX] = '\0';

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

// Main
{
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_CARLA, PATCHBAY_ICON_CARLA, -1, 0.0f, getName());

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in1");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in2");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out1");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out2");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_MIDI_IN, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, "midi-in");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_CARLA, RACK_PATCHBAY_CARLA_PORT_MIDI_OUT, PATCHBAY_PORT_TYPE_MIDI, 0.0f, "midi-out");
}

// Audio In
{
if (fDeviceName.isNotEmpty())
std::snprintf(strBuf, STR_MAX, "Capture (%s)", fDeviceName.buffer());
else
std::strncpy(strBuf, "Capture", STR_MAX);

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)
{
std::snprintf(strBuf, STR_MAX, "capture_%i", i+1);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO, 0.0f, strBuf);
}
}

// Audio Out
{
if (fDeviceName.isNotEmpty())
std::snprintf(strBuf, STR_MAX, "Playback (%s)", fDeviceName.buffer());
else
std::strncpy(strBuf, "Playback", STR_MAX);

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)
{
std::snprintf(strBuf, STR_MAX, "playback_%i", i+1);
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
{
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)
{
PortNameToId portNameToId;
portNameToId.portId = static_cast<int>(i);
std::strncpy(portNameToId.name, fDummyMidiIn.getPortName(i).c_str(), STR_MAX);
portNameToId.name[STR_MAX] = '\0';
fUsedMidiIns.append(portNameToId);

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

// MIDI Out
{
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)
{
PortNameToId portNameToId;
portNameToId.portId = static_cast<int>(i);
std::strncpy(portNameToId.name, fDummyMidiOut.getPortName(i).c_str(), STR_MAX);
portNameToId.name[STR_MAX] = '\0';
fUsedMidiOuts.append(portNameToId);

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

// Connections
rack->connectLock.enter();

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>(pData->bufAudio.inCount));

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portOut = port;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

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>(pData->bufAudio.inCount));

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portOut = port;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

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>(pData->bufAudio.outCount));

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portIn = port;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

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>(pData->bufAudio.outCount));

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO;
connectionToId.portIn = port;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

pData->bufAudio.rack->connectLock.leave();

for (LinkedList<MidiPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next())
{
const MidiPort& midiPort(it.getValue());

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_MIDI;
connectionToId.portOut = midiPort.portId;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_MIDI_IN;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

for (LinkedList<MidiPort>::Itenerator it=fMidiOuts.begin(); it.valid(); it.next())
{
const MidiPort& midiPort(it.getValue());

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA;
connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_MIDI_OUT;
connectionToId.groupIn = RACK_PATCHBAY_GROUP_MIDI;
connectionToId.portIn = midiPort.portId;

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
}

return true;
}

@@ -639,32 +426,32 @@ protected:
CARLA_SAFE_ASSERT_RETURN(outputBuffer != nullptr,);
CARLA_SAFE_ASSERT_RETURN(nframes == pData->bufferSize,);

if (pData->bufAudio.outCount == 0 || ! pData->bufAudio.isReady)
if (pData->audio.outCount == 0 || ! pData->audio.isReady)
return runPendingRtEvents();

// initialize rtaudio input
if (fIsAudioInterleaved)
{
for (unsigned int i=0, j=0, count=nframes*pData->bufAudio.inCount; i < count; ++i)
for (unsigned int i=0, j=0, count=nframes*pData->audio.inCount; i < count; ++i)
{
fAudioBufIn[i/pData->bufAudio.inCount][j] = insPtr[i];
fAudioBufIn[i/pData->audio.inCount][j] = insPtr[i];

if ((i+1) % pData->bufAudio.inCount == 0)
if ((i+1) % pData->audio.inCount == 0)
j += 1;
}
}
else
{
for (unsigned int i=0; i < pData->bufAudio.inCount; ++i)
for (unsigned int i=0; i < pData->audio.inCount; ++i)
FLOAT_COPY(fAudioBufIn[i], insPtr+(nframes*i), nframes);
}

// initialize rtaudio output
for (unsigned int i=0; i < pData->bufAudio.outCount; ++i)
for (unsigned int i=0; i < pData->audio.outCount; ++i)
FLOAT_CLEAR(fAudioBufOut[i], nframes);

// initialize input events
carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kMaxEngineEventInternalCount);
carla_zeroStruct<EngineEvent>(pData->events.in, kMaxEngineEventInternalCount);

if (fMidiInEvents.mutex.tryLock())
{
@@ -674,7 +461,7 @@ protected:
while (! fMidiInEvents.data.isEmpty())
{
const RtMidiEvent& midiEvent(fMidiInEvents.data.getFirst(true));
EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]);
EngineEvent& engineEvent(pData->events.in[engineEventIndex++]);

if (midiEvent.time < pData->timeInfo.frame)
{
@@ -697,9 +484,9 @@ protected:
fMidiInEvents.mutex.unlock();
}

if (pData->bufAudio.isRack)
if (pData->graph.isRack)
{
pData->processRackFull(fAudioBufIn, pData->bufAudio.inCount, fAudioBufOut, pData->bufAudio.outCount, nframes, false);
pData->processRackFull(fAudioBufIn, pData->audio.inCount, fAudioBufOut, pData->audio.outCount, nframes, false);
}
else
{
@@ -708,17 +495,17 @@ protected:
// output audio
if (fIsAudioInterleaved)
{
for (unsigned int i=0, j=0; i < nframes*pData->bufAudio.outCount; ++i)
for (unsigned int i=0, j=0; i < nframes*pData->audio.outCount; ++i)
{
outsPtr[i] = fAudioBufOut[i/pData->bufAudio.outCount][j];
outsPtr[i] = fAudioBufOut[i/pData->audio.outCount][j];

if ((i+1) % pData->bufAudio.outCount == 0)
if ((i+1) % pData->audio.outCount == 0)
j += 1;
}
}
else
{
for (unsigned int i=0; i < pData->bufAudio.outCount; ++i)
for (unsigned int i=0; i < pData->audio.outCount; ++i)
FLOAT_COPY(outsPtr+(nframes*i), fAudioBufOut[i], nframes);
}

@@ -738,7 +525,7 @@ protected:

void handleMidiCallback(double timeStamp, std::vector<unsigned char>* const message)
{
if (! pData->bufAudio.isReady)
if (! pData->audio.isReady)
return;

const size_t messageSize(message->size());


Loading…
Cancel
Save