[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Getting string events from the music stream
From: |
Carl Sorensen |
Subject: |
Getting string events from the music stream |
Date: |
Fri, 15 Jan 2010 21:02:07 -0700 |
I'm working on trying to make it so both the fretboard_engraver and the
tab_note_head engraver use the same algorithm to choose strings and frets
for notes.
In so doing, I'm looking at some code in the tab-note-heads engraver that
seems wrong to me. But I'm sufficiently inexperienced with engravers that
I'd like to see if my thinking is correct.
Here is the code from lily/tab-note-heads-engraver.cc, with my questions
interspersed. Line numbers are included for convenience if more information
is wanted.
62 IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, note);
63 void
64 Tab_note_heads_engraver::listen_note (Stream_event *ev)
65 {
66 note_events_.push_back (ev);
67 }
68
69 IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, string_number);
70 void 71 Tab_note_heads_engraver::listen_string_number (Stream_event *ev)
72 {
73 tabstring_events_.push_back (ev);
74 }
75
OK, so here it seems we are setting up to listen to both note events and
string events; no problem here, it seems to make sense. Now we move on to
process_music:
76 void
77 Tab_note_heads_engraver::process_music ()
78 {
79 vsize j = 0;
80 for (vsize i = 0; i < note_events_.size (); i++)
81 {
82 SCM string_tunings = get_property ("stringTunings");
83 int string_count = scm_ilength (string_tunings);
84 bool high_string_one = to_boolean (get_property
("highStringOne"));
85
86 Stream_event *event = note_events_[i];
87
88 Stream_event *tabstring_event = 0;
We've grabbed a note_event; so far so good.
89
90 for (SCM s = event->get_property ("articulations");
91 !tabstring_event && scm_is_pair (s); s = scm_cdr (s))
92 {
93 Stream_event *art = unsmob_stream_event (scm_car (s));
94
95 if (art->in_event_class ("string-number-event"))
96 tabstring_event = art;
97 }
Now we search through the articulations of the note_event to see if there's
a string event; that makes sense.
98
99 if (!tabstring_event && j < tabstring_events_.size ())
100 {
101 tabstring_event = tabstring_events_[j];
102 if (j + 1 < tabstring_events_.size ())
103 j++;
104 }
Now if we didn't find an articulation on the note event, we search through
the list of tabstring events to find a non-empty tabstring event. Why are
we doing this second check? Is there another way to get a tabstring event
besides adding a string as an articulation to a note? Is this code
redundant, like I think it is? Actually, it seems to me to be wrong,
because it loses the registration with the note event, because nothing makes
i stay the same as j.
105
106 int string_number = 0;
107 if (tabstring_event)
108 string_number = scm_to_int (tabstring_event->get_property
("string-number"));
109
Now that I have an event (either from the articulations list or from the
tabstring_events[] array), I can get the string number. From here on out,
I'm fine with the code.
110 if (!string_number)
So is there something I'm missing about the code in lines 99-104. Is it
redundant like I think it is? In fact, can I eliminate the string-event
listener from the tab-note-head engraver?
In the automatice fret calculation routines used by the fretboard engraver,
all of the string information is extracted from the list of notes; the
string-number events are never used.
If anybody could help me see if my thoughts are correct, or identify the
errors in my thinking, I'd be grateful.
Thanks,
Carl
- Getting string events from the music stream,
Carl Sorensen <=