Browse Source

replace mixer autoconnect in standalone mode with setting in menu to do so

master
Nils 6 months ago
parent
commit
75f9b1245b
  1. 6
      engine/api.py
  2. 8
      engine/auditioner.py
  3. 27
      engine/main.py
  4. 30
      qtgui/mainwindow.py

6
engine/api.py

@ -169,6 +169,10 @@ def startEngine(nsmClient, additionalData):
callbacks._auditionerVolumeChanged()
#Maybe autoconnect the mixer and auditioner.
if session.standaloneMode and additionalData["autoconnectMixer"]: #this is only for startup.
connectMixerToSystemPorts()
atexit.register(unloadAllInstrumentSamples) #this will handle all python exceptions, but not segfaults of C modules.
logger.info("Tembro api startEngine complete")
@ -176,6 +180,8 @@ def startEngine(nsmClient, additionalData):
def _instr(idKey:tuple)->Instrument:
return session.data.libraries[idKey[0]].instruments[idKey[1]]
def connectMixerToSystemPorts():
session.data.connectMixerToSystemPorts()
def rescanSampleDirectory(newBaseSamplePath):
"""If the user wants to change the sample dir during runtime we use this function

8
engine/auditioner.py

@ -61,12 +61,8 @@ class Auditioner(object):
#Create Stereo Audio Ouput Ports
#Connect to our own pair but also to a generic mixer port that is in Data()
if self.parentData.parentSession.standaloneMode:
jackAudioOutLeft = cbox.JackIO.create_audio_output(self.midiInputPortName+"_L", "#1") #add "#1" as second parameter for auto-connection to system out 1
jackAudioOutRight = cbox.JackIO.create_audio_output(self.midiInputPortName+"_R", "#2") #add "#1" as second parameter for auto-connection to system out 2
else:
jackAudioOutLeft = cbox.JackIO.create_audio_output(self.midiInputPortName+"_L")
jackAudioOutRight = cbox.JackIO.create_audio_output(self.midiInputPortName+"_R")
jackAudioOutLeft = cbox.JackIO.create_audio_output(self.midiInputPortName+"_L")
jackAudioOutRight = cbox.JackIO.create_audio_output(self.midiInputPortName+"_R")
self.outputMergerRouter = cbox.JackIO.create_audio_output_router(jackAudioOutLeft, jackAudioOutRight)
self.outputMergerRouter.set_gain(-3.0)

27
engine/main.py

@ -184,22 +184,33 @@ class Data(TemplateData):
def _createGlobalPorts(self):
"""Create two mixer ports, for stereo. Each instrument will not only create their own jack
out ports but also connect to these left/right.
If we are not in an NSM Session auto-connect them to the system ports for convenience.
Also create an additional stereo port pair to pre-listen to on sample instrument alone,
the Auditioner.
"""
assert not self.parentSession.standaloneMode is None
if self.parentSession.standaloneMode:
self.lmixUuid = cbox.JackIO.create_audio_output('left_mix', "#1") #add "#1" as second parameter for auto-connection to system out 1
self.rmixUuid = cbox.JackIO.create_audio_output('right_mix', "#2") #add "#2" as second parameter for auto-connection to system out 2
else:
self.lmixUuid = cbox.JackIO.create_audio_output('left_mix')
self.rmixUuid = cbox.JackIO.create_audio_output('right_mix')
self.lmixUuid = cbox.JackIO.create_audio_output('left_mix')
self.rmixUuid = cbox.JackIO.create_audio_output('right_mix')
self.auditioner = Auditioner(self)
def connectMixerToSystemPorts(self):
"""Also the auditioner."""
hardwareAudioPorts = cbox.JackIO.get_ports("system*", cbox.JackIO.AUDIO_TYPE, cbox.JackIO.PORT_IS_SINK | cbox.JackIO.PORT_IS_PHYSICAL) #don't sort. This is correctly sorted. Another sorted will do 1, 10, 11,
clientName = cbox.JackIO.status().client_name
mix_l = f"{clientName}:left_mix"
mix_r = f"{clientName}:right_mix"
aud_l = f"{clientName}:{self.auditioner.midiInputPortName}_L"
aud_r = f"{clientName}:{self.auditioner.midiInputPortName}_R"
cbox.JackIO.port_connect(mix_l, hardwareAudioPorts[0])
cbox.JackIO.port_connect(mix_r, hardwareAudioPorts[1])
cbox.JackIO.port_connect(aud_l, hardwareAudioPorts[0])
cbox.JackIO.port_connect(aud_r, hardwareAudioPorts[1])
def exportMetadata(self)->dict:
"""Data we sent in callbacks. This is the 'build-the-instrument-database' function.
Each first level dict contains another dict with instruments, but also a special key

30
qtgui/mainwindow.py

@ -161,6 +161,11 @@ class MainWindow(TemplateMainWindow):
if settings.contains("showOnlyLoadedInstruments"):
self.ui.actionShowOnlyLoadedInstruments.setChecked(settings.value("showOnlyLoadedInstruments", type=bool))
autoconnectMixer = False
if api.isStandaloneMode() and settings.contains("autoconnectMixer"):
autoconnectMixer = settings.value("autoconnectMixer", type=bool)
additionalData["autoconnectMixer"] = autoconnectMixer
self.start(additionalData) #This shows the GUI, or not, depends on the NSM gui save setting. We need to call that after the menu, otherwise the about dialog will block and then we get new menu entries, which looks strange.
api.callbacks.rescanSampleDir.append(self.react_rescanSampleDir) #This only happens on actual, manually instructed rescanning through the api. We instruct this through our Rescan-Dialog.
@ -195,7 +200,23 @@ class MainWindow(TemplateMainWindow):
self.menu.addMenuEntry("menuView", "actionPianoRollVisible", QtCore.QCoreApplication.translate("Menu", "Piano Roll"), self.pianoRollToggleVisibleAndRemember, shortcut="Ctrl+R", checkable=True, startChecked=True) #function receives check state as automatic parameter
self.menu.addMenuEntry("menuView", "actionPianoVisible", QtCore.QCoreApplication.translate("Menu", "Piano"), self.pianoToggleVisibleAndRemember, shortcut="Ctrl+P", checkable=True, startChecked=True) #function receives check state as automatic parameter
self.menu.orderSubmenus(["menuFile", "menuEdit", "menuView", "menuHelp"])
if api.isStandaloneMode():
settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"])
autoconnectMixer = settings.value("autoconnectMixer", type=bool) if settings.contains("autoconnectMixer") else False
self.menu.addSubmenu("menuSettings", QtCore.QCoreApplication.translate("mainWindow", "Settings"))
self.menu.addMenuEntry(
submenu = "menuSettings",
actionAsString = "actionAutoconnectMixer",
text = QtCore.QCoreApplication.translate("Menu", "Autoconnect Mixer and Auditioner ports"),
connectedFunction = self.react_autoconnectMixerCheckbox,
tooltip = QtCore.QCoreApplication.translate("Menu", "Wether to autoconnect the mixer and auditioner ports on program start. Not for NSM."),
checkable=True,
startChecked=autoconnectMixer,
)
self.menu.orderSubmenus(["menuFile", "menuEdit", "menuView", "menuSettings", "menuHelp"])
else:
self.menu.orderSubmenus(["menuFile", "menuEdit", "menuView", "menuHelp"])
def react_rescanSampleDir(self):
"""instructs the GUI to forget all cached data and start fresh.
@ -205,6 +226,13 @@ class MainWindow(TemplateMainWindow):
The program start happens without that and just sends data into a prepared but empty GUI."""
self.instrumentTreeController.reset()
def react_autoconnectMixerCheckbox(self, state:bool):
assert api.isStandaloneMode()
settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"])
settings.setValue("autoconnectMixer", state)
if state:
api.connectMixerToSystemPorts()
def toggleShowOnlyLoadedInstrumentsAndRemember(self, state:bool):
"""
This function can only be called after the instrument tree has been build.

Loading…
Cancel
Save