Handle remaining samples < 4 correctly(?).
[calfbox.git] / py / sfzparser.py
blob9cadc3c0e5670baa1b2f66ae903799c44502d0b9
1 import os
2 import re
4 class SFZRegion(dict):
5 def __init__(self, group):
6 dict.__init__(self)
7 self.group = group
9 def merged(self):
10 if self.group is None:
11 return dict(self)
12 v = dict(self)
13 v.update(self.group)
14 return v
16 def __str__(self):
17 return "(" + str(self.group) + ") : " + dict.__str__(self.merged())
19 class SFZContext:
20 def __init__(self):
21 self.group = None
22 self.region = None
24 class SFZ:
25 def __init__(self):
26 self.regions = []
28 def load(self, fname):
29 self.parse(open(fname, "r").read())
31 def parse(self, data):
32 context = SFZContext()
33 for ptype, pdata in re.findall("<(region|group)>\s*([^<]*)", data, re.S):
34 self.parse_part(ptype, pdata.strip(), context)
36 def parse_part(self, ptype, pdata, context):
37 if ptype == 'group':
38 context.group = {}
39 context.region = None
40 target = context.group
41 else:
42 context.region = SFZRegion(context.group)
43 target = context.region
45 pairs = re.split("\s+([a-zA-Z_0-9]+)=", " "+pdata)[1:]
46 for i in range(0, len(pairs), 2):
47 target[pairs[i]] = pairs[i + 1]
48 if ptype == 'region':
49 self.regions.append(target)
51 def find_sample_in_path(path, sample):
52 jpath = os.path.join(path, sample)
53 if os.path.exists(jpath):
54 return jpath
55 path, sample = os.path.split(jpath)
56 sample = sample.lower()
57 files = os.path.listdir(path)
58 for f in files:
59 if f.lower() == sample:
60 return os.path.join(path, f)
61 return None