> Yes.  I'm happy to license this under the GPL.

In that case if you could add the following notice (substituting your
name, etc) to the top of the attached auto-ottava file then I think
we'd have it:

<one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Thanks, and sorry for all the extra work! (Though I am a little
surprised this hasn't come up before?)

On Sat, May 9, 2015 at 2:33 PM, David Nalesnik <david.nales...@gmail.com> wrote:
>
>
> On Sat, May 9, 2015 at 4:10 PM, Urs Liska <u...@openlilylib.org> wrote:
>>
>> Am 09.05.2015 um 23:06 schrieb David Bellows:
>>>>
>>>> I'm not sure so this maybe wrong. But AFAIK copyright for content posted
>>>> to the list is by default with the author and has no license by itself. So 
>>>> I
>>>> think you can't assume it's PD.
>>>
>>>
>>> This sounds correct as well. Does just making the code available to
>>> the world in a public manner imply anything about it being OK to use
>>> it in another project? I don't know the answer to that and thus these
>>> questions. But you are correct, I'm betting, that the author does
>>> automatically own the copyright to the code (at least in the US).
>>>
>>> Should there be some kind of agreement that everyone signs off on when
>>> subscribing to the mail list concerning any code they might
>>> contribute?
>>
>>
>> I *think* I've read an agreement somewhere that explicitly states what I
>> wrote before, so if that's true we explicitly have no PD on the list.
>>
>>>
>>> And is the line that David added sufficient?:
>>>
>>>> I'm more than happy to let you use the "auto-ottava" code for your
>>>> project.  By posting it on this forum I make it available to anybody
>>>> who sees utility in it.
>>
>>
>> I would say you can take this as a sufficient "license agreement" that
>> overrides the general list rules ;-)
>
>
> Yes.  I'm happy to license this under the GPL.
>
> David
>
> _______________________________________________
> lilypond-user mailing list
> lilypond-user@gnu.org
> https://lists.gnu.org/mailman/listinfo/lilypond-user
>
\version "2.19.15"

#(define (ledger-line-no middle-C-pos p)
   "Returns the number of ledger-lines a pitch @var{p} will have with
middle C position @var{middle-C-pos} expressed as staff-steps from the
middle staff line."
   (let* ((ps (ly:pitch-steps p))
          (mid-staff-steps (- middle-C-pos))
          (top-line (+ mid-staff-steps 4))
          (bottom-line (- mid-staff-steps 4))
          (above? (> ps top-line))
          (below? (< ps bottom-line))
          (steps-outside-staff
           (cond
            (below? (- ps bottom-line))
            (above? (- ps top-line))
            (else 0))))
     (truncate (/ steps-outside-staff 2))))

#(define (find-clefMiddleCPosition mus)
   (let ((clef-pos -6)) ; treble is default
     (for-some-music
      (lambda (x)
        (let ((n (ly:music-property x 'symbol)))
          (and (eq? n 'middleCClefPosition)
               (set! clef-pos (ly:music-property x 'value)))))
      mus)
     clef-pos))

#(define clefs
   ; An alist of (clef . position of middle C) pairs.  Center line of staff = 0.
   ; For use when \ottavate is called on a music expression which begins with a
   ; clef other than treble, which has been set before that expression.
   '((treble . -6)
     (treble_8 . 1)
     (bass . 6)
     (bass_8 . 13)
     (alto . 0)
     (tenor . 2)))

#(define (make-ottava-music arg)
   (list (make-music
          'OttavaMusic
          'ottava-number arg)))

#(define (select-ottava-music str)
   (let ((options
          '(("up-an-octave" . 1)
            ("down-an-octave" . -1)
            ("up-two-octaves" . 2)
            ("down-two-octaves" . -2)
            ("loco" . 0))))
     (make-ottava-music (assoc-get str options))))

#(define naming-options
   '((short . (("up-an-octave" . "8")
               ("down-an-octave" . "8")
               ("up-two-octaves" . "15")
               ("down-two-octaves" . "15")
               ("loco" . #f)))
     (long . (("up-an-octave" . "8va")
              ("down-an-octave" . "8va bassa")
              ("up-two-octaves" . "15ma")
              ("down-two-octaves" . "15ma")
              ("loco" , #f)))
     (default . #f)))

#(define (make-alternate-name name)
   (let* ((ps (make-music
               'PropertySet
               'symbol 'ottavation
               'value name))
          (csm (make-music
                'ContextSpeccedMusic
                'element ps
                'context-type 'Staff)))
     (list csm)))

#(define (select-name displacement name-style)
   (let* ((style (assoc-get name-style naming-options))
          (name (if style
                    (assoc-get displacement style)
                    #f)))
     (if name
         (make-alternate-name name)
         '())))


ottavate =
#(define-music-function (parser location upper lower options mus)
   (number-pair? number-pair? list? ly:music?)
   "Create ottavas for music based on numbers of ledger lines.  Both @var{upper}
and @var{lower} are pairs specifying a range of ledger lines: @var{upper}
determines @code{8va} and @code{15ma}, and @var{lower} determines @var{8vb} and
@var{15mb}.  Within this range (inclusive), an @code{8va} or @code{8ba} will
be created.  Notes with numbers of ledger lines exceeding these ranges will be
assigned @code{15ma} or @code{15mb}.

Numbers of ledger lines above the staff are specified in @var{upper} as
positive integers, while ledger lines below the staff are specified in @var{lower}
as negative numbers.

The parameter @var{options} is an alist of symbol/value pairs. The symbol
@var{name-style} may be paired with @var{short}, @var{long}, or @var{default}.
The symbol @var{opening-clef} is for use when the music expression on which
@code{ottavate} is called begins with a clef other than treble which has been
set before that music expression.

The parameter @var{options} is not optional.  Any symbol left out will be assigned
its default value.  The empty list selects all default values.
"
   (let* ((upper8 (car upper))
          (upper15 (cdr upper))
          (lower8 (car lower))
          (lower15 (cdr lower))
          (name-style (assoc-get 'name-style options 'default))
          ;; Since clef information is found by scanning the music expression, any clef
          ;; change must be within the music expression fed to ottavate.  There is no access
          ;; to context properties from within a music function.  User needs to tell
          ;; \ottavate the opening clef if it is other than treble and not set within
          ;; the music expression on which \ottavate is called.
          (opening-clef (assoc-get 'opening-clef options 'treble))
          (opening-middle-C-pos (assoc-get opening-clef clefs)) 
          (loco (make-ottava-music 0)))
     
     (define (select-displacement-string ledger-count)
       (cond 
        ((> ledger-count upper15)
         "up-two-octaves")
        ((>= ledger-count upper8)
         "up-an-octave")
        ((< ledger-count lower15)
         "down-two-octaves")
        ((<= ledger-count lower8)
         "down-an-octave")
        (else "loco")))
     
     (define (calc-displacement clef-pos mus-expr)
       ; Return a string designating displacement.  "Loco" means "as written."
       ; Chords have the ledger-line count of their members averaged.
       ; Algorithm ought to be more sophisticated, and take context into consideration.
       ; We should not lose an ottava if one note in a passage dips below the
       ; threshold.
       (cond
        ((music-is-of-type? mus-expr 'event-chord)
         (let* ((elts (ly:music-property mus-expr 'elements))
                (ledger-list
                 (map (lambda (e)
                        (ledger-line-no clef-pos (ly:music-property e 'pitch)))
                   elts))
                (lowest (apply min ledger-list))
                (highest (apply max ledger-list)))
           (cond
            ((every positive? ledger-list)
             (select-displacement-string lowest))
            ((every negative? ledger-list)
             (select-displacement-string highest))
            (else "loco"))))
        ((music-is-of-type? mus-expr 'note-event)
         (let* ((pitch (ly:music-property mus-expr 'pitch))
                (ledger-count (ledger-line-no clef-pos pitch)))
           (select-displacement-string ledger-count)))))
     
     (define (build-new-elts mus-expr new-expr prev clef-pos)
       (if (null? mus-expr)
           new-expr
           (begin
            (if (music-is-of-type? (car mus-expr) 'context-specification)
                (set! clef-pos (find-clefMiddleCPosition (car mus-expr))))
            (cond
             ;; We do not extend across rests for now.
             ((music-is-of-type? (car mus-expr) 'rest-event)
              (build-new-elts
               (cdr mus-expr)
               (append
                new-expr
                loco
                (list (car mus-expr)))
               "loco" clef-pos))
             
             ((or (music-is-of-type? (car mus-expr) 'event-chord)
                  (music-is-of-type? (car mus-expr) 'note-event))
              (let ((d (calc-displacement clef-pos (car mus-expr))))
                (cond
                 ((and d (not (string=? d prev)))
                  (build-new-elts
                   (cdr mus-expr)
                   (append
                    new-expr
                    (select-ottava-music d)
                    (select-name d name-style)
                    (list (car mus-expr)))
                   d clef-pos))
                 (else
                  (build-new-elts
                   (cdr mus-expr)
                   (append new-expr (list (car mus-expr)))
                   prev clef-pos)))))
             ; ew.
             (else 
              (build-new-elts
               (cdr mus-expr)
               (append new-expr (list (car mus-expr)))
               prev clef-pos))))))
     
     (define (recurse music)
       (let ((elts (ly:music-property music 'elements))
             (e (ly:music-property music 'element)))
         (if (ly:music? e)
             (recurse e))
         (if (pair? elts)
             (if (or
                  (any (lambda (elt) (music-is-of-type? elt 'note-event)) elts)
                  (any (lambda (elt) (music-is-of-type? elt 'event-chord)) elts)
                  (any (lambda (elt) (music-is-of-type? elt 'rest-event)) elts))
                 (set! (ly:music-property music 'elements)
                       (build-new-elts elts '() "loco" opening-middle-C-pos))
                 (map recurse elts)))))
     (recurse mus)
     
     ;(display-scheme-music mus) ; for testing
   
     mus))

% %%%%%%%%%%% EXAMPLE %%%%%%%%%%%%
% {
%   f''' g''' \clef bass g,, e,,
% }

% {
%   \ottavate #'(4 . 7) #'(-4 . -7) #'((name-style . short)) { f''' g''' \clef bass g,, e,,}
% }

% music = { c d e f }

% % WRONG!

% {
%   \clef bass \ottavate #'(4 . 7) #'(-4 . -7) #'() \music
% }

% % RIGHT!
% {
%   \clef bass % not visible to \ottavate... 
%   \ottavate #'(4 . 7) #'(-4 . -7) #'((opening-clef . bass)) \music
% }


% musFour = \relative c' {
  
%   <c e g> <e g c> <g c e>
%   <c e g> <e g c> <g c e>
%   <c e g> <e g c> <g c e>
%   <c e g> <e g c> <g c e>
%   <c e g> <g c e> <e g c>
%   <c e g> <g c e> <e g c>
%   <c e g> <g c e> <e g c>
%   <c e g> <g c e> <e g c>
% }

% {
%   \musFour
% }

% {
%   \ottavate #'(3 . 6) #'(-3 . -6) #'((name-style . short)) \musFour
% }
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to