/usr/lib/python2.7/dist-packages/mididings/engine.py is in python-mididings 0~20120419~ds0-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 | # -*- coding: utf-8 -*-
#
# mididings
#
# Copyright (C) 2008-2012 Dominic Sacré <dominic.sacre@gmx.de>
#
# 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
# (at your option) any later version.
#
import _mididings
import mididings.patch as _patch
import mididings.scene as _scene
import mididings.util as _util
import mididings.misc as _misc
import mididings.setup as _setup
import mididings.constants as _constants
import mididings.overload as _overload
import mididings.arguments as _arguments
from mididings.units.base import _UNIT_TYPES
import time as _time
import weakref as _weakref
import threading as _threading
import gc as _gc
import atexit as _atexit
import os as _os
import sys as _sys
if _sys.version_info >= (3,):
raw_input = input
_TheEngine = None
class Engine(_mididings.Engine):
def __init__(self):
# initialize C++ base class
engine_args = (
_setup.get_config('backend'),
_setup.get_config('client_name'),
_setup._in_portnames,
_setup._out_portnames,
not _setup.get_config('silent')
)
_mididings.Engine.__init__(self, *engine_args)
self.connect_ports(_setup._in_port_connections, _setup._out_port_connections)
self._scenes = {}
def setup(self, scenes, control, pre, post):
# build and setup all scenes and scene groups
for number, scene in scenes.items():
if isinstance(scene, _scene.SceneGroup):
self._scenes[number] = (scene.name, [])
for subscene in scene.subscenes:
sceneobj = _scene._parse_scene(subscene)
self._scenes[number][1].append(sceneobj.name)
# build patches
patch = _patch.Patch(sceneobj.patch)
init_patch = _patch.Patch(sceneobj.init_patch)
# add scene to base class object
self.add_scene(_util.actual(number), patch, init_patch)
else:
sceneobj = _scene._parse_scene(scene)
self._scenes[number] = (sceneobj.name, [])
# build patches
patch = _patch.Patch(sceneobj.patch)
init_patch = _patch.Patch(sceneobj.init_patch)
# add scene to base class object
self.add_scene(_util.actual(number), patch, init_patch)
# build and setup control, pre, and post patches
control_patch = _patch.Patch(control) if control else None
pre_patch = _patch.Patch(pre) if pre else None
post_patch = _patch.Patch(post) if post else None
# tell base class object about these patches
self.set_processing(control_patch, pre_patch, post_patch)
global _TheEngine
_TheEngine = _weakref.ref(self)
_gc.collect()
_gc.disable()
def run(self):
self._quit = _threading.Event()
# delay before actually sending any midi data (give qjackctl patchbay time to react...)
self._start_delay()
self._call_hooks('on_start')
initial_scene, initial_subscene = self._parse_scene_number(_setup.get_config('initial_scene'))
# start the actual event processing
self.start(initial_scene, initial_subscene)
try:
# wait() with no timeout also blocks KeyboardInterrupt, but a very long timeout doesn't. weird...
while not self._quit.isSet():
self._quit.wait(86400)
except KeyboardInterrupt:
pass
finally:
self._call_hooks('on_exit')
global _TheEngine
_TheEngine = None
def _start_delay(self):
delay = _setup.get_config('start_delay')
if delay is not None:
if delay > 0:
_time.sleep(delay)
else:
raw_input("press enter to start midi processing...")
def _parse_scene_number(self, number):
if number in self._scenes:
# single scene number, no subscene
return (_util.actual(number), -1)
elif _misc.issequence(number) and len(number) > 1 and number[0] in self._scenes:
# scene/subscene numbers as tuple...
if _util.actual(number[1]) < len(self._scenes[number[0]][1]):
# both scene and subscene numbers are valid
return (_util.actual(number[0]), _util.actual(number[1]))
# subscene number is invalid
return (_util.actual(number[0]), -1)
# no such scene
return (-1, -1)
def process_file(self):
self.start(0, -1)
def scene_switch_callback(self, scene, subscene):
# the scene and subscene parameters are the actual numbers without offset!
if scene == -1:
# no scene specified, use current
scene = _mididings.Engine.current_scene(self)
if subscene == -1:
# no subscene specified, use first
subscene = 0
# save actual subscene index
subscene_index = subscene
# add data offset to scene/subscene numbers
scene = _util.offset(scene)
subscene = _util.offset(subscene)
found = (scene in self._scenes and
(not subscene_index or subscene_index < len(self._scenes[scene][1])))
# get string representation of scene/subscene number
if subscene_index or (scene in self._scenes and len(self._scenes[scene][1])):
number = "%d.%d" % (scene, subscene)
else:
number = str(scene)
if not _setup.get_config('silent'):
if found:
# get scene/subscene name
scene_data = self._scenes[scene]
if scene_data[1]:
name = "%s - %s" % (scene_data[0], scene_data[1][subscene_index])
else:
name = scene_data[0]
scene_desc = ("%s: %s" % (number, name)) if name else str(number)
print("switching to scene %s" % scene_desc)
else:
print("no such scene: %s" % number)
if found:
self._call_hooks('on_switch_scene', scene, subscene)
def _call_hooks(self, name, *args):
for hook in _setup.get_hooks():
if hasattr(hook, name):
f = getattr(hook, name)
f(*args)
def switch_scene(self, scene, subscene=None):
_mididings.Engine.switch_scene(self,
_util.actual(scene),
_util.actual(subscene) if subscene is not None else -1
)
def switch_subscene(self, subscene):
_mididings.Engine.switch_scene(self, -1, _util.actual(subscene))
def current_scene(self):
return _util.offset(_mididings.Engine.current_scene(self))
def current_subscene(self):
return _util.offset(_mididings.Engine.current_subscene(self))
def scenes(self):
return self._scenes
def process_event(self, ev):
ev._finalize()
return _mididings.Engine.process_event(self, ev)
def output_event(self, ev):
ev._finalize()
_mididings.Engine.output_event(self, ev)
def process(self, ev):
ev._finalize()
return _mididings.Engine.process(self, ev)
def restart(self):
_atexit.register(self._restart)
self.quit()
@staticmethod
def _restart():
# run the same interpreter with the same arguments again
_os.execl(_sys.executable, _sys.executable, *_sys.argv)
def quit(self):
self._quit.set()
@_overload.mark
@_arguments.accept(_UNIT_TYPES)
def run(patch):
"""
Create the engine and start event processing. This function does not
usually return until mididings exits.
"""
if isinstance(patch, dict) and all(not isinstance(k, _constants._EventType) for k in patch.keys()):
# bypass the overload mechanism (just this once...) if there's no way
# the given dict could be accepted as a split
run(scenes=patch)
else:
e = Engine()
e.setup({_util.offset(0): patch}, None, None, None)
e.run()
@_overload.mark
@_arguments.accept(_UNIT_TYPES, _arguments.nullable(_UNIT_TYPES), _arguments.nullable(_UNIT_TYPES), _arguments.nullable(_UNIT_TYPES))
def run(scenes, control=None, pre=None, post=None):
"""
Create the engine and start event processing. This function does not
usually return until mididings exits.
"""
e = Engine()
e.setup(scenes, control, pre, post)
e.run()
def process_file(infile, outfile, patch):
"""
Process a MIDI file using the smf backend.
"""
_setup._config_impl(
backend='smf',
)
_setup.config(
in_ports=[infile],
out_ports=[outfile],
)
e = Engine()
e.setup({_util.offset(0): patch}, None, None, None)
e.process_file()
def switch_scene(scene, subscene=None):
"""
Switch to the given scene number.
"""
_TheEngine().switch_scene(scene, subscene)
def switch_subscene(subscene):
"""
Switch to the given subscene number.
"""
_TheEngine().switch_subscene(subscene)
def current_scene():
"""
Return the current scene number.
"""
return _TheEngine().current_scene()
def current_subscene():
"""
Return the current subscene number.
"""
return _TheEngine().current_subscene()
def scenes():
"""
Return a mapping from scene numbers to a tuple of the form
(scene_name, [subscene_name, ...]).
"""
return _TheEngine().scenes()
def output_event(ev):
"""
Send an event directly to an output port.
"""
_TheEngine().output_event(ev)
def in_ports():
"""
Return the list of input port names.
"""
return _setup._in_portnames
def out_ports():
"""
Return the list of output port names.
"""
return _setup._out_portnames
def time():
"""
Return a floating point number of seconds since some unspecified starting
point.
"""
return _TheEngine().time()
def active():
"""
Return True if the engine is running, otherwise False.
"""
return _TheEngine is not None and _TheEngine() is not None
def restart():
"""
Restart mididings.
"""
_TheEngine().restart()
def quit():
"""
Quit mididings.
"""
_TheEngine().quit()
|