Browse Source

Implement device config changes at runtime (juce and jack)

tags/v2.1-rc1
falkTX 6 years ago
parent
commit
18095d27b1
11 changed files with 135 additions and 4 deletions
  1. +8
    -2
      resources/ui/carla_settings_driver.ui
  2. +8
    -0
      source/backend/CarlaEngine.hpp
  3. +8
    -0
      source/backend/CarlaHost.h
  4. +8
    -0
      source/backend/CarlaStandalone.cpp
  5. +5
    -0
      source/backend/engine/CarlaEngine.cpp
  6. +10
    -0
      source/backend/engine/CarlaEngineJack.cpp
  7. +63
    -0
      source/backend/engine/CarlaEngineJuce.cpp
  8. +1
    -0
      source/backend/engine/CarlaEngineNative.cpp
  9. +19
    -0
      source/frontend/carla_backend.py
  10. +3
    -0
      source/frontend/carla_host.py
  11. +2
    -2
      source/frontend/carla_settings.py

+ 8
- 2
resources/ui/carla_settings_driver.ui View File

@@ -37,7 +37,7 @@
</property>
<property name="sizeHint" stdset="0">
<size>
<width>1</width>
<width>40</width>
<height>1</height>
</size>
</property>
@@ -61,6 +61,9 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
@@ -94,10 +97,13 @@
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
<height>1</height>
</size>
</property>
</spacer>


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

@@ -837,8 +837,16 @@ public:
*/
virtual void clearXruns() const noexcept;

/*!
* Dynamically change buffer size and/or sample rate while engine is running.
* @see ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE
* @see ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE
*/
virtual bool setBufferSizeAndSampleRate(const uint bufferSize, const double sampleRate);

/*!
* Show the custom control panel for the current engine device.
* @see ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL
*/
virtual bool showDeviceControlPanel() const noexcept;



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

@@ -427,8 +427,16 @@ CARLA_EXPORT const CarlaRuntimeEngineInfo* carla_get_runtime_engine_info();
*/
CARLA_EXPORT const CarlaRuntimeEngineDriverDeviceInfo* carla_get_runtime_engine_driver_device_info();

/*!
* Dynamically change buffer size and/or sample rate while engine is running.
* @see ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE
* @see ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE
*/
CARLA_EXPORT bool carla_set_engine_buffer_size_and_sample_rate(uint bufferSize, double sampleRate);

/*!
* Show the custom control panel for the current engine device.
* @see ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL
*/
CARLA_EXPORT bool carla_show_engine_device_control_panel();



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

@@ -541,6 +541,14 @@ const CarlaRuntimeEngineDriverDeviceInfo* carla_get_runtime_engine_driver_device
return &retInfo;
}

bool carla_set_engine_buffer_size_and_sample_rate(uint bufferSize, double sampleRate)
{
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, false);
carla_debug("carla_set_engine_buffer_size_and_sample_rate(%u, %f)", bufferSize, sampleRate);

return gStandalone.engine->setBufferSizeAndSampleRate(bufferSize, sampleRate);
}

bool carla_show_engine_device_control_panel()
{
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, false);


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

@@ -410,6 +410,11 @@ bool CarlaEngine::showDeviceControlPanel() const noexcept
return false;
}

bool CarlaEngine::setBufferSizeAndSampleRate(const uint, const double)
{
return false;
}

// -----------------------------------------------------------------------
// Plugin management



+ 10
- 0
source/backend/engine/CarlaEngineJack.cpp View File

@@ -1191,6 +1191,16 @@ public:
}
#endif

bool setBufferSizeAndSampleRate(const uint bufferSize, const double sampleRate) override
{
CARLA_SAFE_ASSERT_RETURN(carla_isEqual(pData->sampleRate, sampleRate), false);
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, false);

try {
return jackbridge_set_buffer_size(fClient, bufferSize);
} CARLA_SAFE_EXCEPTION_RETURN("setBufferSizeAndSampleRate", false);
}

EngineTimeInfo getTimeInfo() const noexcept override
{
if (pData->options.transportMode != ENGINE_TRANSPORT_MODE_JACK)


+ 63
- 0
source/backend/engine/CarlaEngineJuce.cpp View File

@@ -352,6 +352,69 @@ public:
pData->xruns = xruns > 0 ? static_cast<uint32_t>(xruns) : 0;
}

bool setBufferSizeAndSampleRate(const uint bufferSize, const double sampleRate) override
{
CARLA_SAFE_ASSERT_RETURN(fDevice != nullptr, false);

juce::StringArray inputNames(fDevice->getInputChannelNames());
juce::StringArray outputNames(fDevice->getOutputChannelNames());

if (inputNames.size() < 0 || outputNames.size() <= 0)
{
setLastError("Selected device does not have any outputs");
return false;
}

juce::BigInteger inputChannels;
inputChannels.setRange(0, inputNames.size(), true);

juce::BigInteger outputChannels;
outputChannels.setRange(0, outputNames.size(), true);

// stop stream first
if (fDevice->isPlaying())
fDevice->stop();
if (fDevice->isOpen())
fDevice->close();

juce::String error = fDevice->open(inputChannels, outputChannels, sampleRate, static_cast<int>(bufferSize));

if (error.isNotEmpty())
{
setLastError(error.toUTF8());

// try to roll back
error = fDevice->open(inputChannels, outputChannels, pData->sampleRate, static_cast<int>(pData->bufferSize));

// if we failed, we are screwed...
if (error.isNotEmpty())
{
fDevice = nullptr;
close();
}

return false;
}

const uint32_t newBufferSize = static_cast<uint32_t>(fDevice->getCurrentBufferSizeSamples());
const double newSampleRate = fDevice->getCurrentSampleRate();

if (carla_isNotEqual(pData->sampleRate, newSampleRate))
{
pData->sampleRate = newSampleRate;
sampleRateChanged(newSampleRate);
}

if (pData->bufferSize != newBufferSize)
{
pData->bufferSize = newBufferSize;
bufferSizeChanged(newBufferSize);
}

fDevice->start(this);
return true;
}

bool showDeviceControlPanel() const noexcept override
{
try {


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

@@ -2738,6 +2738,7 @@ uint CarlaEngine::getJuceApiCount() { return 0;
const char* CarlaEngine::getJuceApiName(const uint) { return nullptr; }
const char* const* CarlaEngine::getJuceApiDeviceNames(const uint) { return nullptr; }
const EngineDriverDeviceInfo* CarlaEngine::getJuceDeviceInfo(const uint, const char* const) { return nullptr; }
bool CarlaEngine::showJuceDeviceControlPanel(const uint, const char* const) { return false; }
# else
CarlaEngine* CarlaEngine::newRtAudio(const AudioApi) { return nullptr; }
uint CarlaEngine::getRtAudioApiCount() { return 0; }


+ 19
- 0
source/frontend/carla_backend.py View File

@@ -1508,7 +1508,14 @@ class CarlaHostMeta(object):
def get_runtime_engine_driver_device_info(self):
raise NotImplementedError

# Dynamically change buffer size and/or sample rate while engine is running.
# @see ENGINE_DRIVER_DEVICE_VARIABLE_BUFFER_SIZE
# @see ENGINE_DRIVER_DEVICE_VARIABLE_SAMPLE_RATE
def set_engine_buffer_size_and_sample_rate(self, bufferSize, sampleRate):
raise NotImplementedError

# Show the custom control panel for the current engine device.
# @see ENGINE_DRIVER_DEVICE_HAS_CONTROL_PANEL
def show_engine_device_control_panel(self):
raise NotImplementedError

@@ -2168,6 +2175,9 @@ class CarlaHostNull(CarlaHostMeta):
def get_runtime_engine_driver_device_info(self):
return PyCarlaRuntimeEngineDriverDeviceInfo

def set_engine_buffer_size_and_sample_rate(self, bufferSize, sampleRate):
return False

def show_engine_device_control_panel(self):
return False

@@ -2477,6 +2487,9 @@ class CarlaHostDLL(CarlaHostMeta):
self.lib.carla_get_runtime_engine_driver_device_info.argtypes = None
self.lib.carla_get_runtime_engine_driver_device_info.restype = POINTER(CarlaRuntimeEngineDriverDeviceInfo)

self.lib.carla_set_engine_buffer_size_and_sample_rate.argtypes = [c_uint, c_double]
self.lib.carla_set_engine_buffer_size_and_sample_rate.restype = c_bool

self.lib.carla_show_engine_device_control_panel.argtypes = None
self.lib.carla_show_engine_device_control_panel.restype = c_bool

@@ -2776,6 +2789,9 @@ class CarlaHostDLL(CarlaHostMeta):
def get_runtime_engine_driver_device_info(self):
return structToDict(self.lib.carla_get_runtime_engine_driver_device_info().contents)

def set_engine_buffer_size_and_sample_rate(self, bufferSize, sampleRate):
return bool(self.lib.carla_set_engine_buffer_size_and_sample_rate(bufferSize, sampleRate))

def show_engine_device_control_panel(self):
return bool(self.lib.carla_show_engine_device_control_panel())

@@ -3166,6 +3182,9 @@ class CarlaHostPlugin(CarlaHostMeta):
def get_runtime_engine_driver_device_info(self):
return PyCarlaRuntimeEngineDriverDeviceInfo

def set_engine_buffer_size_and_sample_rate(self, bufferSize, sampleRate):
return False

def show_engine_device_control_panel(self):
return False



+ 3
- 0
source/frontend/carla_host.py View File

@@ -877,6 +877,9 @@ class HostWindow(QMainWindow):
QMessageBox.warning(self, self.tr("Warning"), self.tr("Engine was stopped while configuring settings, all changes have been ignored"))
return

bufferSize, sampleRate = dialog.getValues()
self.host.set_engine_buffer_size_and_sample_rate(bufferSize, sampleRate)

@pyqtSlot()
def slot_engineStopTryAgain(self):
if self.host.is_engine_running() and not self.host.set_engine_about_to_close():


+ 2
- 2
source/frontend/carla_settings.py View File

@@ -281,9 +281,9 @@ class RuntimeDriverSettingsW(QDialog):
bufferSize = self.ui.cb_buffersize.currentText()
sampleRate = self.ui.cb_samplerate.currentText()

if bufferSize == self.AUTOMATIC_OPTION:
if bufferSize == DriverSettingsW.AUTOMATIC_OPTION:
bufferSize = "0"
if sampleRate == self.AUTOMATIC_OPTION:
if sampleRate == DriverSettingsW.AUTOMATIC_OPTION:
sampleRate = "0"

return (int(bufferSize), int(sampleRate))


Loading…
Cancel
Save