Autor Thema: Brauche Hilfe bei Funktion: Verkleinerung der Notenköpfe einer Stimme  (Gelesen 1714 mal)

flatfoot

  • Member
Erstmal hallo zusammen,

dies ist mein erster Post in diesem Forum. :)

Ich benutze Lilypond schon seit ein paar Jahren und habe bisher durch einfache Internetrecherche alles hinbekommen, was ich gebraucht habe.

Zwar habe ich auch Programmiererfahrung in diversen Sprachen, komme aber hier nicht weiter:
Ich brauche eine Funktion, die die Notenköpfe von Nebenstimmen, bzw. eben einer der Funktion übergebenen Stimme, verkleinert.

Mit
\tweak font-size #-3 cfunktioniert das einwandfrei für eine einzelne Note.

Im angehängten Codebeispiel findet ihr ein Halbwegs-Minmalbeispiel. Die kürzere Funktion funktioniert für einzelne Noten – aber dann kann ich auch den \tweak-Befehl direkt verwenden.

Kann mir irgendwer nen Tip geben, wie ich die rekursive Funktion zum Laufen bekomme bzw. wie ich es anderweitig hinbekomme?

Grüße,
flatfoot


\version "2.18.0-1"

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Funktion zum Verkleinern eines Notenkopfs
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
smallNoteHeadsOne = #(define-music-function (parser location myNotes )
(ly:music?)
#{
\tweak font-size #-3 $myNotes
#})
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Funktion zum Verkleinern der Notenköpfe einer Stimme – funktioniert nicht
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
smallNoteHeads = #(define-music-function (parser location myNotes )
(symbol-list?)
(if (null? myNotes)
;; issue an empty music expression
#{ #}
#{
% tweak size of the first grob type of the current list
\tweak font-size #-3 #(car myNotes)
% recursively call itself with the remainder
% of the current list.
\smallNoteHeads #(cdr myNotes)
#}))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



myVoiceOne = \relative c' {
g'8 fis e4 d d
}

myVoiceOneSmall = \relative c' {
\smallNoteHeadsOne g'8 \smallNoteHeadsOne fis \smallNoteHeadsOne e4 \smallNoteHeadsOne d \smallNoteHeadsOne d
}

myVoiceTwo = \relative c' {
e8 d c4 b a
}

myMel = \relative c' {
<<
{ \voiceTwo \myVoiceTwo }
\new Voice { \voiceOne \myVoiceOne }
>>
}

myMelTwo = \relative c' {
<<
{ \voiceTwo \myVoiceTwo }
\new Voice { \voiceOne \myVoiceOneSmall }
>>
}

myMelThree = \relative c' {
<<
{ \voiceTwo \myVoiceTwo }
\new Voice { \voiceOne \smallNoteHeads { \myVoiceOne } }
>>
}

\new Voice = "Verse" { \myMel }

\new Voice = "VerseTwo" { \myMelTwo }

\new Voice = "VerseThree" { \myMelThree }

Manuela

  • Member
Re: Brauche Hilfe bei Funktion: Verkleinerung der Notenköpfe einer Stimme
« Antwort #1 am: Dienstag, 9. August 2016, 21:45 »
Das kriege sogar ich hin  ;)

\new Voice
      \with { \override NoteHead.font-size = #-2 }

Ist zwar keine Funktion, aber so kannst du die ganze Stimme kleiner setzen.

HTH

fugenkomponist

  • Member
Re: Brauche Hilfe bei Funktion: Verkleinerung der Notenköpfe einer Stimme
« Antwort #2 am: Dienstag, 9. August 2016, 23:41 »
Du solltest dir grundsätzlich mal den Befehl \override und seine Umgebung anschauen (z. B. \once, \revert, \tweak, evtl. auch \temporary, \with und \layout { \context { … } } ). Ist oft einfach praktisch ;)

\version "2.18.2"

% in manchen Situationen \tweak und \once \override gleich:
{ b \tweak NoteHead.color #red b b }
{ b \once \override NoteHead.color = #red b b }

% in manchen Situationen verschieden:
% 1. nur h rot
{ <b a> <\tweak NoteHead.color #red b a> <b a> }
% 2. beide schwarz; warum? Ich *vermute*, dass tweak auf den EventChord
% (Akkord) geschmissen wird statt auf die enthaltenen NoteEvents
\displayMusic { <b a> \tweak NoteHead.color #red <b a> <b a> }
% 3. beide rot
{ <b a> \once \override NoteHead.color = #red <b a> <b a> }

% \override und \revert
{ b \override NoteHead.color = #red b b b
  \override NoteHead.color = #green b b b \revert NoteHead.color b }

% \temporary \override
{ b \override NoteHead.color = #red b b b
  \temporary \override NoteHead.color = #green b b b \revert NoteHead.color b }

% auf nen ganzen Kontext bezogen
\new Voice \with {
  \override NoteHead.color = #red
} { b b b b b b b b }
das letzte, folgende Beispiel muss in eine eigene Datei, weil sonst die Effekte der anderen Beispiele überschrieben werden.
\version "2.18.2"

% oder auf alle Kontexte des gleichen Types
\layout {
  \context {
    \Voice
    \override NoteHead.color = #red
  }
}
% folgender Code erstellt zwei Voices
<<
  { b b b b }
  \\
  { a a a a }
>>

flatfoot

  • Member
Re: Brauche Hilfe bei Funktion: Verkleinerung der Notenköpfe einer Stimme
« Antwort #3 am: Mittwoch, 10. August 2016, 14:08 »
Danke schonmal für eure Antworten. Bei dem von mir geposteten Minimalbeispiel funktioniert es mit \with { \overide …} auch. Allerdings teilen sich die Stimmen in den Stücken, die es eigentlich betrifft, immer einen Notenhals. Wenn man dann Notenköpfe einzelner Stimmen verkleinern möchte, kann man nicht mehr mit \override arbeiten, weil das dann den kompletten „Akkord“ betrifft.

So bin ich auf \tweak gekommen, das nun aber leider vor jede einzelne Note muss. Daher mein Ansatz mit der Funktion.

Habt ihr noch ne Idee?

Anbei mal ein entsprechendes Minimalbeispiel:

\version "2.18.0-1"

refMel = \relative c'' {

\numericTimeSignature

gis8 b |

\bar ".|:"

cis4 cis8 b gis4 r |

}

refMelZwei = \relative c' {

e8 gis | a4 a8 gis e4 r |
}

refMelDrei = \relative c' {

b8 e | e4 e8 e b4 r |
}


\new Voice = "Refrain" {
<<
\key e \major \partial 4
\refMel
\refMelZwei
\refMelDrei
>>
}


Manuela

  • Member
Re: Brauche Hilfe bei Funktion: Verkleinerung der Notenköpfe einer Stimme
« Antwort #4 am: Mittwoch, 10. August 2016, 14:38 »
Das kommt annähernd hin, sieht man davon ab, dass die kleineren Notenköpfe zu weit weg vom Notenhals sitzen:
\version "2.18.0-1"
refMel = \relative c'' {

\numericTimeSignature
\stemUp
gis8 b |

\bar ".|:"

cis4 cis8 b gis4 r |

}

refMelZwei = \relative c' {
\override NoteHead.font-size = #-2
e8 gis | a4 a8 gis e4 r |
}

refMelDrei = \relative c' {

b8 e | e4 e8 e b4 r |
}


\new Voice = "Refrain" {
<<
\key e \major \partial 4

\new Voice \refMel
\new Voice \with
{ \remove Stem_engraver
\remove Beam_engraver
}
\refMelZwei
\new Voice \with {
\remove Beam_engraver
} { \autoBeamOff \stemUp
\override Flag.transparent=##t
\refMelDrei }
>>

Dafür lässt sich sicher auch was finden.

harm6

  • Member
Re: Brauche Hilfe bei Funktion: Verkleinerung der Notenköpfe einer Stimme
« Antwort #5 am: Mittwoch, 10. August 2016, 14:56 »
Hallo flatfoot,

herzlich willkommen im Forum.

Wie wärs mit:

\version "2.18.0"

refMel = \relative c'' {
  \numericTimeSignature
  gis8 b |
  \bar ".|:"
  cis4 cis8 b gis4 r |
}

refMelZwei = \relative c' {
  e8 gis | a4 a8 gis e4 r |
}

refMelDrei = \relative c' {
  b8 e | e4 e8 e b4 r |
}

foo =
#(define-music-function (parser location mus) (ly:music?)
  (for-each
    (lambda (m)
      (ly:music-set-property! m 'tweaks
        (acons 'font-size -6 (ly:music-property m 'tweaks))))
    (extract-named-music mus 'NoteEvent))
  mus)

\new Voice = "Refrain" {
  <<
    \key e \major \partial 4
    \refMel
    \foo \refMelZwei
    \refMelDrei
  >>
}

Dein vorheriger Ansatz mit der music-function konnte nicht zum Ziel führen, da LilyPond die Musik nicht als simple symbol-list behandelt.

Das kann man gut sehen wenn man displayMusic vorschaltet. Im terminal erscheint dann für \displayMusic \refMelZwei

Zitat
(make-music
  'RelativeOctaveMusic
  'element
  (make-music
    'SequentialMusic
    'elements
    (list (make-music
            'NoteEvent
            'duration
            (ly:make-duration 3 0 1)
            'pitch
            (ly:make-pitch 0 2 0))
          (make-music
            'NoteEvent
            'pitch
            (ly:make-pitch 0 4 1/2)
            'duration
            (ly:make-duration 3 0 1))
          (make-music (quote BarCheck))
          (make-music
            'NoteEvent
            'duration
            (ly:make-duration 2 0 1)
            'pitch
            (ly:make-pitch 0 5 0))
          (make-music
            'NoteEvent
            'duration
            (ly:make-duration 3 0 1)
            'pitch
            (ly:make-pitch 0 5 0))
          (make-music
            'NoteEvent
            'pitch
            (ly:make-pitch 0 4 1/2)
            'duration
            (ly:make-duration 3 0 1))
          (make-music
            'NoteEvent
            'duration
            (ly:make-duration 2 0 1)
            'pitch
            (ly:make-pitch 0 2 0))
          (make-music
            'RestEvent
            'duration
            (ly:make-duration 2 0 1))
          (make-music (quote BarCheck)))))

D.h. die eigentlichen Noten sind in einer Liste (den 'elements), aber verschachtelt.
Man kann die 'elements natürlich auslesen, den tweak anwenden und alles wieder restaurieren. Das ginge auch rekursiv.

Aber wozu die Mühe, geht ja auch einfacher ;)

HTH,
  Harm

P.S.
\version "2.18.0-1" gibt mit neueren Versionen einen error aus:
error: Invalid version string "2.18.0-1"
muß \version "2.18.0" heißen.
Würd mich überraschen wenn
#(write-me "LilyPond-Version: " (lilypond-version))
wirklich "2.18.0-1" ausgäbe.

fugenkomponist

  • Member
Re: Brauche Hilfe bei Funktion: Verkleinerung der Notenköpfe einer Stimme
« Antwort #6 am: Mittwoch, 10. August 2016, 15:09 »
Ok, ich seh, harm war schneller; ich hätte fast exakt die gleiche Lösung und den Hinweis zu \version ;) Trotzdem gut, ich hab nämlich mit music-map und ner Abfrage auf (ly:music-property m 'name) gearbeitet und jetzt extract-named-music (und außerdem acons) kennengelernt.

Zu Manuelas Lösung noch ein Hinweis: Das kann schnell kaputt gehen, wenn sich Halsrichtungen ändern. Außerdem ist es suboptimal, die Fahnen (Flag) nur unsichtbar zu machen. Stattdessen sollte der stencil entfernt werden, sodass die Fahnen keinen Platz mehr verbrauchen.

Für \override Foo.transparent = ##t und \override Foo.stencil = ##f gibt es übrigens (auch in Version 2.18 schon) die Abkürzungen \hide Foo und \omit Foo. Die funktionieren auch mit \once und statt eines \reverts wie \revert Foo.transparent kann man \undo \hide Foo verwenden.

flatfoot

  • Member
Re: Brauche Hilfe bei Funktion: Verkleinerung der Notenköpfe einer Stimme
« Antwort #7 am: Mittwoch, 10. August 2016, 15:54 »
Wow, vielen, vielen Dank, harm6!

Darauf, dass die eigentlich Noten in der Liste verschachtelt sind, bin ich inzwischen auch gestoßen. Habe sogar schon irgendwo eine Funktion gefunden, die ich evtl. für meine Zwecke hätte umschreiben können, aber du warst schneller. ;)

Habe deine Funktion gerade in drei unterschiedlichen Szenarien, die bei mir immer wieder vorkommen getestet – läuft! Jetzt steckt sie in meinem include-File.

Mal sehen, wann ich hier mal jemandem helfen kann …