[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: parallel versus series scoring
From: |
Nicolas Sceaux |
Subject: |
Re: parallel versus series scoring |
Date: |
Sat, 21 Jan 2006 12:01:39 +0100 |
User-agent: |
Gnus/5.11 (Gnus v5.11) Emacs/22.0.50 (darwin) |
Han-Wen Nienhuys <address@hidden> writes:
> Nicolas Sceaux wrote:
>> ------------------------------------------------------
>> parallelMusic = #(def-music-function (parser location voice-number
>> music) (number? ly:music?)
>
> it's hack, but it's a cool one. With a little polishing, we should be
> able to put it in the standard distribution. Wouldn't it be better to
> store the voices in different variables? It would be nice to check
> whether the lengths of all bars are equal.
If it were to be actually used, it should be a bit more generic. Maybe:
\parallelMusic voice-identifiers output-pattern parallel-music
For instance (not workable example, see below):
\parallelMusic #'(voiceA voiceB voiceC)
<< \new Staff \voiceA
\new Staff \voiceB
\new Staff \voiceC >>
{ c'1 | e' | g' |
d' | fis' | a' | }
<==>
<< \new Staff { c'1 | d' | }
\new Staff { e' | fis' | }
\new Staff { g' | a' | } >>
But the "pattern" argument should not be actually parsed before the
binding to the voice identifiers are created, which is problematic.
Using a string is not really user-friendly, because one would have to
escape all #\\ and #\" characters.
The following example shows a possible implementation (checking bar
length not done yet):
#(use-modules (srfi srfi-1))
#(define (read-bracket-delimited-string chr port)
"Read a string delimited by #[ #] and return the string."
(read-char port) ;; discard the first [
(call-with-output-string
(lambda (out)
(do ((c (read-char port) (read-char port)))
;; we stop when #] is reached
((and (char=? c #\#) (char=? (peek-char port) #\]))
(read-char port)) ;; discard the last ]
(display c out)))))
#(read-hash-extend #\[ read-bracket-delimited-string)
parallelMusic =
#(def-music-function (parser location voice-ids pattern music) (list? string?
ly:music?)
(let* ((voices (apply circular-list (make-list (length voice-ids) (list))))
(current-voices voices))
(define (push-music m)
(list-set! current-voices 0 (cons m (car current-voices))))
(define (change-voice)
(set! current-voices (cdr current-voices)))
(define (bar-check? m)
(eql? (ly:music-property m 'name) 'BarCheck))
(map-in-order (lambda (m)
(push-music m)
(if (bar-check? m) (change-voice)))
(ly:music-property music 'elements))
(let ((parser-clone (ly:clone-parser parser)))
(map (lambda (voice-id voice)
(ly:parser-define! parser-clone voice-id
(make-music 'SequentialMusic
'origin location
'elements (reverse! voice))))
voice-ids voices)
(ly:parse-string-result pattern parser-clone))))
\parallelMusic #'(voiceA voiceB voiceC)
##[
\new StaffGroup <<
\new Staff \voiceA
\new Staff \voiceB
\new Staff \voiceC
>> #]
{
\time 4/4
g' g' g' g' |
e' e' e' e' |
c' c' c' c' |
%%
\time 3/4 a' a' a' | fis' fis' fis' |d' d' d' |
%%
\time 2/4
b' b' c'' c'' |
gis' gis' a' a' |
e' e' f' f' |
}
But then there is still more syntax (#[ #])...
nicolas
- Re: parallel versus series scoring,
Nicolas Sceaux <=