Browse Source

Change metronome to use good port names. New menu settings with option to autoconnect metronome on startup

master
Nils 2 years ago
parent
commit
6ac999b5f0
  1. 13
      engine/api.py
  2. 3
      engine/config.py
  3. 1
      engine/tempotrack.py
  4. 11
      qtgui/designer/mainwindow.py
  5. 21
      qtgui/designer/mainwindow.ui
  6. 25
      qtgui/mainwindow.py
  7. 2
      qtgui/menu.py
  8. 4
      template/engine/metronome.py
  9. 19
      template/engine/sequencer.py

13
engine/api.py

@ -2668,6 +2668,19 @@ def connectModMidiMerger():
pass
def connectMetronomeToSystemPorts():
try:
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,
l, r = session.data.metronome.getPortNames()
cbox.JackIO.port_connect(l, hardwareAudioPorts[0])
cbox.JackIO.port_connect(r, hardwareAudioPorts[1])
except:
pass
#Debug
def printPitches():

3
engine/config.py

@ -40,7 +40,8 @@ METADATA={
#How many audio outputs do you want? must be pairs. These are just unconnected jack outputs
#that need to be connected internally to instrument outputs like fluidsynth
"cboxOutputs" : 1 * 2, #metronome
#DEPRECATED SOON
"cboxOutputs" : 0,
#Does the program use a metronome? In this case you need at least two cboxOutputs above
"metronome" : True,

1
engine/tempotrack.py

@ -721,5 +721,4 @@ class TempoTrack(GraphTrackCC):
pairs = pairwise(onlyStandalone)
result = " ".join(_ly(tempoItem, nextTempoItem) for tempoItem, nextTempoItem in pairs)
#return "" here to not generate any metronome marks. Not even the default lilypond one.
return result

11
qtgui/designer/mainwindow.py

@ -76,6 +76,8 @@ class Ui_MainWindow(object):
self.menuMIDI.setObjectName("menuMIDI")
self.menuLilypond = QtWidgets.QMenu(self.menubar)
self.menuLilypond.setObjectName("menuLilypond")
self.menuSettings = QtWidgets.QMenu(self.menubar)
self.menuSettings.setObjectName("menuSettings")
MainWindow.setMenuBar(self.menubar)
self.leftToolBar = QtWidgets.QToolBar(MainWindow)
self.leftToolBar.setEnabled(True)
@ -672,6 +674,9 @@ class Ui_MainWindow(object):
self.actionMove_Block_to_end_of_track.setObjectName("actionMove_Block_to_end_of_track")
self.actionMove_Block_to_start_of_track = QtWidgets.QAction(MainWindow)
self.actionMove_Block_to_start_of_track.setObjectName("actionMove_Block_to_start_of_track")
self.actionAutoconnect_Metronome = QtWidgets.QAction(MainWindow)
self.actionAutoconnect_Metronome.setCheckable(True)
self.actionAutoconnect_Metronome.setObjectName("actionAutoconnect_Metronome")
self.menuObjects.addAction(self.actionMetrical_Instruction)
self.menuObjects.addAction(self.actionClef)
self.menuObjects.addAction(self.actionKey_Signature)
@ -859,6 +864,7 @@ class Ui_MainWindow(object):
self.menuLilypond.addAction(self.actionLyFree_Instruction)
self.menuLilypond.addAction(self.actionLyMarkAbove)
self.menuLilypond.addAction(self.actionLyMarkBelow)
self.menuSettings.addAction(self.actionAutoconnect_Metronome)
self.menubar.addAction(self.menuView.menuAction())
self.menubar.addAction(self.menuEdit_2.menuAction())
self.menubar.addAction(self.menu.menuAction())
@ -869,6 +875,7 @@ class Ui_MainWindow(object):
self.menubar.addAction(self.menuToolbox.menuAction())
self.menubar.addAction(self.menu_2.menuAction())
self.menubar.addAction(self.menuLilypond.menuAction())
self.menubar.addAction(self.menuSettings.menuAction())
self.menubar.addAction(self.menuHelp.menuAction())
self.menubar.addAction(self.menuGeneric.menuAction())
@ -891,6 +898,7 @@ class Ui_MainWindow(object):
self.menuInsert.setTitle(_translate("MainWindow", "&Note Generation"))
self.menuMIDI.setTitle(_translate("MainWindow", "&MIDI"))
self.menuLilypond.setTitle(_translate("MainWindow", "&Lilypond"))
self.menuSettings.setTitle(_translate("MainWindow", "Settings"))
self.actionDelete.setText(_translate("MainWindow", "&Delete Item"))
self.actionBackspace.setText(_translate("MainWindow", "Delete previous &Item"))
self.actionAddCursorNoteToChord.setText(_translate("MainWindow", "&Add Note to Chord"))
@ -1012,3 +1020,6 @@ class Ui_MainWindow(object):
self.actionMove_Block_to_end_of_track.setShortcut(_translate("MainWindow", "Alt+End"))
self.actionMove_Block_to_start_of_track.setText(_translate("MainWindow", "Move Block to start of track"))
self.actionMove_Block_to_start_of_track.setShortcut(_translate("MainWindow", "Alt+Home"))
self.actionAutoconnect_Metronome.setText(_translate("MainWindow", "Autoconnect Metronome"))
self.actionAutoconnect_Metronome.setIconText(_translate("MainWindow", "Wether to autoconnect the mixer ports on program start. Not for NSM."))
self.actionAutoconnect_Metronome.setToolTip(_translate("MainWindow", "Wether to autoconnect the mixer ports on program start. Not for NSM."))

21
qtgui/designer/mainwindow.ui

@ -328,6 +328,12 @@
<addaction name="actionLyMarkAbove"/>
<addaction name="actionLyMarkBelow"/>
</widget>
<widget class="QMenu" name="menuSettings">
<property name="title">
<string>Settings</string>
</property>
<addaction name="actionAutoconnect_Metronome"/>
</widget>
<addaction name="menuView"/>
<addaction name="menuEdit_2"/>
<addaction name="menu"/>
@ -338,6 +344,7 @@
<addaction name="menuToolbox"/>
<addaction name="menu_2"/>
<addaction name="menuLilypond"/>
<addaction name="menuSettings"/>
<addaction name="menuHelp"/>
<addaction name="menuGeneric"/>
</widget>
@ -1781,6 +1788,20 @@
<string>Alt+Home</string>
</property>
</action>
<action name="actionAutoconnect_Metronome">
<property name="checkable">
<bool>true</bool>
</property>
<property name="text">
<string>Autoconnect Metronome</string>
</property>
<property name="iconText">
<string>Wether to autoconnect the mixer ports on program start. Not for NSM.</string>
</property>
<property name="toolTip">
<string>Wether to autoconnect the mixer ports on program start. Not for NSM.</string>
</property>
</action>
</widget>
<resources/>
<connections/>

25
qtgui/mainwindow.py

@ -42,6 +42,7 @@ from .menu import MenuActionDatabase
from .scoreview import ScoreView
from .trackEditor import TrackEditor
from .resources import *
from engine.config import METADATA
class MainWindow(TemplateMainWindow):
@ -116,6 +117,20 @@ class MainWindow(TemplateMainWindow):
self.start() #Inherited from template main window #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.
stepMidiInput.start() #imported directly. Handles everything else internally, we just need to start it after the engine somehow. Which is here.
#Check if to connect the metronome on startup. But only when not running under NSM
if api.isStandaloneMode():
self.ui.actionAutoconnect_Metronome.setEnabled(True)
settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"])
if settings.contains("autoconnectMetronome"):
autoconnectMixer = settings.value("autoconnectMetronome", type=bool)
else:
autoconnectMixer = False
self.ui.actionAutoconnect_Metronome.setChecked(autoconnectMixer)
self.reactToAutoconnectMixerCheckbox(autoconnectMixer) #do the connection
else:
self.ui.actionAutoconnect_Metronome.setEnabled(False)
#Populate the left toolbar. The upper toolbar is created in menu.py
self.ui.leftToolBar.addWidget(LeftToolBarPrevailingDuration(self)) #needs stepmidiinput started
@ -128,7 +143,7 @@ class MainWindow(TemplateMainWindow):
#Here is the crowbar-method.
self.nsmClient.announceSaveStatus(isClean = True)
api.connectModMidiMerger()
def zoom(self, scaleFactor:float):
@ -179,6 +194,14 @@ class MainWindow(TemplateMainWindow):
self.scoreView.updateMode()
self.trackEditor.setEnabled(False)
def reactToAutoconnectMixerCheckbox(self, state:bool):
"""Triggered by the user and programatically during startup in __init__"""
assert api.isStandaloneMode()
settings = QtCore.QSettings("LaborejoSoftwareSuite", METADATA["shortName"])
settings.setValue("autoconnectMetronome", state)
if state:
api.connectMetronomeToSystemPorts()
class LeftToolBarPrevailingDuration(QtWidgets.QLabel):
def __init__(self, mainWindow):
super().__init__(self.makeText(api.D4))

2
qtgui/menu.py

@ -210,6 +210,8 @@ class MenuActionDatabase(object):
self.mainWindow.ui.actionPlayFromEditCursor : api.playFromCursor,
self.mainWindow.ui.actionPlay_from_Block : api.playFromBlockStart,
self.mainWindow.ui.actionMetronome_Enabled : api.toggleMetronome, #toggle is enough. The callback makes sure all the checkboxes have the correct value.
self.mainWindow.ui.actionAutoconnect_Metronome : self.mainWindow.reactToAutoconnectMixerCheckbox,
}
self.noteEditActions = { #these are only available in Note Edit Mode, not in CC Edit Mode etc. #all xxxEditActions are mutually exclusive.

4
template/engine/metronome.py

@ -73,6 +73,10 @@ class Metronome(object):
self.label = "" #E.g. current Track Name, but can be anything.
self.setEnabled(False) #TODO: save load
def getPortNames(self)->(str,str):
"""Return two client:port , for left and right channel"""
return (self.sfzInstrumentSequencerInterface.portnameL, self.sfzInstrumentSequencerInterface.portnameR)
def soundStresses(self, value:bool):
self._soundStresses = value
self.generate(self._cachedData, self.label)

19
template/engine/sequencer.py

@ -503,10 +503,21 @@ class SfzInstrumentSequencerInterface(_Interface):
self.calfboxTrack.set_external_output("")
#Metadata
portnameL = f"{cbox.JackIO.status().client_name}:out_1"
portnameR = f"{cbox.JackIO.status().client_name}:out_2"
cbox.JackIO.Metadata.set_pretty_name(portnameL, name.title() + "-L")
cbox.JackIO.Metadata.set_pretty_name(portnameR, name.title() + "-R")
l = f"{cbox.JackIO.status().client_name}:out_1"
r = f"{cbox.JackIO.status().client_name}:out_2"
self.portnameL = cbox.JackIO.status().client_name + ":" + name.title() + "-L"
self.portnameR = cbox.JackIO.status().client_name + ":" + name.title() + "-R"
luuid = cbox.JackIO.create_audio_output(name.title() + "-L")
ruuid = cbox.JackIO.create_audio_output(name.title() + "-R")
cbox.JackIO.Metadata.set_pretty_name(self.portnameL, name.title() + "-L")
cbox.JackIO.Metadata.set_pretty_name(self.portnameR, name.title() + "-R")
self.outputMergerRouter = cbox.JackIO.create_audio_output_router(luuid, ruuid)
self.outputMergerRouter.set_gain(-1.0)
self.instrumentLayer.get_output_slot(0).rec_wet.attach(self.outputMergerRouter) #output_slot is 0 based and means a pair.
def enable(self, enabled):
if enabled:

Loading…
Cancel
Save