<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.multimedia.cx/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Xperroni</id>
	<title>MultimediaWiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.multimedia.cx/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Xperroni"/>
	<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php/Special:Contributions/Xperroni"/>
	<updated>2026-05-04T08:54:25Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.5</generator>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Xmf&amp;diff=12878</id>
		<title>Xmf</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Xmf&amp;diff=12878"/>
		<updated>2010-07-28T16:34:38Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#Redirect [[Extensible Music Format (XMF)]]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12877</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12877"/>
		<updated>2010-07-28T16:04:07Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: /* Simple Example Parser */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;[http://www.beatnik.com/pdf_files/xmf_datasheet.pdf eXtensible Music Format]&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;[http://www.sonivoxrocks.com/google.html SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;[http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection]&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;[http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 Mobile eXtensible Music File]&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;[http://www.midi.org/techspecs/manid.php MANUFACTURER'S ID NUMBERS]&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12876</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12876"/>
		<updated>2010-07-28T16:02:05Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: /* File Structure */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;[http://www.beatnik.com/pdf_files/xmf_datasheet.pdf eXtensible Music Format]&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;[http://www.sonivoxrocks.com/google.html SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r&amp;amp;#39;&amp;amp;#39;&amp;amp;#39;Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     &amp;amp;#39;&amp;amp;#39;&amp;amp;#39;&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;[http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection]&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;[http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 Mobile eXtensible Music File]&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;[http://www.midi.org/techspecs/manid.php MANUFACTURER'S ID NUMBERS]&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12875</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12875"/>
		<updated>2010-07-28T14:48:26Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: /* Node Chunk */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;[http://www.beatnik.com/pdf_files/xmf_datasheet.pdf eXtensible Music Format]&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;[http://www.sonivoxrocks.com/google.html SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;[http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection]&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;[http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 Mobile eXtensible Music File]&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;[http://www.midi.org/techspecs/manid.php MANUFACTURER'S ID NUMBERS]&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12874</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12874"/>
		<updated>2010-07-28T14:37:29Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: /* Tools */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;[http://www.beatnik.com/pdf_files/xmf_datasheet.pdf eXtensible Music Format]&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;[http://www.sonivoxrocks.com/google.html SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;[http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection]&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;[http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 Mobile eXtensible Music File]&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;[http://www.midi.org/techspecs/manid.php MANUFACTURER'S ID NUMBERS]&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12873</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12873"/>
		<updated>2010-07-28T14:34:36Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;[http://www.beatnik.com/pdf_files/xmf_datasheet.pdf eXtensible Music Format]&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;[http://www.sonivoxrocks.com/google.html SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;[http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection]&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;[http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 Mobile eXtensible Music File]&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;[http://www.midi.org/techspecs/manid.php  MMANUFACTURER'S ID NUMBERS]&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12872</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12872"/>
		<updated>2010-07-28T14:31:31Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;# [http://www.beatnik.com/pdf_files/xmf_datasheet.pdf eXtensible Music Format]&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;{{cite web |url=http://www.sonivoxrocks.com/google.html |title=SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform |date=2007-11-01 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;{{cite web |url=http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf |title=Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection |date=2007-06-12 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;{{cite web |url=http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 |title=Mobile eXtensible Music File |date=2010-01-09 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;{{cite web |url=http://www.midi.org/techspecs/manid.php |title=MMANUFACTURER'S ID NUMBERS |date=2010-06-01 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Documentation&amp;diff=12871</id>
		<title>Template:Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Documentation&amp;diff=12871"/>
		<updated>2010-07-28T14:28:44Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;!--&lt;br /&gt;
  Automatically add {{template sandbox notice}} when on a /sandbox page.&lt;br /&gt;
--&amp;gt;{{#ifeq: {{SUBPAGENAME}} | sandbox&lt;br /&gt;
| &amp;lt;div style=&amp;quot;clear: both;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;{{template sandbox notice}}&lt;br /&gt;
}}&amp;lt;!--&lt;br /&gt;
  Automatically add {{pp-template}} to protected templates.&lt;br /&gt;
--&amp;gt;{{template other&lt;br /&gt;
| {{#ifeq: {{PROTECTIONLEVEL:move}} | sysop&lt;br /&gt;
  | {{pp-template}}&lt;br /&gt;
  | {{#if: {{PROTECTIONLEVEL:edit}}&lt;br /&gt;
    | {{pp-template}}&lt;br /&gt;
    | &amp;lt;!--Not protected, or only semi-move-protected--&amp;gt;&lt;br /&gt;
    }}&lt;br /&gt;
  }}&lt;br /&gt;
}}&amp;lt;!--&lt;br /&gt;
  Start of green doc box.&lt;br /&gt;
--&amp;gt;{{documentation/core2&lt;br /&gt;
| heading = {{{heading|¬}}}   &amp;lt;!--Empty but defined means no header--&amp;gt;&lt;br /&gt;
| heading-style = {{{heading-style|}}}&lt;br /&gt;
| content = {{{content|}}}&lt;br /&gt;
| link box = {{{link box|}}}   &amp;lt;!--So &amp;quot;link box=off&amp;quot; works--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--Some namespaces must have the /doc, /sandbox and /testcases &lt;br /&gt;
    in talk space--&amp;gt;&lt;br /&gt;
| docspace =&lt;br /&gt;
  {{#switch: {{SUBJECTSPACE}}&lt;br /&gt;
  | {{ns:0}}&lt;br /&gt;
  | {{ns:File}}&lt;br /&gt;
  | {{ns:MediaWiki}}&lt;br /&gt;
  | {{ns:Category}} = {{TALKSPACE}}&lt;br /&gt;
  | #default = {{SUBJECTSPACE}}&lt;br /&gt;
  }}&lt;br /&gt;
&lt;br /&gt;
| 1 = {{{1|}}}   &amp;lt;!--Other docname, if fed--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--The namespace is added in /core2--&amp;gt;&lt;br /&gt;
| template page = &lt;br /&gt;
  {{#switch: {{SUBPAGENAME}}&lt;br /&gt;
  | sandbox&lt;br /&gt;
  | testcases = {{BASEPAGENAME}}&lt;br /&gt;
  | #default = {{PAGENAME}}&lt;br /&gt;
  }}&lt;br /&gt;
&lt;br /&gt;
}}&amp;lt;!--End of green doc box--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Add categories and interwikis to the /doc subpage, not here! --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Namespace_detect&amp;diff=12870</id>
		<title>Template:Namespace detect</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Namespace_detect&amp;diff=12870"/>
		<updated>2010-07-28T14:26:54Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: Copied from Wikipedia&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#switch:&lt;br /&gt;
  {{lc:               &amp;lt;!--Lower case the result--&amp;gt;&lt;br /&gt;
    &amp;lt;!--If no or empty &amp;quot;demospace&amp;quot; parameter then detect namespace--&amp;gt;&lt;br /&gt;
    {{#if:{{{demospace|}}} &lt;br /&gt;
    | {{{demospace}}}&lt;br /&gt;
    | {{#if:{{{page|}}} &lt;br /&gt;
      | &amp;lt;!--Detect the namespace in the &amp;quot;page&amp;quot; parameter--&amp;gt;&lt;br /&gt;
        {{#ifeq:{{NAMESPACE:{{{page}}} }}|{{TALKSPACE:{{{page}}} }}&lt;br /&gt;
        | talk&lt;br /&gt;
        | {{SUBJECTSPACE:{{{page}}} }} &lt;br /&gt;
        }}&lt;br /&gt;
      | &amp;lt;!--No &amp;quot;demospace&amp;quot; or &amp;quot;page&amp;quot; parameters, so detect actual namespace--&amp;gt;&lt;br /&gt;
        {{#ifeq:{{NAMESPACE}}|{{TALKSPACE}}&lt;br /&gt;
        | talk&lt;br /&gt;
        | {{SUBJECTSPACE}} &lt;br /&gt;
        }}&lt;br /&gt;
      }}&lt;br /&gt;
    }}&lt;br /&gt;
  }}&lt;br /&gt;
&amp;lt;!-- Only one of the lines below will be executed --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Respecting empty parameters on purpose --&amp;gt;&lt;br /&gt;
| main        &amp;lt;!--&amp;quot;demospace=main&amp;quot; or {{SUBJECTSPACE}}={{ns:0}}=&amp;quot;&amp;quot;--&amp;gt;&lt;br /&gt;
|           = {{{main| {{{other|}}} }}}&lt;br /&gt;
| talk      = {{{talk| {{{other|}}} }}}&lt;br /&gt;
| user      = {{{user| {{{other|}}} }}}&lt;br /&gt;
| wikipedia = {{{wikipedia| {{{other|}}} }}}&lt;br /&gt;
| file&lt;br /&gt;
| image     = {{{file| {{{image| {{{other|}}} }}} }}}&lt;br /&gt;
| mediawiki = {{{mediawiki| {{{other|}}} }}}&lt;br /&gt;
| template  = {{{template| {{{other|}}} }}}&lt;br /&gt;
| help      = {{{help| {{{other|}}} }}}&lt;br /&gt;
| category  = {{{category| {{{other|}}} }}}&lt;br /&gt;
| portal    = {{{portal| {{{other|}}} }}}&lt;br /&gt;
| book      = {{{book| {{{other|}}} }}}&lt;br /&gt;
| other&lt;br /&gt;
| #default  = {{{other|}}}   &amp;lt;!--&amp;quot;demospace=other&amp;quot; or a new namespace--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
}}&amp;lt;!--End switch--&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{pp-template}}&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories and interwikis to the /doc subpage, not here! --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Mbox&amp;diff=12869</id>
		<title>Template:Mbox</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Mbox&amp;diff=12869"/>
		<updated>2010-07-28T14:25:51Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: Copied from Wikipedia&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{&lt;br /&gt;
  {{namespace detect &lt;br /&gt;
  | demospace = {{{demospace|}}}&lt;br /&gt;
  | main      = ambox&lt;br /&gt;
  | talk      = tmbox&lt;br /&gt;
  | file      = imbox&lt;br /&gt;
  | category  = cmbox&lt;br /&gt;
  | other     = ombox&lt;br /&gt;
  }}&lt;br /&gt;
| type       = {{{type|}}}&lt;br /&gt;
| image      = {{{image|}}}&lt;br /&gt;
| imageright = {{{imageright|}}}&lt;br /&gt;
| style      = {{{style|}}}&lt;br /&gt;
| textstyle  = {{{textstyle|}}}&lt;br /&gt;
| text       = {{{text}}}&lt;br /&gt;
| small      = {{{small|}}}&lt;br /&gt;
| smallimage = {{{smallimage|}}}&lt;br /&gt;
| smallimageright = {{{smallimageright|}}}&lt;br /&gt;
| smalltext  = {{{smalltext|}}}&lt;br /&gt;
}}&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories and interwikis to the /doc subpage, not here! --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Pp-meta&amp;diff=12868</id>
		<title>Template:Pp-meta</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Pp-meta&amp;diff=12868"/>
		<updated>2010-07-28T14:23:08Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: Copied from Wikipedia&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{#ifeq:{{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
  |move=&amp;lt;!--&lt;br /&gt;
 --&amp;gt;{{#ifeq:&lt;br /&gt;
      {{#switch:{{lc:{{{demolevel|undefined}}}}}&lt;br /&gt;
        |semi&lt;br /&gt;
        |autoconfirmed=autoconfirmed&lt;br /&gt;
        |administrator&lt;br /&gt;
        |full&lt;br /&gt;
        |sysop=sysop&lt;br /&gt;
        |undefined={{PROTECTIONLEVEL:move}}&lt;br /&gt;
        |#default=&amp;lt;!--fallback value: null&lt;br /&gt;
   --&amp;gt;}}&lt;br /&gt;
      |sysop|yes|no&lt;br /&gt;
    }}&lt;br /&gt;
  |create=&amp;lt;!--&lt;br /&gt;
 --&amp;gt;{{#if:&lt;br /&gt;
      {{#switch:{{lc:{{{demolevel|undefined}}}}}&lt;br /&gt;
        |semi&lt;br /&gt;
        |autoconfirmed=autoconfirmed&lt;br /&gt;
        |administrator&lt;br /&gt;
        |full&lt;br /&gt;
        |sysop=sysop&lt;br /&gt;
        |undefined={{PROTECTIONLEVEL:create}}&lt;br /&gt;
        |#default=&amp;lt;!--fallback value: null&lt;br /&gt;
   --&amp;gt;}}&lt;br /&gt;
      |yes|no&lt;br /&gt;
    }}&lt;br /&gt;
  |pending=&amp;lt;!--&lt;br /&gt;
 --&amp;gt;{{#if:&lt;br /&gt;
      {{#switch:{{lc:{{{demolevel|undefined}}}}}&lt;br /&gt;
        |semi&lt;br /&gt;
        |autoconfirmed=autoconfirmed&lt;br /&gt;
        |administrator&lt;br /&gt;
        |full&lt;br /&gt;
        |sysop=sysop&lt;br /&gt;
        |undefined=autoconfirmed&lt;br /&gt;
        |#default=&amp;lt;!--fallback value: null&lt;br /&gt;
   --&amp;gt;}}&lt;br /&gt;
      |yes|no&lt;br /&gt;
    }}&lt;br /&gt;
  |pending2=&amp;lt;!--&lt;br /&gt;
 --&amp;gt;{{#if:&lt;br /&gt;
      {{#switch:{{lc:{{{demolevel|undefined}}}}}&lt;br /&gt;
        |semi&lt;br /&gt;
        |autoconfirmed=autoconfirmed&lt;br /&gt;
        |administrator&lt;br /&gt;
        |full&lt;br /&gt;
        |sysop=sysop&lt;br /&gt;
        |undefined=autoconfirmed&lt;br /&gt;
        |#default=&amp;lt;!--fallback value: null&lt;br /&gt;
   --&amp;gt;}}&lt;br /&gt;
      |yes|no&lt;br /&gt;
    }}&lt;br /&gt;
|#default&amp;lt;!--includes all other types--&amp;gt;=&amp;lt;!--&lt;br /&gt;
 --&amp;gt;{{#if:&lt;br /&gt;
      {{#switch:{{lc:{{{demolevel|undefined}}}}}&lt;br /&gt;
        |semi&lt;br /&gt;
        |autoconfirmed=autoconfirmed&lt;br /&gt;
        |administrator&lt;br /&gt;
        |full&lt;br /&gt;
        |sysop=sysop&lt;br /&gt;
        |undefined={{PROTECTIONLEVEL:edit}}&lt;br /&gt;
        |#default=&amp;lt;!--fallback value: null&lt;br /&gt;
   --&amp;gt;}}&lt;br /&gt;
      |{{#ifeq:{{#switch:{{lc:{{{disallowlevel|}}}}}&lt;br /&gt;
                 |semi&lt;br /&gt;
                 |autoconfirmed=autoconfirmed&lt;br /&gt;
                 |administrator&lt;br /&gt;
                 |full&lt;br /&gt;
                 |sysop=sysop&lt;br /&gt;
                 |#default=&amp;lt;!--fallback value: null--&amp;gt;}}&lt;br /&gt;
         |{{#switch:{{lc:{{{demolevel|undefined}}}}}&lt;br /&gt;
            |semi&lt;br /&gt;
            |autoconfirmed=autoconfirmed&lt;br /&gt;
            |administrator&lt;br /&gt;
            |full&lt;br /&gt;
            |sysop=sysop&lt;br /&gt;
            |undefined={{PROTECTIONLEVEL:edit}}&lt;br /&gt;
            |#default=&amp;lt;!--fallback value: null&lt;br /&gt;
       --&amp;gt;}}&lt;br /&gt;
         |no|yes&lt;br /&gt;
       }}&lt;br /&gt;
   |no}}&lt;br /&gt;
}}|yes|{{#ifeq:{{lc:{{{small|}}}}}|yes|&lt;br /&gt;
&amp;lt;div class=&amp;quot;metadata topicon&amp;quot; id=&amp;quot;protected-icon&amp;quot; style=&amp;quot;display:none; right:55px;&amp;quot;&amp;gt;[[Image:{{{image|{{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
 |full=Padlock.svg&lt;br /&gt;
 |semi=Padlock-silver-medium.svg&lt;br /&gt;
 |pending=Padlock-orange.svg&lt;br /&gt;
 |move=Padlock-olive.svg&lt;br /&gt;
 |indef=Padlock-red.svg&lt;br /&gt;
 |office=Padlock-black.svg&lt;br /&gt;
 |create=Padlock-skyblue.svg&lt;br /&gt;
 |pending=Padlock-silver-light.svg&lt;br /&gt;
 |pending2=Padlock-orange.svg&lt;br /&gt;
 |#default=Transparent.gif&lt;br /&gt;
}}}}}|20px|link={{{icon-link|Wikipedia:Protection policy#{{lc:{{{type}}}}}}}}|{{{icon-text|This {{pagetype|subjectspace=yes}} is {{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
 |semi=semi-&lt;br /&gt;
 |move=move-&lt;br /&gt;
 |indef=permanently&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |create=creation-&lt;br /&gt;
 |office=&amp;lt;!--null, but should this have a special tag?--&amp;gt;&lt;br /&gt;
 |pending=pending changes&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |pending2=Level II pending changes&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |full&lt;br /&gt;
 |#default=&amp;lt;!--null--&amp;gt;&lt;br /&gt;
}}protected{{#ifeq:{{lc:{{{type}}}}}|indef||{{#if:{{{expiry|}}}|&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;until {{#time:F j, Y|{{{expiry}}}}}}}}}{{#if:{{{icon-reason|}}}|&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;{{{icon-reason}}}}}.}}}|alt=Page {{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
 |semi=semi-&lt;br /&gt;
 |move=move-&lt;br /&gt;
 |indef=permanently&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |create=creation-&lt;br /&gt;
 |office=&amp;lt;!--null, but should this have a special tag?--&amp;gt;&lt;br /&gt;
 |pending=pending changes&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |pending2=Level II pending changes&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |full&lt;br /&gt;
 |#default=&amp;lt;!--null--&amp;gt;&lt;br /&gt;
}}protected]]&amp;lt;/div&amp;gt;&lt;br /&gt;
|&amp;lt;!-- else, not small --&amp;gt;&lt;br /&gt;
{{mbox &lt;br /&gt;
| demospace = {{{demospace|}}}&lt;br /&gt;
| type = protection&lt;br /&gt;
| image = [[Image:{{{image|{{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
 |full=Padlock.svg&lt;br /&gt;
 |semi=Padlock-silver-medium.svg&lt;br /&gt;
 |move=Padlock-olive.svg&lt;br /&gt;
 |indef=Padlock-red.svg&lt;br /&gt;
 |office=Padlock-black.svg&lt;br /&gt;
 |create=Padlock-skyblue.svg&lt;br /&gt;
 |pending=Padlock-silver-light.svg&lt;br /&gt;
 |pending2=Padlock-orange.svg&lt;br /&gt;
 |#default=Transparent.gif&lt;br /&gt;
}}}}}|40px|{{{icon-text|This page is {{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
 |semi=semi-&lt;br /&gt;
 |move=move-&lt;br /&gt;
 |indef=permanently&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |create=creation-&lt;br /&gt;
 |office=&amp;lt;!--null, but should this have a special tag?--&amp;gt;&lt;br /&gt;
 |pending=pending changes&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |pending2=Level II pending changes&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
 |full&lt;br /&gt;
 |#default=&amp;lt;!--null--&amp;gt;&lt;br /&gt;
}}protected.}}}]]&lt;br /&gt;
| text = '''{{{reason-text|{{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
 |full=This page is currently [[Wikipedia:This page is protected|protected]] from editing&lt;br /&gt;
 |semi=Editing of this {{pagetype|subjectspace=yes}} by [[Wikipedia:User access levels#Autoconfirmed_users|new]] or [[Wikipedia:User access levels#Anonymous_users|unregistered]] users is currently [[Wikipedia:Protection policy|disabled]]&lt;br /&gt;
 |move=This {{pagetype|subjectspace=yes}} is currently [[Wikipedia:This page is protected|protected]] from [[Help:Moving a page|page moves]]&lt;br /&gt;
 |indef=This page is [[Wikipedia:This page is protected|protected]] from editing ''indefinitely''&lt;br /&gt;
 |office=This {{pagetype|subjectspace=yes}} is currently [[Wikipedia:This page is protected|protected]] from editing&lt;br /&gt;
 |pending=Latest edits to this {{pagetype|subjectspace=yes}} by [[Wikipedia:User access levels#Autoconfirmed_users|new]] or [[Wikipedia:User access levels#Anonymous_users|unregistered]] users [[Wikipedia:Pending changes|may be delayed]] before being made public ''&amp;lt;span style=&amp;quot;font-weight:normal;font-size:90%&amp;quot;&amp;gt;([[Help:Pending changes|what's this]]?)&amp;lt;/span&amp;gt;''&lt;br /&gt;
 |pending2=Edits to this {{pagetype|subjectspace=yes}} by non-[[Wikipedia:Reviewers#Who checks articles and what do they check|reviewers]] may be [[Wikipedia:Pending changes|delayed]] before being made public&lt;br /&gt;
 |create=[[Help:Starting a new page|Recreation]] of this {{pagetype|subjectspace=yes}} [[Wikipedia:This page is protected|has been disabled]]&lt;br /&gt;
}}{{#ifeq:{{lc:{{{type}}}}}|indef||{{#if:{{{expiry|}}}|&amp;amp;#32;until {{#time:F j, Y|{{{expiry}}}}}}}}}{{{reason&amp;lt;includeonly&amp;gt;|&amp;lt;/includeonly&amp;gt;}}}.}}}'''&amp;lt;br /&amp;gt; {{{explanation-text|{{#ifeq:{{lc:{{{dispute}}}}}|yes|This protection is '''not''' an endorsement of the {{#ifeq:{{{type}}}|move|[{{fullurl:Special:Log|type=move&amp;amp;page={{FULLPAGENAMEE}}}} current title]|[{{fullurl:{{FULLPAGENAMEE}}|action=history}} current version]}}.}} See the [[Wikipedia:Protection policy|protection policy]] and [{{fullurl:Special:Log|type=protect&amp;amp;page={{FULLPAGENAMEE}}}} protection log] for more details. {{#switch:{{lc:{{{type}}}}}&lt;br /&gt;
 |full|indef=Please discuss any changes on the [[{{TALKPAGENAME}}|talk page]]; you may use the {{tlx|editprotected}} template to ask an [[Wikipedia:Administrator|administrator]] to make the edit if it is supported by [[Wikipedia:Consensus|consensus]]. {{#ifeq:{{NAMESPACE}}|{{ns:8}}&amp;lt;!--MediaWiki--&amp;gt;||You may also [[Wikipedia:Requests for page protection|request]] that this page be unprotected.}}&lt;br /&gt;
 |semi=If you cannot edit this {{pagetype|subjectspace=yes}} and you wish to make a change, you can {{#ifeq:{{NAMESPACE}}|{{TALKSPACE}}||[[Template:Editsemiprotected|request an edit]], [[{{TALKPAGENAME}}|discuss changes on the talk page]],}} [[Wikipedia:Requests for page protection#Current requests for unprotection|request unprotection]], [[Special:Userlogin|log in]], or &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[http://en.wikipedia.org/w/index.php?title=Special:Userlogin&amp;amp;type=signup &amp;lt;span style=&amp;quot;color:#002bb8;&amp;quot; title=&amp;quot;Sign in / create account&amp;quot;&amp;gt;create an account&amp;lt;/span&amp;gt;].&lt;br /&gt;
 |move=The page may still be edited but cannot be moved until unprotected. Please discuss any suggested moves on the [[{{TALKPAGENAME}}|talk page]] or at [[Wikipedia:Requested moves]].  You can also [[Wikipedia:Requests for page protection|request]] that the page be unprotected.  &lt;br /&gt;
 |office=If you are able to edit this page, please discuss all changes and additions on the [[{{TALKPAGENAME}}|talk page]] first. '''Do not remove protection from this article unless you are authorized by the Wikimedia Foundation to do so.'''&lt;br /&gt;
 |pending=You are welcome to make changes to this page, but they may not be publicly visible until they have been [[Wikipedia:Reviewing|reviewed]]. You may also [[Wikipedia:Requests for page protection#Current requests for unprotection|request unprotection]], [[Special:Userlogin|log in]], or &amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;[http://en.wikipedia.org/w/index.php?title=Special:Userlogin&amp;amp;type=signup &amp;lt;span style=&amp;quot;color:#002bb8;&amp;quot; title=&amp;quot;Sign in / create account&amp;quot;&amp;gt;create an account&amp;lt;/span&amp;gt;].&lt;br /&gt;
 |pending2=You are welcome to make changes to this page, but they may not be publicly visible until they have been [[Wikipedia:Reviewing|reviewed]]. You may also [[Wikipedia:Requests for page protection#Current requests for unprotection|request]] that this page be unprotected.&lt;br /&gt;
 |create=Please see the {{#if:{{{xfd|}}}|'''[[{{{xfd}}}|deletion discussion]]''' or the}} [{{fullurl:Special:Log|type=delete&amp;amp;page={{FULLPAGENAMEE}}}} deletion log] for details of why this page was deleted. If you would like to create a page at this title, you must first [[Wikipedia:Requests for page protection|request]] for it to be unprotected, or contact the administrator who deleted the page for the deleted material to be restored. If unsuccessful, you can use [[Wikipedia:Deletion review|deletion review]].&lt;br /&gt;
}}}}}&lt;br /&gt;
}}&lt;br /&gt;
}}|[[Category:Wikipedia pages with incorrect protection templates]]}}&amp;lt;!--End if small--&amp;gt;&amp;lt;includeonly&amp;gt;{{#ifeq:{{lc:{{{categories|no}}}}}|no||{{{categories|}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories and interwikis to the /doc subpage, not here! --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Pp-template&amp;diff=12867</id>
		<title>Template:Pp-template</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Pp-template&amp;diff=12867"/>
		<updated>2010-07-28T14:21:59Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: Copied from Wikipedia&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{pp-meta&lt;br /&gt;
|type={{#switch:{{{demolevel|{{#ifeq:{{PROTECTIONLEVEL:edit}}-{{PROTECTIONLEVEL:move}}|-sysop|move|{{PROTECTIONLEVEL:edit}}}}}}}&lt;br /&gt;
   |semi&lt;br /&gt;
   |autoconfirmed=semi&lt;br /&gt;
   |administrator&lt;br /&gt;
   |full&lt;br /&gt;
   |sysop=indef&lt;br /&gt;
   |move=move&lt;br /&gt;
   |#default=indef&amp;lt;!--fallback value--&amp;gt;}}&lt;br /&gt;
|small={{{small|yes}}}&lt;br /&gt;
|demospace={{{demospace|}}}&lt;br /&gt;
|demolevel={{#ifeq:{{PAGENAME}}/{{NAMESPACE}}|{{SUBPAGENAME}}/{{ns:Template}}|{{{demolevel|undefined}}}|{{#ifeq:{{lc:{{SUBPAGENAME}}}}|sandbox|sysop|{{{demolevel|undefined}}}}}}}&lt;br /&gt;
|expiry=&amp;lt;!--not applicable--&amp;gt;&lt;br /&gt;
|dispute=no&lt;br /&gt;
|icon-text=This {{#ifeq:{{NAMESPACE}}|{{ns:6}}|image, included in a high-risk template or message,|high-risk template}} is indefinitely {{#switch:{{{demolevel|{{#ifeq:{{PROTECTIONLEVEL:edit}}-{{PROTECTIONLEVEL:move}}|-sysop|move|{{PROTECTIONLEVEL:edit}}}}}}}&lt;br /&gt;
   |semi&lt;br /&gt;
   |autoconfirmed=semi-protected from editing&lt;br /&gt;
   |move=move-protected&lt;br /&gt;
   |administrator&lt;br /&gt;
   |full&lt;br /&gt;
   |sysop&lt;br /&gt;
   |#default=&amp;lt;!--fallback value--&amp;gt;protected from editing}} to prevent vandalism.&lt;br /&gt;
|reason-text=This {{#switch:{{NAMESPACE}}&lt;br /&gt;
  |{{ns:image}}=image, used in one or more [[Wikipedia:High-risk templates|high-risk templates]]{{#switch:{{{demolevel|{{PROTECTIONLEVEL:edit}}}}}&lt;br /&gt;
   |semi&lt;br /&gt;
   |autoconfirmed=&lt;br /&gt;
   |administrator&lt;br /&gt;
   |full&lt;br /&gt;
   |sysop=&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;and/or [[Special:Allmessages|system messages]],&lt;br /&gt;
   |#default=&amp;lt;!--fallback value--&amp;gt;}}&lt;br /&gt;
  |#default=[[Wikipedia:High-risk templates|high-risk template]]&lt;br /&gt;
}} has been [[Wikipedia:This page is protected|{{#switch:{{{demolevel|{{#ifeq:{{PROTECTIONLEVEL:edit}}-{{PROTECTIONLEVEL:move}}|-sysop|move|{{PROTECTIONLEVEL:edit}}}}}}}&lt;br /&gt;
   |semi&lt;br /&gt;
   |autoconfirmed=semi-&lt;br /&gt;
   |move=move-&lt;br /&gt;
   |administrator&lt;br /&gt;
   |full&lt;br /&gt;
   |sysop&amp;lt;!--uses default--&amp;gt;&lt;br /&gt;
   |#default=&amp;lt;!--fallback value--&amp;gt;}}protected]]{{#ifeq:{{PROTECTIONLEVEL:edit}}-{{PROTECTIONLEVEL:move}}|-sysop||&amp;lt;nowiki&amp;gt; &amp;lt;/nowiki&amp;gt;from editing}} to prevent [[Wikipedia:Vandalism|vandalism]]. {{#switch:{{{demolevel|{{PROTECTIONLEVEL:edit}}}}}&lt;br /&gt;
   |semi&lt;br /&gt;
   |autoconfirmed=&lt;br /&gt;
   |administrator&lt;br /&gt;
   |full&lt;br /&gt;
   |sysop&amp;lt;!--uses default--&amp;gt;&lt;br /&gt;
   |#default={{#switch:{{NAMESPACE}}|{{ns:image}}=&amp;lt;br /&amp;gt;&amp;lt;small&amp;gt;'''Do not move this image''' to [[commons:|Wikimedia Commons]].&amp;lt;/small&amp;gt;}}}}&lt;br /&gt;
|categories={{{categories|{{#ifeq:{{NAMESPACE}}|{{ns:10}}|{{#switch:{{{demolevel|{{#ifeq:{{PROTECTIONLEVEL:edit}}-{{PROTECTIONLEVEL:move}}|-sysop|move|{{PROTECTIONLEVEL:edit}}}}}}}&lt;br /&gt;
   |semi&lt;br /&gt;
   |autoconfirmed=[[Category:Wikipedia semi-protected templates|{{PAGENAME}}]]{{#ifeq:{{PROTECTIONLEVEL:move}}|sysop|[[Category:Wikipedia move-protected templates|{{PAGENAME}}]]}}&lt;br /&gt;
   |move=[[Category:Wikipedia move-protected templates|{{PAGENAME}}]]&lt;br /&gt;
   |administrator&lt;br /&gt;
   |full&lt;br /&gt;
   |sysop&amp;lt;!--uses default--&amp;gt;&lt;br /&gt;
   |#default=[[Category:Wikipedia protected templates|{{PAGENAME}}]]&amp;lt;!--fallback value--&amp;gt;}}}}{{#ifeq:{{NAMESPACE}}|{{ns:6}}|[[Category:{{#switch:{{{demolevel|{{PROTECTIONLEVEL:edit}}}}}&lt;br /&gt;
   |semi&lt;br /&gt;
   |autoconfirmed=Semi-protected&lt;br /&gt;
   |administrator&lt;br /&gt;
   |full&lt;br /&gt;
   |sysop&amp;lt;!--uses default--&amp;gt;&lt;br /&gt;
   |#default=Protected&amp;lt;!--fallback value--&amp;gt;}} images|{{PAGENAME}}]]}}}}}}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{pp-template|categories=no}}  &amp;lt;!-- Show the small version --&amp;gt;&lt;br /&gt;
{{pp-template|small=no}}      &amp;lt;!-- Show the large version --&amp;gt;&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;!-- Add categories and interwikis to the /doc subpage, not here! --&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Cite_web&amp;diff=12866</id>
		<title>Template:Cite web</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Cite_web&amp;diff=12866"/>
		<updated>2010-07-28T14:20:41Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: Copied the {{cite web}} template code from Wikipedia, hope this works.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;includeonly&amp;gt;{{Citation/core&lt;br /&gt;
  |Citation class=web&lt;br /&gt;
  |Surname1 = {{#if:{{{last|}}}&lt;br /&gt;
                |{{{last}}}&lt;br /&gt;
                |{{#if:{{{last1|}}}&lt;br /&gt;
                   |{{{last1}}}&lt;br /&gt;
                   |{{{author|}}} &lt;br /&gt;
                 }}&lt;br /&gt;
              }}&lt;br /&gt;
  |Surname2 = {{{last2|{{{surname2|{{{author2|}}}}}}}}} &lt;br /&gt;
  |Surname3 = {{{last3|}}}&lt;br /&gt;
  |Surname4 = {{{last4|}}}&lt;br /&gt;
  |Surname5 = {{{last5|}}}&lt;br /&gt;
  |Surname6 = {{{last6|}}}&lt;br /&gt;
  |Surname7 = {{{last7|}}}&lt;br /&gt;
  |Surname8 = {{{last8|}}}&lt;br /&gt;
  |Surname9 = {{{last9|}}}&lt;br /&gt;
  |Given1 = {{#if:{{{first|}}}|{{{first}}}|{{{first1|}}}}}&lt;br /&gt;
  |Given2 = {{{first2|}}}&lt;br /&gt;
  |Given3 = {{{first3|}}}&lt;br /&gt;
  |Given4 = {{{first4|}}}&lt;br /&gt;
  |Given5 = {{{first5|}}}&lt;br /&gt;
  |Given6 = {{{first6|}}}&lt;br /&gt;
  |Given7 = {{{first7|}}}&lt;br /&gt;
  |Given8 = {{{first8|}}}&lt;br /&gt;
  |Given9 = {{{first9|}}}&lt;br /&gt;
  |Authorlink1 = {{#if:{{{authorlink|}}}|{{{authorlink}}}|{{{authorlink1|}}}}}&lt;br /&gt;
  |Authorlink2 = {{{authorlink2|}}}&lt;br /&gt;
  |Authorlink3 = {{{authorlink3|}}}&lt;br /&gt;
  |Authorlink4 = {{{authorlink4|}}}&lt;br /&gt;
  |Authorlink5 = {{{authorlink5|}}}&lt;br /&gt;
  |Authorlink6 = {{{authorlink6|}}}&lt;br /&gt;
  |Authorlink7 = {{{authorlink7|}}}&lt;br /&gt;
  |Authorlink8 = {{{authorlink8|}}}&lt;br /&gt;
  |Authorlink9 = {{{authorlink9|}}}&lt;br /&gt;
  |Coauthors = {{{coauthor|{{{coauthors|}}}}}}&lt;br /&gt;
  |EditorSurname1 = {{{editor-last|{{{editor-surname|{{{editor1-last|{{{editor1-surname|{{{editor1|{{{editor|{{{editors|}}}}}}}}}}}}}}}}}}}}}&lt;br /&gt;
  |EditorSurname2 = {{{editor2-last|{{{editor2-surname|{{{editor2|}}}}}}}}}&lt;br /&gt;
  |EditorSurname3 = {{{editor3-last|{{{editor3-surname|{{{editor3|}}}}}}}}}&lt;br /&gt;
  |EditorSurname4 = {{{editor4-last|{{{editor4-surname|{{{editor4|}}}}}}}}}&lt;br /&gt;
  |EditorGiven1 = {{{editor-first|{{{editor-given|{{{editor1-first|{{{editor1-given|}}}}}}}}}}}}&lt;br /&gt;
  |EditorGiven2={{{editor2-first|{{{editor2-given|}}}}}}&lt;br /&gt;
  |EditorGiven3={{{editor3-first|{{{editor3-given|}}}}}}&lt;br /&gt;
  |EditorGiven4={{{editor4-first|{{{editor4-given|}}}}}}&lt;br /&gt;
  |Editorlink1={{{editor-link|{{{editor1-link|}}}}}}&lt;br /&gt;
  |Editorlink2={{{editor2-link|}}}&lt;br /&gt;
  |Editorlink3={{{editor3-link|}}}&lt;br /&gt;
  |Editorlink4={{{editor4-link|}}}&lt;br /&gt;
  |Year={{#if:{{{year|}}}|{{{year}}}    &amp;lt;!-- attempt to derive year from date, if possible --&amp;gt;&lt;br /&gt;
          |{{#if: {{{date|}}}&lt;br /&gt;
             |{{#iferror: {{#time:Y|{{{date|}}} }}&lt;br /&gt;
                |{{#iferror:{{#time:Y|{{{publication-date|einval}}} }}||{{#time:Y|{{{publication-date|}}} }}}}&lt;br /&gt;
                |{{#time:Y|{{{date|}}} }}&lt;br /&gt;
              }}&lt;br /&gt;
             |{{{publication-date|}}} &amp;lt;!-- last resort --&amp;gt;&lt;br /&gt;
           }}&lt;br /&gt;
        }}&lt;br /&gt;
  |Date = {{#if:{{{date|}}}|{{{date}}}|{{{day|}}} {{{month|}}} {{#if:{{{year|}}}|{{{year}}}|{{{publication-date|}}}}}}}&lt;br /&gt;
  |Title={{{work|}}}&lt;br /&gt;
  |TransTitle={{{trans_title|}}}&lt;br /&gt;
  |At = {{#if:{{{page|}}}|p. {{{page}}}|{{#if:{{{pages|}}}|pp. {{{pages|}}}|{{{at|}}} }} }}&lt;br /&gt;
  |IncludedWorkTitle = {{&lt;br /&gt;
    #if:{{{title|}}}&lt;br /&gt;
    |{{{title}}}&lt;br /&gt;
    |{{&lt;br /&gt;
      #if:{{{trans_title|}}}&lt;br /&gt;
      |&lt;br /&gt;
      |{{Citation error|no &amp;lt;code&amp;gt;&amp;amp;#124;title&amp;amp;#61;&amp;lt;/code&amp;gt; specified|Cite web}}&lt;br /&gt;
      }}&lt;br /&gt;
    }}&lt;br /&gt;
  |IncludedWorkURL = {{#if:{{{archiveurl|}}}|{{{archiveurl|}}}|{{{url|}}}}}&lt;br /&gt;
  |PublicationPlace = {{{location|}}}&lt;br /&gt;
  |Publisher = {{{publisher|}}}&lt;br /&gt;
  |language = {{{language|}}}&lt;br /&gt;
  |format = {{{format|}}}&lt;br /&gt;
  |DOI={{{doi|{{{DOI|}}}}}}&lt;br /&gt;
  |AccessDate={{#if:{{{accessdate|}}}&lt;br /&gt;
                |{{#if: {{{accessyear|}}}&lt;br /&gt;
                   |{{{accessdate}}} {{{accessyear}}}&lt;br /&gt;
                   |{{{accessdate}}}&lt;br /&gt;
                 }}&lt;br /&gt;
                |{{{accessday|}}} {{{accessmonth|}}} {{{accessyear|}}}&lt;br /&gt;
   }}&lt;br /&gt;
  |DateFormat={{#if:{{{dateformat|}}}|{{{dateformat}}}|none}}&lt;br /&gt;
  |quote = {{{quote|}}}&lt;br /&gt;
  |Ref={{{ref|}}}&lt;br /&gt;
  |Sep = {{#ifeq:{{{separator|{{{seperator}}} }}}|;|&amp;amp;#059;|{{{separator|{{{seperator|.}}} }}} }}&lt;br /&gt;
  |PS={{#if:{{{quote|}}}||{{{postscript|.}}}}}&lt;br /&gt;
  |ArchiveURL = {{{archiveurl|}}}&lt;br /&gt;
  |OriginalURL = {{{url|}}}&lt;br /&gt;
  |ArchiveDate= {{{archivedate|}}}&lt;br /&gt;
}}{{#if:{{{accessdaymonth|}}}{{{accessmonthday|}}}{{{accessday|}}}{{{accessmonth|}}}{{{accessyear|}}}{{{day|}}}{{{access-date|}}}{{{dateformat|}}}|[[Category:Pages containing cite templates with deprecated parameters|{{NAMESPACE}} {{PAGENAME}}]]}}&amp;lt;/includeonly&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{Pp-template|small=yes}}&lt;br /&gt;
{{Documentation}}&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12865</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12865"/>
		<updated>2010-07-28T14:17:56Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;{{cite web |url=http://www.beatnik.com/pdf_files/xmf_datasheet.pdf |title=eXtensible Music Format}}&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;{{cite web |url=http://www.sonivoxrocks.com/google.html |title=SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform |date=2007-11-01 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;{{cite web |url=http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf |title=Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection |date=2007-06-12 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;{{cite web |url=http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 |title=Mobile eXtensible Music File |date=2010-01-09 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;{{cite web |url=http://www.midi.org/techspecs/manid.php |title=MMANUFACTURER'S ID NUMBERS |date=2010-06-01 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Reflist&amp;diff=12853</id>
		<title>Template:Reflist</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Reflist&amp;diff=12853"/>
		<updated>2010-07-26T21:17:18Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: Rolling back edits after failing to get it to work. Will try again later.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;references-small {{#if: {{{colwidth|}}} | references-column-width | {{#iferror: {{#ifexpr: {{{1|1}}}&amp;gt;1 | references-column-count references-column-count-{{{1}}} }} }} }}&amp;quot; {{#if: {{{colwidth|}}}| style=&amp;quot;-moz-column-width:{{{colwidth}}}; column-width:{{{colwidth}}};&amp;quot; | {{#if: {{{1|}}}| style=&amp;quot;-moz-column-count:{{{1}}}; column-count:{{{1}}};&amp;quot; }} }}&amp;gt;&lt;br /&gt;
{{#tag:references|{{{refs|}}}|group={{{group|}}}}}&amp;lt;/div&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12852</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12852"/>
		<updated>2010-07-26T21:14:18Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;{{cite web |url=http://www.beatnik.com/pdf_files/xmf_datasheet.pdf |title=eXtensible Music Format}}&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;{{cite web |url=http://www.sonivoxrocks.com/google.html |title=SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform |date=2007-11-01 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;{{cite web |url=http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf |title=Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection |date=2007-06-12 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;{{cite web |url=http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 |title=Mobile eXtensible Music File |date=2010-01-09 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;{{cite web |url=http://www.midi.org/techspecs/manid.php |title=MMANUFACTURER'S ID NUMBERS |date=2010-06-01 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
{{reflist}}&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Reflist&amp;diff=12851</id>
		<title>Template:Reflist</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Reflist&amp;diff=12851"/>
		<updated>2010-07-26T21:13:26Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;references-small&amp;quot;&amp;gt;&lt;br /&gt;
{{#tag:references|{{{refs|}}}|group={{{group|}}}}}&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Template:Reflist&amp;diff=12850</id>
		<title>Template:Reflist</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Template:Reflist&amp;diff=12850"/>
		<updated>2010-07-26T21:12:25Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;references-small&amp;quot; {{#if: {{{colwidth|}}} | references-column-width | {{#iferror: {{#ifexpr: {{{1|1}}}&amp;gt;1 | references-column-count references-column-count-{{{1}}} }} }} }} {{#if: {{{colwidth|}}}| style=&amp;quot;-moz-column-width:{{{colwidth}}}; column-width:{{{colwidth}}};&amp;quot; | {{#if: {{{1|}}}| style=&amp;quot;-moz-column-count:{{{1}}}; column-count:{{{1}}};&amp;quot; }} }}&amp;gt;&lt;br /&gt;
{{#tag:references|{{{refs|}}}|group={{{group|}}}}}&amp;lt;/div&amp;gt;&amp;lt;noinclude&amp;gt;&lt;br /&gt;
{{documentation}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12849</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12849"/>
		<updated>2010-07-26T14:55:39Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;{{cite web |url=http://www.beatnik.com/pdf_files/xmf_datasheet.pdf |title=eXtensible Music Format}}&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;{{cite web |url=http://www.sonivoxrocks.com/google.html |title=SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform |date=2007-11-01 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;{{cite web |url=http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf |title=Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection |date=2007-06-12 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;{{cite web |url=http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 |title=Mobile eXtensible Music File |date=2010-01-09 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;{{cite web |url=http://www.midi.org/techspecs/manid.php |title=MMANUFACTURER'S ID NUMBERS |date=2010-06-01 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
{{reflist|3}}&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12848</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12848"/>
		<updated>2010-07-26T14:49:22Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;{{cite web |url=http://www.beatnik.com/pdf_files/xmf_datasheet.pdf |title=eXtensible Music Format}}&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;{{cite web |url=http://www.sonivoxrocks.com/google.html |title=SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform |date=2007-11-01 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;{{cite web |url=http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf |title=Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection |date=2007-06-12 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;{{cite web |url=http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 |title=Mobile eXtensible Music File |date=2010-01-09 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;{{cite web |url=http://www.midi.org/techspecs/manid.php |title=MMANUFACTURER'S ID NUMBERS |date=2010-06-01 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12847</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12847"/>
		<updated>2010-07-26T14:46:41Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;{{cite web |url=http://www.beatnik.com/pdf_files/xmf_datasheet.pdf |title=eXtensible Music Format |date=2003-01-30 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disappeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;{{cite web |url=http://www.sonivoxrocks.com/google.html |title=SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform |date=2007-11-01 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;{{cite web |url=http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf |title=Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection |date=2007-06-12 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;{{cite web |url=http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 |title=Mobile eXtensible Music File |date=2010-01-09 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;{{cite web |url=http://www.midi.org/techspecs/manid.php |title=MMANUFACTURER'S ID NUMBERS |date=2010-06-01 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12846</id>
		<title>Extensible Music Format (XMF)</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=Extensible_Music_Format_(XMF)&amp;diff=12846"/>
		<updated>2010-07-26T14:41:00Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''eXtensible Music Format (XMF)''' is a tree-structured container format developed by the [http://www.midi.org/ MIDI Manufacturer's Association] from 2001 to 2004. Historically it was promoted as a way to package together MIDI tunes and DLS instrument sounds for distribution, ensuring a consistent playback experience across environments&amp;lt;ref name=&amp;quot;WhatXMFIsFor&amp;quot;&amp;gt;{{cite web |url=http://www.beatnik.com/pdf_files/xmf_datasheet.pdf |title=eXtensible Music Format |date=2003-01-30 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;. It saw ample adoption on early &amp;quot;polyphonic&amp;quot; mobile phones, but as handsets achieved support for MP3 and other digital audio formats, the consumer market for instrument-based formats all but disapeared. Despite that it remains widely supported: even recent mobile architectures such as Google's Android include XMF playing technology&amp;lt;ref name=&amp;quot;XMFInAndroid&amp;quot;&amp;gt;{{cite web |url=http://www.sonivoxrocks.com/google.html |title=SONiVOX Contributes audioINSIDE Technology to Google Open Handset Alliance and Android Platform |date=2007-11-01 |accessdate=2010-07-23}}&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
Internally, XMF files are composed of a ''header chunk'' and a collection of ''node chunks'' ordered in [http://en.wikipedia.org/wiki/Tree_traversal#Depth-first_Traversal preorder]. Nodes can be either of type ''folder'' (in which case they will have at least one child node) or ''contents'' (in which case they encapsulate a data stream, such as MIDI or DLS contents). Most data in XMF nodes is encoded in [http://en.wikipedia.org/wiki/Variable-length_quantity variable-length quantity (VLQ)], a universal code that uses an arbitrary number of binary octets (eight-bit bytes) to represent an arbitrarily large integer. The Python code snippet below illustrates how a VLQ-encoded integer can be converted back to its native representation:&lt;br /&gt;
&lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1)) &lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
         &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
&lt;br /&gt;
The diagram below illustrates the structure of the XMF format, displaying an example file's internals both in contiguous and tree forms.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;50%&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|align=&amp;quot;center&amp;quot; colspan=&amp;quot;2&amp;quot;|ut_60-dls.xmf&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Header Chunk&lt;br /&gt;
|-&lt;br /&gt;
|Root Node&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 1&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 1&lt;br /&gt;
|-&lt;br /&gt;
|ut.mid&lt;br /&gt;
|-&lt;br /&gt;
|Folder Node 2&lt;br /&gt;
|-&lt;br /&gt;
|Contents Node 2&lt;br /&gt;
|-&lt;br /&gt;
|mobile60.dls&lt;br /&gt;
|}&lt;br /&gt;
|[[Image:Ut_60-dls.xmf.png]]&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The structure above is typical of several XMF authoring tools, including Beatnik's Mobile Sound Builder and Nokia's [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Audio Suite] plugin for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX]. It's far from optimal, however, as it unnecessarily nests the media contents inside exclusive folder nodes, when they could very well be put directly under the root node (and in fact some mobile players are known to choke on those extra nodes).&lt;br /&gt;
&lt;br /&gt;
=== Header Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF header chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Format ID&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;&amp;quot;XMF_&amp;quot; (0x584d465f)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Format version&lt;br /&gt;
|&amp;lt;code&amp;gt;byte[4]&amp;lt;/code&amp;gt;&lt;br /&gt;
|One of &amp;lt;code&amp;gt;&amp;quot;1.00&amp;quot; (0x312E3030)&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;&amp;quot;1.01&amp;quot; (0x312E3031)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;&amp;quot;2.00&amp;quot; (0x322E3030)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File Type Revision ID&lt;br /&gt;
|&amp;lt;code&amp;gt;int32&amp;lt;/code&amp;gt;&lt;br /&gt;
|Magic number indicating the XMF file type's revision&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|File size&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The file size in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the Metadata Types Table (MTT), in bytes&lt;br /&gt;
|-&lt;br /&gt;
|MTT Contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded contents of the MTT&lt;br /&gt;
|-&lt;br /&gt;
|Tree Start Offset (TFO)&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The root node's absolute offset within the XMF file&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;small&amp;gt;1. Included as of version 2.0 of the spec. Not present in files encoded to earlier versions.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Node Chunk ===&lt;br /&gt;
&lt;br /&gt;
The table below relates the fields of a XMF node chunk, in order of occurrence.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; width=&amp;quot;70%&amp;quot; border=&amp;quot;1&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #aaa solid; border-collapse: collapse&amp;quot;&lt;br /&gt;
|-align=&amp;quot;left&amp;quot;&lt;br /&gt;
!width=&amp;quot;20%&amp;quot;| Field&lt;br /&gt;
!width=&amp;quot;7%&amp;quot;|  Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
|Node length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|The node's length in bytes, including the length of all child nodes (for folder nodes) or encapsulated contents (for content nodes)&lt;br /&gt;
|-&lt;br /&gt;
|Item count&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Children node count, must be zero for content nodes&lt;br /&gt;
|-&lt;br /&gt;
|Node header length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of this node's header, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata length&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Length of the node's metadata, in bytes&lt;br /&gt;
|-&lt;br /&gt;
|Node metadata contents&lt;br /&gt;
|N/A&lt;br /&gt;
|Binary-encoded node metadata contents&lt;br /&gt;
|-&lt;br /&gt;
|Reference type&lt;br /&gt;
|&amp;lt;code&amp;gt;VLQ&amp;lt;/code&amp;gt;&lt;br /&gt;
|Indicates whether the following contents constitute an actual data buffer (&amp;lt;code&amp;gt;0x1&amp;lt;/code&amp;gt;) or an offset to somewhere else within the file (&amp;lt;code&amp;gt;0x2&amp;lt;/code&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
|Contents&lt;br /&gt;
|&amp;lt;code&amp;gt;N/A&amp;lt;/code&amp;gt;&lt;br /&gt;
|Either a data buffer or an offset value within the file, depending on the reference type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Simple Example Parser ===&lt;br /&gt;
&lt;br /&gt;
As way of illustration, the Python script below decodes an input XMF file, printing various statistics about its contents:&lt;br /&gt;
&lt;br /&gt;
 from os import SEEK_CUR, SEEK_SET&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodemetadata(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMetadata Size   : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnodeheader(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.metadata = xmfnodemetadata()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nHeader Size     : ' + str(self.size)   + ' bytes' + \&lt;br /&gt;
             str(self.metadata)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmfnode(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.header = xmfnodeheader()&lt;br /&gt;
         self.children = []&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nNode Size       : ' + str(self.size)          + ' bytes' + \&lt;br /&gt;
                                      str(self.header)        + \&lt;br /&gt;
             '\nReference Type  : ' + hex(self.reftype)       + \&lt;br /&gt;
             '\nContents        : ' + str(self.contents)      + \&lt;br /&gt;
             '\nChildren Count  : ' + str(len(self.children)) + \&lt;br /&gt;
             '\n'.join([str(child).replace('\n', '\n    ') for child in self.children])&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class mtt(object):&lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return '\nMTT Length        : ' + str(self.size) + ' bytes'&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 class xmf10(object):&lt;br /&gt;
     def __init__(self):&lt;br /&gt;
         self.mtt = mtt()&lt;br /&gt;
 &lt;br /&gt;
     def __str__(self):&lt;br /&gt;
         return \&lt;br /&gt;
             '\nFormat ID         : ' + self.formatid + \&lt;br /&gt;
             '\nFormat Version    : ' + self.version + \&lt;br /&gt;
             '\nFile Size         : ' + str(self.size) + ' bytes' + \&lt;br /&gt;
             str(self.mtt)            + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             '\nContent Nodes:'       + \&lt;br /&gt;
             '\n'                     + \&lt;br /&gt;
             str(self.root)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def vlq2int(data):&lt;br /&gt;
     r'''Read one VLQ-encoded integer value from an input data stream.&lt;br /&gt;
     '''&lt;br /&gt;
     value = 0&lt;br /&gt;
     while True:&lt;br /&gt;
         # Read one numeric octet from the input stream&lt;br /&gt;
         octet = ord(data.read(1))&lt;br /&gt;
 &lt;br /&gt;
         # Appends the octet to the output value, discarding the continuation bit&lt;br /&gt;
         value = (value &amp;lt;&amp;lt; 7) + (octet &amp;amp; 0x7F)&lt;br /&gt;
 &lt;br /&gt;
         # If the continuation bit is zero, this was the last octet&lt;br /&gt;
         if (octet &amp;amp; 0x80) == 0:&lt;br /&gt;
             break&lt;br /&gt;
 &lt;br /&gt;
     return value&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parsenode(data):&lt;br /&gt;
     offset = data.tell()&lt;br /&gt;
 &lt;br /&gt;
     node = xmfnode()&lt;br /&gt;
     node.size = vlq2int(data)&lt;br /&gt;
     childcount = vlq2int(data)&lt;br /&gt;
     node.header.size = vlq2int(data)&lt;br /&gt;
     node.header.metadata.size = vlq2int(data)&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.header.size, SEEK_SET)&lt;br /&gt;
     node.reftype = vlq2int(data)&lt;br /&gt;
     node.contents = '(folder)'&lt;br /&gt;
     node.children = []&lt;br /&gt;
 &lt;br /&gt;
     if childcount &amp;gt; 0:&lt;br /&gt;
         node.children = [parsenode(data) for i in range(0, childcount)]&lt;br /&gt;
     elif node.reftype == 1:&lt;br /&gt;
         node.contents = data.read(4)&lt;br /&gt;
     else:&lt;br /&gt;
         raise Exception('Invalid type ' + hex(node.reftype))&lt;br /&gt;
 &lt;br /&gt;
     data.seek(offset + node.size, SEEK_SET)&lt;br /&gt;
 &lt;br /&gt;
     return node&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 def parse(path):&lt;br /&gt;
     with open(path, 'rb') as data:&lt;br /&gt;
         xmf = xmf10()&lt;br /&gt;
 &lt;br /&gt;
         xmf.formatid = data.read(4)&lt;br /&gt;
         xmf.version = data.read(4)&lt;br /&gt;
         if xmf.version != '1.00':&lt;br /&gt;
             raise Exception('Invalid version \&amp;quot;' + xmf.version + '\&amp;quot;')&lt;br /&gt;
 &lt;br /&gt;
         xmf.size = vlq2int(data)&lt;br /&gt;
         xmf.mtt.size = vlq2int(data)&lt;br /&gt;
         data.seek(xmf.mtt.size, SEEK_CUR)&lt;br /&gt;
 &lt;br /&gt;
         tfo = vlq2int(data)&lt;br /&gt;
         data.seek(tfo, SEEK_SET)&lt;br /&gt;
         xmf.root = parsenode(data)&lt;br /&gt;
 &lt;br /&gt;
         return path + '\n' + str(xmf)&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 if __name__ == '__main__':&lt;br /&gt;
     from sys import argv&lt;br /&gt;
 &lt;br /&gt;
     parsed = parse(argv[1])&lt;br /&gt;
     print(parsed)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools ==&lt;br /&gt;
&lt;br /&gt;
The MMA provides a [http://www.midi.org/techspecs/xmf/xmf_products.php list of authoring tools for XMF]; however, virtually every one of them is currently unsupported, their makers having either moved past the format or gone with it. Some can still be found around the Internet, however:&lt;br /&gt;
&lt;br /&gt;
# The [http://www.beatnik.com/pdf_files/msb_datasheet.pdf Mobile Sound Builder] was [http://www.beatnik.com/ Beatnik]'s solution for authoring and playing XMF files. It's hard to tell from their half-functioning company website whether it's still supported, but binaries for version 1.2 often turn up in Google searches;&lt;br /&gt;
# [http://www.forum.nokia.com/info/sw.nokia.com/id/9395846c-262c-47e0-9420-3cd5dec627af/Nokia_Audio_Suite.html Nokia Audio Suite] is a plug-in for [http://www.steinberg.net/en/support/downloads/cubase_sx_3.html Steinberg Cubase SX] which adds the ability to author XMF files. It's a free download, however license keys for version 2.0 are issued only to users outside of Japan and US, while keys for version 1.1 aren't even available anymore – so effectively it can't be used by neither Japanese nor American developers;&lt;br /&gt;
# [http://www.faith-inc.com/ Faith] reportedly&amp;lt;ref name=&amp;quot;FaithmXMFTool&amp;quot;&amp;gt;{{cite web |url=http://www.faith-inc.com/ir/pdf/070612rm_faithinsound4.pdf |title=Mobile Game Audio Gets Boost from Faith West’s mXMFTool and New Royalty-Free Game Sounds Collection |date=2007-06-12 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt; once provided the mXMFTool as a free download, however it was removed when their San Francisco office (Faith West) was closed. Currently it's nowhere to be found, though it seems you can talk them into mailing you a copy&amp;lt;ref name=&amp;quot;FaithmXMFToolGet&amp;quot;&amp;gt;{{cite web |url=http://www.j2meforums.com/forum/index.php?PHPSESSID=a41099ffd022ae3b4afb8e2838c0a398&amp;amp;topic=22589.msg104916#msg104916 |title=Mobile eXtensible Music File |date=2010-01-09 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;;&lt;br /&gt;
# The [http://www.pac.fi/ Professional Audio Company] apparently provided some sort of XMF-related tool in the past, but no further information seems to be available. The company relinquished their MMA Manufacturer ID&amp;lt;ref name=&amp;quot;PACMMAID&amp;quot;&amp;gt;{{cite web |url=http://www.midi.org/techspecs/manid.php |title=MMANUFACTURER'S ID NUMBERS |date=2010-06-01 |accessdate=2010-07-26}}&amp;lt;/ref&amp;gt;, so it's very unlikely they still work with it;&lt;br /&gt;
# [http://www.crimsontech.jp/eng/home.html Crimson Technology] still provides a demo version for their [http://www.crimsontech.jp/eng/dls/ DLS tools], however it's unclear what XMF features (if any) they enable.&lt;br /&gt;
&lt;br /&gt;
== External links ==&lt;br /&gt;
&lt;br /&gt;
# [http://www.midi.org/techspecs/xmf/ XMF - eXtensible Music Format]&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
	<entry>
		<id>https://wiki.multimedia.cx/index.php?title=File:Ut_60-dls.xmf.png&amp;diff=12845</id>
		<title>File:Ut 60-dls.xmf.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.multimedia.cx/index.php?title=File:Ut_60-dls.xmf.png&amp;diff=12845"/>
		<updated>2010-07-26T14:37:41Z</updated>

		<summary type="html">&lt;p&gt;Xperroni: Internal structure of XMF file ut_60-dls.xmf in tree form.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Internal structure of XMF file ut_60-dls.xmf in tree form.&lt;/div&gt;</summary>
		<author><name>Xperroni</name></author>
	</entry>
</feed>