Hi Kieren,

for-some-music does not return music.  It works on music in-place.  So
the last thing in your music function must not be for-some-music but
rather the music that you have been working on.
So…

%%%  SNIPPET BEGINS
adjustPitch =
#(define-music-function (pitchIn pitchOut music) (ly:pitch? ly:pitch? ly:music?)
    (for-some-music
     (lambda (m)
         (if (music-is-of-type? m 'note-event)
             (if (and (= (ly:pitch-notename (ly:music-property m 'pitch)) 
(ly:pitch-notename pitchIn))
                           (= (ly:pitch-alteration (ly:music-property m 
'pitch)) (ly:pitch-alteration pitchIn)))
                 (ly:music-set-property! m 'pitch
                                         (ly:make-pitch
                                          (ly:pitch-octave (ly:music-property m 
'pitch))
                                          (ly:pitch-notename pitchOut)
                                          (ly:pitch-alteration pitchOut)))
                 m)
             #f))
         music)
     music)

testmusic = \fixed c' { c4 d es e f g c' es' eis }

{ \testmusic }

{ \adjustPitch ees e \testmusic }
%%%  SNIPPET ENDS

??

The last "m" in your innermost (if ...) is unnecessary: As with the
difference between "for" and "map" in plain Scheme, the return value of
the lambda function in for-some-music gets discarded ("for" functions
are supposed to _do_ something, not _return_ something). So your branch
stating "... else return m" can be omitted.

Next, as you already hinted: If you use the same expression more than
once (here (ly:music-property m 'pitch)), it is usually reasonably to
store it in a variable, i.e. use (let ...).

Also some food for thought, if I may:

- What if I want to replace each b by the c _above_ it?

- I've been thinking about a conventient user interface. If I understand
you correctly, you aim for something like a list of input-pitches and a
list of output-pitches, both preferably given as music, so we can do

\adjustPitch { c d e } { fis e d } \music

meaning: turn c into fis, d into e, and e into d. If I'm right, you'll
probably be able to make good use of (music-pitches ...). Also, for
search-and-replace tasks in Scheme, using an association list (alist) as
a dictionary is often convenient. This would mean we rather want a list
of pairs (old-pitch . new-pitch). In order to construct such a list of
pairs from two music inputs as above, (map ...) provides a very elegant way.

See also:

https://www.gnu.org/software/guile/manual/html_node/Association-Lists.html
https://www.gnu.org/software/guile/manual/html_node/List-Mapping.html

Lukas

Reply via email to