First off, further apologies for accidentally posting a follow-up via an
second email address.
Aaron, thanks for all of this. Helpful to have the demonstration of
column-formatted note names from pitches, along with evidence of
something called "note-name->markup"; maybe that's all I need if I stick
with ordinary letter note names.
And thanks especially for the crucial info that pitch-notename returns a
number, despite its name. Makes sense from a coding standpoint but the
name threw me, what with NoteNames seeming string-y. (Is there a list of
data types for parameters and returned values for the internal functions?)
Anyway with that in mind and with your helper functions added in, I have
my function working (here, it returns vanilla note name forms for
LilyPond notename numbers, but custom forms are now easy). Next I'll try
adding a loop to process the entire input, discarding non-pitch,
non-chord events and building up a corresponding string of note names.
Sticking with the way this function has been designed, getting note
names for transposed music would require first transposing the input
within the function or via another helper one, I guess, and then
processing the transposed music. David's displayLilyMusic-based function
would make unnecessary any code to handle transposition, but weeding out
all the non-notename characters from the string it produces would take
some work.
#(define (pitch->name pitch)
(vector-ref '#("C" "D" "E" "F" "G" "A" "B")
(ly:pitch-notename pitch)))
#(define (pitch->alteration pitch)
(assoc-get (ly:pitch-alteration pitch)
'((-1/2 . "b") (1/2 . "#") (-1 . "-double-flat") (1 . "-double-sharp")) ""))
notenamer =
#(define-scheme-function (pitchin)
(ly:music?)
(let* (
(note-datum (car (ly:music-property pitchin 'elements)))
(pitch-datum (ly:music-property note-datum 'pitch))
(out-notename (pitch->name pitch-datum))
(out-acc (pitch->alteration pitch-datum)))
#{\markup
\bold
\concat {$out-notename $out-acc }
#}
)
)
\notenamer {ees d b c g}
From: Aaron Hill
Subject: Re: Scheme function to return pitchnames as markup/text
Date: Tue, 19 Nov 2019 09:19:26 -0800
On 2019-11-19 6:05 am, Stephen Cummings wrote:
Am I missing a basic LilyPond command/directive--something built-in
that takes music as input and returns note names as text?
There is the NoteNames context, but its functionality is wrapped up in C++ code
and is not easily customizable.
%%%%
\version "2.19.83"
melody = \fixed c' { e8 fis g4 <f bes>2 }
<< \new NoteNames \melody \new Staff \melody >>
%%%%
Next, the logic behind ChordNames has a number of helper functions that are
used to compose the final markup for a given chord.
%%%%
\version "2.19.83"
\markup \column \override #'(word-space . 0.1) { #@(map
(lambda (pitch) (note-name->markup pitch #f))
(list #{ d, #} #{ ees #} #{ fisis' #})) }
%%%%
Finally, you can do it manually when you need to fully customize naming:
%%%%
\version "2.19.83"
#(define (pitch->name pitch)
(vector-ref '#("Do" "Re" "Mi" "Fa" "So" "La" "Ti")
(ly:pitch-notename pitch)))
#(define (pitch->alteration pitch)
(assoc-get (ly:pitch-alteration pitch)
'((-1/2 . "-flat") (1 . "-double-sharp")) ""))
\markup \column { #@(map
(lambda (pitch) #{ \markup \concat {
$(object->string pitch) ": "
$(pitch->name pitch) $(pitch->alteration pitch) } #})
(list #{ d, #} #{ ees #} #{ fisis' #})) }
%%%%
What is important to note is that ly:pitch-notename returns a number, not a
string. It is up to the caller to map that number into a suitable value within
the desired naming system.
-- Aaron Hill