# -*- coding: ISO-8859-1 -*- """ capellaScript -- Bernd Jungmann >>> Wo bin ich Unterstützung für Blinde:|| Das Skript zeigt ein Fenster mit einem Edit-Feld, in dem die aktuelle Cursor-Position beschrieben ist. Diese Beschreibung kann über einen Screen-Reader auf der Braille-Zeile ausgegeben oder laut vorglesen werden. Version 3.1 BJ 26.11.08 Versetzungszeichen jetzt gefiltert nach Tonart, abschaltbar durch g_noRedundantAlters = False Version 3: BJ 15.11.08 Unterstützung für Englisch Version 2: Bernd Jungmann 30.9.08 Textausgabe modifiziert DrawObj in separaten Fenstern Version 1: Bernd Jungmann 25.9.08 <<< Where am I?

Support for blind users:

The script shows a window with an edit field containing a description of the note object at the cursor position. This description may be read aloud by a screen reader or routed to a Braille display.

Version 3.1 Bernd Jungmann 26.11.08

Wo bin ich?

Unterstützung für Blinde:

Das Skript zeigt ein Fenster mit einem Edit-Feld, in dem das Notenobjekt an der Cursor-Position beschrieben ist. Diese Beschreibung kann über einen Screen-Reader auf der Braille-Zeile ausgegeben oder laut vorglesen werden.

Version 3.1 Bernd Jungmann 26.11.08

""" # Vielen Dank an Loic Fejoz für seinen RTF-Parser Rtf2TxtAndFont # http://sourceforge.net/projects/pyrtflib # unterdrücke Vorzeichen, die zur aktuellen Tonart gehören # (d.h. Note wird angezeigt wie per Computertastatur eingegeben) g_noRedundantAlters = True translations = [('de', { 'myTitle': 'Wo bin ich?', 'rest': 'P', 'wholeMeasureRest': 'G', 'measure': 'T', 'object': 'O', 'voice': 'St', 'stave': 'Z', 'key': 'Tonart', 'system': 'Sy', 'barline': 'fester Taktstrich', 'clef': 'Schlüssel', 'meter': 'Metrum', 'slur': 'Bindebogen', 'notes': 'Noten', 'simpleText': 'Einfachtext', 'transpos': 'Transponierbar', 'guitar': 'Gitarrengriff', 'image': 'Bild', 'richText': 'Textfeld: ', 'line': 'Linie', 'rect': 'Rechteck', 'ellipse': 'Ellipse', 'wavy': 'Schlangenlinie', 'triplet': 'Triole', 'duplet': 'Duole', 'tuplet': 'Tole', 'decrescendo': 'Decrescendo', 'crescendo': 'Crescendo', 'noteLines': 'Notenlinien', 'polygon': 'Polygon', 'ending': 'Voltenklammer', 'number': 'Nummer', 'trill': 'Trillerschlange', 'group': 'Gruppe', 'Musiksymbol': 'Musiksymbol ', 'end': 'Ende'}), ("en", { 'myTitle': 'Where am I?', 'rest': 'R', 'wholeMeasureRest': 'W', 'measure': 'M', 'object': 'O', 'voice': 'V', 'stave': 'St', 'key': 'key', 'system': 'Sy', 'barline': 'fixed barline', 'clef': 'clef', 'meter': 'meter', 'slur': 'slur', 'notes': 'notes', 'simpleText': 'simple text', 'transpos': 'transposable', 'guitar': 'guitar diagram', 'image': 'image', 'richText': 'freeform text: ', 'line': 'line', 'rect': 'rectangle', 'ellipse': 'ellipse', 'wavy': 'wavy line', 'triplet': 'triplet', 'duplet': 'duplet', 'tuplet': 'tuplet', 'decrescendo': 'decrescendo', 'crescendo': 'crescendo', 'noteLines': 'note lines', 'polygon': 'polygon', 'ending': 'ending', 'number': 'number', 'trill': 'trill', 'group': 'group', 'Musiksymbol': 'music symbol ', 'end': 'end'})] setLanguages(translations) import time def gettime(duration): if duration == 0: return "" dots = 0 while duration.p > 1 and duration.q > 1: duration.p -= 1 duration.p /= 2 duration.q /= 2 dots +=1 time = str(duration.q) while dots > 0: time += "." dots -= 1 if duration.q == 1: time = tr('wholeMeasureRest') + str(duration) return time def barAndPos(as,pos): staff = as.system(pos[0]).staff(pos[1]) dm = staff.defaultMeter() voice = staff.voice(pos[2]) durationsum = Rational(0) measurecount = 1 for ob in voice.noteObjs(): if ob.index() >= pos[3]: break durationsum += ob.duration() if durationsum >= dm: measurecount += 1 durationsum -= dm if ob.subType() == ob.METER: dm = ob.meter() elif ob.subType() == ob.EXPL_BARLINE: durationsum = 0 measurecount += 1 return measurecount, durationsum def fromCapella3(capella3str): if capella3str == "f": return "forte" elif capella3str == "g": return "fortissimo" elif capella3str == "h": return "ffortissimo" elif capella3str == "j": return "mezzoforte" elif capella3str == "p": return "piano" elif capella3str == "q": return "pianissimo" elif capella3str == "r": return "ppianissimo" elif capella3str == "i": return "mezzopiano" elif capella3str == "s": return "sforzato" elif capella3str == "z": return "sforzato" elif capella3str == "{": return "forzato" elif capella3str == "|": return "fortepiano" return tr('Musiksymbol')+capella3str g_alterstring = {-1:"-", -2:"--",0:"", 1:"+",2:"++"} locale = getLocale() if locale == "de-DE": g_octaves = ["?","SK","KO","GR","KL","1","2","3","4","5","6"] g_notes = ["c","d","e","f","g","a","h"] else: g_octaves = ["?","0","1","2","3","4","5","6","7","8","9"] g_notes = ["c","d","e","f","g","a","b"] g_noteKeys = [(-6,2),(-4,4),(-2,6),(-7,1),(-5,3),(-3,5),(-1,7)] def pitchToString(dp, key): step, alter = dp iOctave = step / 7 iNote = step%7 if g_noRedundantAlters: low, high = g_noteKeys[iNote] if alter == 0: if key <= low: alterfiltered = 1 elif key >= high: alterfiltered = -1 else: alterfiltered = alter elif alter < 0: if key <= low: alterfiltered = 0 elif key >= high: alterfiltered = -2 else: alterfiltered = alter elif alter > 0: if key >= high: alterfiltered = 0 elif key <= low: alterfiltered = 2 else: alterfiltered = alter else: alterfiltered = alter notestring = g_octaves[iOctave] + g_alterstring[alterfiltered] + g_notes[iNote] return notestring if activeScore(): as = activeScore() vl = as.voiceList() sel = curSelection() start = sel[0] stop = sel[1] sysind, staffind, voiceind, objind = stop obj = cursorObj() pitches = [] bar, pos = barAndPos(as, stop) barstring = "%s%d+%s"%(tr('measure'),bar,str(pos)) nDrawObjs = 0 if obj: system = as.system(sysind) moment = obj.time() subtype = obj.subType() objstring = "?" timestring = gettime(obj.duration()) keystring = obj.curKey() if subtype == obj.CHORD: nDrawObjs = obj.nDrawObjs() nHeads = obj.nHeads() if nHeads > 1: objstring = "(" for i in range(nHeads): if i > 0: objstring += " " dp = obj.diatonicPitch(i) objstring += pitchToString(dp, keystring) + timestring pitches.append(obj.chromaticPitch(i)) objstring += ")" else: dp = obj.diatonicPitch(0) # objstring += " " + str(dp) objstring = pitchToString(dp, keystring) + timestring pitches.append(obj.chromaticPitch(0)) elif subtype == obj.REST: nDrawObjs = obj.nDrawObjs() objstring = "%s%s"%(tr('rest'),timestring) elif subtype == obj.EXPL_BARLINE: objstring = tr('barline') elif subtype == obj.CLEF: objstring = tr('clef') elif subtype == obj.METER: d = obj.meter() objstring = "%s %s"%(tr('meter'),str(d)) elif subtype == obj.KEY: voice = activeScore().system(stop[0]).staff(stop[1]).voice(stop[2]) if obj.index()+1 < voice.nNoteObjs(): obj1 = voice.noteObj(obj.index()+1) objstring = "%s %s"%(tr('key'),str(obj1.curKey())) else: objstring = tr('key') else: objstring = tr('end') voice = activeScore().system(stop[0]).staff(stop[1]).voice(stop[2]) if 0 < voice.nNoteObjs(): lastObj = voice.noteObj(voice.nNoteObjs()-1) moment = lastObj.time() + lastObj.duration().__float__() else: moment = 0.0 if stop[3] > 1: keystring = voice.noteObj(stop[3]-1).curKey() else: keystring = 0 if nDrawObjs > 0: drawObjString = "+%d"%nDrawObjs else: drawObjString = "" edit = Edit("%s %s %s%d%s %s%d %s%d %s%d %s%d"% (objstring, barstring, tr('object'),objind+1, drawObjString, tr('voice'), voiceind+1, tr('stave'), staffind+1, tr('key'), keystring, tr('system'),sysind+1), width=60) if nDrawObjs > 0: list = [edit] for i in range(nDrawObjs): d = obj.drawObj(i) if d["type"] == "slur": drawObjString = "%s %d %s"%(tr('slur'),d["noteRange"]+1, tr('notes')) elif d["type"] == "text": font = d["font"] if font["face"] == "capella3": drawObjString = fromCapella3(d["content"]) else: drawObjString = "%s: %s"%(tr('simpleText'),d["content"]) elif d["type"] == "transposable": drawObjString = tr('transpos') elif d["type"] == "guitar": drawObjString = tr('guitar') elif d["type"] == "metafile": drawObjString = tr('image') elif d["type"] == "richText": import Rtf2TxtAndFont TxtAndFonts = Rtf2TxtAndFont.getTxt(d["data"]) # messageBox("TxtAndFonts",str(TxtAndFonts)) drawObjString = tr('richText') for j in range(1,len(TxtAndFonts)): textchunk = TxtAndFonts[j] index = 0 # messageBox("textchunk",textchunk) for i in range(6): index = textchunk.find(";",index) + 1 drawObjString += textchunk[index:] elif d["type"] == "line": drawObjString = tr('line') elif d["type"] == "rectangle": drawObjString = tr('rect') elif d["type"] == "ellipse": drawObjString = tr('ellipse') elif d["type"] == "wavyLine": drawObjString = tr('wavy') elif d["type"] == "bracket": number = d["number"] if number == 3: oleStr = tr('triplet') elif number == 2: oleStr = tr('duplet') else: oleStr = "%d-%s"%(number,tr('tuplet')) drawObjString = "%s %d %s"%(oleStr, d["noteRange"]+1,tr('notes')) elif d["type"] == "wedge": try: if d["decrescendo"]: drawObjString = "%s %d %s"%(tr('decrescendo'),d["noteRange"]+1,tr('notes')) else: drawObjString = "%s %d %s"%(tr('crescendo'),d["noteRange"]+1,tr('notes')) except: drawObjString = "%s %d %s"%(tr('crescendo'),d["noteRange"]+1,tr('notes')) elif d["type"] == "notelines": drawObjString = tr('noteLines') elif d["type"] == "polygon": drawObjString = tr('polygon') elif d["type"] == "volta": messageBox("Volta", str(d)) drawObjString = "%s %s %d %d %s"%(tr('ending'),tr('number'), d["firstNumber"],d["noteRange"]+1,tr('notes')) elif d["type"] == "trill": drawObjString = tr('trill') elif d["type"] == "group": drawObjString = tr('group') editDraw = Edit(drawObjString, width=60) list.append(editDraw) vbox = VBox(list) else: vbox = VBox([edit]) dlg = Dialog(tr('myTitle'), vbox ) if dlg.run(): if len(pitches) > 0: MidiChan = 0 # nur 16 Midikanäle möglich MidiVolume = 127 # todo: aus Mustersystem holen for pitch in pitches: MidiOut.noteOn(MidiChan, pitch, MidiVolume) time.sleep(0.5) for pitch in pitches: MidiOut.noteOff(MidiChan, pitch)