Re: Identifying non-chord notes in Scheme

2019-11-29 Thread Steve Cummings
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

2019-11-27 Thread Steve Cummings
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

2019-11-26 Thread Steve Cummings
(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

2019-11-26 Thread Steve Cummings
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

2019-11-19 Thread Steve Cummings
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

2019-11-18 Thread Steve Cummings
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

2019-08-28 Thread Steve Cummings

(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