This is a big job, and not for the faint of heart - I wish you luck!
Skink is written in Java, and uses a parser written in Javacc. (so a c++
set of datastructures would have done me little good...) I actually
started off with a C++ version using Flex++ and Bison, but found Java
and never looked back... Some coments below, for what it's worth.
I was thinking that the output would be a C struct, which should be readable
by any language. I'd like some input about limitations in your favorite
language. Linkage is an issue, too. I'm most familar with C++ and Windows,
so I need to avoid my natural instinct here.
5. The purpose of this structure is to completely separate the parser,
the
formatter, and the player. Each one of these three functions can be
developed independently, and different developers can have their pieces
snap
in.
This is more-or-less what I did with Skink, though the intermediate
representation is a set of objects,
not a file. I have defined an interface for my renderer (I have two,
for different versions of Java)
and for my player, (although I only have one at the moment.)
The intermediate could be memory or a file. I was originally thinking that
if we define the structure without pointers, it would be more likely
readable by other languages, and we could blast the entire thing out to disk
if we wanted to, but we wouldn't have to.
7. This structure is for a single tune. To do multiple tunes, you can
simply
have an array of these.
Not quite - there is additional content that is not inside any tune, and
some of it might want to be displayed.
In particular, creating tables-of-contents, indexes, and pagenumbers
needs some back-and-forth between
the tune and the display.
I seem to remember that there is some data that is global over all tunes
until it is changed. (That was causing an issue with concatinating files).
That data needs to be passed along with the tune, for sure.
As far as TOC, etc, I think that is not quite the scope of what I'm doing.
It would be simple to feed the parser one tune at a time and get the info
you need, though.
8. Everything possible should be interpreted as much as possible. In
other
words, a chord of Gm would be stored as a G minor chord, not the text
Gm. This allows the player to not need to do any parsing.
I'm not sure I agree with this - the chord notation has been much abused.
That's one reason for the paragraph below. I was thinking that, if the
parser sees a quote, it tries to recognize the chord. If it can recognize
it, it represents it internally. If not, it puts a place holder in there
meaning unknown chord. In either case, it saves the exact text also in
case the client wants it. A MIDI player probably wouldn't want it. A
formatter might have a choice about whether to display all the chords it
recognizes in a similar format for consistancy between tunes, or display
them as originally written. A formatter could also optionally highlight in
red the chords it doesn't recognize.
9. however, the original wording should be available if needed. In other
words, GM and G are both a G major chord. Some formatting programs
may
wish to use one or the other exclusively, or may choose to parrot
whatever
was specified.
11. The structure should have a simple, fixed format so that it can be
saved
to disk easily, or passed between programs written in different
languages.
The saved version would be something of a compiled version, that is,
our
equivalent of an OBJ file. This means that there can't be any pointers in
the structure.
I think this restriction essentially ends up being true only for an
intermediate form. For example, if you have
a | abcd | dead | cabb :| age
(a purposely wrong, but often found construct) you will need to figure
out how to point back to the
first barline for the repeat. In other words, the player will have to
construct an intermediate form that
does have pointers.
I didn't mean pointer in that sense. I meant in the sense of an absolute
memory location. In the sense you mean, I think the pointer would the
ordinal number of the element.
12. A C++ class will encapsulate the structure, so that users of C++ can
easily gain access to the data in a natural way.
Java? Perl? Ruby? python? ...
I'd love to have someone encapsulate the structure for all common languages.
And suggest a good way to pass the data. If we were only worried about
Windows I'd suggest COM.
For C++, there'll be source code that you can link into your app directly
that has a public function that does the parsing.
I need some guidance about the best way to link to other languages. It may
be that there needs to be a little glue for each one we support, I don't
know.
You will need to define an 'extent' of notes that have certain
characteristics. Some items will cause changes
in the player and/or the display context. For example
K:D
|: abcd || [K:Bb] def
abc :|
Hmmm... it looks like the key signature,