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
|
"""
EventParser first draft (very very alpha stage!).
Score format:
Class_name => starttime duration *args **kwargs
Class_name {class reference}: The name of the class which should play the event,
starttime {float}: Start time of the event, in seconds.
duration {float}: Start time of the event, in seconds.
*args {list of floats}: user-defined arguments (optional).
**kwargs {dictionary}: user-defined keyword arguments (optional).
"""
# Notes:
# We should be able to define an event using multiple lines.
# Actually, the parser uses splitlines() to separate events.
# How to automatically use globals() from the __main__ module, I don't
# want to ask the user to pass globals() to have access to instrument classes.
class EventParser:
def __init__(self, server, score="", globals=None):
self.server = server
self.globals = globals
self._instruments = {}
self.parse(score)
def extractKwArgs(self, args):
kwargs = ""
if "{" in args:
p1 = args.find("{")
args, kwargs = args[:p1], args[p1:]
if kwargs:
kwargs = eval(kwargs)
return args, kwargs
def parse(self, score):
for line in score.splitlines():
if line.strip() == "":
continue
instr, args = line.split("=>")
instr = instr.strip()
args, kwargs = self.extractKwArgs(args)
args = [float(x) for x in args.split()] # should also eval variable
# names, not just numbers
if instr not in self._instruments:
self._instruments[instr] = [{"args": args, "kwargs": kwargs}]
else:
self._instruments[instr].append({"args": args, "kwargs": kwargs})
def play(self):
self._playing = []
for instr in self._instruments:
for event in self._instruments[instr]:
self.server.setGlobalDel(event["args"][0])
self.server.setGlobalDur(event["args"][1] + 0.2)
if not event["kwargs"]:
self._playing.append(self.globals[instr](*event["args"][1:]))
else:
self._playing.append(self.globals[instr](*event["args"][1:], **event["kwargs"]))
self.server.setGlobalDel(0)
self.server.setGlobalDur(0)
|