Connection between the classes and the xml elements is not a one-to-one relation: for simplification, a class may contain several MusicXML elements, provided that these elements are not reused anywhere else. For example, MusicXML defines dynamics
as separate elements (see common.dtd): using a single object to represent them clarifies the representation. Apart a few exceptions detailled below, all of the MusicXML elements have their counterpart in the library representation.
A good knowledge of MusicXML is required for a good comprehension of the library.
Objects that are handled using smart pointers derive from the smartable
class. Their implementation prevents direct call to the constructor. Instead of constructor call, they provide a function to create a new object directly embedded within a smart pointer.
Smart pointers don't work when a loop in the reference occurs. However, it doesn't matter in our case since MusicXML is strictly hierarchical.
Txxx
where xxx
relates to the MusicXML element name.
For each smartable
class, a typedef defines the corresponding smart pointer as follow:
typedef Txxx Sxxx
where xxx
is the class name.
More generally:
for a class named Txxx
where xxx
is the class name, the new function name is newxxx
.
A new function interface is similar to the class constructor. Each MusicXML object provides a unique constructor. Arguments of a class constructor are limited to the required MusicXML element attributes.
set
are write only methods, get
are read only methods, transpose()
to access a fTranspose
field) are read/write methods, add
methods are polymorphic methods used to push new elements into internal lists.
<!ENTITY % position "default-x %tenths; #IMPLIED default-y %tenths; #IMPLIED relative-x %tenths; #IMPLIED relative-y %tenths; #IMPLIED"> <!ENTITY % placement "placement (above | below) #IMPLIED"> <!ENTITY % orientation "orientation (over | under) #IMPLIED">
These entities are defined as separate objects. A class is defined to aggregate the corresponding properties to objects that require them. For example, a TOrientation
class is defined to describe the orientation
entity; next an Orientable
class is intended to provide the corresponding properties to derived classes. MusicXML elements that carry the orientation entity have to derive the Orientable
class.
MusicXML also makes use of entities to enumerate values like the orientation
defined above or the start-stop
or yes-no
examples below.
<!ENTITY % start-stop "(start | stop)"> <!ENTITY % yes-no "(yes | no)">
For all these entities, the library provides conversion classes (like the YesNo
class) that:
class EXP YesNo { public: enum type { undefined, yes, no, last=no }; static const string xml (type d); static type xml (const string str); };
TMusicData
is an abstract class which purpose is to define a common type for all the elements covered by the music-data
entity. It also provides the smartability and visitability properties to the derived objects.
class TMusicData : public virtual visitable, public virtual smartable { protected: TMusicData () {} virtual ~TMusicData() {} };
Similarly:
TDirectionTypeElement
is an abstract class which purpose is to define a common type for all the elements of a direction-type
element, -TNotationElement
is an abstract class which purpose is to define a common type for all the elements of a notation
element,TPartListElement
is an abstract class which purpose is to define a common type for all the elements of a part-list
element.TScoreVisitor
as the base class of the visitor design.
To preserve the choice of different strategies for the traversing the music representation structure, traversing has not been implemented in the tree components: it is assumed that it's the visitor responsability. A visitor that implements a basic traversing of the music structure is included in the library: the TRoutedVisitor
.
A TRoutedVisitor
provides a path for traversing of a score tree. Each implemented visite method calls accept() for its subclasses. Order of these calls is the following:
TMusicXMLFile
object provides a simple API to read and write MusicXML files.
class EXP TMusicXMLFile { public: TMusicXMLFile() {} virtual ~TMusicXMLFile() {} SScore read (const string& file); bool write (SScore score, const string& file); bool write (SScore score, ostream& os); };
It provides a read
method that takes a file name as argument and returns smart pointer to a music score as result. The returned pointer is null in case of failure.
It provides write
methods that take a music score and a file name or an ostream
as arguments and returns a boolean value as result. The returned value is false in case of failure.
From attributes.dtd: