[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Custom music notation?

From: Jean Abou Samra
Subject: Custom music notation?
Date: Mon, 8 Feb 2021 22:50:51 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.5.0

Hello, Lilypond users and developers.
I have designed a music notation system called Plain Music Notation or PMN for short.
But unfortunately I am not a software developer at all.

You can find more info about it here:

I wrote to the guys at regarding some contradiction in their 'criteria' for proposing custom music notations on their website, but since also my notation does not comply to at least two of their 'criteria', I was allowed to upload it in the 'wiki board' of their site.

I would really like to find one software developer or maybe two, who would eventually find the idea interesting enough, so in their spare time to make it as a working program (preferably free and open source).

If Lilypond devs can give some advices or instruction on how I can modify the code to be able to get PMN in some early working pre-alpha stage, that would be fantastic!

That's it for now! Best regards!


LilyPond is quite well-suited to that kind of task. You
don't need to modify its code at all, just write custom
functions in the Scheme programming language as
David N. pointed out.

Since you asked, some advice follows.

Here is how to define your own input note names:

\version "2.23.1"

     `(pmn . (
               (bo . ,(ly:make-pitch -1 0 NATURAL))
               (da . ,(ly:make-pitch -1 0 SHARP))
               (fe . ,(ly:make-pitch -1 1 NATURAL))
               (gu . ,(ly:make-pitch -1 1 SHARP))
               (lo . ,(ly:make-pitch -1 2 NATURAL))
               (ma . ,(ly:make-pitch -1 3 NATURAL))
               (ne . ,(ly:make-pitch -1 3 SHARP))
               (pu . ,(ly:make-pitch -1 4 NATURAL))
               (ro . ,(ly:make-pitch -1 4 SHARP))
               (sa . ,(ly:make-pitch -1 5 NATURAL))
               (te . ,(ly:make-pitch -1 5 SHARP))
               (vu . ,(ly:make-pitch -1 6 NATURAL))


\language pmn

\relative bo' {
  bo4 da fe gu lo ma ne pu ro sa te vu

You can draw your note heads using \markup \path,
like this:

\markup \path #0.05
  #'((lineto 0.5 0.3)
     (lineto 0.5 -0.3)

\markup \path #0.05
  #'((lineto 0.5 0)
     (lineto 0 -0.5)

\markup \path #0.05
  #'((moveto 0 0.5)
     (curveto 0 0.25 0.25 0 0.5 0)
     (curveto 0.25 0 0 -0.25 0 -0.5)
     (curveto 0 -0.25 -0.25 0 -0.5 0)
     (curveto -0.25 0 0 0.25 0 0.5))

See the documentation for this command:

Next, to draw the note head on a staff position based
on its octave instead of its pitch, and to switch between
filled and empty note heads, you can do something
along the lines of this very rough sketch:

\version "2.23.1"

% Map note ranks in semitones (0=Bo, 1=Da,
% etc.) to paths using the syntax shown above.

#(define all-note-head-paths
  '((9 . ((lineto 0.5 0.3)
          (lineto 0.5 -0.3)
    (10 . ((lineto 0.5 0)
           (lineto 0 -0.5)
    (5 . ((moveto 0 0.5)
          (curveto 0 0.25 0.25 0 0.5 0)
          (curveto 0.25 0 0 -0.25 0 -0.5)
          (curveto 0 -0.25 -0.25 0 -0.5 0)
          (curveto -0.25 0 0 0.25 0 0.5)))))

\layout {
  \context {
    \override NoteHead.pitch =
    #(lambda (grob)
       (ly:event-property (event-cause grob) 'pitch))
    \override NoteHead.stencil =
    #(lambda (grob)
       (let* ((pitch (ly:grob-property grob 'pitch))
              (semitones (ly:pitch-semitones pitch))
              (abs-semitones (modulo semitones 12))
              (path (assv-ref all-note-head-paths abs-semitones)))
         (ly:grob-property grob 'filled)
           (markup #:scale '(1.4 . 1.4) #:path 0.05 path))))
    \override NoteHead.filled =
    #(lambda (grob)
       (<= 2 (ly:grob-property grob 'duration-log)))
    \override NoteHead.stem-attachment = #'(0 . 0)
    \override NoteHead.before-line-breaking =
    #(lambda (grob)
       (let* ((pitch (ly:grob-property grob 'pitch))
              (octave (ly:pitch-octave pitch)))
         (ly:grob-set-property! grob 'staff-position octave)))
  \context {
    \remove Staff_symbol_engraver
    \remove Accidental_engraver

{ f4 a4 ais2  f'8 a' ais' f'' a''4 ais''''4 }

Please find documentation for grob callbacks here:

As you can see, the repeated pattern is to write callbacks
like this. You will likely need ones for Beam.beaming,
TimeSignature.stencil, Clef.stencil, NoteHead.stem-attachment,
and a number of others. A description of all properties
is the internals reference:

How to use this document is described here:

and more advanced explanations are here:

Some closing thoughts:

- I am not sure how you envision you application. The way
  LilyPond works is processing a plain text file; be aware that
  GUI (graphical user interface) development is very difficult.

- Your first task should be to learn Scheme and how to extend
  LilyPond. We have a (for now somewhat minimalistic) manual
  for this:

  There is also this excellent resource for Scheme itself:

  You might also be interested in this popular although
  old book to learn Scheme: 

- Please note that I am personally not currently interested in
  or available for furthering this idea.

- Also, since this is a mailing list, deleting posts is impossible ;-)

I wish you to either manage to code the system yourself
or find interested people. The path to success is most
probably a combination of the two. Notice that is not
necessary to be a software developer to extend
LilyPond − I am not, and I think most helpers on this
list aren't.

Best regards,
Jean Abou Samra

reply via email to

[Prev in Thread] Current Thread [Next in Thread]