Hi Harm, > %% Redefine `fret->pitch`, otherwise `fret-partials` from source is taken
in theory you can redefine the internal list like this:
%% Redefine `fret-partials`
#(module-set!
(resolve-module '(lily))
'fret-partials
'(("0" . 0)
("12" . 1)
("7" . 2)
("19" . 2)
("5" . 3)
("24" . 3)
("4" . 4)
("9" . 4)
("16" . 4)
("3" . 5)
("3.2" . 5) ;; !!
("2.7" . 6)
("2.8" . 6) ;; !!
("2.3" . 7)
("2" . 8)))
Of course this is some kind of monkey-patching, but in such cases I think
monkey-patching should be reasonable.
About the numbers: Harmonics have kind of the problem that higher frets are
played closer to the nut and closer together, while frets closer to the nut are
further apart. So for low harmonics you get too much resolution, for high ones
you get too little.
Mathematically the nth harmonic is given by the coprime fractions k/n. In terms
of frets this means
log_b(n) - log_b(k)
where b = 2^(1/12)
Assuming k = n-1 (highest position) then this is log_b(n) - log_b(n - 1). With
some amount of rounding this gives us:
| harmonic | True Fret | fret | True Position [% of scale length] | Position [%
of scale length] | Abserr [% of scale length] | Relerr [% of true position] |
| -------- | --------- | ---- | --------------------------------- |
---------------------------- | -------------------------- |
--------------------------- |
| 2 | 12,000 | 12 | 50,000 % | 50,000 %
| 0,000 % | 0,000 % |
| 3 | 7,020 | 7 | 33,333 % | 33,258 %
| 0,075 % | 0,226 % |
| 4 | 4,980 | 5 | 25,000 % | 25,085 %
| 0,085 % | 0,339 % |
| 5 | 3,863 | 4 | 20,000 % | 20,630 %
| 0,630 % | 3,150 % |
| 6 | 3,156 | 3 | 16,667 % | 15,910 %
| 0,756 % | 4,538 % |
| 7 | 2,669 | 3 | 14,286 % | 15,910 %
| 1,625 % | 11,373 % |
| 8 | 2,312 | 2 | 12,500 % | 10,910 %
| 1,590 % | 12,719 % |
| 9 | 2,039 | 2 | 11,111 % | 10,910 %
| 0,201 % | 1,809 % |
| 10 | 1,824 | 2 | 10,000 % | 10,910 %
| 0,910 % | 9,101 % |
| 11 | 1,650 | 2 | 9,091 % | 10,910 %
| 1,819 % | 20,011 % |
| 12 | 1,506 | 2 | 8,333 % | 10,910 %
| 2,577 % | 30,922 % |
| 13 | 1,386 | 1 | 7,692 % | 5,613 %
| 2,080 % | 27,037 % |
| 14 | 1,283 | 1 | 7,143 % | 5,613 %
| 1,530 % | 21,424 % |
| 15 | 1,194 | 1 | 6,667 % | 5,613 %
| 1,054 % | 15,811 % |
So we see that rounding to frets works out nicely for the first three
overtones. Then harmonic 5 is just slightly below 4th fret — the error is just
about 3%, but this is equivalent of doing the first overtone not on 12th fret,
but in the middle between 12 and 13. This will still ring out, though with
significant dampening. Harmonic 6 is not much above 3rd fret, but the error is
already 4.5%. This is equivalent the first overtone a little bit above 11th
fret. You still get something there, but it will be dampened very much. With
stellar technique you might get it to sound somewhat, but then ... For higher
harmonics we see more and more how rounding becomes an issue.
Now, of course an experienced player will know this. But an experienced player
won’t require Tabs in the first place. So really this should be beginner
friendly, and then giving a hint where to get the harmonic properly would be
good I think.
Of course from a usefulness-perspective it makes sense that this indications
get more detailed the higher up the neck they are. E.g. if we want to have at
most 1.5% error in rounding position we approximate these using
12, 7, 5, 3.9, 3.2, 2.7, 2.3, 2.05, 1.8, 1.65, 1.5, 1.4, 1.3, 1.2
But then if we place 6th fret on the other hand we can simply use 31st fret
with an error of just about 0.1%.
A calculation like this can also be done directly in Lilypond:
%%%
#(define (calc-harmonic-fret n k tol)
(let* ((b (expt 2 1/12))
(trueposition (/ (- n k) n))
(res_progression '(2. 5/2 2.))
(theoretical_fret (- (/ (log trueposition) (log b)))))
(define (iter res res_progression)
(let* ((lower (/ (inexact->exact (floor (* theoretical_fret res))) res))
(upper (/ (inexact->exact (ceiling (* theoretical_fret res)))
res))
(err_l (* n (abs (- (expt b (- lower)) trueposition))))
(err_u (* n (abs (- (expt b (- upper)) trueposition))))
(opt (if (< err_l err_u) lower upper))
(err_opt (if (< err_l err_u) err_l err_u)))
(if (<= err_opt tol)
opt
(iter (* res (car res_progression))
(append (cdr res_progression) (list (car
res_progression)))))))
(iter 1 res_progression)))
\new TabStaff {
\override TabNoteHead.stencil =
#(lambda (grob)
(let* ((details (ly:grob-property grob 'details))
(harmonic-n (assoc-get 'harmonic-n details #f))
(harmonic-k (assoc-get 'harmonic-k details 1)))
(if harmonic-n
(tab-note-head::print-custom-fret-label
(number->string (calc-harmonic-fret harmonic-n harmonic-k 0.015)))
(ly:text-interface::print grob))))
\textMark "1st overtone"
\tweak details.harmonic-n #2 e'1\break
\textMark "2nd overtone"
\tweak details.harmonic-n #3 e'
\tweak details.harmonic-n #3 \tweak details.harmonic-k #2 e'\break
\textMark "3rd overtone"
\tweak details.harmonic-n #4 e'
\tweak details.harmonic-n #4 \tweak details.harmonic-k #3 e'\break
\textMark "4th overtone"
\tweak details.harmonic-n #5 e'
\tweak details.harmonic-n #5 \tweak details.harmonic-k #2 e'
\tweak details.harmonic-n #5 \tweak details.harmonic-k #3 e'
\tweak details.harmonic-n #5 \tweak details.harmonic-k #4 e'\break
\textMark "5th overtone"
\tweak details.harmonic-n #6 e'
\tweak details.harmonic-n #6 \tweak details.harmonic-k #5 e'\break
\textMark "6th overtone"
\tweak details.harmonic-n #7 e'
\tweak details.harmonic-n #7 \tweak details.harmonic-k #2 e'
\tweak details.harmonic-n #7 \tweak details.harmonic-k #3 e'
\tweak details.harmonic-n #7 \tweak details.harmonic-k #4 e'
\tweak details.harmonic-n #7 \tweak details.harmonic-k #5 e'
\tweak details.harmonic-n #7 \tweak details.harmonic-k #6 e'\break
\textMark "7th overtone"
\tweak details.harmonic-n #8 e'
\tweak details.harmonic-n #8 \tweak details.harmonic-k #3 e'
\tweak details.harmonic-n #8 \tweak details.harmonic-k #5 e'
\tweak details.harmonic-n #8 \tweak details.harmonic-k #7 e'\break
\textMark "8th overtone"
\tweak details.harmonic-n #9 e'
\tweak details.harmonic-n #9 \tweak details.harmonic-k #2 e'
\tweak details.harmonic-n #9 \tweak details.harmonic-k #4 e'
\tweak details.harmonic-n #9 \tweak details.harmonic-k #5 e'
\tweak details.harmonic-n #9 \tweak details.harmonic-k #7 e'
\tweak details.harmonic-n #9 \tweak details.harmonic-k #8 e'\break
\textMark "9th overtone"
\tweak details.harmonic-n #10 e'
\tweak details.harmonic-n #10 \tweak details.harmonic-k #3 e'
\tweak details.harmonic-n #10 \tweak details.harmonic-k #7 e'
\tweak details.harmonic-n #10 \tweak details.harmonic-k #9 e'
}
%%%
Cheers,
Tina
signature.asc
Description: This is a digitally signed message part.
