@@ -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 | |||
@@ -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); | |||
} | |||
} | |||
@@ -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) | |||
@@ -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) | |||
{ | |||
@@ -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,); | |||
@@ -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 | |||
@@ -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; | |||
} | |||
@@ -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 | |||