victor@2
|
1 '''
|
victor@2
|
2 Created on 10/11/2014
|
victor@2
|
3
|
victor@2
|
4 @organization: Lancaster University & University of Leeds
|
victor@2
|
5 @version: 1.0
|
victor@2
|
6 Created on 11/12/2014
|
victor@2
|
7
|
victor@2
|
8 @author: Victor Padilla
|
victor@2
|
9 @contact: v.padilla@lancaster.ac.uk
|
victor@2
|
10
|
victor@2
|
11 Functions related to convert music21 output
|
victor@2
|
12 to symbols for aligning and voting
|
victor@2
|
13 '''
|
victor@2
|
14 from music21 import note
|
victor@2
|
15 from music21 import chord
|
victor@2
|
16 from music21 import meter
|
victor@2
|
17 from music21 import key
|
victor@2
|
18 from music21 import stream
|
victor@2
|
19 from music21 import tie
|
victor@2
|
20 from music21 import bar
|
victor@2
|
21 from music21 import harmony
|
victor@2
|
22 from music21 import clef
|
victor@2
|
23 class SymbolConversion:
|
victor@2
|
24
|
victor@2
|
25
|
victor@2
|
26 def __getSymbolMesure(self,symbol):
|
victor@2
|
27 '''
|
victor@2
|
28 Detects if it is a barline symbol and gets the first element
|
victor@2
|
29 '''
|
victor@2
|
30 if isinstance(symbol,list):
|
victor@2
|
31 if symbol[0].find('!')!=-1:
|
victor@2
|
32 return symbol
|
victor@2
|
33
|
victor@2
|
34 def convertM21(self,symbolArray):
|
victor@2
|
35 '''
|
victor@2
|
36 Converts one Array of symbols to music21
|
victor@2
|
37
|
victor@2
|
38 usage:
|
victor@2
|
39
|
victor@2
|
40 outVote=vote.vote(omr_symbolsAlign)
|
victor@2
|
41 #apply voices if it is needed
|
victor@2
|
42
|
victor@2
|
43 outVote=sc.setVoices(outVote)
|
victor@2
|
44 #convert to music21
|
victor@2
|
45 resultS2=sc.convertM21(outVote)
|
victor@2
|
46
|
victor@2
|
47 '''
|
victor@2
|
48
|
victor@2
|
49 sOut=stream.Score()
|
victor@2
|
50 sPart=stream.Part()
|
victor@2
|
51 measureIndex=1
|
victor@2
|
52 measure=stream.Measure()
|
victor@2
|
53 measure.number=measureIndex
|
victor@2
|
54 voicesLength=8
|
victor@2
|
55 for v in range(voicesLength):
|
victor@2
|
56 voice=stream.Voice()
|
victor@2
|
57 voice.id=v
|
victor@2
|
58 measure.append(voice)
|
victor@2
|
59 indexS=0
|
victor@2
|
60
|
victor@2
|
61 for symbol in symbolArray:
|
victor@2
|
62 mytie=""
|
victor@2
|
63 realDuration=None
|
victor@2
|
64 s=symbol
|
victor@2
|
65
|
victor@2
|
66 if isinstance(s,list):
|
victor@2
|
67 s=s[0]
|
victor@2
|
68 if s.find('TS:')!=-1:
|
victor@2
|
69 ts=meter.TimeSignature(s[3:])
|
victor@2
|
70
|
victor@2
|
71 measure.append(ts)
|
victor@2
|
72 if s.find('KS:')!=-1:
|
victor@2
|
73 k=key.KeySignature(int(s[3:]))
|
victor@2
|
74
|
victor@2
|
75 measure.append(k)
|
victor@2
|
76 if s.find('CL:')!=-1:
|
victor@2
|
77 c=clef.clefFromString(str(s[3:]))
|
victor@2
|
78
|
victor@2
|
79 measure.append(c)
|
victor@2
|
80 if s.find('N:')!=-1:
|
victor@2
|
81 try:
|
victor@2
|
82 if isinstance(symbol,list):
|
victor@2
|
83 realDuration=symbol[1]
|
victor@2
|
84 mytie=symbol[2]
|
victor@2
|
85
|
victor@2
|
86 sep=s.index("_")
|
victor@2
|
87 duration=s[sep+1:]
|
victor@2
|
88 #*************************************
|
victor@2
|
89 #duration vs realDuration for triplets
|
victor@2
|
90 if realDuration!=None:
|
victor@2
|
91 duration=realDuration
|
victor@2
|
92 #*************************************
|
victor@2
|
93 if(float(duration)>0):
|
victor@2
|
94 n=note.Note(s[2:sep],quarterLength=float(duration))
|
victor@2
|
95 if symbol[5]!=None:
|
victor@2
|
96 n.color=symbol[5]
|
victor@2
|
97 if mytie!="":
|
victor@2
|
98 n.tie=tie.Tie(mytie)
|
victor@2
|
99 if len(symbol)>6:#voices
|
victor@2
|
100 measure.voices[symbol[6]].append(n)
|
victor@2
|
101 else:
|
victor@2
|
102 measure.append(n)
|
victor@2
|
103 except:
|
victor@2
|
104 print "error"+s
|
victor@2
|
105
|
victor@2
|
106 if s.find('R:')!=-1:
|
victor@2
|
107 try:
|
victor@2
|
108 if isinstance(symbol,list):
|
victor@2
|
109 realDuration=symbol[1]
|
victor@2
|
110 mytie=symbol[2]
|
victor@2
|
111 duration=s[2:]
|
victor@2
|
112 #*************************************
|
victor@2
|
113 #duration vs realDuration for triplets
|
victor@2
|
114 if realDuration!=None:
|
victor@2
|
115 duration=realDuration
|
victor@2
|
116 #*************************************
|
victor@2
|
117 n=note.Rest(quarterLength=float(duration))
|
victor@2
|
118 if symbol[5]!=None:
|
victor@2
|
119 n.color=symbol[5]
|
victor@2
|
120 if len(symbol)>6:#voices
|
victor@2
|
121 measure.voices[symbol[6]].append(n)
|
victor@2
|
122 else:
|
victor@2
|
123 measure.append(n)
|
victor@2
|
124 except:
|
victor@2
|
125 print "error"+s
|
victor@2
|
126
|
victor@2
|
127 if s.find('C:')!=-1:
|
victor@2
|
128 notes=s.split("[:")
|
victor@2
|
129 cPitch=[]
|
victor@2
|
130 for n in notes:
|
victor@2
|
131 if n!='C:':
|
victor@2
|
132 sep=n.index("_")
|
victor@2
|
133 duration=n[sep+1:]
|
victor@2
|
134 pitch= n[0:sep]
|
victor@2
|
135 cPitch.append(pitch)
|
victor@2
|
136 c=chord.Chord(cPitch)
|
victor@2
|
137 c.duration.quarterLength=float(duration)
|
victor@2
|
138 if symbol[5]!=None:
|
victor@2
|
139 c.color=symbol[5]
|
victor@2
|
140 if mytie!="":
|
victor@2
|
141 c.tie=tie.Tie(mytie)
|
victor@2
|
142
|
victor@2
|
143 if len(symbol)>6:#voices
|
victor@2
|
144 measure.voices[symbol[6]].append(c)
|
victor@2
|
145 else:
|
victor@2
|
146 measure.append(c)
|
victor@2
|
147
|
victor@2
|
148 if s.find('!')!=-1:
|
victor@2
|
149 if isinstance(symbol,list):
|
victor@2
|
150 barType= symbol[1]
|
victor@2
|
151 barRepeat= symbol[2]
|
victor@2
|
152 if barType!="":
|
victor@2
|
153 try:
|
victor@2
|
154 mybartype=bar.styleToMusicXMLBarStyle(barType)
|
victor@2
|
155 myBar=bar.Barline(style=mybartype)
|
victor@2
|
156 measure.rightBarline=myBar
|
victor@2
|
157 except:
|
victor@2
|
158 print "error barline"
|
victor@2
|
159
|
victor@2
|
160 if barRepeat!="":
|
victor@2
|
161 try:
|
victor@2
|
162 myBar=bar.Repeat(direction=barRepeat)
|
victor@2
|
163 if barRepeat=="start":
|
victor@2
|
164 measure.leftBarline=myBar
|
victor@2
|
165 if barRepeat=="end":
|
victor@2
|
166 measure.rightBarline=myBar
|
victor@2
|
167 except:
|
victor@2
|
168 print "error barline"
|
victor@2
|
169 sPart.append(measure)
|
victor@2
|
170 measureIndex+=1
|
victor@2
|
171 measure=stream.Measure()
|
victor@2
|
172 measure.number=measureIndex
|
victor@2
|
173 for v in range(voicesLength):
|
victor@2
|
174 voice=stream.Voice()
|
victor@2
|
175 voice.id=v
|
victor@2
|
176 measure.append(voice)
|
victor@2
|
177
|
victor@2
|
178 indexS+=1
|
victor@2
|
179
|
victor@2
|
180 sOut.append(sPart)
|
victor@2
|
181 return sOut
|
victor@2
|
182
|
victor@2
|
183
|
victor@2
|
184
|
victor@2
|
185
|
victor@2
|
186 def __orderChord(self,mychord):
|
victor@2
|
187 '''
|
victor@2
|
188 Private function that returns a chord ordered
|
victor@2
|
189 in a string from lower to higher
|
victor@2
|
190 '''
|
victor@2
|
191 midi=[]
|
victor@2
|
192 midi2=[]
|
victor@2
|
193 orderC=[]
|
victor@2
|
194 for n in mychord:
|
victor@2
|
195 if isinstance(n,note.Note):
|
victor@2
|
196 midi.append(n.midi)
|
victor@2
|
197 midi2.append(n.midi)
|
victor@2
|
198
|
victor@2
|
199 while len(midi)>0:
|
victor@2
|
200 indexMin=midi2.index(min(midi))
|
victor@2
|
201 indexPop=midi.index(min(midi))
|
victor@2
|
202 orderC.append(mychord[indexMin])
|
victor@2
|
203 midi.pop(indexPop)
|
victor@2
|
204
|
victor@2
|
205 myOrderChord=chord.Chord(orderC)
|
victor@2
|
206 myOrderChord.duration.quarterLength=mychord.duration.quarterLength
|
victor@2
|
207 return myOrderChord
|
victor@2
|
208
|
victor@2
|
209
|
victor@2
|
210 def __getKeyOffset(self,item):
|
victor@2
|
211 '''
|
victor@2
|
212 Private function that returns the offset of one item
|
victor@2
|
213 '''
|
victor@2
|
214 return item['offset']
|
victor@2
|
215
|
victor@2
|
216 def __removeDuplicates(self,input_raw):
|
victor@2
|
217 '''
|
victor@2
|
218 Private function to remove duplicates in the string input
|
victor@2
|
219 '''
|
victor@2
|
220 seen = set()
|
victor@2
|
221 new_l = []
|
victor@2
|
222 for d in input_raw:
|
victor@2
|
223 t = tuple(d.items())
|
victor@2
|
224 if t not in seen:
|
victor@2
|
225 seen.add(t)
|
victor@2
|
226 new_l.append(d)
|
victor@2
|
227
|
victor@2
|
228 return new_l
|
victor@2
|
229
|
victor@2
|
230
|
victor@2
|
231 def getElementsFromMeasureOrderByOffset(self,measure):
|
victor@2
|
232 '''
|
victor@2
|
233 Returns the symbols of a measure ordered by offset
|
victor@2
|
234 '''
|
victor@2
|
235 offset=measure.flat.offsetMap
|
victor@2
|
236 offset_n=self.__removeDuplicates(offset)
|
victor@2
|
237 sorted_offset=sorted(offset_n,key=self.__getKeyOffset)
|
victor@2
|
238 return sorted_offset
|
victor@2
|
239
|
victor@2
|
240 def __swapSymbols(self,s1,s2):
|
victor@2
|
241 '''
|
victor@2
|
242 Swap the s1,s2 symbols
|
victor@2
|
243 '''
|
victor@2
|
244 inter=s1
|
victor@2
|
245 s1=s2
|
victor@2
|
246 s2=inter
|
victor@2
|
247 return s1,s2
|
victor@2
|
248
|
victor@2
|
249 def orderSymbolsByPitch(self,symbols):
|
victor@2
|
250 '''
|
victor@2
|
251 Orders the symbol string from lower to high if they have
|
victor@2
|
252 the same offset
|
victor@2
|
253 '''
|
victor@2
|
254 for i in range(len(symbols)-1):
|
victor@2
|
255 for j in range(i,i+2):
|
victor@2
|
256 pitch_i=0
|
victor@2
|
257 pitch_j=0
|
victor@2
|
258 if(symbols[i]['offset']==symbols[j]['offset']):
|
victor@2
|
259 if isinstance(symbols[i]['element'],note.Note):
|
victor@2
|
260 pitch_i=symbols[i]['element'].pitch.midi
|
victor@2
|
261 if isinstance(symbols[j]['element'],note.Note):
|
victor@2
|
262 pitch_j=symbols[j]['element'].pitch.midi
|
victor@2
|
263
|
victor@2
|
264 if pitch_j>pitch_i:#higher pitch first
|
victor@2
|
265 symbols[i],symbols[j]=self.__swapSymbols(symbols[i],symbols[j])
|
victor@2
|
266
|
victor@2
|
267 if pitch_j==pitch_i and pitch_j>0:#longest first if equal pitch
|
victor@2
|
268 if symbols[i]['element'].duration<symbols[j]['element'].duration:
|
victor@2
|
269 symbols[i],symbols[j]=self.__swapSymbols(symbols[i],symbols[j])
|
victor@2
|
270
|
victor@2
|
271 if isinstance(symbols[j]['element'],note.Rest):#rest first
|
victor@2
|
272 symbols[i],symbols[j]=self.__swapSymbols(symbols[i],symbols[j])
|
victor@2
|
273
|
victor@2
|
274 return symbols
|
victor@2
|
275
|
victor@2
|
276 def getRepetitionMarks(self,measure):
|
victor@2
|
277 '''
|
victor@2
|
278 Returns the repetition marks symbol from a measure
|
victor@2
|
279 '''
|
victor@2
|
280 symbols=[]
|
victor@2
|
281 for barline in measure.getElementsByClass(bar.Barline):
|
victor@2
|
282 symbol={'voiceIndex': None, 'element': barline, 'endTime': 0.0, 'offset': barline.offset}
|
victor@2
|
283 symbols.append(symbol)
|
victor@2
|
284 return symbols
|
victor@2
|
285
|
victor@2
|
286 def getTS(self,measure):
|
victor@2
|
287 '''
|
victor@2
|
288 Returns the time signature symbol from a measure
|
victor@2
|
289 '''
|
victor@2
|
290 symbols=[]
|
victor@2
|
291 for ts in measure.getElementsByClass(meter.TimeSignature):
|
victor@2
|
292 symbol={'voiceIndex': None, 'element': ts, 'endTime': 0.0, 'offset': ts.offset}
|
victor@2
|
293 symbols.append(symbol)
|
victor@2
|
294 return symbols
|
victor@2
|
295
|
victor@2
|
296 def removeTS(self,symbols):
|
victor@2
|
297 '''
|
victor@2
|
298 Removes the time signature from the symbols array
|
victor@2
|
299 '''
|
victor@2
|
300 for symbol in symbols:
|
victor@2
|
301 s=symbol['element']
|
victor@2
|
302 if 'TimeSignature' in s.classes:
|
victor@2
|
303 symbols.pop(symbols.index(symbol))
|
victor@2
|
304 break
|
victor@2
|
305 return symbols
|
victor@2
|
306
|
victor@2
|
307 def filterOMR(self,omr,idPart):
|
victor@2
|
308 '''
|
victor@2
|
309 Removes elements from the music21 input as text, slurs and expressions (p, mp, f...)
|
victor@2
|
310
|
victor@2
|
311 Returns the omr filtered and the symbols array converted
|
victor@2
|
312
|
victor@2
|
313 '''
|
victor@2
|
314 omr_filtered=stream.Stream()
|
victor@2
|
315 omr_symbols=[]
|
victor@2
|
316 #for single parts
|
victor@2
|
317 print "Partes=",len(omr.parts)
|
victor@2
|
318 if len(omr.parts)==1:
|
victor@2
|
319 idPart=0
|
victor@2
|
320 if len(omr.parts)==0:
|
victor@2
|
321 idPart=0
|
victor@2
|
322 mypart=omr
|
victor@2
|
323 if len(omr.parts)>=1:
|
victor@2
|
324 if(int(idPart)>=len(omr.parts)):
|
victor@2
|
325 print "error in OMR"
|
victor@2
|
326 return [],[]
|
victor@2
|
327 mypart=omr.parts[int(idPart)]
|
victor@2
|
328
|
victor@2
|
329
|
victor@2
|
330
|
victor@2
|
331 isFirstClef=True
|
victor@2
|
332 indexMes=0
|
victor@2
|
333 print idPart
|
victor@2
|
334 for measure in mypart.getElementsByClass(stream.Measure):
|
victor@2
|
335 indexMes+=1
|
victor@2
|
336 symbols=self.getElementsFromMeasureOrderByOffset(measure.semiFlat)#key signature time signature and clef are missing if not flat
|
victor@2
|
337 symbols=self.orderSymbolsByPitch(symbols)
|
victor@2
|
338 symbolsRepetition=self.getRepetitionMarks(measure)
|
victor@2
|
339 symbolsTS=self.getTS(measure)
|
victor@2
|
340 symbols=self.removeTS(symbols)
|
victor@2
|
341 symbols=symbolsTS+symbols+symbolsRepetition
|
victor@2
|
342
|
victor@2
|
343 newMeasure=stream.Measure()
|
victor@2
|
344 styleBarline=""
|
victor@2
|
345 directionRepeat=""
|
victor@2
|
346 strClef=""
|
victor@2
|
347
|
victor@2
|
348 for symbol in symbols:
|
victor@2
|
349 #symbol={'voiceIndex': 0, 'element': <music21.note.Note C>, 'endTime': 1.0, 'offset': 0.0}
|
victor@2
|
350 s=symbol['element']
|
victor@2
|
351 if 'TimeSignature' in s.classes:
|
victor@2
|
352 newMeasure.append(s)
|
victor@2
|
353 str0="TS:"+str(s.numerator)+"/"+str(s.denominator)
|
victor@2
|
354 omr_symbols.append([str0,None,None,symbol['offset'],symbol['endTime'],None])
|
victor@2
|
355
|
victor@2
|
356 elif 'KeySignature' in s.classes:
|
victor@2
|
357 newMeasure.append(s)
|
victor@2
|
358 str0="KS:"+str(s.sharps)
|
victor@2
|
359 omr_symbols.append([str0,None,None,symbol['offset'],symbol['endTime'],None])
|
victor@2
|
360
|
victor@2
|
361 elif 'Clef' in s.classes:
|
victor@2
|
362 newMeasure.append(s)
|
victor@2
|
363 strClef="CL:"+str(s.sign)
|
victor@2
|
364 if isFirstClef:
|
victor@2
|
365 omr_symbols.append([strClef,None,None,symbol['offset'],symbol['endTime'],None])
|
victor@2
|
366 strClef=""
|
victor@2
|
367 isFirstClef=False
|
victor@2
|
368
|
victor@2
|
369 elif 'Note' in s.classes:
|
victor@2
|
370 newMeasure.append(s)
|
victor@2
|
371 mytype=s.duration.type
|
victor@2
|
372 duration=note.duration.convertTypeToQuarterLength(mytype)
|
victor@2
|
373 realDuration=s.duration.quarterLength
|
victor@2
|
374 if realDuration==duration+duration/2: #dot case
|
victor@2
|
375 duration=realDuration
|
victor@2
|
376 n="N:"+s.pitch.nameWithOctave+"_"+str(duration)
|
victor@2
|
377 # Ties case
|
victor@2
|
378 mytie=""
|
victor@2
|
379 if s.tie!=None:
|
victor@2
|
380 mytie=s.tie.type
|
victor@2
|
381
|
victor@2
|
382 if float(realDuration)>0:
|
victor@2
|
383 omr_symbols.append([n,realDuration,mytie,symbol['offset'],symbol['endTime'],s.color] )
|
victor@2
|
384
|
victor@2
|
385 elif 'Rest' in s.classes:
|
victor@2
|
386 newMeasure.append(s)
|
victor@2
|
387 mytype=s.duration.type
|
victor@2
|
388 if mytype!="complex":
|
victor@2
|
389 duration=note.duration.convertTypeToQuarterLength(mytype)
|
victor@2
|
390 else:
|
victor@2
|
391 duration=s.duration.quarterLength
|
victor@2
|
392 realDuration=s.duration.quarterLength
|
victor@2
|
393 if realDuration==duration+duration/2: #dot case
|
victor@2
|
394 duration=realDuration
|
victor@2
|
395 n="R:"+str(duration)
|
victor@2
|
396 # realDuration=s.duration.quarterLength
|
victor@2
|
397 omr_symbols.append([n,realDuration,False,symbol['offset'],symbol['endTime'],s.color])
|
victor@2
|
398
|
victor@2
|
399 elif 'Chord' in s.classes:
|
victor@2
|
400 if type(s) is not harmony.ChordSymbol:
|
victor@2
|
401 newMeasure.append(s)
|
victor@2
|
402 mytype=s.duration.type
|
victor@2
|
403 duration=note.duration.convertTypeToQuarterLength(mytype)
|
victor@2
|
404 realDuration=s.duration.quarterLength
|
victor@2
|
405 if realDuration==duration+duration/2: #dot case
|
victor@2
|
406 duration=realDuration
|
victor@2
|
407 chord="C:"
|
victor@2
|
408 sOrder=self.__orderChord(s)
|
victor@2
|
409 for n in sOrder:
|
victor@2
|
410 chord+="[:"+n.pitch.nameWithOctave+"_"+str(duration)
|
victor@2
|
411
|
victor@2
|
412
|
victor@2
|
413
|
victor@2
|
414 # Ties case
|
victor@2
|
415 mytie=""
|
victor@2
|
416 if s.tie!=None:
|
victor@2
|
417 mytie=s.tie.type
|
victor@2
|
418 omr_symbols.append([chord,realDuration,mytie,symbol['offset'],symbol['endTime'],s.color])
|
victor@2
|
419
|
victor@2
|
420 elif 'Barline' in s.classes:
|
victor@2
|
421 styleBarline=s.style
|
victor@2
|
422 try:
|
victor@2
|
423 directionRepeat=s.direction
|
victor@2
|
424 except:
|
victor@2
|
425 directionRepeat=""
|
victor@2
|
426
|
victor@2
|
427
|
victor@2
|
428 omr_symbols.append(['!',styleBarline,directionRepeat,symbol['offset'],symbol['endTime'],None])
|
victor@2
|
429 if strClef!="":
|
victor@2
|
430 omr_symbols.append([strClef,None,None,0,0,None])
|
victor@2
|
431 omr_filtered.append(newMeasure)
|
victor@2
|
432 return omr_filtered,omr_symbols
|
victor@2
|
433
|
victor@2
|
434 def removeExtraTies(self,arraySymbols):
|
victor@2
|
435 '''
|
victor@2
|
436 Removes the non logical ties from the symbol array
|
victor@2
|
437
|
victor@2
|
438 '''
|
victor@2
|
439 for s in arraySymbols:
|
victor@2
|
440 if isinstance(s,list):
|
victor@2
|
441 mainSymbol=s[0]
|
victor@2
|
442 if mainSymbol.find('N:')!=-1:
|
victor@2
|
443 tie1=s[2]
|
victor@2
|
444 if arraySymbols.index(s)<len(arraySymbols):
|
victor@2
|
445 sNext=arraySymbols[arraySymbols.index(s)+1]
|
victor@2
|
446 if isinstance(sNext,list):
|
victor@2
|
447 mainSymbol2=sNext[0]
|
victor@2
|
448 if mainSymbol2.find('N:')!=-1:
|
victor@2
|
449 tie2=sNext[2]
|
victor@2
|
450 if tie1=='start' and tie2!='end':
|
victor@2
|
451 s[2]=''
|
victor@2
|
452
|
victor@2
|
453 return arraySymbols
|
victor@2
|
454
|
victor@2
|
455
|
victor@2
|
456 def setVoices(self,strSymbols):
|
victor@2
|
457 '''
|
victor@2
|
458 Divides each measure in voices, if it is necessary.
|
victor@2
|
459
|
victor@2
|
460 The output is the symbol string using voices
|
victor@2
|
461
|
victor@2
|
462 '''
|
victor@2
|
463 quarters=self.__getTimeSignatureQuarters(strSymbols)
|
victor@2
|
464 measures=self.__chopMeasures(strSymbols)
|
victor@2
|
465 newString=[]
|
victor@2
|
466 for measure in measures:
|
victor@2
|
467 newMeasure=self.divideMeasureinVoices(measure,quarters)
|
victor@2
|
468 for s in newMeasure:
|
victor@2
|
469 newString.append(s)
|
victor@2
|
470 return newString
|
victor@2
|
471
|
victor@2
|
472 def __getTimeSignatureQuarters(self,strSymbols):
|
victor@2
|
473 '''
|
victor@2
|
474 returns the number of quarters of the first time signature found
|
victor@2
|
475 '''
|
victor@2
|
476 quarters=4 #4/4 by default
|
victor@2
|
477 for s in strSymbols:
|
victor@2
|
478 if isinstance(s,list):
|
victor@2
|
479 s=s[0]
|
victor@2
|
480 if s.find('TS:')!=-1:
|
victor@2
|
481 ts=s[3:]
|
victor@2
|
482 timeSig=ts.split("/")
|
victor@2
|
483 num=int(timeSig[0])
|
victor@2
|
484 den=int(timeSig[1])
|
victor@2
|
485 quarters=(4/den)*num
|
victor@2
|
486 return quarters
|
victor@2
|
487
|
victor@2
|
488 def __chopMeasures(self,strSymbols):
|
victor@2
|
489 '''
|
victor@2
|
490 Divides the symbol string in measures
|
victor@2
|
491 '''
|
victor@2
|
492 strMeasures=[]
|
victor@2
|
493 strMeasure=[]
|
victor@2
|
494 for s in strSymbols:
|
victor@2
|
495 strMeasure.append(s)
|
victor@2
|
496 bar=self.__getSymbolMesure(s)
|
victor@2
|
497 if bar!=None:
|
victor@2
|
498 strMeasures.append(strMeasure)
|
victor@2
|
499 strMeasure=[]
|
victor@2
|
500 return strMeasures
|
victor@2
|
501
|
victor@2
|
502
|
victor@2
|
503 def isNoteRest(self,symbol):
|
victor@2
|
504 '''
|
victor@2
|
505 Returns true if the symbol is note, rest or chord
|
victor@2
|
506 '''
|
victor@2
|
507 s=symbol
|
victor@2
|
508 if isinstance(s,list):
|
victor@2
|
509 if s[0].find('N:')!=-1:
|
victor@2
|
510 return True
|
victor@2
|
511 if s[0].find('R:')!=-1:
|
victor@2
|
512 return True
|
victor@2
|
513 if s[0].find('C:')!=-1:
|
victor@2
|
514 return True
|
victor@2
|
515 return False
|
victor@2
|
516 return False
|
victor@2
|
517
|
victor@2
|
518 def divideMeasureinVoices(self,strMeasure,quarters):
|
victor@2
|
519 '''
|
victor@2
|
520 If the length of each measure in the string is higher than quarters,
|
victor@2
|
521 adjusting to voices
|
victor@2
|
522
|
victor@2
|
523 '''
|
victor@2
|
524 newMeasure=[]
|
victor@2
|
525 duration=0
|
victor@2
|
526 #if duration is higher than time signatura
|
victor@2
|
527 for s in strMeasure:
|
victor@2
|
528 if self.isNoteRest(s):
|
victor@2
|
529 if s[1]!=None:
|
victor@2
|
530 try:
|
victor@2
|
531 duration+=s[1]
|
victor@2
|
532 except:
|
victor@2
|
533 pass
|
victor@2
|
534 # voices only if needed
|
victor@2
|
535 if duration<=quarters:
|
victor@2
|
536 return strMeasure
|
victor@2
|
537
|
victor@2
|
538
|
victor@2
|
539 for s in strMeasure:
|
victor@2
|
540 if not self.isNoteRest(s):
|
victor@2
|
541 if self.__getSymbolMesure(s)==None:
|
victor@2
|
542 newMeasure.append(s)
|
victor@2
|
543 voiceslength=8
|
victor@2
|
544 for v in range(voiceslength-1):
|
victor@2
|
545 offset=0.0
|
victor@2
|
546 firstNote=False
|
victor@2
|
547 for s in strMeasure:
|
victor@2
|
548 if self.isNoteRest(s):
|
victor@2
|
549 if len(s)<7:#not voice yet
|
victor@2
|
550 offsetNote=s[3]
|
victor@2
|
551 if firstNote==False:
|
victor@2
|
552 offset=offsetNote
|
victor@2
|
553 firstNote=True
|
victor@2
|
554 if offsetNote>0:
|
victor@2
|
555 rest=[]
|
victor@2
|
556 rest.append("R:"+str(offsetNote))
|
victor@2
|
557 rest.append(offsetNote)
|
victor@2
|
558 rest.append(False)
|
victor@2
|
559 rest.append(0)
|
victor@2
|
560 rest.append(offsetNote)
|
victor@2
|
561 rest.append(None)
|
victor@2
|
562 rest.append(v)
|
victor@2
|
563 newMeasure.append(rest)
|
victor@2
|
564 if(offset==offsetNote):
|
victor@2
|
565 s.append(v)
|
victor@2
|
566 newMeasure.append(s)
|
victor@2
|
567 offset=s[4]
|
victor@2
|
568
|
victor@2
|
569
|
victor@2
|
570 for s in strMeasure:
|
victor@2
|
571 if self.__getSymbolMesure(s)!=None:
|
victor@2
|
572 newMeasure.append(s)
|
victor@2
|
573
|
victor@2
|
574
|
victor@2
|
575 return newMeasure |