Jump to content

Recitation tone: Difference between revisions

From LilyPond wiki
Recitation tones for modern chant
 
m Formatting to avoid overlong lines, adding categories
 
Line 1: Line 1:
A reciting note is sustained for several syllables.
A reciting note is sustained for several syllables.


Normally only the initial reciting tone is printed (and it's printed as a  
Normally only the initial reciting tone is printed (and it is printed as a  
half-note, whole-note, or breve) and the rest of the syllables are printed  
half-note, whole-note, or breve) and the rest of the syllables are printed  
without notes above them. However, if the number of syllables to be recited is  
without notes above them. However, if the number of syllables to be recited is  
long enough that a line break needs to occur within the recitation, then the  
long enough that a line break needs to occur within the recitation, then the  
reciting tone is repeated at the beginning of the new line. These definitions  
reciting tone is repeated at the beginning of the new line. These definitions  
enable this formatting.
enable this formatting.


Usage:
Usage:
    \recite 8 g'
The number is the number of syllables to be said on the reciting tone.  These syllables are entered as normal in \lyricmode.
The note is the pitch for the reciting tone.
    \recite g'
When there are no lyrics associated with the recitation tone (as, for example, when printing a psalm tone) then only the pitch of the reciting tone is specified.  This usage is for ensuring consistent appearance.


\recite 8 g'


The number is the number of syllables to be said on the reciting tone. These syllables are entered as normal in <code>\lyricmode</code>. The note is the pitch for the reciting tone.
\recite g'
When there are no lyrics associated with the recitation tone (as, for example, when printing a psalm tone) then only the pitch of the reciting tone is specified. This usage is for ensuring consistent appearance.


<lilypond version="2.24">
<lilypond version="2.24">
#(define (line-position grob)
#(define (line-position grob)
    "Returns position of @var{grob} in current system:
  "Return position of @var{grob} in current system:
    @code{'start}, if at first time-step
@code{'start}, if at first time-step;
    @code{'end}, if at last time-step
@code{'end}, if at last time-step;
    @code{'middle} otherwise
@code{'middle} otherwise."
    "
  (let* ((col (ly:item-get-column grob))
    (let* ((col (ly:item-get-column grob))
          (ln (ly:grob-object col 'left-neighbor))
            (ln (ly:grob-object col 'left-neighbor))
          (rn (ly:grob-object col 'right-neighbor))
            (rn (ly:grob-object col 'right-neighbor))
          (col-to-check-left (if (ly:grob? ln) ln col))
            (col-to-check-left (if (ly:grob? ln) ln col))
          (col-to-check-right (if (ly:grob? rn) rn col))
            (col-to-check-right (if (ly:grob? rn) rn col))
          (break-dir-left
            (break-dir-left
          (and
            (and
            (ly:grob-property col-to-check-left 'non-musical #f)
              (ly:grob-property col-to-check-left 'non-musical #f)
            (ly:item-break-dir col-to-check-left)))
              (ly:item-break-dir col-to-check-left)))
          (break-dir-right
            (break-dir-right
          (and
            (and
            (ly:grob-property col-to-check-right 'non-musical #f)
              (ly:grob-property col-to-check-right 'non-musical #f)
            (ly:item-break-dir col-to-check-right))))
              (ly:item-break-dir col-to-check-right))))
    (cond ((eqv? 1 break-dir-left) 'start)
        (cond ((eqv? 1 break-dir-left) 'start)
          ((eqv? -1 break-dir-right) 'end)
              ((eqv? -1 break-dir-right) 'end)
          (else 'middle))))
              (else 'middle))))


#(define (tranparent-at-line-position vctor)
#(define (tranparent-at-line-position vctor)
    (lambda (grob)
  (lambda (grob)
        "Relying on @code{line-position} select the relevant entry from @var{vctor}.
    "Relying on @code{line-position} select the relevant entry from
          Used to determine transparency,"
@var{vctor}. Used to determine transparency."
        (case (line-position grob)
    (case (line-position grob)
            ((end) (not (vector-ref vctor 0)))
      ((end) (not (vector-ref vctor 0)))
            ((middle) (not (vector-ref vctor 1)))
      ((middle) (not (vector-ref vctor 1)))
            ((start) (not (vector-ref vctor 2))))))
      ((start) (not (vector-ref vctor 2))))))


noteHeadBreakVisibility =
noteHeadBreakVisibility =
#(define-music-function (break-visibility)(vector?)
  #(define-music-function (break-visibility)(vector?)
     "Makes notes transparent relying on @var{break-visibility}.
     "Makes notes transparent relying on @var{break-visibility}.
      The list of objects to make transparent is taken from @code{hideNotes}."
The list of objects to make transparent is taken from @code{hideNotes}."
     #{
     #{
        \override NoteHead.transparent = #(tranparent-at-line-position break-visibility)
      \override NoteHead.transparent =
        \override Dots.transparent = #(tranparent-at-line-position break-visibility)
#(tranparent-at-line-position break-visibility)
        \override Accidental.transparent = #(tranparent-at-line-position break-visibility)
      \override Dots.transparent =
        \override Rest.transparent = #(tranparent-at-line-position break-visibility)
#(tranparent-at-line-position break-visibility)
        %stems are always hidden in chant
      \override Accidental.transparent =
        %we assume chants are not in a TabStaff and so don't need to hide TabNoteHeads
#(tranparent-at-line-position break-visibility)
        %ledger lines have to be taken care of in the layout block using delete-ledgers-for-transparent-note-heads
      \override Rest.transparent =
#(tranparent-at-line-position break-visibility)
      % Stems are always hidden in chant.
      % We assume chants are not in a TabStaff and so don't need to hide
      % TabNoteHeads.
      % Ledger lines have to be taken care of in the layout block using
      % delete-ledgers-for-transparent-note-heads.
     #})
     #})


#(define delete-ledgers-for-transparent-note-heads
#(define delete-ledgers-for-transparent-note-heads
    (lambda (grob)
  (lambda (grob)
        "Reads whether a @code{NoteHead} is transparent.
    "Reads whether a @code{NoteHead} is transparent.
          If so this @code{NoteHead} is removed from @code{'note-heads} from
If so this @code{NoteHead} is removed from @code{'note-heads} from
          @var{grob}, which is supposed to be @code{LedgerLineSpanner}.
@var{grob}, which is supposed to be @code{LedgerLineSpanner}.
          As a result ledgers are not printed for this @code{NoteHead}"
As a result ledgers are not printed for this @code{NoteHead}"
        (let* ((nhds-array (ly:grob-object grob 'note-heads))
    (let* ((nhds-array (ly:grob-object grob 'note-heads))
                (nhds-list
            (nhds-list
                (if (ly:grob-array? nhds-array)
            (if (ly:grob-array? nhds-array)
                    (ly:grob-array->list nhds-array)
                (ly:grob-array->list nhds-array)
                    '()))
                '()))
                ;; Relies on the transparent-property being done before
            ;; Relies on the transparent-property being done before
                ;; Staff.LedgerLineSpanner.after-line-breaking is executed.
            ;; Staff.LedgerLineSpanner.after-line-breaking is executed.
                ;; This is fragile ...
            ;; This is fragile ...
                (to-keep
            (to-keep
                (remove
            (remove
                  (lambda (nhd)
                      (ly:grob-property nhd 'transparent #f))
                  nhds-list)))
            ;; TODO find a better method to iterate over grob-arrays, similiar
            ;; to filter/remove etc for lists
            ;; For now rebuilt from scratch
            (set! (ly:grob-object grob 'note-heads)  '())
            (for-each
               (lambda (nhd)
               (lambda (nhd)
                  (ly:pointer-group-interface::add-grob grob 'note-heads nhd))
                (ly:grob-property nhd 'transparent #f))
              to-keep))))
              nhds-list)))
      ;; TODO find a better method to iterate over grob-arrays, similar
      ;; to filter/remove etc for lists.
      ;; For now rebuilt from scratch.
      (set! (ly:grob-object grob 'note-heads)  '())
      (for-each
        (lambda (nhd)
          (ly:pointer-group-interface::add-grob grob 'note-heads nhd))
        to-keep))))




\layout {
\layout {
    \context {
  \context {
        \Staff
    \Staff
        \override LedgerLineSpanner.after-line-breaking =
    \override LedgerLineSpanner.after-line-breaking =
        #delete-ledgers-for-transparent-note-heads
      #delete-ledgers-for-transparent-note-heads
    }
  }
}


}
recite =
  #(define-music-function (times note) ((index? 1) ly:music?)
    "Causes @code{note} to be set as a reciting note for @code{times}
syllables.  The value of @code{recite-duration} determines
how the recitation note looks: 1 is a half-note, 0 is a
whole note, and -1 is a breve.  Only the first occurance
of the recitation note and those which appear at the
beginning of a line are visible."
    (let* ((note2 (ly:music-deep-copy note))
    (recite-duration 0)
    (recite-multiplier (/ (expt 2 recite-duration) 4)))
      (if (eqv? times 1)
          (withMusicProperty
    'duration (ly:make-duration recite-duration) note)
          #{ #(withMusicProperty
'duration (ly:make-duration
  recite-duration 0 recite-multiplier) note)
            \noteHeadBreakVisibility #begin-of-line-visible
            \repeat unfold #(1- times) {
      #(withMusicProperty
'duration (ly:make-duration
    recite-duration 0 recite-multiplier) note2)
      \bar "" }
            \noteHeadBreakVisibility #all-visible
          #})))


recite = #(define-music-function (times note) ((index? 1) ly:music?)
              "Causes @code{note} to be set as a reciting note for @code{times}
              syllables.  The value of @code{recite-duration} determines
              how the recitation note looks: 1 is a half-note, 0 is a
              whole note, and -1 is a breve.  Only the first occurance
              of the recitation note and those which appear at the
              beginning of a line are visible."
              (let* ((note2 (ly:music-deep-copy note)) (recite-duration 0) (recite-multiplier (/ (expt 2 recite-duration) 4)))
                  (if (eqv? times 1)
                      (withMusicProperty 'duration (ly:make-duration recite-duration) note)
                      #{ #(withMusicProperty 'duration (ly:make-duration recite-duration 0 recite-multiplier) note)
                        \noteHeadBreakVisibility #begin-of-line-visible
                        \repeat unfold #(1- times) { #(withMusicProperty 'duration (ly:make-duration recite-duration 0 recite-multiplier) note2) \bar "" }
                        \noteHeadBreakVisibility #all-visible
                      #})))


% Examples starts here.
% Examples starts here.
Line 124: Line 140:


music = {
music = {
    \recite 6 g' d' f' g' \bar "|"
  \recite 6 g' d' f' g' \bar "|"
}
}


doxology_words = \lyricmode {
doxology_words = \lyricmode {
    Glory be to the Father and to the Son
  Glory be to the Father and to the Son
}
}


\new Staff
\new Staff
<<
<<
    \new Voice = "mel" {  
  \new Voice = "mel" {
        \cadenzaOn \global \music \bar "||"
    \cadenzaOn \global \music \bar "||"
        \music \bar "||"
    \music \bar "||"
        \music \bar "|."
    \music \bar "|."
    }
  }
    \new Lyrics \lyricsto "mel" {
  \new Lyrics \lyricsto "mel" {
        \doxology_words
    \doxology_words
        \doxology_words
    \doxology_words
        \doxology_words
    \doxology_words
    }
  }
>>
>>
</lilypond>


 
[[Category:Scheme]]
 
[[Category:Specific notation]]
</lilypond>
[[Category:Vocal music]]
[[Category:Snippet]]

Latest revision as of 06:32, 11 December 2025

A reciting note is sustained for several syllables.

Normally only the initial reciting tone is printed (and it is printed as a half-note, whole-note, or breve) and the rest of the syllables are printed without notes above them. However, if the number of syllables to be recited is long enough that a line break needs to occur within the recitation, then the reciting tone is repeated at the beginning of the new line. These definitions enable this formatting.

Usage:

\recite 8 g'

The number is the number of syllables to be said on the reciting tone. These syllables are entered as normal in \lyricmode. The note is the pitch for the reciting tone.

\recite g'

When there are no lyrics associated with the recitation tone (as, for example, when printing a psalm tone) then only the pitch of the reciting tone is specified. This usage is for ensuring consistent appearance.

\version "2.24"

#(define (line-position grob)
   "Return position of @var{grob} in current system:
@code{'start}, if at first time-step;
@code{'end}, if at last time-step;
@code{'middle} otherwise."
   (let* ((col (ly:item-get-column grob))
          (ln (ly:grob-object col 'left-neighbor))
          (rn (ly:grob-object col 'right-neighbor))
          (col-to-check-left (if (ly:grob? ln) ln col))
          (col-to-check-right (if (ly:grob? rn) rn col))
          (break-dir-left
           (and
            (ly:grob-property col-to-check-left 'non-musical #f)
            (ly:item-break-dir col-to-check-left)))
          (break-dir-right
           (and
            (ly:grob-property col-to-check-right 'non-musical #f)
            (ly:item-break-dir col-to-check-right))))
     (cond ((eqv? 1 break-dir-left) 'start)
           ((eqv? -1 break-dir-right) 'end)
           (else 'middle))))

#(define (tranparent-at-line-position vctor)
   (lambda (grob)
     "Relying on @code{line-position} select the relevant entry from
@var{vctor}.  Used to determine transparency."
     (case (line-position grob)
       ((end) (not (vector-ref vctor 0)))
       ((middle) (not (vector-ref vctor 1)))
       ((start) (not (vector-ref vctor 2))))))

noteHeadBreakVisibility =
  #(define-music-function (break-visibility)(vector?)
     "Makes notes transparent relying on @var{break-visibility}.
The list of objects to make transparent is taken from @code{hideNotes}."
     #{
       \override NoteHead.transparent =
	 #(tranparent-at-line-position break-visibility)
       \override Dots.transparent =
	 #(tranparent-at-line-position break-visibility)
       \override Accidental.transparent =
	 #(tranparent-at-line-position break-visibility)
       \override Rest.transparent =
	 #(tranparent-at-line-position break-visibility)
       % Stems are always hidden in chant.
       % We assume chants are not in a TabStaff and so don't need to hide
       % TabNoteHeads.
       % Ledger lines have to be taken care of in the layout block using
       % delete-ledgers-for-transparent-note-heads.
     #})

#(define delete-ledgers-for-transparent-note-heads
   (lambda (grob)
     "Reads whether a @code{NoteHead} is transparent.
If so this @code{NoteHead} is removed from @code{'note-heads} from
@var{grob}, which is supposed to be @code{LedgerLineSpanner}.
As a result ledgers are not printed for this @code{NoteHead}"
     (let* ((nhds-array (ly:grob-object grob 'note-heads))
            (nhds-list
             (if (ly:grob-array? nhds-array)
                 (ly:grob-array->list nhds-array)
                 '()))
            ;; Relies on the transparent-property being done before
            ;; Staff.LedgerLineSpanner.after-line-breaking is executed.
            ;; This is fragile ...
            (to-keep
             (remove
              (lambda (nhd)
                (ly:grob-property nhd 'transparent #f))
              nhds-list)))
       ;; TODO find a better method to iterate over grob-arrays, similar
       ;; to filter/remove etc for lists.
       ;; For now rebuilt from scratch.
       (set! (ly:grob-object grob 'note-heads)  '())
       (for-each
        (lambda (nhd)
          (ly:pointer-group-interface::add-grob grob 'note-heads nhd))
        to-keep))))


\layout {
  \context {
    \Staff
    \override LedgerLineSpanner.after-line-breaking =
      #delete-ledgers-for-transparent-note-heads
  }
}

recite =
  #(define-music-function (times note) ((index? 1) ly:music?)
     "Causes @code{note} to be set as a reciting note for @code{times}
syllables.  The value of @code{recite-duration} determines
how the recitation note looks: 1 is a half-note, 0 is a
whole note, and -1 is a breve.  Only the first occurance
of the recitation note and those which appear at the
beginning of a line are visible."
     (let* ((note2 (ly:music-deep-copy note))
	    (recite-duration 0)
	    (recite-multiplier (/ (expt 2 recite-duration) 4)))
       (if (eqv? times 1)
           (withMusicProperty
	    'duration (ly:make-duration recite-duration) note)
           #{ #(withMusicProperty
		'duration (ly:make-duration
			   recite-duration 0 recite-multiplier) note)
             \noteHeadBreakVisibility #begin-of-line-visible
             \repeat unfold #(1- times) {
	       #(withMusicProperty
		 'duration (ly:make-duration
			    recite-duration 0 recite-multiplier) note2)
	       \bar "" }
             \noteHeadBreakVisibility #all-visible
           #})))


% Examples starts here.
\language "english"

global = { \key c \major }

music = {
  \recite 6 g' d' f' g' \bar "|"
}

doxology_words = \lyricmode {
  Glory be to the Father and to the Son
}

\new Staff
<<
  \new Voice = "mel" {
    \cadenzaOn \global \music \bar "||"
    \music \bar "||"
    \music \bar "|."
  }
  \new Lyrics \lyricsto "mel" {
    \doxology_words
    \doxology_words
    \doxology_words
  }
>>