def resetState(self): self.lastNote = None self.lastMusicdata = TimestepSequence()
class AbstractFormatter(object): def __init__(self): self.lastNote = None self.lastMusicdata = None def resetState(self): self.lastNote = None self.lastMusicdata = TimestepSequence() # Abstract methods which can be overriden in concrete implementations def startOfScore(self, score): pass def whitespace(self, count=1, obj=None): self.addSymbol(u'⠀'*count, obj) def startOfPart(self, part): if part.name: self.addSymbol(part.name, part) self.whitespace() self.addSymbol(keySignature(part.key())+timeSignature(*part.time())) def endOfPart(self): self.addSymbol(endofmusic_symbol) def newLine(self): pass def newSystem(self, system): self.newLine() self.addSymbol(brailleNumber(system[0].num()) +u'⠤'+brailleNumber(system[-1].num()), system) def startOfStaff(self, staff): pass def startOfMeasure(self, measure): pass def addSymbol(self, symbol, obj=None): pass def measureElement(self, symbol, obj): self.addSymbol(symbol, obj) # Main entry-point of abstract algorithm def format(self, obj): getattr(self, 'format'+obj.__class__.__name__)(obj) def formatScore(self, score): self.startOfScore(score) for part in score: self.format(part) def formatPart(self, part): def layoutType(measure): return (measure.staves(), bool(measure.lyrics()), False) self.resetState() self.startOfPart(part) layouts = [(layout, list(i)) for layout, i in itertools.groupby(part, layoutType)] if len(layouts) > 1: index = 0 while index < len(layouts)-1: if layouts[index][0] == (1, False, False) and \ layouts[index+1][0] == (1, True, False): layouts[index+1] = (layouts[index+1][0], layouts[index][1]+layouts[index+1][1]) layouts.pop(index) elif layouts[index][0] == (1, True, False) and \ layouts[index+1][0] == (1, False, False): layouts[index] = (layouts[index][0], layouts[index][1]+layouts[index+1][1]) layouts.pop(index+1) else: index += 1 for layout, measures in layouts: self.processLayout(layout, measures) self.endOfPart() def processLayout(self, layout, measures): def groupBySystems(measures): system = [] for measure in measures: if measure.newSystem() and len(system): yield system system = [] system.append(measure) if len(system): yield system def groupByLyricLines(measure, width): system = [] for measure in measures: system.append(measure) if len(reduce(lambda x,y: x+y.lyrics(), system, "")) > width: if len(system) > 1: tmp = system.pop(-1) yield system system = [tmp] else: yield system system = [] if len(system): yield system staves, lyric, harmony = layout # Process various layout types individually if staves == 1 and not lyric and not harmony: for system in groupBySystems(measures): self.newSystem(system) for measure in system: self.startOfMeasure(measure) self.printBrailleForStaff(measure.staff(0)) elif staves == 2 and not lyric and not harmony: for system in groupBySystems(measures): self.newSystem(system) for staff in range(2): self.startOfStaff(staff) for i, measure in enumerate(system): self.startOfMeasure(measure) if i == 0: self.addSymbol(hand_symbols[staff], None) self.printBrailleForStaff(measure.staff(staff)) elif staves == 1 and lyric and not harmony: for system in groupByLyricLines(measures, self.width): self.newLine() [self.addSymbol(unicode(note.lyric), note) for measure in system for note in measure.musicdata.justNotes() if note.lyric] self.newLine() self.whitespace() for measure in system: self.startOfMeasure(measure) self.printBrailleForStaff(measure.staff(0)) else: raise TypeError("Unsupported layout (%d, %r, %r)" % (staves, lyric, harmony)) def printBrailleForStaff(self, musicdata): if musicdata.equalNotes(self.lastMusicdata): self.addSymbol(simile_symbol, musicdata) else: for v in range(musicdata.voices()): if self.lastMusicdata.voices() == musicdata.voices() and \ self.lastMusicdata.voice(v).equalNotes(musicdata.voice(v)): self.measureElement(simile_symbol, musicdata.voice(v)) else: self.printBrailleForVoice(musicdata.voice(v)) if v != musicdata.voices()-1: self.measureElement(voice_separation_symbol, None) self.lastNote = None if musicdata.voices()>1: self.lastNote = None self.lastMusicdata = musicdata def printBrailleForVoice(self, musicdata): for note in musicdata: self.measureElement( getattr(self, 'getBrailleFor%s'%note.__class__.__name__)(note), note) def getBrailleForNote(self, note): output = note2braille(note, self.lastNote) if note.pitch: self.lastNote=note if note.slursRight()>0 and note.slursRight()<4: output += slur_symbol return output def getBrailleForChord(self, chord): descending = chord.clef() == Clef('G') startNote=chord.note(0,descending) output = note2braille(startNote, self.lastNote) for first, interval, second in chord.iterintervals(descending): if second.accidental: output += accidental_symbols[second.accidental] if abs(interval) > 7: output += octave_symbols[second.pitch.octave+1] output += interval_symbols[((abs(interval)-1)%7)+1] if second.fingering is not None: if second.fingering >= 1: output += finger_symbols[second.fingering] self.lastNote = startNote return output
class AbstractFormatter(object): def __init__(self): self.lastNote = None self.lastMusicdata = None def resetState(self): self.lastNote = None self.lastMusicdata = TimestepSequence() # Abstract methods which can be overriden in concrete implementations def startOfScore(self, score): pass def whitespace(self, count=1, obj=None): self.addSymbol(u'⠀' * count, obj) def startOfPart(self, part): if part.name: self.addSymbol(part.name, part) self.whitespace() self.addSymbol(keySignature(part.key()) + timeSignature(*part.time())) def endOfPart(self): self.addSymbol(endofmusic_symbol) def newLine(self): pass def newSystem(self, system): self.newLine() self.addSymbol( brailleNumber(system[0].num()) + u'⠤' + brailleNumber(system[-1].num()), system) def startOfStaff(self, staff): pass def startOfMeasure(self, measure): pass def addSymbol(self, symbol, obj=None): pass def measureElement(self, symbol, obj): self.addSymbol(symbol, obj) # Main entry-point of abstract algorithm def format(self, obj): getattr(self, 'format' + obj.__class__.__name__)(obj) def formatScore(self, score): self.startOfScore(score) for part in score: self.format(part) def formatPart(self, part): def layoutType(measure): return (measure.staves(), bool(measure.lyrics()), False) self.resetState() self.startOfPart(part) layouts = [(layout, list(i)) for layout, i in itertools.groupby(part, layoutType)] if len(layouts) > 1: index = 0 while index < len(layouts) - 1: if layouts[index][0] == (1, False, False) and \ layouts[index+1][0] == (1, True, False): layouts[index + 1] = (layouts[index + 1][0], layouts[index][1] + layouts[index + 1][1]) layouts.pop(index) elif layouts[index][0] == (1, True, False) and \ layouts[index+1][0] == (1, False, False): layouts[index] = (layouts[index][0], layouts[index][1] + layouts[index + 1][1]) layouts.pop(index + 1) else: index += 1 for layout, measures in layouts: self.processLayout(layout, measures) self.endOfPart() def processLayout(self, layout, measures): def groupBySystems(measures): system = [] for measure in measures: if measure.newSystem() and len(system): yield system system = [] system.append(measure) if len(system): yield system def groupByLyricLines(measure, width): system = [] for measure in measures: system.append(measure) if len(reduce(lambda x, y: x + y.lyrics(), system, "")) > width: if len(system) > 1: tmp = system.pop(-1) yield system system = [tmp] else: yield system system = [] if len(system): yield system staves, lyric, harmony = layout # Process various layout types individually if staves == 1 and not lyric and not harmony: for system in groupBySystems(measures): self.newSystem(system) for measure in system: self.startOfMeasure(measure) self.printBrailleForStaff(measure.staff(0)) elif staves == 2 and not lyric and not harmony: for system in groupBySystems(measures): self.newSystem(system) for staff in range(2): self.startOfStaff(staff) for i, measure in enumerate(system): self.startOfMeasure(measure) if i == 0: self.addSymbol(hand_symbols[staff], None) self.printBrailleForStaff(measure.staff(staff)) elif staves == 1 and lyric and not harmony: for system in groupByLyricLines(measures, self.width): self.newLine() [ self.addSymbol(unicode(note.lyric), note) for measure in system for note in measure.musicdata.justNotes() if note.lyric ] self.newLine() self.whitespace() for measure in system: self.startOfMeasure(measure) self.printBrailleForStaff(measure.staff(0)) else: raise TypeError("Unsupported layout (%d, %r, %r)" % (staves, lyric, harmony)) def printBrailleForStaff(self, musicdata): if musicdata.equalNotes(self.lastMusicdata): self.addSymbol(simile_symbol, musicdata) else: for v in range(musicdata.voices()): if self.lastMusicdata.voices() == musicdata.voices() and \ self.lastMusicdata.voice(v).equalNotes(musicdata.voice(v)): self.measureElement(simile_symbol, musicdata.voice(v)) else: self.printBrailleForVoice(musicdata.voice(v)) if v != musicdata.voices() - 1: self.measureElement(voice_separation_symbol, None) self.lastNote = None if musicdata.voices() > 1: self.lastNote = None self.lastMusicdata = musicdata def printBrailleForVoice(self, musicdata): for note in musicdata: self.measureElement( getattr(self, 'getBrailleFor%s' % note.__class__.__name__)(note), note) def getBrailleForNote(self, note): output = note2braille(note, self.lastNote) if note.pitch: self.lastNote = note if note.slursRight() > 0 and note.slursRight() < 4: output += slur_symbol return output def getBrailleForChord(self, chord): descending = chord.clef() == Clef('G') startNote = chord.note(0, descending) output = note2braille(startNote, self.lastNote) for first, interval, second in chord.iterintervals(descending): if second.accidental: output += accidental_symbols[second.accidental] if abs(interval) > 7: output += octave_symbols[second.pitch.octave + 1] output += interval_symbols[((abs(interval) - 1) % 7) + 1] if second.fingering is not None: if second.fingering >= 1: output += finger_symbols[second.fingering] self.lastNote = startNote return output