From 45f74421793b09f5079f25cb5e38b8beb0e03caa Mon Sep 17 00:00:00 2001 From: falkTX Date: Fri, 6 Jan 2017 18:30:26 +0000 Subject: [PATCH] Implement basic tempo data for internal time (non-jack) --- source/backend/engine/CarlaEngine.cpp | 6 ++ source/backend/engine/CarlaEngineBridge.cpp | 2 + source/backend/engine/CarlaEngineInternal.cpp | 76 +++++++++++++++++-- source/backend/engine/CarlaEngineInternal.hpp | 7 ++ source/backend/engine/CarlaEngineJack.cpp | 8 +- source/backend/engine/CarlaEngineJuce.cpp | 3 +- source/backend/engine/CarlaEngineNative.cpp | 1 + source/backend/engine/CarlaEngineRtAudio.cpp | 1 + source/native-plugins/midi-pattern.cpp | 4 + 9 files changed, 99 insertions(+), 9 deletions(-) diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 53f60b2c6..ba6289319 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -1341,16 +1341,19 @@ void CarlaEngine::setFileCallback(const FileCallbackFunc func, void* const ptr) void CarlaEngine::transportPlay() noexcept { pData->time.playing = true; + pData->time.fillEngineTimeInfo(pData->timeInfo, 0); } void CarlaEngine::transportPause() noexcept { pData->time.playing = false; + pData->time.fillEngineTimeInfo(pData->timeInfo, 0); } void CarlaEngine::transportRelocate(const uint64_t frame) noexcept { pData->time.frame = frame; + pData->time.fillEngineTimeInfo(pData->timeInfo, 0); } // ----------------------------------------------------------------------- @@ -1664,6 +1667,9 @@ void CarlaEngine::sampleRateChanged(const double newSampleRate) } #endif + pData->time.sampleRate = newSampleRate; + pData->time.fillEngineTimeInfo(pData->timeInfo, 0); + for (uint i=0; i < pData->curPluginCount; ++i) { CarlaPlugin* const plugin(pData->plugins[i].plugin); diff --git a/source/backend/engine/CarlaEngineBridge.cpp b/source/backend/engine/CarlaEngineBridge.cpp index 5bd83f85a..a176e897b 100644 --- a/source/backend/engine/CarlaEngineBridge.cpp +++ b/source/backend/engine/CarlaEngineBridge.cpp @@ -472,6 +472,8 @@ public: CARLA_SAFE_ASSERT_INT(opcode == kPluginBridgeNonRtClientSetSampleRate, opcode); pData->sampleRate = fShmNonRtClientControl.readDouble(); + pData->initTime(); + if (shmRtClientDataSize != sizeof(BridgeRtClientData) || shmNonRtClientDataSize != sizeof(BridgeNonRtClientData) || shmNonRtServerDataSize != sizeof(BridgeNonRtServerData)) return false; diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp index f2070c2ce..6c49c0e19 100644 --- a/source/backend/engine/CarlaEngineInternal.cpp +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -57,9 +57,64 @@ void EngineInternalEvents::clear() noexcept // ----------------------------------------------------------------------- // InternalTime +static const float kTicksPerBeat = 1920.0f; + EngineInternalTime::EngineInternalTime() noexcept : playing(false), - frame(0) {} + frame(0), + bpm(120.0), + sampleRate(0.0), + tick(0.0) {} + +void EngineInternalTime::fillEngineTimeInfo(EngineTimeInfo& info, const uint32_t newFrames) noexcept +{ + CARLA_SAFE_ASSERT_RETURN(carla_isNotZero(sampleRate),); + + info.playing = playing; + info.frame = frame; + info.usecs = 0; + + if (newFrames == 0) + { + info.valid = EngineTimeInfo::kValidBBT; + info.bbt.beatsPerBar = 4.0f; + info.bbt.beatType = 4.0f; + info.bbt.ticksPerBeat = kTicksPerBeat; + info.bbt.beatsPerMinute = bpm; + + double abs_beat, abs_tick; + + { + const double min = frame / (sampleRate * 60.0); + abs_tick = min * bpm * kTicksPerBeat; + abs_beat = abs_tick / kTicksPerBeat; + } + + info.bbt.bar = abs_beat / info.bbt.beatsPerBar; + info.bbt.beat = abs_beat - (info.bbt.bar * info.bbt.beatsPerBar) + 1; + tick = abs_tick - (abs_beat * kTicksPerBeat); + info.bbt.barStartTick = info.bbt.bar * info.bbt.beatsPerBar * kTicksPerBeat; + info.bbt.bar++; + } + else + { + tick += newFrames * kTicksPerBeat * bpm / (sampleRate * 60); + + while (tick >= kTicksPerBeat) + { + tick -= kTicksPerBeat; + + if (++info.bbt.beat > info.bbt.beatsPerBar) + { + info.bbt.beat = 1; + ++info.bbt.bar; + info.bbt.barStartTick += info.bbt.beatsPerBar * kTicksPerBeat; + } + } + } + + info.bbt.tick = (int)(tick + 0.5); +} // ----------------------------------------------------------------------- // NextAction @@ -253,6 +308,16 @@ void CarlaEngine::ProtectedData::close() name.clear(); } +void CarlaEngine::ProtectedData::initTime() +{ + time.playing = false; + time.frame = 0; + time.bpm = 120.0; + time.sampleRate = sampleRate; + time.tick = 0.0; + time.fillEngineTimeInfo(timeInfo, 0); +} + // ----------------------------------------------------------------------- #ifndef BUILD_BRIDGE @@ -351,13 +416,10 @@ PendingRtEventsRunner::~PendingRtEventsRunner() noexcept { pData->doNextPluginAction(true); - if (pData->time.playing) - pData->time.frame += pData->bufferSize; - - if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL) + if (pData->time.playing && pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL) { - pData->timeInfo.playing = pData->time.playing; - pData->timeInfo.frame = pData->time.frame; + pData->time.frame += pData->bufferSize; + pData->time.fillEngineTimeInfo(pData->timeInfo, pData->bufferSize); } } diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 4e9a4b7e6..81a446c3c 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -112,9 +112,14 @@ private: struct EngineInternalTime { bool playing; uint64_t frame; + double bpm; + double sampleRate; + double tick; EngineInternalTime() noexcept; + void fillEngineTimeInfo(EngineTimeInfo& info, const uint32_t newFrames) noexcept; + CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalTime) }; @@ -219,6 +224,8 @@ struct CarlaEngine::ProtectedData { bool init(const char* const clientName); void close(); + void initTime(); + // ------------------------------------------------------------------- void doPluginRemove() noexcept; diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index 0b8cd7de8..1fddb189c 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -1,6 +1,6 @@ /* * Carla Plugin Host - * Copyright (C) 2011-2015 Filipe Coelho + * Copyright (C) 2011-2017 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -953,6 +953,7 @@ public: pData->bufferSize = jackbridge_get_buffer_size(fClient); pData->sampleRate = jackbridge_get_sample_rate(fClient); + pData->initTime(); jackbridge_set_thread_init_callback(fClient, carla_jack_thread_init_callback, nullptr); jackbridge_set_buffer_size_callback(fClient, carla_jack_bufsize_callback, this); @@ -1117,6 +1118,7 @@ public: fClient = client; pData->bufferSize = jackbridge_get_buffer_size(client); pData->sampleRate = jackbridge_get_sample_rate(client); + pData->initTime(); jackbridge_set_buffer_size_callback(client, carla_jack_bufsize_callback, this); jackbridge_set_sample_rate_callback(client, carla_jack_srate_callback, this); @@ -1532,7 +1534,9 @@ protected: pData->timeInfo.bbt.beatsPerMinute = fTransportPos.beats_per_minute; } else + { pData->timeInfo.valid = 0x0; + } } else { @@ -1545,6 +1549,8 @@ protected: { const PendingRtEventsRunner prt(this); + CARLA_SAFE_ASSERT_RETURN(nframes == pData->bufferSize,); + saveTransportInfo(); #ifdef BUILD_BRIDGE diff --git a/source/backend/engine/CarlaEngineJuce.cpp b/source/backend/engine/CarlaEngineJuce.cpp index 13f3ee4f7..5999bef0f 100644 --- a/source/backend/engine/CarlaEngineJuce.cpp +++ b/source/backend/engine/CarlaEngineJuce.cpp @@ -200,6 +200,7 @@ public: pData->bufferSize = static_cast(fDevice->getCurrentBufferSizeSamples()); pData->sampleRate = fDevice->getCurrentSampleRate(); + pData->initTime(); pData->graph.create(static_cast(inputNames.size()), static_cast(outputNames.size())); @@ -495,7 +496,7 @@ protected: fMidiInEvents.mutex.unlock(); } - pData->graph.process(pData, inputChannelData, outputChannelData, static_cast(numSamples)); + pData->graph.process(pData, inputChannelData, outputChannelData, nframes); fMidiOutMutex.lock(); diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index b2d60873b..a0c1c6595 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -603,6 +603,7 @@ public: pData->bufferSize = pHost->get_buffer_size(pHost->handle); pData->sampleRate = pHost->get_sample_rate(pHost->handle); + pData->initTime(); if (outChan == 0) outChan = inChan; diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index d8ce4c250..8cfec6965 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -282,6 +282,7 @@ public: pData->bufferSize = bufferFrames; pData->sampleRate = fAudio.getStreamSampleRate(); + pData->initTime(); fAudioInCount = iParams.nChannels; fAudioOutCount = oParams.nChannels; diff --git a/source/native-plugins/midi-pattern.cpp b/source/native-plugins/midi-pattern.cpp index aef044a3f..f65365188 100644 --- a/source/native-plugins/midi-pattern.cpp +++ b/source/native-plugins/midi-pattern.cpp @@ -51,6 +51,8 @@ public: fParameters[kParameterMeasures] = 4.0f; fParameters[kParameterDefLength] = 4.0f; fParameters[kParameterQuantize] = 4.0f; + + fMaxTicks = 48.0*fTimeSigNum*fParameters[kParameterMeasures] /2; // FIXME: why /2 ? } protected: @@ -348,9 +350,11 @@ protected: midiEvent.data[3] = event->data[3]; midiEvent.size = event->size; +#ifdef DEBUG carla_stdout("Playing at %f :: %03X:%03i:%03i", float(double(midiEvent.time)*fTicksPerFrame), midiEvent.data[0], midiEvent.data[1], midiEvent.data[2]); +#endif NativePluginAndUiClass::writeMidiEvent(&midiEvent); }