Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 %%%% This file is part of LilyPond, the GNU music typesetter. | |
2 %%%% | |
3 %%%% Copyright (C) 2011 Graham Percival <graham@percival-music.ca> | |
4 %%%% | |
5 %%%% LilyPond is free software: you can redistribute it and/or modify | |
6 %%%% it under the terms of the GNU General Public License as published by | |
7 %%%% the Free Software Foundation, either version 3 of the License, or | |
8 %%%% (at your option) any later version. | |
9 %%%% | |
10 %%%% LilyPond is distributed in the hope that it will be useful, | |
11 %%%% but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 %%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 %%%% GNU General Public License for more details. | |
14 %%%% | |
15 %%%% You should have received a copy of the GNU General Public License | |
16 %%%% along with LilyPond. If not, see <http://www.gnu.org/licenses/>. | |
17 % | |
18 % | |
19 % | |
20 % This file is used for Vivi, the Virtual Violinist: | |
21 % http://percival-music.ca/vivi.html | |
hanwenn
2011/04/18 03:50:59
frankly, I don't understand why this should be par
Graham Percival (old account)
2011/04/18 07:49:32
Recent requests:
http://lists.gnu.org/archive/html
| |
22 % but it may be helpful to other researchers, either with the same | |
23 % output, or as a basis for other work in extracting music events | |
24 % from lilypond. | |
hanwenn
2011/04/18 03:50:59
Document output format, perhaps with a small examp
Graham Percival (old account)
2011/04/18 07:49:32
I like small, focused patches. Documentation come
| |
25 | |
26 | |
27 \version "2.13.57" | |
28 | |
29 %%%% Helper functions | |
30 | |
31 #(define (filename-from-staffname engraver) | |
32 (let* ((inst-name (ly:context-property | |
33 (ly:translator-context engraver) | |
34 'instrumentName))) | |
35 (string-concatenate (list | |
36 ( substring ( object->string ( command-line )) | |
37 ;; filename without .ly part | |
38 ( + ( string-rindex ( object->string ( command-line ) ) #\sp ) | |
hanwenn
2011/04/18 03:50:59
no spaces inside scheme parens, ie. "(a b)" iso.
Graham Percival (old account)
2011/04/18 07:49:32
done.
| |
39 2 ) | |
40 ( - ( string-length ( object->string ( command-line ) )) | |
41 5 )) | |
42 "-" | |
43 (if (string? inst-name) | |
44 inst-name | |
45 "unnamed-staff") | |
46 ".notes")))) | |
47 | |
48 #(define (format-moment moment) | |
49 (exact->inexact | |
50 (/ (ly:moment-main-numerator moment) | |
51 (ly:moment-main-denominator moment)))) | |
52 | |
53 #(define (adjust-for-grace moment) | |
54 (if | |
55 (eq? 0 (ly:moment-grace-numerator moment)) | |
56 moment | |
57 ;; get moment including grace note | |
58 ;; grace notes have a negative numerator, so add | |
59 (ly:moment-add moment | |
60 ;; make the "grace duration" half as long | |
61 (ly:moment-mul | |
62 (ly:make-moment 1 2) | |
63 (ly:make-moment | |
64 (ly:moment-grace-numerator moment) | |
65 (ly:moment-grace-denominator moment)))))) | |
66 | |
67 #(define (get-moment moment) | |
68 (format-moment (adjust-for-grace | |
69 moment))) | |
70 | |
71 | |
72 #(define (print-line engraver event values) | |
73 (let* ((p (open-file (filename-from-staffname engraver) "a")) | |
74 (context (ly:translator-context engraver)) | |
75 (moment (ly:context-current-moment context))) | |
76 (display | |
77 (string-append | |
78 (string-join | |
79 (map | |
80 (lambda (x) (ly:format "~a" x)) | |
81 (append | |
82 (list (get-moment moment)) | |
83 values)) | |
84 "\t") | |
85 "\n") | |
86 p) | |
87 (close p))) | |
88 | |
89 | |
90 %%% main functions | |
91 | |
92 #(define (format-rest engraver event) | |
93 (print-line engraver event | |
94 (list | |
95 "rest" | |
96 (ly:duration->string | |
97 (ly:event-property event 'duration))))) | |
98 | |
99 #(define (format-note engraver event) | |
100 (let* ((origin (ly:input-file-line-char-column | |
101 (ly:event-property event 'origin)))) | |
102 (print-line engraver event | |
103 (list | |
104 "note" | |
105 ;; get a MIDI pitch value. | |
106 (+ 60 (ly:pitch-semitones | |
107 (ly:event-property event 'pitch))) | |
108 (format-moment (ly:duration-length | |
109 (ly:event-property event 'duration))) | |
110 ;; point and click info | |
111 (ly:format "point-and-click ~a ~a" | |
112 (caddr origin) | |
113 (cadr origin)))))) | |
114 | |
115 #(define (format-tempo engraver event) | |
116 (print-line engraver event | |
117 (list | |
118 "tempo" | |
119 ; get length of quarter notes, in seconds | |
120 (/ (ly:event-property event 'metronome-count) | |
121 (format-moment (ly:duration-length (ly:event-property | |
122 event | |
123 'tempo-unit))))))) | |
124 | |
125 | |
126 #(define (format-breathe engraver event) | |
127 (print-line engraver event | |
128 (list "breathe"))) | |
129 | |
130 #(define (format-articulation engraver event) | |
131 (print-line engraver event | |
132 (list | |
133 "script" | |
134 (ly:event-property event 'articulation-type)))) | |
135 | |
136 #(define (format-text engraver event) | |
137 (print-line engraver event | |
138 (list | |
139 "text" | |
140 (ly:event-property event 'text)))) | |
141 | |
142 #(define (format-slur engraver event) | |
143 (print-line engraver event | |
144 (list | |
145 "slur" | |
146 (ly:event-property event 'span-direction)))) | |
147 | |
148 #(define (format-dynamic engraver event) | |
149 (print-line engraver event | |
150 (list | |
151 "dynamic" | |
152 (ly:event-property event 'text)))) | |
153 | |
154 #(define (format-cresc engraver event) | |
155 (print-line engraver event | |
156 (list | |
157 "cresc" | |
158 (ly:event-property event 'span-direction)))) | |
159 | |
160 #(define (format-decresc engraver event) | |
161 (print-line engraver event | |
162 (list | |
163 "decresc" | |
164 (ly:event-property event 'span-direction)))) | |
165 | |
166 #(define (format-textspan engraver event) | |
167 (let* ((context (ly:translator-context engraver)) | |
168 (moment (ly:context-current-moment context)) | |
169 (spanner-props (ly:context-property context 'TextSpanner)) | |
170 (details (chain-assoc-get 'bound-details spanner-props)) | |
171 (left-props (assoc-get 'left details '())) | |
172 (left-text (assoc-get 'text left-props '()))) | |
173 (print-line engraver event | |
174 (list | |
175 "set_string" | |
176 (ly:event-property event 'span-direction) | |
177 left-text)))) | |
178 | |
179 | |
180 %%%% The actual engraver definition: We just install some listeners so we | |
181 %%%% are notified about all notes and rests. We don't create any grobs or | |
182 %%%% change any settings. | |
183 | |
184 \layout { | |
185 \context { | |
186 \Voice | |
187 \consists #(list | |
188 (cons 'listeners | |
189 (list | |
190 (cons 'tempo-change-event format-tempo) | |
191 (cons 'rest-event format-rest) | |
192 (cons 'note-event format-note) | |
193 (cons 'articulation-event format-articulation) | |
194 (cons 'text-script-event format-text) | |
195 (cons 'slur-event format-slur) | |
196 (cons 'breathing-event format-breathe) | |
197 (cons 'dynamic-event format-dynamic) | |
198 (cons 'crescendo-event format-cresc) | |
199 (cons 'decrescendo-event format-decresc) | |
200 (cons 'text-span-event format-textspan) | |
201 ))) | |
202 } | |
203 } | |
OLD | NEW |