Browse Source

Add Staccato and Tenuto to Lilypond output.

master
Nils 2 years ago
parent
commit
a5135c81fe
  1. 1
      CHANGELOG
  2. 32
      engine/items.py
  3. 5
      qtgui/items.py

1
CHANGELOG

@ -28,6 +28,7 @@ Add information label with order of blocks to Track Editor.
Fix lilypond tempo export. Also add option to Lilypond Properties to not print metronome markings. Fix lilypond tempo export. Also add option to Lilypond Properties to not print metronome markings.
Optional text description for tempo items like "allegro" Optional text description for tempo items like "allegro"
Add Slurs to Lilypond output. Add Slurs to Lilypond output.
Add Staccato and Tenuto to Lilypond output.
Dynamic signatures and ramps are now output to Lilypond as well Dynamic signatures and ramps are now output to Lilypond as well
Cleaner .ly export with more line breaks, comments and using more default ly instructions when available, instead of our custom generic-purpose scripts. Cleaner .ly export with more line breaks, comments and using more default ly instructions when available, instead of our custom generic-purpose scripts.
Settings menu to autoconnect metronome audio ports to system on startup. Default off. Settings menu to autoconnect metronome audio ports to system on startup. Default off.

32
engine/items.py

@ -576,22 +576,29 @@ class Duration(object):
else: else:
self.tuplet = (2,3) self.tuplet = (2,3)
lilypondDurationKeywords = {
D_TIE : "~",
D_STACCATO : "-.", #shorthand for \staccato
D_TENUTO : "--",
}
def lilypond(self, carryLilypondRanges): def lilypond(self, carryLilypondRanges):
"""Called by note.lilypond(carryLilypondRanges), See Item.lilypond for the general docstring. """Called by note.lilypond(carryLilypondRanges), See Item.lilypond for the general docstring.
returns a number as string.""" returns a number as string."""
if self.durationKeyword == D_TIE:
append = "~" if self.durationKeyword in Duration.lilypondDurationKeywords:
append = Duration.lilypondDurationKeywords[self.durationKeyword]
else: else:
append = "" append = ""
n = self.genericNumber n = self.genericNumber
if n == 0: if n == 0:
return "\\breve" + append return "\\breve" + self.dots*"." + append
elif n == -1: elif n == -1:
return "\\longa" + append return "\\longa" + self.dots*"." + append
elif n == -2: elif n == -2:
return "\\maxima" + append return "\\maxima" + self.dots*"." + append
else: else:
return str(n) + self.dots*"." + append return str(n) + self.dots*"." + append
@ -1774,7 +1781,8 @@ class Chord(Item):
slur = "" slur = ""
#Create lilypond durations # Check and create lilypond durations
# A staccato note counts as different than a non-staccato. If the whole chord is staccato -> True, mixed -> False
pitches, durations = zip(*(note.lilypond(carryLilypondRanges) for note in self.notelist)) pitches, durations = zip(*(note.lilypond(carryLilypondRanges) for note in self.notelist))
onlyOneDuration = durations.count(durations[0]) == len(durations) onlyOneDuration = durations.count(durations[0]) == len(durations)
@ -1810,9 +1818,17 @@ class Chord(Item):
assert int(ticks) == ticks, ticks assert int(ticks) == ticks, ticks
assert int(minimumTicksInChord) == minimumTicksInChord, minimumTicksInChord assert int(minimumTicksInChord) == minimumTicksInChord, minimumTicksInChord
assert minimumTicksInChord <= ticks assert minimumTicksInChord <= ticks
#Ties in pseudo polyphone will not lead to a ly-error. It will simply produce no tie output.
if lilydur.endswith("~"): if lilydur.endswith("~"):
lilydur = lilydur[:-1] #without ~ #TODO: not supported yet. logger.warning("We do not support ties in pseudo-polyphony. Lilypond will run, but not show the tie. Please use multiple tracks for such complex polyphony or let lilypond split and tie longer notes for you: " + " ".join(pitches) + " ".join(durations) )
dur = lilydur + " * {}/{}".format(int(minimumTicksInChord), int(ticks)) #lilypond requires the x/y syntax, even if it is 1/y #TODO: this is very ugly lilydur = lilydur[:-1] #without ~ and Duration Keywords. #TODO: not supported yet in mixed duration chords.
if int(minimumTicksInChord) == int(ticks): #This is correct and nicer, because it removes <e'>4 * 53760/53760 .
dur = lilydur #the test for 'onlyOneDuration' above failed because we have mixed tenuto, staccato etc. and not because the actual durations were different.
else:
dur = lilydur + " * {}/{}".format(int(minimumTicksInChord), int(ticks)) #lilypond requires the x/y syntax, even if it is 1/y #TODO: this is very ugly
substrings.append("\\\\ { <" + " ".join(lst) + ">" + dur + " }" ) substrings.append("\\\\ { <" + " ".join(lst) + ">" + dur + " }" )
tupletSubstring = _createLilypondTuplet(self.durationGroup, carryLilypondRanges) tupletSubstring = _createLilypondTuplet(self.durationGroup, carryLilypondRanges)

5
qtgui/items.py

@ -303,14 +303,13 @@ class GuiNote(QtWidgets.QGraphicsItem):
if noteExportObject["durationKeyword"]: if noteExportObject["durationKeyword"]:
self.durationKeywordGlyph = GuiNote.durationKeywords[noteExportObject["durationKeyword"]](noteExportObject) self.durationKeywordGlyph = GuiNote.durationKeywords[noteExportObject["durationKeyword"]](noteExportObject)
#width = self.noteHead.boundingRect().width() #1000 !? Weird svg. #width = self.noteHead.boundingRect().width()
#setPos is relative to noteHead. #setPos is relative to noteHead.
if directionRightAndUpwards: if directionRightAndUpwards:
#self.durationKeywordGlyph.setScale(-1) #doesn't work because center of rotation is somehwere at pixel 1000!!
self.durationKeywordGlyph.setPos(0, -1*constantsAndConfigs.stafflineGap) #x should be the width of the notehead. self.durationKeywordGlyph.setPos(0, -1*constantsAndConfigs.stafflineGap) #x should be the width of the notehead.
else: else:
self.durationKeywordGlyph.setPos(0, constantsAndConfigs.stafflineGap-1) self.durationKeywordGlyph.setPos(0, constantsAndConfigs.stafflineGap+2)
self.durationKeywordGlyph.setParentItem(self.noteHead) self.durationKeywordGlyph.setParentItem(self.noteHead)

Loading…
Cancel
Save