大譜表をまたぐスラーの調整

 大譜表をまたぐフレーズにスラーをかける時、スラーの終わりが思った位置に来ないことがある。

\version "2.12.0" \paper { indent = 0 line-width = 10 \cm } \new PianoStaff << \new Staff = "rh" { s1*2 } \new Staff = "lh" { \clef bass \oneVoice \change Staff = rh b'8 ( a' dis' e' f' fis' g' e' \change Staff = lh \voiceOne << { \voiceOne d'8 c' b4 ) ~ b4 gis } \new Voice { f1 } >> } >>

 スラーは3次のスプライン曲線(参考:ドキュメント 5.5.4, Modifying Shapes)なので、4つの制御点の位置を決めてやればよいのだが、「計算した位置に対して相対値で動かす」機能がどうも用意されていないらしい。そこで、Slurcontrol-points 属性に対して試行錯誤で決めた値を入れることになる。音符の挿入・削除でレイアウトが変わってしまうと計算し直すハメになる。やれやれ。

\version "2.12.0" \paper { indent = 0 line-width = 10 \cm } \new PianoStaff << \new Staff = "rh" { s1*2 } \new Staff = "lh" { \clef bass \oneVoice \change Staff = rh \override Slur #'control-points = #'((0 . -1) (3 . -9) (26 . 0) (28.5 . -5)) b'8 ( a' dis' e' f' fis' g' e' \change Staff = lh \voiceOne << { \voiceOne d'8 c' b4 ) ~ b4 gis } \new Voice { f1 } >> } >>

 さらに難しいのが、スラーの途中で段が替わるとき。たとえば、先ほどの例で1小節目のあとに \break を入れてみる。

 実はこのケースは、マニュアルの "Difficult Tweaks" の項に例として挙げてあって、after-line-break のコールバック関数を定義すればよい。マニュアルの例は extra-offset を設定するものだが、ここでは control-points の値を変更するようにしてみた。

\version "2.12.0" \paper { indent = 0 line-width = 10 \cm } #(define (broken-slur-tweak grob n) (let* ( ; 段替えで分割されているか? (orig (ly:grob-original grob)) ; もしそうなら、分割されている要素を取り出す (siblings (if (ly:grob? orig) (ly:spanner-broken-into orig) '() ))) ; 分割された2番目の方なら、調整を行う (if (and (>= (length siblings) 2) (eq? (car (last-pair siblings)) grob)) (let* ( ; control-points の値を変更 (m (ly:grob-property grob 'control-points)) (mm (map (lambda (ma na) (cons (+ (car ma) (car na)) (+ (cdr ma) (cdr na)))) m n))) (ly:grob-set-property! grob 'control-points mm))))) \new PianoStaff << \new Staff = "rh" { s1*2 } \new Staff = "lh" { \clef bass \oneVoice \change Staff = rh \override Slur #'after-line-breaking = #(lambda (grob) (broken-slur-tweak grob '((0 . 4) (0 . 6) (0 . 6) (0 . 2)))) % 8つの数値は、調整前の値に対する相対値 b'8 ( a' dis' e' f' fis' g' e' \break % ここで強制改行している \change Staff = lh \voiceOne << { \voiceOne d'8 c' b4 ) ~ b4 gis } \new Voice { f1 } >> } >>

 相対値の方が調整しやすいので、段が替わらないときにもコールバックで引っ掛けられればいいのだが、どうすればいいんだろう?

(2011/10/29 追記)相対値で調整する方法発見しました。→「スラーの調整(その2)

(2011/02/13 作成、2011/10/29 追記)