Browse Source

Initial working implementation of juce driver

tags/1.9.4
falkTX 10 years ago
parent
commit
c9bbf0396f
6 changed files with 195 additions and 47 deletions
  1. +12
    -12
      source/backend/engine/CarlaEngine.cpp
  2. +2
    -2
      source/backend/engine/CarlaEngineInternal.cpp
  3. +175
    -27
      source/backend/engine/CarlaEngineJuce.cpp
  4. +3
    -3
      source/backend/engine/CarlaEngineRtAudio.cpp
  5. +1
    -1
      source/modules/juce_audio_devices/AppConfig.h
  6. +2
    -2
      source/modules/juce_audio_devices/Makefile

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

@@ -731,11 +731,11 @@ CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)

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

if (std::strcmp(driverName, "OSS") == 0)
@@ -748,11 +748,11 @@ CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)

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

// -------------------------------------------------------------------
@@ -760,20 +760,20 @@ CarlaEngine* CarlaEngine::newDriverByName(const char* const driverName)

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

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



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

@@ -659,8 +659,8 @@ void CarlaEngine::ProtectedData::processRack(const float* inBufReal[2], float* o

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


+ 175
- 27
source/backend/engine/CarlaEngineJuce.cpp View File

@@ -73,13 +73,19 @@ static void initJuceDevicesIfNeeded()

sDeviceManager.createAudioDeviceTypes(gJuceDeviceTypes);

// maybe remove devices used by rtaudio
// remove JACK from device list
for (int i=0, count=gJuceDeviceTypes.size(); i < count; ++i)
{
if (gJuceDeviceTypes[i]->getTypeName() != "JACK")
continue;

gJuceDeviceTypes.remove(i, true);
}
}

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

#if 0
class CarlaEngineJuce : public CarlaEngine,
public AudioIODeviceCallback
{
@@ -155,24 +161,32 @@ public:

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

pData->bufferSize = static_cast<uint32_t>(fDevice->getCurrentBufferSizeSamples());
pData->sampleRate = fDevice->getCurrentSampleRate();

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

CARLA_SAFE_ASSERT(pData->audio.outCount > 0);
if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
{
pData->audio.inCount = 2;
pData->audio.outCount = 2;
}
else
{
pData->audio.inCount = 0;
pData->audio.outCount = 0;
}

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

fDevice->start(this);

CarlaEngine::init(clientName);
pData->audio.isReady = true;

patchbayRefresh();

return true;
@@ -225,24 +239,166 @@ public:

bool patchbayRefresh() override
{
// const String& deviceName(fDevice->getName());
CARLA_SAFE_ASSERT_RETURN(pData->audio.isReady, false);

//fUsedMidiPorts.clear();

if (pData->graph.isRack)
patchbayRefreshRack();
else
patchbayRefreshPatchbay();

return true;
}

void patchbayRefreshRack()
{
RackGraph* const rack(pData->graph.rack);

rack->connections.clear();

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

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

callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN1, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in1");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_IN2, PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, "audio-in2");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT1, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out1");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_AUDIO_OUT2, PATCHBAY_PORT_TYPE_AUDIO, 0.0f, "audio-out2");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_IN, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, "midi-in");
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_CARLA, RACK_GRAPH_CARLA_PORT_MIDI_OUT, PATCHBAY_PORT_TYPE_MIDI, 0.0f, "midi-out");
}

String deviceName(fDevice->getName());

if (deviceName.isNotEmpty())
deviceName = deviceName.dropLastCharacters(deviceName.fromFirstOccurrenceOf(", ", true, false).length());

// Audio In
{
StringArray inputNames(fDevice->getInputChannelNames());

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_GRAPH_GROUP_AUDIO_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf);

for (int i=0, count=inputNames.size(); i<count; ++i)
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_AUDIO_IN, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO, 0.0f, inputNames[i].toRawUTF8());
}

// Audio Out
{
StringArray outputNames(fDevice->getOutputChannelNames());

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_GRAPH_GROUP_AUDIO_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf);

for (int i=0, count=outputNames.size(); i<count; ++i)
callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_GRAPH_GROUP_AUDIO_OUT, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, outputNames[i].toRawUTF8());
}

// TODO - MIDI

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

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

ConnectionToId connectionToId;
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, connectionToId.id, 0, 0, 0.0f, strBuf);

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

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

ConnectionToId connectionToId;
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, connectionToId.id, 0, 0, 0.0f, strBuf);

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

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

ConnectionToId connectionToId;
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, connectionToId.id, 0, 0, 0.0f, strBuf);

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

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

ConnectionToId connectionToId;
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, connectionToId.id, 0, 0, 0.0f, strBuf);

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

rack->audio.mutex.unlock();

// TODO - MIDI
}

void patchbayRefreshPatchbay() noexcept
{
}

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

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->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),);
CARLA_SAFE_ASSERT_RETURN(numInputChannels >= 0, runPendingRtEvents());
CARLA_SAFE_ASSERT_RETURN(numOutputChannels > 0, runPendingRtEvents());
CARLA_SAFE_ASSERT_RETURN(outputChannelData != nullptr, runPendingRtEvents());
CARLA_SAFE_ASSERT_RETURN(numSamples == static_cast<int>(pData->bufferSize), runPendingRtEvents());

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

// initialize juce output
for (int i=0; i < numOutputChannels; ++i)
FloatVectorOperations::clear(outputChannelData[i], numSamples);

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

@@ -250,7 +406,7 @@ protected:

if (pData->graph.isRack)
{
pData->processRackFull(const_cast<float**>(inputChannelData), static_cast<uint32_t>(numInputChannels),
pData->processRackFull(inputChannelData, static_cast<uint32_t>(numInputChannels),
outputChannelData, static_cast<uint32_t>(numOutputChannels),
static_cast<uint32_t>(numSamples), false);
}
@@ -266,10 +422,6 @@ protected:

runPendingRtEvents();
return;

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

void audioDeviceAboutToStart(AudioIODevice* /*device*/) override
@@ -287,22 +439,22 @@ protected:

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

bool connectRackMidiInPort(const int) override
bool connectRackMidiInPort(const char* const /*portName*/) override
{
return false;
}

bool connectRackMidiOutPort(const int) override
bool connectRackMidiOutPort(const char* const /*portName*/) override
{
return false;
}

bool disconnectRackMidiInPort(const int) override
bool disconnectRackMidiInPort(const char* const /*portName*/) override
{
return false;
}

bool disconnectRackMidiOutPort(const int) override
bool disconnectRackMidiOutPort(const char* const /*portName*/) override
{
return false;
}
@@ -315,7 +467,6 @@ private:

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaEngineJuce)
};
#endif

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

@@ -366,14 +517,11 @@ CarlaEngine* CarlaEngine::newJuce(const AudioApi api)

deviceType->scanForDevices();

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

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

initJuceDevicesIfNeeded();

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


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

@@ -78,7 +78,7 @@ static void initRtAudioAPIsIfNeeded()
if (it != gRtAudioApis.end()) gRtAudioApis.erase(it);
}

#if 0//def HAVE_JUCE
#ifdef HAVE_JUCE
// prefer juce to handle some APIs
it = std::find(gRtAudioApis.begin(), gRtAudioApis.end(), RtAudio::LINUX_ALSA);
if (it != gRtAudioApis.end()) gRtAudioApis.erase(it);
@@ -398,7 +398,7 @@ public:
// -------------------------------------------------------------------
// Patchbay

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

@@ -412,7 +412,7 @@ public:
return true;
}

void patchbayRefreshRack() noexcept
void patchbayRefreshRack()
{
RackGraph* const rack(pData->graph.rack);



+ 1
- 1
source/modules/juce_audio_devices/AppConfig.h View File

@@ -45,7 +45,7 @@
/** Config: JUCE_ALSA
Enables ALSA audio devices (Linux only).
*/
#if 0 //JUCE_LINUX
#if JUCE_LINUX
#define JUCE_ALSA 1
#define JUCE_ALSA_MIDI_INPUT_NAME "Carla"
#define JUCE_ALSA_MIDI_OUTPUT_NAME "Carla"


+ 2
- 2
source/modules/juce_audio_devices/Makefile View File

@@ -71,10 +71,10 @@ win64: ../juce_audio_devices.win64.a

# --------------------------------------------------------------

%.cpp.o: %.cpp
%.cpp.o: %.cpp *.h
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

%.mm.o: %.mm
%.mm.o: %.mm %.cpp *.h
$(CXX) $< $(BUILD_CXX_FLAGS) -c -o $@

%.posix32.o: %


Loading…
Cancel
Save