lilypond-user
[Top][All Lists]
Advanced

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

Re: Snippet "music box" does not work in 2.16


From: David Kastrup
Subject: Re: Snippet "music box" does not work in 2.16
Date: Wed, 12 Dec 2012 23:03:43 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

David Kastrup <address@hidden> writes:

> Eric <address@hidden> writes:
>
>> Hi Lilypond helpers,
>>
>> The following snippet :
>>
>> http://lsr.dsi.unimi.it/LSR/Snippet?id=346
>>
>> does not work any longer.
>>
>> The error occurs "In procedure car in expression (car pes):
>> /home/eric/musique/lilypond/test.ly:49:49: Wrong type (expecting
>> pair): ()"
>>
>> that is, at line (in function defineTransform) :
>>
>> (pnew (ly:music-property (car pes) 'pitch))
>>
>>
>> Can anyone find what is wrong ?
>
> Things got simpler.  Converge the two lines
>
>                      (pes (ly:music-property (list-ref pitches i)
> elements))
>                      (pnew (ly:music-property (car pes) 'pitch))
>
> into
>
>                        (pnew (ly:music-property (list-ref pitches i)
> pitch))

Actually, I find I like the following better (except one should likely
make the fold-some-music call into a separate predefined extract-pitches
function).

% This file demonstrates how to typeset different pitches with the
% same rhythm.

% It defines a function, defineTransform,
% that you can use to make transformation functions.

% Call it like this:
% myTransformation =
% \defineTransform { c'4 c'8 c'8 d'16 d' d' d' < c' d' > }

% You have now defined a transformation with the name "myTransformation".
% The rhythm in the transformation must be specified with notes c' d' e' f' g'  
etc.

% After having defined the transformation, you can call it like this:

% \myTransformation { e gis }
% To insert the rhythm from the transformation,
% where c' is substituted with e and d' is substituted with gis


%%% The following scheme function is just some mumbo-jumbo
%%% That you should add at the top of your program:

defineTransform =
#(define-scheme-function (parser location pattern)
   (ly:music?)
   (define-music-function (parser location pitchseq)
     (ly:music?)
     (let ((pitches (list->vector
                     (reverse!
                      (fold-some-music
                       (lambda (m)
                         (ly:pitch? (ly:music-property m 'pitch)))
                       (lambda (m l)
                         (cons (ly:music-property m 'pitch) l))
                       '()
                       pitchseq))))
           (m (ly:music-deep-copy pattern)))
       (for-some-music
        (lambda (m)
          (let ((p (ly:music-property m 'pitch)))
            (and (ly:pitch? p)
                 (begin
                   (set! (ly:music-property m 'pitch)
                         (vector-ref pitches
                                     (ly:pitch-steps p)))
                   #t))))
        m)
       m)))

%%% To illustrate, here follows the Bach Prelude in C major,
%%% Typeset using defineTransform:

% This is the unabridged version of the whole Prelude.
% If we were to implement it in the documentation, we
% might have to consider commenting about 80% of it. -vv

\include "deutsch.ly"

%%% This defines one measure of the prelude,
%%% using the five notes c' d' e' f' g' instead of the "real" notes:
makePreludeMeasure =
\defineTransform \transpose c c' \repeat unfold 2 {
  <<
    \context Staff = "up" {r8 e16 f g e f g }
    \context Staff = "down" << {r16 d8.~d4 } \\ { c2 } >> 
  >>
}

%%% This is the last two measures - defined normally:
ending = <<
  \context Staff = up { s1*2 }
  \context Staff = up { r8 f,16 a, c f c a, \stemUp c \change Staff = down
    a, f, a, f, d, f, d, \change Staff = up \stemNeutral
    r8 g16 h d' f' d' h d' h g h d f e\prall d <e g c'>1^\fermata \bar "|."
  }
  \context Staff = down <<
    \new Voice {
      \stemUp \tieUp r16 c,8.~c,4~c,2 r16 h,,8.~h,,4~h,,2 c,1 \bar "|."
    }
    \new Voice {
      \stemDown \tieDown c,,2~c,, c,,~c,, c,,1_\fermata 
    }
  >>
>>


\header {
  title = "Praeludium in C major"
  composer = "J. S. Bach"
}

\score {
  \transpose c c' \context PianoStaff <<
    \new Staff = "up"   { \clef "G" }
    \new Staff = "down" { \clef "F" 
      \tempo 4 = 80
      %%% The first measure should use notes c e g c' e' :
      \makePreludeMeasure {c e g c' e' }
      %%% Etc. :
      \makePreludeMeasure {c d a d' f' }
                                %we get the idea now.
                                %comment the following block if the snippet is 
too long.
      
      \makePreludeMeasure {h, d g d' f' }
      \makePreludeMeasure {c e g c' e' }
      
      \makePreludeMeasure {c e a e' a' }
      \makePreludeMeasure {c d fis a d'  }
      \makePreludeMeasure {h, d g d' g' }
      \makePreludeMeasure {h, c e g c' }
      \makePreludeMeasure {a, c e g c'  }
      \makePreludeMeasure {d, a, d fis c' }
      \makePreludeMeasure {g, h, d g h }
      \makePreludeMeasure {g, b, e g cis'  }
      \makePreludeMeasure {f, a, d a d' }
      \makePreludeMeasure {f, as, d f h }
      \makePreludeMeasure {e, g, c g c' }
      \makePreludeMeasure {e, f, a, c f }
      \makePreludeMeasure {d, f, a, c f }
      
      \makePreludeMeasure {g,, d, g, h, f }
      \makePreludeMeasure {c, e, g, c e }
      \makePreludeMeasure {c, g, b, c e }
      \makePreludeMeasure {f,, f, a, c e  }
      \makePreludeMeasure {fis,, c, a, c es }
      \makePreludeMeasure {as,, f, h, c d }
      \makePreludeMeasure {g,, f, g, h, d }
      \makePreludeMeasure {g,, e, g, c e }
      \makePreludeMeasure {g,, d, g, c f }
      \makePreludeMeasure {g,, d, g, h, f }
      \makePreludeMeasure {g,, es, a, c fis }
      \makePreludeMeasure {g,, e, g, c g }
      \makePreludeMeasure {g,, d, g, c f }
      \makePreludeMeasure {g,, d, g, h, f }
      \makePreludeMeasure {c,, c, g, b, e }
      %%% Finally insert the ending:
      \ending
                                % here ends the block to comment

    }
  >>
  
  \layout {}   
  \midi {}
}

-- 
David Kastrup

reply via email to

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