Re: Identifying non-chord notes in Scheme
Aaron, thanks a million for the solution (with the convincing demo). I'm examining note data rather than tweaking output, but with your example as a guide the rest will be 'easy' (as easy as Scheme goes for me). If you have time for a question: The "for-some-music" function is new to me. Any quick comments when to use each of the different functions/methods for recursion through input music? Or do you know of any tutorials/explications of recursion through music? LilyPond offers 'music-map,' 'map-some-music,' and 'for-some-music,' and I've also seen code based on plain old 'map.' Steve From: Aaron Hill Subject:Re: Identifying non-chord notes in Scheme Date: Wed, 27 Nov 2019 11:09:12 -0800 User-agent: Roundcube Webmail/1.3.8 Hi Steve, Sorry for the delay in responding to your original query. But as some say, "better late, than never." (: \version "2.19.83" colorNonChordNotes = #(define-music-function (color music) (color? ly:music?) (define (color-stop? mus) (if (music-is-of-type? mus 'note-event) (let* ((curr (ly:music-property mus 'tweaks '())) (new `((color . ,color) ((Accidental . color) . ,color))) (tweaks (append curr new))) (set! (ly:music-property mus 'tweaks) tweaks)) ;; Stop recursion on chords. (music-is-of-type? mus 'event-chord))) (for-some-music color-stop? music) music) soprano = \fixed c' { 4 b8 d' 2 } alto = \fixed c' { e8 d 4 dis2 } tenor = \fixed c { 4 b2 } bass = \fixed c { c4 d 2 } \score { \colorNonChordNotes #(x11-color 'tomato) \new ChoirStaff << \new Staff \voices 1,2 << \clef "treble" \soprano \\ \alto >> \new Staff \voices 1,2 << \clef "bass" \tenor \\ \bass >> >> } Not knowing *what* you intended to do with non-chord notes, I just simply appended a few \tweaks to those notes to demonstrate the technique of using for-some-music with a custom stop? procedure. -- Aaron Hill non-chord-notes.cropped.png* *
Re: Identifying non-chord notes in Scheme
Jaap, thank you for taking this up but I'm not sure whether your answer helps--yes, I can find notes within chords because they are branches of EventChord, but those same notes also occur as individual NoteEvent events *before* the EventChord event. If I'm trying to extract or otherwise process only notes that *don't* belong to any chord, waiting for the ChordEvent that follows and then backtracking would be complicated. I should think I could check some property of a NoteEvent ("parent" or "chord" would be nice). So is there any way to tell that a note is *not* a branch (a leaf?) on any EventChord event? Notice that I'm using "music-map" to get a list of the events, and the list it generates includes chord notes twice: first as separate NoteEvents and then again as members of the Chord of which they are branches/members. If there's no simple way to look at a NoteEvent and tell whether it is part of a chord, maybe there's a different way to get a list of music events that doesn't have this duplication of chord notes. Or maybe there's a different way entirely to approach the problem of processing/extracting non-chord notes. Thanks for pointing out ContextSpeccedMusic. lilyp...@de-wolff.org wrote on 11/27/2019 8:45 AM: Steve, When you see the music expression as a tree, then the NoteEvent’s belonging to a chord are branches of an EventChord. This is for all chords including 4 etc. And as an extra bonus: When you have chords like “c:7+” the EventChord’s are branches (or sub-branches) of an ContextSpeccedMusic event with the music-attribute ‘context-type’ = “ChordsName” Jaap *Van:*lilypond-user *Namens *Steve Cummings *Verzonden:* Tuesday, November 26, 2019 7:31 PM *Aan:* lilypond-user@gnu.org *Onderwerp:* Identifying non-chord notes in Scheme What's the test for differentiating between non-chord notes and notes within a chord, when iterating through events in music? I can examine the notes within a chord individually, but I can't been able to find the way to capture notes that don't belong to a chord (or alternatively, to discard note events do belong to a chord). Leaning heavily on code from Giles T, here's a simple routine that displays pitches of note events when they are encountered as such, and also when they occur within a chord. If the goal is to process non-chord notes only, how can I pick them out? In the listing below I've marked relevant places with "<<--" Thanks, Steve \version "2.19" #(use-modules (ice-9 receive)) %% so 'receive' can be used #(define (noteEvent? music) (eq? (name-of music) 'NoteEvent)) #(define (name-of music) " (display-scheme-music (ly:music-property music 'name))" (ly:music-property music 'name) ) #(define* (music-to-console music #:optional (strict-comp? #t)) (music-map (lambda(mus) (display (name-of mus)) (newline) (cond ((eq? 'EventChord (name-of mus)) (display "Chord")(newline) (receive (notes others) (partition noteEvent? (ly:music-property mus 'elements)) <<--Examine different music property? (map(lambda(note)(display (ly:music-property note 'pitch))) notes) (newline))) ((eq? 'NoteEvent (name-of mus)) <<- Test here? (display "A note event, but does it stand alone, or is it part of a chord?") <<- or here? (newline) (display (ly:music-property mus 'pitch))(newline)) (else (display "(Not a note or a chord)")(newline)) ) (newline) #{ #mus #}) music)) showNotesAndChords = #(define-music-function (music) (ly:music?) (music-to-console music #t)) someNotes = \transpose c f { 4 c'4 d'4 \transpose f c {c''>2 c'}} \showNotesAndChords \someNotes
Re: Frescobaldi LilyPond Log
(Apologies for any duplication--I didn't see this alternative mentioned in the thread.) Nothing wrong with the Autohotkey solution but it's pretty easy to unstick the stuck font size setting in the log, a known problem in the Windows version of Frescobaldi. The issue has been fixed in the source (https://github.com/frescobaldi/frescobaldi/pull/1115, https://github.com/frescobaldi/frescobaldi/issues/1066#issuecomment-388319437) but as of a few days ago the binary available for download didn't include that change. You can apply the fix yourself just by commenting out or deleting one line of python code. Stepwise, for us blockheads, it's: 1. Open the file log.py (located in the ..\Frescobaldi\frescobaldi_app\ folder) in a text editor -- Frescobaldi will do. 2. Find the line (line number 124 in the current Windows version) that reads output.setProperty(QTextFormat.FontSizeAdjustment, 0) 3. Comment out that line (put a # at the beginning of the line). 4. Save the file. When you close and restart Frescobaldi the font setting for the log should work--did for me. You can delete the line instead of commenting it out. Either way, with that change the mousewheel/Autohotkey zoom no longer works.
Identifying non-chord notes in Scheme
What's the test for differentiating between non-chord notes and notes within a chord, when iterating through events in music? I can examine the notes within a chord individually, but I can't been able to find the way to capture notes that don't belong to a chord (or alternatively, to discard note events do belong to a chord). Leaning heavily on code from Giles T, here's a simple routine that displays pitches of note events when they are encountered as such, and also when they occur within a chord. If the goal is to process non-chord notes only, how can I pick them out? In the listing below I've marked relevant places with "<<--" Thanks, Steve \version "2.19" #(use-modules (ice-9 receive)) %% so 'receive' can be used #(define (noteEvent? music) (eq? (name-of music) 'NoteEvent)) #(define (name-of music) " (display-scheme-music (ly:music-property music 'name))" (ly:music-property music 'name) ) #(define* (music-to-console music #:optional (strict-comp? #t)) (music-map (lambda(mus) (display (name-of mus)) (newline) (cond ((eq? 'EventChord (name-of mus)) (display "Chord")(newline) (receive (notes others) (partition noteEvent? (ly:music-property mus 'elements)) <<--Examine different music property? (map(lambda(note)(display (ly:music-property note 'pitch))) notes) (newline))) ((eq? 'NoteEvent (name-of mus)) <<- Test here? (display "A note event, but does it stand alone, or is it part of a chord?") <<- or here? (newline) (display (ly:music-property mus 'pitch))(newline)) (else (display "(Not a note or a chord)")(newline)) ) (newline) #{ #mus #}) music)) showNotesAndChords = #(define-music-function (music) (ly:music?) (music-to-console music #t)) someNotes = \transpose c f { 4 c'4 d'4 \transpose f c {c''>2 c'}} \showNotesAndChords \someNotes
Re: Scheme function to return pitchnames as markup/text
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 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
Scheme function to return pitchnames as markup/text
Though I remain baffled by Scheme and its use in LilyPond, my hope is to build one or more functions/procedures that would transpose input music and for each chord display the transposed chord's note names, with control over the way the names are represented (as in Cb or F# instead of ces and fis). Here, I'm just asking for help with one part of the function-to-be: how to turn notes in LilyPond music into note names as text (schematic of the complete imagined function below). Here's what I've tried so far, in LilyPond 2.19.8x, based closely on working procedures found on this list. Once this is running right for single notes I'll (hope to) get it to loop through all input music. #(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 (ly:pitch-notename pitch-datum))) #{ \markup \bold $out-notename #} )) I get "syntax error, unexpected NUMBER_IDENTIFIER" on the $out-notename line when calling notenamer with a note wrapped in braces, as in: \notenamer {a} Without the braces around the music, the error is "In procedure car in expression (car (ly:music-property pitchin #)):Wrong type (expecting pair): () Results are the same if I do "define-music-function" instead of "define-scheme-function." Many thanks for your attention and help, Steve PS: I have a working NoteNames reformatter but it seems to require listing in a substitution table the specific notes of each and every chord in each transposition. A custom function would allow display of the chord note names in a columnar stack so if these markups were used as text scripts they wouldn't either take too much space or collide with the names of adjacent notes. Alternatively, chord note names could be placed beneath ChordNames.
Transpose up or down conditionally
(also posted on Stack Exchange) version 2.19... How can I make Lilypond decide whether to transpose up or down depending on a target octave/range for one of the transposed notes? I want to make a set of chord voicings, each in multiple transpositions, with the lowest note of each transposed voicing always within a specified octave, say between "c" and "b" (the octave below middle C in Lilypond notation). This would require some sort of conditional (in concept, something like: "try transposing the chord down; if the lowest note of the downward transposition is too low, transpose up"). I can't find any relevant snippets in the Lilypond snippet library. I found one discussion of conditional transposing here: http://lilypond.1069038.n5.nabble.com/problems-trying-to-write-a-conditional-transpose-td148815.html but the Scheme code is opaque to me--with the sparse comments I can't even understand what the original poster was trying to accomplish, much less the proposed solution. And when I tried to test that code using the short sample "input" quoted in the above link I got errors, as follows: |Parsing...C:...tmpdocument.ly:7:3: In procedure ly:music-set-property! in expression ((setter ly:music-property) (quote from-to) music ...): C:...tmpdocument.ly:7:3: Wrong type argument in position 1 (expecting Prob): from-to | A fancy-ish implementation might take any specified note in a series as the reference point for the up/down decision, or even calculate an "average" reference pitch, but for my purposes the reference note will always be the first one in the chord, for example the 'c' in the C major '< c e g >' triad. Thank you, Steve ___ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user