Re: Extracting pitch names from music
Just found the markup macro in the docs. Changing (ly:grob-set-property! grob 'text new-name) to (ly:grob-set-property! grob 'text (markup #:italic #:smaller new-name)) does what I'm looking for. Is this the right way to handle issues like this? By that question, I think I really mean Is there any downside to using Scheme to solve problems like this? Cheers, Mike On Thu, Dec 9, 2010 at 1:02 PM, Michael Ellis michael.f.el...@gmail.comwrote: Putting the \midi block inside a separate \score block solved the audio doubling issue. I could still use some suggestions regarding how to control the font properties of the NoteNames output. With lyrics, I can do things like \context { \Lyrics %% Pack stanzas a little closer vertically minimumVerticalExtent = #'(0 . 0) %% decrease lyric font size by 1 increment \override LyricText #'font-size = #-1 } Thanks, Mike On Tue, Dec 7, 2010 at 3:40 PM, Michael Ellis michael.f.el...@gmail.comwrote: Thanks Valentin, that's quite helpful. I ended up taking an approach you suggested in a previous posthttp://lists.gnu.org/archive/html/lilypond-user/2010-10/msg00687.htmlto this list. Using the NoteNames context with alternative note names seems to be doing pretty much everything I want. Here's a revised version of my script that works as desired: % Moveable Do as lyrics example % define solfege pitchnames pitchnames = #`( (do . ,(ly:make-pitch -1 0 NATURAL)) (re . ,(ly:make-pitch -1 1 NATURAL)) (mi . ,(ly:make-pitch -1 2 NATURAL)) ) #(ly:parser-set-note-names parser pitchnames) % Apparently, LilyPond reverts to dutch names when % using the NoteNames context. The following % workaround was posted by V. Villenave at % http://lists.gnu.org/archive/html/lilypond-user/2010-10/msg00687.html newnames = #`((c . do) (d . re) (e . mi)) myNoteNames = #(lambda (grob) (let* ((default-name (ly:grob-property grob 'text)) (new-name (assoc-get default-name newnames))) (ly:grob-set-property! grob 'text new-name) (ly:text-interface::print grob))) % compose as though in C major mynotes = \relative do' {\key do \major do2 re4( mi4) } % transpose to desired key melody = \transpose do mi { \mynotes } % Produce score with solfege names as lyrics \score { \new Voice = myVoice { \melody } \context NoteNames \with { \override NoteName #'stencil = #myNoteNames } { \mynotes } } \version 2.12.3 This approach seems to work ok with a larger example where I defined all the chromatic solfege names. The only issue I seem to be encountering in the larger example is an unintended doubling of voices on the midi output. Does the NoteNames engraver produce a midi stream by default? If so, how can I turn it off? My midi section looks like \midi { %% voodoo that lets us specify instrument in melody \context { \Staff \remove Staff_performer } \context { \Voice \consists Staff_performer } } Cheers, Mike On Tue, Dec 7, 2010 at 11:41 AM, Valentin Villenave valen...@villenave.net wrote: On Tue, Dec 7, 2010 at 4:35 PM, Michael Ellis michael.f.el...@gmail.com wrote: It seems to me that the best solution would be to use LilyPond's built-in Scheme interpreter to extract the pitch names while the file is being processed. I've made some attempts to use map with ly:note-pitchname, but so far no success. This is probably because I know squat about Scheme, especially as used in LilyPond scripts. Here's an attempt of a patch I recently made, that might give you some pointers: diff --git a/scm/chord-name.scm b/scm/chord-name.scm index 7f5909b..2853102 100644 --- a/scm/chord-name.scm +++ b/scm/chord-name.scm @@ -59,15 +59,38 @@ (make-hspace-markup (if (= alteration SHARP) 0.2 0.1)) +(define (note-names-vector alist) + Extract note names from a pitchnames ALIST. + (let ((name-ls '())) +(map (lambda (x) + (let* ((pitch (cdr x)) + (alteration (ly:pitch-alteration pitch))) +(if (eq? alteration 0) +(set! name-ls (cons + (string-capitalize (symbol-string (car x))) + name-ls) + alist) +(list-vector (reverse name-ls + -(define-public (note-name-markup pitch lowercase?) +(define-public (note-name-markup pitch lowercase? . input-language) Return pitch markup for PITCH. - (make-line-markup - (list -(make-simple-markup - (conditional-string-downcase - (vector-ref #(C D E F G A B) (ly:pitch-notename pitch)) - lowercase?)) -(accidental-markup (ly:pitch-alteration pitch) + (let* ((get-pitchnames (lambda (x) + (ly:assoc-get (string-symbol x) +
Re: Extracting pitch names from music
On Thu, Dec 9, 2010 at 7:02 PM, Michael Ellis michael.f.el...@gmail.com wrote: Putting the \midi block inside a separate \score block solved the audio doubling issue. I could still use some suggestions regarding how to control the font properties of the NoteNames output. With lyrics, I can do things like \context { \Lyrics %% Pack stanzas a little closer vertically minimumVerticalExtent = #'(0 . 0) %% decrease lyric font size by 1 increment \override LyricText #'font-size = #-1 } You should be able to do something similar with \context { \NoteNames \override NoteName #'foo = #bar } Just found the markup macro in the docs. Changing (ly:grob-set-property! grob 'text new-name) to (ly:grob-set-property! grob 'text (markup #:italic #:smaller new-name)) does what I'm looking for. Is this the right way to handle issues like this? By that question, I think I really mean Is there any downside to using Scheme to solve problems like this? Well, the downside is the need to use a Scheme function at all in the first place :-) But since you're using one anyway, you might as well fiddle with it to your liking. That being said, I hope I'll be able to fix the note names function soon, which may make things simpler (e.g. having the ability to choose your note-names language, etc.) Cheers, Valentin. ___ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Extracting pitch names from music
Putting the \midi block inside a separate \score block solved the audio doubling issue. I could still use some suggestions regarding how to control the font properties of the NoteNames output. With lyrics, I can do things like \context { \Lyrics %% Pack stanzas a little closer vertically minimumVerticalExtent = #'(0 . 0) %% decrease lyric font size by 1 increment \override LyricText #'font-size = #-1 } Thanks, Mike On Tue, Dec 7, 2010 at 3:40 PM, Michael Ellis michael.f.el...@gmail.comwrote: Thanks Valentin, that's quite helpful. I ended up taking an approach you suggested in a previous posthttp://lists.gnu.org/archive/html/lilypond-user/2010-10/msg00687.htmlto this list. Using the NoteNames context with alternative note names seems to be doing pretty much everything I want. Here's a revised version of my script that works as desired: % Moveable Do as lyrics example % define solfege pitchnames pitchnames = #`( (do . ,(ly:make-pitch -1 0 NATURAL)) (re . ,(ly:make-pitch -1 1 NATURAL)) (mi . ,(ly:make-pitch -1 2 NATURAL)) ) #(ly:parser-set-note-names parser pitchnames) % Apparently, LilyPond reverts to dutch names when % using the NoteNames context. The following % workaround was posted by V. Villenave at % http://lists.gnu.org/archive/html/lilypond-user/2010-10/msg00687.html newnames = #`((c . do) (d . re) (e . mi)) myNoteNames = #(lambda (grob) (let* ((default-name (ly:grob-property grob 'text)) (new-name (assoc-get default-name newnames))) (ly:grob-set-property! grob 'text new-name) (ly:text-interface::print grob))) % compose as though in C major mynotes = \relative do' {\key do \major do2 re4( mi4) } % transpose to desired key melody = \transpose do mi { \mynotes } % Produce score with solfege names as lyrics \score { \new Voice = myVoice { \melody } \context NoteNames \with { \override NoteName #'stencil = #myNoteNames } { \mynotes } } \version 2.12.3 This approach seems to work ok with a larger example where I defined all the chromatic solfege names. The only issue I seem to be encountering in the larger example is an unintended doubling of voices on the midi output. Does the NoteNames engraver produce a midi stream by default? If so, how can I turn it off? My midi section looks like \midi { %% voodoo that lets us specify instrument in melody \context { \Staff \remove Staff_performer } \context { \Voice \consists Staff_performer } } Cheers, Mike On Tue, Dec 7, 2010 at 11:41 AM, Valentin Villenave valen...@villenave.net wrote: On Tue, Dec 7, 2010 at 4:35 PM, Michael Ellis michael.f.el...@gmail.com wrote: It seems to me that the best solution would be to use LilyPond's built-in Scheme interpreter to extract the pitch names while the file is being processed. I've made some attempts to use map with ly:note-pitchname, but so far no success. This is probably because I know squat about Scheme, especially as used in LilyPond scripts. Here's an attempt of a patch I recently made, that might give you some pointers: diff --git a/scm/chord-name.scm b/scm/chord-name.scm index 7f5909b..2853102 100644 --- a/scm/chord-name.scm +++ b/scm/chord-name.scm @@ -59,15 +59,38 @@ (make-hspace-markup (if (= alteration SHARP) 0.2 0.1)) +(define (note-names-vector alist) + Extract note names from a pitchnames ALIST. + (let ((name-ls '())) +(map (lambda (x) + (let* ((pitch (cdr x)) + (alteration (ly:pitch-alteration pitch))) +(if (eq? alteration 0) +(set! name-ls (cons + (string-capitalize (symbol-string (car x))) + name-ls) + alist) +(list-vector (reverse name-ls + -(define-public (note-name-markup pitch lowercase?) +(define-public (note-name-markup pitch lowercase? . input-language) Return pitch markup for PITCH. - (make-line-markup - (list -(make-simple-markup - (conditional-string-downcase - (vector-ref #(C D E F G A B) (ly:pitch-notename pitch)) - lowercase?)) -(accidental-markup (ly:pitch-alteration pitch) + (let* ((get-pitchnames (lambda (x) + (ly:assoc-get (string-symbol x) +language-pitch-names))) +(alist (get-pitchnames default-language))) +(if input-language + (cond ((string? input-language) + (set! alist (get-pitchnames input-language))) + ((boolean? input-language)) + (set! alist pitchnames))) +(make-line-markup + (list + (make-simple-markup + (conditional-string-downcase + (vector-ref (note-names-vector alist) +
Extracting pitch names from music
I use LilyPond to create practice scores and etudes. I've figured out how to allow note entry in Moveable Do solfege notation and have a template (see below) that supports displaying the solfege symbols as lyrics beneath the notes. At present, I have to manually extract the lyrics from the notation plus markup that generates the music. I've been able to partially automate this with some python and vim code (not shown here), but it is still somewhat unsatisfactory. It seems to me that the best solution would be to use LilyPond's built-in Scheme interpreter to extract the pitch names while the file is being processed. I've made some attempts to use map with ly:note-pitchname, but so far no success. This is probably because I know squat about Scheme, especially as used in LilyPond scripts. % Moveable Do as lyrics template % define some solfege pitchnames % (in practice, the full set goes into english.ly) pitchnames = #`( (do . ,(ly:make-pitch -1 0 NATURAL)) (re . ,(ly:make-pitch -1 1 NATURAL)) (mi . ,(ly:make-pitch -1 2 NATURAL)) ) #(ly:parser-set-note-names parser pitchnames) % compose as though in C major mynotes = \relative do' {\key do \major do2 re4( mi4) } % transpose to desired key melody = \transpose do mi { \mynotes } % I WANT TO AUTOMATICALLY CREATE THE % THE PITCHNAMES IN THIS BLOCK % FROM THE CONTENTS OF \mynotes solfa = \lyricmode { \set ignoreMelismata = ##t % one syllable per note do re mi \unset ignoreMelismata % allow normal placement of other lyrics } % Produce score with solfege names as lyrics \score { \new Voice = myVoice { \melody } \new Lyrics \lyricsto myVoice \solfa } \version 2.12.3 Note: I've also posted this question at StackOverflowhttp://stackoverflow.com/questions/4378228/lilypond-extracting-pitch-names-from-music but I'm not sure how many LilyPond gurus are active there, so it seems worthwhile to ask the same question here. Thanks, Mike ___ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Extracting pitch names from music
On Tue, Dec 7, 2010 at 4:35 PM, Michael Ellis michael.f.el...@gmail.com wrote: It seems to me that the best solution would be to use LilyPond's built-in Scheme interpreter to extract the pitch names while the file is being processed. I've made some attempts to use map with ly:note-pitchname, but so far no success. This is probably because I know squat about Scheme, especially as used in LilyPond scripts. Here's an attempt of a patch I recently made, that might give you some pointers: diff --git a/scm/chord-name.scm b/scm/chord-name.scm index 7f5909b..2853102 100644 --- a/scm/chord-name.scm +++ b/scm/chord-name.scm @@ -59,15 +59,38 @@ (make-hspace-markup (if (= alteration SHARP) 0.2 0.1)) +(define (note-names-vector alist) + Extract note names from a pitchnames ALIST. + (let ((name-ls '())) +(map (lambda (x) + (let* ((pitch (cdr x)) + (alteration (ly:pitch-alteration pitch))) +(if (eq? alteration 0) +(set! name-ls (cons + (string-capitalize (symbol-string (car x))) + name-ls) + alist) +(list-vector (reverse name-ls + -(define-public (note-name-markup pitch lowercase?) +(define-public (note-name-markup pitch lowercase? . input-language) Return pitch markup for PITCH. - (make-line-markup - (list -(make-simple-markup - (conditional-string-downcase - (vector-ref #(C D E F G A B) (ly:pitch-notename pitch)) - lowercase?)) -(accidental-markup (ly:pitch-alteration pitch) + (let* ((get-pitchnames (lambda (x) + (ly:assoc-get (string-symbol x) +language-pitch-names))) +(alist (get-pitchnames default-language))) +(if input-language + (cond ((string? input-language) + (set! alist (get-pitchnames input-language))) + ((boolean? input-language)) + (set! alist pitchnames))) +(make-line-markup + (list + (make-simple-markup + (conditional-string-downcase + (vector-ref (note-names-vector alist) + (ly:pitch-notename pitch)) + lowercase?)) + (accidental-markup (ly:pitch-alteration pitch)) Sorry for not being more helpful, if there are things you don't understand I'll try and help you further. Cheers, Valentin. ___ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user
Re: Extracting pitch names from music
Thanks Valentin, that's quite helpful. I ended up taking an approach you suggested in a previous posthttp://lists.gnu.org/archive/html/lilypond-user/2010-10/msg00687.htmlto this list. Using the NoteNames context with alternative note names seems to be doing pretty much everything I want. Here's a revised version of my script that works as desired: % Moveable Do as lyrics example % define solfege pitchnames pitchnames = #`( (do . ,(ly:make-pitch -1 0 NATURAL)) (re . ,(ly:make-pitch -1 1 NATURAL)) (mi . ,(ly:make-pitch -1 2 NATURAL)) ) #(ly:parser-set-note-names parser pitchnames) % Apparently, LilyPond reverts to dutch names when % using the NoteNames context. The following % workaround was posted by V. Villenave at % http://lists.gnu.org/archive/html/lilypond-user/2010-10/msg00687.html newnames = #`((c . do) (d . re) (e . mi)) myNoteNames = #(lambda (grob) (let* ((default-name (ly:grob-property grob 'text)) (new-name (assoc-get default-name newnames))) (ly:grob-set-property! grob 'text new-name) (ly:text-interface::print grob))) % compose as though in C major mynotes = \relative do' {\key do \major do2 re4( mi4) } % transpose to desired key melody = \transpose do mi { \mynotes } % Produce score with solfege names as lyrics \score { \new Voice = myVoice { \melody } \context NoteNames \with { \override NoteName #'stencil = #myNoteNames } { \mynotes } } \version 2.12.3 This approach seems to work ok with a larger example where I defined all the chromatic solfege names. The only issue I seem to be encountering in the larger example is an unintended doubling of voices on the midi output. Does the NoteNames engraver produce a midi stream by default? If so, how can I turn it off? My midi section looks like \midi { %% voodoo that lets us specify instrument in melody \context { \Staff \remove Staff_performer } \context { \Voice \consists Staff_performer } } Cheers, Mike On Tue, Dec 7, 2010 at 11:41 AM, Valentin Villenave valen...@villenave.netwrote: On Tue, Dec 7, 2010 at 4:35 PM, Michael Ellis michael.f.el...@gmail.com wrote: It seems to me that the best solution would be to use LilyPond's built-in Scheme interpreter to extract the pitch names while the file is being processed. I've made some attempts to use map with ly:note-pitchname, but so far no success. This is probably because I know squat about Scheme, especially as used in LilyPond scripts. Here's an attempt of a patch I recently made, that might give you some pointers: diff --git a/scm/chord-name.scm b/scm/chord-name.scm index 7f5909b..2853102 100644 --- a/scm/chord-name.scm +++ b/scm/chord-name.scm @@ -59,15 +59,38 @@ (make-hspace-markup (if (= alteration SHARP) 0.2 0.1)) +(define (note-names-vector alist) + Extract note names from a pitchnames ALIST. + (let ((name-ls '())) +(map (lambda (x) + (let* ((pitch (cdr x)) + (alteration (ly:pitch-alteration pitch))) +(if (eq? alteration 0) +(set! name-ls (cons + (string-capitalize (symbol-string (car x))) + name-ls) + alist) +(list-vector (reverse name-ls + -(define-public (note-name-markup pitch lowercase?) +(define-public (note-name-markup pitch lowercase? . input-language) Return pitch markup for PITCH. - (make-line-markup - (list -(make-simple-markup - (conditional-string-downcase - (vector-ref #(C D E F G A B) (ly:pitch-notename pitch)) - lowercase?)) -(accidental-markup (ly:pitch-alteration pitch) + (let* ((get-pitchnames (lambda (x) + (ly:assoc-get (string-symbol x) +language-pitch-names))) +(alist (get-pitchnames default-language))) +(if input-language + (cond ((string? input-language) + (set! alist (get-pitchnames input-language))) + ((boolean? input-language)) + (set! alist pitchnames))) +(make-line-markup + (list + (make-simple-markup + (conditional-string-downcase + (vector-ref (note-names-vector alist) + (ly:pitch-notename pitch)) + lowercase?)) + (accidental-markup (ly:pitch-alteration pitch)) Sorry for not being more helpful, if there are things you don't understand I'll try and help you further. Cheers, Valentin. ___ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user