Created
December 15, 2023 19:56
-
-
Save TheConstructor/c58cf6a2f0e878e26cd6a0003534d59b to your computer and use it in GitHub Desktop.
Skript um Noten-Namen in Capella zu ergänzen
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: UTF-8 -*- | |
""" capellaScript -- 15.12.2023 Matthias Vill | |
>>> Bunte Notennamen einfügen | |
(Version 1.0 - 15.12.2023)||| | |
Mit diesem Skript werden die Notennamen der ausgewählten Notenzeile als Grafikobject eingefügt. | |
Zur leichteren Unterscheidung wird ein farbiger Rahmen hinter den Namen der Note gelegt.|| | |
Der Nutzer hat die Wahl zwischen transponierbaren Symbolen und Symbolen mit Oktaven-Bezeichnung.|| | |
Bitte den Cursor für die automatische Zeilenwahl in die entsprechende Notenzeile setzen, | |
oder die gewünschte Notenzeile im nachfolgenden Dialog wählen.|| | |
Es werden nur einstimmige Notenzeilen unterstützt.| | |
Bei mehrstimmigen Notenzeilen werden die Notennamen der obersten Stimme angezeigt.|| | |
Bei Akkorden wird der Name der untersten Note angezeigt.||| | |
Rückmeldungen bitte an Matthias Vill | |
<<< | |
NEU in Version 1.0: Erste Version basierend auf Notennamen-anzeigen.py von Hans H. Lampe | |
und chordSymbols.py von Hartmut Ring et. al. | |
""" | |
isUsingAutoPl = False | |
#if capVersion() >= (9, 0, 0): | |
# if activeScore(): | |
# if activeScore().isUsingAutoPlacement(): | |
# isUsingAutoPl = True | |
noteNames = { | |
0:('ceses','ces','c','cis','cisis'), | |
1:('deses','des','d','dis','disis'), | |
2:('eses', 'es', 'e','eis','eisis'), | |
3:('feses','fes','f','fis','fisis'), | |
4:('geses','ges','g','gis','gisis'), | |
5:('asas', 'as', 'a','ais','aisis'), | |
6:('heses','b', 'h','his','hisis'), | |
7:('Ceses','Ces','C','Cis','Cisis'), | |
8:('Deses','Des','D','Dis','Disis'), | |
9:('Eses', 'Es', 'E','Eis','Eisis'), | |
10:('Feses','Fes','F','Fis','Fisis'), | |
11:('Geses','Ges','G','Gis','Gisis'), | |
12:('Asas', 'As', 'A','Ais','Aisis'), | |
13:('Heses','B', 'H','His','Hisis'), | |
} | |
noteColors = { | |
0: (0x000000, 0x00FFFF), #c | |
1: (0xFFFFFF, 0xA03070), #d | |
2: (0x000000, 0x00C0FF), #e | |
3: (0x000000, 0xADCBF8), #f | |
4: (0xFFFFFF, 0x50B000), #g | |
5: (0xFFFFFF, 0x0000C0), #a | |
6: (0xFFFFFF, 0xC07000), #h | |
7: (0x000000, 0x00FFFF), #C | |
8: (0xFFFFFF, 0xA03070), #D | |
9: (0x000000, 0x00C0FF), #E | |
10: (0x000000, 0xADCBF8), #F | |
11: (0xFFFFFF, 0x50B000), #G | |
12: (0xFFFFFF, 0x0000C0), #A | |
13: (0xFFFFFF, 0xC07000), #H | |
} | |
# (pitch, alter) -> pitch: u.a. Index der Note oben - 7; alter: 1 -> b, 2 -> '', 3 -> # | |
quintenZirkel = [ | |
(3, 1), # Fes | |
(0, 1), # Ces | |
(4, 1), # Ges | |
(1, 1), # Des | |
(5, 1), # As | |
(2, 1), # Es | |
(6, 1), # B | |
(3, 2), # F | |
(0, 2), # C | |
(4, 2), # G | |
(1, 2), # D | |
(5, 2), # A | |
(2, 2), # E | |
(6, 2), # H | |
(3, 3), # Fis | |
(0, 3), # Cis | |
(4, 3), # Gis | |
(1, 3), # Dis | |
(5, 3), # Ais | |
(2, 3), # Eis | |
(6, 3) # His | |
] | |
# 0, 7, 14, 21, 28, 35, 42, 49, 56, 63 | |
octaves = ("3", "2", "1", "", "", "'", '"', "'''", '4', '5') | |
# -------- Cursorzeile ermitteln --------- # | |
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 | |
# ------------- Dialog ------------- # | |
labStaff1 = Label('Notenzeile des Instruments wählen (durch Cursorpositionierung automatisch vorgewählt)') | |
selStaff = ComboBox(staffList, value = staffIndex, width=23) | |
labStaff2 = Label(' "Beschreibung" der Notenzeile im Mustersystem', width=38) | |
numberSize = Edit(' 8', width=2) | |
labSize = Label(' Zeichengröße ') | |
vertDist = Edit('-5', width=2) | |
labDist = Label(' vertikaler Abstand von der Notenzeile nach oben ("negative Werte" nach unten)') | |
displOct = CheckBox('Sollen Oktavkennzeichnungen angezeigt werden?', value=0) | |
remark = Label('HINWEIS: Oktavkennzeichnungen deaktivieren die Transponierbarkeit der Texte!\r\n\r\nHINWEIS: Es wird jeweils nur der unterste Ton jedes Akords der obersten Stimme in der Notenzeile angegeben') | |
dlg = Dialog(' Bunte Notennamen (Version 1.0)', | |
VBox([ | |
HBox([labStaff1]), | |
(''), | |
HBox([selStaff, labStaff2]), | |
(''), | |
HBox([numberSize, labSize, vertDist, labDist]), | |
(''), | |
HBox([displOct]), | |
(''), | |
HBox([remark]), | |
('') | |
] | |
) | |
) | |
# ---------------------------------- # | |
from caplib.capDOM import ScoreChange | |
import tempfile, codecs | |
def displayNoteNames(score): | |
displOctaves = displOct.value() | |
for system in activeScore().systems(): | |
for staff in system.staves(): | |
if staff.index() != selStaff.value(): # suche die gewählte Notenzeile | |
continue | |
voice = staff.voice(0) # nur einstimmige Notenzeilen | |
for noteObj in voice.noteObjs(): | |
subType = noteObj.subType() | |
if subType != 1: # 1 = Chord | |
continue | |
else: # Chord | |
head = noteObj.head(0) | |
diatonic = head.diatonicPitch() | |
pitch = int(diatonic[0]) | |
alter = int(diatonic[1]) + 2 # Alteration - Vorzeichen | |
newDrawObject = None | |
if displOctaves: | |
octave = octaves[int(pitch / 7)] | |
pitch = (pitch % 7 + 7) if pitch < 28 else pitch % 7 | |
newDrawObject = CreateGroup(pitch, alter, octave) | |
else: | |
pitch = int(diatonic[0]) % 7 # Name des Stammtones | |
nRefNote = 0 | |
for (i, note) in enumerate(quintenZirkel): | |
if note[0] == pitch and note[1] == alter: | |
nRefNote = i - 8 | |
break | |
newDrawObject = CreateTransposable(nRefNote) | |
replacedDrawObject = False | |
# Rückwärts iterieren, damit wir nach dem Löschen eines Objekts nicht durcheinander kommen | |
for i in range(noteObj.nDrawObjs() - 1, -1, -1): | |
drawObject = noteObj.drawObj(i) | |
if drawObject.get('tag', None) == '118614-1': | |
if replacedDrawObject: | |
noteObj.deleteDrawObj(i) | |
else: | |
noteObj.replaceDrawObj(i, newDrawObject) | |
replacedDrawObject = True | |
if not replacedDrawObject: | |
noteObj.addDrawObj(newDrawObject) | |
def CreateTransposable(nRefNote): | |
objectList = [] | |
for note in quintenZirkel: | |
objectList.append(CreateGroup(note[0] + 7, note[1])) | |
if isUsingAutoPl: | |
return { | |
'type': 'transposable', | |
'nRefNote': nRefNote, | |
'items': objectList, | |
'tag': '118614-1', | |
'placement': 'auto', | |
'yPlacement': ("above" if int(vertDist.value()) >= 0 else "below"), | |
'placementHint': 'chordSymbol' | |
} | |
else: | |
return { | |
'type': 'transposable', | |
'nRefNote': nRefNote, | |
'items': objectList, | |
'tag': '118614-1' | |
} | |
def CreateGroup(pitch, alter, octave=''): | |
noteColor = noteColors[pitch] # Table-LookUp | |
noteName = noteNames[pitch] # Table-LookUp | |
textDrawObject = { | |
'type': 'text', | |
'x': 0, | |
'y': -int(vertDist.value()), | |
'font': { | |
'weight': 700, # fett | |
'height': int(numberSize.value()), | |
'color': noteColor[0] | |
}, | |
'content': noteName[alter]+octave, | |
'tag': '118614-1' | |
} | |
rectangleDrawObject = { | |
'type': 'rectangle', | |
'x1': -0.3, | |
'y1': -int(vertDist.value()) - 1.5, | |
'x2': 2.3, | |
'y2': -int(vertDist.value()) + 0.4, | |
'filled': True, | |
'fillColor': noteColor[1], | |
'lineWidth': 0, | |
'tag': '118614-1' | |
} | |
groupDrawObject = { | |
'type': 'group', | |
'items': [rectangleDrawObject, textDrawObject], | |
'tag': '118614-1' | |
} | |
return groupDrawObject | |
class displNoteNames(ScoreChange): | |
def changeScore(self, score): | |
global scriptAction, doc | |
doc = score.parentNode | |
displayNoteNames(score) | |
# ------ Hauptprogramm ------ # | |
activeScore().registerUndo("Notennamen anzeigen") | |
if dlg.run(): | |
if activeScore(): | |
activeScore().registerUndo("Notennamen anzeigen") | |
tempInput = tempfile.mktemp('.capx') # für aktuelle aktive Partitur # | |
tempOutput = tempfile.mktemp('.capx') | |
activeScore().write(tempInput) | |
displNoteNames(tempInput, tempOutput) # Notennamen anzeigen | |
os.remove(tempInput) | |
os.remove(tempOutput) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment