Hi Patrick, hi tablature users,
just a short sign of life - I am still working on the problem. For
now, lilypond computes
the correct pitches and transposes the notes accordingly, but I
didn't manage to get
the 'HarmonicEvent on the right place within the music expression.
The simplest case
\harmonicByRatio #1/2 e,,4
would work, but neither
\harmonicByRatio #1/2 { e,,4 a, } nor
\harmonicByRatio #1/2 { < d g >4 }
If this is solved, I'll have to adapt the fret number. Here I am
not sure how to get this done -
I have some ideas, but didn't yet find the time to test it.
Attached is my work-in-progress so you can see how it works. If you
have some ideas/corrections/solutions,
let me know!
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)))
(if (pair? es)
(ly:music-set-property! music 'elements
(map (lambda (x) (calc-harmonic-
pitch pitch x)) es)))
(if (ly:music? e)
(ly:music-set-property! music 'element (calc-harmonic-pitch
pitch e)))
(if (ly:pitch? p)
(begin
(set! p (ly:pitch-transpose p pitch))
(ly:music-set-property! music 'pitch p)))
music))
harmonicByRatio = #(define-music-function (parser location ratio
music) (number? ly:music?)
(let ((pitch (ratio->pitch ratio)))
(calc-harmonic-pitch pitch music))
)
harmonicByFret = #(define-music-function (parser location fret
music) (number? ly:music?)
(let ((pitch (fret->pitch (number->string fret))))
(calc-harmonic-pitch pitch music))
)
test = {
c4 \harmonicByRatio #1/4 c4
c4 \harmonicByFret #2.3 c4
}
\score {
<<
\new Staff {
\new Voice {
\clef "treble_8"
\test
}
}
\new TabStaff {
\new TabVoice {
\test
}
}
}