Mercurial > hg > syncopation-dataset
comparison Syncopation models/synpy/rhythm_parser.py @ 45:6e9154fc58df
moving the code files to the synpy package directory
author | christopherh <christopher.harte@eecs.qmul.ac.uk> |
---|---|
date | Thu, 23 Apr 2015 23:52:04 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
44:144460f34b5e | 45:6e9154fc58df |
---|---|
1 ''' | |
2 Authors: Chunyang Song, Christopher Harte | |
3 Institution: Centre for Digital Music, Queen Mary University of London | |
4 ''' | |
5 | |
6 # Parse the rhythm file and return a list of Bar objects | |
7 #Piece = [] | |
8 | |
9 from parameter_setter import timeSignatureBase | |
10 from music_objects import * | |
11 | |
12 comment_sign = '#' | |
13 | |
14 def discard_comments(line): | |
15 if comment_sign in line: | |
16 line = line[0:line.find(comment_sign)] | |
17 return line | |
18 | |
19 def discard_spaces(line): | |
20 line = line.replace(" ", '').replace("\t", '') | |
21 return line | |
22 | |
23 def discard_linereturns(line): | |
24 line = line.replace("\n","").replace("\r","") | |
25 return line | |
26 | |
27 | |
28 # def extractInfo(line): | |
29 # try: | |
30 # if '{' not in line and '}' not in line: | |
31 # raise RhythmSyntaxError(line) | |
32 # else: | |
33 # return line[line.find('{')+1 : line.find('}')] | |
34 # except RhythmSyntaxError: | |
35 # print 'Rhythmic information needs to be enclosed by "{" and "}"' | |
36 | |
37 | |
38 def read_rhythm(fileName): | |
39 fileContent = file(fileName) | |
40 | |
41 barList = BarList() | |
42 | |
43 tempo=None | |
44 timeSignature=None | |
45 ticksPerQuarter=None | |
46 | |
47 # for each line in the file, parse the line and add any | |
48 # new bars to the main bar list for the piece | |
49 for line in fileContent: | |
50 | |
51 # ignore the line if it's only a comment | |
52 if is_comment(line) or line=="\n": | |
53 continue | |
54 | |
55 # if time signature has not yet been set then it should be the first | |
56 # thing we find in a file after the comments at the top | |
57 if timeSignature==None: | |
58 (field, line) = get_next_field(line) | |
59 # if there is a valid field, it should be a time signature | |
60 if field!=None: | |
61 [fieldname,value] = field | |
62 if fieldname.lower()=="t": | |
63 timeSignature = TimeSignature(value) | |
64 else: | |
65 print 'Error, first field in the file should set the time signature.' | |
66 | |
67 # parse the line | |
68 (newbarlist, tempo, timeSignature, ticksPerQuarter) = parse_line(line, timeSignature, tempo, ticksPerQuarter) | |
69 | |
70 # if we found some bars in this line then add them to the overall bar list | |
71 if len(newbarlist)>0: | |
72 barList.concat(newbarlist) | |
73 | |
74 return barList | |
75 | |
76 def is_comment(line): | |
77 if discard_spaces(line)[0]==comment_sign: | |
78 return True | |
79 else: | |
80 return False | |
81 | |
82 def parse_line(line, timeSignature=None, tempo=None, ticksPerQuarter=None): | |
83 | |
84 #strip the line of line returns, spaces and comments | |
85 line = discard_linereturns(discard_spaces(discard_comments(line))) | |
86 | |
87 bars = BarList() | |
88 | |
89 #work through each field in the line | |
90 while len(line)>0: | |
91 (field, line) = get_next_field(line) | |
92 | |
93 if field!=None: | |
94 | |
95 [fieldname, value] = field | |
96 | |
97 if fieldname.lower() == "v": | |
98 #velocity sequence | |
99 bar = Bar(VelocitySequence(value),timeSignature, ticksPerQuarter, tempo) | |
100 bars.append(bar) | |
101 | |
102 elif fieldname.lower() == "y": | |
103 #note sequence | |
104 bar = Bar(NoteSequence(value), timeSignature, ticksPerQuarter, tempo) | |
105 bars.append(bar) | |
106 | |
107 elif fieldname.lower() == "t": | |
108 #time signature | |
109 timeSignature = TimeSignature(value) | |
110 | |
111 elif fieldname.lower() == "tpq": | |
112 #ticks per quarter | |
113 ticksPerQuarter = int(value) | |
114 | |
115 elif fieldname.lower() == "qpm": | |
116 #tempo | |
117 tempo = int(value) | |
118 | |
119 else: | |
120 print 'Unrecognised field type: "' + fieldname + '"' | |
121 | |
122 return bars, tempo, timeSignature, ticksPerQuarter | |
123 | |
124 class RhythmSyntaxError(Exception): | |
125 def __init__(self, value): | |
126 self.value = value | |
127 def __str__(self): | |
128 return repr(self.value) | |
129 | |
130 def get_next_field(line): | |
131 index = line.find("}") | |
132 field = None | |
133 if index>=0: | |
134 fieldtext = line[:index] | |
135 line = line[index+1:] | |
136 field = fieldtext.split("{") | |
137 else: | |
138 print 'Error, incorrect syntax: "'+line+'"' | |
139 raise RhythmSyntaxError(line) | |
140 | |
141 return field,line | |
142 | |
143 | |
144 | |
145 | |
146 |