victor@1
|
1 '''
|
victor@1
|
2 @organization: Lancaster University & University of Leeds
|
victor@1
|
3 @version: 1.0
|
victor@1
|
4 Created on 11/12/2014
|
victor@1
|
5
|
victor@1
|
6 @author: Victor Padilla
|
victor@1
|
7 @contact: v.padilla@lancaster.ac.uk
|
victor@1
|
8
|
victor@1
|
9 Functions to manipulate measures
|
victor@1
|
10
|
victor@1
|
11
|
victor@1
|
12 '''
|
victor@1
|
13
|
victor@1
|
14 from music21 import stream
|
victor@1
|
15 from music21 import note
|
victor@1
|
16 from music21 import meter
|
victor@1
|
17 from music21 import omr
|
victor@1
|
18 from music21 import spanner
|
victor@1
|
19 from music21 import chord
|
victor@1
|
20 import copy
|
victor@1
|
21
|
victor@1
|
22
|
victor@1
|
23 class MeasureFunctions:
|
victor@1
|
24
|
victor@1
|
25 def getDuration(self,bar):
|
victor@1
|
26 '''
|
victor@1
|
27 Returns the duration of a single measure
|
victor@1
|
28 '''
|
victor@1
|
29 duration=0
|
victor@1
|
30 try:
|
victor@1
|
31 for event in bar:
|
victor@1
|
32 try:
|
victor@1
|
33 if(event.isNote):
|
victor@1
|
34 duration+=event.duration.quarterLength
|
victor@1
|
35 if(event.isRest):
|
victor@1
|
36 duration+=event.duration.quarterLength
|
victor@1
|
37 except:
|
victor@1
|
38 pass
|
victor@1
|
39 except:
|
victor@1
|
40 pass
|
victor@1
|
41 return str(duration)
|
victor@1
|
42
|
victor@1
|
43 def correctIncorrectMeasuresArray(self,omr,incorrectMeasures):
|
victor@1
|
44 '''
|
victor@1
|
45 Iteractive method that detects if some measures have been wrong flagged as an error.
|
victor@1
|
46 It is under development
|
victor@1
|
47 '''
|
victor@1
|
48 measures=omr.parts[0].getElementsByClass(stream.Measure)
|
victor@1
|
49 if 0 in incorrectMeasures:
|
victor@1
|
50 incorrectMeasures.remove(0)#Anacrusis
|
victor@1
|
51
|
victor@1
|
52 for barNumber in incorrectMeasures:
|
victor@1
|
53 if barNumber<len(measures)-1:
|
victor@1
|
54 measure=measures[barNumber]
|
victor@1
|
55 measureNext=measures[barNumber+1]
|
victor@1
|
56 duration=self.getDuration(measure)
|
victor@1
|
57
|
victor@1
|
58 if(float(duration)<=0):
|
victor@1
|
59 incorrectMeasures.remove(barNumber)
|
victor@1
|
60 self.correctIncorrectMeasuresArray(omr,incorrectMeasures)
|
victor@1
|
61
|
victor@1
|
62 if(measureNext!=None):
|
victor@1
|
63 durationNext=self.getDuration(measureNext)
|
victor@1
|
64 if(float(duration)+float(durationNext)==4):
|
victor@1
|
65 try:
|
victor@1
|
66 incorrectMeasures.remove(barNumber)
|
victor@1
|
67 incorrectMeasures.remove(barNumber+1)
|
victor@1
|
68 except:
|
victor@1
|
69 pass
|
victor@1
|
70 self.correctIncorrectMeasuresArray(omr,incorrectMeasures)
|
victor@1
|
71 return incorrectMeasures
|
victor@1
|
72
|
victor@1
|
73
|
victor@1
|
74 def filterExtraMeasures(self,omr):
|
victor@1
|
75 '''
|
victor@1
|
76 Function that removes empty measures
|
victor@1
|
77 '''
|
victor@1
|
78 sco=stream.Score()
|
victor@1
|
79 s=stream.Part()
|
victor@1
|
80 for measure in omr.parts[0].getElementsByClass(stream.Measure):
|
victor@1
|
81 if measure.flat.duration.quarterLength>0:
|
victor@1
|
82 s.append(measure)
|
victor@1
|
83 sco.append(s)
|
victor@1
|
84 return sco
|
victor@1
|
85
|
victor@1
|
86
|
victor@1
|
87 def getIncorrectMeasureIndices(self,omr):
|
victor@1
|
88 '''
|
victor@1
|
89 Method that detect wrong measures using transitions
|
victor@1
|
90 '''
|
victor@1
|
91 arrChunks= self.getTransitions(omr)
|
victor@1
|
92 measures=omr.parts[0].getElementsByClass(stream.Measure)
|
victor@1
|
93 indexBar=0
|
victor@1
|
94 FlagErrors=[]
|
victor@1
|
95 barFrom=0
|
victor@1
|
96 barTo=0
|
victor@1
|
97 for chunk in arrChunks:
|
victor@1
|
98 indexC=arrChunks.index(chunk)
|
victor@1
|
99 chunkBefore=arrChunks[indexC-1]
|
victor@1
|
100 if(indexC==0):
|
victor@1
|
101 barFrom=0
|
victor@1
|
102 else:
|
victor@1
|
103 barFrom+=chunkBefore[1]
|
victor@1
|
104 barTo=chunk[1]+barFrom
|
victor@1
|
105 chunkMeasures=measures[barFrom:barTo]
|
victor@1
|
106 quarterChunk=round(chunk[0]/2)
|
victor@1
|
107 for measure in chunkMeasures:
|
victor@1
|
108 if measure.duration.quarterLength!=quarterChunk:
|
victor@1
|
109 FlagErrors.append(indexBar)
|
victor@1
|
110 indexBar+=1
|
victor@1
|
111 return FlagErrors
|
victor@1
|
112
|
victor@1
|
113 def _filterTransitions(self,arrMeasureIndex):
|
victor@1
|
114 '''
|
victor@1
|
115 Inner method that removes false transitions in measures for detecting missing time signatures
|
victor@1
|
116 '''
|
victor@1
|
117 arrMeasureIndex2=[]
|
victor@1
|
118 arrMeasureIndex.insert(0,0)
|
victor@1
|
119 arrMeasureIndex.append(-1)
|
victor@1
|
120 for mes in arrMeasureIndex:
|
victor@1
|
121 indexM=arrMeasureIndex.index(mes)
|
victor@1
|
122 if indexM>0:
|
victor@1
|
123 bars=arrMeasureIndex[indexM]-arrMeasureIndex[indexM-1]
|
victor@1
|
124 if (bars>9):
|
victor@1
|
125 arrMeasureIndex2.append(mes)
|
victor@1
|
126 arrMeasureIndex2.insert(0,0)
|
victor@1
|
127 arrMeasureIndex2.append(-1)
|
victor@1
|
128 return arrMeasureIndex2
|
victor@1
|
129
|
victor@1
|
130 def getTransitions(self,omr):
|
victor@1
|
131 '''
|
victor@1
|
132 Returns transitions in a omr
|
victor@1
|
133 '''
|
victor@1
|
134 MeasuresLength=[]
|
victor@1
|
135 arrMeasureIndex_before=self._getTransitionBar(omr)
|
victor@1
|
136
|
victor@1
|
137 arrMeasureIndex=self._filterTransitions(arrMeasureIndex_before)
|
victor@1
|
138 for i in range(len(arrMeasureIndex)-1):
|
victor@1
|
139 arrMeasureslength= self._getAverageQuavers(omr,arrMeasureIndex[i],arrMeasureIndex[i+1],False)
|
victor@1
|
140 MeasuresLength.append(arrMeasureslength)
|
victor@1
|
141
|
victor@1
|
142 return MeasuresLength
|
victor@1
|
143
|
victor@1
|
144 def _getTransitionBar(self,omr):
|
victor@1
|
145 '''
|
victor@1
|
146 Inner function for getting transitions
|
victor@1
|
147 '''
|
victor@1
|
148 arrOut=[]
|
victor@1
|
149 measures=omr.parts[0].getElementsByClass(stream.Measure)
|
victor@1
|
150 barsNumber=len(measures)
|
victor@1
|
151 for barIndex in range(5,barsNumber):
|
victor@1
|
152 averageBefore=self._getAverageQuavers(omr,barIndex-4,barIndex,isUntilTS=False)
|
victor@1
|
153 averageAfter=self._getAverageQuavers(omr,barIndex,barIndex+2,isUntilTS=False)
|
victor@1
|
154 if(abs(averageBefore[0]-averageAfter[0])>1.5):
|
victor@1
|
155 if(measures[barIndex].duration.quarterLength<averageBefore[0]*2):#rest bars or missing bars
|
victor@1
|
156 arrOut.append(barIndex)
|
victor@1
|
157 return arrOut
|
victor@1
|
158
|
victor@1
|
159 def _getAverageQuavers(self,myStream,measureIndex,measureIndexEnd,isUntilTS):
|
victor@1
|
160 '''
|
victor@1
|
161 Inner function for getting the average quavers per measure in a group of measures
|
victor@1
|
162 '''
|
victor@1
|
163 quavers=0
|
victor@1
|
164 barNumbers=0
|
victor@1
|
165 averageQuavers=0
|
victor@1
|
166 measures=myStream.parts[0].getElementsByClass(stream.Measure)
|
victor@1
|
167 for bar in measures[measureIndex:measureIndexEnd]:
|
victor@1
|
168 duration=bar.duration.quarterLength*2
|
victor@1
|
169 barNumbers+=1
|
victor@1
|
170 if(duration>0 and duration<10):
|
victor@1
|
171 quavers+=duration
|
victor@1
|
172 if isUntilTS:
|
victor@1
|
173 if (len(bar.getElementsByClass(meter.TimeSignature))>0):
|
victor@1
|
174 break
|
victor@1
|
175 if barNumbers>0:
|
victor@1
|
176 averageQuavers=quavers/barNumbers
|
victor@1
|
177 return averageQuavers,barNumbers
|
victor@1
|
178
|
victor@1
|
179 #**************************************************
|
victor@1
|
180 def getPossibleBeamsErrors(self,omr):
|
victor@1
|
181 '''
|
victor@1
|
182 Function that returns measure errors based on non conventional beaming
|
victor@1
|
183 '''
|
victor@1
|
184 arrErrors=[]
|
victor@1
|
185 measures=omr.parts[0].getElementsByClass(stream.Measure)
|
victor@1
|
186 barsNumber=len(measures)
|
victor@1
|
187 for i in range(barsNumber):
|
victor@1
|
188 notes=measures[i].getElementsByClass(note.Note)
|
victor@1
|
189 count=0
|
victor@1
|
190 state=0
|
victor@1
|
191 for n in notes:
|
victor@1
|
192 if n.duration.quarterLength==0.25:
|
victor@1
|
193 bs=n.beams.getNumbers()
|
victor@1
|
194 if(len(bs)>0):
|
victor@1
|
195 b=n.beams.getByNumber(bs[0])
|
victor@1
|
196 if b.type=='start':
|
victor@1
|
197 count=1
|
victor@1
|
198 state=1
|
victor@1
|
199 if b.type=='continue':
|
victor@1
|
200 if(state==1 or state==2):
|
victor@1
|
201 count+=1
|
victor@1
|
202 state=2
|
victor@1
|
203 if b.type=='stop':
|
victor@1
|
204 if(state==1 or state==2):
|
victor@1
|
205 count+=1
|
victor@1
|
206 if count==3:
|
victor@1
|
207 arrErrors.append(i)
|
victor@1
|
208 arrErrors=list(set(arrErrors))
|
victor@1
|
209 return arrErrors
|
victor@1
|
210
|
victor@1
|
211 def getPossibleLastNoteErrors(self,omr):
|
victor@1
|
212 '''
|
victor@1
|
213 Function that returns measure errors based on the last notes rhythm
|
victor@1
|
214 '''
|
victor@1
|
215 arrErrors=[]
|
victor@1
|
216 measures=omr.parts[0].getElementsByClass(stream.Measure)
|
victor@1
|
217 barsNumber=len(measures)
|
victor@1
|
218 for i in range(barsNumber):
|
victor@1
|
219 notes=measures[i].getElementsByClass(note.GeneralNote)
|
victor@1
|
220 if(len(notes)>0):
|
victor@1
|
221 lastNote=notes[len(notes)-1]
|
victor@1
|
222 if lastNote.duration.quarterLength<=0.25:
|
victor@1
|
223 if(lastNote.isRest):
|
victor@1
|
224 arrErrors.append(i)
|
victor@1
|
225 else:
|
victor@1
|
226 bs=lastNote.beams.getNumbers()
|
victor@1
|
227
|
victor@1
|
228 if(len(bs)==0):
|
victor@1
|
229 if(len(notes)>2):
|
victor@1
|
230 noteBefore=notes[len(notes)-2]
|
victor@1
|
231 if noteBefore.duration.quarterLength+lastNote.duration.quarterLength!=1:
|
victor@1
|
232 arrErrors.append(i)
|
victor@1
|
233
|
victor@1
|
234
|
victor@1
|
235 return arrErrors
|
victor@1
|
236
|
victor@1
|
237 def flagIncorrectMeasures(self,omr2):
|
victor@1
|
238 '''
|
victor@1
|
239 flag the incorrect measures from a omr using different methods
|
victor@1
|
240 '''
|
victor@1
|
241 mf=MeasureFunctions()
|
victor@1
|
242 sc=omr.correctors.ScoreCorrector(omr2)
|
victor@1
|
243 part=sc.getSinglePart(0)
|
victor@1
|
244
|
victor@1
|
245 arrErrors=[]
|
victor@1
|
246 im=part.getIncorrectMeasureIndices(runFast=False)
|
victor@1
|
247
|
victor@1
|
248 im1= mf.getIncorrectMeasureIndices(omr2)
|
victor@1
|
249
|
victor@1
|
250 im2= mf.getPossibleBeamsErrors(omr2)
|
victor@1
|
251 im3= mf.getPossibleLastNoteErrors(omr2)
|
victor@1
|
252
|
victor@1
|
253
|
victor@1
|
254 arrErrors.append(im)
|
victor@1
|
255 arrErrors.append(im1)
|
victor@1
|
256 arrErrors.append(im2)
|
victor@1
|
257 arrErrors.append(im3)
|
victor@1
|
258
|
victor@1
|
259 if(len(im)>15):
|
victor@1
|
260 if(len(im1)<len(im)):
|
victor@1
|
261 im=im1
|
victor@1
|
262 imSum=list(set(im)|set(im2)|set(im3))
|
victor@1
|
263 imSum=sorted(imSum)
|
victor@1
|
264 imOK=mf.correctIncorrectMeasuresArray(omr2,imSum)
|
victor@1
|
265 print im
|
victor@1
|
266 return imOK,arrErrors
|
victor@1
|
267
|
victor@1
|
268 def getSlurs(self,part):
|
victor@1
|
269 '''
|
victor@1
|
270 Returns the slurs from one part
|
victor@1
|
271 '''
|
victor@1
|
272 slurs=part.flat.getElementsByClass(spanner.Spanner)
|
victor@1
|
273 return slurs
|
victor@1
|
274
|
victor@1
|
275 def reconstructScore(self,part,hashPart):
|
victor@1
|
276 '''
|
victor@1
|
277 This function include rest measures in one part based on the hash part aligned
|
victor@1
|
278 '''
|
victor@1
|
279 partReconstructed=stream.Part()
|
victor@1
|
280 barNumber=1
|
victor@1
|
281 gaps=[]
|
victor@1
|
282 for i in range(len(hashPart)):
|
victor@1
|
283 if hashPart[i]!="*":
|
victor@1
|
284 m=part.getElementsByClass(stream.Measure)[barNumber-1]
|
victor@1
|
285 partReconstructed.append(m)
|
victor@1
|
286 barNumber+=1
|
victor@1
|
287 else:
|
victor@1
|
288 m=stream.Measure()
|
victor@1
|
289 partReconstructed.append(m)
|
victor@1
|
290 gaps.append(i)
|
victor@1
|
291 slurs=self.getSlurs(part)
|
victor@1
|
292 partReconstructed.append(slurs)
|
victor@1
|
293 myStream=self.reorderMeasures(partReconstructed)
|
victor@1
|
294 return myStream,gaps
|
victor@1
|
295
|
victor@1
|
296 def reorderMeasures(self,omr):
|
victor@1
|
297 '''
|
victor@1
|
298 Returns the correct measures number
|
victor@1
|
299 '''
|
victor@1
|
300 slurs=self.getSlurs(omr)
|
victor@1
|
301 s=stream.Part()
|
victor@1
|
302 barNumber=1
|
victor@1
|
303 for measure in omr.getElementsByClass(stream.Measure):
|
victor@1
|
304 measure.number=barNumber
|
victor@1
|
305 s.append(measure)
|
victor@1
|
306 barNumber+=1
|
victor@1
|
307 s.append(slurs)
|
victor@1
|
308 return s
|
victor@1
|
309
|
victor@1
|
310 def getNoteByOffset(self,voice,offset):
|
victor@1
|
311 '''
|
victor@1
|
312 Returns one note in one voice according to the offset
|
victor@1
|
313 '''
|
victor@1
|
314 for n in voice.getElementsByClass(note.Note):
|
victor@1
|
315 if n.offset==offset:
|
victor@1
|
316 return n
|
victor@1
|
317 for n in voice.getElementsByClass(chord.Chord):
|
victor@1
|
318 if n.offset==offset:
|
victor@1
|
319 return n
|
victor@1
|
320
|
victor@1
|
321 def convertVoicesToChord(self,omr):
|
victor@1
|
322 '''
|
victor@1
|
323 Function that converts voices with the same rhythm to chords
|
victor@1
|
324 '''
|
victor@1
|
325 for part in omr.getElementsByClass(stream.Part):
|
victor@1
|
326 for measure in part.getElementsByClass(stream.Measure):
|
victor@1
|
327 measure.show('text')
|
victor@1
|
328 voices=measure.getElementsByClass(stream.Voice)
|
victor@1
|
329 if len(voices)>=2:
|
victor@1
|
330 for element1 in voices[0].getElementsByClass(note.GeneralNote):
|
victor@1
|
331 offset1= element1.offset
|
victor@1
|
332 for voice in voices:
|
victor@1
|
333 if voice!=voices[0]:
|
victor@1
|
334 element2=self.getNoteByOffset( voice, offset1)
|
victor@1
|
335 if element2 is not None and element1.duration.quarterLength==element2.duration.quarterLength and not isinstance(element1,note.Rest):
|
victor@1
|
336 mychord=self.mergeChords(element1,element2)
|
victor@1
|
337 mychord.duration.quarterLength=element1.quarterLength
|
victor@1
|
338 voices[0].replace(element1,mychord)
|
victor@1
|
339 myrest=note.Rest()
|
victor@1
|
340 myrest.duration.quarterLength=element1.quarterLength
|
victor@1
|
341 voice.replace(element2,myrest)
|
victor@1
|
342
|
victor@1
|
343 omr=self.removeRestVoice(omr)
|
victor@1
|
344 return omr
|
victor@1
|
345 def removeRestVoice(self,omr):
|
victor@1
|
346 '''
|
victor@1
|
347 This option removes the rest voices (without notes)
|
victor@1
|
348 '''
|
victor@1
|
349 for part in omr.getElementsByClass(stream.Part):
|
victor@1
|
350 for measure in part.getElementsByClass(stream.Measure):
|
victor@1
|
351 voices=measure.getElementsByClass(stream.Voice)
|
victor@1
|
352 for voice in voices:
|
victor@1
|
353 myvoice = copy.deepcopy(voice)
|
victor@1
|
354 myvoice.removeByClass('Rest')
|
victor@1
|
355 if len(myvoice)==0:
|
victor@1
|
356 measure.remove(voice)
|
victor@1
|
357
|
victor@1
|
358 return omr
|
victor@1
|
359
|
victor@1
|
360 def mergeChords(self,element1,element2):
|
victor@1
|
361 '''
|
victor@1
|
362 Returns one chord made by two elements, notes or chords
|
victor@1
|
363 '''
|
victor@1
|
364 notes1=[]
|
victor@1
|
365 notes2=[]
|
victor@1
|
366 notes=[]
|
victor@1
|
367 if isinstance(element1,chord.Chord):
|
victor@1
|
368 notes1=element1.pitches
|
victor@1
|
369 else:
|
victor@1
|
370 notes1.append(element1.pitch)
|
victor@1
|
371
|
victor@1
|
372 if isinstance(element2,chord.Chord):
|
victor@1
|
373 notes2=element2.pitches
|
victor@1
|
374 else:
|
victor@1
|
375 notes2.append(element2.pitch)
|
victor@1
|
376
|
victor@1
|
377 for n in notes1:
|
victor@1
|
378 notes.append(n)
|
victor@1
|
379 for n in notes2:
|
victor@1
|
380 notes.append(n)
|
victor@1
|
381
|
victor@1
|
382 mychord = chord.Chord(notes)
|
victor@1
|
383 return mychord
|
victor@1
|
384
|
victor@1
|
385
|
victor@1
|
386 def convertBeamsToTriplets(self,omr):
|
victor@1
|
387 '''
|
victor@1
|
388 This option search for measures where the rhythm is bigger than the time signature
|
victor@1
|
389 and tries to convert 3 note beams in triplets
|
victor@1
|
390 '''
|
victor@1
|
391 tsDefault=omr.flat.getElementsByClass('TimeSignature')[0]
|
victor@1
|
392 idPart=0
|
victor@1
|
393 for part in omr.getElementsByClass(stream.Part):
|
victor@1
|
394 idPart+=1
|
victor@1
|
395 idMeasure=0
|
victor@1
|
396 for measure in part.getElementsByClass(stream.Measure):
|
victor@1
|
397 idMeasure+=1
|
victor@1
|
398 if self._IsMeasureHigherTS(idMeasure, part,tsDefault):
|
victor@1
|
399 print idMeasure
|
victor@1
|
400 measure=self.beamsToTriplets(measure)
|
victor@1
|
401 return omr
|
victor@1
|
402
|
victor@1
|
403
|
victor@1
|
404 def _IsMeasureHigherTS(self,idMeasure,part,ts):
|
victor@1
|
405 '''
|
victor@1
|
406 Inner function that detects if one measure is bigger than the time signature
|
victor@1
|
407 '''
|
victor@1
|
408 idCountMeasure=0
|
victor@1
|
409 for measure in part.getElementsByClass(stream.Measure):
|
victor@1
|
410 idCountMeasure+=1
|
victor@1
|
411 newts=measure.flat.getElementsByClass('TimeSignature')
|
victor@1
|
412 if len(newts)>0:
|
victor@1
|
413 ts=newts[0]
|
victor@1
|
414 if idMeasure==idCountMeasure:
|
victor@1
|
415 voices=measure.getElementsByClass(stream.Voice)
|
victor@1
|
416 totalDuration=0
|
victor@1
|
417 if len(voices)>=1:
|
victor@1
|
418 for voice in voices:
|
victor@1
|
419 totalDuration=0
|
victor@1
|
420 for element in voice.getElementsByClass(note.GeneralNote):
|
victor@1
|
421 totalDuration+=element.duration.quarterLength;
|
victor@1
|
422 else:
|
victor@1
|
423 for element in measure.getElementsByClass(note.GeneralNote):
|
victor@1
|
424 totalDuration+=element.duration.quarterLength;
|
victor@1
|
425 quartersBymeasure=ts.numerator*(4.0/ts.denominator)
|
victor@1
|
426 if totalDuration>quartersBymeasure:
|
victor@1
|
427 return True
|
victor@1
|
428 else:
|
victor@1
|
429 return False
|
victor@1
|
430 def beamsToTriplets(self,measure):
|
victor@1
|
431 '''
|
victor@1
|
432 This function returns one measure changing 3 notes beamed by triplets
|
victor@1
|
433 '''
|
victor@1
|
434 voices=measure.getElementsByClass(stream.Voice)
|
victor@1
|
435 if len(voices)>=1:
|
victor@1
|
436 for voice in voices:
|
victor@1
|
437 notes=voice.getElementsByClass(note.NotRest)
|
victor@1
|
438 notes=self._notesToTriplets(notes)
|
victor@1
|
439
|
victor@1
|
440 else:
|
victor@1
|
441 notes=measure.getElementsByClass(note.NotRest)
|
victor@1
|
442 notes=self._notesToTriplets(notes)
|
victor@1
|
443
|
victor@1
|
444 return measure
|
victor@1
|
445
|
victor@1
|
446
|
victor@1
|
447 def _notesToTriplets(self,notes):
|
victor@1
|
448 '''
|
victor@1
|
449 Gets one note arrays and tries to convert to triplets
|
victor@1
|
450 '''
|
victor@1
|
451
|
victor@1
|
452 for i in range(len(notes)):
|
victor@1
|
453 self._removeSlurs(notes[i])
|
victor@1
|
454 beams1=notes[i].beams.beamsList
|
victor@1
|
455
|
victor@1
|
456 try:
|
victor@1
|
457 beams2=notes[i+1].beams.beamsList
|
victor@1
|
458 beams3=notes[i+2].beams.beamsList
|
victor@1
|
459 if len(beams1)>0 and len(beams2)>0 and len(beams3)>0:
|
victor@1
|
460 if beams1[0].type=='start' and beams2[0].type=='continue' and beams3[0].type=='stop':
|
victor@1
|
461 if notes[i].duration.quarterLength==notes[i+1].duration.quarterLength==notes[i+2].duration.quarterLength:
|
victor@1
|
462 mytype=notes[i].duration.type
|
victor@1
|
463 duration=note.duration.convertTypeToQuarterLength(mytype)
|
victor@1
|
464 realDuration=duration*2.0/3.0
|
victor@1
|
465 notes[i].duration.quarterLength=realDuration
|
victor@1
|
466 notes[i+1].duration.quarterLength=realDuration
|
victor@1
|
467 notes[i+2].duration.quarterLength=realDuration
|
victor@1
|
468
|
victor@1
|
469 except:
|
victor@1
|
470 pass
|
victor@1
|
471
|
victor@1
|
472 return notes
|
victor@1
|
473
|
victor@1
|
474 def _removeSlurs(self,n):
|
victor@1
|
475 '''
|
victor@1
|
476 Removes the slur in one note
|
victor@1
|
477 '''
|
victor@1
|
478 for element in n.getSites():
|
victor@1
|
479 if isinstance(element,stream.SpannerStorage):
|
victor@1
|
480 for e in element.elements:
|
victor@1
|
481 element.pop(0)
|
victor@1
|
482
|
victor@1
|
483 def removesEmptyVoices(self,omr):
|
victor@1
|
484 '''
|
victor@1
|
485 Removes empty voices (just rests)
|
victor@1
|
486 '''
|
victor@1
|
487 for part in omr.getElementsByClass(stream.Part):
|
victor@1
|
488 for measure in part.getElementsByClass(stream.Measure):
|
victor@1
|
489 print measure
|
victor@1
|
490 voices=measure.getElementsByClass(stream.Voice)
|
victor@1
|
491 if len(voices)>=1:
|
victor@1
|
492 print len(voices)
|
victor@1
|
493 for voice in voices:
|
victor@1
|
494 notes=voice.getElementsByClass(note.NotRest)
|
victor@1
|
495 if len(notes)==0:
|
victor@1
|
496 index=measure.index(voice)
|
victor@1
|
497 measure.pop(index)
|
victor@1
|
498 voices=measure.getElementsByClass(stream.Voice)
|
victor@1
|
499 if len(voices)==1:
|
victor@1
|
500 measure.flattenUnnecessaryVoices()
|
victor@1
|
501 return omr
|
victor@1
|
502
|
victor@1
|
503 def removesGaps(self,omr):
|
victor@1
|
504 '''
|
victor@1
|
505 This option changes gaps by rests in voices
|
victor@1
|
506 '''
|
victor@1
|
507 for part in omr.getElementsByClass(stream.Part):
|
victor@1
|
508 for measure in part.getElementsByClass(stream.Measure):
|
victor@1
|
509 voices=measure.getElementsByClass(stream.Voice)
|
victor@1
|
510 if len(voices)>=1:
|
victor@1
|
511 for voice in voices:
|
victor@1
|
512 v=voice.findGaps()
|
victor@1
|
513 if v!=None:
|
victor@1
|
514 nextOffset=1000
|
victor@1
|
515 for element in voice.getElementsByClass(note.GeneralNote):
|
victor@1
|
516 offset= element.offset
|
victor@1
|
517 if offset>nextOffset:
|
victor@1
|
518 rest=note.Rest()
|
victor@1
|
519 rest.duration.quarterLength=offset-nextOffset
|
victor@1
|
520 voice.insert(nextOffset,rest)
|
victor@1
|
521 nextOffset=1000
|
victor@1
|
522 else:
|
victor@1
|
523 duration=element.duration.quarterLength
|
victor@1
|
524 nextOffset=offset+duration
|
victor@1
|
525 return omr
|
victor@1
|
526
|
victor@1
|
527
|