File: laborejo-qt

package info (click to toggle)
laborejo 0.8~ds0-2
  • links: PTS
  • area: main
  • in suites: buster, stretch
  • size: 13,260 kB
  • ctags: 2,211
  • sloc: python: 20,735; sh: 169; makefile: 5
file content (144 lines) | stat: -rwxr-xr-x 8,589 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#! /usr/bin/env python3
# -*- coding: utf-8 -*-
from time import sleep
from signal import SIGKILL
from os import getpid, kill
if __name__ == "__main__":
    import argparse, os
    parser = argparse.ArgumentParser(description="Laborejo Qt")
    parser.add_argument('infiles', help="One or more lbjs or lbj files to load.", nargs="*")
    parser.add_argument("-n", "--new", help="Start with an empty file (additionally to loaded files)", action="store_true")
    parser.add_argument("-c", "--config", help="The configuration dir for user scripts, templates and configs etc. Default=~/.laborejo/", type=str)
    parser.add_argument("-g", "--geometry", help="Start with a window geometry 'width x height' or 'width x height + leftCorner + rightCorner'. Example A: 1024x768 Example B: 1920x1080+0+0", type=str, default=None)
    parser.add_argument("-m", "--mute", help ="Don't start the audio/midi engine. You need this for playback but it can be turned off if you don't want JACK or for performance reasons", action="store_true")
    parser.add_argument("-j", "--jack", help ="Start with active JACK Mode instead of internal sampler mode. Can be toggled at any time in the program again.", action="store_true")
    parser.add_argument("-i", "--midiin", help="Jack Midi input port for note insert. No ALSA. Example: jack-keyboad:midi_out . Default: as sepcified in config file.", type=str, default=None)
    parser.add_argument("-l", "--lonely", help ="Don't connect any jack ports, not even a given jack midi port --midiin. Use this if you restore your jack connections with an external tool. This is not needed for Non-Session-Manager support.", action="store_true")
    parser.add_argument("-s", "--soundfont", help="A path to an alternative .sf2 soundfont to be used by the internal midi sampler. Example /usr/share/soundfonts/fluidr3/FluidR3GM.SF2", type=str, default=None)


    args = parser.parse_args()

    #initialize the GUI. We do this after parse init
    #because if it were just --help we don't need to start the whole Qt chain.
    import laborejoqt
    from laborejoqt import laborejoqtnsmclient as nsmclient #laborejoqtnsmclient.py is a local file.

    """
    If Laborejo was started through the non-session manager this means
    nsmclient.states.nsmUrl is True.
    We use this information to change some functions in the program.

    Many parser arguments will be ignored. We automatically assume
    NSM means Jack is working as well.
    """

    if args.config:
        p = os.path.realpath(args.config) + "/"
        print ("Starting Laborejo-Qt with config directory", p)
        laborejoqt.api._getSession().configdir = p

    laborejoqt.config.JACKMODE = bool(nsmclient.states.nsmUrl) or args.jack

    laborejoqt.main = laborejoqt.StartQT4(geometry = args.geometry, nonSessionManager = nsmclient.states.nsmUrl)

    if (laborejoqt.config.JACK and not args.mute) or nsmclient.states.nsmUrl:
        midiInTimer = laborejoqt.QtCore.QTimer()
        midiInTimer.start(laborejoqt.config.MIDI_TIMER) #50ms default

    if nsmclient.states.nsmUrl:
        #Initialize the session handler:
        ##after we have the functions from laborejoqt.main
        ##but before init calfbox since we need the unique session id to load/save files and create jack ports
        capabilities = {
            "switch" : False,       #client is capable of responding to multiple `open` messages without restarting
            "dirty" : True,        #client knows when it has unsaved changes
            "progress" : False,     #client can send progress updates during time-consuming operations
            "message" : False,      #client can send textual status updates
            "optional-gui" : True, #client has an optional GUI
            }
        requiredFunctions = {
            "function_open" : laborejoqt.main.nsmLoad, #Accept two parameters. Return two values. A bool and a status string. Otherwise you'll get a message that does not help at all: "Exception TypeError: "'NoneType' object is not iterable" in 'liblo._callback' ignored"
            "function_save" : laborejoqt.main.nsmSave, #Accept one parameter. Return two values. A bool and a status string. Otherwise you'll get a message that does not help at all: "Exception TypeError: "'NoneType' object is not iterable" in 'liblo._callback' ignored"
            }


        def quitty():
            try:
                laborejoqt.api.calfboxShutdown()
            except:
                pass
            try:
                midiInTimer.stop()
            except:
                pass
            kill(getpid(), SIGKILL) #Killing Blow, if those above fail.


        optionalFunctions = {
            "function_quit" : quitty,  #Accept zero parameters. Return True or False
            "function_showGui" : laborejoqt.main.show, #Accept zero parameters. Return True or False
            "function_hideGui" : laborejoqt.main.hide, #Accept zero parameters. Return True or False
            }
        laborejoqt.main.session.ourNsmClient, nsmReturnedTimerFunction = nsmclient.init(
            prettyName = "LaborejoQt",
            capabilities = capabilities,
            requiredFunctions = requiredFunctions,
            optionalFunctions = optionalFunctions,
            sleepValueMs = 0) #no additional sleeps. The qt timer takes care of that

        #Now start the timer. Hopefully that gives us nsmClientId from nsmLoad() before we init cbox
        laborejoqt.QtCore.QObject.connect(midiInTimer, laborejoqt.QtCore.SIGNAL("timeout()"), nsmReturnedTimerFunction)

    if nsmclient.states.nsmUrl:
        #The qt timer starts only when we call laborejoqt.app.exec_(), which starts the event loop.
        #We need the nsmLoad() function for nsmClientId. Call the osc query manually until we get something.
        while not laborejoqt.main.session.nsmClientId:
            nsmReturnedTimerFunction()
            sleep(0.3)
        laborejoqt.api.calfboxInit(None, autoconnect = False, clientName = laborejoqt.main.session.nsmClientId) #If soundfont is none it falls back to a small default GM provided within the Laborejo source tree
    elif laborejoqt.config.JACK and not args.mute:
        midiInPort = args.midiin if args.midiin else laborejoqt.config.midiinport
        laborejoqt.api.calfboxInit(
            args.soundfont, #If soundfont is none it falls back to a small default GM provided within the Laborejo source tree
            autoconnect=not args.lonely,
            midiInPort = midiInPort)

    if laborejoqt.api.cboxSmfCompatibleModule: #started succesfully?
        laborejoqt.main.session.playbackEngine = True
        laborejoqt.QtCore.QObject.connect(midiInTimer, laborejoqt.QtCore.SIGNAL("timeout()"), laborejoqt.api.calfboxProcessor)
        laborejoqt.main.createMidiShortcuts()
        laborejoqt.api.calfboxSetTransportKeepRolling(laborejoqt.config.TRANSPORT_KEEP_ROLLING) #live update.
    else:
        laborejoqt.main.session.playbackEngine = False
        if nsmclient.states.nsmUrl:
            raise RuntimeError("You tried to run Laborejo-Qt in NSM mode but the playback engine could not be started. You need JACK started and calfbox/calfbox python module installed for session management")

    laborejoqt.listener.main = laborejoqt.main #We need this before initializing the listeners below. This is also the reason why we can't move this code into the listener module.
    laborejoqt.listener.init() #Connect the listeners with the backend.

    #load command line files. A new empty file can also be opened, does not conflict with loading files.
    if args.infiles and not nsmclient.states.nsmUrl:
        lbjsScoreFiles = [x for x in args.infiles if x.endswith(".lbjs")]
        lbjCollectionFiles = [x for x in args.infiles if x.endswith(".lbj")]
        if lbjsScoreFiles:
            laborejoqt.main.load(lbjsScoreFiles)
        if lbjCollectionFiles:
            laborejoqt.main.loadCollection(lbjCollectionFiles)

    if args.new and not nsmclient.states.nsmUrl:
        laborejoqt.api.new()
    #else it is just an empty program start

    if not nsmclient.states.nsmUrl:
        from atexit import register
        register(laborejoqt.api.calfboxShutdown) #On Exit shut down the jack client properly. Even if started with -m this will not fail. There is a "try" inside.
    #else:
        #NSM has its own exit signal. We will use that instead.

    laborejoqt.api.jackMidiInToggleMute(boolean = False)

    if nsmclient.states.nsmUrl:
        laborejoqt.QtCore.QTimer.singleShot(0, laborejoqt.main.nsmActuallyLoadFirstFiles)

    laborejoqt.app.exec_()