Browse Source

Initial work for setting bpm value

tags/1.9.8
falkTX 7 years ago
parent
commit
9aed25df6c
11 changed files with 108 additions and 15 deletions
  1. +0
    -3
      resources/ui/carla_host.ui
  2. +5
    -0
      source/backend/CarlaEngine.hpp
  3. +5
    -0
      source/backend/CarlaHost.h
  4. +8
    -0
      source/backend/CarlaStandalone.cpp
  5. +7
    -0
      source/backend/engine/CarlaEngine.cpp
  6. +19
    -9
      source/backend/engine/CarlaEngineInternal.cpp
  7. +1
    -0
      source/backend/engine/CarlaEngineInternal.hpp
  8. +30
    -2
      source/backend/engine/CarlaEngineJack.cpp
  9. +8
    -0
      source/backend/engine/CarlaEngineNative.cpp
  10. +17
    -0
      source/carla_backend.py
  11. +8
    -1
      source/carla_host.py

+ 0
- 3
resources/ui/carla_host.ui View File

@@ -627,9 +627,6 @@
<layout class="QVBoxLayout" name="verticalLayout_5"> <layout class="QVBoxLayout" name="verticalLayout_5">
<item> <item>
<widget class="QDoubleSpinBox" name="dsb_transport_bpm"> <widget class="QDoubleSpinBox" name="dsb_transport_bpm">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix"> <property name="suffix">
<string> BPM</string> <string> BPM</string>
</property> </property>


+ 5
- 0
source/backend/CarlaEngine.hpp View File

@@ -988,6 +988,11 @@ public:
*/ */
virtual void transportPause() noexcept; virtual void transportPause() noexcept;


/*!
* Set the engine transport bpm to @a bpm.
*/
virtual void transportBPM(const double bpm) noexcept;

/*! /*!
* Relocate the engine transport to @a frames. * Relocate the engine transport to @a frames.
*/ */


+ 5
- 0
source/backend/CarlaHost.h View File

@@ -433,6 +433,11 @@ CARLA_EXPORT void carla_transport_play();
*/ */
CARLA_EXPORT void carla_transport_pause(); CARLA_EXPORT void carla_transport_pause();


/*!
* Set the engine transport bpm.
*/
CARLA_EXPORT void carla_transport_bpm(double bpm);

/*! /*!
* Relocate the engine transport to a specific frame. * Relocate the engine transport to a specific frame.
*/ */


+ 8
- 0
source/backend/CarlaStandalone.cpp View File

@@ -743,6 +743,14 @@ void carla_transport_pause()
gStandalone.engine->transportPause(); gStandalone.engine->transportPause();
} }


void carla_transport_bpm(double bpm)
{
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);
carla_debug("carla_transport_bpm(%f)", bpm);

gStandalone.engine->transportBPM(bpm);
}

void carla_transport_relocate(uint64_t frame) void carla_transport_relocate(uint64_t frame)
{ {
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),); CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr && gStandalone.engine->isRunning(),);


+ 7
- 0
source/backend/engine/CarlaEngine.cpp View File

@@ -1351,6 +1351,13 @@ void CarlaEngine::transportPause() noexcept
pData->time.setNeedsReset(); pData->time.setNeedsReset();
} }


void CarlaEngine::transportBPM(const double bpm) noexcept
{
try {
pData->time.setBPM(bpm);
} CARLA_SAFE_EXCEPTION("CarlaEngine::transportBPM");
}

void CarlaEngine::transportRelocate(const uint64_t frame) noexcept void CarlaEngine::transportRelocate(const uint64_t frame) noexcept
{ {
pData->time.relocate(frame); pData->time.relocate(frame);


+ 19
- 9
source/backend/engine/CarlaEngineInternal.cpp View File

@@ -136,6 +136,16 @@ void EngineInternalTime::enableLink(const bool enable)
needsReset = true; needsReset = true;
} }


void EngineInternalTime::setBPM(const double bpm)
{
beatsPerMinute = bpm;

#if defined(HAVE_HYLIA) && !defined(BUILD_BRIDGE)
if (hylia.instance != nullptr)
hylia_set_beats_per_minute(hylia.instance, bpm);
#endif
}

void EngineInternalTime::setNeedsReset() noexcept void EngineInternalTime::setNeedsReset() noexcept
{ {
needsReset = true; needsReset = true;
@@ -163,10 +173,8 @@ void EngineInternalTime::fillEngineTimeInfo(const uint32_t newFrames) noexcept
if (needsReset) if (needsReset)
{ {
timeInfo.valid = EngineTimeInfo::kValidBBT; timeInfo.valid = EngineTimeInfo::kValidBBT;
timeInfo.bbt.beatsPerBar = beatsPerBar;
timeInfo.bbt.beatType = 4.0f; timeInfo.bbt.beatType = 4.0f;
timeInfo.bbt.ticksPerBeat = kTicksPerBeat; timeInfo.bbt.ticksPerBeat = kTicksPerBeat;
timeInfo.bbt.beatsPerMinute = beatsPerMinute;


double abs_beat, abs_tick; double abs_beat, abs_tick;


@@ -195,8 +203,8 @@ void EngineInternalTime::fillEngineTimeInfo(const uint32_t newFrames) noexcept
needsReset = false; needsReset = false;
} }


timeInfo.bbt.bar = (int32_t)(std::floor(abs_beat / timeInfo.bbt.beatsPerBar) + 0.5);
timeInfo.bbt.beat = (int32_t)(abs_beat - (timeInfo.bbt.bar * timeInfo.bbt.beatsPerBar) + 1.5);
timeInfo.bbt.bar = (int32_t)(std::floor(abs_beat / beatsPerBar) + 0.5);
timeInfo.bbt.beat = (int32_t)(abs_beat - (timeInfo.bbt.bar * beatsPerBar) + 1.5);
timeInfo.bbt.barStartTick = timeInfo.bbt.bar * beatsPerBar * kTicksPerBeat; timeInfo.bbt.barStartTick = timeInfo.bbt.bar * beatsPerBar * kTicksPerBeat;
++timeInfo.bbt.bar; ++timeInfo.bbt.bar;


@@ -220,6 +228,8 @@ void EngineInternalTime::fillEngineTimeInfo(const uint32_t newFrames) noexcept
} }
} }


timeInfo.bbt.beatsPerBar = beatsPerBar;
timeInfo.bbt.beatsPerMinute = beatsPerMinute;
timeInfo.bbt.tick = (int32_t)(ticktmp + 0.5); timeInfo.bbt.tick = (int32_t)(ticktmp + 0.5);
tick = ticktmp; tick = ticktmp;


@@ -237,10 +247,8 @@ void EngineInternalTime::fillJackTimeInfo(jack_position_t* const pos, const uint
if (needsReset) if (needsReset)
{ {
pos->valid = JackPositionBBT; pos->valid = JackPositionBBT;
pos->beats_per_bar = beatsPerBar;
pos->beat_type = 4.0f; pos->beat_type = 4.0f;
pos->ticks_per_beat = kTicksPerBeat; pos->ticks_per_beat = kTicksPerBeat;
pos->beats_per_minute = beatsPerMinute;


double abs_beat, abs_tick; double abs_beat, abs_tick;


@@ -269,9 +277,9 @@ void EngineInternalTime::fillJackTimeInfo(jack_position_t* const pos, const uint
needsReset = false; needsReset = false;
} }


pos->bar = (int32_t)(std::floor(abs_beat / pos->beats_per_bar) + 0.5);
pos->beat = (int32_t)(abs_beat - (pos->bar * pos->beats_per_bar) + 1.5);
pos->bar_start_tick = pos->bar * pos->beats_per_bar * kTicksPerBeat;
pos->bar = (int32_t)(std::floor(abs_beat / beatsPerBar) + 0.5);
pos->beat = (int32_t)(abs_beat - (pos->bar * beatsPerBar) + 1.5);
pos->bar_start_tick = pos->bar * beatsPerBar * kTicksPerBeat;
++pos->bar; ++pos->bar;


//ticktmp = abs_tick - pos->bar_start_tick; //ticktmp = abs_tick - pos->bar_start_tick;
@@ -294,6 +302,8 @@ void EngineInternalTime::fillJackTimeInfo(jack_position_t* const pos, const uint
} }
} }


pos->beats_per_bar = beatsPerBar;
pos->beats_per_minute = beatsPerMinute;
pos->tick = (int32_t)(ticktmp + 0.5); pos->tick = (int32_t)(ticktmp + 0.5);
tick = ticktmp; tick = ticktmp;
} }


+ 1
- 0
source/backend/engine/CarlaEngineInternal.hpp View File

@@ -121,6 +121,7 @@ public:
void updateAudioValues(const uint32_t bufferSize, const double sampleRate); void updateAudioValues(const uint32_t bufferSize, const double sampleRate);


void enableLink(const bool enable); void enableLink(const bool enable);
void setBPM(const double bpm);
void setNeedsReset() noexcept; void setNeedsReset() noexcept;
void relocate(const uint64_t frame) noexcept; void relocate(const uint64_t frame) noexcept;




+ 30
- 2
source/backend/engine/CarlaEngineJack.cpp View File

@@ -816,6 +816,7 @@ public:
#ifdef BUILD_BRIDGE #ifdef BUILD_BRIDGE
fIsRunning(false) fIsRunning(false)
#else #else
fTimebaseMaster(false),
fUsedGroups(), fUsedGroups(),
fUsedPorts(), fUsedPorts(),
fUsedConnections(), fUsedConnections(),
@@ -951,9 +952,10 @@ public:
jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this); jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this);
jackbridge_set_latency_callback(fClient, carla_jack_latency_callback, this); jackbridge_set_latency_callback(fClient, carla_jack_latency_callback, this);
jackbridge_set_process_callback(fClient, carla_jack_process_callback, this); jackbridge_set_process_callback(fClient, carla_jack_process_callback, this);
jackbridge_set_timebase_callback(fClient, true, carla_jack_timebase_callback, this);
jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this); jackbridge_on_shutdown(fClient, carla_jack_shutdown_callback, this);


fTimebaseMaster = jackbridge_set_timebase_callback(fClient, true, carla_jack_timebase_callback, this);

if (pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY) if (pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY)
initJackPatchbay(jackClientName); initJackPatchbay(jackClientName);


@@ -1373,7 +1375,7 @@ public:
{ {
// old timebase master no longer active, make ourselves master again // old timebase master no longer active, make ourselves master again
pData->time.setNeedsReset(); pData->time.setNeedsReset();
jackbridge_set_timebase_callback(fClient, true, carla_jack_timebase_callback, this);
fTimebaseMaster = jackbridge_set_timebase_callback(fClient, true, carla_jack_timebase_callback, this);
} }


try { try {
@@ -1395,6 +1397,31 @@ public:
} }
} }


void transportBPM(const double bpm) noexcept override
{
CarlaEngine::transportBPM(bpm);

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

jack_position_t jpos;

// invalidate
jpos.unique_1 = 1;
jpos.unique_2 = 2;
jackbridge_transport_query(fClient, &jpos);

if (jpos.unique_1 == jpos.unique_2 && (jpos.valid & JackPositionBBT) != 0)
{
carla_stdout("NOTE: Changing BPM without being JACK timebase master");
jpos.beats_per_minute = bpm;

try {
jackbridge_transport_reposition(fClient, &jpos);
} catch(...) {}
}
}

void transportRelocate(const uint64_t frame) noexcept override void transportRelocate(const uint64_t frame) noexcept override
{ {
if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL) if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
@@ -1984,6 +2011,7 @@ private:


jack_port_t* fRackPorts[kRackPortCount]; jack_port_t* fRackPorts[kRackPortCount];


bool fTimebaseMaster;
PatchbayGroupList fUsedGroups; PatchbayGroupList fUsedGroups;
PatchbayPortList fUsedPorts; PatchbayPortList fUsedPorts;
PatchbayConnectionList fUsedConnections; PatchbayConnectionList fUsedConnections;


+ 8
- 0
source/backend/engine/CarlaEngineNative.cpp View File

@@ -236,6 +236,14 @@ protected:
{ {
fEngine->transportPause(); fEngine->transportPause();
} }
else if (std::strcmp(msg, "transport_bpm") == 0)
{
double bpm;

CARLA_SAFE_ASSERT_RETURN(readNextLineAsDouble(bpm), true);

fEngine->transportBPM(bpm);
}
else if (std::strcmp(msg, "transport_relocate") == 0) else if (std::strcmp(msg, "transport_relocate") == 0)
{ {
uint64_t frame; uint64_t frame;


+ 17
- 0
source/carla_backend.py View File

@@ -1382,6 +1382,11 @@ class CarlaHostMeta(object):
def transport_pause(self): def transport_pause(self):
raise NotImplementedError raise NotImplementedError


# Pause the engine transport.
@abstractmethod
def transport_bpm(self, bpm):
raise NotImplementedError

# Relocate the engine transport to a specific frame. # Relocate the engine transport to a specific frame.
@abstractmethod @abstractmethod
def transport_relocate(self, frame): def transport_relocate(self, frame):
@@ -1927,6 +1932,9 @@ class CarlaHostNull(CarlaHostMeta):
def transport_pause(self): def transport_pause(self):
return return


def transport_bpm(self, bpm):
return

def transport_relocate(self, frame): def transport_relocate(self, frame):
return return


@@ -2206,6 +2214,9 @@ class CarlaHostDLL(CarlaHostMeta):
self.lib.carla_transport_pause.argtypes = None self.lib.carla_transport_pause.argtypes = None
self.lib.carla_transport_pause.restype = None self.lib.carla_transport_pause.restype = None


self.lib.carla_transport_bpm.argtypes = [c_double]
self.lib.carla_transport_bpm.restype = None

self.lib.carla_transport_relocate.argtypes = [c_uint64] self.lib.carla_transport_relocate.argtypes = [c_uint64]
self.lib.carla_transport_relocate.restype = None self.lib.carla_transport_relocate.restype = None


@@ -2477,6 +2488,9 @@ class CarlaHostDLL(CarlaHostMeta):
def transport_pause(self): def transport_pause(self):
self.lib.carla_transport_pause() self.lib.carla_transport_pause()


def transport_bpm(self, bpm):
self.lib.carla_transport_bpm(bpm)

def transport_relocate(self, frame): def transport_relocate(self, frame):
self.lib.carla_transport_relocate(frame) self.lib.carla_transport_relocate(frame)


@@ -2812,6 +2826,9 @@ class CarlaHostPlugin(CarlaHostMeta):
def transport_pause(self): def transport_pause(self):
self.sendMsg(["transport_pause"]) self.sendMsg(["transport_pause"])


def transport_bpm(self, bpm):
self.sendMsg(["transport_bpm", bpm])

def transport_relocate(self, frame): def transport_relocate(self, frame):
self.sendMsg(["transport_relocate"]) self.sendMsg(["transport_relocate"])




+ 8
- 1
source/carla_host.py View File

@@ -292,7 +292,7 @@ class HostWindow(QMainWindow):
self.ui.l_transport_frame.setMinimumWidth(minValueWidth + 3) self.ui.l_transport_frame.setMinimumWidth(minValueWidth + 3)
self.ui.l_transport_time.setMinimumWidth(minValueWidth + 3) self.ui.l_transport_time.setMinimumWidth(minValueWidth + 3)


if host.isPlugin:
if host.isControl or host.isPlugin:
self.ui.b_transport_play.setEnabled(False) self.ui.b_transport_play.setEnabled(False)
self.ui.b_transport_stop.setEnabled(False) self.ui.b_transport_stop.setEnabled(False)
self.ui.b_transport_backwards.setEnabled(False) self.ui.b_transport_backwards.setEnabled(False)
@@ -441,6 +441,7 @@ class HostWindow(QMainWindow):
self.ui.b_transport_stop.clicked.connect(self.slot_transportStop) self.ui.b_transport_stop.clicked.connect(self.slot_transportStop)
self.ui.b_transport_backwards.clicked.connect(self.slot_transportBackwards) self.ui.b_transport_backwards.clicked.connect(self.slot_transportBackwards)
self.ui.b_transport_forwards.clicked.connect(self.slot_transportForwards) self.ui.b_transport_forwards.clicked.connect(self.slot_transportForwards)
self.ui.dsb_transport_bpm.valueChanged.connect(self.slot_transportBpmChanged)
self.ui.cb_transport_jack.clicked.connect(self.slot_transportJackEnabled) self.ui.cb_transport_jack.clicked.connect(self.slot_transportJackEnabled)
self.ui.cb_transport_link.clicked.connect(self.slot_transportLinkEnabled) self.ui.cb_transport_link.clicked.connect(self.slot_transportLinkEnabled)


@@ -1683,7 +1684,9 @@ class HostWindow(QMainWindow):
self.fLastTransportBPM = bpm self.fLastTransportBPM = bpm


if bpm > 0.0: if bpm > 0.0:
self.ui.dsb_transport_bpm.blockSignals(True)
self.ui.dsb_transport_bpm.setValue(bpm) self.ui.dsb_transport_bpm.setValue(bpm)
self.ui.dsb_transport_bpm.blockSignals(False)
self.ui.dsb_transport_bpm.setStyleSheet("") self.ui.dsb_transport_bpm.setStyleSheet("")
else: else:
self.ui.dsb_transport_bpm.setStyleSheet("QDoubleSpinBox { color: palette(mid); }") self.ui.dsb_transport_bpm.setStyleSheet("QDoubleSpinBox { color: palette(mid); }")
@@ -1725,6 +1728,10 @@ class HostWindow(QMainWindow):


self.host.transport_relocate(newFrame) self.host.transport_relocate(newFrame)


@pyqtSlot(float)
def slot_transportBpmChanged(self, newValue):
self.host.transport_bpm(newValue)

@pyqtSlot() @pyqtSlot()
def slot_transportForwards(self): def slot_transportForwards(self):
if self.fSampleRate == 0.0 or self.host.isPlugin or not self.host.is_engine_running(): if self.fSampleRate == 0.0 or self.host.isPlugin or not self.host.is_engine_running():


Loading…
Cancel
Save