Hi Lukas,

I’m sorry, I messed that up. It should say

(calc-harmonic-pitch (fret->pitch (number->string fret))

I did my intropections with that using fret=12, and then I forgot to change 
that when copying. See the attached file for the correction.

About your points:

1) Yes. Without my mistake it calculates on which fret the sounding note would 
be, thus placing the note head onto the correct string. I’m sorry for that.

2) Yes, you are right about that. The nomenclature might be a bit confusing, 
but it helps to thing of the pitch in calc-harmonic-pitch as ratio.

About your example: What exactly does not work? This look exactly like I would 
expect from the lilypond code.

3) Forcing a string number can be done manually easily (though this is not 
good if the tuning changes at some point). But in code it is quite a bit more 
effort to achieve the same result, because we then would need to read the 
string tunings from the context and determine for each single note on which 
string that is. By simply setting minimumFret to an appropriate value (sorry 
again), we can achieve the same result without coding the same thing multiple 
times. Only problem is that doing it this way will override minimumFret 
directions done before.

4) Okay, first you need to understand that harmonicByFret is more or less a 
hack. It transposes the music for a normal staff, but it overrides the 
TabNoteHead to print the given fret. If the music wasn’t transposed this would 
do more or less what we want (though it makes big trouble in chords!, for 
these you might consider to change harmonicByFret to take just one note and 
replace all the overrides with tweaks), but since the music is transposed up, 
lilypond will just place it on a higher string (since it just thinks that this 
was a regular high note).

Your understanding is correct, but it is just that harmonicByFret is not 
optimal.

I think the cleanest way to do this would be adding different new engravers to 
Voice and TabVoice that listen to some sort of harmonic event and will do 
everything a properly.
For example you might want the staff notation of harmonics to be different, 
like 
notating the touched note and the sounding note in parentheses above. This 
would just not work with harmonicByFret, as it would be insanely hard to just 
add these notes to Voice, but not to TabVoice.

Regards,
Valentin
\version "2.21.0"

harmonicByFret = #(define-music-function (fret music) (number? ly:music?)
  (_i "Convert @var{music} into mixed harmonics; the resulting notes resemble
harmonics played on a fretted instrument by touching the strings at @var{fret}.")
  #{
    \set harmonicDots = ##t
    \temporary \override TabNoteHead.stencil = #(tab-note-head::print-custom-fret-label (number->string fret))
    \temporary \override NoteHead.Y-extent = #grob::always-Y-extent-from-stencil
    \temporary \override NoteHead.stencil = #(lambda (grob) (ly:grob-set-property! grob 'style 'harmonic-mixed)
                                            (ly:note-head::print grob))
    
    \set minimumFret = #(ly:pitch-semitones
                         (ly:prob-property
                          (calc-harmonic-pitch (fret->pitch (number->string fret))
                                               (make-music 'NoteEvent 'pitch (ly:make-pitch 0 0)))
                          'pitch))
    
    #(make-harmonic
       (calc-harmonic-pitch (fret->pitch (number->string fret)) music))
    
    \unset minimumFret
    
    \unset harmonicDots
    \revert TabNoteHead.stencil
    \revert NoteHead.Y-extent
    \revert NoteHead.stencil
  #})

music =
{
   c4 d e f g a b c'
   \bar "||"
   \harmonicByFret #12 g,
   \harmonicByFret #7 g,
   \harmonicByFret #5 g,
}

<<
   \new TabStaff {
     \set TabStaff.stringTunings = \stringTuning <c, g, d a>
     \music
   }

   \new Staff {
     \clef bass
     \music
   }
 >>

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

Reply via email to