self._parseMusic()
self.verses = [[]]
self.chorus = []
- if autoDetectChorus :
- self._findChorus()
- self._findVersesLoops()
+ self.songStartsWithChorus = False
+ self._findVersesLoops(autoDetectChorus)
def _parseMusic(self) :
divisions = 0
previous.addDuration(note)
continue
else :
- previous.addDuration(note)
+ try :
+ previous.addDuration(note)
+ except AttributeError :
+ # can occur if part starts with a rest.
+ if previous is not None :
+ # something else is wrong.
+ raise
continue
previous = note
self.quarterNoteDuration = int(round(60000/tempo))
-
- def _findChorus(self):
- """ le refrain correspond aux notes pour lesquelles
- il n'existe q'une seule syllable attachée.
- """
- start = stop = None
- for i, note in enumerate(self.notes) :
- ll = len(note.lyrics)
- if start is None and ll == 1 :
- start = i
- elif start is not None and ll > 1 :
- stop = i
- break
- if not (start or stop) :
- self.chorus = []
- else :
- self.chorus = self.notes[start:stop]
-
- def _findVersesLoops(self) :
+ def _findVersesLoops(self, autoDetectChorus) :
"recherche des couplets / boucles"
verse = self.verses[0]
for note in self.notes[:-1] :
self.verses.append(verse)
verse.append(self.notes[-1])
+ if autoDetectChorus and len(self.verses) > 1 :
+ for i, verse in enumerate(self.verses) :
+ if len(verse[0].lyrics) == 1 :
+ self.chorus = self.verses.pop(i)
+ self.songStartsWithChorus = i==0
+ break
+
- def iterNotes(self, indefinitely=True) :
+ def iterNotes(self) :
"exécution de la chanson avec l'alternance couplets / refrains"
- if indefinitely == False :
- iterable = self.verses
- else :
- iterable = cycle(self.verses)
- for verse in iterable :
+ for verse in self.verses :
+ if self.songStartsWithChorus :
+ for note in self.chorus :
+ yield note, 0
+
#print "---partie---"
repeats = len(verse[0].lyrics)
if repeats > 1 :
else :
for note in verse :
yield note, 0
+
+ @property
+ def intervalsHistogram(self) :
+ histogram = {}
+ it = self.iterNotes()
+ previousNote = it.next()[0]
+ for note, _ in it :
+ interval = note.midi - previousNote.midi
+ if histogram.has_key(interval) :
+ histogram[interval] += 1
+ else :
+ histogram[interval] = 1
+ previousNote = note
+ return histogram
+
+ @property
+ def duration(self) :
+ 'Durée de référence du morceau en milisecondes'
+ it = self.iterNotes()
+ duration = 0
+ for note, verseIndex in it :
+ duration = duration + note.duration
+ duration = duration * self.quarterNoteDuration # en milisecondes
+ return duration
+
def pprint(self) :
for note, verseIndex in self.iterNotes(indefinitely=False) :
doc = d.documentElement
# TODO conversion préalable score-timewise -> score-partwise
- assert doc.nodeName == u'score-partwise'
+ if doc.nodeName != u'score-partwise' :
+ raise ValueError('not a musicxml file')
parts = doc.getElementsByTagName('part')
leadPart = parts[partIndex]
if len(args) != 1 :
raise SystemExit(op.format_help())
- musicXml2Song(args[0],
+ song = musicXml2Song(args[0],
partIndex=options.partIndex,
autoDetectChorus=options.autoDetectChorus,
printNotes=options.printNotes)
+ from pprint import pprint
+ pprint(song.intervalsHistogram)
+ print song.duration
if __name__ == '__main__' :