lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Custom note names, or meta-score?


From: Aaron Hill
Subject: Re: Custom note names, or meta-score?
Date: Sat, 31 Jul 2021 13:42:46 -0700
User-agent: Roundcube Webmail/1.4.9

On 2021-07-31 10:43 am, Craig Comstock wrote:
So said another way, I’d like to write a meta-score like { aa4 aa2 aa
aa ab ab ab ac ac ca ca } and those note names relate to a set of
pitches determined maybe in another file (not code hopefully) so that
as the pitches are chosen/changed it is easy to regenerate the
score/parts.

The following (minimally-tested) proof-of-concept should get you pretty close to your goal:

%%%%
\version "2.22.0"

#(define generic-notes '())

defineGenericNote =
#(begin
  (define (note-event? arg)
   (and (ly:music? arg)
        (music-is-of-type? arg 'note-event)))
  (define-void-function (name music) (symbol? note-event?)
   (if (ly:assoc-get name generic-notes #f)
    (ly:input-warning (*location*)
     "note name ~s is already defined" name)
    (set! generic-notes (cons (cons name music) generic-notes)))))

registerGenericLanguage =
#(define-void-function () ()
  (define pitch-names
   (let ((len (length generic-notes)))
    (cons 'generic
     (map (lambda (n idx)
           ;; Encode index within alteration.
           (cons (car n) (ly:make-pitch 0 0 (/ idx len))))
      generic-notes (iota len)))))
  (set! language-pitch-names (cons pitch-names language-pitch-names)))

fixupGenericMusic =
#(define-music-function (music) (ly:music?)
  (define (fixup! m)
   (let* ((pitch (ly:music-property m 'pitch))
          (oct (ly:pitch-octave pitch))
          (alt (ly:pitch-alteration pitch))
          (idx (numerator alt))
          (note (cdr (list-ref generic-notes idx))))
    ;; Adjust pitch, applying octave transposition.
    (ly:music-set-property! m 'pitch
     (ly:pitch-transpose
      (ly:music-property note 'pitch)
      (ly:make-pitch oct 0 0)))
    ;; Merge articulations.
    (ly:music-set-property! m 'articulations
     (append (ly:music-property note 'articulations '())
             (ly:music-property m 'articulations '())))
    ;; Merge tweaks.
    (ly:music-set-property! m 'tweaks
     (append (ly:music-property note 'tweaks '())
             (ly:music-property m 'tweaks '())))))
  (map fixup! (extract-typed-music music 'note-event))
  music)

toplevel-music-functions =
#(cons fixupGenericMusic toplevel-music-functions)

% NOTE: Pitches here use the current \language setting.
\defineGenericNote qw d'
\defineGenericNote er d'-.
\defineGenericNote ty \tweak font-size -3 fis'

\registerGenericLanguage
\language "generic"

{ qw4 er2 ty8-> <qw' \tweak color red ty> }
%%%%

Each generic note name is mapped to a note event that specifies the desired pitch along with tweaks and articulations. Target pitches need not be unique.

As an implementation detail, a generic note is associated with a placeholder pitch with a special alteration value for looking up the reference note event. A top-level handler is installed that processes music to convert these temporary pitches into the correct ones while merging tweaks and articulations. As shown above with qw', the reference pitch can be shifted by octave as needed.

Chords mostly work, however certain articulations need to be applied to the chord-event rather than individual notes. Additional logic is needed to support chords fully, and it might be useful for generic note names to be chords as well.

Key signatures do not support the generic note names as they are processed before the top-level handler. For now, you would have to manually specify the pitch:

%%%%
\key #(ly:make-pitch 0 1 0) \major   %{ equiv. to \key d \major %}
%%%%

-- Aaron Hill

Attachment: note-name-articulations.cropped.png
Description: PNG image


reply via email to

[Prev in Thread] Current Thread [Next in Thread]