Signed-off-by: falkTX <falktx@falktx.com>tags/v1.3.0
| @@ -49,7 +49,7 @@ sudo cp build64/wineasio64.dll.so /usr/lib/x86_64-linux-gnu/wine/x86_64-unix/ | |||||
| For user convenience a `wineasio-register` script is included in this repo, if you are packaging WineASIO consider installing it as part of WineASIO. | For user convenience a `wineasio-register` script is included in this repo, if you are packaging WineASIO consider installing it as part of WineASIO. | ||||
| Additionally a control panel GUI is provided in this repository's `gui` subdir, which requires PyQt5 to build and run. | |||||
| Additionally a control panel GUI is provided in this repository's `gui` subdir, which requires PyQt6 or PyQt5 to build and run. | |||||
| The WineASIO driver will use this GUI as the ASIO control panel. | The WineASIO driver will use this GUI as the ASIO control panel. | ||||
| ### REGISTERING | ### REGISTERING | ||||
| @@ -123,7 +123,8 @@ that overrides the JACK client name derived from the program name. | |||||
| ### CHANGE LOG | ### CHANGE LOG | ||||
| #### 1.3.0 WIP | |||||
| #### 1.3.0 | |||||
| * 24-JUL-2025: Make GUI settings panel compatible with PyQt6 or PyQt5 | |||||
| * 17-JUL-2025: Load libjack.so.0 dynamically at runtime, removing build dep | * 17-JUL-2025: Load libjack.so.0 dynamically at runtime, removing build dep | ||||
| * 17-JUL-2025: Remove useless -mnocygwin flag | * 17-JUL-2025: Remove useless -mnocygwin flag | ||||
| * 28-JUN-2025: Remove dependency on asio headers | * 28-JUN-2025: Remove dependency on asio headers | ||||
| @@ -16,10 +16,42 @@ all: | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| # UI code | # UI code | ||||
| define UI_IMPORTS | |||||
| try:\\n | |||||
| from PyQt6.QtCore import Qt, QCoreApplication, QMetaObject\\n | |||||
| from PyQt6.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox\\n | |||||
| from PyQt6.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy\\n | |||||
| Qt.AlignRight = Qt.AlignmentFlag.AlignRight\\n | |||||
| Qt.AlignTrailing = Qt.AlignmentFlag.AlignTrailing\\n | |||||
| Qt.AlignVCenter = Qt.AlignmentFlag.AlignVCenter\\n | |||||
| Qt.Horizontal = Qt.Orientation.Horizontal\\n | |||||
| QSizePolicy.Fixed = QSizePolicy.Policy.Fixed\\n | |||||
| QSizePolicy.Minimum = QSizePolicy.Policy.Minimum\\n | |||||
| QDialogButtonBox.Cancel = QDialogButtonBox.StandardButton.Cancel\\n | |||||
| QDialogButtonBox.Ok = QDialogButtonBox.StandardButton.Ok\\n | |||||
| QDialogButtonBox.RestoreDefaults = QDialogButtonBox.StandardButton.RestoreDefaults\\n | |||||
| except ImportError:\\n | |||||
| from PyQt5.QtCore import Qt, QCoreApplication, QMetaObject\\n | |||||
| from PyQt5.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox\\n | |||||
| from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy | |||||
| endef | |||||
| export UI_IMPORTS | |||||
| regen: ui_settings.py | regen: ui_settings.py | ||||
| ui_%.py: %.ui | ui_%.py: %.ui | ||||
| $(PYUIC) $< -o $@ | $(PYUIC) $< -o $@ | ||||
| sed -i 's/QtCore.//g' $@ | |||||
| sed -i 's/QtGui.//g' $@ | |||||
| sed -i 's/QtWidgets.//g' $@ | |||||
| sed -i 's/_translate = QCoreApplication.translate/_tr = QCoreApplication.translate/' $@ | |||||
| sed -i 's/_translate(/_tr(/g' $@ | |||||
| sed -i 's/"WineASIOSettings"/self.OBJECT_NAME/g' $@ | |||||
| sed -i 's/ # type: ignore//g' $@ | |||||
| sed -i 's/WineASIOSettings(object):/WineASIOSettings(object):\n OBJECT_NAME = "WineASIOSettings"\n/' $@ | |||||
| sed -i 's/from PyQt5 import QtWidgets/$(shell echo "$$UI_IMPORTS")/' $@ | |||||
| sed -i 's/ except ImportError:/except ImportError:/' $@ | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -2,7 +2,7 @@ | |||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
| # WineASIO Settings GUI | # WineASIO Settings GUI | ||||
| # Copyright (C) 2020 Filipe Coelho <falktx@falktx.com> | |||||
| # Copyright (C) 2020-2025 Filipe Coelho <falktx@falktx.com> | |||||
| # | # | ||||
| # This program is free software; you can redistribute it and/or modify | # This program is free software; you can redistribute it and/or modify | ||||
| # it under the terms of the GNU General Public License as published by | # it under the terms of the GNU General Public License as published by | ||||
| @@ -21,8 +21,15 @@ | |||||
| import os | import os | ||||
| import sys | import sys | ||||
| from PyQt5.QtCore import pyqtSlot, QDir | |||||
| from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox | |||||
| try: | |||||
| from PyQt6.QtCore import pyqtSlot, QDir | |||||
| from PyQt6.QtWidgets import QApplication, QDialog, QDialogButtonBox | |||||
| QDialogButtonBox.RestoreDefaults = QDialogButtonBox.StandardButton.RestoreDefaults | |||||
| useQt6 = True | |||||
| except ImportError: | |||||
| from PyQt5.QtCore import pyqtSlot, QDir | |||||
| from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox | |||||
| useQt6 = False | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -38,7 +45,7 @@ WINEPREFIX = os.getenv("WINEPREFIX") | |||||
| if not WINEPREFIX: | if not WINEPREFIX: | ||||
| WINEPREFIX = os.path.join(HOME, ".wine") | WINEPREFIX = os.path.join(HOME, ".wine") | ||||
| WINEASIO_PREFIX = "HKEY_CURRENT_USER\Software\Wine\WineASIO" | |||||
| WINEASIO_PREFIX = "HKEY_CURRENT_USER\\Software\\Wine\\WineASIO" | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -137,7 +144,7 @@ class WineASIOSettingsDialog(QDialog, Ui_WineASIOSettings): | |||||
| def slot_saveSettings(self): | def slot_saveSettings(self): | ||||
| REGFILE = 'REGEDIT4\n' | REGFILE = 'REGEDIT4\n' | ||||
| REGFILE += '\n' | REGFILE += '\n' | ||||
| REGFILE += '[HKEY_CURRENT_USER\Software\Wine\WineASIO]\n' | |||||
| REGFILE += '[HKEY_CURRENT_USER\\Software\\Wine\\WineASIO]\n' | |||||
| REGFILE += '"Autostart server"=dword:0000000%i\n' % int(1 if self.cb_jack_autostart.isChecked() else 0) | REGFILE += '"Autostart server"=dword:0000000%i\n' % int(1 if self.cb_jack_autostart.isChecked() else 0) | ||||
| REGFILE += '"Connect to hardware"=dword:0000000%i\n' % int(1 if self.cb_ports_connect_hw.isChecked() else 0) | REGFILE += '"Connect to hardware"=dword:0000000%i\n' % int(1 if self.cb_ports_connect_hw.isChecked() else 0) | ||||
| REGFILE += '"Fixed buffersize"=dword:0000000%i\n' % int(1 if self.cb_jack_fixed_bsize.isChecked() else 0) | REGFILE += '"Fixed buffersize"=dword:0000000%i\n' % int(1 if self.cb_jack_fixed_bsize.isChecked() else 0) | ||||
| @@ -164,6 +171,7 @@ if __name__ == '__main__': | |||||
| gui.show() | gui.show() | ||||
| # Exit properly | # Exit properly | ||||
| sys.exit(app.exec_()) | |||||
| ret = app.exec() if useQt6 else app.exec_() | |||||
| sys.exit(ret) | |||||
| # --------------------------------------------------------------------------------------------------------------------- | # --------------------------------------------------------------------------------------------------------------------- | ||||
| @@ -11,7 +11,7 @@ | |||||
| </rect> | </rect> | ||||
| </property> | </property> | ||||
| <property name="windowTitle"> | <property name="windowTitle"> | ||||
| <string>Dialog</string> | |||||
| <string>WineASIO Settings</string> | |||||
| </property> | </property> | ||||
| <layout class="QVBoxLayout" name="verticalLayout"> | <layout class="QVBoxLayout" name="verticalLayout"> | ||||
| <item> | <item> | ||||
| @@ -180,8 +180,9 @@ Default is off</string> | |||||
| <item> | <item> | ||||
| <widget class="QCheckBox" name="cb_jack_fixed_bsize"> | <widget class="QCheckBox" name="cb_jack_fixed_bsize"> | ||||
| <property name="toolTip"> | <property name="toolTip"> | ||||
| <string>When on, an asio app will be able to change the jack buffer size. | |||||
| Default is off</string> | |||||
| <string>When on: ASIO applications will respect the current JACK buffer size | |||||
| When off: ASIO applications can change the JACK buffer size | |||||
| Default is on</string> | |||||
| </property> | </property> | ||||
| <property name="text"> | <property name="text"> | ||||
| <string>Fixed buffersize</string> | <string>Fixed buffersize</string> | ||||
| @@ -1,28 +1,31 @@ | |||||
| #!/usr/bin/env python3 | |||||
| # -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||||
| # WineASIO Settings GUI | |||||
| # Copyright (C) 2020 Filipe Coelho <falktx@falktx.com> | |||||
| # Form implementation generated from reading ui file 'settings.ui' | |||||
| # | # | ||||
| # This program is free software; you can redistribute it and/or modify | |||||
| # it under the terms of the GNU General Public License as published by | |||||
| # the Free Software Foundation; either version 2 of the License, or | |||||
| # any later version. | |||||
| # Created by: PyQt5 UI code generator 5.15.11 | |||||
| # | # | ||||
| # This program is distributed in the hope that it will be useful, | |||||
| # but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
| # GNU General Public License for more details. | |||||
| # | |||||
| # For a full copy of the GNU General Public License see the COPYING.GUI file | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| # WARNING: Any manual changes made to this file will be lost when pyuic5 is | |||||
| # run again. Do not edit this file unless you know what you are doing. | |||||
| try: | |||||
| from PyQt6.QtCore import Qt, QCoreApplication, QMetaObject | |||||
| from PyQt6.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox | |||||
| from PyQt6.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy | |||||
| Qt.AlignRight = Qt.AlignmentFlag.AlignRight | |||||
| Qt.AlignTrailing = Qt.AlignmentFlag.AlignTrailing | |||||
| Qt.AlignVCenter = Qt.AlignmentFlag.AlignVCenter | |||||
| Qt.Horizontal = Qt.Orientation.Horizontal | |||||
| QSizePolicy.Fixed = QSizePolicy.Policy.Fixed | |||||
| QSizePolicy.Minimum = QSizePolicy.Policy.Minimum | |||||
| QDialogButtonBox.Cancel = QDialogButtonBox.StandardButton.Cancel | |||||
| QDialogButtonBox.Ok = QDialogButtonBox.StandardButton.Ok | |||||
| QDialogButtonBox.RestoreDefaults = QDialogButtonBox.StandardButton.RestoreDefaults | |||||
| except ImportError: | |||||
| from PyQt5.QtCore import Qt, QCoreApplication, QMetaObject | |||||
| from PyQt5.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox | |||||
| from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy | |||||
| from PyQt5.QtCore import Qt, QCoreApplication, QMetaObject | |||||
| from PyQt5.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox | |||||
| from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy | |||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| class Ui_WineASIOSettings(object): | class Ui_WineASIOSettings(object): | ||||
| OBJECT_NAME = "WineASIOSettings" | OBJECT_NAME = "WineASIOSettings" | ||||
| @@ -112,53 +115,30 @@ class Ui_WineASIOSettings(object): | |||||
| self.buttonBox.rejected.connect(WineASIOSettings.reject) | self.buttonBox.rejected.connect(WineASIOSettings.reject) | ||||
| QMetaObject.connectSlotsByName(WineASIOSettings) | QMetaObject.connectSlotsByName(WineASIOSettings) | ||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||
| def retranslateUi(self, WineASIOSettings): | def retranslateUi(self, WineASIOSettings): | ||||
| _tr = QCoreApplication.translate | _tr = QCoreApplication.translate | ||||
| WineASIOSettings.setWindowTitle(_tr(self.OBJECT_NAME, "WineASIO Settings")) | WineASIOSettings.setWindowTitle(_tr(self.OBJECT_NAME, "WineASIO Settings")) | ||||
| # Audio Ports | |||||
| self.group_ports.setTitle(_tr(self.OBJECT_NAME, "Audio Ports")) | self.group_ports.setTitle(_tr(self.OBJECT_NAME, "Audio Ports")) | ||||
| self.label_ports_in.setToolTip(_tr(self.OBJECT_NAME, "Number of jack ports that wineasio will try to open.\n" | |||||
| "Default is 16")) | |||||
| self.label_ports_in.setText(_tr(self.OBJECT_NAME, "Number of inputs:")) | self.label_ports_in.setText(_tr(self.OBJECT_NAME, "Number of inputs:")) | ||||
| self.label_ports_in.setToolTip(_tr(self.OBJECT_NAME, | |||||
| "Number of jack ports that wineasio will try to open.\n" | |||||
| "Default is 16")) | |||||
| self.sb_ports_in.setToolTip(_tr(self.OBJECT_NAME, | |||||
| "Number of jack ports that wineasio will try to open.\n" | |||||
| "Default is 16")) | |||||
| self.sb_ports_in.setToolTip(_tr(self.OBJECT_NAME, "Number of jack ports that wineasio will try to open.\n" | |||||
| "Default is 16")) | |||||
| self.label_ports_out.setToolTip(_tr(self.OBJECT_NAME, "Number of jack ports that wineasio will try to open.\n" | |||||
| "Default is 16")) | |||||
| self.label_ports_out.setText(_tr(self.OBJECT_NAME, "Number of outputs:")) | self.label_ports_out.setText(_tr(self.OBJECT_NAME, "Number of outputs:")) | ||||
| self.label_ports_out.setToolTip(_tr(self.OBJECT_NAME, | |||||
| "Number of jack ports that wineasio will try to open.\n" | |||||
| "Default is 16")) | |||||
| self.sb_ports_out.setToolTip(_tr(self.OBJECT_NAME, | |||||
| "Number of jack ports that wineasio will try to open.\n" | |||||
| "Default is 16")) | |||||
| self.sb_ports_out.setToolTip(_tr(self.OBJECT_NAME, "Number of jack ports that wineasio will try to open.\n" | |||||
| "Default is 16")) | |||||
| self.cb_ports_connect_hw.setToolTip(_tr(self.OBJECT_NAME, "Try to connect the asio channels to the\n" | |||||
| "physical I/O ports on your hardware.\n" | |||||
| "Default is on")) | |||||
| self.cb_ports_connect_hw.setText(_tr(self.OBJECT_NAME, "Connect to hardware")) | self.cb_ports_connect_hw.setText(_tr(self.OBJECT_NAME, "Connect to hardware")) | ||||
| self.cb_ports_connect_hw.setToolTip(_tr(self.OBJECT_NAME, | |||||
| "Try to connect the asio channels to the\n" | |||||
| "physical I/O ports on your hardware.\n" | |||||
| "Default is on")) | |||||
| # JACK Options | |||||
| self.group_jack.setTitle(_tr(self.OBJECT_NAME, "JACK Options")) | self.group_jack.setTitle(_tr(self.OBJECT_NAME, "JACK Options")) | ||||
| self.cb_jack_autostart.setToolTip(_tr(self.OBJECT_NAME, "Enable wineasio to launch the jack server.\n" | |||||
| "Default is off")) | |||||
| self.cb_jack_autostart.setText(_tr(self.OBJECT_NAME, "Autostart server")) | self.cb_jack_autostart.setText(_tr(self.OBJECT_NAME, "Autostart server")) | ||||
| self.cb_jack_autostart.setToolTip(_tr(self.OBJECT_NAME, | |||||
| "Enable wineasio to launch the jack server.\n" | |||||
| "Default is off")) | |||||
| self.cb_jack_fixed_bsize.setToolTip(_tr(self.OBJECT_NAME, "When on: ASIO applications will respect the current JACK buffer size\n" | |||||
| "When off: ASIO applications can change the JACK buffer size\n" | |||||
| "Default is on")) | |||||
| self.cb_jack_fixed_bsize.setText(_tr(self.OBJECT_NAME, "Fixed buffersize")) | self.cb_jack_fixed_bsize.setText(_tr(self.OBJECT_NAME, "Fixed buffersize")) | ||||
| self.cb_jack_fixed_bsize.setToolTip(_tr(self.OBJECT_NAME, | |||||
| "When on: ASIO applications will respect the current JACK buffer size\n" | |||||
| "When off: ASIO applications can change the JACK buffer size" | |||||
| "Default is on")) | |||||
| self.label_jack_buffer_size.setText(_tr(self.OBJECT_NAME, "Preferred buffersize:")) | self.label_jack_buffer_size.setText(_tr(self.OBJECT_NAME, "Preferred buffersize:")) | ||||
| # --------------------------------------------------------------------------------------------------------------------- | |||||