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