Harmonica tablature notation

View: New views
8 Messages — Rating Filter:   Alert me  

Harmonica tablature notation

by bradford powell :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello--

I have been trying to write something to produce tablature-like
notation for the harmonica. Googling revealed a post from several
years ago which involved preprocessing a lilypond file. Not only
out-of-date with regard to lilypond syntax, but I also prefer
something that would act from within lilypond.

For background, a diatonic harmonica (using the standard Richter
tuning) has ten holes. Each hole has two reeds which play two
different primary notes, one during exhalation (the "blow" notes) and
one during the inhalation (the "draw" notes). Some of these notes can
be "bent" to a varying degree to provide some chromatic notes by
flattening pitches. The site overblow.com gives a fairly complete
tuning chart. One way that I have seen beginner notation for this is
to have the hole numbers for blow notes and in circles for draw notes
(sometimes with arrows or some other notation for bends).

My first thought was to write an engraver (since that is what guitar
tablature seems to do). After looking into the source a bit, and
deciding to try to avoid needing to recompile, I have tried two other
approaches. The first is based on adding markup to notes similar to
the commented-out 'add-staccato' function in 'ly/gregorian.ly'. The
second approach (which I think I prefer) is to create lyrics using
similar markup.

So, the markup-based approach can be seen at
http://grove.ufl.edu/~bpow/lilypond-harmonica/harmonica-markup.ly and
http://grove.ufl.edu/~bpow/lilypond-harmonica/harmonica-markup.pdf

The lyric-based approch is at
http://grove.ufl.edu/~bpow/lilypond-harmonica/harmonica-as-lyrics.ly and
http://grove.ufl.edu/~bpow/lilypond-harmonica/harmonica-as-lyrics.pdf

I would appreciate any comments. One area in particular that I have
questions about is cleaning up the case statement that converts pitch
to markup-- specifically in that I am weirdly interspersing lilypond
syntax (with the '(markup #:flat #:flat #:circle "2")'-type
statements). I would prefer to have a function like for blow and for
draw that can incorporate parameters for the hole and the number of
bends. I've tried:

#(define draw hole bends) (markup (make-list-markup (append (list
#:simple) (make-list bends #:flat) (list hole)))))

This doesn't work, any suggestions?

-- Bradford


_______________________________________________
lilypond-user mailing list
lilypond-user@...
http://lists.gnu.org/mailman/listinfo/lilypond-user

Re: Harmonica tablature notation

by Robin Bannister :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

bradford powell wrote:  
>  This doesn't work, any suggestions?


#(define* (draw hole #:optional (bends 0))
  (markup (make-line-markup (make-list bends #:flat )) #:circle hole))

 
The make-list result is not itself a markup;
for that, it must be passed to something like #:line.    
And then the restriction at the end of NR 6.4.1 applies.  
http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Markup-construction-in-Scheme

Note that setting up markup for individual bend cases
would let you use doubleflat, etc.  


Cheers,
Robin


_______________________________________________
lilypond-user mailing list
lilypond-user@...
http://lists.gnu.org/mailman/listinfo/lilypond-user

Re: Harmonica tablature notation

by bradford powell :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Oct 26, 2009 at 4:12 PM, Robin Bannister <rcb@...> wrote:
> #(define* (draw hole #:optional (bends 0))  (markup (make-line-markup
> (make-list bends #:flat )) #:circle hole))
>
>  The make-list result is not itself a markup; for that, it must be passed to
> something like #:line.    And then the restriction at the end of NR 6.4.1
> applies.
> http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Markup-construction-in-Scheme
>

When I try that (with something like (draw "4" 1)), I still get:
 error: make-line-markup: Invalid argument in position 1.  Expect:
list of markups, found: (#:flat)

I guess I could just hard-code the different degrees of bending, but
it seems like there should be a way to do this.

-- Bradford


_______________________________________________
lilypond-user mailing list
lilypond-user@...
http://lists.gnu.org/mailman/listinfo/lilypond-user

Re: Harmonica tablature notation

by Carl Sorensen-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message




On 10/27/09 7:11 PM, "bradford powell" <bradford.powell@...> wrote:

> On Mon, Oct 26, 2009 at 4:12 PM, Robin Bannister <rcb@...> wrote:
>> #(define* (draw hole #:optional (bends 0))  (markup (make-line-markup
>> (make-list bends #:flat )) #:circle hole))
>>
>>  The make-list result is not itself a markup; for that, it must be passed to
>> something like #:line.    And then the restriction at the end of NR 6.4.1
>> applies.
>> http://lilypond.org/doc/v2.12/Documentation/user/lilypond/Markup-construction
>> -in-Scheme
>>
>
> When I try that (with something like (draw "4" 1)), I still get:
>  error: make-line-markup: Invalid argument in position 1.  Expect:
> list of markups, found: (#:flat)
>
> I guess I could just hard-code the different degrees of bending, but
> it seems like there should be a way to do this.

Why are you using make-line-markup, which needs an argument of a list of
markups?  Don't you just need a markup.

i.e. couldn't you just do

 (markup (draw "4" 1))?

HTH,

Carl



_______________________________________________
lilypond-user mailing list
lilypond-user@...
http://lists.gnu.org/mailman/listinfo/lilypond-user

Re: Harmonica tablature notation

by Carl Sorensen-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

bradford powell <bradford.powell <at> gmail.com> writes:

>
> My first thought was to write an engraver (since that is what guitar
> tablature seems to do).

Writing an engraver is not as difficult as it seems, as long as you have good
models to follow.  But it *is* an involved process, and isn't the easiest way
for a new developer to get started.


> After looking into the source a bit, and
> deciding to try to avoid needing to recompile,

Recompiling is virtually impossible on windows, but it's doable on Linux and
OS/X.  If you really want to do some developing (and you're not on Windows),
it's probably worth learning to compile LilyPond.

> I have tried two other
> approaches. The first is based on adding markup to notes similar to
> the commented-out 'add-staccato' function in 'ly/gregorian.ly'. The
> second approach (which I think I prefer) is to create lyrics using
> similar markup.

I prefer the markup to notes, rather than the lyrics approach.  But this
tablature is new to me; I learned to play harmonica with arrows
indicating blow or draw and numbers indicating holes.

If you want to get the lyrics-based approach integrated into LilyPond, you'll
probably want a HarmonicaTab context and harmonica_tab_engraver.
You can copy this functionality from the FretBoards context and
Fretboard_engraver.  These are pretty simple, and could form a template
for your work if you're interested.

>
> I would appreciate any comments. One area in particular that I have
> questions about is cleaning up the case statement that converts pitch
> to markup-- specifically in that I am weirdly interspersing lilypond
> syntax (with the '(markup #:flat #:flat #:circle "2")'-type
> statements). I would prefer to have a function like for blow and for
> draw that can incorporate parameters for the hole and the number of
> bends. I've tried:
>
> #(define draw hole bends) (markup (make-list-markup (append (list
> #:simple) (make-list bends #:flat) (list hole)))))
>

If you can write the code that will return the list of arguments that you
would like to have passed to the markup function, then you can do
something like this:

(append '(markup) (function-that-returns-argument-list))

to get the scheme function you want.

HTH,

Carl



_______________________________________________
lilypond-user mailing list
lilypond-user@...
http://lists.gnu.org/mailman/listinfo/lilypond-user

Re: Harmonica tablature notation

by Robin Bannister :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

bradford powell wrote:
>  When I try that (with something like (draw "4" 1)),
>  I still get: error   [...]  (#:flat)


Sorry.  This must be related to the restriction I referenced.  

It seems that instead of    
>   (make-list bends #:flat)  
you have to say    
>   (make-list bends (make-flat-markup))


This is quite beyond me.  
It doesn't help that (with my 2.12) the error message routine
is tripped up by such cases; it errors while building its message.  

Check out semitones.ly which exercises the whole range.  


Cheers,
Robin
[semitones.ly]

\version "2.12"

#(define* (blow hole #:optional (bends 0))
  (markup (make-line-markup (make-list bends (make-flat-markup))) #:simple hole))
#(define* (draw hole #:optional (bends 0))
  (markup (make-line-markup (make-list bends (make-flat-markup))) #:circle hole))

#(define (harmonica-map semitones)
  (case semitones
    ((-12) (blow "1"))
    ((-11) (draw "1" 1))
    ((-10) (draw "1"))
    ;((-9) (overblow "1"))
    ((-8) (blow "2"))
    ((-7) (draw "2" 2))
    ((-6) (draw "2" 1))
    ((-5) (draw "2"))
    ;((-5) (blow "3"))
    ((-4) (draw "3" 3))
    ((-3) (draw "3" 2))
    ((-2) (draw "3" 1))
    ((-1) (draw "3"))
    ((0) (blow "4"))
    ((1) (draw "4" 1))
    ((2) (draw "4"))
    ;((3) (overblow "4"))
    ((4) (blow "5"))
    ((5) (draw "5"))
    ;((6) (overblow "5"))
    ((7) (blow "6"))
    ((8) (draw "6" 1))
    ((9) (draw "6"))
    ;((10) (overblow "6"))
    ((11) (draw "7"))
    ((12) (blow "7"))
    ;((13) (overdraw "7"))
    ((14) (draw "8"))
    ((15) (blow "8" 1))
    ((16) (blow "8"))
    ((17) (draw "9"))
    ((18) (blow "9" 1))
    ((19) (blow "9"))
    ;((20) (overdraw "9"))
    ((21) (draw "10"))
    ((22) (blow "10" 2))
    ((23) (blow "10" 1))
    ((24) (blow "10"))
    (else (blow " "))
))

#(define (add-harmonica m)
  (if (equal? (ly:music-property m 'name) 'NoteEvent)
      (make-music 'LyricEvent
        'duration (ly:music-property m 'duration)
        'text (harmonica-map (ly:pitch-semitones (ly:music-property m 'pitch))))
      m))

scale ={
  c4 cis4 d4 ees4
  e4 f4 fis4 g4
  aes4 a4 bes4 b4
}

notes = {
  \transpose c c   { \scale } \break
  \transpose c c'  { \scale } \break
  \transpose c c'' { \scale } c'''4
}

staffMelody = \new Staff {
  \context Voice = "melody" \notes
  \bar "|."
}

<<
  \staffMelody
  \context Lyrics = "newtab" \lyricmode { \applyMusic #(lambda (x) (music-map add-harmonica x)) \notes }
>>





_______________________________________________
lilypond-user mailing list
lilypond-user@...
http://lists.gnu.org/mailman/listinfo/lilypond-user

Re: Harmonica tablature notation

by Trevor Daniels :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


bradford powell wrote Sunday, October 25, 2009 2:32 AM

> I would appreciate any comments. One area in particular that I
> have
> questions about is cleaning up the case statement that converts
> pitch
> to markup-- specifically in that I am weirdly interspersing
> lilypond
> syntax (with the '(markup #:flat #:flat #:circle "2")'-type
> statements). I would prefer to have a function like for blow and
> for
> draw that can incorporate parameters for the hole and the number
> of
> bends. I've tried:
>
> #(define draw hole bends) (markup (make-list-markup (append (list
> #:simple) (make-list bends #:flat) (list hole)))))
>
> This doesn't work, any suggestions?

This is not very elegant and not very Scheme-like,
but I think it works.  I'm sure someone can show us
how to code a tail-recursive version of this.

#(define (draw hole nbends)
  (define bend-glyphs "")
  (while
    (> nbends 0)
    (set! bend-glyphs (markup #:flat bend-glyphs))
    (set! nbends (1- nbends)))
  (markup bend-glyphs #:circle hole))

Call with     ((1) (draw "4" 1 )) etc in your
case statement.

BTW, thanks for your example showing how to use
\applyMusic - it helped me with a similar problem.

Trevor



_______________________________________________
lilypond-user mailing list
lilypond-user@...
http://lists.gnu.org/mailman/listinfo/lilypond-user

Re: Harmonica tablature notation

by Gilles THIBAULT :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

> how to code a tail-recursive version of this.
>
> #(define (draw hole nbends)
>  (define bend-glyphs "")
>  (while
>    (> nbends 0)
>    (set! bend-glyphs (markup #:flat bend-glyphs))
>    (set! nbends (1- nbends)))
>  (markup bend-glyphs #:circle hole))
>
Perhaps something like that ? :

#(define (draw hole nbends)
  (let loop ((bend-glyphs "")
                 (n nbends))
      (if (> n 0)
        (loop (markup #:flat bend-glyphs)
                 (1- n))
        (markup bend-glyphs #:circle hole))))

>thanks for your example showing how to use
>\applyMusic - it helped me with a similar problem.

Well, for me, I don't really undersand the difference between :
\context Voice = "melody"
                \applyMusic #(lambda (x) (music-map add-harmonica x)) \notes
and
\context Voice = "melody"  \musicMap #add-harmonica \notes  ?

It seems to have the same result.

Gilles




_______________________________________________
lilypond-user mailing list
lilypond-user@...
http://lists.gnu.org/mailman/listinfo/lilypond-user