diff --git a/resources/resources.qrc b/resources/resources.qrc index 87793d9f2..606b0f5a5 100644 --- a/resources/resources.qrc +++ b/resources/resources.qrc @@ -42,6 +42,7 @@ 48x48/juce.png 48x48/folder.png 48x48/warning.png + 48x48/wine.png 48x48/carla.png 48x48/carla-control.png diff --git a/resources/ui/carla_settings.ui b/resources/ui/carla_settings.ui index ef5240aa7..e80694f27 100644 --- a/resources/ui/carla_settings.ui +++ b/resources/ui/carla_settings.ui @@ -7,7 +7,7 @@ 0 0 612 - 465 + 484 @@ -86,6 +86,11 @@ paths + + + wine + + experimental @@ -172,6 +177,24 @@ + + Wine + + + + 75 + true + + + + + :/48x48/wine.png:/48x48/wine.png + + + ItemIsSelectable|ItemIsEnabled + + + Experimental @@ -1380,6 +1403,290 @@ + + + + 2 + + + + + + + <b>Wine</b> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + :/48x48/wine.png + + + Qt::AlignHCenter|Qt::AlignTop + + + + + + + + + Executable + + + + + + Path to 'wine' binary: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Prefix + + + + + + Auto-detect Wine prefix based on plugin filename + + + + + + + Fallback: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + + + + Realtime Priority + + + true + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + 1 + + + 89 + + + + + + + Base priority: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + WineServer priority: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 1 + + + 99 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 22 + 22 + + + + + + + :/16x16/dialog-information.png + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + These options are not available for Carla as plugin + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 115 + + + + + + + + + 16777215 + 5 + + + + + + + + + @@ -1494,6 +1801,16 @@ + + + + false + + + Enable Wine bridges + + + @@ -1753,5 +2070,21 @@ This mode is not available for VST plugins. + + cb_exp_plugin_bridges + toggled(bool) + ch_exp_wine_bridges + setEnabled(bool) + + + 402 + 122 + + + 402 + 145 + + + diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h index 01bf64cc5..0778ac9b2 100644 --- a/source/backend/CarlaBackend.h +++ b/source/backend/CarlaBackend.h @@ -1090,10 +1090,40 @@ typedef enum { */ ENGINE_OPTION_FRONTEND_WIN_ID = 17, + /*! + * Set path to wine executable. + */ + ENGINE_OPTION_WINE_EXECUTABLE = 18, + + /*! + * Enable automatic wineprefix detection. + */ + ENGINE_OPTION_WINE_AUTO_PREFIX = 19, + + /*! + * Fallback wineprefix to use if automatic detection fails or is diabled, and WINEPREFIX is not set. + */ + ENGINE_OPTION_WINE_FALLBACK_PREFIX = 20, + + /*! + * Enable realtie priority for Wine application and server threads. + */ + ENGINE_OPTION_WINE_RT_PRIO_ENABLED = 21, + + /*! + * Base realtime priority for Wine threads. + */ + ENGINE_OPTION_WINE_BASE_RT_PRIO = 22, + + /*! + * Wine server realtime priority. + */ + ENGINE_OPTION_WINE_SERVER_RT_PRIO = 23, + /*! * Capture console output into debug callbacks. */ - ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT = 18 + ENGINE_OPTION_DEBUG_CONSOLE_OUTPUT = 24 } EngineOption; diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index f66b4441b..942267a65 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -254,6 +254,25 @@ struct CARLA_API EngineOptions { bool preventBadBehaviour; uintptr_t frontendWinId; + struct Wine { + const char* exec; + + bool autoPrefix; + const char* fallbackPrefix; + + bool rtPrio; + int baseRtPrio; + int serverRtPrio; + + Wine() + : exec(nullptr), + autoPrefix(true), + fallbackPrefix(nullptr), + rtPrio(true), + baseRtPrio(15), + serverRtPrio(10) {} + } wine; + #ifndef DOXYGEN EngineOptions() noexcept; ~EngineOptions() noexcept; diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp index ff360fd82..1e5cdd99a 100644 --- a/source/backend/CarlaStandalone.cpp +++ b/source/backend/CarlaStandalone.cpp @@ -224,6 +224,8 @@ static void carla_engine_init_common() gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_BUFFER_SIZE, static_cast(gStandalone.engineOptions.audioBufferSize), nullptr); gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE, static_cast(gStandalone.engineOptions.audioSampleRate), nullptr); + gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_SAMPLE_RATE, static_cast(gStandalone.engineOptions.audioSampleRate), nullptr); + if (gStandalone.engineOptions.audioDevice != nullptr) gStandalone.engine->setOption(CB::ENGINE_OPTION_AUDIO_DEVICE, 0, gStandalone.engineOptions.audioDevice); diff --git a/source/carla_backend.py b/source/carla_backend.py index 0bb587ba6..d3e10c491 100644 --- a/source/carla_backend.py +++ b/source/carla_backend.py @@ -1243,8 +1243,9 @@ class CarlaHostMeta(object): self.preferPluginBridges = False self.preferUIBridges = False self.preventBadBehaviour = False - self.showPluginBridges = False self.showLogs = False + self.showPluginBridges = False + self.showWineBridges = False self.uiBridgesTimeout = 0 self.uisAlwaysOnTop = False diff --git a/source/carla_database.py b/source/carla_database.py index 559d9a86b..c3e1eb8a2 100755 --- a/source/carla_database.py +++ b/source/carla_database.py @@ -1073,6 +1073,18 @@ class PluginRefreshW(QDialog): self.ui.label_win64.hide() self.ui.sep_format.hide() + elif not host.showWineBridges: + self.ui.ch_win32.setChecked(False) + self.ui.ch_win32.setEnabled(False) + self.ui.ch_win32.setVisible(False) + self.ui.ch_win64.setChecked(False) + self.ui.ch_win64.setEnabled(False) + self.ui.ch_win64.setVisible(False) + self.ui.ico_win32.hide() + self.ui.ico_win64.hide() + self.ui.label_win32.hide() + self.ui.label_win64.hide() + # ---------------------------------------------------------------------------------------------------- # Resize to minimum size, as it's very likely UI stuff was hidden @@ -1319,9 +1331,9 @@ class PluginDatabaseW(QDialog): self.loadSettings() # ---------------------------------------------------------------------------------------------------- - # Disable bridges (experimental for now) + # Disable bridges if not enabled in settings - if not host.experimental: + if not host.showPluginBridges: self.ui.ch_native.setChecked(True) self.ui.ch_native.setEnabled(False) self.ui.ch_native.setVisible(False) @@ -1333,6 +1345,11 @@ class PluginDatabaseW(QDialog): self.ui.ch_bridged_wine.setVisible(False) self.ui.l_arch.setVisible(False) + elif not host.showWineBridges: + self.ui.ch_bridged_wine.setChecked(False) + self.ui.ch_bridged_wine.setEnabled(False) + self.ui.ch_bridged_wine.setVisible(False) + # ---------------------------------------------------------------------------------------------------- # Set-up connections diff --git a/source/carla_host.py b/source/carla_host.py index 9baf79af1..1292ca550 100644 --- a/source/carla_host.py +++ b/source/carla_host.py @@ -2554,15 +2554,20 @@ def loadHostSettings(host): except: host.preventBadBehaviour = CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR + try: + host.showLogs = settings.value(CARLA_KEY_MAIN_SHOW_LOGS, CARLA_DEFAULT_MAIN_SHOW_LOGS, type=bool) + except: + host.showLogs = CARLA_DEFAULT_MAIN_SHOW_LOGS + try: host.showPluginBridges = settings.value(CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES, CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES, type=bool) except: host.showPluginBridges = CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES try: - host.showLogs = settings.value(CARLA_KEY_MAIN_SHOW_LOGS, CARLA_DEFAULT_MAIN_SHOW_LOGS, type=bool) + host.showWineBridges = settings.value(CARLA_KEY_EXPERIMENTAL_WINE_BRIDGES, CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES, type=bool) except: - host.showLogs = CARLA_DEFAULT_MAIN_SHOW_LOGS + host.showWineBridges = CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES try: host.uiBridgesTimeout = settings.value(CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT, CARLA_DEFAULT_UI_BRIDGES_TIMEOUT, type=int) diff --git a/source/carla_settings.py b/source/carla_settings.py index a65e83d59..de499c454 100755 --- a/source/carla_settings.py +++ b/source/carla_settings.py @@ -193,8 +193,9 @@ class CarlaSettingsW(QDialog): TAB_INDEX_CANVAS = 1 TAB_INDEX_ENGINE = 2 TAB_INDEX_PATHS = 3 - TAB_INDEX_EXPERIMENTAL = 4 - TAB_INDEX_NONE = 5 + TAB_INDEX_WINE = 4 + TAB_INDEX_EXPERIMENTAL = 5 + TAB_INDEX_NONE = 6 # Path indexes PATH_INDEX_LADSPA = 0 @@ -275,6 +276,11 @@ class CarlaSettingsW(QDialog): if host.isControl or host.isPlugin: self.ui.ch_exp_load_lib_global.hide() + self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) + + if not LINUX: + self.ui.ch_exp_wine_bridges.setVisible(False) + self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) # FIXME, pipes on win32 not working if WINDOWS: @@ -315,6 +321,7 @@ class CarlaSettingsW(QDialog): self.ui.lw_sfz.currentRowChanged.connect(self.slot_pluginPathRowChanged) self.ui.ch_main_experimental.toggled.connect(self.slot_enableExperimental) + self.ui.ch_exp_wine_bridges.toggled.connect(self.slot_enableWineBridges) self.ui.cb_canvas_eyecandy.toggled.connect(self.slot_canvasEyeCandyToggled) self.ui.cb_canvas_fancy_eyecandy.toggled.connect(self.slot_canvasFancyEyeCandyToggled) @@ -374,6 +381,10 @@ class CarlaSettingsW(QDialog): if not self.host.experimental: self.ui.lw_page.hideRow(self.TAB_INDEX_EXPERIMENTAL) + self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) + + elif not self.host.showWineBridges: + self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) # ---------------------------------------------------------------------------------------------------- # Engine @@ -415,6 +426,8 @@ class CarlaSettingsW(QDialog): self.ui.ch_engine_force_stereo.setChecked(self.host.forceStereo or not self.ui.ch_engine_force_stereo.isEnabled()) self.ui.ch_engine_prefer_plugin_bridges.setChecked(self.host.preferPluginBridges) self.ui.ch_exp_export_lv2.setChecked(self.host.exportLV2) + self.ui.cb_exp_plugin_bridges.setChecked(self.host.showPluginBridges) + self.ui.ch_exp_wine_bridges.setChecked(self.host.showWineBridges) # ---------------------------------------------------------------------------------------------------- # Paths @@ -470,11 +483,34 @@ class CarlaSettingsW(QDialog): self.ui.lw_sfz.addItem(sfz) # ---------------------------------------------------------------------------------------------------- - # Experimental + # Wine + + self.ui.le_wine_exec.setText(settings.value(CARLA_KEY_WINE_EXECUTABLE, + CARLA_DEFAULT_WINE_EXECUTABLE, + type=str)) + + self.ui.cb_wine_prefix_detect.setChecked(settings.value(CARLA_KEY_WINE_AUTO_PREFIX, + CARLA_DEFAULT_WINE_AUTO_PREFIX, + type=bool)) + + self.ui.le_wine_prefix_fallback.setText(settings.value(CARLA_KEY_WINE_FALLBACK_PREFIX, + CARLA_DEFAULT_WINE_FALLBACK_PREFIX, + type=str)) - self.ui.cb_exp_plugin_bridges.setChecked(settings.value(CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES, - CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES, - type=bool)) + self.ui.group_wine_realtime.setChecked(settings.value(CARLA_KEY_WINE_RT_PRIO_ENABLED, + CARLA_DEFAULT_WINE_RT_PRIO_ENABLED, + type=bool)) + + self.ui.sb_wine_base_prio.setValue(settings.value(CARLA_KEY_WINE_BASE_RT_PRIO, + CARLA_DEFAULT_WINE_BASE_RT_PRIO, + type=int)) + + self.ui.sb_wine_server_prio.setValue(settings.value(CARLA_KEY_WINE_SERVER_RT_PRIO, + CARLA_DEFAULT_WINE_SERVER_RT_PRIO, + type=int)) + + # ---------------------------------------------------------------------------------------------------- + # Experimental self.ui.ch_exp_jack_apps.setChecked(settings.value(CARLA_KEY_EXPERIMENTAL_JACK_APPS, CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS, @@ -558,6 +594,8 @@ class CarlaSettingsW(QDialog): self.host.preferPluginBridges = self.ui.ch_engine_prefer_plugin_bridges.isChecked() self.host.preferUIBridges = self.ui.ch_engine_prefer_ui_bridges.isChecked() self.host.showLogs = self.ui.ch_main_show_logs.isChecked() + self.host.showPluginBridges = self.ui.cb_exp_plugin_bridges.isChecked() + self.host.showWineBridges = self.ui.ch_exp_wine_bridges.isChecked() self.host.uiBridgesTimeout = self.ui.sb_engine_ui_bridges_timeout.value() self.host.uisAlwaysOnTop = self.ui.ch_engine_uis_always_on_top.isChecked() @@ -581,6 +619,8 @@ class CarlaSettingsW(QDialog): settings.setValue(CARLA_KEY_ENGINE_UI_BRIDGES_TIMEOUT, self.host.uiBridgesTimeout) settings.setValue(CARLA_KEY_ENGINE_UIS_ALWAYS_ON_TOP, self.host.uisAlwaysOnTop) settings.setValue(CARLA_KEY_EXPERIMENTAL_EXPORT_LV2, self.host.exportLV2) + settings.setValue(CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES, self.host.showPluginBridges) + settings.setValue(CARLA_KEY_EXPERIMENTAL_WINE_BRIDGES, self.host.showWineBridges) # ---------------------------------------------------------------------------------------------------- # Paths @@ -636,10 +676,23 @@ class CarlaSettingsW(QDialog): settings.setValue(CARLA_KEY_PATHS_SF2, sf2s) settings.setValue(CARLA_KEY_PATHS_SFZ, sfzs) + # ---------------------------------------------------------------------------------------------------- + # Wine + + settings.setValue(CARLA_KEY_EXPERIMENTAL_JACK_APPS, self.ui.ch_exp_jack_apps.isChecked()) + settings.setValue(CARLA_KEY_EXPERIMENTAL_LOAD_LIB_GLOBAL, self.ui.ch_exp_load_lib_global.isChecked()) + settings.setValue(CARLA_KEY_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR, self.ui.ch_exp_prevent_bad_behaviour.isChecked()) + + settings.setValue(CARLA_KEY_WINE_EXECUTABLE, self.ui.le_wine_exec.text()) + settings.setValue(CARLA_KEY_WINE_AUTO_PREFIX, self.ui.cb_wine_prefix_detect.isChecked()) + settings.setValue(CARLA_KEY_WINE_FALLBACK_PREFIX, self.ui.le_wine_prefix_fallback.text()) + settings.setValue(CARLA_KEY_WINE_RT_PRIO_ENABLED, self.ui.group_wine_realtime.isChecked()) + settings.setValue(CARLA_KEY_WINE_BASE_RT_PRIO, self.ui.sb_wine_base_prio.value()) + settings.setValue(CARLA_KEY_WINE_SERVER_RT_PRIO, self.ui.sb_wine_server_prio.value()) + # ---------------------------------------------------------------------------------------------------- # Experimental - settings.setValue(CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES, self.ui.cb_exp_plugin_bridges.isChecked()) settings.setValue(CARLA_KEY_EXPERIMENTAL_JACK_APPS, self.ui.ch_exp_jack_apps.isChecked()) settings.setValue(CARLA_KEY_EXPERIMENTAL_LOAD_LIB_GLOBAL, self.ui.ch_exp_load_lib_global.isChecked()) settings.setValue(CARLA_KEY_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR, self.ui.ch_exp_prevent_bad_behaviour.isChecked()) @@ -770,6 +823,17 @@ class CarlaSettingsW(QDialog): if not path: continue self.ui.lw_sfz.addItem(path) + # ---------------------------------------------------------------------------------------------------- + # Wine + + elif self.ui.lw_page.currentRow() == self.TAB_INDEX_WINE: + self.ui.le_wine_exec.setText(CARLA_DEFAULT_WINE_EXECUTABLE) + self.ui.cb_wine_prefix_detect.setChecked(CARLA_DEFAULT_WINE_AUTO_PREFIX) + self.ui.le_wine_prefix_fallback.setText(CARLA_DEFAULT_WINE_FALLBACK_PREFIX) + self.ui.group_wine_realtime.setChecked(CARLA_DEFAULT_WINE_RT_PRIO_ENABLED) + self.ui.sb_wine_base_prio.setValue(CARLA_DEFAULT_WINE_BASE_RT_PRIO) + self.ui.sb_wine_server_prio.setValue(CARLA_DEFAULT_WINE_SERVER_RT_PRIO) + # ---------------------------------------------------------------------------------------------------- # Experimental @@ -779,6 +843,7 @@ class CarlaSettingsW(QDialog): def resetExperimentalSettings(self): # Forever experimental self.ui.cb_exp_plugin_bridges.setChecked(CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES) + self.ui.ch_exp_wine_bridges.setChecked(CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES) self.ui.ch_exp_jack_apps.setChecked(CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS) self.ui.ch_exp_export_lv2.setChecked(CARLA_DEFAULT_EXPERIMENTAL_LV2_EXPORT) self.ui.ch_exp_load_lib_global.setChecked(CARLA_DEFAULT_EXPERIMENTAL_LOAD_LIB_GLOBAL) @@ -797,8 +862,18 @@ class CarlaSettingsW(QDialog): def slot_enableExperimental(self, toggled): if toggled: self.ui.lw_page.showRow(self.TAB_INDEX_EXPERIMENTAL) + if self.ui.ch_exp_wine_bridges.isChecked(): + self.ui.lw_page.showRow(self.TAB_INDEX_WINE) else: self.ui.lw_page.hideRow(self.TAB_INDEX_EXPERIMENTAL) + self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) + + @pyqtSlot(bool) + def slot_enableWineBridges(self, toggled): + if toggled: + self.ui.lw_page.showRow(self.TAB_INDEX_WINE) + else: + self.ui.lw_page.hideRow(self.TAB_INDEX_WINE) @pyqtSlot(bool) def slot_canvasEyeCandyToggled(self, toggled): diff --git a/source/carla_shared.py b/source/carla_shared.py index 8a745457b..1468ee2bf 100644 --- a/source/carla_shared.py +++ b/source/carla_shared.py @@ -227,7 +227,15 @@ CARLA_KEY_PATHS_GIG = "Paths/GIG" CARLA_KEY_PATHS_SF2 = "Paths/SF2" CARLA_KEY_PATHS_SFZ = "Paths/SFZ" +CARLA_KEY_WINE_EXECUTABLE = "Wine/Executable" # str +CARLA_KEY_WINE_AUTO_PREFIX = "Wine/AutoPrefix" # bool +CARLA_KEY_WINE_FALLBACK_PREFIX = "Wine/FallbackPrefix" # str +CARLA_KEY_WINE_RT_PRIO_ENABLED = "Wine/RtPrioEnabled" # bool +CARLA_KEY_WINE_BASE_RT_PRIO = "Wine/BaseRtPrio" # int +CARLA_KEY_WINE_SERVER_RT_PRIO = "Wine/ServerRtPrio" # int + CARLA_KEY_EXPERIMENTAL_PLUGIN_BRIDGES = "Experimental/PluginBridges" # bool +CARLA_KEY_EXPERIMENTAL_WINE_BRIDGES = "Experimental/WineBridges" # bool CARLA_KEY_EXPERIMENTAL_JACK_APPS = "Experimental/JackApplications" # bool CARLA_KEY_EXPERIMENTAL_EXPORT_LV2 = "Experimental/ExportLV2" # bool CARLA_KEY_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR = "Experimental/PreventBadBehaviour" # bool @@ -289,7 +297,17 @@ else: CARLA_DEFAULT_PROCESS_MODE = ENGINE_PROCESS_MODE_PATCHBAY CARLA_DEFAULT_TRANSPORT_MODE = ENGINE_TRANSPORT_MODE_INTERNAL +# Wine +CARLA_DEFAULT_WINE_EXECUTABLE = "wine" +CARLA_DEFAULT_WINE_AUTO_PREFIX = True +CARLA_DEFAULT_WINE_FALLBACK_PREFIX = os.path.expanduser("~/.wine") +CARLA_DEFAULT_WINE_RT_PRIO_ENABLED = True +CARLA_DEFAULT_WINE_BASE_RT_PRIO = 15 +CARLA_DEFAULT_WINE_SERVER_RT_PRIO = 10 + +# Experimental CARLA_DEFAULT_EXPERIMENTAL_PLUGIN_BRIDGES = False +CARLA_DEFAULT_EXPERIMENTAL_WINE_BRIDGES = False CARLA_DEFAULT_EXPERIMENTAL_JACK_APPS = False CARLA_DEFAULT_EXPERIMENTAL_LV2_EXPORT = False CARLA_DEFAULT_EXPERIMENTAL_PREVENT_BAD_BEHAVIOUR = False