Browse Source

More patchbay work, now for rtaudio

tags/1.9.4
falkTX 10 years ago
parent
commit
3162795d3f
7 changed files with 319 additions and 382 deletions
  1. +5
    -5
      source/backend/engine/CarlaEngine.cpp
  2. +21
    -8
      source/backend/engine/CarlaEngineInternal.cpp
  3. +5
    -7
      source/backend/engine/CarlaEngineInternal.hpp
  4. +66
    -67
      source/backend/engine/CarlaEngineJack.cpp
  5. +52
    -43
      source/backend/engine/CarlaEngineJuce.cpp
  6. +164
    -246
      source/backend/engine/CarlaEngineRtAudio.cpp
  7. +6
    -6
      source/backend/engine/Makefile

+ 5
- 5
source/backend/engine/CarlaEngine.cpp View File

@@ -616,7 +616,7 @@ uint CarlaEngine::getDriverCount()
if (jackbridge_is_ok())
count += 1;

#if 0 //ndef BUILD_BRIDGE
#ifndef BUILD_BRIDGE
count += getRtAudioApiCount();
# ifdef HAVE_JUCE
count += getJuceApiCount();
@@ -635,7 +635,7 @@ const char* CarlaEngine::getDriverName(const uint index2)
if (jackbridge_is_ok() && index-- == 0)
return "JACK";

#if 0 //ndef BUILD_BRIDGE
#ifndef BUILD_BRIDGE
if (index < getRtAudioApiCount())
return getRtAudioApiName(index);

@@ -663,7 +663,7 @@ const char* const* CarlaEngine::getDriverDeviceNames(const uint index2)
return ret;
}

#if 0 //ndef BUILD_BRIDGE
#ifndef BUILD_BRIDGE
if (index < getRtAudioApiCount())
return getRtAudioApiDeviceNames(index);

@@ -695,7 +695,7 @@ const EngineDriverDeviceInfo* CarlaEngine::getDriverDeviceInfo(const uint index2
return &devInfo;
}

#if 0 //ndef BUILD_BRIDGE
#ifndef BUILD_BRIDGE
if (index < getRtAudioApiCount())
return getRtAudioDeviceInfo(index, deviceName);

@@ -719,7 +719,7 @@ CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)
if (std::strcmp(driverName, "JACK") == 0)
return newJack();

#if 0 //ndef BUILD_BRIDGE
#ifndef BUILD_BRIDGE
// -------------------------------------------------------------------
// common



+ 21
- 8
source/backend/engine/CarlaEngineInternal.cpp View File

@@ -55,7 +55,7 @@ static uint getCarlaRackPortIdFromName(const char* const shortname) noexcept
// -----------------------------------------------------------------------
// RackGraph

const char* RackGraph::MIDI::getName(const bool isInput, const uint index) const
const char* RackGraph::MIDI::getName(const bool isInput, const uint index) const noexcept
{
for (LinkedList<PortNameToId>::Itenerator it = isInput ? ins.begin() : outs.begin(); it.valid(); it.next())
{
@@ -68,6 +68,19 @@ const char* RackGraph::MIDI::getName(const bool isInput, const uint index) const
return nullptr;
}

uint RackGraph::MIDI::getPortId(const bool isInput, const char portName[]) const noexcept
{
for (LinkedList<PortNameToId>::Itenerator it = isInput ? ins.begin() : outs.begin(); it.valid(); it.next())
{
const PortNameToId& port(it.getValue());

if (std::strcmp(port.name, portName) == 0)
return port.port;
}

return 0;
}

bool RackGraph::connect(CarlaEngine* const engine, const uint groupA, const uint portA, const uint groupB, const uint portB) noexcept
{
CARLA_SAFE_ASSERT_RETURN(engine != nullptr, false);
@@ -146,7 +159,7 @@ bool RackGraph::connect(CarlaEngine* const engine, const uint groupA, const uint
return false;
}

ConnectionToId connectionToId = { ++lastConnectionId, groupA, portA, groupB, portB };
ConnectionToId connectionToId = { ++connections.lastId, groupA, portA, groupB, portB };

char strBuf[STR_MAX+1];
strBuf[STR_MAX] = '\0';
@@ -154,16 +167,16 @@ bool RackGraph::connect(CarlaEngine* const engine, const uint groupA, const uint

engine->callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);

audio.usedConnections.append(connectionToId);
connections.list.append(connectionToId);
return true;
}

bool RackGraph::disconnect(CarlaEngine* const engine, const uint connectionId) noexcept
{
CARLA_SAFE_ASSERT_RETURN(engine != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(audio.usedConnections.count() > 0, false);
CARLA_SAFE_ASSERT_RETURN(connections.list.count() > 0, false);

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

@@ -240,7 +253,7 @@ bool RackGraph::disconnect(CarlaEngine* const engine, const uint connectionId) n

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

audio.usedConnections.remove(it);
connections.list.remove(it);
return true;
}

@@ -250,14 +263,14 @@ bool RackGraph::disconnect(CarlaEngine* const engine, const uint connectionId) n

const char* const* RackGraph::getConnections() const
{
if (audio.usedConnections.count() == 0)
if (connections.list.count() == 0)
return nullptr;

LinkedList<const char*> connList;
char strBuf[STR_MAX+1];
strBuf[STR_MAX] = '\0';

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



+ 5
- 7
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -80,7 +80,7 @@ enum RackGraphCarlaPortIds {
// RackGraph

struct RackGraph {
uint lastConnectionId;
PatchbayConnectionList connections;

struct Audio {
CarlaMutex mutex;
@@ -88,18 +88,17 @@ struct RackGraph {
LinkedList<uint> connectedIn2;
LinkedList<uint> connectedOut1;
LinkedList<uint> connectedOut2;
LinkedList<ConnectionToId> usedConnections;
} audio;

struct MIDI {
LinkedList<PortNameToId> ins;
LinkedList<PortNameToId> outs;

const char* getName(const bool isInput, const uint index) const;
const char* getName(const bool isInput, const uint index) const noexcept;
uint getPortId(const bool isInput, const char portName[]) const noexcept;
} midi;

RackGraph() noexcept
: lastConnectionId(0) {}
RackGraph() noexcept {}

~RackGraph() noexcept
{
@@ -108,14 +107,13 @@ struct RackGraph {

void clear() noexcept
{
lastConnectionId = 0;
connections.clear();

audio.mutex.lock();
audio.connectedIn1.clear();
audio.connectedIn2.clear();
audio.connectedOut1.clear();
audio.connectedOut2.clear();
audio.usedConnections.clear();
audio.mutex.unlock();

midi.ins.clear();


+ 66
- 67
source/backend/engine/CarlaEngineJack.cpp View File

@@ -852,6 +852,8 @@ public:

bool init(const char* const clientName) override
{
CARLA_SAFE_ASSERT_RETURN(fClient == nullptr, false);
CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
carla_debug("CarlaEngineJack::init(\"%s\")", clientName);

fFreewheel = false;
@@ -863,7 +865,7 @@ public:
if (pData->bufferSize == 0 || pData->sampleRate == 0.0)
{
// open temp client to get initial buffer-size and sample-rate values
if (jack_client_t* tmpClient = jackbridge_client_open(clientName, JackNullOption, nullptr))
if (jack_client_t* const tmpClient = jackbridge_client_open(clientName, JackNullOption, nullptr))
{
pData->bufferSize = jackbridge_get_buffer_size(tmpClient);
pData->sampleRate = jackbridge_get_sample_rate(tmpClient);
@@ -876,60 +878,54 @@ public:

return CarlaEngine::init(clientName);
#else
fUsedGroups.clear();
fUsedPorts.clear();
fUsedConnections.clear();
fNewGroups.clear();

fClient = jackbridge_client_open(clientName, JackNullOption, nullptr);

if (fClient != nullptr)
if (fClient == nullptr)
{
pData->bufferSize = jackbridge_get_buffer_size(fClient);
pData->sampleRate = jackbridge_get_sample_rate(fClient);
setLastError("Failed to create new JACK client");
return false;
}

jackbridge_set_thread_init_callback(fClient, carla_jack_thread_init_callback, nullptr);
jackbridge_set_buffer_size_callback(fClient, carla_jack_bufsize_callback, this);
jackbridge_set_sample_rate_callback(fClient, carla_jack_srate_callback, this);
jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this);
jackbridge_set_latency_callback(fClient, carla_jack_latency_callback, this);
jackbridge_set_process_callback(fClient, carla_jack_process_callback, this);
jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this);
pData->bufferSize = jackbridge_get_buffer_size(fClient);
pData->sampleRate = jackbridge_get_sample_rate(fClient);

const char* const jackClientName(jackbridge_get_client_name(fClient));
jackbridge_set_thread_init_callback(fClient, carla_jack_thread_init_callback, nullptr);
jackbridge_set_buffer_size_callback(fClient, carla_jack_bufsize_callback, this);
jackbridge_set_sample_rate_callback(fClient, carla_jack_srate_callback, this);
jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this);
jackbridge_set_latency_callback(fClient, carla_jack_latency_callback, this);
jackbridge_set_process_callback(fClient, carla_jack_process_callback, this);
jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this);

initJackPatchbay(jackClientName);
const char* const jackClientName(jackbridge_get_client_name(fClient));

jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this);
jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this);
jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this);
jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this);
initJackPatchbay(jackClientName);

if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
{
fRackPorts[kRackPortAudioIn1] = jackbridge_port_register(fClient, "audio-in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fRackPorts[kRackPortAudioIn2] = jackbridge_port_register(fClient, "audio-in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fRackPorts[kRackPortAudioOut1] = jackbridge_port_register(fClient, "audio-out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fRackPorts[kRackPortAudioOut2] = jackbridge_port_register(fClient, "audio-out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fRackPorts[kRackPortEventIn] = jackbridge_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
fRackPorts[kRackPortEventOut] = jackbridge_port_register(fClient, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
}
jackbridge_set_client_registration_callback(fClient, carla_jack_client_registration_callback, this);
jackbridge_set_port_registration_callback(fClient, carla_jack_port_registration_callback, this);
jackbridge_set_port_connect_callback(fClient, carla_jack_port_connect_callback, this);
jackbridge_set_port_rename_callback(fClient, carla_jack_port_rename_callback, this);

if (jackbridge_activate(fClient))
{
CarlaEngine::init(jackClientName);
return true;
}
else
{
setLastError("Failed to activate the JACK client");
jackbridge_client_close(fClient);
fClient = nullptr;
}
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
{
fRackPorts[kRackPortAudioIn1] = jackbridge_port_register(fClient, "audio-in1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fRackPorts[kRackPortAudioIn2] = jackbridge_port_register(fClient, "audio-in2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
fRackPorts[kRackPortAudioOut1] = jackbridge_port_register(fClient, "audio-out1", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fRackPorts[kRackPortAudioOut2] = jackbridge_port_register(fClient, "audio-out2", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
fRackPorts[kRackPortEventIn] = jackbridge_port_register(fClient, "events-in", JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0);
fRackPorts[kRackPortEventOut] = jackbridge_port_register(fClient, "events-out", JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0);
}
else
setLastError("Failed to create new JACK client");

if (jackbridge_activate(fClient))
{
CarlaEngine::init(jackClientName);
return true;
}

jackbridge_client_close(fClient);
fClient = nullptr;

setLastError("Failed to activate the JACK client");
return false;
#endif
}
@@ -994,14 +990,16 @@ public:
for (LinkedList<uint>::Itenerator it = newPlugins.begin(); it.valid(); it.next())
{
const uint groupId(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(groupId > 0);

const char* const groupName(fUsedGroups.getGroupName(groupId));
CARLA_SAFE_ASSERT_CONTINUE(groupId > 0 && groupName != nullptr && groupName[0] != '\0');
CARLA_SAFE_ASSERT_CONTINUE(groupName != nullptr && groupName[0] != '\0');

int pluginId = -1;
PatchbayIcon icon = PATCHBAY_ICON_PLUGIN;

callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_DATA_CHANGED, groupId, icon, pluginId, 0.0f, nullptr);
findPluginIdAndIcon(groupName, pluginId, icon);
if (findPluginIdAndIcon(groupName, pluginId, icon))
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_DATA_CHANGED, groupId, icon, pluginId, 0.0f, nullptr);
}

newPlugins.clear();
@@ -1034,41 +1032,40 @@ public:

CarlaEngineClient* addClient(CarlaPlugin* const plugin) override
{

jack_client_t* client = nullptr;

#ifdef BUILD_BRIDGE
client = fClient = jackbridge_client_open(plugin->getName(), JackNullOption, nullptr);

CARLA_SAFE_ASSERT_RETURN(client != nullptr, nullptr);

pData->bufferSize = jackbridge_get_buffer_size(client);
pData->sampleRate = jackbridge_get_sample_rate(client);

jackbridge_set_thread_init_callback(client, carla_jack_thread_init_callback, nullptr);
jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this);
jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this);
jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this);
jackbridge_set_latency_callback(client, carla_jack_latency_callback, this);
jackbridge_set_process_callback(client, carla_jack_process_callback, this);
jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this);
#else
#ifndef BUILD_BRIDGE
if (pData->options.processMode == ENGINE_PROCESS_MODE_SINGLE_CLIENT)
{
client = fClient;
}
else if (pData->options.processMode == ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
#endif
{
client = jackbridge_client_open(plugin->getName(), JackNullOption, nullptr);

CARLA_SAFE_ASSERT_RETURN(client != nullptr, nullptr);

jackbridge_set_thread_init_callback(client, carla_jack_thread_init_callback, nullptr);

#ifndef BUILD_BRIDGE
jackbridge_set_latency_callback(client, carla_jack_latency_callback_plugin, plugin);
jackbridge_set_process_callback(client, carla_jack_process_callback_plugin, plugin);
jackbridge_on_shutdown(client, carla_jack_shutdown_callback_plugin, plugin);
}
#else
fClient = client;
pData->bufferSize = jackbridge_get_buffer_size(client);
pData->sampleRate = jackbridge_get_sample_rate(client);

jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this);
jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this);
jackbridge_set_freewheel_callback(client, carla_jack_freewheel_callback, this);
jackbridge_set_latency_callback(client, carla_jack_latency_callback, this);
jackbridge_set_process_callback(client, carla_jack_process_callback, this);
jackbridge_on_shutdown(client, carla_jack_shutdown_callback, this);
#endif
}

return new CarlaEngineJackClient(*this, client);
}

@@ -1180,6 +1177,8 @@ public:
const char* const fullPortNameB = fUsedPorts.getFullPortName(groupB, portB);
CARLA_SAFE_ASSERT_RETURN(fullPortNameB != nullptr && fullPortNameB[0] != '\0', false);

carla_stdout("patchbayConnect(%u, %u, %u, %u => %s, %s)", groupA, portA, groupB, portB, fullPortNameA, fullPortNameB);

if (! jackbridge_connect(fClient, fullPortNameA, fullPortNameB))
{
setLastError("JACK operation failed");
@@ -2020,7 +2019,7 @@ private:
(void)portIsOSC;
}

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

void processPlugin(CarlaPlugin* const plugin, const uint32_t nframes)
{
@@ -2072,7 +2071,7 @@ private:
setPluginPeaks(plugin->getId(), inPeaks, outPeaks);
}

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

#define handlePtr ((CarlaEngineJack*)arg)



+ 52
- 43
source/backend/engine/CarlaEngineJuce.cpp View File

@@ -22,7 +22,7 @@
#include "CarlaEngineInternal.hpp"
#include "CarlaBackendUtils.hpp"

// #include "RtLinkedList.hpp"
#include "RtLinkedList.hpp"

#include "juce_audio_devices.h"

@@ -35,38 +35,51 @@ CARLA_BACKEND_START_NAMESPACE
#endif

// -------------------------------------------------------------------------------------------------------------------
// Global static data

static const char** gRetNames = nullptr;
static OwnedArray<AudioIODeviceType> gJuceDeviceTypes;

static void initJuceDevices()
{
static AudioDeviceManager manager;

if (gJuceDeviceTypes.size() == 0)
manager.createAudioDeviceTypes(gJuceDeviceTypes);
}

// -------------------------------------------------------------------------------------------------------------------
// Cleanup

static struct JuceCleanup {
JuceCleanup() {}
struct JuceCleanup {
JuceCleanup() noexcept {}
~JuceCleanup()
{
if (gRetNames != nullptr)
{
for (int i=0; gRetNames[i] != nullptr; ++i)
delete[] gRetNames[i];

delete[] gRetNames;
gRetNames = nullptr;
}

gJuceDeviceTypes.clear(true);
}
} sJuceCleanup;
};

// -------------------------------------------------------------------------------------------------------------------
// Cleanup

static void initJuceDevicesIfNeeded()
{
static const JuceCleanup sJuceCleanup;
static AudioDeviceManager sDeviceManager;
static bool needsInit = true;

if (! needsInit)
return;

needsInit = false;

sDeviceManager.createAudioDeviceTypes(gJuceDeviceTypes);

// maybe remove devices used by rtaudio
}

// -------------------------------------------------------------------------------------------------------------------
// Juce Engine

#if 0
class CarlaEngineJuce : public CarlaEngine,
public AudioIODeviceCallback
{
@@ -300,14 +313,15 @@ private:
ScopedPointer<AudioIODevice> fDevice;
AudioIODeviceType* const fDeviceType;

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJuce)
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJuce)
};
#endif

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

CarlaEngine* CarlaEngine::newJuce(const AudioApi api)
{
initJuceDevices();
initJuceDevicesIfNeeded();

String juceApi;

@@ -352,44 +366,43 @@ CarlaEngine* CarlaEngine::newJuce(const AudioApi api)

deviceType->scanForDevices();

return new CarlaEngineJuce(deviceType);
return nullptr;
//return new CarlaEngineJuce(deviceType);
}

uint CarlaEngine::getJuceApiCount()
{
return 0; // TODO

initJuceDevices();
initJuceDevicesIfNeeded();

return static_cast<uint>(gJuceDeviceTypes.size());
}

const char* CarlaEngine::getJuceApiName(const uint index)
const char* CarlaEngine::getJuceApiName(const uint uindex)
{
initJuceDevices();
initJuceDevicesIfNeeded();

if (static_cast<int>(index) >= gJuceDeviceTypes.size())
return nullptr;
const int index(static_cast<int>(uindex));

AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
CARLA_SAFE_ASSERT_RETURN(index < gJuceDeviceTypes.size(), nullptr);

if (deviceType == nullptr)
return nullptr;
AudioIODeviceType* const deviceType(gJuceDeviceTypes[index]);
CARLA_SAFE_ASSERT_RETURN(deviceType != nullptr, nullptr);

return deviceType->getTypeName().toRawUTF8();
}

const char* const* CarlaEngine::getJuceApiDeviceNames(const uint index)
const char* const* CarlaEngine::getJuceApiDeviceNames(const uint uindex)
{
initJuceDevices();
initJuceDevicesIfNeeded();

if (static_cast<int>(index) >= gJuceDeviceTypes.size())
return nullptr;
const int index(static_cast<int>(uindex));

AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
CARLA_SAFE_ASSERT_RETURN(index < gJuceDeviceTypes.size(), nullptr);

if (deviceType == nullptr)
return nullptr;
AudioIODeviceType* const deviceType(gJuceDeviceTypes[index]);
CARLA_SAFE_ASSERT_RETURN(deviceType != nullptr, nullptr);

deviceType->scanForDevices();

@@ -416,20 +429,16 @@ const char* const* CarlaEngine::getJuceApiDeviceNames(const uint index)
return gRetNames;
}

const EngineDriverDeviceInfo* CarlaEngine::getJuceDeviceInfo(const uint index, const char* const deviceName)
const EngineDriverDeviceInfo* CarlaEngine::getJuceDeviceInfo(const uint uindex, const char* const deviceName)
{
initJuceDevices();
initJuceDevicesIfNeeded();

if (static_cast<int>(index) >= gJuceDeviceTypes.size())
{
carla_stderr("here 001");
return nullptr;
}
const int index(static_cast<int>(uindex));

AudioIODeviceType* const deviceType(gJuceDeviceTypes[static_cast<int>(index)]);
CARLA_SAFE_ASSERT_RETURN(index < gJuceDeviceTypes.size(), nullptr);

if (deviceType == nullptr)
return nullptr;
AudioIODeviceType* const deviceType(gJuceDeviceTypes[index]);
CARLA_SAFE_ASSERT_RETURN(deviceType != nullptr, nullptr);

deviceType->scanForDevices();



+ 164
- 246
source/backend/engine/CarlaEngineRtAudio.cpp View File

@@ -44,9 +44,13 @@ struct RtAudioCleanup {
{
if (gRetNames != nullptr)
{
for (int i=0; gRetNames[i] != nullptr; ++i)
delete[] gRetNames[i];

delete[] gRetNames;
gRetNames = nullptr;
}

gRtAudioApis.clear();
}
};
@@ -172,13 +176,9 @@ public:
CarlaEngineRtAudio(const RtAudio::Api api)
: CarlaEngine(),
fAudio(api),
fAudioInBuf(nullptr),
fAudioInCount(0),
fAudioOutBuf(nullptr),
fAudioOutCount(0),
fLastEventTime(0),
fDummyMidiIn(getMatchedAudioMidiAPI(api), "Carla"),
fDummyMidiOut(getMatchedAudioMidiAPI(api), "Carla")
fLastEventTime(0)
{
carla_debug("CarlaEngineRtAudio::CarlaEngineRtAudio(%i)", api);

@@ -188,24 +188,21 @@ public:

~CarlaEngineRtAudio() override
{
CARLA_SAFE_ASSERT(fAudioInBuf == nullptr);
CARLA_SAFE_ASSERT(fAudioInCount == 0);
CARLA_SAFE_ASSERT(fAudioOutBuf == nullptr);
CARLA_SAFE_ASSERT(fAudioOutCount == 0);
CARLA_SAFE_ASSERT(fLastEventTime == 0);
carla_debug("CarlaEngineRtAudio::~CarlaEngineRtAudio()");

fUsedMidiIns.clear();
fUsedMidiOuts.clear();
fUsedMidiPorts.clear();
}

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

bool init(const char* const clientName) override
{
CARLA_SAFE_ASSERT_RETURN(fAudioInBuf == nullptr, false);
CARLA_SAFE_ASSERT_RETURN(fAudioInCount == 0, false);
CARLA_SAFE_ASSERT_RETURN(fAudioOutBuf == nullptr, false);
CARLA_SAFE_ASSERT_RETURN(fAudioOutCount == 0, false);
CARLA_SAFE_ASSERT_RETURN(fLastEventTime == 0, false);
CARLA_SAFE_ASSERT_RETURN(clientName != nullptr && clientName[0] != '\0', false);
carla_debug("CarlaEngineRtAudio::init(\"%s\")", clientName);

@@ -282,39 +279,9 @@ public:
pData->bufferSize = bufferFrames;
pData->sampleRate = fAudio.getStreamSampleRate();

fAudioInCount = iParams.nChannels;

if (fAudioInCount > 0)
{
fAudioInBuf = new float*[fAudioInCount];

// set as null first
for (uint i=0; i < fAudioInCount; ++i)
fAudioInBuf[i] = nullptr;

for (uint i=0; i < fAudioInCount; ++i)
{
fAudioInBuf[i] = new float[pData->bufferSize];
FLOAT_CLEAR(fAudioInBuf[i], pData->bufferSize);
}
}

fAudioInCount = iParams.nChannels;
fAudioOutCount = oParams.nChannels;

if (fAudioOutCount > 0)
{
fAudioOutBuf = new float*[fAudioOutCount];

// set as null first
for (uint i=0; i < fAudioOutCount; ++i)
fAudioOutBuf[i] = nullptr;

for (uint i=0; i < fAudioOutCount; ++i)
{
fAudioOutBuf[i] = new float[pData->bufferSize];
FLOAT_CLEAR(fAudioOutBuf[i], pData->bufferSize);
}
}
fLastEventTime = 0;

if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
{
@@ -349,7 +316,6 @@ public:

bool close() override
{
CARLA_SAFE_ASSERT(fAudioOutBuf != nullptr);
CARLA_SAFE_ASSERT(fAudioOutCount != 0);
carla_debug("CarlaEngineRtAudio::close()");

@@ -377,40 +343,6 @@ public:
fAudio.closeStream();
}

if (fAudioInBuf != nullptr)
{
for (uint i=0; i < fAudioInCount; ++i)
{
if (fAudioInBuf[i] != nullptr)
{
delete[] fAudioInBuf[i];
fAudioInBuf[i] = nullptr;
}
}

delete[] fAudioInBuf;
fAudioInBuf = nullptr;
}

fAudioInCount = 0;

if (fAudioOutBuf != nullptr)
{
for (uint i=0; i < fAudioOutCount; ++i)
{
if (fAudioOutBuf[i] != nullptr)
{
delete[] fAudioOutBuf[i];
fAudioOutBuf[i] = nullptr;
}
}

delete[] fAudioOutBuf;
fAudioOutBuf = nullptr;
}

fAudioOutCount = 0;

for (LinkedList<MidiPort>::Itenerator it = fMidiIns.begin(); it.valid(); it.next())
{
MidiPort& port(it.getValue());
@@ -428,13 +360,12 @@ public:
delete midiOutPort;
}

fAudioInCount = 0;
fAudioOutCount = 0;
fLastEventTime = 0;

fDeviceName.clear();

fMidiIns.clear();
fMidiOuts.clear();

fUsedMidiPorts.clear();
fMidiInEvents.clear();
//fMidiOutEvents.clear();

@@ -468,8 +399,7 @@ public:
{
CARLA_SAFE_ASSERT_RETURN(pData->audio.isReady, false);

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

if (pData->graph.isRack)
patchbayRefreshRack();
@@ -483,8 +413,7 @@ public:
{
RackGraph* const rack(pData->graph.rack);

rack->lastConnectionId = 0;
rack->usedConnections.clear();
rack->clear();

char strBuf[STR_MAX+1];
strBuf[STR_MAX] = '\0';
@@ -535,151 +464,141 @@ public:

// MIDI In
{
RtMidiIn midiIn(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), "carla-discovery");

callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_MIDI_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Readable MIDI ports");

for (uint i=0, count=fDummyMidiIn.getPortCount(); i < count; ++i)
for (uint i=0, count = midiIn.getPortCount(); i < count; ++i)
{
std::string portName(midiIn.getPortName(i));

std::snprintf(strBuf, STR_MAX, "Readable MIDI ports:%s", portName.c_str());

PortNameToId portNameToId;
portNameToId.port = static_cast<int>(i);
std::strncpy(portNameToId.name, fDummyMidiIn.getPortName(i).c_str(), STR_MAX);
portNameToId.name[STR_MAX] = '\0';
fUsedMidiIns.append(portNameToId);
portNameToId.setData(RACK_GRAPH_GROUP_MIDI_IN, i, portName.c_str(), strBuf);

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, portNameToId.group, static_cast<int>(portNameToId.port), PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name);

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_MIDI_IN, portNameToId.port, PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name);
rack->midi.ins.append(portNameToId);
}
}

// MIDI Out
{
RtMidiOut midiOut(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), "carla-discovery");

callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_GRAPH_GROUP_MIDI_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Writable MIDI ports");

for (uint i=0, count=fDummyMidiOut.getPortCount(); i < count; ++i)
for (uint i=0, count = midiOut.getPortCount(); i < count; ++i)
{
std::string portName(midiOut.getPortName(i));

std::snprintf(strBuf, STR_MAX, "Writable MIDI ports:%s", portName.c_str());

PortNameToId portNameToId;
portNameToId.port = static_cast<int>(i);
std::strncpy(portNameToId.name, fDummyMidiOut.getPortName(i).c_str(), STR_MAX);
portNameToId.name[STR_MAX] = '\0';
fUsedMidiOuts.append(portNameToId);
portNameToId.setData(RACK_GRAPH_GROUP_MIDI_OUT, i, portName.c_str(), strBuf);

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_MIDI_OUT, portNameToId.port, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, portNameToId.group, static_cast<int>(portNameToId.port), PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name);
}
}

// Connections
rack->connectLock.lock();
rack->audio.mutex.lock();

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

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupA = RACK_GRAPH_GROUP_AUDIO_IN;
connectionToId.portA = port;
connectionToId.groupB = RACK_GRAPH_GROUP_CARLA;
connectionToId.portB = RACK_GRAPH_CARLA_PORT_AUDIO_IN1;
connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN1);

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);

rack->connections.list.append(connectionToId);
}

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

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupA = RACK_GRAPH_GROUP_AUDIO_IN;
connectionToId.portA = port;
connectionToId.groupB = RACK_GRAPH_GROUP_CARLA;
connectionToId.portB = RACK_GRAPH_CARLA_PORT_AUDIO_IN2;
connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_AUDIO_IN, portId, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN2);

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);

rack->connections.list.append(connectionToId);
}

for (LinkedList<int>::Itenerator it = rack->connectedOut1.begin(); it.valid(); it.next())
for (LinkedList<uint>::Itenerator it = rack->audio.connectedOut1.begin(); it.valid(); it.next())
{
const int& port(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(fAudioOutCount));
const uint& portId(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount);

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupA = RACK_GRAPH_GROUP_CARLA;
connectionToId.portA = RACK_GRAPH_CARLA_PORT_AUDIO_OUT1;
connectionToId.groupB = RACK_GRAPH_GROUP_AUDIO_OUT;
connectionToId.portB = port;
connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT1, RACK_GRAPH_GROUP_AUDIO_OUT, portId);

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);

rack->connections.list.append(connectionToId);
}

for (LinkedList<int>::Itenerator it = rack->connectedOut2.begin(); it.valid(); it.next())
for (LinkedList<uint>::Itenerator it = rack->audio.connectedOut2.begin(); it.valid(); it.next())
{
const int& port(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(fAudioOutCount));
const uint& portId(it.getValue());
CARLA_SAFE_ASSERT_CONTINUE(portId < fAudioOutCount);

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupA = RACK_GRAPH_GROUP_CARLA;
connectionToId.portA = RACK_GRAPH_CARLA_PORT_AUDIO_OUT2;
connectionToId.groupB = RACK_GRAPH_GROUP_AUDIO_OUT;
connectionToId.portB = port;
connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, RACK_GRAPH_GROUP_AUDIO_OUT, portId);

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);

rack->connections.list.append(connectionToId);
}

rack->connectLock.unlock();
rack->audio.mutex.unlock();

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

const uint portId(rack->midi.getPortId(true, midiPort.name));
CARLA_SAFE_ASSERT_CONTINUE(portId > 0 && portId < rack->midi.ins.count());

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupA = RACK_GRAPH_GROUP_MIDI_IN;
connectionToId.portA = midiPort.portId;
connectionToId.groupB = RACK_GRAPH_GROUP_CARLA;
connectionToId.portB = RACK_GRAPH_CARLA_PORT_MIDI_IN;
connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, RACK_GRAPH_GROUP_AUDIO_OUT, portId);

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);

rack->connections.list.append(connectionToId);
}

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

const uint portId(rack->midi.getPortId(false, midiPort.name));
CARLA_SAFE_ASSERT_CONTINUE(portId > 0 && portId < rack->midi.outs.count());

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.groupA = RACK_GRAPH_GROUP_CARLA;
connectionToId.portA = RACK_GRAPH_CARLA_PORT_MIDI_OUT;
connectionToId.groupB = RACK_GRAPH_GROUP_MIDI_OUT;
connectionToId.portB = midiPort.portId;
connectionToId.setData(++(rack->connections.lastId), RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_OUT, RACK_GRAPH_GROUP_MIDI_OUT, portId);

std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupA, connectionToId.portA, connectionToId.groupB, connectionToId.portB);
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, 0, 0, 0.0f, strBuf);

rack->usedConnections.append(connectionToId);
++rack->lastConnectionId;
callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, connectionToId.id, 0, 0, 0.0f, strBuf);

rack->connections.list.append(connectionToId);
}
}

@@ -693,23 +612,27 @@ protected:
void handleAudioProcessCallback(void* outputBuffer, void* inputBuffer, uint nframes, double streamTime, RtAudioStreamStatus status)
{
// get buffers from RtAudio
float* const insPtr = (float*)inputBuffer;
float* const outsPtr = (float*)outputBuffer;
const float* const insPtr = (const float*)inputBuffer;
float* const outsPtr = (float*)outputBuffer;

// assert rtaudio buffers
CARLA_SAFE_ASSERT_RETURN(outputBuffer != nullptr,);
CARLA_SAFE_ASSERT_RETURN(nframes == pData->bufferSize,);
CARLA_SAFE_ASSERT_RETURN(outputBuffer != nullptr, runPendingRtEvents());
CARLA_SAFE_ASSERT_RETURN(pData->bufferSize == nframes, runPendingRtEvents());

if (! pData->audio.isReady)
return runPendingRtEvents();

// initialize rtaudio input
const float* inBuf[fAudioInCount];

for (uint i=0; i < fAudioInCount; ++i)
FLOAT_COPY(fAudioInBuf[i], insPtr+(nframes*i), nframes);
inBuf[i] = insPtr+(nframes*i);

// initialize rtaudio output
float* outBuf[fAudioOutCount];

for (uint i=0; i < fAudioOutCount; ++i)
FLOAT_CLEAR(fAudioOutBuf[i], nframes);
outBuf[i] = outsPtr+(nframes*i);

// initialize input events
carla_zeroStruct<EngineEvent>(pData->events.in, kMaxEngineEventInternalCount);
@@ -748,16 +671,12 @@ protected:

if (pData->graph.isRack)
{
pData->processRackFull(fAudioInBuf, fAudioInCount, fAudioOutBuf, fAudioOutCount, nframes, false);
pData->processRackFull(inBuf, fAudioInCount, outBuf, fAudioOutCount, nframes, false);
}
else
{
}

// output audio
for (uint i=0; i < fAudioOutCount; ++i)
FLOAT_COPY(outsPtr+(nframes*i), fAudioOutBuf[i], nframes);

// output events
{
// TODO
@@ -805,31 +724,31 @@ protected:
for (; i < EngineMidiEvent::kDataSize; ++i)
midiEvent.data[i] = 0;

fMidiInEvents.append(midiEvent);
fMidiInEvents.appendNonRT(midiEvent);
}

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

bool connectRackMidiInPort(const int portId) override
bool connectRackMidiInPort(const char* const portName) override
{
CARLA_SAFE_ASSERT_RETURN(fUsedMidiIns.count() > 0, false);
CARLA_SAFE_ASSERT_RETURN(portId >= 0, false);
CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(portId) < fUsedMidiIns.count(), false);
carla_debug("CarlaEngineRtAudio::connectRackMidiInPort(%i)", portId);

const PortNameToId fallback = { 0, { '\0' } };
const char* const portName(fUsedMidiIns.getAt(static_cast<size_t>(portId), fallback).name);
CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false);
carla_debug("CarlaEngineRtAudio::connectRackMidiInPort(\"%s\")", portName);

char newPortName[STR_MAX+1];
std::snprintf(newPortName, STR_MAX, "%s:in-%i", getName(), portId+1);
RackGraph* const rack(pData->graph.rack);
CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false);

bool found = false;
uint rtMidiPortIndex;
CarlaString newRtMidiPortName;
newRtMidiPortName += getName();
newRtMidiPortName += ":";
newRtMidiPortName += portName;

RtMidiIn* const rtMidiIn(new RtMidiIn(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), newPortName, 512));
RtMidiIn* const rtMidiIn(new RtMidiIn(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), newRtMidiPortName.buffer(), 512));
rtMidiIn->ignoreTypes();
rtMidiIn->setCallback(carla_rtmidi_callback, this);

bool found = false;
uint rtMidiPortIndex;

for (uint i=0, count=rtMidiIn->getPortCount(); i < count; ++i)
{
if (rtMidiIn->getPortName(i) == portName)
@@ -846,35 +765,36 @@ protected:
return false;
}

rtMidiIn->openPort(rtMidiPortIndex, newPortName+(std::strlen(getName())+1));
rtMidiIn->openPort(rtMidiPortIndex, portName);

MidiPort midiPort;
midiPort.portId = portId;
midiPort.rtmidi = rtMidiIn;

fMidiIns.append(midiPort);
std::strncpy(midiPort.name, portName, STR_MAX);
midiPort.name[STR_MAX] = '\0';

fMidiIns.append(midiPort);
return true;
}

bool connectRackMidiOutPort(const int portId) override
bool connectRackMidiOutPort(const char* const portName) override
{
CARLA_SAFE_ASSERT_RETURN(fUsedMidiOuts.count() > 0, false);
CARLA_SAFE_ASSERT_RETURN(portId >= 0, false);
CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(portId) < fUsedMidiOuts.count(), false);
carla_debug("CarlaEngineRtAudio::connectRackMidiOutPort(%i)", portId);
CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false);
carla_debug("CarlaEngineRtAudio::connectRackMidiOutPort(\"%s\")", portName);

RackGraph* const rack(pData->graph.rack);
CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false);

const PortNameToId fallback = { 0, { '\0' } };
const char* const portName(fUsedMidiOuts.getAt(static_cast<size_t>(portId), fallback).name);
CarlaString newRtMidiPortName;
newRtMidiPortName += getName();
newRtMidiPortName += ":";
newRtMidiPortName += portName;

char newPortName[STR_MAX+1];
std::snprintf(newPortName, STR_MAX, "%s:out-%i", getName(), portId+1);
RtMidiOut* const rtMidiOut(new RtMidiOut(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), newRtMidiPortName.buffer()));

bool found = false;
uint rtMidiPortIndex;

RtMidiOut* const rtMidiOut(new RtMidiOut(getMatchedAudioMidiAPI(fAudio.getCurrentApi()), newPortName));

for (uint i=0, count=rtMidiOut->getPortCount(); i < count; ++i)
{
if (rtMidiOut->getPortName(i) == portName)
@@ -891,63 +811,67 @@ protected:
return false;
}

rtMidiOut->openPort(rtMidiPortIndex, newPortName+(std::strlen(getName())+1));
rtMidiOut->openPort(rtMidiPortIndex, portName);

MidiPort midiPort;
midiPort.portId = portId;
midiPort.rtmidi = rtMidiOut;

fMidiOuts.append(midiPort);
std::strncpy(midiPort.name, portName, STR_MAX);
midiPort.name[STR_MAX] = '\0';

fMidiOuts.append(midiPort);
return true;
}

bool disconnectRackMidiInPort(const int portId) override
// FIXME - this seems to be reversed
bool disconnectRackMidiInPort(const char* const portName) override
{
CARLA_SAFE_ASSERT_RETURN(fUsedMidiIns.count() > 0, false);
CARLA_SAFE_ASSERT_RETURN(portId >= 0, false);
CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(portId) < fUsedMidiIns.count(), false);
carla_debug("CarlaEngineRtAudio::connectRackMidiInPort(%i)", portId);
CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false);
carla_debug("CarlaEngineRtAudio::disconnectRackMidiInPort(\"%s\")", portName);

RackGraph* const rack(pData->graph.rack);
CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false);

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

if (midiPort.portId == portId)
{
RtMidiOut* const midiOutPort((RtMidiOut*)midiPort.rtmidi);
if (std::strcmp(midiPort.name, portName) != 0)
continue;

delete midiOutPort;
RtMidiOut* const midiOutPort((RtMidiOut*)midiPort.rtmidi);

fMidiOuts.remove(it);
return true;
}
delete midiOutPort;

fMidiOuts.remove(it);
return true;
}

return false;
}

bool disconnectRackMidiOutPort(const int portId) override
bool disconnectRackMidiOutPort(const char* const portName) override
{
CARLA_SAFE_ASSERT_RETURN(fUsedMidiOuts.count() > 0, false);
CARLA_SAFE_ASSERT_RETURN(portId >= 0, false);
CARLA_SAFE_ASSERT_RETURN(static_cast<size_t>(portId) < fUsedMidiOuts.count(), false);
carla_debug("CarlaEngineRtAudio::disconnectRackMidiOutPort(%i)", portId);
CARLA_SAFE_ASSERT_RETURN(portName != nullptr && portName[0] != '\0', false);
carla_debug("CarlaEngineRtAudio::disconnectRackMidiOutPort(\"%s\")", portName);

RackGraph* const rack(pData->graph.rack);
CARLA_SAFE_ASSERT_RETURN(rack->midi.ins.count() > 0, false);

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

if (midiPort.portId == portId)
{
RtMidiIn* const midiInPort((RtMidiIn*)midiPort.rtmidi);
if (std::strcmp(midiPort.name, portName) != 0)
continue;

midiInPort->cancelCallback();
delete midiInPort;
RtMidiIn* const midiInPort((RtMidiIn*)midiPort.rtmidi);

fMidiIns.remove(it);
return true;
}
midiInPort->cancelCallback();
delete midiInPort;

fMidiIns.remove(it);
return true;
}

return false;
@@ -958,29 +882,19 @@ protected:
private:
RtAudio fAudio;

// audio copy to split and de-interleave rtaudio buffers
float** fAudioInBuf;
uint fAudioInCount;

float** fAudioOutBuf;
uint fAudioOutCount;

// useful info
uint fAudioInCount;
uint fAudioOutCount;
uint64_t fLastEventTime;

// current device name
CarlaString fDeviceName;

// dummy rtmidi to scan available ports
RtMidiIn fDummyMidiIn;
RtMidiOut fDummyMidiOut;

LinkedList<PortNameToId> fUsedMidiIns;
LinkedList<PortNameToId> fUsedMidiOuts;
PatchbayPortList fUsedMidiPorts;

struct MidiPort {
RtMidi* rtmidi;
int portId;
char name[STR_MAX+1];
};

LinkedList<MidiPort> fMidiIns;
@@ -1008,7 +922,7 @@ private:
clear();
}

void append(const RtMidiEvent& event)
void appendNonRT(const RtMidiEvent& event)
{
mutex.lock();
dataPending.append(event);
@@ -1100,8 +1014,7 @@ const char* CarlaEngine::getRtAudioApiName(const uint index)
{
initRtAudioAPIsIfNeeded();

if (index >= gRtAudioApis.size())
return nullptr;
CARLA_SAFE_ASSERT_RETURN(index < gRtAudioApis.size(), nullptr);

return CarlaBackend::getRtAudioApiName(gRtAudioApis[index]);
}
@@ -1144,8 +1057,13 @@ const char* const* CarlaEngine::getRtAudioApiDeviceNames(const uint index)
gRetNames = new const char*[realDevCount+1];

for (size_t i=0; i < realDevCount; ++i)
{
gRetNames[i] = devNames.getAt(i, nullptr);

if (gRetNames[i] == nullptr)
gRetNames[i] = carla_strdup("(unknown)");
}

gRetNames[realDevCount] = nullptr;
devNames.clear();

@@ -1183,8 +1101,8 @@ const EngineDriverDeviceInfo* CarlaEngine::getRtAudioDeviceInfo(const uint index
return nullptr;

static EngineDriverDeviceInfo devInfo = { 0x0, nullptr, nullptr };
static uint32_t dummyBufferSizes[11] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 0 };
static double dummySampleRates[14] = { 22050.0, 32000.0, 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, 0.0 };
static uint32_t dummyBufferSizes[] = { 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 0 };
static double dummySampleRates[] = { 22050.0, 32000.0, 44100.0, 48000.0, 88200.0, 96000.0, 176400.0, 192000.0, 0.0 };

// reset
devInfo.hints = 0x0;


+ 6
- 6
source/backend/engine/Makefile View File

@@ -15,13 +15,13 @@ OBJS = \
CarlaEngineThread.cpp.o

OBJSa = $(OBJS) \
CarlaEngineJack.cpp.o
# CarlaEngineRtAudio.cpp.o
CarlaEngineJack.cpp.o \
CarlaEngineRtAudio.cpp.o

# ifeq ($(HAVE_JUCE),true)
# OBJSa += \
# CarlaEngineJuce.cpp.o
# endif
ifeq ($(HAVE_JUCE),true)
OBJSa += \
CarlaEngineJuce.cpp.o
endif

ifneq ($(WIN32),true)
OBJSa += \


Loading…
Cancel
Save