Browse Source

Big push to get transport working correctly. Seems quite nice now

tags/v1.9.11
falkTX 6 years ago
parent
commit
9a68a49849
10 changed files with 173 additions and 132 deletions
  1. +4
    -1
      source/backend/CarlaEngine.hpp
  2. +1
    -1
      source/backend/engine/CarlaEngine.cpp
  3. +35
    -0
      source/backend/engine/CarlaEngineData.cpp
  4. +15
    -69
      source/backend/engine/CarlaEngineInternal.cpp
  5. +80
    -56
      source/backend/engine/CarlaEngineJack.cpp
  6. +1
    -1
      source/backend/plugin/CarlaPluginBridge.cpp
  7. +1
    -1
      source/backend/plugin/CarlaPluginJack.cpp
  8. +1
    -1
      source/backend/plugin/CarlaPluginLV2.cpp
  9. +34
    -1
      source/backend/plugin/CarlaPluginNative.cpp
  10. +1
    -1
      source/backend/plugin/CarlaPluginVST2.cpp

+ 4
- 1
source/backend/CarlaEngine.hpp View File

@@ -291,6 +291,7 @@ struct CARLA_API EngineTimeInfoBBT {

#ifndef DOXYGEN
EngineTimeInfoBBT() noexcept;
EngineTimeInfoBBT(const EngineTimeInfoBBT&) noexcept;
#endif
};

@@ -310,6 +311,8 @@ struct CARLA_API EngineTimeInfo {

#ifndef DOXYGEN
EngineTimeInfo() noexcept;
EngineTimeInfo(const EngineTimeInfo&) noexcept;
EngineTimeInfo& operator=(const EngineTimeInfo&) noexcept;

// quick operator, doesn't check all values
bool operator==(const EngineTimeInfo& timeInfo) const noexcept;
@@ -922,7 +925,7 @@ public:
/*!
* Get the current Time information (read-only).
*/
const EngineTimeInfo& getTimeInfo() const noexcept;
virtual EngineTimeInfo getTimeInfo() const noexcept;

// -------------------------------------------------------------------
// Information (peaks)


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

@@ -1127,7 +1127,7 @@ const EngineOptions& CarlaEngine::getOptions() const noexcept
return pData->options;
}

const EngineTimeInfo& CarlaEngine::getTimeInfo() const noexcept
EngineTimeInfo CarlaEngine::getTimeInfo() const noexcept
{
return pData->timeInfo;
}


+ 35
- 0
source/backend/engine/CarlaEngineData.cpp View File

@@ -304,6 +304,17 @@ EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept
ticksPerBeat(0.0),
beatsPerMinute(0.0) {}

EngineTimeInfoBBT::EngineTimeInfoBBT(const EngineTimeInfoBBT& bbt) noexcept
: valid(bbt.valid),
bar(bbt.bar),
beat(bbt.beat),
tick(bbt.tick),
barStartTick(bbt.barStartTick),
beatsPerBar(bbt.beatsPerBar),
beatType(bbt.beatType),
ticksPerBeat(bbt.ticksPerBeat),
beatsPerMinute(bbt.beatsPerMinute) {}

// -----------------------------------------------------------------------
// EngineTimeInfo

@@ -321,6 +332,30 @@ void EngineTimeInfo::clear() noexcept
carla_zeroStruct(bbt);
}

EngineTimeInfo::EngineTimeInfo(const EngineTimeInfo& info) noexcept
: playing(info.playing),
frame(info.frame),
usecs(info.usecs),
bbt(info.bbt) {}

EngineTimeInfo& EngineTimeInfo::operator=(const EngineTimeInfo& info) noexcept
{
playing = info.playing;
frame = info.frame;
usecs = info.usecs;
bbt.valid = info.bbt.valid;
bbt.bar = info.bbt.bar;
bbt.tick = info.bbt.tick;
bbt.tick = info.bbt.tick;
bbt.barStartTick = info.bbt.barStartTick;
bbt.beatsPerBar = info.bbt.beatsPerBar;
bbt.beatType = info.bbt.beatType;
bbt.ticksPerBeat = info.bbt.ticksPerBeat;
bbt.beatsPerMinute = info.bbt.beatsPerMinute;

return *this;
}

bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept
{
if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.bbt.valid != bbt.valid)


+ 15
- 69
source/backend/engine/CarlaEngineInternal.cpp View File

@@ -176,10 +176,11 @@ void EngineInternalTime::fillEngineTimeInfo(const uint32_t newFrames) noexcept

double ticktmp;

timeInfo.usecs = 0;

if (transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
{
timeInfo.usecs = 0;
timeInfo.frame = nextFrame;
}

if (needsReset)
{
@@ -256,74 +257,19 @@ void EngineInternalTime::fillJackTimeInfo(jack_position_t* const pos, const uint
{
CARLA_SAFE_ASSERT_RETURN(carla_isNotZero(sampleRate),);
CARLA_SAFE_ASSERT_RETURN(newFrames > 0,);

double ticktmp;

if (needsReset)
{
pos->valid = JackPositionBBT;
pos->beat_type = 4.0f;
pos->ticks_per_beat = kTicksPerBeat;

double abs_beat, abs_tick;

#if defined(HAVE_HYLIA) && !defined(BUILD_BRIDGE)
if (hylia.enabled)
{
if (hylia.timeInfo.beat >= 0.0)
{
abs_beat = hylia.timeInfo.beat;
abs_tick = abs_beat * kTicksPerBeat;
}
else
{
abs_beat = 0.0;
abs_tick = 0.0;
timeInfo.playing = false;
}
}
else
#endif
{
const double min = static_cast<double>(pos->frame) / (sampleRate * 60.0);
abs_beat = min * beatsPerMinute;
abs_tick = abs_beat * kTicksPerBeat;
}

const double bar = std::floor(abs_beat / beatsPerBar);
const double beat = std::floor(std::fmod(abs_beat, beatsPerBar));

pos->bar = static_cast<int32_t>(bar) + 1;
pos->beat = static_cast<int32_t>(beat) + 1;
pos->bar_start_tick = ((bar * beatsPerBar) + beat) * kTicksPerBeat;

ticktmp = abs_tick - pos->bar_start_tick;
}
else if (timeInfo.playing)
{
ticktmp = tick + (newFrames * kTicksPerBeat * beatsPerMinute / (sampleRate * 60.0));

while (ticktmp >= kTicksPerBeat)
{
ticktmp -= kTicksPerBeat;

if (++pos->beat > beatsPerBar)
{
++pos->bar;
pos->beat = 1;
pos->bar_start_tick += beatsPerBar * kTicksPerBeat;
}
}
}
else
{
ticktmp = tick;
}

pos->beats_per_bar = static_cast<float>(beatsPerBar);
CARLA_SAFE_ASSERT(transportMode == ENGINE_TRANSPORT_MODE_JACK);

fillEngineTimeInfo(newFrames);

pos->valid = JackPositionBBT;
pos->bar = timeInfo.bbt.bar;
pos->beat = timeInfo.bbt.beat;
pos->tick = static_cast<int32_t>(tick + 0.5);
pos->bar_start_tick = timeInfo.bbt.barStartTick;
pos->beats_per_bar = timeInfo.bbt.beatsPerBar;
pos->beat_type = timeInfo.bbt.beatType;
pos->ticks_per_beat = kTicksPerBeat;
pos->beats_per_minute = beatsPerMinute;
pos->tick = ticktmp;
tick = ticktmp;
}

void EngineInternalTime::preProcess(const uint32_t numFrames)


+ 80
- 56
source/backend/engine/CarlaEngineJack.cpp View File

@@ -811,6 +811,7 @@ public:
fIsRunning(false)
#else
fTimebaseMaster(false),
fTimebaseRolling(false),
fUsedGroups(),
fUsedPorts(),
fUsedConnections(),
@@ -950,6 +951,8 @@ public:
jackbridge_set_process_callback(fClient, carla_jack_process_callback, this);
jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this);

fTimebaseRolling = false;

if (opts.transportMode == ENGINE_TRANSPORT_MODE_JACK)
fTimebaseMaster = jackbridge_set_timebase_callback(fClient, true, carla_jack_timebase_callback, this);
else
@@ -1086,6 +1089,55 @@ public:
return "JACK";
}

EngineTimeInfo getTimeInfo() const noexcept override
{
if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)
return CarlaEngine::getTimeInfo();
if (pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS)
return CarlaEngine::getTimeInfo();

jack_position_t jpos;

// invalidate
jpos.unique_1 = 1;
jpos.unique_2 = 2;

EngineTimeInfo timeInfo;
const bool playing = jackbridge_transport_query(fClient, &jpos) == JackTransportRolling;

if (jpos.unique_1 != jpos.unique_2)
{
timeInfo.playing = false;
timeInfo.frame = 0;
timeInfo.usecs = 0;
timeInfo.bbt.valid = false;
return timeInfo;
}

timeInfo.playing = playing;
timeInfo.frame = jpos.frame;
timeInfo.usecs = jpos.usecs;

if (jpos.valid & JackPositionBBT)
{
timeInfo.bbt.valid = true;
timeInfo.bbt.bar = jpos.bar;
timeInfo.bbt.beat = jpos.beat;
timeInfo.bbt.tick = jpos.tick;
timeInfo.bbt.barStartTick = jpos.bar_start_tick;
timeInfo.bbt.beatsPerBar = jpos.beats_per_bar;
timeInfo.bbt.beatType = jpos.beat_type;
timeInfo.bbt.ticksPerBeat = jpos.ticks_per_beat;
timeInfo.bbt.beatsPerMinute = jpos.beats_per_minute;
}
else
{
timeInfo.bbt.valid = false;
}

return timeInfo;
}

#ifndef BUILD_BRIDGE
void setOption(const EngineOption option, const int value, const char* const valueStr) noexcept override
{
@@ -1392,7 +1444,7 @@ public:

void transportPlay() noexcept override
{
if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)
return CarlaEngine::transportPlay();

if (fClient != nullptr)
@@ -1412,7 +1464,7 @@ public:

void transportPause() noexcept override
{
if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)
return CarlaEngine::transportPause();

if (fClient != nullptr)
@@ -1425,9 +1477,10 @@ public:

void transportBPM(const double bpm) noexcept override
{
CarlaEngine::transportBPM(bpm);
if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK || fTimebaseMaster)
return CarlaEngine::transportBPM(bpm);

if (fClient == nullptr || fTimebaseMaster)
if (fClient == nullptr)
return;

jack_position_t jpos;
@@ -1450,7 +1503,7 @@ public:

void transportRelocate(const uint64_t frame) noexcept override
{
if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)
return CarlaEngine::transportRelocate(frame);

if (fClient != nullptr)
@@ -1557,57 +1610,12 @@ protected:
offlineModeChanged(isFreewheel);
}

void saveTransportInfo()
{
if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)
return;

jack_position_t jpos;

// invalidate
jpos.unique_1 = 1;
jpos.unique_2 = 2;

pData->timeInfo.playing = (jackbridge_transport_query(fClient, &jpos) == JackTransportRolling);

if (jpos.unique_1 == jpos.unique_2)
{
pData->timeInfo.frame = jpos.frame;
pData->timeInfo.usecs = jpos.usecs;

if (jpos.valid & JackPositionBBT)
{
pData->timeInfo.bbt.valid = true;
pData->timeInfo.bbt.bar = jpos.bar;
pData->timeInfo.bbt.beat = jpos.beat;
pData->timeInfo.bbt.tick = jpos.tick;
pData->timeInfo.bbt.barStartTick = jpos.bar_start_tick;
pData->timeInfo.bbt.beatsPerBar = jpos.beats_per_bar;
pData->timeInfo.bbt.beatType = jpos.beat_type;
pData->timeInfo.bbt.ticksPerBeat = jpos.ticks_per_beat;
pData->timeInfo.bbt.beatsPerMinute = jpos.beats_per_minute;
}
else
{
pData->timeInfo.bbt.valid = false;
}
}
else
{
pData->timeInfo.frame = 0;
pData->timeInfo.usecs = 0;
pData->timeInfo.bbt.valid = false;
}
}

void handleJackProcessCallback(const uint32_t nframes)
{
const PendingRtEventsRunner prt(this, nframes);

CARLA_SAFE_ASSERT_RETURN(nframes == pData->bufferSize,);

saveTransportInfo();

#ifdef BUILD_BRIDGE
CarlaPlugin* const plugin(pData->plugins[0].plugin);

@@ -1783,6 +1791,18 @@ protected:
}
}
}

if (fTimebaseMaster)
{
const bool playing = jackbridge_transport_query(fClient, nullptr) == JackTransportRolling;

if (fTimebaseRolling != playing)
{
carla_stdout("state changed SAVE %i", playing);
fTimebaseRolling = playing;
pData->timeInfo.playing = playing;
}
}
#endif // ! BUILD_BRIDGE
}

@@ -1797,6 +1817,9 @@ protected:
if (new_pos)
pData->time.setNeedsReset();

pData->timeInfo.playing = fTimebaseRolling;
pData->timeInfo.frame = pos->frame;
pData->timeInfo.usecs = pos->usecs;
pData->time.fillJackTimeInfo(pos, nframes);
}

@@ -2055,6 +2078,8 @@ private:
jack_port_t* fRackPorts[kRackPortCount];

bool fTimebaseMaster;
bool fTimebaseRolling;

PatchbayGroupList fUsedGroups;
PatchbayPortList fUsedPorts;
PatchbayConnectionList fUsedConnections;
@@ -2486,15 +2511,15 @@ private:
handlePtr->handleJackFreewheelCallback(bool(starting));
}

static int JACKBRIDGE_API carla_jack_process_callback(jack_nframes_t nframes, void* arg) __attribute__((annotate("realtime")))
static void JACKBRIDGE_API carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg)
{
handlePtr->handleJackProcessCallback(nframes);
return 0;
handlePtr->handleJackLatencyCallback(mode);
}

static void JACKBRIDGE_API carla_jack_latency_callback(jack_latency_callback_mode_t mode, void* arg)
static int JACKBRIDGE_API carla_jack_process_callback(jack_nframes_t nframes, void* arg) __attribute__((annotate("realtime")))
{
handlePtr->handleJackLatencyCallback(mode);
handlePtr->handleJackProcessCallback(nframes);
return 0;
}

#ifndef BUILD_BRIDGE
@@ -2567,7 +2592,6 @@ private:
if (plugin->tryLock(engine->fFreewheel))
{
plugin->initBuffers();
engine->saveTransportInfo();
engine->processPlugin(plugin, nframes);
plugin->unlock();
}


+ 1
- 1
source/backend/plugin/CarlaPluginBridge.cpp View File

@@ -1467,7 +1467,7 @@ public:
// --------------------------------------------------------------------------------------------------------
// TimeInfo

const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());
BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);

bridgeTimeInfo.playing = timeInfo.playing;


+ 1
- 1
source/backend/plugin/CarlaPluginJack.cpp View File

@@ -940,7 +940,7 @@ public:
// --------------------------------------------------------------------------------------------------------
// TimeInfo

const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());
BridgeTimeInfo& bridgeTimeInfo(fShmRtClientControl.data->timeInfo);

bridgeTimeInfo.playing = timeInfo.playing;


+ 1
- 1
source/backend/plugin/CarlaPluginLV2.cpp View File

@@ -2779,7 +2779,7 @@ public:
// --------------------------------------------------------------------------------------------------------
// TimeInfo

const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());

if (fFirstActive || fLastTimeInfo != timeInfo)
{


+ 34
- 1
source/backend/plugin/CarlaPluginNative.cpp View File

@@ -1537,7 +1537,7 @@ public:
// --------------------------------------------------------------------------------------------------------
// Set TimeInfo

const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());

fTimeInfo.playing = timeInfo.playing;
fTimeInfo.frame = timeInfo.frame;
@@ -1563,6 +1563,39 @@ public:
fTimeInfo.bbt.valid = false;
}

#if 0
// This test code has proven to be quite useful
// So I am leaving it behind, I might need it again..
if (pData->id == 1)
{
static int64_t last_frame = timeInfo.frame;
static int64_t last_dev_frame = 0;
static double last_val = timeInfo.bbt.barStartTick + ((timeInfo.bbt.beat-1) * timeInfo.bbt.ticksPerBeat) + timeInfo.bbt.tick;
static double last_dev_val = 0.0;

int64_t cur_frame = timeInfo.frame;
int64_t cur_dev_frame = cur_frame - last_frame;

double cur_val = timeInfo.bbt.barStartTick + ((timeInfo.bbt.beat-1) * timeInfo.bbt.ticksPerBeat) + timeInfo.bbt.tick;
double cur_dev_val = cur_val - last_val;

if (std::abs(last_dev_val - cur_dev_val) >= 0.0001 || last_dev_frame != cur_dev_frame)
{
carla_stdout("currently %u at %u => %f : DEV1: %li : DEV2: %f",
frames,
timeInfo.frame,
cur_val,
cur_dev_frame,
cur_dev_val);
}

last_val = cur_val;
last_dev_val = cur_dev_val;
last_frame = cur_frame;
last_dev_frame = cur_dev_frame;
}
#endif

// --------------------------------------------------------------------------------------------------------
// Event Input and Processing



+ 1
- 1
source/backend/plugin/CarlaPluginVST2.cpp View File

@@ -1121,7 +1121,7 @@ public:
// --------------------------------------------------------------------------------------------------------
// Set TimeInfo

const EngineTimeInfo& timeInfo(pData->engine->getTimeInfo());
const EngineTimeInfo timeInfo(pData->engine->getTimeInfo());

fTimeInfo.flags = kVstTransportChanged;



Loading…
Cancel
Save