From 6e7f0c577441d7fca7d722d238338b388241c6c7 Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 4 Oct 2012 07:45:31 +0100 Subject: [PATCH] Cadence: Implement Alsa-Audio support (complete), misc fixes --- Makefile | 6 +- src/cadence.py | 114 ++++++++++++++++++++++++++++++++--- src/cadence_aloop_daemon.py | 4 ++ src/cadence_session_start.py | 9 +++ src/shared_cadence.py | 7 +++ 5 files changed, 131 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 5a368fa..2958a45 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,8 @@ all: UI RES CPP UI: cadence catarina catia claudia carla tools cadence: src/ui_cadence.py \ - src/ui_cadence_tb_jack.py src/ui_cadence_tb_a2j.py src/ui_cadence_tb_pa.py src/ui_cadence_rwait.py + src/ui_cadence_tb_jack.py src/ui_cadence_tb_alsa.py src/ui_cadence_tb_a2j.py src/ui_cadence_tb_pa.py \ + src/ui_cadence_rwait.py catarina: src/ui_catarina.py \ src/ui_catarina_addgroup.py src/ui_catarina_removegroup.py src/ui_catarina_renamegroup.py \ @@ -55,6 +56,9 @@ src/ui_cadence.py: src/ui/cadence.ui src/ui_cadence_tb_jack.py: src/ui/cadence_tb_jack.ui $(PYUIC) $< -o $@ +src/ui_cadence_tb_alsa.py: src/ui/cadence_tb_alsa.ui + $(PYUIC) $< -o $@ + src/ui_cadence_tb_a2j.py: src/ui/cadence_tb_a2j.ui $(PYUIC) $< -o $@ diff --git a/src/cadence.py b/src/cadence.py index 41397a0..84ea4fb 100755 --- a/src/cadence.py +++ b/src/cadence.py @@ -24,7 +24,7 @@ from subprocess import getoutput # Imports (Custom Stuff) import ui_cadence -import ui_cadence_tb_jack, ui_cadence_tb_a2j, ui_cadence_tb_pa, ui_cadence_rwait +import ui_cadence_tb_jack, ui_cadence_tb_alsa, ui_cadence_tb_a2j, ui_cadence_tb_pa, ui_cadence_rwait import systray from shared_cadence import * from shared_jack import * @@ -91,12 +91,6 @@ global jackClientIdALSA, jackClientIdPulse jackClientIdALSA = -1 jackClientIdPulse = -1 -iAlsaFileNone = 0 -iAlsaFileLoop = 1 -iAlsaFileJACK = 2 -iAlsaFilePulse = 3 -iAlsaFileMax = 4 - # jackdbus indexes iGraphVersion = 0 iJackClientId = 1 @@ -528,7 +522,16 @@ class ForceRestartThread(QThread): # If we made it this far, then JACK is started self.m_wasStarted = True - # Start A2J and Pulse according to user settings + # Start bridges according to user settings + + # ALSA-Audio + if GlobalSettings.value("ALSA-Audio/BridgeIndexType", iAlsaFileNone, type=int) == iAlsaFileLoop: + os.system("cadence-aloop-daemon &") + sleep(0.5) + + self.emit(SIGNAL("progressChanged(int)"), 94) + + # ALSA-MIDI if GlobalSettings.value("A2J/AutoStart", True, type=bool) and DBus.a2j and not bool(DBus.a2j.is_started()): a2jExportHW = GlobalSettings.value("A2J/ExportHW", True, type=bool) DBus.a2j.set_hw_export(a2jExportHW) @@ -536,6 +539,7 @@ class ForceRestartThread(QThread): self.emit(SIGNAL("progressChanged(int)"), 96) + # PulseAudio if GlobalSettings.value("Pulse2JACK/AutoStart", True, type=bool) and not isPulseAudioBridged(): if GlobalSettings.value("Pulse2JACK/PlaybackModeOnly", False, type=bool): os.system("cadence-pulse2jack -p") @@ -569,6 +573,10 @@ class ForceWaitDialog(QDialog, ui_cadence_rwait.Ui_Dialog): else: QMessageBox.critical(self, self.tr("Error"), self.tr("Could not start JACK!")) + def done(self, r): + QDialog.done(self, r) + self.close() + # Additional JACK options class ToolBarJackDialog(QDialog, ui_cadence_tb_jack.Ui_Dialog): def __init__(self, parent): @@ -621,6 +629,27 @@ class ToolBarJackDialog(QDialog, ui_cadence_tb_jack.Ui_Dialog): GlobalSettings.setValue("JACK/AutoLoadLadishStudio", self.rb_ladish.isChecked()) GlobalSettings.setValue("JACK/LadishStudioName", self.cb_studio_name.currentText()) + def done(self, r): + QDialog.done(self, r) + self.close() + +# Additional ALSA Audio options +class ToolBarAlsaAudioDialog(QDialog, ui_cadence_tb_alsa.Ui_Dialog): + def __init__(self, parent): + QDialog.__init__(self, parent) + self.setupUi(self) + + asoundrcFile = os.path.join(HOME, ".asoundrc") + asoundrcFd = open(asoundrcFile, "r") + asoundrcRead = asoundrcFd.read().strip() + asoundrcFd.close() + + self.textBrowser.setPlainText(asoundrcRead) + + def done(self, r): + QDialog.done(self, r) + self.close() + # Additional ALSA MIDI options class ToolBarA2JDialog(QDialog, ui_cadence_tb_a2j.Ui_Dialog): def __init__(self, parent): @@ -635,6 +664,10 @@ class ToolBarA2JDialog(QDialog, ui_cadence_tb_a2j.Ui_Dialog): def slot_setOptions(self): GlobalSettings.setValue("A2J/ExportHW", self.cb_export_hw.isChecked()) + def done(self, r): + QDialog.done(self, r) + self.close() + # Additional PulseAudio options class ToolBarPADialog(QDialog, ui_cadence_tb_pa.Ui_Dialog): def __init__(self, parent): @@ -649,6 +682,10 @@ class ToolBarPADialog(QDialog, ui_cadence_tb_pa.Ui_Dialog): def slot_setOptions(self): GlobalSettings.setValue("Pulse2JACK/PlaybackModeOnly", self.cb_playback_only.isChecked()) + def done(self, r): + QDialog.done(self, r) + self.close() + # Main Window class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): def __init__(self, parent=None): @@ -663,6 +700,8 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): self.pix_error = QIcon(getIcon("dialog-error", 16)).pixmap(16, 16) self.pix_warning = QIcon(getIcon("dialog-warning", 16)).pixmap(16, 16) + self.m_lastAlsaIndexType = -2 # invalid + # ------------------------------------------------------------- # Set-up icons @@ -967,6 +1006,8 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): self.connect(self.b_alsa_start, SIGNAL("clicked()"), SLOT("slot_AlsaBridgeStart()")) self.connect(self.b_alsa_stop, SIGNAL("clicked()"), SLOT("slot_AlsaBridgeStop()")) + self.connect(self.cb_alsa_type, SIGNAL("currentIndexChanged(int)"), SLOT("slot_AlsaBridgeChanged(int)")) + self.connect(self.tb_alsa_options, SIGNAL("clicked()"), SLOT("slot_AlsaAudioBridgeOptions()")) self.connect(self.b_a2j_start, SIGNAL("clicked()"), SLOT("slot_A2JBridgeStart()")) self.connect(self.b_a2j_stop, SIGNAL("clicked()"), SLOT("slot_A2JBridgeStop()")) @@ -1239,6 +1280,7 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): self.cb_alsa_type.setCurrentIndex(iAlsaFileNone) self.tb_alsa_options.setEnabled(False) self.label_bridge_alsa.setText(self.tr("No bridge in use")) + self.m_lastAlsaIndexType = -1 # null return asoundrcFd = open(asoundrcFile, "r") @@ -1291,6 +1333,8 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): self.tb_alsa_options.setEnabled(True) self.label_bridge_alsa.setText(self.tr("Using custom asoundrc, not managed by Cadence")) + self.m_lastAlsaIndexType = self.cb_alsa_type.currentIndex() + def checkPulseAudio(self): if isPulseAudioStarted(): if isPulseAudioBridged(): @@ -1448,6 +1492,59 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): if os.path.exists(checkFile): os.remove(checkFile) + @pyqtSlot(int) + def slot_AlsaBridgeChanged(self, index): + if self.m_lastAlsaIndexType == -2 or self.m_lastAlsaIndexType == index: + return + + if self.m_lastAlsaIndexType == iAlsaFileMax: + ask = CustomMessageBox(self, QMessageBox.Warning, self.tr("Warning"), + self.tr("" + "You're using a custom ~/.asoundrc file not managed by Cadence.
" + "By choosing to use a Cadence ALSA-Audio bridge, the file will be replaced." + ""), + self.tr("Are you sure you want to do this?")) + + if ask == QMessageBox.Yes: + self.cb_alsa_type.blockSignals(True) + self.cb_alsa_type.removeItem(iAlsaFileMax) + self.cb_alsa_type.setCurrentIndex(index) + self.cb_alsa_type.blockSignals(False) + else: + self.cb_alsa_type.blockSignals(True) + self.cb_alsa_type.setCurrentIndex(iAlsaFileMax) + self.cb_alsa_type.blockSignals(False) + return + + asoundrcFile = os.path.join(HOME, ".asoundrc") + + if index == iAlsaFileNone: + os.remove(asoundrcFile) + + elif index == iAlsaFileLoop: + asoundrcFd = open(asoundrcFile, "w") + asoundrcFd.write(asoundrc_aloop+"\n") + asoundrcFd.close() + + elif index == iAlsaFileJACK: + asoundrcFd = open(asoundrcFile, "w") + asoundrcFd.write(asoundrc_jack+"\n") + asoundrcFd.close() + + elif index == iAlsaFilePulse: + asoundrcFd = open(asoundrcFile, "w") + asoundrcFd.write(asoundrc_pulse+"\n") + asoundrcFd.close() + + else: + print("Cadence::AlsaBridgeChanged(%i) - invalid index" % index) + + self.checkAlsaAudio() + + @pyqtSlot() + def slot_AlsaAudioBridgeOptions(self): + ToolBarAlsaAudioDialog(self).exec_() + @pyqtSlot() def slot_A2JBridgeStart(self): DBus.a2j.start() @@ -1934,6 +2031,7 @@ class CadenceMainW(QMainWindow, ui_cadence.Ui_CadenceMainW): self.settings.setValue("Geometry", self.saveGeometry()) GlobalSettings.setValue("JACK/AutoStart", self.cb_jack_autostart.isChecked()) + GlobalSettings.setValue("ALSA-Audio/BridgeIndexType", self.cb_alsa_type.currentIndex()) GlobalSettings.setValue("A2J-MIDI/AutoStart", self.cb_a2j_autostart.isChecked()) GlobalSettings.setValue("Pulse2JACK/AutoStart", (havePulseAudio and self.cb_pulse_autostart.isChecked())) diff --git a/src/cadence_aloop_daemon.py b/src/cadence_aloop_daemon.py index 19005e5..50b44a8 100755 --- a/src/cadence_aloop_daemon.py +++ b/src/cadence_aloop_daemon.py @@ -58,8 +58,10 @@ def run_alsa_bridge(): if procIn.state() != QProcess.NotRunning: procIn.terminate() + procIn.waitForFinished(1000) if procOut.state() != QProcess.NotRunning: procOut.terminate() + procOut.waitForFinished(1000) procIn.start("env", ["JACK_SAMPLE_RATE=%i" % sampleRate, "JACK_PERIOD_SIZE=%i" % bufferSize, "alsa_in", "-j", "alsa2jack", "-d", "cloop", "-q", "1"]) procOut.start("env", ["JACK_SAMPLE_RATE=%i" % sampleRate, "JACK_PERIOD_SIZE=%i" % bufferSize, "alsa_out", "-j", "jack2alsa", "-d", "ploop", "-q", "1"]) @@ -115,5 +117,7 @@ if __name__ == '__main__': if procIn.state() != QProcess.NotRunning: procIn.terminate() + procIn.waitForFinished(1000) if procOut.state() != QProcess.NotRunning: procOut.terminate() + procOut.waitForFinished(1000) diff --git a/src/cadence_session_start.py b/src/cadence_session_start.py index b1ad587..0661db5 100755 --- a/src/cadence_session_start.py +++ b/src/cadence_session_start.py @@ -82,11 +82,20 @@ def startSession(): print("JACK Failed to Start") return False + # Start bridges according to user settings + + # ALSA-Audio + if GlobalSettings.value("ALSA-Audio/BridgeIndexType", iAlsaFileNone, type=int) == iAlsaFileLoop: + os.system("cadence-aloop-daemon &") + sleep(0.5) + + # ALSA-MIDI if GlobalSettings.value("A2J/AutoStart", True, type=bool) and DBus.a2j and not bool(DBus.a2j.is_started()): a2jExportHW = GlobalSettings.value("A2J/ExportHW", True, type=bool) DBus.a2j.set_hw_export(a2jExportHW) DBus.a2j.start() + # PulseAudio if GlobalSettings.value("Pulse2JACK/AutoStart", True, type=bool): if GlobalSettings.value("Pulse2JACK/PlaybackModeOnly", False, type=bool): os.system("cadence-pulse2jack -p") diff --git a/src/shared_cadence.py b/src/shared_cadence.py index fe6eae9..ea80b66 100644 --- a/src/shared_cadence.py +++ b/src/shared_cadence.py @@ -34,6 +34,13 @@ DEFAULT_VST_PATH = [ os.path.join("/", "usr", "local", "lib", "vst") ] +# ALSA file-type indexes +iAlsaFileNone = 0 +iAlsaFileLoop = 1 +iAlsaFileJACK = 2 +iAlsaFilePulse = 3 +iAlsaFileMax = 4 + # Global Settings GlobalSettings = QSettings("Cadence", "GlobalSettings")