# -*- coding: ISO-8859-1 -*- """ capellaScript -- 16.01.2008 Hans H. Lampe >>> Ventilgriffe oder Posaunenzüge anzeigen (Version 2.8 - 28.02.2011)|| Mit diesem Skript werden die Griffe, bzw. Züge für die folgenden Blasinstrumente angezeigt: || Flügelhörner, Hörner, Kornetts, Tenorhörner, Trompeten, Ventilposaunen, Zugposaunen, Baritons, Euphoniums,|B-Tuben und Sandner Flöten.|| Wie in Posaunenchören üblich, wird auch die "klingende Notierung" von B-Instrumenten unterstützt.|| Bitte den Cursor für die automatische Zeilenwahl in die entsprechende Notenzeile setzen, oder die gewünschte Notenzeile im nachfolgenden Dialog wählen.|| Falls nur bestimmte Noten die Griff-, bzw. Zug-Angaben erhalten sollen, bitte diese vor Aufruf des Skripts markieren.|| Rückmeldungen bitte an Hans H. Lampe:|HansHermann.Lampe@t-online.de <<< Neu in V1.2: Strich für Wiederholung desselben Griffes, bzw. Zuges Neu in V1.3: Posaune mit Quartventil wird unterstützt zusätzliche Selektion), Töne außerhalb der Tonbereiche führen nicht mehr zu einer Python-Fehlermeldung, sondern werden "abgefangen" und angezeigt Töne oberhalb des jeweiligen Tonbereichs werden in rot, Töne unterhalb des jeweiligen Tonbereichs werden in blau dargestellt NEU in V1.4: Posaune: fis' auf Zug 3, g' auf 2, as' auf 1 und H auf Q2 (lt. eMail Fr. Ernst 20.02.08) Trompete: gis'' auf 1, a'' auf 2 und ais'' auf 0 (lt. eMail Fr. Ernst 20.02.08) NEU in V1.5: 11.04.08 tel. mit Herrn Singer: gis" = 23, a" = 12, b" = 1 Achtung zweite Zeile für Alternativgriffe eingeführt, z.B. 12\r\n(3) [eMail Prof. Ring 13.04.08] NEU in V1.6: Für "B-Instrument klingend notiert" noch die beiden tiefen Töne '52' und '53' eingeführt (Hinweis von Herrn Weisser, eMail 3.05.08) NEU in V2.0: Bariton (Bassschlüssel) unterstützt. (H. Blum, eMail 12.05.08) NEU in V2.1: Markierte Noten können exklusiv bezeichnet werden (H. Weisser, eMail 12.05.08) NEU in V2.2: Zusätzlich Posaune in B Violinschlüssel NEU in V2.3: Zusätzlich Posaune in B Violinschlüssel + Quartventil NEU in V2.4: Instrumente #4 und #5 um cis3 (85) erweitert (H.Baier, eMail 19.06.08) Die Instrumente "Euphonium" und "B-Tuba mit 4 Vent. BassSchl." wurden ergänzt (H. Weisser,eMail 24.06.08) NEU in V2.5: Integration der Es-Ventilfanfare (eMail Sinan Akman vom 14.10.08), Es-Tuba NEU in V2.6: Integration der B-Tuba klingend (eMail Dennis Scheilin 10.10.2010) und vorläufig Eingabe der Vorspieltransposition zur Kompensation der Vorspieltransposition im Mustersystem (Einfluss auf MIDI-Notennummern)) NEU in V2.7: Sandner Flöten (H. Betzing - Leiter eines Spielmannszuges, eMail 4.02.11) NEU in V2.8: Automatisches Ermitteln der Vorspiel-Transp. in Mustersystem. Veränderte MIDI-Notenwerte werden korrigiert """ ###################################################################### from caplib.capDOM import ScoreChange import xml.dom.minidom DOC = xml.dom.minidom.Document import tempfile, codecs activeScore().registerUndo("Ventilgriffe anzeigen") ######################################################################### # -------- Cursorzeile ermitteln --------- # staffList = activeScore().voiceList() staffIndex = 0 sel = curSelection() if sel <> 0: (sy,st,vo,no0) = sel[0] (sy1,st1,vo1,no1) = sel[1] # nur 'no1' wird verwendet system = activeScore().system(sy) staff = system.staff(st) # ------ Aktuellen Eintrag im Mustersystem bestimmen ------- # i = 0 for descr in staffList: if staff.index() == system.staffIndexFromDescr(descr): staffIndex = i i += 1 # -------- Typenliste -------- # typeList = ['transponierend notiert', # 0 'B-Instrument klingend notiert', # 1 'Posaune (Bassschlüssel)', # 2 ### (Bassschlüssel) ###### 'Posaune mit Quartventil (Q-V)', # 3 'Posaune in B ViolinSchlüssel', # 4 'Posaune in B ViolinSchl. (Q-V)', # 5 'Bariton (BassSchlüssel)', # 6 'Euphonium 4-Vent. (BassSchl.)', # 7 'B-Tuba 4-Ventile (BassSchl.)', # 8 'Es-Ventilfanfare', # 9 'Es-Tuba', #10 'B-Tuba klingend notiert', #11 'Sandner Flöte'] #12 # -------- Dialogbox --------- # labStaff1 = Label('Notenzeile des Instruments wählen (durch Cursorpositionierung automatisch vorgewählt)') selStaff = ComboBox(staffList, value = staffIndex, width = 24) labStaff2 = Label(' "Beschreibung" der Notenzeile im Mustersystem', width=38) selType = ComboBox(typeList, value=0, width=24) labType = Label(' Bitte Instrumententyp auswählen', width=12) note = Label('"transponierend notiert" schließt C-Instrumente - wie z.B.Trompete in C - mit ein') numberSize = Edit(' 8', width=2) labSize = Label(' Zifferngröße ') vertDist = Edit(' 7', width=2) labDist = Label(' vertikaler Abstand von der Notenzeile nach unten ("negative Werte" nach oben)') strich = CheckBox('gleichbleibende Griffe, bzw. Züge werden durch einen Strich dargestellt', value=1) markieren = Label('HINWEIS: Für markierte Noten werden Griffe, bzw. Züge exklusiv angezeigt') dlg = Dialog('Ventilgriffe oder Posaunenzüge anzeigen (Version 2.8)', VBox([ HBox([labStaff1]), (''), HBox([selStaff, labStaff2]), (''), HBox([selType, labType]), HBox([note]), (''), HBox([numberSize, labSize, vertDist, labDist]), (''), HBox([strich]), (''), HBox([markieren]), ('') ] ) ) # ------ Hauptprogramm ------ # def dlgRun(): global system, vo, no if dlg.run(): # Nach OK im Dialog transposeClass(tempInput) # Ermittlung der Vorspiel-Transposition aus dem Mustersystem # 0 = Trompete transponierend notiert, 1 = B-Instrument klingend notiert, 2 = Posaune, 3 = Posaune mit Quartventil types = {0:{54:'123',55:'13',56:'23',57:'12',58:'1',59:'2',60:'0',61:'123',62:'13',63:'23',64:'12',65:'1', 66:'2',67:'0',68:'23',69:'12',70:'1',71:'2',72:'0',73:'12',74:'1',75:'2',76:'0',77:'1',78:'2', 79:'0',80:'23',81:'12\r\n(3)',82:'1',83:'2',84:'0',85:'12',86:'1',87:'2',88:'0',89:'1'}, 1:{52:'123',53:'13',54:'23',55:'12',56:'1',57:'2',58:'0',59:'123',60:'13',61:'23',62:'12',63:'1', 64:'2',65:'0',66:'23',67:'12',68:'1',69:'2',70:'0',71:'12',72:'1',73:'2',74:'0',75:'1',76:'2', 77:'0',78:'23',79:'12\r\n(3)',80:'1',81:'2',82:'0',83:'12',84:'1',85:'2',86:'0',87:'1'}, 2:{40:'7',41:'6',42:'5',43:'4',44:'3',45:'2',46:'1',47:'7',48:'6',49:'5',50:'4',51:'3',52:'2',53:'1',54:'5',55:'4', 56:'3',57:'2',58:'1',59:'4',60:'3',61:'2',62:'1',63:'3',64:'2',65:'1',66:'3',67:'2',68:'1',69:'2',70:'1'}, 3:{35:'Q7',36:'Q6',37:'Q5',38:'Q4',39:'Q3',40:'Q2',41:'6',42:'5',43:'4',44:'3',45:'2',46:'1',47:'Q2',48:'6',49:'5',50:'4',51:'3', 52:'2',53:'1',54:'5',55:'4',56:'3',57:'2',58:'1',59:'4',60:'3',61:'2',62:'1',63:'3',64:'2',65:'1',66:'3',67:'2',68:'1',69:'2',70:'1'}, 4:{54:'7',55:'6',56:'5',57:'4',58:'3',59:'2',60:'1',61:'7',62:'6',63:'5',64:'4',65:'3',66:'2',67:'1\r\n(6)',68:'5',69:'4',70:'3', 71:'2',72:'1\r\n(5)',73:'4',74:'3',75:'2',76:'1\r\n(4)',77:'3',78:'2',79:'1\r\n(4)',80:'3',81:'2',82:'3',83:'2',84:'1',85:'2'}, 5:{47:'\r\n2',48:'\r\n1',49:'\r\n(nein)',50:'\r\nQ6',51:'\r\nQ5',52:'\r\nQ4',53:'\r\nQ3',54:'7\r\nQ2',55:'6\r\nQ1',56:'5',57:'4', 58:'3',59:'2',60:'1',61:'7',62:'6',63:'5',64:'4',65:'3',66:'2',67:'1\r\n(6)',68:'5',69:'4',70:'3',71:'2',72:'1\r\n(5)',73:'4', 74:'3',75:'2',76:'1\r\n(4)',77:'3',78:'2',79:'1\r\n(4)',80:'3',81:'2',82:'3',83:'2',84:'1',85:2}, 6:{40:'123\r\n(24)',41:'13',42:'23',43:'12\r\n(3)',44:'1',45:'2',46:'0',47:'123\r\n(24)',48:'13',49:'23',50:'12\r\n(3)',51:'1', 52:'2',53:'0',54:'23',55:'12\r\n(3)',56:'1',57:'2',58:'0',59:'12\r\n(3)',60:'1',61:'2',62:'0',63:'1',64:'2', 65:'0',66:'23',67:'12\r\n(3)',68:'1',69:'2',70:'0'}, 7:{34:'0',35:'4123',36:'413',37:'423',38:'412\r\n(43)',39:'41',40:'123\r\n(24)',41:'13\r\n(4)',42:'23',43:'12\r\n(3)',44:'1',45:'2', 46:'0',47:'123\r\n(24)',48:'13',49:'23',50:'12\r\n(3)',51:'1',52:'2',53:'0',54:'23',55:'12\r\n(3)',56:'1',57:'2',58:'0',59:'12\r\n(3)', 60:'1',61:'2',62:'0',63:'1',64:'2',65:'0',66:'23',67:'12\r\n(3)',68:'1',69:'2',70:'0'}, 8:{22:'0',23:'4123',24:'413',25:'423',26:'412',27:'41',28:'42',29:'4',30:'23',31:'12',32:'1',33:'2',34:'0',35:'42',36:'13\r\n(4)', 37:'23',38:'12',39:'1',40:'2',41:'0',42:'23',43:'12\r\n(3)',44:'1',45:'2',46:'0',47:'12',48:'1',49:'2',50:'0\r\n(12)',51:'1', 52:'2',53:'0',54:'23',55:'12',56:'1',57:'2',58:'0'}, 9:{53:'13',54:'23',55:'12',56:'1',57:'2',58:'0',59:'23',60:'12',61:'1',62:'2',63:'0',64:'12',65:'1', 66:'2',67:'0',68:'1',69:'2',70:'0',71:'1',72:'2',73:'0',74:'2',75:'0',76:'2',77:'1'}, 10:{33:'123\r\n(24)',34:'13',35:'23',36:'12\r\n(3)',37:'1',38:'2',39:'0',40:'123\r\n(24)',41:'13',42:'23',43:'12\r\n(3)',44:'1',45:'2', 46:'0',47:'23',48:'12\r\n(3)',49:'1',50:'2',51:'0',52:'12\r\n(3)',53:'1',54:'2',55:'0',56:'1',57:'2',58:'0',59:'23', 60:'12\r\n(3)',61:'1',62:'2',63:'0'}, 11:{28:'123\r\n(24)',29:'13\r\n(4)',30:'23',31:'12\r\n(3)',32:'1',33:'2',34:'0',35:'123\r\n(24)',36:'13\r\n(4)',37:'23',38:'12\r\n(3)',39:'1',40:'2', 41:'0',42:'23',43:'12\r\n(3)',44:'1',45:'2',46:'0',47:'12\r\n(3)',48:'1',49:'2',50:'0',51:'1',52:'2',53:'0',54:'23', 55:'12\r\n(3)',56:'1',57:'2',58:'0'}, 12:{62:'1\r\n2\r\n3\r\n4\r\n5\r\n6\r\n7',63:'1\r\n2\r\n3\r\n4\r\n5\r\n6',64:'1\r\n2\r\n3\r\n4\r\n5\r\n7',65:'1\r\n2\r\n3\r\n4\r\n6\r\n7', 66:'1\r\n2\r\n3\r\n5\r\n6\r\n7',67:'1\r\n2\r\n3',68:'1\r\n2\r\n4\r\n5\r\n6\r\n7',69:'1\r\n2',70:'1\r\n3\r\n4\r\n5\r\n6',71:'1',72:'2\r\n3', 73:'4\r\n5\r\n6',74:'2\r\n3\r\n4\r\n5\r\n6\r\n7',75:'2\r\n3\r\n4\r\n5\r\n6',76:'1\r\n2\r\n3\r\n4\r\n5',77:'1\r\n2\r\n3\r\n4\r\n6', 78:'1\r\n2\r\n3\r\n5\r\n6',79:'1\r\n2\r\n3',80:'1\r\n2\r\n4',81:'1\r\n2',82:'1\r\n3',83:'1',84:'1\r\n3\r\n4\r\n6',85:'4\r\n5\r\n6', 86:'2\r\n3',87:'2\r\n3\r\n4\r\n5',88:'1\r\n2\r\n5\r\n6',89:'1\r\n2\r\n4',90:'1\r\n2\r\n4\r\n5\r\n6\r\n7',91:'1\r\n3\r\n5\r\n6\r\n7',92:'3\r\n6'} } range = {0:(54,89),1:(52,87),2:(40,70),3:(35,70),4:(54,85),5:(47,85),6:(40,70),7:(34,70),8:(22,58),9:(53,77),10:(33,63),11:(28,58),12:(62,92)} # Tonumfäge der Instrumente number = {'x':0,'y':8,'font':{'height':8.0},'type':'text','content':''} font = number['font'] font['height'] = int(numberSize.value()) number['y'] = int(vertDist.value()) saveNumber = 'x' # zum Erkennen gleichbleibender Griffen, bzw. Zügen, die durch '-' dargestellt werden indOutRange = 0 # Ventilgriffe / Züge erzeugen #============================= for system in activeScore().systems(): for staff in system.staves(): if staff.index() <> system.staffIndexFromDescr(staffList[selStaff.value()]): continue # Aufsuchen der entsprechenden Notenzeile for obj in staff.noteObjs(): if obj.isChord(): if sel[0] != sel[1]: # Markierung vorhanden syIndex = system.index() stIndex = staff.index() if syIndex == sy and stIndex == st: objIndex = obj.index() if objIndex < no0 or no1 <= objIndex: # markierter Bereich zwischen 'no0' und 'no1'-1 continue head = obj.head(0) chrP = head.chromaticPitch() chrP = chrP-int(transpose) # Korrektur des MIDI-Notenwerts, der durch Vorspiel-Transp. verändert wird type = types[selType.value()] Bl = (Color.RGB(0,0,0)) # schwarz obj.setColor(Bl) try: # prüfen, ob Tonumfang des gewählten Instruments eingehalten ist number['content'] = type[chrP] font['weight'] = 0 # nicht fett except: # Tonumfang ist nicht eingehalten indOutRange = 1 saveNumber = 'x' # keinen Strich nach Note(n) außerhalb des Tonbereichs continue # Ablauf fortsetzen if strich.value(): # Striche sollen dargestellt werden if saveNumber == type[chrP]: # Griff, bzw. Zug bleibt gleich number['content'] = '-' saveNumber = type[chrP] # für den Vergleich zweier einander folgender gleicher Griffe/Züge obj.addDrawObj(number) # Anzeige des Griffes/Zuges oder Strichs else: # keine Markierung vorhanden head = obj.head(0) chrP = head.chromaticPitch() #messageBox('transpose',str(transpose)) chrP = chrP-int(transpose) # Korrektur des MIDI-Notenwerts, der durch Vorspiel-Transp. verändert wird type = types[selType.value()] Bl = (Color.RGB(0,0,0)) # schwarz obj.setColor(Bl) try: # prüfen, ob Tonumfang des gewählten Instruments eingehalten ist number['content'] = type[chrP] font['weight'] = 0 # nicht fett except: # Tonumfang ist nicht eingehalten indOutRange = 1 saveNumber = 'x' # keinen Strich nach Note(n) außerhalb des Tonbereichs continue # Ablauf fortsetzen if strich.value(): # Striche sollen dargestellt werden if saveNumber == type[chrP]: # Griff, bzw. Zug bleibt gleich number['content'] = '-' saveNumber = type[chrP] # für den Vergleich zweier einander folgender gleicher Griffe/Züge obj.addDrawObj(number) # Anzeige des Griffes/Zuges oder Strichs # ------ Einfärben der Noten außerhalb des Tonbereichs ------ # if indOutRange: for system in activeScore().systems(): for staff in system.staves(): if staff.index() <> system.staffIndexFromDescr(staffList[selStaff.value()]): continue # -------- Töne außerhalb des Tonumfangs werden rot, bzw. blau dargestellt -------- # R = (Color.RGB(255,0,0)) # rot = Note oberhalb des Tonumfang des gewählten Instruments B = (Color.RGB(0,0,255)) # blau = Note unterhalb des Tonumfang des gewählten Instruments for obj in staff.noteObjs(): if obj.isChord(): head = obj.head(0) chrP = head.chromaticPitch() pR = range[selType.value()] # PitchRange des gewählten Instruments pLow = pR[0] pHigh = pR[1] if (chrP < pLow): # Note liegt unterhalb des Tonbereich obj.setColor(B) elif (chrP > pHigh): # Note liegt oberhalb des Tonbereichs obj.setColor(R) continue messageBox('Note(n) außerhalb des Standardbereichs der gewählten Instrumentenart', "Diese Noten werden farbig dargestellt: blau unterhalb, bzw. rot oberhalb des Bereichs", img=3) class transposeClass(ScoreChange): # Ermitteln der Vorspiel-Transp. in Mustersystem def changeScore(self, score): global scriptAction, doc doc = score.parentNode transpose(score) def transpose(score): # Ermitteln der Vorspiel-Transp. in Mustersystem global transpose staffList = activeScore().voiceList() for staffLayout in score.getElementsByTagName('staffLayout'): description = staffLayout.getAttribute('description') if description == staffList[selStaff.value()]: break sound = staffLayout.getElementsByTagName('sound')[0] transpose = sound.getAttribute('transpose') # Ermitteln der Vorspiel-Transp. in Mustersystem if transpose == '': # kann fehlen - abprüfen transpose=0 tempInput = tempfile.mktemp('.capx') # für aktuelle aktive Partitur activeScore().write(tempInput) # Partitur einlesen dlgRun()