[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Bar numbers “repeat aware” for music for dancing
From: |
Niols |
Subject: |
Bar numbers “repeat aware” for music for dancing |
Date: |
Wed, 15 Apr 2020 01:13:11 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 |
Hello everyone,
This is my first message on this mailing list and I hope I do it
correctly. My apologies in advance if I don't. I have been using
LilyPond for a while to engrave various things. Among them, traditional
Scottish tunes used for dancing.
For such tunes, we are not so interested in the “usual” printed bar
numbers, but rather in the bar numbers (“repeat aware”) from the dance.
In particular, a repeat in the music does not mean a repeat in the
dance: if the first eight bars are repeated in the music, I would like
the bar numbers to go from 1 to 8 and then directly to 17.
I am unsure how to deal with that in an automated and clean way. I have
tried searching for that on Internet, without great success. I have then
tried implementing something myself with some success. I copied the code
at the end of this e-mail, if you are interested. The logic is that
every time a repeat starts, I push the current bar number to a stack.
That way, when the repeat ends, I can see for how many bars it lasted
and adjust the current bar number accordingly. However, my solution has
many big issues:
- It is quite ugly Scheme code, but that bit I could improve myself
quite easily.
- I am pretty sure I did not do it “the right way” by defining an engraver.
- I did not find an easy way (which is most likely related to the
previous point) to detect the right events I wanted to be listening to,
so there is quite a lot of machinery to not repeat the same things
several times per bar.
- The handling of alternatives seems very ad hoc, and the code always
assumes that we repeat twice.
Would you have pointers to help me write a cleaner more efficient version?
Also, I would want to not print one bar number but all the bar numbers
within the repeat. If the first eight bars are repeated, I would like to
print 1 9, 2 10, 3 11, etc. This is less a priority for me but I guess
it is linked to the same problem. Would you have pointers for that too?
Thank you in advance for your time!
Best regards,
— Nicolas “Niols” Jeannerod
#(define-public (Repeat_bar_number_skip_engraver context)
(make-engraver
(listeners
(
(StreamEvent engraver event)
(let* ((cbn (ly:context-property context 'currentBarNumber))
(mp (ly:context-property context 'measurePosition))
(mp (if (eq? mp '()) '() (ly:moment-main-numerator mp)))
(rc (ly:context-property context 'repeatCommands))
(h-rc (not (null? rc)))
(srbn (ly:context-property context 'startRepeatBarNumbers))
(lrec (ly:context-property context 'lastRbnskEngraverCall))
(trec (list cbn mp rc)))
(if (equal? trec lrec)
(display "")
(begin
;; Iter on all repeat commands. Remember if we see a volta;
;; because if we see a end-repeat followed by a volta, it means
;; we are in an alternative where, for some reason, the measure
;; number is that of the beginning of the measure.
;;
(let ((s #f)(v #f))
(map
(lambda (r)
(if (eq? r 'start-repeat)
(begin
;; For each start of a repeat, we push the current bar
;; number on the stack startRepeatBarNumbers
;;
(set! s #t)
(set! srbn (cons cbn srbn)))
(if (eq? r 'end-repeat)
(begin
;; For each end of a repeat, we pop the opening of it,
;; and we make the current bar number jump by the
;; difference. In case of volta previously seen, we have
;; to add one.
;;
;; FIXME: figure out why exactly.
;; FIXME: handle partials nicely
;; FIXME: handle repeats more than twice
;;
(if s
(display "")
(begin
;; Update current bar number by adding the number of
;; bars in the repeat.
;; Add 1 more if we are in an alternative.
;; Add 1 more if we are in a partial measure.
(set! cbn (+ cbn (- cbn (car srbn))))
(set! cbn (+ cbn (if v 1 0)))
(set! cbn (+ cbn (if (= mp 0) 0 1)))
;; Pop from the list
(set! srbn (cdr srbn)))))
(begin
(set! v #t)))))
rc))
(let ((trec (list cbn mp rc)))
(ly:context-set-property! context 'currentBarNumber cbn)
(ly:context-set-property! context 'startRepeatBarNumbers srbn)
(ly:context-set-property! context 'lastRbnskEngraverCall trec))
)))))))
- Bar numbers “repeat aware” for music for dancing,
Niols <=