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">
<item>
<widget class="QDoubleSpinBox" name="dsb_transport_bpm">
<property name="enabled">
<bool>false</bool>
</property>
<property name="suffix">
<string> BPM</string>
</property>


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

@@ -988,6 +988,11 @@ public:
*/
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.
*/


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

@@ -433,6 +433,11 @@ CARLA_EXPORT void carla_transport_play();
*/
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.
*/


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

@@ -743,6 +743,14 @@ void carla_transport_pause()
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)
{
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();
}

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
{
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;
}

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

double abs_beat, abs_tick;

@@ -195,8 +203,8 @@ void EngineInternalTime::fillEngineTimeInfo(const uint32_t newFrames) noexcept
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.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);
tick = ticktmp;

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

double abs_beat, abs_tick;

@@ -269,9 +277,9 @@ void EngineInternalTime::fillJackTimeInfo(jack_position_t* const pos, const uint
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;

//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);
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 enableLink(const bool enable);
void setBPM(const double bpm);
void setNeedsReset() 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
fIsRunning(false)
#else
fTimebaseMaster(false),
fUsedGroups(),
fUsedPorts(),
fUsedConnections(),
@@ -951,9 +952,10 @@ public:
jackbridge_set_freewheel_callback(fClient, carla_jack_freewheel_callback, this);
jackbridge_set_latency_callback(fClient, carla_jack_latency_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);

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

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

@@ -1373,7 +1375,7 @@ public:
{
// old timebase master no longer active, make ourselves master again
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 {
@@ -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
{
if (pData->options.transportMode == ENGINE_TRANSPORT_MODE_INTERNAL)
@@ -1984,6 +2011,7 @@ private:

jack_port_t* fRackPorts[kRackPortCount];

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


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

@@ -236,6 +236,14 @@ protected:
{
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)
{
uint64_t frame;


+ 17
- 0
source/carla_backend.py View File

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

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

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

def transport_bpm(self, bpm):
return

def transport_relocate(self, frame):
return

@@ -2206,6 +2214,9 @@ class CarlaHostDLL(CarlaHostMeta):
self.lib.carla_transport_pause.argtypes = 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.restype = None

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

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

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

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

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

def transport_relocate(self, frame):
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_time.setMinimumWidth(minValueWidth + 3)

if host.isPlugin:
if host.isControl or host.isPlugin:
self.ui.b_transport_play.setEnabled(False)
self.ui.b_transport_stop.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_backwards.clicked.connect(self.slot_transportBackwards)
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_link.clicked.connect(self.slot_transportLinkEnabled)

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

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

self.host.transport_relocate(newFrame)

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

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


Loading…
Cancel
Save