diff --git a/source/backend/Makefile b/source/backend/Makefile index 8bac9e24a..744b12615 100644 --- a/source/backend/Makefile +++ b/source/backend/Makefile @@ -37,6 +37,10 @@ ifeq ($(HAVE_DGL),true) STANDALONE_LIBS += $(MODULEDIR)/dgl.a endif +ifeq ($(HAVE_HYLIA),true) +STANDALONE_LIBS += $(MODULEDIR)/hylia.a +endif + ifeq ($(MACOS_OR_WIN32),true) STANDALONE_LIBS += $(MODULEDIR)/juce_audio_devices.a STANDALONE_LIBS += $(MODULEDIR)/juce_audio_processors.a diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp index 6c49c0e19..8f8e24d3b 100644 --- a/source/backend/engine/CarlaEngineInternal.cpp +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -64,7 +64,23 @@ EngineInternalTime::EngineInternalTime() noexcept frame(0), bpm(120.0), sampleRate(0.0), +#ifdef BUILD_BRIDGE tick(0.0) {} +#else + tick(0.0), + hylia(nullptr), + hylia_enabled(0) +{ + carla_zeroStruct(hylia_time); +} +#endif + +EngineInternalTime::~EngineInternalTime() noexcept +{ +#ifndef BUILD_BRIDGE + hylia_cleanup(hylia); +#endif +} void EngineInternalTime::fillEngineTimeInfo(EngineTimeInfo& info, const uint32_t newFrames) noexcept { @@ -84,6 +100,19 @@ void EngineInternalTime::fillEngineTimeInfo(EngineTimeInfo& info, const uint32_t double abs_beat, abs_tick; +#ifndef BUILD_BRIDGE + if (hylia_enabled > 0 && hylia_time.bpm > 0.0) + { + const double beats = hylia_time.beats; + + if (beats < 0.0) + return; + + abs_beat = std::floor(beats); + abs_tick = beats * kTicksPerBeat; + } + else +#endif { const double min = frame / (sampleRate * 60.0); abs_tick = min * bpm * kTicksPerBeat; @@ -316,6 +345,14 @@ void CarlaEngine::ProtectedData::initTime() time.sampleRate = sampleRate; time.tick = 0.0; time.fillEngineTimeInfo(timeInfo, 0); + +#ifndef BUILD_BRIDGE + CARLA_SAFE_ASSERT_RETURN(time.hylia == nullptr,); + time.hylia = hylia_create(120.0, bufferSize, sampleRate); + + //time.hylia_enabled = 1; + //hylia_enable(time.hylia, true, 120.0); +#endif } // ----------------------------------------------------------------------- @@ -409,8 +446,27 @@ void CarlaEngine::ProtectedData::doNextPluginAction(const bool unlock) noexcept // ----------------------------------------------------------------------- // PendingRtEventsRunner -PendingRtEventsRunner::PendingRtEventsRunner(CarlaEngine* const engine) noexcept - : pData(engine->pData) {} +PendingRtEventsRunner::PendingRtEventsRunner(CarlaEngine* const engine, const uint32_t bufSize) noexcept + : pData(engine->pData), + bufferSize(bufSize) +{ +#ifndef BUILD_BRIDGE + if (pData->time.hylia_enabled > 0) + { + hylia_process(pData->time.hylia, bufferSize, &pData->time.hylia_time); + const double new_bpm = pData->time.hylia_time.bpm; + + if (new_bpm > 0.0 && (pData->time.bpm != new_bpm || ++pData->time.hylia_enabled > 50)) + { + pData->time.bpm = new_bpm; + pData->time.hylia_enabled = 1; + + if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL) + pData->time.fillEngineTimeInfo(pData->timeInfo, 0); + } + } +#endif +} PendingRtEventsRunner::~PendingRtEventsRunner() noexcept { @@ -418,8 +474,8 @@ PendingRtEventsRunner::~PendingRtEventsRunner() noexcept if (pData->time.playing && pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL) { - pData->time.frame += pData->bufferSize; - pData->time.fillEngineTimeInfo(pData->timeInfo, pData->bufferSize); + pData->time.frame += bufferSize; + pData->time.fillEngineTimeInfo(pData->timeInfo, bufferSize); } } diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 81a446c3c..fbc04f58b 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -22,6 +22,8 @@ #include "CarlaEngineThread.hpp" #include "CarlaEngineUtils.hpp" +#include "hylia/hylia.h" + // FIXME only use CARLA_PREVENT_HEAP_ALLOCATION for structs // maybe separate macro @@ -116,7 +118,14 @@ struct EngineInternalTime { double sampleRate; double tick; +#ifndef BUILD_BRIDGE + hylia_t* hylia; + int hylia_enabled; + hylia_time_info_t hylia_time; +#endif + EngineInternalTime() noexcept; + ~EngineInternalTime() noexcept; void fillEngineTimeInfo(EngineTimeInfo& info, const uint32_t newFrames) noexcept; @@ -245,11 +254,12 @@ struct CarlaEngine::ProtectedData { class PendingRtEventsRunner { public: - PendingRtEventsRunner(CarlaEngine* const engine) noexcept; + PendingRtEventsRunner(CarlaEngine* const engine, const uint32_t bufferSize) noexcept; ~PendingRtEventsRunner() noexcept; private: CarlaEngine::ProtectedData* const pData; + const uint32_t bufferSize; CARLA_PREVENT_HEAP_ALLOCATION CARLA_DECLARE_NON_COPY_CLASS(PendingRtEventsRunner) diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index 1fddb189c..8d8ce64f8 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -1547,7 +1547,7 @@ protected: void handleJackProcessCallback(const uint32_t nframes) { - const PendingRtEventsRunner prt(this); + const PendingRtEventsRunner prt(this, nframes); CARLA_SAFE_ASSERT_RETURN(nframes == pData->bufferSize,); @@ -1911,7 +1911,7 @@ protected: signalThreadShouldExit(); #endif - const PendingRtEventsRunner prt(this); + const PendingRtEventsRunner prt(this, pData->bufferSize); for (uint i=0; i < pData->curPluginCount; ++i) { diff --git a/source/backend/engine/CarlaEngineJuce.cpp b/source/backend/engine/CarlaEngineJuce.cpp index 5999bef0f..16fdfa97e 100644 --- a/source/backend/engine/CarlaEngineJuce.cpp +++ b/source/backend/engine/CarlaEngineJuce.cpp @@ -442,9 +442,10 @@ public: // ------------------------------------------------------------------- protected: - void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, int numOutputChannels, int numSamples) override + void audioDeviceIOCallback(const float** inputChannelData, int numInputChannels, float** outputChannelData, + int numOutputChannels, int numSamples) override { - const PendingRtEventsRunner prt(this); + const PendingRtEventsRunner prt(this, numSamples); // assert juce buffers CARLA_SAFE_ASSERT_RETURN(numInputChannels >= 0,); diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index a0c1c6595..4ddd37cfd 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -1329,7 +1329,7 @@ protected: void process(float** const inBuffer, float** const outBuffer, const uint32_t frames, const NativeMidiEvent* const midiEvents, const uint32_t midiEventCount) { - const PendingRtEventsRunner prt(this); + const PendingRtEventsRunner prt(this, frames); // --------------------------------------------------------------- // Time Info diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index 8cfec6965..e18540e5c 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -553,7 +553,7 @@ public: protected: void handleAudioProcessCallback(void* outputBuffer, void* inputBuffer, uint nframes, double streamTime, RtAudioStreamStatus status) { - const PendingRtEventsRunner prt(this); + const PendingRtEventsRunner prt(this, nframes); // get buffers from RtAudio const float* const insPtr = (const float*)inputBuffer; @@ -694,6 +694,8 @@ protected: } } + fMidiOutMutex.unlock(); + if (fAudioInterleaved) { for (uint i=0; i < nframes; ++i) @@ -701,8 +703,6 @@ protected: outsPtr[i*fAudioOutCount+j] = outBuf[j][i]; } - fMidiOutMutex.unlock(); - return; // unused (void)streamTime; (void)status; } diff --git a/source/plugin/Makefile b/source/plugin/Makefile index 8442e7b2f..59b5c5d24 100644 --- a/source/plugin/Makefile +++ b/source/plugin/Makefile @@ -41,6 +41,10 @@ ifeq ($(HAVE_DGL),true) LIBS += $(MODULEDIR)/dgl.a endif +ifeq ($(HAVE_HYLIA),true) +LIBS += $(MODULEDIR)/hylia.a +endif + ifeq ($(MACOS_OR_WIN32),true) LIBS += $(MODULEDIR)/juce_audio_processors.a LIBS += $(MODULEDIR)/juce_data_structures.a