Allgemein > Fragen zu Funktionen
Verlängerungspunkt hinter dem Takstrich (HALB GELÖST)
harm6:
--- Zitat von: ingmar ---Leider hat die von dir, harm6, netterweise ausbaldoverte Lösung ein Problem, wenn die punktierte Note in einer anderen Oktav liegt; offenbar wird diese Oktavänderung dann für den Punkt ein zweites Mal angenommen, so dass wir anschließend in der falschen Oktav liegen.
--- Ende Zitat ---
Das grundlegende Problem welches hier getriggert wird ist: \relative vs \absolute
Ich schrieb bereits:
--- Zitat von: harm6 am Sonntag, 15. Februar 2015, 11:41 ---[...]
Darüberhinaus ist es im relative-modus schwieriger (manchmal unmöglich) mit Musikfunktionen ins Geschehen einzugreifen. Das sind aber in der Regel Spezialfälle, die erstmal kein Argument gegen \relative darstellen.
[...]
--- Ende Zitat ---
Hier ist es aber ein Problem (die Definition würde in \absolute tadellos funktioniert haben)!
Insoweit habe ich ein optionales Argument einfügt mit dem man zwischen \relative und \absolute umschalten kann.
--- Code: ---\version "2.18.2"
%\language "english"
SHIFTDOT =
#(define-music-function (parser location relative? music)
((boolean? #t) ly:music?)
"
Replaces a dotted note with a single main note and (a tied) single additional
note.
The Tie will be transparent.
The second note will appear as dot, without Stem, Flag, Beam, Articulations.
Barchecks should not be used.
Limitation: does not work for chords.
If \\absolute is used, @var{relative?} needs to be set @val{#f}
"
(let* ((duration (ly:music-property music 'duration))
(dot-count (if (ly:duration? duration)
(ly:duration-dot-count duration)
0)))
;; Apply it only if the note is a single-dotted note
(if (= dot-count 1)
(let* ((m-1 (ly:music-deep-copy music))
(m-2 (ly:music-deep-copy music))
(dur-log (ly:duration-log duration))
(first-dur (ly:make-duration dur-log))
(second-dur (ly:make-duration (+ dur-log 1))))
;; Defines a procedure to replace the given NoteHead with a dot.
(define (note-head->dot note-head)
(let* ((stencil (ly:grob-property note-head 'stencil))
(note-head-X-length
(interval-length (ly:stencil-extent stencil X)))
(dot (ly:font-get-glyph (ly:grob-default-font note-head)
"dots.dot"))
(dot-X-length (interval-length (ly:stencil-extent dot X)))
(staff-pos (ly:grob-property note-head 'staff-position))
(stem (ly:grob-object note-head 'stem))
(flag (ly:grob-object stem 'flag))
(accidental-grob (ly:grob-object note-head 'accidental-grob))
;; Get values for translating the dot-stencil to avoid putting
;; it on a staff-line.
;; Because ledger-lines will be removed, we return 0, if the
;; NoteHead is above or below the staff.
(dir (if (and (even? staff-pos)
(not (> staff-pos 5))
(not (< staff-pos -5)))
-2
0))
;; Calculate a value to center the dot with NoteHeads from
;; other voices
(x-offset (/ (- note-head-X-length dot-X-length) 2))
(new-note-stencil
(ly:stencil-translate-axis
(ly:stencil-aligned-to dot Y dir)
x-offset
X)))
;; No Stem, Flag or Accidental!
(if (not (null? stem))
(ly:grob-set-property! stem 'stencil point-stencil))
(if (not (null? flag))
(ly:grob-set-property! flag 'stencil point-stencil))
(if (not (null? accidental-grob))
(ly:grob-set-property! accidental-grob 'stencil point-stencil))
;; Replace the NoteHead with a centered dot
(ly:grob-set-property! note-head 'stencil new-note-stencil)))
;; Build the notes to insert, replacing the dotted one.
(ly:music-set-property! m-1 'duration first-dur)
(ly:music-set-property! m-2 'duration second-dur)
;; In order not to disturb midi we insert a Tie here, making it
;; tranparent later.
(let ((articulations (ly:music-property m-1 'articulations)))
(ly:music-set-property! m-1 'articulations
(append (list (make-music 'TieEvent))
articulations)))
;; No Beam!
;; Also, we don't want other elements in 'articulations of the second
;; note, let us replaces them.
(ly:music-set-property! m-2 'articulations
(list (make-music 'BeamForbidEvent)))
;; If \relative is used make sure to cause no other octavation
(if relative?
(let* ((m-1-pitch (ly:music-property music 'pitch))
(pitch-notename (ly:pitch-notename m-1-pitch))
(pitch-alteration (ly:pitch-alteration m-1-pitch))
;; create a pitch with alteration, name and
;; octave set to -1!
(p (ly:make-pitch -1 pitch-notename pitch-alteration)))
(ly:music-set-property! m-2 'pitch p)))
#{
\override Tie #'transparent = ##t
$m-1
\noBreak
\once \override NoteHead #'no-ledgers = ##t
\once \override NoteHead #'before-line-breaking = #note-head->dot
$m-2
#})
music)))
\relative c'' {
a4 gis a \SHIFTDOT f'4.
e8 f cis d2
}
\absolute {
a'4 gis' a' \SHIFTDOT ##f f''4.
e''8 f'' cis'' d''2
}
--- Ende Code ---
HTH,
Harm
P.S. Die "Indentation" meines von Dir zitierten Codes war total verbockt. Hat da irgendein mail-program oder viewer Mist gebaut?
P.P.S harm-wikia ist geschlossen für heute ;)
ingmar:
Soweit funktioniert das alles gut. Ich habe kein Problem damit, meine Quelldatein von \relative in absolute Angaben zu verwandeln, die Funktion kann sich also gerne auf relative Angaben verlassen.
Es ist aber ein weiterer Wunsch aufgekommen: Das zu automatisieren, also nicht vor die jeweilige Note davor schreiben zu müssen.
Also sowas:
MUSIC = {
c2 d2.
e4 f g4.
a8 bes a g2
f4. e8 f1.
d e
c1
}
\Shiftdot { \MUSIC } % hier würde bei allen punktierten Noten, die über den Taktstrich zeigen (Zeilen 1, 2, 4), der Punkt hinter diesen geschoben.
\Tiedot { \MUSIC } % hier würden bei den gleichen Noten der Punkt in den entsprechenden angehängten Notenwert verwandelt.
Wofür braucht man sowas? - für historische Notation, die man einmal nahe am Original, einmal für rhythmisch unsichere Laienmusiker ausgeben will.
Gruß,
--ingmar
harm6:
Hallo ingmar,
Tiedot gibts eigentlich schon:
--- Code: ---Tiedot =
\with {
\remove "Note_heads_engraver"
\consists "Completion_heads_engraver"
\remove "Rest_engraver"
\consists "Completion_rest_engraver"
}
MUSIC = {
c2 d2.
e4 f g4.
a8 bes a g2
f4. e8 f1.
d e
c1
}
\new Voice \MUSIC
\new Voice \Tiedot \MUSIC
--- Ende Code ---
Wenn ich Dich richtig verstehe sollen bei einer generalisierten Anwendung von SHIFTDOT nur die Noten deren Dauer in den nächsten Takt hineinragt verändert werden, nicht aber punktierte Noten innerhalb eines Taktes. Richtig?
Jede punktierte Note anzugehen wäre relative einfach, denke ich. Aber nur bestimmte, abhängig davon ob sie innerhalb des Taktes zu Ende sind? Mag sich als harte Nuss erweisen Ich denk mal drüber nach...
Gruß,
Harm
ingmar:
--- Zitat ---harm6: Tiedot gibts eigentlich schon: [...]
--- Ende Zitat ---
Ah, super! Als hätte ichs geahnt... - Kurzer Versuch:
--- Code: ---\version "2.18.2"
\language "english"
\score {
\new Staff \with {
instrumentName = "treble"
\remove "Note_heads_engraver"
\consists "Completion_heads_engraver"
\remove "Rest_engraver"
\consists "Completion_rest_engraver"
}
\relative c' {
b4. c8 d2.
e4 f e8 d
e8 f g2 fs4
g2 f1
e1
d4 e
f2 e
}
}
--- Ende Code ---
Leider werden im neuen Takt zwar Notenköpfe, aber keine Hälse gedruckt. Und im Fall der ganzen Note entsteht ein Artefakt; vielleicht wird auch hier ein gefüllter Notenkopf gedruckt und die ganze Note dann darüber.
Darüber hinaus hagelt es jede Menge Fehlermeldungen:
14:17: Warnung: der rhythmische Kopf gehört nicht zu einer rhythmischen Kolumne
b4. c8 d2.
Jeder Takt scheint doppelt so oft moniert zu werden, wie er Noten enthält - dieser erste dreimal als ganzer Takt, dann jede Note einzeln, mit praktisch identischer Fehlermeldung.
--- Zitat ---harm6: Wenn ich Dich richtig verstehe sollen bei einer generalisierten Anwendung von SHIFTDOT nur die Noten deren Dauer in den nächsten Takt hineinragt verändert werden, nicht aber punktierte Noten innerhalb eines Taktes. Richtig?
--- Ende Zitat ---
Ja, so hatte ich mir das vorgestellt. Aber wahrscheinlich ist zu dem Zeitpunkt, wo das entscheiden werden müsste, noch gar nicht klar, wo die Taktstriche liegen werden, richtig?
Danke, und Gruß,
--ingmar
mgd:
Hallo ingmar,
es funktioniert, wenn du das nicht auf Staff Level, sondern auf Voice Level anwendest:
--- Code: ---\version "2.18.2"
\language "english"
\score {
\new Staff \with {
instrumentName = "treble"
} <<
\new Voice \with {
\remove "Note_heads_engraver"
\consists "Completion_heads_engraver"
\remove "Rest_engraver"
\consists "Completion_rest_engraver"
}
\relative c' {
b4. c8 d2.
e4 f e8 d
e8 f g2 fs4
g2 f1
e1
d4 e
f2 e
}
>>
}
--- Ende Code ---
Ich habe es allerdings nicht mit 2.18.2, sondern mit 2.19.22 getestet. Da kommen übrigens weder bei deiner, noch bei obiger Fassung irgendwelche Warnungen.
Nachtrag:
Ich habe es inzwischen mit 2.18.2 getestet. Bei deiner Fassung bekomme ich dann Mengen an Warnungen. Obige Fassung funktioniert bei mir dann ohne Warnungen.
HTH,
Michael
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln