# -*- coding: ISO-8859-1 -*- """ capellaScript -- 27.12.2007 Hans H. Lampe >>> Konvertieren von Violine nach Viola und v.v. (Version 1.0 - 11.05.2008)|| Konvertieren der Notierung einer Violine in die einer Viola (Bratsche) und umgekehrt.|| Noten außerhalb des Tonumfangs des Zielinstruments werden farbig markiert und auf Wunsch automatisch oktaviert.|| Bitte den Cursor für die automatische Zeilenwahl in die entsprechende Notenzeile setzen, oder die gewünschte Notenzeile im nachfolgenden Dialog wählen.|| In dieser Version werden nur einstimmige Notenzeilen unterstützt.||| Rückmeldungen bitte an Hans H. Lampe:|HansHermann.Lampe@t-online.de <<< """ from caplib.capDOM import ScoreChange import xml.dom.minidom DOC = xml.dom.minidom.Document import tempfile, codecs def change(score): # ------ vom (fiktiven) C-Instrument zum Zielinstrument (T = Target) ------ # #===========================================================================# transposeTo = toInstr.value() # Position des "nach-Instruments" in der Tabelle Instrparam = fromCinstr[transposeTo] # Instrumentenparameter aus Tabelle lesen for system in score.getElementsByTagName('system'): for staff in system.getElementsByTagName('staff'): # Aufsuchen der selektierten Notenzeile layout = staff.getAttribute('layout') if layout != staffList[selStaff.value()]: continue transposeTo = toInstr.value() toInstrX = fromCinstr[transposeTo] clefType = toInstrX[1] # Schlüssel setzen #================= for staffLayout in score.getElementsByTagName('staffLayout'): # Setzen des Schlüssels im Mustersystem # description = staffLayout.getAttribute('description') if description != staffList[selStaff.value()]: continue notation = staffLayout.getElementsByTagName('notation')[0] notation.setAttribute('defaultClef',['treble','alto'][clefType]) for staff in score.getElementsByTagName('staff'): # Setzen des Schlüssels in der Partitur # layout = staff.getAttribute('layout') if layout != staffList[selStaff.value()]: continue clefSign = staff.getElementsByTagName('clefSign')[0] clefSign.setAttribute('clef',['treble','alto'][clefType]) def Octave(score): global indOktaviert # ------ Eventuelles Oktavieren der Noten außerhalb des Tonbereichs des Zielinstruments ------ # indOktaviert = 0 if oktavieren: # Noten außerhalb des Tonbereichs des Zielinstruments oktavieren? if indColor: indOktaviert = 1 for display in score.getElementsByTagName('display'): color = display.getAttribute('color') heads = display.parentNode.getElementsByTagName('head') noHeads = len(heads) #messageBox('stop',str(noHeads)) if heads != []: # nur bei 'head' weiter ('display' kommt auch in ganzen und Ganztakt-Pausen vor) headLow = display.parentNode.getElementsByTagName('head')[0] # unterster oder einziger Kopf pitchLow = headLow.getAttribute('pitch') if noHeads > 1: #mehr als ein Kopf (bei 2 = Doppelgriff) headHigh = display.parentNode.getElementsByTagName('head')[noHeads-1] # der höchsteKopf pitchHigh = headHigh.getAttribute('pitch') if color == 'FF0000': # rot (oben außerhalb des Tonbereichs) headHigh.setAttribute('pitch', pitchHigh[0]+str(int(pitchHigh[1])-1)) if color == '0000FF': # blau (unten außerhalb des Tonbereichs) headHigh.setAttribute('pitch',pitchHigh[0]+str(int(pitchHigh[1])+1)) if color == 'FF0000': # rot (oben außerhalb des Tonbereichs) headLow.setAttribute('pitch', pitchLow[0]+str(int(pitchLow[1])-1)) if color == '0000FF': # blau (unten außerhalb des Tonbereichs) headLow.setAttribute('pitch',pitchLow[0]+str(int(pitchLow[1])+1)) class changeClass(ScoreChange): def changeScore(self, score): global scriptAction, doc doc = score.parentNode change(score) class OctaveClass(ScoreChange): def changeScore(self, score): global scriptAction, doc doc = score.parentNode Octave(score) # -------- Unterstützte Instrumente --------- # instrList = ['Instrument auswählen', #--00--# Default-Eintrag 'Violine', #--01--# 'Viola (Bratsche)' #--02--# ] # -------- toCinstr = {0:[9], # 1:[0], # 2:[0], # } # -------- V = 0 # Violinschlüssel A = 1 # Bratschenschlüssel fromCinstr = {0:[9,0], # vom fixtiven C-Instrument 1:[0,V], # 2:[0,A], # } # --------- Tonumfänge der Instrumente ---------- # pRt = {0:(00,00), # PitchRange-Table 1:(55,96), # Violine: g-c4 (d5, Flageolett) 2:(48,84), # Viola : c-c3 (e4, Flageolett) } active = 0 # zum Steuern der Schlussanzeige staffList = activeScore().voiceList() staffIndex = 0 sel = curSelection() if sel <> 0: (sy,st,vo,no) = sel[0] 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 # -------- Dialogbox --------- # labStaff1 = Label(' Notenzeile des Instruments (durch Positionierung des Cursors wurde diese vorbestimmt)') selStaff = ComboBox(staffList, value=staffIndex, width=20) labStaff2 = Label(' "Beschreibung" der Notenzeile im capella-Mustersystem') fromLab = Label(' von Instrument -------------------------->') fromInstr = ComboBox(instrList, value=0, width=18) toLab = Label('nach Instrument', width=21) toInstr = ComboBox(instrList, value=0, width=18) oktavieren = CheckBox('Noten außerhalb des Tonbereichs werden oktaviert', value=0 ) nullLab = Label('') Hinweis1a = Label('HINWEISE: - Falls nur der Tonumfang eines Instruments überprüft und/oder die Noten außerhalb seines Tonbereichs') Hinweis1b = Label(' oktaviert werden sollen, bitte das entsprechende Instrument in beiden Feldern auswählen.') Hinweis2a = Label(' - Falls bei Doppelgriffen nur eine der beiden Noten außerhalb des Tonbereiches liegen sollte,') Hinweis2b = Label(' werden trotzdem beide farbig markiert und ggf. auch beide oktaviert.') dlg = Dialog('Konvertieren von Violine nach Viola und umgekehrt (Version 1.0)', VBox([ HBox([labStaff1]), (''), HBox([selStaff, labStaff2]), (''), HBox([fromLab, toLab], padding = 5), (''), HBox([fromInstr, toInstr, oktavieren],padding = 32), (''), HBox([Hinweis1a]), HBox([Hinweis1b]), HBox([Hinweis2a]), HBox([Hinweis2b]), ('') ] ) ) def dlgRun(): global active, transposeOctave, entfVorz, maxVorz, max6Vorz if dlg.run(): active = 1 # nicht ganz klar - siehe unten transposeFrom = fromInstr.value() transposeTo = toInstr.value() Instr = toCinstr[transposeFrom] Instr = Instr[0] if Instr == 9: messageBox('Bitte das "von Instrument" auswählen', str('Bitte auch die entsprechende Notenzeile auswählen')) dlgRun() return # darf hier anschließend nicht weiterlaufen Instr = fromCinstr[transposeTo] Instr = Instr[0] if Instr == 9: messageBox('Bitte das "nach Instrument" auswählen', str('Bitte auch die entsprechende Notenzeile auswählen')) dlgRun() return # darf hier anschließend nicht weiterlaufen activeScore().registerUndo("Instrumente transponieren") # an dieser Stelle??????????? dlgRun() if active == 1: # keine Schlussanzeige bei 'Abbrechen' #### nicht ganz klar !!!!!!!!!! oktavieren = oktavieren.value() if activeScore(): activeScore().registerUndo("Instrumente transponieren") tempInput = tempfile.mktemp('.capx') # für aktuelle aktive Partitur # tempOutput = tempfile.mktemp('.capx') activeScore().write(tempInput) # Einlesen der aktiven Partitur changeClass(tempInput, tempOutput) # Transposition durchführen activeScore().read(tempOutput) # Ergebnis als aktive Partitur zurück # ------ Überprüfen des Tonumfangs ---- # indColor = 0 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 dargestellt -------- # # Alle Noten werden zuerst auf schwarz gesetzt Bl = (Color.RGB(0,0,0)) # schwarz for obj in staff.noteObjs(): # alle Noten auf schwarz setzen if obj.isChord(): obj.setColor(Bl) trTo = toInstr.value() #transposeTo R = (Color.RGB(255,0,0)) # rot B = (Color.RGB(0,0,255)) # blau for obj in staff.noteObjs(): if obj.isChord(): noHeads = obj.nHeads() # Anzahl der Köpfe headLow = obj.head(0) # der unterste Kopf chrPlow = headLow.chromaticPitch() chrPhigh = headLow.chromaticPitch() #messageBox('stop',str(chrPlow)) pR = pRt[trTo] # PitchRange pLow = pR[0] pHigh = pR[1] if noHeads > 1: headHigh = obj.head(noHeads-1) chrPhigh = headHigh.chromaticPitch() #messageBox('stop',str(chrPhigh)) if (chrPlow < pLow):# or (chrP > pHigh): # !!! durch "setColor" z.B 'b' -> # !!! obj.setColor(B) indColor = 1 elif (chrPhigh > pHigh):# obj.setColor(R) indColor = 1 else: obj.setColor(Bl) # wenn farbige Noten durch Oktavierung wieder zu schwarzen werden müssen # Setzen der Vorspiel-Transposition und eventuelles Oktavieren der Noten außerhalb des Tonbereichs des Zielinstruments #===================================================================================================================== activeScore().write(tempInput) # Partitur wieder einlesen OctaveClass(tempInput, tempOutput) # Funktions-Aufruf activeScore().read(tempOutput) # Ergebnis als aktive Partitur zurück # -------- Schluss-Anzeige --------- # Instrument = instrList[toInstr.value()] staff = staffList[selStaff.value()] if indColor == 1: if indOktaviert == 0: messageBox('Achtung: Der Standard-Tonumfang für >'+str(Instrument)+'< wurde nicht eingehalten!', ' Die >farbigen Noten< liegen außerhalb des Standard-Tonbereichs von >'+str(Instrument)+'<') else: messageBox('Achtung: Der Standard-Tonumfang für >'+str(Instrument)+'< wurde nicht eingehalten!', 'Die >farbigen Noten< lagen außerhalb des Standard-Tonbereichs von >'+str(Instrument)+'< und wurden auf Wunsch oktaviert') else: messageBox(' Alle Noten von >'+Instrument+'< liegen im Standard-Tonumfang', str( 'geprüft wurde in den Notenzeilen >'+staff+'< ("Beschreibung" der Notenzeile im capella-Mustersystem)')) os.remove(tempInput) os.remove(tempOutput)