[frogs] Integrating a Scheme function into Lilypond

[ Thread Index | Date Index | More lilynet.net/frogs Archives ]


Hello all,

As discussed on the lilypond-devel mailing list,
http://lists.gnu.org/archive/html/lilypond-devel/2010-07/msg00141.html

.... I'm working on developing true chromatic transposition as built-in
functionality for Lilypond.

The current fruit of this work is contained in the attached file
naturalizeMusicModern.ly which defines a flexible Scheme function that
can be used to naturalize pitches according to various different rules.

As a first step to building this into core Lilypond, the obvious thing
to do seems to be to move the Scheme functions into a .scm file in the
scm/ directory of the Lilypond source code.  This I've done (see the
attached file naturalize.scm) and I've written another Lilypond demo to
make use of this (naturalizeMusicIntegrated.ly).

Lilypond appears to 'recognize' the existence of the new .scm file since
issuing a 'make' command rebuilds various stuff after that file is
edited.  However, when running the newly-built Lilypond on
naturalizeMusicIntegrated.ly I get an error,

    GNU LilyPond 2.13.28
    Processing `naturalizeMusicIntegrated.ly'
    Parsing...naturalizeMusicIntegrated.ly:5:4: In expression
    (ly:naturalize m (ly:naturalize-limit >= 1) ...):
    naturalizeMusicIntegrated.ly:5:4: Unbound variable: ly:naturalize

(... note that my native installed Lilypond is the 2.12.x version that
comes built in with Ubuntu, so it's not simply that I'm running the
wrong Lilypond.)

So, it looks like the functions in my new .scm file are not visible to
the Lilypond interpreter.  How do I make them so? :-)

Thanks & best wishes,

    -- Joe
#(define (naturalize-limit lim val)
           (define (limit a)
             (lim a val))
           limit)

#(define (naturalize-pitch p high low higheb lowcf)
   (let ((o (ly:pitch-octave p))
         (n (ly:pitch-notename p))
         (a (ly:pitch-alteration p)))
     (do ((aa 0))
         ((= aa a) (ly:make-pitch o n a))
       (set! aa a)
       (cond
        ((and (higheb a) (or (eq? n 2) (eq? n 6)))
         (set! a (- a (/ 1 2)))
         (set! n (+ n 1)))
        ((and (lowcf a) (or (eq? n 0) (eq? n 3)))
         (set! a (+ a (/ 1 2)))
         (set! n (- n 1))))
       (cond
        ((high a) (set! a (- a 1)) (set! n (+ n 1)))
        ((low a) (set! a (+ a 1)) (set! n (- n 1))))
       (if (< n 0) (begin (set! o (- o 1)) (set! n (+ n 7))))
       (if (> n 6) (begin (set! o (+ o 1)) (set! n (- n 7)))))))

#(define (naturalize music high low higheb lowcf)
   (let ((es (ly:music-property music 'elements))
         (e (ly:music-property music 'element))
         (p (ly:music-property music 'pitch)))
     (if (pair? es)
         (ly:music-set-property!
          music 'elements
          (map (lambda (x) (naturalize x high low higheb lowcf)) es)))
     (if (ly:music? e)
         (ly:music-set-property!
          music 'element
          (naturalize e high low higheb lowcf)))
     (if (ly:pitch? p)
         (begin
           (set! p (naturalize-pitch p high low higheb lowcf))
           (ly:music-set-property! music 'pitch p)))
     music))

naturalizeMusic =
#(define-music-function (parser location m)
   (ly:music?)
   (naturalize m (naturalize-limit >= 1)
                 (naturalize-limit <= -1)
                 (naturalize-limit >= (/ 1 2))
                 (naturalize-limit <= (/ -1 2))))

naturalizeMusicHarp =
#(define-music-function (parser location m)
   (ly:music?)
   (naturalize m (naturalize-limit > (/ 1 2))
                 (naturalize-limit < (/ -1 2))
                 (naturalize-limit >= (/ 1 2))
                 (naturalize-limit <= (/ -1 2))))

naturalizeMusicTonal =
#(define-music-function (parser location m)
   (ly:music?)
   (naturalize m (naturalize-limit > 1)
                 (naturalize-limit < -1)
                 (naturalize-limit > (/ 1 2))
                 (naturalize-limit < (/ -1 2))))

music = \relative c' { c4 d e g }
microphrase = \relative c'' { geses4 geseh ges geh g gih gis gisih gisis }

\score {
  \new Staff {
    \set Staff.extraNatural = ##f
    \transpose c ais { \music }
    \bar ":"
    \naturalizeMusic \transpose c ais { \music }
    \bar ":"
    \naturalizeMusicHarp \transpose c ais { \music }
    \bar ":"
    \naturalizeMusicTonal \transpose c ais { \music }
    \bar "||"
    
    \transpose c deses { \music }
    \bar ":"
    \naturalizeMusic \transpose c deses { \music }
    \bar ":"
    \naturalizeMusicHarp \transpose c deses { \music }
    \bar ":"
    \naturalizeMusicTonal \transpose c deses { \music }
    \bar "||"
    \break
    
    \time 9/4
    \microphrase
    \bar ":"
    \naturalizeMusic { \microphrase }
    \bar ":"
    \naturalizeMusicHarp { \microphrase }
    \bar ":"
    \naturalizeMusicTonal{ \microphrase }
    \break
    
    \transpose c ais { \microphrase }
    \bar ":"
    \naturalizeMusic \transpose c ais { \microphrase }
    \bar ":"
    \naturalizeMusicHarp \transpose c ais { \microphrase }
    \bar ":"
    \naturalizeMusicTonal \transpose c ais { \microphrase }
    \break
    
    \transpose c deses { \microphrase }
    \bar ":"
    \naturalizeMusic \transpose c deses { \microphrase }
    \bar ":"
    \naturalizeMusicHarp \transpose c deses { \microphrase }
    \bar ":"
    \naturalizeMusicTonal \transpose c deses { \microphrase }
    \break
    
    \transpose c cih { \microphrase }
    \bar ":"
    \naturalizeMusic \transpose c cih { \microphrase }
    \bar ":"
    \naturalizeMusicHarp \transpose c cih { \microphrase }
    \bar ":"
    \naturalizeMusicTonal \transpose c cih { \microphrase }
  }
  \layout { }
}

(define-public (ly:naturalize-limit lim val)
          (define (limit a)
            (lim a val))
          limit)

(define-public (ly:naturalize-pitch p high low higheb lowcf)
  (let ((o (ly:pitch-octave p))
        (n (ly:pitch-notename p))
        (a (ly:pitch-alteration p)))
    (do ((aa 0))
        ((= aa a) (ly:make-pitch o n a))
      (set! aa a)
      (cond
       ((and (higheb a) (or (eq? n 2) (eq? n 6)))
        (set! a (- a (/ 1 2)))
        (set! n (+ n 1)))
       ((and (lowcf a) (or (eq? n 0) (eq? n 3)))
        (set! a (+ a (/ 1 2)))
        (set! n (- n 1))))
      (cond
       ((high a) (set! a (- a 1)) (set! n (+ n 1)))
       ((low a) (set! a (+ a 1)) (set! n (- n 1))))
      (if (< n 0) (begin (set! o (- o 1)) (set! n (+ n 7))))
      (if (> n 6) (begin (set! o (+ o 1)) (set! n (- n 7)))))))

(define-public (ly:naturalize music high low higheb lowcf)
  (let ((es (ly:music-property music 'elements))
        (e (ly:music-property music 'element))
        (p (ly:music-property music 'pitch)))
    (if (pair? es)
        (ly:music-set-property!
         music 'elements
         (map (lambda (x) (naturalize x high low higheb lowcf)) es)))
    (if (ly:music? e)
        (ly:music-set-property!
         music 'element
         (naturalize e high low higheb lowcf)))
    (if (ly:pitch? p)
        (begin
          (set! p (naturalize-pitch p high low higheb lowcf))
          (ly:music-set-property! music 'pitch p)))
    music))
naturalizeMusic =
#(define-music-function (parser location m)
   (ly:music?)
   (ly:naturalize m (ly:naturalize-limit >= 1)
                    (ly:naturalize-limit <= -1)
                    (ly:naturalize-limit >= (/ 1 2))
                    (ly:naturalize-limit <= (/ -1 2))))

naturalizeMusicHarp =
#(define-music-function (parser location m)
   (ly:music?)
   (ly:naturalize m (ly:naturalize-limit > (/ 1 2))
                    (ly:naturalize-limit < (/ -1 2))
                    (ly:naturalize-limit >= (/ 1 2))
                    (ly:naturalize-limit <= (/ -1 2))))

naturalizeMusicTonal =
#(define-music-function (parser location m)
   (ly:music?)
   (ly:naturalize m (ly:naturalize-limit > 1)
                    (ly:naturalize-limit < -1)
                    (ly:naturalize-limit > (/ 1 2))
                    (ly:naturalize-limit < (/ -1 2))))

music = \relative c' { c4 d e g }
microphrase = \relative c'' { geses4 geseh ges geh g gih gis gisih gisis }

\score {
  \new Staff {
    \set Staff.extraNatural = ##f
    \transpose c ais { \music }
    \bar ":"
    \naturalizeMusic \transpose c ais { \music }
    \bar ":"
    \naturalizeMusicHarp \transpose c ais { \music }
    \bar ":"
    \naturalizeMusicTonal \transpose c ais { \music }
    \bar "||"

    \transpose c deses { \music }
    \bar ":"
    \naturalizeMusic \transpose c deses { \music }
    \bar ":"
    \naturalizeMusicHarp \transpose c deses { \music }
    \bar ":"
    \naturalizeMusicTonal \transpose c deses { \music }
    \bar "||"
    \break

    \time 9/4
    \microphrase
    \bar ":"
    \naturalizeMusic { \microphrase }
    \bar ":"
    \naturalizeMusicHarp { \microphrase }
    \bar ":"
    \naturalizeMusicTonal{ \microphrase }
    \break

    \transpose c ais { \microphrase }
    \bar ":"
    \naturalizeMusic \transpose c ais { \microphrase }
    \bar ":"
    \naturalizeMusicHarp \transpose c ais { \microphrase }
    \bar ":"
    \naturalizeMusicTonal \transpose c ais { \microphrase }
    \break

    \transpose c deses { \microphrase }
    \bar ":"
    \naturalizeMusic \transpose c deses { \microphrase }
    \bar ":"
    \naturalizeMusicHarp \transpose c deses { \microphrase }
    \bar ":"
    \naturalizeMusicTonal \transpose c deses { \microphrase }
    \break

    \transpose c cih { \microphrase }
    \bar ":"
    \naturalizeMusic \transpose c cih { \microphrase }
    \bar ":"
    \naturalizeMusicHarp \transpose c cih { \microphrase }
    \bar ":"
    \naturalizeMusicTonal \transpose c cih { \microphrase }
  }
  \layout { }
}



Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/