File: EventParser.py

package info (click to toggle)
python-pyo 1.0.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,332 kB
  • sloc: python: 135,133; ansic: 127,822; javascript: 16,116; sh: 395; makefile: 388; cpp: 242
file content (63 lines) | stat: -rw-r--r-- 2,341 bytes parent folder | download | duplicates (3)
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)