diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 26b12bd62..5b870d939 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -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 diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp index 7ddcb0ee0..f307fbbf7 100644 --- a/source/backend/engine/CarlaEngineInternal.cpp +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -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(peak1, std::fabs(inBuf0[k]), 1.0f); - peak2 = carla_max(peak2, std::fabs(inBuf1[k]), 1.0f); + peak1 = carla_max(peak1, std::fabs(inBuf0[k]), 1.0f); + peak2 = carla_max(peak2, std::fabs(inBuf1[k]), 1.0f); } pluginData.insPeak[0] = peak1; diff --git a/source/backend/engine/CarlaEngineJuce.cpp b/source/backend/engine/CarlaEngineJuce.cpp index 76be3fce4..94b5782e0 100644 --- a/source/backend/engine/CarlaEngineJuce.cpp +++ b/source/backend/engine/CarlaEngineJuce.cpp @@ -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(fDevice->getCurrentBufferSizeSamples()); pData->sampleRate = fDevice->getCurrentSampleRate(); - pData->audio.inCount = static_cast(inputChannels.countNumberOfSetBits()); - pData->audio.outCount = static_cast(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(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(i), PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, outputNames[i].toRawUTF8()); + } + + // TODO - MIDI + + // Connections + rack->audio.mutex.lock(); + + for (LinkedList::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::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::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::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(pData->audio.inCount),); - CARLA_SAFE_ASSERT_RETURN(numOutputChannels == static_cast(pData->audio.outCount),); - CARLA_SAFE_ASSERT_RETURN(outputChannelData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(numSamples == static_cast(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(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(pData->events.in, kMaxEngineEventInternalCount); @@ -250,7 +406,7 @@ protected: if (pData->graph.isRack) { - pData->processRackFull(const_cast(inputChannelData), static_cast(numInputChannels), + pData->processRackFull(inputChannelData, static_cast(numInputChannels), outputChannelData, static_cast(numOutputChannels), static_cast(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(gJuceDeviceTypes.size()); diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index 24dc03c4f..c3d2ce30e 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -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); diff --git a/source/modules/juce_audio_devices/AppConfig.h b/source/modules/juce_audio_devices/AppConfig.h index f4cf16b16..3ce7d14d9 100755 --- a/source/modules/juce_audio_devices/AppConfig.h +++ b/source/modules/juce_audio_devices/AppConfig.h @@ -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" diff --git a/source/modules/juce_audio_devices/Makefile b/source/modules/juce_audio_devices/Makefile index 1a30fafbc..3397350c5 100644 --- a/source/modules/juce_audio_devices/Makefile +++ b/source/modules/juce_audio_devices/Makefile @@ -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: %