<?xml version="1.0" encoding="UTF-8"?>
<!--
    Relax-NG validation schema for the Mobile Audio Language [maudl]                                      
    - Version 1.1
    - Last modification: 02/02/2011
    - Author: Lasorsa Yohan, INRIA Research Center, Team WAM
-->
<grammar ns="maudl" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
    <start>
        <element name="maudl">
            <!-- 
                Sounds are the playable audio elements.
                The sounds container can configure the properties of the 3D rendering for the sounds
            -->
            <optional>
                <element name="sounds">
                    <!-- The global 3D settings. -->
                    <ref name="global3DSettings"/>
                    <ref name="prioritySettings"/>
                    <zeroOrMore>
                        <ref name="sound"/>
                    </zeroOrMore>
                </element>        
            </optional>
            <!-- 
                Queues allow to play an ordered list of sounds or queues, one after the other.
            -->
            <optional>
                <element name="queues">
                    <zeroOrMore>
                        <ref name="queue"/>    
                    </zeroOrMore>
                </element>        
            </optional>                
            <!-- 
                Mixers allow to perform the submix of a set of sounds, queues and mixers.
                A sound or mixer can only have one parent mixer.
            -->
            <optional>
                <element name="mixers">
                    <!-- Master mix settings. -->
                    <ref name="mixAttributes"/>     
                    <zeroOrMore>
                        <ref name="mixer"/>    
                    </zeroOrMore>
                </element>        
            </optional>        
        </element>
    </start>
    
    <!-- Global 3D settings -->
    <define name="global3DSettings">
        <!-- The listener 3D position. -->
        <optional>
            <attribute name="listenerPos">
                <list>
                    <data type="double"/>    <!-- x, default = 0.0 -->
                    <data type="double"/>    <!-- y, default = 0.0 -->
                    <data type="double"/>    <!-- z, default = 0.0 -->
                </list>
            </attribute>
        </optional>
        <!-- The listener 3D orientation (the direction he is looking at). -->
        <optional>
            <attribute name="listenerLookAt">
                <list>
                    <data type="double"/>    <!-- vx, default = 0.0 -->
                    <data type="double"/>    <!-- vy, default = 0.0 -->
                    <data type="double"/>    <!-- vz, default = 1.0 -->
                </list>
            </attribute>
        </optional>
        <!-- The rolloff model for the volume used in 3D rendering. -->
        <optional>
            <attribute name="rolloff">
                <choice>
                    <value>log</value>      <!-- default realistic logarithmic attenuation model -->
                    <value>linear</value>   <!-- linear attenuation model -->
                </choice>
            </attribute>
        </optional>
        <!-- The rolloff attenuation scale factor. -->
        <optional>
            <attribute name="scale">
                <data type="double"/>    <!-- default = 1.0 -->
            </attribute>
        </optional>
    </define>
    
    <!-- 3D settings of an audio source -->
    <define name="mix3DSettings">
        <!-- The audio source 3D position. -->
        <optional>
            <attribute name="pos">
                <list>
                    <data type="double"/>    <!-- x, default = 0.0 -->
                    <data type="double"/>    <!-- y, default = 0.0 -->
                    <data type="double"/>    <!-- z, default = 0.0 -->
                </list>
            </attribute>
        </optional>
        <!-- Render the audio source in 3D (if disabled, the audio source will be rendered using the standard 	2D model). -->
        <optional>
            <attribute name="render3D">
                <data type="boolean"/>    <!-- default = false -->
            </attribute>
        </optional>
        <!-- The audio source's minimum volume distance. When using the standard log rolloff model, this will 	define how loud is the sound in the 3D space. -->
        <optional>
            <attribute name="min">
                <data type="double"/>    <!-- default = 1.0 -->
            </attribute>
        </optional>
        <!-- The audio source's maximum volume distance after which the volume stops attenuating. -->
        <optional>
            <attribute name="max">
                <data type="double"/>    <!-- default = 100.0 -->
            </attribute>
        </optional>
    </define>
    
    <!-- Priority settings -->
    <define name="prioritySettings">
        <!-- The priority classes. -->
        <optional>
            <attribute name="classOrder">
                <list>
                    <data type="string"/>    <!-- Names of classes ordered by highest to lowest priority. -->
                </list>
            </attribute>
        </optional>
    </define>
    
    <!-- Attributes of a mixable audio object -->
    <define name="mixAttributes">
        <!-- The volume of the audio object, from 0.0 (silence) to 1.0 (full volume). -->
        <optional>
            <attribute name="volume">
                <data type="double"/>   <!-- default = 1.0 -->
            </attribute>
        </optional>
        <!-- The pan of the audio object, from -1.0 (full left) to 1.0 (full right). Ignored when 3D rendering is 	used. -->
        <optional>
            <attribute name="pan">
                <data type="double"/>   <!-- default = 0.0 -->
            </attribute>
        </optional>
    </define>
    
    <!-- Attributes of a playable audio object -->
    <define name="playableAttributes">
        <!-- The priority class of the audio object. If the class does not appear in the classOrder attribute, its 	priority is considered as the lowest, equally with the others of its kind. -->
        <optional>
            <attribute name="class">
                <data type="string"/>
            </attribute>
        </optional>
            <!-- Determines the behavior of the audio object when it is already playing and a new play request 	has been received. -->
            <optional>
                <attribute name="replay">
                    <choice>
                        <value>restart</value>        	<!-- Restart playing the audio object from the beginning 						(default value). -->
                        <value>ignore</value>	<!-- Ignore the new play request. -->
                    </choice>                
                </attribute>
            </optional>		
        <!-- Space-separated list of events that will start the playback of the audio object. -->
        <optional>
            <attribute name="play">
                <ref name="eventList"/>
            </attribute>
        </optional>
        <!-- Space-separated list of events that will pause the playback of the audio object. -->
        <optional>
            <attribute name="pause">
                <ref name="eventList"/>
            </attribute>
        </optional>
        <!-- Space-separated list of events that will reset the playback of the audio object. -->
        <optional>
            <attribute name="reset">
                <ref name="eventList"/>
            </attribute>
        </optional>
        <!-- Space-separated list of events that will stop the playback of the audio object. -->
        <optional>
            <attribute name="stop">
                <ref name="eventList"/>
            </attribute>
        </optional>
        <!-- 
             Space-separated list of events that will enqueue the audio object. 
             The events have additional parameters as follows:
	<event>:<queue_id>[:<max_delay>[:<max_distance>]]
             - event        : the event that will trigger the enqueue action
             - queue_id     : the id of the target queue
             - max_delay    : the maximum acceptable time before playing the audio object, in seconds (default 	= -1, which means indefinite time)
             - max_distance : the maximum acceptable distance from from initial position at the time of the 	event the listener has moved before playing the audio object, in distance unit (default = -1, which 	means indefinite distance)
        -->
        <optional>
            <attribute name="enqueue">
                <ref name="eventList"/>
            </attribute>
        </optional>
    </define>
    
    <!-- A sound object -->
    <define name="sound">
        <!-- 
            A sound is an implicit mixer for 1 or more subsounds.
            Subsounds are introduced to allow for sound variations, but are only seen as being part of one 	sound. 
        -->
        <element name="sound">
            <!-- The unique ID of the sound. An ID must be defined for event interactions and explicit mixing of 	this sound. -->
            <optional>
                <attribute name="id">
                    <data type="ID"/>
                </attribute>
            </optional>
            <!-- Number of times the sound should repeat playback. -->
            <optional>
                <attribute name="loopCount">
                    <data type="int"/>      <!-- Default = 0. If set to -1, the sound will repeat undefinitely. -->
                </attribute>
            </optional>
            <!-- Determines how the subsounds are picked. -->
            <optional>
                <attribute name="pick">
                    <choice>
                        <value>ordered</value>        <!-- Subsounds are played in order, one after the other 							(default value). -->
                        <value>reversed</value>     	<!-- Subsounds are played in reverse order. -->
                        <value>random</value>      	<!-- Subsounds are played in random order. -->
                        <value>omitMostRecent</value>       <!-- Subsounds are played in reverse order, 								excluding the most recently played subsound. -->
                        <value>fixed</value>         	<!-- The currently active subsound does not change (unless 						explicit active request from a subsound). -->
                    </choice>                
                </attribute>
            </optional>
            <!-- The playable attributes of the sound. -->
            <ref name="playableAttributes"/>
            <!-- The mix attributes of the sound. -->
            <ref name="mixAttributes"/>
            <!-- The 3D mix setting of the sound. -->
            <ref name="mix3DSettings"/>
            <!-- The audio source file of the implicit first subsound. -->
            <optional>
                <attribute name="src"/>
            </optional>
            <zeroOrMore>
               <ref name="subsound"/>
            </zeroOrMore>
        </element>    
    </define>
    
    <!-- Subsound object -->
    <define name="subsound">
        <element name="subsound">
            <!-- The unique ID of the subsound. An ID must be defined for event interactions with the 	subsound. -->
            <optional>
                <attribute name="id">
                    <data type="ID"/>
                </attribute>
            </optional>
            <!-- The audio source file. -->
            <attribute name="src"/>
            <!-- Space-separated list of events that will set the current sound as the active one. -->
            <optional>
                <attribute name="setNext">
                    <ref name="eventList"/>
                </attribute>
            </optional>
            <!-- The mix attributes of the subsound. -->
            <ref name="mixAttributes"/>
        </element>    
    </define>
    
    <!-- Queue object -->
    <define name="queue">
        <element name="queue">
            <!-- The unique ID of the queue. -->
            <attribute name="id">
                <data type="ID"/>
            </attribute>
            <!-- Time base of the queue. -->
            <optional>
                <attribute name="timeBase">
                    <choice>
                        <value>playtime</value>   	<!-- The time is based on the addition of the duration of the played audio objects, which means pausing the queue also pause the time for the queue (default value). -->
                        <value>realtime</value>    	<!-- The time is based on the continuous absolute time, which means pausing the queue has no effect on the time for the queue. -->
                    </choice>                
                </attribute>
            </optional>
            <!-- Sorting of the audio objects. -->
            <optional>
                <attribute name="sort">
                    <choice>
                        <value>class</value>       	<!-- Sort the incoming audio objects by their priority class 						(default value). -->
                        <value>fifo</value>             	<!-- Do no sort the incoming audio objects, the oldest 							entered audio object will always be played first. -->
                    </choice>                
                </attribute>
            </optional>
            <!-- Automatically starts playing the queue as new audio objects come in. -->
            <optional>
                <attribute name="autoPlay">
                    <data type="boolean"/>		<!-- Default value is false. -->
                </attribute>
            </optional>
            <!-- Maximum number of audio objects allowed in the queue. -->
            <optional>
                <attribute name="maxElements">
                    <data type="int"/>		<!-- Values <= 0 means no limit (default = 0). -->
                </attribute>
            </optional>
            <!-- The mix attributes of the subsound. -->
            <ref name="playableAttributes"/>
        </element>    
    </define>
    
    <!-- Mixer object -->
    <define name="mixer">
        <element name="mixer">
            <!-- The unique ID of the mixer. An ID must be defined for using this mixer as an input of another 	mixer. -->
            <optional>
                <attribute name="id">
                    <data type="ID"/>
                </attribute>
            </optional>      
            <!-- The mix attributes. -->
            <ref name="mixAttributes"/>
            <!-- 
                Coma-separated list of ID references of sounds or mixers to input in this mixer. 
                An audio source (sound or mixer) can only have 1 mixer parent.
            -->
            <text/>
        </element>    
    </define>
    
    <!-- A list of events. -->
    <define name="eventList">
        <list>
            <oneOrMore>
                <choice>
                    <data type="string"/>
                </choice>
            </oneOrMore>
        </list>
    </define>
    
</grammar>
