lilypond-devel
[Top][All Lists]
Advanced

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

Chord Diagram markup


From: Carl D. Sorensen
Subject: Chord Diagram markup
Date: Mon, 19 Apr 2004 08:32:17 -0600

I have developed a very rudimentary chord diagram markup, thanks to the def-markup-command created by Nicolas Sceaux.
 
There is no capacity (yet) for indicating fret number or for putting fingerings in the circles.  Nor can the diagrams contain barre indicators.  These are all future refinements.
 
There are two arguments to the markup: a size and a definition string.  The size is a multiplier for the staff size, and gives the separation between strings and frets on the diagram.  The definition string is a six-character string that indicates the fret number played for each guitar string.  Silent strings are indicated by x, and open strings are indicated by o.
 
The code must currently all be copied to the lilypond source file, because there's no context or engraver, and I'm not yet ready to add the code to the lilypond .scm files.
 
For those of you in the know, I'd like to tie in glyphs from the feta font to indicate silent strings ("accidentals-4") and open strings ("scripts-open").  But when I tried it, I got nothing -- no output and no errors.  Any suggestions?  My code is still in the file, but commented out.
 
Anyway, for those who have been waiting for chord diagrams, I hope this is helpful.
 
Carl Sorensen
 
     
#(define (draw-strings stringcount fretcount th size)
   (let ((sl (* (+ fretcount 1) size))
         (halfthick (* th 0.5)))
    (if (= stringcount 1)
        (ly:make-stencil (list 'draw-line th 0 0 0 sl)
                         (cons (- halfthick) halfthick) (cons (- halfthick) (+ sl halfthick)) )
        (ly:stencil-combine-at-edge (draw-strings (- stringcount 1) fretcount th size)
              0 1 (ly:make-stencil (list 'draw-line th 0 0 0 sl)
                         (cons (- halfthick) halfthick)
                         (cons (- halfthick) (+ sl halfthick)) ) (- size th) 0)))) 
#(define (draw-frets fretcount stringcount th size)
   (let ((fretlength (* (- stringcount 1) size))
         (halfthick (* th 0.5)))
    (if (= fretcount 0)
        (ly:make-stencil (list 'draw-line th 0 size fretlength size)
                         (cons 0 fretlength)
                         (cons (- size halfthick) (+  size halfthick)))
        (ly:stencil-combine-at-edge (draw-frets (- fretcount 1) stringcount th size)
              1 1 (ly:make-stencil (list 'draw-line th 0 0 fretlength 0)
                         (cons 0 fretlength)
                         (cons (- halfthick) (+ halfthick))) (- size th) 0))))
                        
#(define (draw-dots stringcount fretcount size dotlist)
  "Make dots for fret diagram."
    (let ((dotrad (* size 0.25))
          (xpos (* (- stringcount (caar dotlist)) size))
          (ypos (* (+ 1.5 (- fretcount (cdar dotlist))) size))
          (extent (cons (- (*  size 0.25)) (*  size 0.25))))
    (if (null? (cdr dotlist))
       (ly:make-stencil (list 'dot xpos ypos dotrad ) extent extent)
       (ly:stencil-add
          (draw-dots stringcount fretcount size (cdr dotlist))
          (ly:make-stencil (list 'dot xpos ypos dotrad) extent extent))))
)   
 
#(define (draw-xo stringcount fretcount size font xolist)
  "Put x and o on chord diagram."
    (let ((dotrad (* size 0.25))
          (mypair (car xolist))
          (restlist (cdr xolist))
;          (glyphname  (if (char=? (cdar xolist) #\x) "accidentals-4" "scripts-open"))
          (tmpdot (if (char=? (cdar xolist) #\x) 0 (* size 0.25)))
          (xpos (* (- stringcount (caar xolist)) size))
          (ypos (* (+ 1.5 fretcount) size))
          (extent (cons (- (*  size 0.25)) (*  size 0.25))))
    (if (null? restlist)
; font char           (ly:find-glyph-by-name font glyphname)
; font char           (ly:stencil-add (ly:find-glyph-by-name font glyphname)
       (ly:make-stencil (list 'dot xpos ypos tmpdot ) extent extent)
       (ly:stencil-add
          (draw-xo stringcount fretcount size font (cdr xolist))
          (ly:make-stencil (list 'dot xpos ypos tmpdot) extent extent))))
)
#(define (char->num char)
   (- (char->integer char) (char->integer #\0)))
#(define (string-xo string chord-list)
"convert ordered list of frets and xo's into list of (string (x or o)) pairs"
  (if (null? chord-list)
      (list )
      (let ((fret (car chord-list)) (rest (cdr chord-list)))
        (if (char-numeric? fret)
            (string-xo (- string 1) rest)
            (list* (cons string fret)
               (string-xo (- string 1) rest))))
  )
)

#(define (string-dot string chord-list)
"convert ordered list of frets into list of (string fret) pairs"
  (if (null? chord-list)
      (list )
      (let ((fret (car chord-list)) (rest (cdr chord-list)))
        (if (or (char=? fret #\x) (char=? fret #\o))
            (string-dot (- string 1) rest)
            (list* (cons string (char->num fret))
               (string-dot (- string 1) rest))))
  )
)
#(define (xo-list chord-string stringcount)
  "Convert a chord string into an xo-list"
  (string-xo stringcount (string->list chord-string))
)      
     
#(define (dot-list chord-string stringcount)
  "Convert a chord string into a dot-list"
  (string-dot stringcount (string->list chord-string))
)
      
#(define (make-chord-diagram chord-string stringcount fretcount th size font)
  "Make a chord diagram"
  (ly:stencil-add
    (draw-strings stringcount fretcount th size)
    (draw-frets fretcount stringcount th size)
    (draw-dots stringcount fretcount size (dot-list chord-string stringcount))
    (draw-xo stringcount fretcount size font (xo-list chord-string stringcount)))
)
 
#(def-markup-command (chord-diagram paper props size defstring) (number? string?)
  "Syntax: \\chord-diagram size defstring
   eg: \\markup-fret-diagram #0.75 #\"xxo232\"
    for fret spacing 3/4 of staff space, D chord diagram"
   (let ((font (ly:paper-get-font paper (cons '((font-name . ())
                                    (font-shape . *)
                                    (font-series . *)
                                    (font-family . music))
                                  props))))
   (make-chord-diagram defstring 6 4 .05 size font))
)
 
\score {
    \notes {
        a'2.^\markup \chord-diagram #1 #"x33211"
        c'' ^\markup \chord-diagram #0.5 #"o221oo"
        c' ^\markup \chord-diagram #0.75 #"xxo232"
    }
  \paper{ raggedright = ##t }
}

reply via email to

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