Browse Source

Move a lot of rtaudio stuff around for common share with juce

tags/1.9.4
falkTX 11 years ago
parent
commit
747c8e8918
7 changed files with 1299 additions and 730 deletions
  1. +18
    -18
      source/backend/CarlaEngine.hpp
  2. +434
    -181
      source/backend/engine/CarlaEngine.cpp
  3. +228
    -0
      source/backend/engine/CarlaEngineInternal.hpp
  4. +1
    -1
      source/backend/engine/CarlaEngineJack.cpp
  5. +414
    -32
      source/backend/engine/CarlaEngineJuce.cpp
  6. +5
    -5
      source/backend/engine/CarlaEngineNative.cpp
  7. +199
    -493
      source/backend/engine/CarlaEngineRtAudio.cpp

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

@@ -951,12 +951,12 @@ public:
/*!
* Connect patchbay ports \a portA and \a portB.
*/
virtual bool patchbayConnect(int portA, int portB);
virtual bool patchbayConnect(const int portA, const int portB);

/*!
* Disconnect patchbay connection \a connectionId.
*/
virtual bool patchbayDisconnect(int connectionId);
virtual bool patchbayDisconnect(const int connectionId);

/*!
* Force the engine to resend all patchbay clients, ports and connections again.
@@ -1104,27 +1104,19 @@ protected:
*/
void setPluginPeaks(const unsigned int pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept;

#ifndef BUILD_BRIDGE
/*!
* Proccess audio buffer in rack mode.
* \note RT call
*/
void processRack(float* inBuf[2], float* outBuf[2], const uint32_t frames);
// -------------------------------------------------------------------

/*!
* Proccess audio buffer in patchbay mode.
* In \a bufCount, [0]=inBufCount and [1]=outBufCount
* \note RT call
*/
void processPatchbay(float** inBuf, float** outBuf, const uint32_t bufCount[2], const uint32_t frames);
#endif
virtual bool connectRackMidiInPort(const int) { return false; }
virtual bool connectRackMidiOutPort(const int) { return false; }
virtual bool disconnectRackMidiInPort(const int) { return false; }
virtual bool disconnectRackMidiOutPort(const int) { return false; }

// -------------------------------------------------------------------
// Engine initializers

private:
static CarlaEngine* newJack();

/*!
* Native audio APIs.
*/
enum AudioApi {
AUDIO_API_NULL = 0,
// common
@@ -1140,12 +1132,20 @@ private:
AUDIO_API_DS = 7
};

// -------------------------------------------------------------------
// Engine initializers

// jack
static CarlaEngine* newJack();

// rtaudio
static CarlaEngine* newRtAudio(const AudioApi api);
static unsigned int getRtAudioApiCount();
static const char* getRtAudioApiName(const unsigned int index);
static const char* const* getRtAudioApiDeviceNames(const unsigned int index);
static const EngineDriverDeviceInfo* getRtAudioDeviceInfo(const unsigned int index, const char* const deviceName);

// juce
static CarlaEngine* newJuce(const AudioApi api);
static unsigned int getJuceApiCount();
static const char* getJuceApiName(const unsigned int index);


+ 434
- 181
source/backend/engine/CarlaEngine.cpp View File

@@ -23,6 +23,7 @@
* - proper find&load plugins
* - uncomment CarlaPlugin::newAU and newCSOUND
* - something about the peaks?
* - patchbayDisconnect should return false sometimes
*/

#include "CarlaEngineInternal.hpp"
@@ -190,6 +191,262 @@ void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data
}
}

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

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

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

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

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

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

bool processed = false;

uint32_t oldAudioInCount = 0;
uint32_t oldMidiOutCount = 0;

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

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

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

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

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

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

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

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

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

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

#ifdef HAVE_JUCE
float tmpMin, tmpMax;

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

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

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

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

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

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

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

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

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

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

processed = true;
}
}

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

const CarlaMutex::ScopedLocker sl(rack->connectLock);

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

for (List<uint>::Itenerator it = rack->connectedIns[0].begin(); it.valid(); it.next())
{
const uint& port(it.getConstValue());
CARLA_SAFE_ASSERT_CONTINUE(port < inCount);

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

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

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

for (List<uint>::Itenerator it = rack->connectedIns[1].begin(); it.valid(); it.next())
{
const uint& port(it.getConstValue());
CARLA_SAFE_ASSERT_CONTINUE(port < inCount);

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

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

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

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

// connect output buffers
if (rack->connectedOuts[0].count() != 0)
{
for (List<uint>::Itenerator it = rack->connectedOuts[0].begin(); it.valid(); it.next())
{
const uint& port(it.getConstValue());
CARLA_SAFE_ASSERT_CONTINUE(port < outCount);

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

if (rack->connectedOuts[1].count() != 0)
{
for (List<uint>::Itenerator it = rack->connectedOuts[1].begin(); it.valid(); it.next())
{
const uint& port(it.getConstValue());
CARLA_SAFE_ASSERT_CONTINUE(port < outCount);

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

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

@@ -1606,16 +1863,187 @@ void CarlaEngine::setCallback(const EngineCallbackFunc func, void* const ptr)
// -----------------------------------------------------------------------
// Patchbay

bool CarlaEngine::patchbayConnect(int, int)
bool CarlaEngine::patchbayConnect(const int portA, const int portB)
{
setLastError("Unsupported operation");
return false;
CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false);
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false);
carla_debug("CarlaEngineRtAudio::patchbayConnect(%i, %i)", portA, portB);

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

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

CARLA_SAFE_ASSERT_RETURN_ERR(portA > RACK_PATCHBAY_PORT_MAX, "Invalid output port");
CARLA_SAFE_ASSERT_RETURN_ERR(portB > RACK_PATCHBAY_PORT_MAX, "Invalid input port");

// only allow connections between Carla and other ports
if (portA < 0 && portB < 0)
{
setLastError("Invalid connection (1)");
return false;
}
if (portA >= 0 && portB >= 0)
{
setLastError("Invalid connection (2)");
return false;
}

const int carlaPort = (portA < 0) ? portA : portB;
const int targetPort = (carlaPort == portA) ? portB : portA;
bool makeConnection = false;

switch (carlaPort)
{
case RACK_PATCHBAY_PORT_AUDIO_IN1:
CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999);
rack->connectLock.lock();
rack->connectedIns[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
rack->connectLock.unlock();
makeConnection = true;
break;

case RACK_PATCHBAY_PORT_AUDIO_IN2:
CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999);
rack->connectLock.lock();
rack->connectedIns[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000);
rack->connectLock.unlock();
makeConnection = true;
break;

case RACK_PATCHBAY_PORT_AUDIO_OUT1:
CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999);
rack->connectLock.lock();
rack->connectedOuts[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
rack->connectLock.unlock();
makeConnection = true;
break;

case RACK_PATCHBAY_PORT_AUDIO_OUT2:
CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999);
rack->connectLock.lock();
rack->connectedOuts[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);
rack->connectLock.unlock();
makeConnection = true;
break;

case RACK_PATCHBAY_PORT_MIDI_IN:
CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000);
CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_IN*1000+999);
makeConnection = connectRackMidiInPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_IN*1000);
break;

case RACK_PATCHBAY_PORT_MIDI_OUT:
CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_OUT*1000+999);
makeConnection = connectRackMidiOutPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
break;
}

if (! makeConnection)
{
setLastError("Invalid connection (3)");
return false;
}

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.portOut = portA;
connectionToId.portIn = portB;

callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, portA, portB, 0.0f, nullptr);

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

return true;
}

bool CarlaEngine::patchbayDisconnect(int)
bool CarlaEngine::patchbayDisconnect(const int connectionId)
{
setLastError("Unsupported operation");
return false;
CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false);
CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false);
carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId);

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

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

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

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

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

if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000)
{
const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000);
disconnectRackMidiInPort(portId);
}
else if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000)
{
const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000);
disconnectRackMidiOutPort(portId);
}
else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000)
{
CARLA_ASSERT(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2);

const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000);

rack->connectLock.lock();

if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1)
rack->connectedOuts[0].removeAll(portId);
else
rack->connectedOuts[1].removeAll(portId);

rack->connectLock.unlock();
}
else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000)
{
CARLA_ASSERT(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2);

const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000);

rack->connectLock.lock();

if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1)
rack->connectedIns[0].removeAll(portId);
else
rack->connectedIns[1].removeAll(portId);

rack->connectLock.unlock();
}
else
{
CARLA_ASSERT(false);
}

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

rack->usedConnections.remove(it);
break;
}
}

return true;
}

bool CarlaEngine::patchbayRefresh()
@@ -1884,181 +2312,6 @@ void CarlaEngine::setPluginPeaks(const unsigned int pluginId, float const inPeak
pluginData.outsPeak[1] = outPeaks[1];
}

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

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

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

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

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

bool processed = false;

uint32_t oldAudioInCount = 0;
uint32_t oldMidiOutCount = 0;

const bool forcedOffline(isOffline());

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

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

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

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

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

// initialize event outputs (zero)
std::memset(pData->bufEvents.out, 0, sizeof(EngineEvent)*kEngineMaxInternalEventCount);
}
}

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

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

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

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

#ifdef HAVE_JUCE
float tmpMin, tmpMax;

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

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

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

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

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

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

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

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

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

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

processed = true;
}
}

void CarlaEngine::processPatchbay(float** inBuf, float** outBuf, const uint32_t bufCount[2], const uint32_t frames)
{
// TODO
return;

// unused, for now
(void)inBuf;
(void)outBuf;
(void)bufCount;
(void)frames;
}
#endif

// -----------------------------------------------------------------------
// Bridge/Controller OSC stuff



+ 228
- 0
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -24,6 +24,7 @@
#include "CarlaPlugin.hpp"

#include "CarlaMutex.hpp"
#include "List.hpp"

#ifdef HAVE_JUCE
# include "juce_audio_basics.h"
@@ -167,6 +168,137 @@ struct EnginePluginData {

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

enum RackPatchbayGroupIds {
RACK_PATCHBAY_GROUP_CARLA = -1,
RACK_PATCHBAY_GROUP_AUDIO_IN = 0,
RACK_PATCHBAY_GROUP_AUDIO_OUT = 1,
RACK_PATCHBAY_GROUP_MIDI_IN = 2,
RACK_PATCHBAY_GROUP_MIDI_OUT = 3,
RACK_PATCHBAY_GROUP_MAX = 4
};

enum RackPatchbayPortIds {
RACK_PATCHBAY_PORT_AUDIO_IN1 = -1,
RACK_PATCHBAY_PORT_AUDIO_IN2 = -2,
RACK_PATCHBAY_PORT_AUDIO_OUT1 = -3,
RACK_PATCHBAY_PORT_AUDIO_OUT2 = -4,
RACK_PATCHBAY_PORT_MIDI_IN = -5,
RACK_PATCHBAY_PORT_MIDI_OUT = -6,
RACK_PATCHBAY_PORT_MAX = -7
};

struct PortNameToId {
int portId;
char name[STR_MAX+1];
};

struct ConnectionToId {
int id;
int portOut;
int portIn;
};

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

struct EngineRackBuffers {
float* in[2];
float* out[2];

// connections stuff
List<uint> connectedIns[2];
List<uint> connectedOuts[2];
CarlaMutex connectLock;

int lastConnectionId;
List<ConnectionToId> usedConnections;

EngineRackBuffers(const uint32_t bufferSize)
: lastConnectionId(0)
{
resize(bufferSize);
}

~EngineRackBuffers()
{
clear();
}

void clear()
{
lastConnectionId = 0;

if (in[0] != nullptr)
{
delete[] in[0];
in[0] = nullptr;
}

if (in[1] != nullptr)
{
delete[] in[1];
in[1] = nullptr;
}

if (out[0] != nullptr)
{
delete[] out[0];
out[0] = nullptr;
}

if (out[1] != nullptr)
{
delete[] out[1];
out[1] = nullptr;
}

connectedIns[0].clear();
connectedIns[1].clear();
connectedOuts[0].clear();
connectedOuts[1].clear();
usedConnections.clear();
}

void resize(const uint32_t bufferSize)
{
if (bufferSize > 0)
{
in[0] = new float[bufferSize];
in[1] = new float[bufferSize];
out[0] = new float[bufferSize];
out[1] = new float[bufferSize];
}
else
{
in[0] = nullptr;
in[1] = nullptr;
out[0] = nullptr;
out[1] = nullptr;
}
}
};

struct EnginePatchbayBuffers {
EnginePatchbayBuffers(const uint32_t bufferSize)
{
resize(bufferSize);
}

~EnginePatchbayBuffers()
{
clear();
}

void clear()
{
}

void resize(const uint32_t /*bufferSize*/)
{
}
};

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

struct CarlaEngineProtectedData {
CarlaEngineOsc osc;
CarlaEngineThread thread;
@@ -192,6 +324,94 @@ struct CarlaEngineProtectedData {

EnginePluginData* plugins;

#ifndef BUILD_BRIDGE
struct InternalAudio {
bool isReady;
bool usePatchbay;

union {
EngineRackBuffers* rack;
EnginePatchbayBuffers* patchbay;
};

InternalAudio() noexcept
: isReady(false),
usePatchbay(false)
{
rack = nullptr;
}

~InternalAudio()
{
CARLA_ASSERT(! isReady);
CARLA_ASSERT(rack == nullptr);
}

void initPatchbay()
{
if (usePatchbay)
{
CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
}
else
{
CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);

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

void clear()
{
isReady = false;

if (usePatchbay)
{
CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
delete patchbay;
patchbay = nullptr;
}
else
{
CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
delete rack;
rack = nullptr;
}
}

void create(const uint32_t bufferSize)
{
if (usePatchbay)
{
CARLA_SAFE_ASSERT_RETURN(patchbay == nullptr,);
patchbay = new EnginePatchbayBuffers(bufferSize);
}
else
{
CARLA_SAFE_ASSERT_RETURN(rack == nullptr,);
rack = new EngineRackBuffers(bufferSize);
}

isReady = true;
}

void resize(const uint32_t bufferSize)
{
if (usePatchbay)
{
CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
patchbay->resize(bufferSize);
}
else
{
CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
rack->resize(bufferSize);
}
}
} bufAudio;
#endif

struct InternalEvents {
EngineEvent* in;
EngineEvent* out;
@@ -346,6 +566,14 @@ struct CarlaEngineProtectedData {
nextAction.mutex.unlock();
}

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

// extended, will call processRack() in the middle
void processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline);
#endif

class ScopedActionLock
{
public:


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

@@ -1133,7 +1133,7 @@ protected:
}

// process rack
processRack(inBuf, outBuf, nframes);
pData->processRack(inBuf, outBuf, nframes, fFreewheel);

// output control
{


+ 414
- 32
source/backend/engine/CarlaEngineJuce.cpp View File

@@ -21,7 +21,6 @@

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

// #include "RtList.hpp"

@@ -51,32 +50,102 @@ static void initJuceDevices()
// -------------------------------------------------------------------------------------------------------------------
// Juce Engine

class CarlaEngineJuce : public CarlaEngine/*,
public AudioIODeviceCallback*/
class CarlaEngineJuce : public CarlaEngine,
public AudioIODeviceCallback
{
public:
CarlaEngineJuce()
: CarlaEngine()
CarlaEngineJuce(AudioIODeviceType* const devType)
: CarlaEngine(),
AudioIODeviceCallback(),
fDeviceType(devType)
{
carla_debug("CarlaEngineJuce::CarlaEngineJuce()");
carla_debug("CarlaEngineJuce::CarlaEngineJuce(%p)", devType);

// just to make sure
pData->options.transportMode = ENGINE_TRANSPORT_MODE_INTERNAL;
}

~CarlaEngineJuce() override
{
carla_debug("CarlaEngineJuce::~CarlaEngineJuce()");

if (gRetNames != nullptr)
{
delete[] gRetNames;
gRetNames = nullptr;
}

gJuceDeviceTypes.clear(true);
}

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

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

if (pData->options.processMode != ENGINE_PROCESS_MODE_CONTINUOUS_RACK && pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY)
{
setLastError("Invalid process mode");
return false;
}

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

String deviceName;

if (pData->options.audioDevice != nullptr && pData->options.audioDevice[0] != '\0')
{
deviceName = pData->options.audioDevice;
}
else
{
const int defaultIndex(fDeviceType->getDefaultDeviceIndex(false));
StringArray deviceNames(fDeviceType->getDeviceNames());

if (defaultIndex >= 0 && defaultIndex < deviceNames.size())
deviceName = deviceNames[defaultIndex];
}

if (deviceName.isEmpty())
{
setLastError("something");
return false;
}

fDevice = fDeviceType->createDevice(deviceName, deviceName);

if (fDevice == nullptr)
{
setLastError("something 2");
return false;
}

BigInteger inputChannels;
BigInteger outputChannels;

String error = fDevice->open(inputChannels, outputChannels, pData->options.audioSampleRate, static_cast<int>(pData->options.audioBufferSize));

if (error.isNotEmpty())
{
fDevice = nullptr;
setLastError(error.toUTF8());
return false;
}

fDevice->start(this);

//getActiveOutputChannels();
//getActiveInputChannels();
pData->bufferSize = fDevice->getCurrentBufferSizeSamples();
pData->sampleRate = fDevice->getCurrentSampleRate();

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

CarlaEngine::init(clientName);
patchbayRefresh();

return true;
}

@@ -84,12 +153,29 @@ public:
{
carla_debug("CarlaEngineJuce::close()");

return CarlaEngine::close();
pData->bufAudio.isReady = false;

bool hasError = !CarlaEngine::close();

if (fDevice != nullptr)
{
if (fDevice->isPlaying())
fDevice->stop();

if (fDevice->isOpen())
fDevice->close();

fDevice = nullptr;
}

pData->bufAudio.clear();

return !hasError;
}

bool isRunning() const noexcept override
{
return false;
return fDevice != nullptr && fDevice->isPlaying();
}

bool isOffline() const noexcept override
@@ -104,45 +190,341 @@ public:

const char* getCurrentDriverName() const noexcept override
{
return nullptr;
return fDeviceType->getTypeName().toRawUTF8();
}

// -------------------------------------------------------------------
// Patchbay

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];

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

// Main
{
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_CARLA, 0, 0, 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");
}

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

callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_IN, 0, 0, 0.0f, strBuf);

/*for (unsigned int i=0; i < fAudioCountIn; ++i)
{
std::snprintf(strBuf, STR_MAX, "capture_%i", i+1);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_IN, RACK_PATCHBAY_GROUP_AUDIO_IN*1000 + i, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, strBuf);
}*/
}

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

callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_OUT, 0, 0, 0.0f, strBuf);

/*for (unsigned int i=0; i < fAudioCountOut; ++i)
{
std::snprintf(strBuf, STR_MAX, "playback_%i", i+1);
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_OUT, RACK_PATCHBAY_GROUP_AUDIO_OUT*1000 + i, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, strBuf);
}*/
}

#if 0 // midi-out not implemented yet
// MIDI In
{
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI_IN, 0, 0, 0.0f, "Readable MIDI ports");

for (unsigned int i=0, count=fDummyMidiIn.getPortCount(); i < count; ++i)
{
PortNameToId portNameToId;
portNameToId.portId = RACK_PATCHBAY_GROUP_MIDI_IN*1000 + i;
std::strncpy(portNameToId.name, fDummyMidiIn.getPortName(i).c_str(), STR_MAX);
fUsedMidiIns.append(portNameToId);

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

// MIDI Out
{
callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, 0, RACK_PATCHBAY_GROUP_MIDI_OUT, 0, 0.0f, "Writable MIDI ports");

for (unsigned int i=0, count=fDummyMidiOut.getPortCount(); i < count; ++i)
{
PortNameToId portNameToId;
portNameToId.portId = RACK_PATCHBAY_GROUP_MIDI_OUT*1000 + i;
std::strncpy(portNameToId.name, fDummyMidiOut.getPortName(i).c_str(), STR_MAX);
fUsedMidiOuts.append(portNameToId);

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, 0, RACK_PATCHBAY_GROUP_MIDI_OUT, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, portNameToId.name);
}
}
#endif

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

for (List<uint>::Itenerator it = rack->connectedIns[0].begin(); it.valid(); it.next())
{
const uint& port(it.getConstValue());
//CARLA_SAFE_ASSERT_CONTINUE(port < fAudioCountIn); // FIXME

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.portOut = RACK_PATCHBAY_GROUP_AUDIO_IN*1000 + port;
connectionToId.portIn = RACK_PATCHBAY_PORT_AUDIO_IN1;

callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);

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

for (List<uint>::Itenerator it = rack->connectedIns[1].begin(); it.valid(); it.next())
{
const uint& port(it.getConstValue());
//CARLA_SAFE_ASSERT_CONTINUE(port < fAudioCountIn); // FIXME

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.portOut = RACK_PATCHBAY_GROUP_AUDIO_IN*1000 + port;
connectionToId.portIn = RACK_PATCHBAY_PORT_AUDIO_IN2;

callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);

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

for (List<uint>::Itenerator it = rack->connectedOuts[0].begin(); it.valid(); it.next())
{
const uint& port(it.getConstValue());
//CARLA_SAFE_ASSERT_CONTINUE(port < fAudioCountOut); // FIXME

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.portOut = RACK_PATCHBAY_PORT_AUDIO_OUT1;
connectionToId.portIn = RACK_PATCHBAY_GROUP_AUDIO_OUT*1000 + port;

callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);

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

for (List<uint>::Itenerator it = rack->connectedOuts[1].begin(); it.valid(); it.next())
{
const uint& port(it.getConstValue());
//CARLA_SAFE_ASSERT_CONTINUE(port < fAudioCountOut); // FIXME

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.portOut = RACK_PATCHBAY_PORT_AUDIO_OUT2;
connectionToId.portIn = RACK_PATCHBAY_GROUP_AUDIO_OUT*1000 + port;

callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);

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

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

#if 0
for (List<MidiPort>::Itenerator it=fMidiIns.begin(); it.valid(); it.next())
{
const MidiPort& midiPort(it.getConstValue());

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.portOut = RACK_PATCHBAY_GROUP_MIDI_IN*1000 + midiPort.portId;
connectionToId.portIn = RACK_PATCHBAY_PORT_MIDI_IN;

callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);

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

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

ConnectionToId connectionToId;
connectionToId.id = rack->lastConnectionId;
connectionToId.portOut = RACK_PATCHBAY_PORT_MIDI_OUT;
connectionToId.portIn = RACK_PATCHBAY_GROUP_MIDI_OUT*1000 + midiPort.portId;

callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, connectionToId.portOut, connectionToId.portIn, 0.0f, nullptr);

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

return true;
}

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

protected:
// void audioDeviceIOCallback (const float** inputChannelData,
// int numInputChannels,
// float** outputChannelData,
// int numOutputChannels,
// int numSamples)
// {
// }
//
// void audioDeviceAboutToStart (juce::AudioIODevice* device)
// {
// }
//
// void audioDeviceStopped()
// {
// }
//
// void audioDeviceError (const juce::String& errorMessage)
// {
// }
void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) override
{
// assert juce buffers
CARLA_SAFE_ASSERT_RETURN(outputChannelData != nullptr,);
CARLA_SAFE_ASSERT_RETURN(numSamples == static_cast<int>(pData->bufferSize),);

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

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

// TODO - get events from juce

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

// output events
{
// TODO
//fMidiOutEvents...
}

runPendingRtEvents();
return;

// unused
(void)inputChannelData;
(void)numInputChannels;
}

void audioDeviceAboutToStart(AudioIODevice* /*device*/) override
{
}

void audioDeviceStopped() override
{
}

void audioDeviceError(const String& errorMessage) override
{
callback(ENGINE_CALLBACK_ERROR, 0, 0, 0, 0.0f, errorMessage.toRawUTF8());
}

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

bool connectRackMidiInPort(const int) override
{
return false;
}

bool connectRackMidiOutPort(const int) override
{
return false;
}

bool disconnectRackMidiInPort(const int) override
{
return false;
}

bool disconnectRackMidiOutPort(const int) override
{
return false;
}

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

private:
//juce::AudioIODeviceType* fDeviceType;
ScopedPointer<AudioIODevice> fDevice;
AudioIODeviceType* const fDeviceType;

//JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJuce)
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJuce)
};

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

CarlaEngine* CarlaEngine::newJuce(const AudioApi /*api*/)
CarlaEngine* CarlaEngine::newJuce(const AudioApi api)
{
return new CarlaEngineJuce();
initJuceDevices();

String juceApi;

switch (api)
{
case AUDIO_API_NULL:
case AUDIO_API_OSS:
case AUDIO_API_PULSE:
break;
case AUDIO_API_JACK:
juceApi = "JACK";
break;
case AUDIO_API_ALSA:
juceApi = "ALSA";
break;
case AUDIO_API_CORE:
juceApi = "CoreAudio";
break;
case AUDIO_API_ASIO:
juceApi = "ASIO";
break;
case AUDIO_API_DS:
juceApi = "DirectSound";
break;
}

if (juceApi.isEmpty())
return nullptr;

AudioIODeviceType* deviceType = nullptr;

for (int i=0, count=gJuceDeviceTypes.size(); i < count; ++i)
{
deviceType = gJuceDeviceTypes[i];

if (deviceType == nullptr || deviceType->getTypeName() == juceApi)
break;
}

if (deviceType == nullptr)
return nullptr;

deviceType->scanForDevices();

return new CarlaEngineJuce(deviceType);
}

unsigned int CarlaEngine::getJuceApiCount()


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

@@ -519,14 +519,14 @@ protected:
// -----------------------------------------------------------
// create audio buffers

float* inBuf[2] = { inBuffer[0], inBuffer[1] };
float* outBuf[2] = { outBuffer[0], outBuffer[1] };
uint32_t bufCount[2] = { 2, 2 };
//float* inBuf[2] = { inBuffer[0], inBuffer[1] };
//float* outBuf[2] = { outBuffer[0], outBuffer[1] };
//uint32_t bufCount[2] = { 2, 2 };

// -----------------------------------------------------------
// process

processPatchbay(inBuf, outBuf, bufCount, frames);
//pData->processPatchbay(inBuf, outBuf, bufCount, frames, isOffline());
}
else
{
@@ -539,7 +539,7 @@ protected:
// -----------------------------------------------------------
// process

processRack(inBuf, outBuf, frames);
pData->processRack(inBuf, outBuf, frames, isOffline());
}

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


+ 199
- 493
source/backend/engine/CarlaEngineRtAudio.cpp
File diff suppressed because it is too large
View File


Loading…
Cancel
Save