From: Carl Sorensen Date: Wed, 30 Jul 2008 03:26:57 +0000 (-0600) Subject: Add predefined fret diagrams to FretBoards context X-Git-Tag: release/2.11.56-1~2^2~43^2~17 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=2d532bb826559cdb52f1414dabefd23efdbc91a4;p=lilypond.git Add predefined fret diagrams to FretBoards context --- diff --git a/Documentation/user/fretted-strings.itely b/Documentation/user/fretted-strings.itely index e49b1bc739..6052386b1e 100644 --- a/Documentation/user/fretted-strings.itely +++ b/Documentation/user/fretted-strings.itely @@ -36,8 +36,9 @@ to fretted string instruments. * String number indications:: * Default tablatures:: * Custom tablatures:: -* Automatic fret diagrams:: * Fret diagram markups:: +* Predefined fret diagrams:: +* Automatic fret diagrams:: * Right-hand fingerings:: @end menu @@ -286,115 +287,6 @@ Internals Reference: No guitar special effects have been implemented. -@node Automatic fret diagrams -@subsubsection Automatic fret diagrams -@cindex fret diagrams -@cindex chord diagrams - -Fret diagrams can be automatically created from entered notes using the -@code{FretBoards} context. This context calculates strings and frets -which can be used to play the notes. - -@lilypond[quote,ragged-right,verbatim] -<< - \context ChordNames { - \chordmode { - f1 g - } - } - \context FretBoards { - < f, c f a c' f'>1 - < g,\6 b, d g b g'> - } - \context Staff { - \clef "treble_8" - < f, c f a c' f'>1 - < g, b, d g b' g'> - } ->> -@end lilypond - -Notes can be explicitly placed on a string. It is often enough -to place only the lowest note on an explicit string; the rest of -the notes will then be placed appropriately by the @code{FretBoards} -context. - -@lilypond[quote,ragged-right,verbatim] -<< - \context ChordNames { - \chordmode { - c1 c d:m d:m - } - } - \context FretBoards { - < c e g c' e' > 1 - < c\5 e g c' e' > 1 - < d a d' f'> - < d\4 a d' f'> - } - \context Staff { - \clef "treble_8" - < c e g c' e' > 1 - < c e g c' e' > 1 - < d a d' f'> - < d a d' f'> - } ->> -@end lilypond - -Fingerings can be added to FretBoard fret diagrams. - -@lilypond[quote, verbatim] -<< - \context ChordNames { - \chordmode { - c1 d:m - } - } - \context FretBoards { - < c\5-3 e-2 g c'-1 e' > 1 - < d\4 a-2 d'-3 f'-1> - } - \context Staff { - \clef "treble_8" - < c e g c' e' > 1 - < d a d' f'> - } ->> -@end lilypond - -The strings and frets for the @code{FretBoards} context depend -on the @code{stringTunings} property, which has the same meaning -as in the TabStaff context. See @ref{Custom tablatures} for -information on the @code{stringTunings} property. - -The graphical layout of a fret diagram can be customized according to -user preference through the properties of the @code{fret-diagram-interface}. -Details are found at @rinternals{fret-diagram-interface}. For a -@code{FretBoards} fret diagram, the interface properties belong to -@code{FretBoards}. - -@snippets -The minimum fret to be used in calculating strings and frets for -the FretBoard context can be set with the @code{minimumFret} -property. - -@c TODO -- snippet showing minimum fret. - -@c TODO -- snippet for using StringTunings - -@seealso - -Notation Reference: -@ref{Custom tablatures} - -Snippets: -@rlsr{Fretted strings}. - -Internals Reference: -@rinternals {fret-diagram-interface}. - - @node Fret diagram markups @subsubsection Fret diagram markups @cindex fret diagrams @@ -724,7 +616,174 @@ Snippets: Internals Reference: @rinternals{fret-diagram-interface}. -@node Right-hand fingerings +@@node Predefined fret diagrams +@subsbusection Predefined fret diagrams +@cindex fret diagrams +@cindex chord diagrams + +Fret diagrams can be displayed using the @code{FretBoards} context. By +default, the @code{FretBoards} context will display fret diagrams that +are stored in a lookup table: + +TODO -- simple example of fretboards + +Fret diagrams are stored based on the pitches of a chord and the value of +@code{StringTunings} that is currently in use. Currently, predefined chords +are available only for @code{guitar-tuning}. Chord pitches can be entered +either as simultaneous music or using chord mode @ref{Chords}. + +TODO -- example of different chords, with and without chordmode + +It is common that both chord names and fret diagrams are displayed together. +This is achieved by putting a @code{ChordNames} context in parallel with +a @node{FretBoards} context and giving both contexts the same music. + +TODO -- example of ChordNames in parallel with FretBoards + +Predefined fret diagrams are transposable, as long as a diagram for the +transposed chord is stored in the fret diagram table. + +TODO -- example of transposition + +The predefined fret diagram table contains seven chords (major, minor, +augmented, diminished, dominant seventh, major seventh, minor seventh) +for each of 17 keys (C, C\sharp?, D\flat, D, D\sharp, E\flat, E, F, +F\sharp, G\flat, G, G\sharp, A\flat, A, A\sharp, B\flat, and B). A +complete list of the predefined fret diagrams is shown in TODO ref to +appendix. If there is no entry in the table for a chord, the FretBoards +engraver will calculate a fret-diagram using the automatic fret diagram +functionality described in @ref{Automatic fret diagrams}. + +TODO -- example of existing chord, non-existing chord + +Fret diagrams can be added to the fret diagram table. To add a diagram you +must specify the chord for the diagram, the tuning to be used, and the +fret-diagram-terse definition string for the diagram. + +TODO -- add a few diagrams to the table and display it + +Different fret diagrams for the same chord name can be stored using different +octaves of pitches. + +TODO -- show the use of different fret diagrams + +In addition to fret diagrams, LilyPond stores an internal list of chord +shapes. + +The appearance of the fret diagrams is controlled using the +@code{fret-diagram-interface}, which is explained in @ref{}. + + +@@node Automatic fret diagrams +@subsubsection Automatic fret diagrams +@cindex fret diagrams +@cindex chord diagrams + +Fret diagrams can be automatically created from entered notes using the +@code{FretBoards} context. This context calculates strings and frets +which can be used to play the notes. + +@lilypond[quote,ragged-right,verbatim] +<< + \context ChordNames { + \chordmode { + f1 g + } + } + \context FretBoards { + < f, c f a c' f'>1 + < g,\6 b, d g b g'> + } + \context Staff { + \clef "treble_8" + < f, c f a c' f'>1 + < g, b, d g b' g'> + } +>> +@end lilypond + +Notes can be explicitly placed on a string. It is often enough +to place only the lowest note on an explicit string; the rest of +the notes will then be placed appropriately by the @code{FretBoards} +context. + +@lilypond[quote,ragged-right,verbatim] +<< + \context ChordNames { + \chordmode { + c1 c d:m d:m + } + } + \context FretBoards { + < c e g c' e' > 1 + < c\5 e g c' e' > 1 + < d a d' f'> + < d\4 a d' f'> + } + \context Staff { + \clef "treble_8" + < c e g c' e' > 1 + < c e g c' e' > 1 + < d a d' f'> + < d a d' f'> + } +>> +@end lilypond + +Fingerings can be added to FretBoard fret diagrams. + +@lilypond[quote, verbatim] +<< + \context ChordNames { + \chordmode { + c1 d:m + } + } + \context FretBoards { + < c\5-3 e-2 g c'-1 e' > 1 + < d\4 a-2 d'-3 f'-1> + } + \context Staff { + \clef "treble_8" + < c e g c' e' > 1 + < d a d' f'> + } +>> +@end lilypond + +The strings and frets for the @code{FretBoards} context depend +on the @code{stringTunings} property, which has the same meaning +as in the TabStaff context. See @ref{Custom tablatures} for +information on the @code{stringTunings} property. + +The graphical layout of a fret diagram can be customized according to +user preference through the properties of the @code{fret-diagram-interface}. +Details are found at @rinternals{fret-diagram-interface}. For a +@code{FretBoards} fret diagram, the interface properties belong to +@code{FretBoards}. + +@snippets +The minimum fret to be used in calculating strings and frets for +the FretBoard context can be set with the @code{minimumFret} +property. + +@c TODO -- snippet showing minimum fret. + +@c TODO -- snippet for using StringTunings + +@seealso + +Notation Reference: +@ref{Custom tablatures} + +Snippets: +@rlsr{Fretted strings}. + +Internals Reference: +@rinternals {fret-diagram-interface}. + + +node Right-hand fingerings @subsubsection Right-hand fingerings Right-hand fingerings @var{p-i-m-a} must be entered within a diff --git a/lily/fretboard-engraver.cc b/lily/fretboard-engraver.cc index b75156f545..f284161a80 100644 --- a/lily/fretboard-engraver.cc +++ b/lily/fretboard-engraver.cc @@ -97,7 +97,8 @@ ADD_TRANSLATOR (Fretboard_engraver, "minimumFret " "maximumFretStretch " "tablatureFormat " - "highStringOne ", + "highStringOne " + "predefinedDiagramTable", /* write */ "" diff --git a/ly/declarations-init.ly b/ly/declarations-init.ly index b8c36e4f33..88fdfe1c03 100644 --- a/ly/declarations-init.ly +++ b/ly/declarations-init.ly @@ -63,6 +63,7 @@ escapedBiggerSymbol = #(make-span-event 'DecrescendoEvent START) escapedSmallerSymbol = #(make-span-event 'CrescendoEvent START) +#(define fretboard-table (make-hash-table 100)) \include "scale-definitions-init.ly" @@ -117,3 +118,6 @@ setDefaultDurationToQuarter = { c4 } #(define book-music-handler collect-book-music-for-book) #(define book-score-handler ly:book-add-score!) #(define book-text-handler ly:book-add-score!) + + +\include "predefined-fretboards-init.ly" diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index ffee024a1c..022fb8a1d9 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -22,6 +22,8 @@ \consists "Separating_line_group_engraver" \consists "Font_size_engraver" \consists "Instrument_name_engraver" + + predefinedDiagramTable = #fretboard-table } \context { diff --git a/ly/predefined-fretboards-init.ly b/ly/predefined-fretboards-init.ly new file mode 100644 index 0000000000..587d7f37e6 --- /dev/null +++ b/ly/predefined-fretboards-init.ly @@ -0,0 +1,481 @@ +%%%% predefined-fretboard-init.ly +%%%% +%%%% source file of the GNU LilyPond music typesetter +%%%% +%%%% (c) 2008 Carl D. Sorensen + +%%%%% define storage structures + +% base-chord-shapes is an alist of chord shapes +% in the form of fret-diagram-terse strings with +% scheme symbols as keys. For convenience, the +% symbols are LilyPond chordmode chord descriptions, +% but that is unnecessary. + +#(define base-chord-shapes + (list + '(f . "1-1-(;3-3;3-4;2-2;1-1;1-1-);") + '(f:m . "1-1-(;3-3;3-4;1-1;1-1;1-1-);") + '(f:7 . "1-1-(;3-3;1-1;2-2;1-1;1-1-);") + '(f:m7 . "1-1-(;3-3;1-1;1-1;1-1;1-1-);") + '(bes . "x;1-1-(;3-2;3-3;3-4;1-1-);") + '(bes:m . "x;1-1-(;3-3;3-4;2-2;1-1-);") + '(bes:m7 . "x;1-1-(;3-3;1-1;2-2;1-1-);") + '(bes:7 . "x;1-1-(;3-2;1-1;3-3;1-1-);") + '(bes:maj7 . "x;1-1;3-3;2-2;3-4;x;") + '(c:dim . "x;x;1-1;2-3;1-2;2-4;") + '(c:aug . "x;x;2-2;1-1-(;1-1-);4-4;") + '(cis . "x;x;3-3;1-1-(;2-2;1-1-);") + '(ees:dim . "x;x;1-1;2-3;1-2;2-4;") + '(a:dim . "x;x;1-1;2-3;1-2;2-4;") + )) + + +% music function for adding a chord shape to +% base-chord-shapes + +addChordShape = +#(define-music-function (parser location shape-pair) + (pair?) + (set! base-chord-shapes (acons + (car shape-pair) + (cdr shape-pair) + base-chord-shapes)) + (make-music 'SequentialMusic 'void #t)) + + +% music function for adding a predefined diagram to +% fretboard-table + +storePredefinedDiagram = +#(define-music-function (parser location chord tuning terse-definition) + (ly:music? list? string?) + (let* ((pitches (event-chord-pitches + (car (extract-named-music chord 'EventChord)))) + (hash-key (cons tuning pitches))) + (hash-set! fretboard-table + hash-key + (parse-terse-string terse-definition))) + (make-music 'SequentialMusic 'void #t)) + + +% for convenience, to eliminate storage list in .ly references + +#(define (chord-shape shape-code) + (get-chord-shape shape-code base-chord-shapes)) + +#(define predefined-diagram-table fretboard-table) + +%%%%%%%%%%%%%%%%%%%%%%% +%%% + +% definitions of predefined diagrams below here + +%%%% c chords +% +\storePredefinedDiagram \chordmode {c} + #guitar-tuning + #"x;3-3;2-2;o;1-1;o;" +\storePredefinedDiagram \chordmode {c:m} + #guitar-tuning + #(offset-fret 2 (chord-shape 'bes:m)) +\storePredefinedDiagram \chordmode {c:aug} + #guitar-tuning + #(chord-shape 'c:aug) +\storePredefinedDiagram \chordmode {c:dim} + #guitar-tuning + #(chord-shape 'c:dim) +\storePredefinedDiagram \chordmode {c:7} + #guitar-tuning + #"o;3-3;2-2;3-4;1-1;o;" +\storePredefinedDiagram \chordmode {c:maj7} + #guitar-tuning + #"x;3-3;2-2;o;o;o;" +\storePredefinedDiagram \chordmode {c:m7} + #guitar-tuning + #(offset-fret 2 (chord-shape 'bes:m7)) + +%%%% cis chords +% +\storePredefinedDiagram \chordmode {cis} + #guitar-tuning + #(chord-shape 'cis) +\storePredefinedDiagram \chordmode {cis:m} + #guitar-tuning + #"x;x;2-2;1-1;2-3;o;" +\storePredefinedDiagram \chordmode {cis:aug} + #guitar-tuning + #"x;4-4;3-3;2-1;2-2;x;" +\storePredefinedDiagram \chordmode {cis:dim} + #guitar-tuning + #(offset-fret 1 (chord-shape 'c:dim)) +\storePredefinedDiagram \chordmode {cis:7} + #guitar-tuning + #"x;x;3-2;4-3;2-1;4-4;" +\storePredefinedDiagram \chordmode {cis:maj7} + #guitar-tuning + #"x;4-4;3-3;1-1-(;1-1;1-1-);" +\storePredefinedDiagram \chordmode {cis:m7} + #guitar-tuning + #"x;4-4;2-2;1-1;o;o;" + +%%%% des chords +% +\storePredefinedDiagram \chordmode {des} + #guitar-tuning + #"x;x;3-3;1-1-(;2-2;1-1-);" +\storePredefinedDiagram \chordmode {des:m} + #guitar-tuning + #"x;x;2-2;1-1;2-3;o;" +\storePredefinedDiagram \chordmode {des:aug} + #guitar-tuning + #"x;4-4;3-3;2-1;2-2;x;" +\storePredefinedDiagram \chordmode {des:dim} + #guitar-tuning + #(offset-fret 1 (chord-shape 'c:dim)) +\storePredefinedDiagram \chordmode {des:7} + #guitar-tuning + #"x;x;3-2;4-3;2-1;4-4;" +\storePredefinedDiagram \chordmode {des:maj7} + #guitar-tuning + #"x;4-4;3-3;1-1-(;1-1;1-1-);" +\storePredefinedDiagram \chordmode {des:m7} + #guitar-tuning + #"x;4-4;2-2;1-1;o;o;" + +%%%% d chords +% +\storePredefinedDiagram \chordmode {d} + #guitar-tuning + #"x;x;o;2-1;3-2;2-3;" +\storePredefinedDiagram \chordmode {d:m} + #guitar-tuning + #"x;x;o;2-2;3-3;1-1;" +\storePredefinedDiagram \chordmode {d:aug} + #guitar-tuning + #"x;x;o;3-2;3-3;2-1;" +\storePredefinedDiagram \chordmode {d:dim} + #guitar-tuning + #"x;x;o;1-1;o;1-2;" +\storePredefinedDiagram \chordmode {d:7} + #guitar-tuning + #"x;x;o;2-2;1-1;2-3;" +\storePredefinedDiagram \chordmode {d:maj7} + #guitar-tuning + #"x;x;o;2-1;2-2;2-3;" +\storePredefinedDiagram \chordmode {d:m7} + #guitar-tuning + #"x;x;o;2-2;1-1-(;1-1-);" + +%%%% dis chords +% +\storePredefinedDiagram \chordmode {dis} + #guitar-tuning + #(offset-fret 2 (chord-shape 'cis)) +\storePredefinedDiagram \chordmode {dis:m} + #guitar-tuning + #"x;x;4-3;3-2;4-4;1-1;" +\storePredefinedDiagram \chordmode {dis:aug} + #guitar-tuning + #"3-3;2-2;1-1;o;o;3-4" +\storePredefinedDiagram \chordmode {dis:dim} + #guitar-tuning + #(chord-shape 'ees:dim) +\storePredefinedDiagram \chordmode {dis:7} + #guitar-tuning + #"x;x;1-1;3-3;2-2;3-4;" +\storePredefinedDiagram \chordmode {dis:maj7} + #guitar-tuning + #"x;x;1-1;3-2;3-3;3-4;" +\storePredefinedDiagram \chordmode {dis:m7} + #guitar-tuning + #"x;x;1-1;3-2;2-3;2-4;" + +%%%% ees chords +% +\storePredefinedDiagram \chordmode {ees} + #guitar-tuning + #(offset-fret 2 (chord-shape 'cis)) +\storePredefinedDiagram \chordmode {ees:m} + #guitar-tuning + #"x;x;4-3;3-2;4-4;1-1;" +\storePredefinedDiagram \chordmode {ees:aug} + #guitar-tuning + #"3-3;2-2;1-1;o;o;3-4" +\storePredefinedDiagram \chordmode {ees:dim} + #guitar-tuning + #(chord-shape 'ees:dim) +\storePredefinedDiagram \chordmode {ees:7} + #guitar-tuning + #"x;x;1-1;3-3;2-2;3-4;" +\storePredefinedDiagram \chordmode {ees:maj7} + #guitar-tuning + #"x;x;1-1;3-2;3-3;3-4;" +\storePredefinedDiagram \chordmode {ees:m7} + #guitar-tuning + #"x;x;1-1;3-2;2-3;2-4;" + +%%%% e chords +% +\storePredefinedDiagram \chordmode {e} + #guitar-tuning + #"o;2-2;2-3;1-1;o;o;" +\storePredefinedDiagram \chordmode {e:m} + #guitar-tuning + #"o;2-2;2-3;o;o;o;" +\storePredefinedDiagram \chordmode {e:aug} + #guitar-tuning + #"o;3-3;2-2;1-1;x;x;" +\storePredefinedDiagram \chordmode {e:dim} + #guitar-tuning + #(offset-fret 1 (chord-shape 'ees:dim)) +\storePredefinedDiagram \chordmode {e:7} + #guitar-tuning + #"o;2-2;o;1-1;o;o;" +\storePredefinedDiagram \chordmode {e:maj7} + #guitar-tuning + #"o;2-3;1-1;1-2;o;x;" +\storePredefinedDiagram \chordmode {e:m7} + #guitar-tuning + #"o;2-2;o;o;o;o;" + +%%%% f chords +% +\storePredefinedDiagram \chordmode {f} + #guitar-tuning + #(chord-shape 'f) +\storePredefinedDiagram \chordmode {f:m} + #guitar-tuning + #(chord-shape 'f:m) +\storePredefinedDiagram \chordmode {f:aug} + #guitar-tuning + #"x;x;1-1;4-3;4-4;3-2;" +\storePredefinedDiagram \chordmode {f:dim} + #guitar-tuning + #"x;x;o;1-1;o;1-2;" +\storePredefinedDiagram \chordmode {f:7} + #guitar-tuning + #(chord-shape 'f:7) +\storePredefinedDiagram \chordmode {f:maj7} + #guitar-tuning + #"x;3-3;3-4;2-2;1-1;" +\storePredefinedDiagram \chordmode {f:m7} + #guitar-tuning + #(chord-shape 'f:m7) + +%%%% fis chords +% +\storePredefinedDiagram \chordmode {fis} + #guitar-tuning + #(offset-fret 1 (chord-shape 'f)) +\storePredefinedDiagram \chordmode {fis:m} + #guitar-tuning + #(offset-fret 1 (chord-shape 'f:m)) +\storePredefinedDiagram \chordmode {fis:aug} + #guitar-tuning + #"2-2;1-1;o;3-4-(;3-4-);2-3;" +\storePredefinedDiagram \chordmode {fis:dim} + #guitar-tuning + #"x;x;1-1;2-3;1-2;2-4;" +\storePredefinedDiagram \chordmode {fis:7} + #guitar-tuning + #(offset-fret 1 (chord-shape 'f:7)) +\storePredefinedDiagram \chordmode {fis:maj7} + #guitar-tuning + #"x;x;4-4;3-3;2-2;1-1;" +\storePredefinedDiagram \chordmode {fis:m7} + #guitar-tuning + #(offset-fret 1 (chord-shape 'f:m7)) + +%%%% ges chords +% +\storePredefinedDiagram \chordmode {ges} + #guitar-tuning + #(offset-fret 1 (chord-shape 'f)) +\storePredefinedDiagram \chordmode {ges:m} + #guitar-tuning + #(offset-fret 1 (chord-shape 'f:m)) +\storePredefinedDiagram \chordmode {ges:aug} + #guitar-tuning + #"2-2;1-1;o;3-4-(;3-4-);2-3;" +\storePredefinedDiagram \chordmode {ges:dim} + #guitar-tuning + #"x;x;1-1;2-3;1-2;2-4;" +\storePredefinedDiagram \chordmode {ges:7} + #guitar-tuning + #(offset-fret 1 (chord-shape 'f:7)) +\storePredefinedDiagram \chordmode {ges:maj7} + #guitar-tuning + #"x;x;4-4;3-3;2-2;1-1;" +\storePredefinedDiagram \chordmode {ges:m7} + #guitar-tuning + #(offset-fret 1 (chord-shape 'f:m7)) + +%%%% g chords +% +\storePredefinedDiagram \chordmode {g} + #guitar-tuning + #"3-2;2-1;o;o;o;3-3;" +\storePredefinedDiagram \chordmode {g:m} + #guitar-tuning + #(offset-fret 2 (chord-shape 'f:m)) +\storePredefinedDiagram \chordmode {g:aug} + #guitar-tuning + #"x;x;5-1;8-3;8-4;7-2;" +\storePredefinedDiagram \chordmode {g:dim} + #guitar-tuning + #"x;x;5-2;6-4;5-3;3-1;" +\storePredefinedDiagram \chordmode {g:7} + #guitar-tuning + #"3-3;2-2;o;o;o;1-1;" +\storePredefinedDiagram \chordmode {g:maj7} + #guitar-tuning + #"x;x;5-4;4-3;3-2;2-1;" +\storePredefinedDiagram \chordmode {g:m7} + #guitar-tuning + #(offset-fret 2 (chord-shape 'f:m7)) + +%%%% gis chords +% +\storePredefinedDiagram \chordmode {gis} + #guitar-tuning + #(offset-fret 3 (chord-shape 'f)) +\storePredefinedDiagram \chordmode {gis:m} + #guitar-tuning + #(offset-fret 3 (chord-shape 'f:m)) +\storePredefinedDiagram \chordmode {gis:aug} + #guitar-tuning + #"o;3-4;2-3;1-1;1-2;o;" +\storePredefinedDiagram \chordmode {gis:dim} + #guitar-tuning + #"x;x;o;1-1;o;1-2;" +\storePredefinedDiagram \chordmode {gis:7} + #guitar-tuning + #(offset-fret 3 (chord-shape 'f:7)) +\storePredefinedDiagram \chordmode {gis:maj7} + #guitar-tuning + #"x;x;1-1-(;1-1;1-1-);3-3;" +\storePredefinedDiagram \chordmode {gis:m7} + #guitar-tuning + #(offset-fret 3 (chord-shape 'f:m7)) + +%%%% aes chords +% +\storePredefinedDiagram \chordmode {aes} + #guitar-tuning + #(offset-fret 3 (chord-shape 'f)) +\storePredefinedDiagram \chordmode {aes:m} + #guitar-tuning + #(offset-fret 3 (chord-shape 'f:m)) +\storePredefinedDiagram \chordmode {aes:aug} + #guitar-tuning + #"o;3-4;2-3;1-1;1-2;o;" +\storePredefinedDiagram \chordmode {aes:dim} + #guitar-tuning + #"x;x;o;1-1;o;1-2;" +\storePredefinedDiagram \chordmode {aes:7} + #guitar-tuning + #(offset-fret 3 (chord-shape 'f:7)) +\storePredefinedDiagram \chordmode {aes:maj7} + #guitar-tuning + #"x;x;1-1-(;1-1;1-1-);3-3;" +\storePredefinedDiagram \chordmode {aes:m7} + #guitar-tuning + #(offset-fret 3 (chord-shape 'f:m7)) + +%%%% a chords +% +\storePredefinedDiagram \chordmode {a} + #guitar-tuning + #"x;o;2-1;2-2;2-3;o;" +\storePredefinedDiagram \chordmode {a:m} + #guitar-tuning + #"x;o;2-2;2-3;1-1;o;" +\storePredefinedDiagram \chordmode {a:aug} + #guitar-tuning + #"x;o;3-4;2-2;2-3;1-1;" +\storePredefinedDiagram \chordmode {a:dim} + #guitar-tuning + #(chord-shape 'a:dim) +\storePredefinedDiagram \chordmode {a:7} + #guitar-tuning + #"x;o;2-1;o;2-3;o;" +\storePredefinedDiagram \chordmode {a:maj7} + #guitar-tuning + #"x;o;2-2;1-1;2-3;o;" +\storePredefinedDiagram \chordmode {a:m7} + #guitar-tuning + #"x;o;2-2;o;1-1;o;" + +%%%% ais chords +% +\storePredefinedDiagram \chordmode {ais} + #guitar-tuning + #(chord-shape 'bes) +\storePredefinedDiagram \chordmode {ais:m} + #guitar-tuning + #(chord-shape 'bes:m) +\storePredefinedDiagram \chordmode {ais:aug} + #guitar-tuning + #"2-2;1-1;o;3-4-(;3-4-);2-3;" +\storePredefinedDiagram \chordmode {ais:dim} + #guitar-tuning + #(offset-fret 1 (chord-shape 'a:dim)) +\storePredefinedDiagram \chordmode {ais:7} + #guitar-tuning + #(chord-shape 'bes:7) +\storePredefinedDiagram \chordmode {ais:maj7} + #guitar-tuning + #"x;1-1;3-3;2-2;3-4;x;" +\storePredefinedDiagram \chordmode {ais:m7} + #guitar-tuning + #(chord-shape 'bes:m7) + +%%%% bes chords +% +\storePredefinedDiagram \chordmode {bes} + #guitar-tuning + #(chord-shape 'bes) +\storePredefinedDiagram \chordmode {bes:m} + #guitar-tuning + #(chord-shape 'bes:m) +\storePredefinedDiagram \chordmode {bes:aug} + #guitar-tuning + #"2-2;1-1;o;3-4-(;3-4-);2-3;" +\storePredefinedDiagram \chordmode {bes:dim} + #guitar-tuning + #(offset-fret 1 (chord-shape 'a:dim)) +\storePredefinedDiagram \chordmode {bes:7} + #guitar-tuning + #(chord-shape 'bes:7) +\storePredefinedDiagram \chordmode {bes:maj7} + #guitar-tuning + #"x;1-1;3-3;2-2;3-4;x;" +\storePredefinedDiagram \chordmode {bes:m7} + #guitar-tuning + #(chord-shape 'bes:m7) + +%%%% b chords +% +\storePredefinedDiagram \chordmode {b} + #guitar-tuning + #(offset-fret 1 (chord-shape 'bes)) +\storePredefinedDiagram \chordmode {b:m} + #guitar-tuning + #(offset-fret 1 (chord-shape 'bes:m)) +\storePredefinedDiagram \chordmode {b:aug} + #guitar-tuning + #"x;3-2;2-1;o;o;x;" +\storePredefinedDiagram \chordmode {b:dim} + #guitar-tuning + #"x;x;o;1-1;o;1-2;" +\storePredefinedDiagram \chordmode {b:7} + #guitar-tuning + #(offset-fret 1 (chord-shape 'bes:7)) +\storePredefinedDiagram \chordmode {b:maj7} + #guitar-tuning + #"x;2-1;4-3;3-2;4-4;x;" +\storePredefinedDiagram \chordmode {b:m7} + #guitar-tuning + #(offset-fret 1 (chord-shape 'bes:m7)) + diff --git a/ly/property-init.ly b/ly/property-init.ly index 9098d313cf..0ed5d49f5b 100644 --- a/ly/property-init.ly +++ b/ly/property-init.ly @@ -341,3 +341,11 @@ bassFigureStaffAlignmentNeutral = { \revert Staff.BassFigureAlignmentPositioning #'direction } +predefinedFretboardsOff = { + \set FretBoards.predefinedDiagramTable = ##f +} + +predefinedFretboardsOn = { + \set FretBoards.predefinedDiagramTable = #fretboard-table +} + diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index a9ca43f9f7..cbd0e1544b 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -345,6 +345,8 @@ the pedal.") sustain pedals: @code{text}, @code{bracket} or @code{mixed} (both).") (pedalUnaCordaStrings ,list? "See @code{pedalSustainStrings}.") (pedalUnaCordaStyle ,symbol? "See @code{pedalSustainStyle}.") + (predefinedDiagramTable ,hash-table? "The hash table of predefined +fret diagrams to use in FretBoards.") (printKeyCancellation ,boolean? "Print restoration alterations before a key signature change.") (printOctaveNames ,boolean? "Print octave marks for the @@ -466,8 +468,7 @@ setting this property, you can make brackets last shorter. (useBassFigureExtenders ,boolean? "Whether to use extender lines for repeated bass figures.") - - + (verticallySpacedContexts ,list? "List of symbols, containing context names whose vertical axis groups should be taken into account for vertical spacing of systems.") diff --git a/scm/define-grob-interfaces.scm b/scm/define-grob-interfaces.scm index d5f5d36fcd..8b0dde24f8 100644 --- a/scm/define-grob-interfaces.scm +++ b/scm/define-grob-interfaces.scm @@ -53,7 +53,7 @@ note)." (ly:add-interface 'fret-diagram-interface "A fret diagram" - '(align-dir fret-diagram-details size string-fret-finger-combinations + '(align-dir fret-diagram-details size dot-placement-list thickness)) (ly:add-interface diff --git a/scm/define-grob-properties.scm b/scm/define-grob-properties.scm index b48cbc25fc..8d2de51b14 100644 --- a/scm/define-grob-properties.scm +++ b/scm/define-grob-properties.scm @@ -168,6 +168,10 @@ other object. Otherwise, it determines whether the object is placed be used: @code{#UP}=@code{1}, @code{#DOWN}=@code{-1}, @code{#LEFT}=@code{-1}, @code{#RIGHT}=@code{1}, @code{#CENTER}=@code{0}.") (dot-count ,integer? "The number of dots.") + (dot-placement-list ,list? "List +consisting of @code{@var{description} (@var{string-number} +@var{fret-number} @var{finger-number})} +entries used to define fret diagrams.") (duration-log ,integer? "The 2-log of the note head duration, i.e., @code{0} = whole note, @code{1} = half note, etc.") @@ -566,9 +570,6 @@ are not spaced separately, but put before musical columns.") (strict-note-spacing ,boolean? "If set, unbroken columns with non-musical material (clefs, bar lines, etc.) are not spaced separately, but put before musical columns.") - (string-fret-finger-combinations ,list? "List consisting of -@code{(@var{string-number} @var{fret-number} @var{finger-number})} -entries.") (stroke-style ,string? "Set to @code{\"grace\"} to turn stroke through flag on.") (style ,symbol? "This setting determines in what style a grob is diff --git a/scm/fret-diagrams.scm b/scm/fret-diagrams.scm index 6378f7d12f..84d9453828 100644 --- a/scm/fret-diagrams.scm +++ b/scm/fret-diagrams.scm @@ -2,7 +2,7 @@ ;;;; ;;;; source file of the GNU LilyPond music typesetter ;;;; -;;;; (c) 2004--2007 Carl D. Sorensen +;;;; (c) 2004--2008 Carl D. Sorensen (define (fret-parse-marking-list marking-list fret-count) (let* ((fret-range (list 1 fret-count)) @@ -366,7 +366,8 @@ Line thickness is given by @var{th}, fret & string spacing by (make-bezier-sandwich-list (* size barre-start-string-coordinate) (* size barre-end-string-coordinate) - (* size (+ 2 (- top-fret (+ low-fret barre-fret-coordinate)))) + (* size (+ 2 (- top-fret + (+ low-fret barre-fret-coordinate)))) (* size bezier-height) (* size bezier-thick) orientation) @@ -823,7 +824,8 @@ with @code{-(} to start a barre and @code{-)} to end the barre. (car definition-list) (cdr definition-list)))) -(define (fret-parse-terse-definition-string props definition-string) +(define-public + (fret-parse-terse-definition-string props definition-string) "Parse a fret diagram string that uses terse syntax; return a pair containing: props, modified to include the string-count determined by the definition-string, and diff --git a/scm/lily.scm b/scm/lily.scm index c324e2bab8..51038bcd29 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -338,7 +338,8 @@ The syntax is the same as `define*-public'." "encoding.scm" "fret-diagrams.scm" - "define-markup-commands.scm" + "predefined-fretboards.scm" + "define-markup-commands.scm" "define-grob-properties.scm" "define-grobs.scm" "define-grob-interfaces.scm" diff --git a/scm/music-functions.scm b/scm/music-functions.scm index c700f190db..5ca4d309af 100644 --- a/scm/music-functions.scm +++ b/scm/music-functions.scm @@ -1002,3 +1002,34 @@ use GrandStaff as a context. " (ly:music-property (car evs) 'pitch) #f))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(define-public (extract-named-music music music-name) +"Return a flat list of all music named @code{music-name} +from @code{music}." + (let ((extracted-list + (if (ly:music? music) + (if (eq? (ly:music-property music 'name) music-name) + (list music) + (let ((elt (ly:music-property music 'element)) + (elts (ly:music-property music 'elements))) + (if (ly:music? elt) + (extract-named-music elt music-name) + (if (null? elts) + '() + (map (lambda(x) + (extract-named-music x music-name )) + elts))))) + '()))) + (flatten-list extracted-list))) + +(define-public (event-chord-notes event-chord) +"Return a list of all notes from @{event-chord}." + (filter + (lambda (m) (eq? 'NoteEvent (ly:music-property m 'name))) + (ly:music-property event-chord 'elements))) + +(define-public (event-chord-pitches event-chord) +"Return a list of all pitches from @{event-chord}." + (map (lambda (x) (ly:music-property x 'pitch)) + (event-chord-notes event-chord))) diff --git a/scm/output-lib.scm b/scm/output-lib.scm index de4e658fe4..7a50af6c1e 100644 --- a/scm/output-lib.scm +++ b/scm/output-lib.scm @@ -650,44 +650,11 @@ centered, X==1 is at the right, X == -1 is at the left." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; fret boards -(define (string-frets->description string-frets string-count) - (let* - ((desc (list->vector - (map (lambda (x) (list 'mute (1+ x))) - (iota string-count))))) - - (for-each (lambda (sf) - (let* - ((string (car sf)) - (fret (cadr sf)) - (finger (caddr sf))) - - - (vector-set! desc (1- string) - (if (= 0 fret) - (list 'open string) - (if finger - (list 'place-fret string fret finger) - (list 'place-fret string fret)) - - - )) - )) - string-frets) - - (vector->list desc))) - (define-public (fret-board::calc-stencil grob) - (let* ((string-frets (ly:grob-property grob 'string-fret-finger-combinations)) - (string-count (assoc-get - 'string-count - (ly:grob-property grob 'fret-diagram-details) - 6))) - (grob-interpret-markup grob (make-fret-diagram-verbose-markup - (string-frets->description string-frets string-count))))) + (ly:grob-property grob 'dot-placement-list)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; scripts diff --git a/scm/predefined-fretboards.scm b/scm/predefined-fretboards.scm new file mode 100644 index 0000000000..7040add95e --- /dev/null +++ b/scm/predefined-fretboards.scm @@ -0,0 +1,68 @@ +;;;; predefined-fretboards.scm +;;;; +;;;; source file of the GNU LilyPOnd music typesetter +;;;; +;;;; (c) 2008 Carl D. Sorensen + + +(define-public (parse-terse-string terse-definition) +"Parse a fret-diagram-terse definition string @code{terse-definition} and +return a marking list, which can be used as with a fretboard grob." + (cdr (fret-parse-terse-definition-string (list '()) terse-definition))) + +(define-public (get-chord-shape shape-code base-chord-shapes) +"Return the chord shape associated with key @code{shape-code} in +the alist @code{base-chord-shapes}." + (assoc-get shape-code base-chord-shapes #f)) + +(define-public (offset-fret fret-offset terse-string) +"Add @code{fret-offset} to each fret indication in @code{terse-string} +and return the resulting fret-diagram-terse definition string." + + (define (split-fretstring fret-string) + (map (lambda (x) (split-item x)) + (string-split fret-string #\sp ))) + + (define (split-item item-string) + (string-split item-string #\- )) + + (define (split-terse-string terse-string) + (let ((long-list + (string-split terse-string #\;))) + (map (lambda (x) (split-fretstring x)) + (list-head long-list (1- (length long-list)))))) + + (define (join-terse-string terse-string-list) + (string-join + (map (lambda (x) (join-fretstring x)) terse-string-list) + ";" 'suffix)) + + (define (join-item item-list) + (string-join item-list "-" )) + + (define (join-fretstring fretstring-list) + (string-join + (map (lambda (x) (join-item x)) fretstring-list) + " " )) + + (define (add-item-fret-offset fret-offset item-list) + (let ((fretval (string->number (car item-list)))) + (if fretval + (cons (number->string (+ fretval fret-offset)) + (cdr item-list)) + item-list))) + + (define (add-fretstring-fret-offset fret-offset fretstring-list) + (map (lambda (x) (add-item-fret-offset fret-offset x)) + fretstring-list)) + + (define (add-terse-fret-offset fret-offset terse-string-list) + (map (lambda (x) (add-fretstring-fret-offset fret-offset x)) + terse-string-list)) + +;; body + (join-terse-string + (add-terse-fret-offset + fret-offset + (split-terse-string terse-string)))) + diff --git a/scm/song-util.scm b/scm/song-util.scm index 22e5d83bd9..2453a14ed3 100644 --- a/scm/song-util.scm +++ b/scm/song-util.scm @@ -116,15 +116,6 @@ `(set! ,list-var (append ,list-var (list ,object)))) (export add!) -(define-public (flatten lst) - (cond - ((null? lst) - lst) - ((pair? (car lst)) - (append (flatten (car lst)) (flatten (cdr lst)))) - (else - (cons (car lst) (flatten (cdr lst)))))) - (define-public (safe-car list) (if (null? list) #f diff --git a/scm/translation-functions.scm b/scm/translation-functions.scm index 667b0e2679..d4c84caf61 100644 --- a/scm/translation-functions.scm +++ b/scm/translation-functions.scm @@ -168,26 +168,68 @@ ;; fret diagrams (define-public (determine-frets context grob notes string-numbers) + (define (ensure-number a b) (if (number? a) a b)) -(let* + + (define (string-frets->dot-placement string-frets string-count) + (let* + ((desc (list->vector + (map (lambda (x) (list 'mute (1+ x))) + (iota string-count))))) + + (for-each (lambda (sf) + (let* + ((string (car sf)) + (fret (cadr sf)) + (finger (caddr sf))) + + (vector-set! + desc (1- string) + (if (= 0 fret) + (list 'open string) + (if finger + (list 'place-fret string fret finger) + (list 'place-fret string fret)) + )) + )) + string-frets) + (vector->list desc))) + +;; body. + (let* ((tunings (ly:context-property context 'stringTunings)) + (my-string-count (length tunings)) (details (ly:grob-property grob 'fret-diagram-details)) + (predefined-frets + (ly:context-property context 'predefinedDiagramTable)) (minimum-fret (ensure-number (ly:context-property context 'minimumFret) 0)) (max-stretch (ensure-number (ly:context-property context 'maximumFretStretch) 4)) (string-frets (determine-frets-mf notes string-numbers minimum-fret max-stretch - tunings))) + tunings)) + (pitches (map (lambda (x) (ly:event-property x 'pitch)) notes))) + + (set! (ly:grob-property grob 'fret-diagram-details) - (set! (ly:grob-property grob 'fret-diagram-details) (if (null? details) (acons 'string-count (length tunings) '()) (acons 'string-count (length tunings) details))) - (set! (ly:grob-property grob 'string-fret-finger-combinations) string-frets))) + (set! (ly:grob-property grob 'dot-placement-list) + (if predefined-frets + (let ((hash-handle + (hash-get-handle + predefined-frets + (cons tunings pitches)))) + (if hash-handle + (cdr hash-handle) ;found default diagram + (string-frets->dot-placement + string-frets my-string-count))) + (string-frets->dot-placement string-frets my-string-count))))) (define-public (determine-frets-mf notes string-numbers minimum-fret max-stretch