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

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to