lilypond-user
[Top][All Lists]
Advanced

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

Re: How to write slurs and ties with scheme


From: Thomas Morley
Subject: Re: How to write slurs and ties with scheme
Date: Thu, 1 Oct 2015 00:58:11 +0200

2015-09-30 4:40 GMT+02:00 Rachael Thomas <address@hidden>:
> On Tue, Sep 29, 2015 at 4:33 PM, David Kastrup <address@hidden> wrote:
>>
>> Thomas Morley <address@hidden> writes:
>>
>> > 2015-09-29 12:26 GMT+02:00 David Kastrup <address@hidden>:
>> >>
>> >> At the current point of time, slurs are only from one chord in a Voice
>> >> to the next chord in a Voice.  So you'd need to put your notes into
>> >> different Voice contexts in order to be able to slur them individually.
>> >> However, Stems are strictly a single-Voice phenomenon.  So you need to
>> >> put your notes in the same Voice.
>>
>> >
>> > I'm thinking about the problem for some time now.
>> > Another part of the problem is that most occurences of slurs in
>> > TabStaff with \tabFullNotation are not really Slurs but what is called
>> > 'hammering on'/'pulling off'.
>
>
> Yes.  Colloquially called hammering-on/pulling-off.  Classical guitarists
> (not me) call them ascending and descending slurs, respectively.
>
>>
>> I'm currently working on making in-chord ties work (if you have more
>> than one tie at the same time, you'd still need to work with
>> spanner-id).  Annoyingly complex to get right without causing too much
>> of a performance hit.
>
>
> Thank you for your good work!
>
> The composition that I am working on is in a different tuning.  For the
> purposes of a minimal example I changed the tuning to standard.
>
> I didn't realize that you tieWaitForNote allows you to call the tie function
> within a chord.  Here is a possible fix:
>
> \version "2.18.2"
>
> \new TabStaff {
>   \tabFullNotation
>   \set tieWaitForNote = ##t
>   < bis'\1 g\4 \tweak TabNoteHead.color #white \tweak
>   TabNoteHead.layer #-1 d\4~>16[ < fis'\2
>   ees\5> < g\3 d\4>]
> }
>
> ( look at that beautiful slur!)
> This minimal example doesn't cause any errors however within the larger
> transcription I am getting the following error:
>
> programming error: Tie without heads.  Suicide
> continuing , cross fingers
>
> I don't understand this error.  It doesn't really seem to affect anything
> though.  So I don't exactly mind it.
>
> What do you think?
>
> Rachael Carlson
>
> PS.  The composition that I am working on is called "Madrid" by Stefano
> Barone.  The transcription that you get when you buy it from him desperately
> needs to be redone with an eye towards detail.  (A lot of the composition is
> in 10/16 and 14/16.  The transcription writes it in 5/4 which makes it
> really difficult to read.)
>
> https://youtu.be/vWs1OdnsJNM

Here another thought, hijacking Glissando this time.
It will cause ugly output for usual Staff and it's not nice to create
all those Glissandi for a chord and throw away all not needed.
And ofcourse still some limitations...

\version "2.19.28"

%% Mostly taken from:
%% https://sourceforge.net/p/testlilyissues/issues/3088/
%% https://code.google.com/p/lilypond/issues/detail?id=3088
%% Thanks Jan

%% FIXME: c&p from stencil.scm -- define-public and remove copy
#(define (make-bezier-sandwich-stencil coords thick xext yext)
  (let* ((command-list `(moveto
                        ,(car (list-ref coords 3))
                        ,(cdr (list-ref coords 3))
                        curveto
                        ,(car (list-ref coords 0))
                        ,(cdr (list-ref coords 0))
                        ,(car (list-ref coords 1))
                        ,(cdr (list-ref coords 1))
                        ,(car (list-ref coords 2))
                        ,(cdr (list-ref coords 2))
                        curveto
                        ,(car (list-ref coords 4))
                        ,(cdr (list-ref coords 4))
                        ,(car (list-ref coords 5))
                        ,(cdr (list-ref coords 5))
                        ,(car (list-ref coords 6))
                        ,(cdr (list-ref coords 6))
                        closepath)))
  (ly:make-stencil
    `(path ,thick `(,@' ,command-list) 'round 'round #t)
    xext
    yext)))

%% FIXME: rewrite generic wrt axes and replace make-parenthesis-stencil
#(define (make-bow-stencil width height thickness angularity)
  "Create a bow stencil.
  @var{width} is the width of the bow markup.
  @var{thickness} is the thickness of the bow.
  @var{height} is the heigth of the bow.
  The higher the value of number @var{angularity},
  the more angular the shape of the bow."
  (let* ((line-width 0.1)
         (base-x (if (< width 0) (- width) 0))
         (base-y (if (< height 0) (- height) 0))
         (x-extent (ordered-cons 0 width))
         (y-extent (ordered-cons 0 height))
         (left-x (interval-start x-extent))
         (right-x (interval-end x-extent))
         (inner-y 0)
         (outer-y height)
         (left-end-point (cons left-x inner-y))
         (right-end-point (cons right-x inner-y))
         (outer-control-y (+ inner-y (* 4/3 outer-y)))
         (inner-control-y (+ outer-control-y
                            (if (< height 0) thickness (- thickness))))
         ;; keeping angularity allows for refactoring and
         ;; merging with make-parenthesis-stencil
         (offset-index (- (* 0.6 angularity) 0.8))
         (left-control-x (interval-index x-extent offset-index))
         (right-control-x (interval-index x-extent (- offset-index)))
         (left-outer-control-point
            (cons left-control-x outer-control-y))
         (right-outer-control-point
            (cons right-control-x outer-control-y))
         (right-inner-control-point
            (cons right-control-x inner-control-y))
         (left-inner-control-point
            (cons left-control-x inner-control-y)))

  (make-bezier-sandwich-stencil
    (list right-inner-control-point
          left-inner-control-point
          left-end-point
          right-end-point
          left-outer-control-point
          right-outer-control-point
          right-end-point
          left-end-point)
    line-width
    x-extent
    y-extent)))

%% FIXME: replace make-parenthesis-stencil by this:
#(define (make-parenthesis-stencil height width thick angularity)
  (ly:stencil-rotate-absolute
    (make-bow-stencil height width thick angularity)
    -90 0 0))

%% FIXME: c&p from bezier-bow.cc
#(define (F0_1 x) (* (/ 2 PI) (atan (* PI x 0.5))))
#(define (slur-height w h_inf r_0)
   (F0_1 (* (/ (* w r_0) h_inf) h_inf)))

#(define (make-tie-stencil width thickness direction)
  (let* ((height-limit 1)
         (ratio 0.25)
         (angularity 0.5)
         (height (slur-height width height-limit ratio)))
  (make-bow-stencil width (* direction height) thickness angularity)))

#(define (replace-gliss-with-tie which)
  "
   Takes a Glissando and replaces the stencil with a tie-stencil, made by
   'make-tie-stencil'.
   The Glissando is selected by @var{which} from simultaneous ones.
   Other stencils are set #f.
  "
  (lambda (grob)
    (let* ((gliss-count (ly:grob-property grob 'glissando-index))
           (x-ext (ly:stencil-extent (ly:grob-property grob 'stencil) X))
           (x-length (interval-length x-ext))
           (left-bound-info (ly:grob-property grob 'left-bound-info))
           (Y-off (assoc-get 'Y left-bound-info))
           (thick (ly:grob-property grob 'thickness 0.12)))
      (ly:grob-set-property! grob 'stencil
        (if (= gliss-count (- which 1))
            (ly:stencil-translate
              (make-tie-stencil
                x-length
                thick
                UP)
              (cons (car x-ext) Y-off))
             #f)))))
bgl =
#(define-music-function (nmbr m)((number? 1) ly:music?)
  "
   Changes a selected Glissando in TabVoice to a flat Bow.  The
default selection for
   a Glissando with an EventChord is the first typed note.
   The Glissando is added to an EventChord or NoteEvent.
  "
  (cond ((music-is-of-type? m 'event-chord)
         (ly:music-set-property! m 'elements
           (cons
             (make-music 'GlissandoEvent)
             (ly:music-property m 'elements))))
        ((music-is-of-type? m 'note-event)
         (ly:music-set-property! m 'articulations
           (cons
             (make-music 'GlissandoEvent)
             (ly:music-property m 'articulations))))
        (else m))
  #{
    \override TabVoice.Glissando.after-line-breaking =
      #(replace-gliss-with-tie nmbr)
    $m
  #})

%% If a Glissando should pass a NoteColumn use:
skip-column =
  \once \override NoteColumn #'glissando-skip = ##t

%% Stem-settings in Tabs
settings-for-stems-in-tabs =
  \with {
      \override Stem #'avoid-note-head = ##f
      \override Stem.layer = -100
      \override TabNoteHead.stem-attachment = #'(0 . 0)
      \override TabNoteHead.stencil =
      #(lambda (grob)
        (let ((default-stil (tab-note-head::print grob)))
          (ly:make-stencil
            (ly:stencil-expr default-stil)
            (ly:stencil-extent default-stil X)
            (interval-widen (ly:stencil-extent default-stil Y) 0.2))))
  }

%% My collected settings for Tabs
my-tabs-settings =
  \with {
    \tabFullNotation
    \settings-for-stems-in-tabs
  }

mus = {
  \bgl #2
  <bis'\1 g\4  >16[
  \skip-column
  <fis'\2 ees\5>
  <g d>]
}

%% Ofcourse only feasable for TabStaff, lots of ugly Glissandos in
%% usual Staff !
<<
\new Staff
  { \clef "G_8" \mus }
\new TabStaff \my-tabs-settings
  \mus
>>




Cheers,
  Harm



reply via email to

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