From 71ae4457dfcc87a4bf4e1157f8d73540848e5418 Mon Sep 17 00:00:00 2001 From: Marc Hohl Date: Tue, 16 Mar 2010 23:27:56 +0000 Subject: [PATCH] Enhancement: tabalture chord repetition For better use with tablature, a new tab-repeat-chord function is provided which takes care of the string information (thanks to Nicolas Sceaux!). A new command \tabChordRepetition is also included to switch to this new repetition style. --- Documentation/notation/fretted-strings.itely | 36 +++++++-- .../regression/tablature-chord-repetition.ly | 30 ++++++++ ly/chord-repetition-init.ly | 75 +++++++++++++------ ly/music-functions-init.ly | 6 +- 4 files changed, 117 insertions(+), 30 deletions(-) create mode 100644 input/regression/tablature-chord-repetition.ly diff --git a/Documentation/notation/fretted-strings.itely b/Documentation/notation/fretted-strings.itely index e331891507..0ef0d10725 100644 --- a/Documentation/notation/fretted-strings.itely +++ b/Documentation/notation/fretted-strings.itely @@ -194,7 +194,7 @@ symbols = { If all musical symbols used in traditional notation should also show up in tablature one has to apply the command @code{\tabFullNotation} in a -@code{TabStaff}-context. Please bear in mind that half notes are +@code{TabStaff}-context. Please bear in mind that half notes are double-stemmed in tablature in order to distinguish them from quarter notes. @@ -221,13 +221,13 @@ symbols = { @funindex minimumFret By default pitches are assigned to the lowest playing position on the -fret-board (first position). Open strings are automatically preferred. +fret-board (first position). Open strings are automatically preferred. If you would like a certain pitch to be played on a specific string -you can add a string number indication to the pitch name. If you +you can add a string number indication to the pitch name. If you define pitch names and string numbers without a chord construct (@code{<>}) the string number indications do not appear in traditional notation. It is much more comfortable to define the playing position -by using the value of @code{minimumFret}. The default value for +by using the value of @code{minimumFret}. The default value for minimumFret is 0. @@ -249,8 +249,34 @@ minimumFret is 0. >> @end lilypond +@funindex \tabChordRepetition -Ties over a line break are parenthesized by default. The same holds for +Chord constructs can be repeated by the chord repetition symbol @code{q}. +To use this feature in combination with tablature, @code{\tabChordRepetition} +is provided. It preserves the string information explicitly given within +chord constructs so repeated chords get identical tablature representations. + +@lilypond[quote,verbatim] +\tabChordRepetition + +guitar = \relative c' { + r8 < gis\4 cis\3 b\2 > ~ q4 q8 ~ q q4 +} + +\new StaffGroup << + \new Staff { + \clef "treble_8" + \override Voice.StringNumber #'transparent = ##t + \guitar + } + \new TabStaff { + \guitar + } +>> +@end lilypond + + +Ties over a line break are parenthesized by default. The same holds for the second alternative of a repeat. @lilypond[quote,ragged-right,verbatim] diff --git a/input/regression/tablature-chord-repetition.ly b/input/regression/tablature-chord-repetition.ly new file mode 100644 index 0000000000..4d31770a35 --- /dev/null +++ b/input/regression/tablature-chord-repetition.ly @@ -0,0 +1,30 @@ +\version "2.13.17" + +\header { + texidoc = "In a TabStaff, the chord repetition function needs +to save the string information. This is handled by +@code{\\tabChordRepetition}." +} + +\tabChordRepetition + +Guitar = \relative c' { + r8 < gis\4 cis\3 b\2 > ~ q4 q8 ~ q q4 +} + +\score { + \new StaffGroup << + \new Staff { + \new Voice { + \clef "treble_8" + \override Voice.StringNumber #'transparent = ##t + \Guitar + } + } + \new TabStaff { + \new TabVoice { + \Guitar + } + } + >> +} diff --git a/ly/chord-repetition-init.ly b/ly/chord-repetition-init.ly index f19e3a10b5..1056cdec2f 100644 --- a/ly/chord-repetition-init.ly +++ b/ly/chord-repetition-init.ly @@ -1,5 +1,5 @@ %%% -*- Mode: Scheme -*- -\version "2.13.9" +\version "2.13.17" %{ The following functions define the chord repetition behavior, and may @@ -16,36 +16,63 @@ ly:parser-set-repetition-function (previous-chord, location, duration, list of articulations) which is supposed to return a new chord. `default-repeat-chord' is the default function set in this file. + `tab-repeat-chord' may be used in tablatures to preserve the string information. %} -#(define-public (default-repeat-chord previous-chord location duration articulations) - "Copy the previous chord, filter out events which are not notes, set -the chord duration, add articulations." +#(define-public ((make-repeat-chord-function chord-element-types note-articulation-types) + previous-chord location duration articulations) + "Make a chord repetition function. +The returned functions copies the notes from @var{previous-chord} into a new chord. +Chord elements, which type is found in @var{chord-element-types}, are copied into +the new chord. Note articulations, which type is found in @var{note-articulation-types}, +are also copied. All other events are not copied into the new chord." + (define (filter-events events event-types) + (filter (lambda (event) + (and (memq (ly:music-property event 'name) event-types) event)) + events)) ;; If previous-chord has an length property, then it means that it ;; has been processed by a music iterator. In other words, the chord - ;; has been memorized in an other music block, which is certainly not - ;; what the user has intended. In that case, raise a warning. + ;; has been memorized from an other music block, which is certainly not + ;; what the user has intended, as anywy the result will be buggy. + ;; In that case, raise a warning. (if (not (and (ly:music? previous-chord) - (null? (ly:music-property previous-chord 'length)))) + (null? (ly:music-property previous-chord 'length)))) (ly:input-message location - (_ "No memorized chord in music block before chord repetition"))) + (_ "No memorized chord in music block before chord repetition"))) ;; Instead of copying the previous chord, then removing the - ;; undesired elements (like articulations), a new empty chord is - ;; built. Then, the pitch found in the previous chord are added to - ;; the new chord, without any "decoration" (e.g. cautionary - ;; accidentals, fingerings, text scripts, articulations). - (make-music - 'EventChord - 'origin location - 'elements (append! (filter identity - (map (lambda (event) - (and (eqv? (ly:music-property event 'name) 'NoteEvent) - (make-music - 'NoteEvent - 'pitch (ly:music-property event 'pitch) - 'duration duration))) - (ly:music-property previous-chord 'elements))) - articulations))) + ;; undesired elements (like articulations), a new empty chord is built. + ;; Then, the pitch found in the previous chord are added to the new + ;; chord, without any "decoration" (e.g. cautionary accidentals, + ;; fingerings, text scripts, articulations). Only the events of types + ;; given in `chord-elements-types' and `note-articulation-types' are + ;; copied from the original chord elements and note articulations, + ;; respectively. + (let ((elements (ly:music-property (ly:music-deep-copy previous-chord) 'elements))) + (make-music + 'EventChord + 'origin location + 'elements (append! + (map (lambda (note) + (let ((new-note (make-music 'NoteEvent + 'pitch (ly:music-property note 'pitch) + 'duration duration)) + (articulations + (filter-events (ly:music-property note 'articulations) + note-articulation-types))) + (if (not (null? articulations)) + (set! (ly:music-property new-note 'articulations) + articulations)) + new-note)) + (filter-events elements '(NoteEvent))) + (filter-events elements chord-element-types) + articulations)))) +#(define-public default-repeat-chord + (make-repeat-chord-function '() '())) + +#(define-public tab-repeat-chord + (make-repeat-chord-function '(StringNumberEvent) '(StringNumberEvent))) + +% default settings #(ly:parser-set-repetition-symbol parser 'q) #(ly:parser-set-repetition-function parser default-repeat-chord) diff --git a/ly/music-functions-init.ly b/ly/music-functions-init.ly index f49797ec81..71a834ba2d 100644 --- a/ly/music-functions-init.ly +++ b/ly/music-functions-init.ly @@ -775,7 +775,11 @@ styledNoteHeads = (_i "Set @var{heads} in @var{music} to @var{style}.") (style-note-heads heads style music)) - +tabChordRepetition = +#(define-music-function (parser location) () + (_i "Include the string information in a chord repetition.") + (ly:parser-set-repetition-function parser tab-repeat-chord) + (make-music 'SequentialMusic 'void #t)) tag = #(define-music-function (parser location tag arg) -- 2.39.2