|
From: | Dave Atkinson |
Subject: | Lilypond custom chords & Scheme |
Date: | Sun, 21 Jun 2020 14:12:45 +0100 |
User-agent: | Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.9.0 |
Hi List...
I've been looking for a way to define custom chord voicing (I wanted to record all the back of the Jamey Aebersold books), and I came across this post on stack exchange (https://music.stackexchange.com/questions/15155/define-custom-chord-voicings-in-lilypond) that almost did what wanted... In a reply to the question, someone suggested the following, saying there was no way to avoid including the duration parameter:
makevoicing = #(define-scheme-function (parser location m) (ly:music?) (define-music-function (parser location d) (ly:duration?) (map-some-music (lambda (m) (and (ly:duration? (ly:music-property m 'duration)) (begin (set! (ly:music-property m 'duration) d) m))) (ly:music-deep-copy m)))) voicing = \makevoicing < g a c e a > % dom7, with 7th in bass \new Staff { % play the whole chord for two quarters, then a half \voicing4 \voicing4 \voicing2 }
I modified the above to produce this:
makeVoicing = #(define-scheme-function (parser location inversion) (ly:music?) (define-music-function (parser location noteEvent) (ly:music?) (map-some-music (lambda (m) (and (ly:duration? (ly:music-property m 'duration)) (begin (set! (ly:music-property m 'duration) (ly:music-property noteEvent 'duration)) m))) (ly:music-transpose (ly:music-deep-copy inversion) (ly:music-property noteEvent 'pitch))))) minorSevenI = \makeVoicing <ef bf d' f'> dominantSevenI = \makeVoicing <e bf d' g'> majorSevenI = \makeGuitarVoicing <e a d' g'> \new Staff { \minorSevenI c'4. \dominantSevenI f8 \majorSevenI bes2 }
to allow me to specify the pitch and duration of the voicing. I was the closest I though I could get to adding my own custom chord entry without actually hacking the lilypond source.
So, I have a couple of questions, as this is my first excursion into Scheme for LilyPond, or indeed Scheme period. First, in the manual, for both define-scheme-function and define-music-function, it seems to say that you need to declare the types of the parameters. So how come 'parser' and 'location' are not specified? I couldn't find anything in the documentation about the first two parameters being the parser and the location? The second question is: why the double definition? Why define a music function inside a Scheme function? My first attempts at achieving this before I found the above (which were moderately successful but much more complicated than the above) used only a music function. Does the original author know something I don't about how this all works (my default assumption) or is it unnecessary?
So is this idiomatic Scheme? All suggestions gratefully received. I was also trying to modify it so that I get notes that are below the twelfth fret of a guitar, regardless of the octave of the pitch given. I have had some success, but it basically relies on calling ly:music-transpose twice, which seems a bit inefficient, so I'll not post that yet. If I work out an efficient way of doing, would people be prepared to critique it for me if I posted it?
Best regards,
Dave
[Prev in Thread] | Current Thread | [Next in Thread] |