Re: [tablatures] harmonics in tablature |
[ Thread Index |
Date Index
| More lilynet.net/tablatures Archives
]
- To: Patrick Schmidt <p.l.schmidt@xxxxxx>
- Subject: Re: [tablatures] harmonics in tablature
- From: Marc Hohl <marc@xxxxxxxxxx>
- Date: Tue, 28 Sep 2010 08:23:17 +0200
- Cc: "tablatures@xxxxxxxxxxx" <tablatures@xxxxxxxxxxx>
- Dkim-signature: v=1; a=rsa-sha1; c=relaxed/relaxed; t=1285654999; l=6507; s=domk; d=hohlart.de; h=Content-Type:In-Reply-To:References:Subject:CC:To:MIME-Version:From: Date:X-RZG-CLASS-ID:X-RZG-AUTH; bh=6Ay97PHqzhLMYWSsyDjMEgKN73c=; b=cQPiQPuLaC/DH5Q774X3tb4BrGa9sn0TtU7GG88DBPlJE2A5SSx8KabwFZr2QSCecYi +Bp/QzrlA3Z8MD92pN3NyWiJtScvDT22gxFUd7Q55GjRbxvg7+0l7/HuFwaqNg+N2+cvr M6U/y6vg4qIE/oqch3jYCx2UzFEyb/ti3UI=
Hello Patrick, hello tablature users,
I have now completed two functions for writing harmonics.
I invite you to test it and comment - I think they are quite useful, and
perhaps we can include them into the lilypond distribution.
The commands are
\harmonicByRatio #<ratio> <music>
where <ratio> is a fraction like 1/2, 1/3, 2/3 and so on. It marks the
absolute place
where you put your finger on the string, so 1/2 is the middle, 1/3 is
the seventh fret,
2/3 the 19th fret (both sound equally) etc.
\harmonicByFret #<fret> <music>
where <fret> is the fret number. For higher naturals, fret numbers like
2.7 and 2.3
are supported.
<music> is any kind of musical expression. If you want to play several
harmonics
on the same position, you can include them in { ... }. Harmonic chords are
possible, too. See harmonic.ly for some examples.
For this purpose, I had to write a new markup function, which cannot be
included
into the test file, so you have to insert the following lines into
scm/tablature.scm
(the place is irrelevant, but perhaps it is safe to append them at the
end of the file):
(define-markup-command (customFretLabel
layout props font-series font-size
fret-label)
(symbol? number? string?)
#:category music
"Draw a custom tab fret label."
(interpret-markup layout props
(markup #:vcenter
#:override (cons 'font-series font-series)
#:fontsize font-size
fret-label)))
After that, harmonic.ly should compile without errors.
Greetings,
Marc
\version "2.13.32"
#(define node-positions
;; for the node on m/n-th of the string length, we get the corresponding
;; (exact) fret position by calculating p=(-12/log 2)*log(1-(m/n));
;; since guitarists normally use the forth fret and not the 3.8th, here
;; are rounded values, ordered by
;; 1/2
;; 1/3 2/3
;; 1/4 2/4 3/4 etc.
;; The value for 2/4 is irrelevant in practical, bacause the string sounds
;; only one octave higher, not two, but since scheme normalizes the fractions
;; anyway, these values are simply placeholders for easier indexing.
;; According to the arithmetic sum, the position of m/n is at 1/2*(n-2)(n-1)+(m-1)
;; if we start counting from zero
(vector 12
7 19
5 12 24
4 9 16 28
3 7 12 19 31
2.7 5.8 9.7 14.7 21.7 33.7
2.3 5 8 12 17 24 36
2 4.4 7 10 14 19 26 38 ))
#(define partial-pitch
(vector '(0 0 0)
'(1 0 0)
'(1 4 0)
'(2 0 0)
'(2 2 0)
'(2 4 0)
'(2 6 -1/2)
'(3 0 0)
'(3 1 0)))
#(define fret-partials
'(("0" . 0)
("12" . 1)
("7" . 2)
("19" . 2)
("5" . 3)
("24" . 3)
("4" . 4)
("9" . 4)
("16" . 4)
("3" . 5)
("2.7" . 6)
("2.3" . 7)
("2" . 8)))
#(define (ratio->fret ratio)
(let* ((nom (numerator ratio))
(den (denominator ratio))
(index (+ (* (- den 2)
(- den 1)
1/2)
nom -1)))
(number->string (vector-ref node-positions index))))
#(define (ratio->pitch ratio)
(let* ((partial (1- (denominator ratio)))
(pitch (vector-ref partial-pitch partial)))
(ly:make-pitch (first pitch)
(second pitch)
(third pitch))))
#(define (fret->pitch fret)
(let* ((partial (assoc-get fret fret-partials 0))
(pitch (vector-ref partial-pitch partial)))
(ly:make-pitch (first pitch)
(second pitch)
(third pitch))))
#(define (calc-harmonic-pitch pitch music)
(let ((es (ly:music-property music 'elements))
(e (ly:music-property music 'element))
(p (ly:music-property music 'pitch)))
(cond
((pair? es)
(ly:music-set-property! music 'elements
(map (lambda (x) (calc-harmonic-pitch pitch x)) es)))
((ly:music? e)
(ly:music-set-property! music 'element (calc-harmonic-pitch pitch e)))
((ly:pitch? p)
(begin
(set! p (ly:pitch-transpose p pitch))
(ly:music-set-property! music 'pitch p))))
music))
% thanks to Neil for this function
#(define (make-harmonic mus)
(let ((elts (ly:music-property mus 'elements))
(elt (ly:music-property mus 'element)))
(cond
((pair? elts)
(map make-harmonic elts))
((ly:music? elt)
(make-harmonic elt))
((music-is-of-type? mus 'note-event)
(set! (ly:music-property mus 'articulations)
(append
(ly:music-property mus 'articulations)
(list (make-music 'HarmonicEvent))))))
mus))
#(define-public ((tab-note-head::print-custom-fret-label fret) grob)
(let ((font-series (ly:grob-property grob 'font-series))
(font-size (ly:grob-property grob 'font-size)))
(grob-interpret-markup grob (make-customFretLabel-markup
font-series 0 fret))))
harmonicByRatio = #(define-music-function (parser location ratio music) (number? ly:music?)
(let ((pitch (ratio->pitch ratio))
(fret (ratio->fret ratio)))
(make-sequential-music
(list
#{
\override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label $fret)
#}
(make-harmonic
(calc-harmonic-pitch pitch music))
#{
\revert TabNoteHead #'stencil
#}))))
harmonicByFret = #(define-music-function (parser location fret music) (number? ly:music?)
(let* ((fret (number->string fret))
(pitch (fret->pitch fret)))
(make-sequential-music
(list
#{
\override TabNoteHead #'stencil = #(tab-note-head::print-custom-fret-label $fret)
#}
(make-harmonic
(calc-harmonic-pitch pitch music))
#{
\revert TabNoteHead #'stencil
#}))))
test = {
e,4
\harmonicByRatio #1/2 e,\6
\harmonicByRatio #1/3 a,\5
\harmonicByRatio #2/3 d,\4 |
\harmonicByRatio #1/4 { g8\3 b\2 e'\1 b\2 < g b e >2 } |
e,1 | % check whether tab note head is restored
\harmonicByFret #12 e'4\1
\ottava #1
\harmonicByFret #7 e'4\1
\harmonicByFret #5 e'4\1
\ottava #2
\harmonicByFret #4 < b\2 e'\1 >4 |
\harmonicByFret #3 < g\3 b\2 e'\1 >4
\harmonicByFret #2.7 < g\3 b\2 e'\1 >4
\harmonicByFret #2.3 < g\3 b\2 e'\1 >4
\harmonicByFret #2 < g\3 b\2 e'\1 >4 |
\ottava #0
e,1 | % check whether tab note head is restored
}
\paper {
ragged-right = ##f
}
\score {
<<
\new Staff {
\new Voice {
\clef "treble_8"
\override Voice.StringNumber #'transparent = ##t
\test
}
}
\new TabStaff {
\new TabVoice {
\test
}
}
>>
}