On Thursday 06 September 2007, Ralph Little wrote:
> Hi,
> I'm trying to get to grips with how the new stream event system works by
> studying the code and following Erik's thesis.

Nice to hear!

> According to the thesis, the stream event contains a "context" field
> which contains the id of the outlet context for the event. I can't seem
> to find this in the event structure at all and I can't think of a good
> reason for it to be there anyway for the implementation as it stands.
>
> I'm playing with exporting streams and being able to identify a context
> id for the Voice would be really useful to me. Does anyone know how
> reproduce the listing that Erik has in his thesis including the outlet
> context id?
>
> Any help would be really cool.

There is no official external representation format for music streams; in the 
internal representation the context information is represented by appearance 
(if the event appears in voice V, then it belongs to voice V). A music stream 
dumper will typically consist of one listener per context, which exports the 
events to some textual format. This listener will typically associate each 
context object with some unique human-readable ID, and tag each heard event 
with this ID (when exporting you could e.g. use a context -> id hash table, 
and when importing a stream, use a hash table for id -> context).

Note that you will need to listen in each context for the creation of new 
child contexts, so that you recursively can add listeners to them as well.

FWIW, I've attached the code I used for import + export in my thesis (beware 
that they are written for an old lily version, and that they are not cleaned 
up, and that context ids were hardcoded in C++ code back then).

In that particular version of lily (2.6), I could override the translation 
procedure by setting the global function translator-proc; this is the entry 
point of my dumper/undumper. I don't know if this still is the way to go.

IIRC, I have written some similar code for the official implementation of 
streams, but it was lost when my laptop was stolen. If you're lucky, I might 
have published some code on lilypond-devel (but I don't remember).

Good luck!

Erik
%#(set-global-staff-size 50)

\layout{raggedright=##t}
#(define imported-stream
  (let* ((handle (open-file "foo.stream" "r"))
         (stream (let get-expr ((tail '()))
                  (let ((e (read handle)))
                   (if (eof-object? e)
                    tail
                    (get-expr (cons (Stream_event::undump (primitive-eval e)) 
tail)))))))
   (reverse! stream)))

%#(display imported-stream)

#(define (translator-proc mus od key)
  (let ((glob (ly:make-translator-context od key)))
   (for-each (lambda (ev)
         (ly:distribute (ly:context-event-source
                         (Global_context::context_from_unique
                          glob
                          (ly:stream-event-property ev 'context)))
          ev))
    imported-stream)
   glob))

{c}
#(define (ly:add-stream-listener glob listener . types )
  (apply ly:add-listener
   (cons* listener (ly:context-events-below glob) types))
  glob)

#(define foo '())

%{

% init displaylily.
initDisplay = #(def-music-function (parser location music) (ly:music?)
   (display-lily-init parser)
;   (display-lily-music music)
   music)

{ \initDisplay c4 }
%}

#(use-modules (srfi srfi-1))

#(define (cwrite e) 
  (cond 
   ((eqv? '() e) (display "()"))
   ((and (list? e)
     (not (and (pair? (cdr e)) (eqv? 'unquote (cadr e)))))
    ; extra clause to make (a unquote foo) -> (a . ,foo)
    (if (pair? e)
     (cond
      ((eqv? (car e) 'quote)
       (display "'")
       (cwrite (cadr e)))
      ((eqv? (car e) 'quasiquote)
       (display "`")
       (cwrite (cadr e)))
      ((eqv? (car e) 'unquote)
       (display ",")
       (cwrite (cadr e)))
      (#t
       (display "(")
       (pair-for-each 
        (lambda (el)
         (cwrite (car el))
         (if (not (eqv? (cdr el) '())) (display " ")))
        e)
       (display ")")))))
   ((pair? e) 
    (display "(") (cwrite (car e)) (display " . ") (cwrite (cdr e)) (display 
")"))
   (#t (write e))))

%brief version
#(define (print-brief ls)
  (for-each
   (lambda (x) 
    (let ((ev (Stream_event::dump x)))
     (write ev))
    (display "\n"))
   (reverse ls)))

%verbose version
#(define (print-verbose ls)
  (for-each
   (lambda (x) 
    (display "`") 
    (cwrite (cadadr x))
    (display "\n"))
   (reverse (cadr (ly:simplify-scheme ls)))))
%}
#(define (print-fun x) (print-brief foo))
#(define (print-fun x) (print-verbose foo))

%#(define (print-fun x) (write foo))
%#(define (print-fun x) (write x))

#(define (translator-proc mus od key)
  (let ((glob (ly:make-translator-context od key)))
   (ly:add-stream-listener
    glob  
    (ly:make-listener (lambda (x) (set! foo (cons x foo))))
    'StreamEvent)
   (ly:add-stream-listener
    glob
    (ly:make-listener print-fun)
    'Finish)
   (ly:interpret-music-expression!
    mus glob)))

%{
#(define (translator-proc mus od key)
  (let ((glob (ly:make-translator-context od key)))
   (ly:add-stream-listener
    glob  
    (ly:make-listener (lambda (x) (write x) (display "one\n")))
    'StreamEvent)
   (ly:add-stream-listener
    glob
    (ly:make-listener (lambda (x) (write x) (display "two\n")))
    'Finish)
   (ly:interpret-music-expression!
    mus glob)))
%}


#(define (tmp-display-lily-music m)
  (let ((chord (make-music
                'EventChord
                'elements
                (list m))))
   (event->string chord #t)))


%{  (parameterize ((*indent* 0)
                 (*previous-duration* (ly:make-duration 2))
                 (*force-duration* #t))
%}

%\include "mozart.ly"
%\include "mozart-mini.ly"
%\include "silly-example.ly"

\include "context-example.ly"
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to