Code review/advice for accordion registers

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

Code review/advice for accordion registers

by David Kastrup :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> I'm not topposting

after getting some advice here, I tried coding some accordion register
setting stuff.  I have little enough available input on the best
available options and names, no idea whatoever about Bayan
(consequently, no Bayan bass here), and have failed to work with
context-sensitive settings.  For example, I'd like to have something
like Voice.registerInstrument which I can independently set per Voice
and which is inherited into subvoices and can be used with \set,
\override etc.  No idea how to do this.

It also feels unclean to have to define this as macro, but short of
using macros, I have no idea how to feed the requisite material into
define-markup-command, itself a macro.  All of this looks pretty ugly.

This defines both music command and markup command (more important at a
later stage when the music command will simultaneously change the
midiRegisterInstrument of the Voice or something while the markup
command does just markup).

Ok, any advice how to wedge material into new Voice context properties?
How to do that?


% The default discant register set has been more or less modeled after
% numeric Swiss notation like depicted in
% <URL:http://de.wikipedia.org/wiki/Register_%28Akkordeon%29>,
% omitting the slashes and dropping leading zeros.
%
% The names are basically three-digit numbers with the lowest digit
% specifying the number of 16' reeds, the tens the number of 8' reeds,
% and the hundreds specifying the number of 4' reeds.  Without
% modification, the specified number of reeds in 8' is in the symbol.
% Newer instruments may have register choices between 8' with and
% without cassotto.  Notationally, the central dot then indicates use
% of cassotto.  You can suffix the tens' digits "1" and "2" with "+"
% or "-" to indicate clustering the dots at the right or left
% respectively rather than centered.
#(define defaultDiscant
  '((glyph . "accordion.accDiscant")
    (reedbank
     (L . ((dots . ((0 . 0.5)))))
     (M . ((dots . ((0 . 1.5)))))
     (MM . ((dots . ((1 . 1.5)))))
     (MMM . ((dots . ((-1 . 1.5)))))
     (H . ((dots . ((0 . 2.5))))))
    (register
     ("1" (reedbanks L))
     ("10" (reedbanks M))
     ("11" (reedbanks L M))
     ("1+0" (reedbanks MM))
     ("1+1" (reedbanks MM L))
     ("1-0" (reedbanks MMM))
     ("1-1" (reedbanks MMM L))
     ("20" (reedbanks MMM MM))
     ("21" (reedbanks MMM MM L))
     ("2+0" (reedbanks MM M))
     ("2+1" (reedbanks MM M L))
     ("2-0" (reedbanks MMM M))
     ("2-1" (reedbanks MMM M L))
     ("30" (reedbanks MMM MM M))
     ("31" (reedbanks MMM MM M L))
     ("100" (reedbanks H))
     ("11" (reedbanks H L))
     ("110" (reedbanks H M))
     ("111" (reedbanks H L M))
     ("11+0" (reedbanks H MM))
     ("11+1" (reedbanks H MM L))
     ("11-0" (reedbanks H MMM))
     ("11-1" (reedbanks H MMM L))
     ("120" (reedbanks H MMM MM))
     ("121" (reedbanks H MMM MM L))
     ("12+0" (reedbanks H MM M))
     ("12+1" (reedbanks H MM M L))
     ("12-0" (reedbanks H MMM M))
     ("12-1" (reedbanks H MMM M L))
     ("130" (reedbanks H MMM MM M))
     ("131" (reedbanks H MMM MM M L)))))

% The default Bass definitions have been modeled after the article
% <URL:http://www.accordions.com/index/art/stradella.shtml>
% originally appearing in Accord Magazine
#(define defaultStdBass
  '((glyph . "accordion.accStdbase")
    (register
     ("Soprano" (reedbanks Soprano))
     ("Alto" (reedbanks Alto Soprano))
     ("Tenor" (reedbanks Tenor Alto Soprano))
     ("Master" (reedbanks Bass Tenor Contralto Alto Soprano))
     ("Soft Bass" (reedbanks Bass Tenor Contralto))
     ("Soft Tenor" (reedbanks Tenor Alto))
     ("Bass/Alto" (reedbanks Bass Alto Soprano)))
    (reedbank
     (Soprano . ((dots . ((0 . 3.5)))))
     (Alto . ((dots . ((0 . 2.5)))))
     (Contralto . ((dots . ((1 . 2)))))
     (Tenor . ((dots . ((0 . 1.5)))))
     (Bass . ((dots . ((0 . 0.5))))))))

% The default Free Bass is modeled after the default Discant register
% description.
#(define defaultFreeBass
  '((glyph . "accordion.accFreebase")
    (reedbank
     (L . ((dots . ((0 . 0.5)))))
     (M . ((dots . ((0 . 1.5))))))
    (register
     ("1" (reedbanks L))
     ("10" (reedbanks M))
     ("11" (reedbanks L M)))))

#(define-macro (registerSetter name value)
  `(begin
    (define-markup-command (,name layout props name) (string?)
     (let* ((instrument ,value)
            (register (ly:assoc-get name (ly:assoc-get 'register instrument)))
            (reedbanks (ly:assoc-get 'reedbank instrument)))
      (interpret-markup layout props
       (let markup-builder ((dots
                             (or (ly:assoc-get 'dots register)
                              (append-map (lambda (x)
                                           (ly:assoc-get 'dots
                                            (ly:assoc-get x reedbanks)))
                               (ly:assoc-get 'reedbanks register))))
                            (result (markup #:musicglyph
                                     (ly:assoc-get 'glyph instrument))))
        (if (null? dots) result
         (markup-builder (cdr dots)
          (markup #:combine result
           #:translate (car dots) #:musicglyph "accordion.accDot")))))))
    (define ,name
     (define-music-function (parser position register) (string?)
      (make-music
       'TextScriptEvent
       'direction
       1
       'text
       (markup ,(symbol->keyword name) register))))))

#(registerSetter Discant defaultDiscant)
#(registerSetter Freebass defaultFreeBass)
#(registerSetter Stdbass defaultStdBass)

{ d'^\markup { \Discant #"12+1" }
  \clef bass \Freebass #"10" c
  <c e g>^\markup { \Stdbass #"Soft Bass" }
}



--
David Kastrup

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

Re: Code review/advice for accordion registers

by Carl Sorensen-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

David,

Congratulations on putting this together.


On 11/10/09 8:47 AM, "David Kastrup" <dak@...> wrote:

>
>
>> I'm not topposting
>
> after getting some advice here, I tried coding some accordion register
> setting stuff.  I have little enough available input on the best
> available options and names, no idea whatoever about Bayan
> (consequently, no Bayan bass here), and have failed to work with
> context-sensitive settings.  For example, I'd like to have something
> like Voice.registerInstrument which I can independently set per Voice
> and which is inherited into subvoices and can be used with \set,
> \override etc.  No idea how to do this.

I don't think that there is any "inheritance" per se in LilyPond.  Voices
are all bottom contexts.  So there aren't any subvoices.  Voices are all
"peers" at the bottom context level, IIUC.

>
> It also feels unclean to have to define this as macro, but short of
> using macros, I have no idea how to feed the requisite material into
> define-markup-command, itself a macro.  All of this looks pretty ugly.

If you look at scm/fret-diagrams.scm and scm/harp-pedals.scm you'll see that
we didn't define these complex markups as combinations of markups.  Instead
we defined them as combinations of stencils.  Stencils are graphical objects
that are formatted for output, and they are wrapped inside of markups to
provide an interface to .ly code.  (This explanation is probably not perfect
technically, but it works for me).

I think if you used scheme code to combine stencils (rather than using the
markup combination commands), you could avoid the def-macro part.  I'm not
saying you *need* to do this, but if it were me I'd at least try it.

>
> This defines both music command and markup command (more important at a
> later stage when the music command will simultaneously change the
> midiRegisterInstrument of the Voice or something while the markup
> command does just markup).
>
> Ok, any advice how to wedge material into new Voice context properties?
> How to do that?

I'm not sure what you mean.  What material do you want to wedge into Voice
context properties?

It seems to me like you could define a music function that would:

A) Check the current midiInstrument; if it's not the one you want, change
the midiInstrument.

B) Call the appropriate markup function

c) Send the appropriate notes to the midi performer (which, IIUC, may not be
the notes that are notated on the staff).

Is there something else that needs to be wedged into Voice context
properties?

HTH,

Carl



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