lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Lilypond custom chords & Scheme


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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]