inweb-bootstrap/docs/foundation-module/6-sd.html
2020-08-16 18:39:53 +01:00

387 lines
84 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Sound Durations</title>
<link href="../docs-assets/Breadcrumbs.css" rel="stylesheet" rev="stylesheet" type="text/css">
<meta name="viewport" content="width=device-width initial-scale=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="Content-Language" content="en-gb">
<link href="../docs-assets/Contents.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Progress.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Navigation.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Fonts.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Base.css" rel="stylesheet" rev="stylesheet" type="text/css">
<link href="../docs-assets/Colours.css" rel="stylesheet" rev="stylesheet" type="text/css">
</head>
<body class="commentary-font">
<nav role="navigation">
<h1><a href="../index.html">
<img src="../docs-assets/Octagram.png" width=72 height=72">
</a></h1>
<ul><li><a href="../inweb/index.html">inweb</a></li>
</ul><h2>Foundation Module</h2><ul>
<li><a href="index.html"><span class="selectedlink">foundation</span></a></li>
<li><a href="../foundation-test/index.html">foundation-test</a></li>
</ul><h2>Example Webs</h2><ul>
<li><a href="../goldbach/index.html">goldbach</a></li>
<li><a href="../twinprimes/twinprimes.html">twinprimes</a></li>
<li><a href="../eastertide/index.html">eastertide</a></li>
</ul><h2>Repository</h2><ul>
<li><a href="https://github.com/ganelson/inweb"><img src="../docs-assets/github.png" height=18> github</a></li>
</ul><h2>Related Projects</h2><ul>
<li><a href="../../../inform/docs/index.html">inform</a></li>
<li><a href="../../../intest/docs/index.html">intest</a></li>
</ul>
</nav>
<main role="main">
<!--Weave of 'Sound Durations' generated by Inweb-->
<div class="breadcrumbs">
<ul class="crumbs"><li><a href="../index.html">Home</a></li><li><a href="index.html">foundation</a></li><li><a href="index.html#6">Chapter 6: Media</a></li><li><b>Sound Durations</b></li></ul></div>
<p class="purpose">These utility routines look at the headers of AIFF, OGG Vorbis or MIDI files to find the durations, and verify that they are what they purport to be.</p>
<ul class="toc"><li><a href="6-sd.html#SP1">&#167;1. AIFF files</a></li><li><a href="6-sd.html#SP2">&#167;2. OGG Vorbis files</a></li><li><a href="6-sd.html#SP3">&#167;3. MIDI files</a></li></ul><hr class="tocbar">
<p class="commentary firstcommentary"><a id="SP1" class="paragraph-anchor"></a><b>&#167;1. AIFF files. </b>The code in this section was once again originated by Toby Nelson. To
explicate the following, see the specifications for AIFF and OGG headers.
Durations are measured in centiseconds.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SoundFiles::get_AIFF_duration</span><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pDuration</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pBitsPerSecond</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pChannels</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sig</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">chunkID</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">chunkLength</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">numSampleFrames</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sampleSize</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sig</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sig</span><span class="plain-syntax"> != </span><span class="constant-syntax">0x464F524D</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"FORM"</span></span><span class="comment-syntax"> indicating an IFF file</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sig</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sig</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sig</span><span class="plain-syntax"> != </span><span class="constant-syntax">0x41494646</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"AIFF"</span></span><span class="comment-syntax"> indicating an AIFF file</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read chunks, skipping over those we are not interested in</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="constant-syntax">TRUE</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">chunkID</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">chunkLength</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chunkID</span><span class="plain-syntax"> == </span><span class="constant-syntax">0x434F4D4D</span><span class="plain-syntax">) { </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"COMM"</span></span><span class="comment-syntax"> indicates common AIFF data</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">chunkLength</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">18</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> Check we have enough data to read</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int16</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="identifier-syntax">pChannels</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">numSampleFrames</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int16</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sampleSize</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP5" class="function-link"><span class="function-syntax">BinaryFiles::read_float80</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (*</span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> Sanity check to avoid a divide by zero</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Result is in centiseconds</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">pDuration</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) (((</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax">) </span><span class="identifier-syntax">numSampleFrames</span><span class="plain-syntax"> * </span><span class="constant-syntax">100</span><span class="plain-syntax">) / *</span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">pBitsPerSecond</span><span class="plain-syntax"> = *</span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax"> * *</span><span class="identifier-syntax">pChannels</span><span class="plain-syntax"> * </span><span class="identifier-syntax">sampleSize</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip unwanted chunk</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, (</span><span class="reserved-syntax">long</span><span class="plain-syntax">) </span><span class="identifier-syntax">chunkLength</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_CUR</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP2" class="paragraph-anchor"></a><b>&#167;2. OGG Vorbis files. </b></p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SoundFiles::get_OggVorbis_duration</span><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pDuration</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pBitsPerSecond</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pChannels</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sig</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">version</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">numSegments</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">packetType</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">vorbisSig1</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">vorbisSig2</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">seekPos</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">fileLength</span><span class="plain-syntax">, </span><span class="identifier-syntax">bytesToRead</span><span class="plain-syntax">, </span><span class="identifier-syntax">lastSig</span><span class="plain-syntax">, </span><span class="identifier-syntax">index</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="identifier-syntax">granulePosition</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[256];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sig</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sig</span><span class="plain-syntax"> != </span><span class="constant-syntax">0x4F676753</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"OggS"</span></span><span class="comment-syntax"> indicating an OGG file</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Check OGG version is zero</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int8</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">version</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">version</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip header type, granule position, serial number, page sequence and CRC</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="constant-syntax">21</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_CUR</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read number of page segments</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int8</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">numSegments</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip segment table</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, (</span><span class="reserved-syntax">long</span><span class="plain-syntax">) </span><span class="identifier-syntax">numSegments</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_CUR</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Vorbis Identification header</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int8</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">packetType</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">packetType</span><span class="plain-syntax"> != </span><span class="constant-syntax">1</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">vorbisSig1</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">vorbisSig1</span><span class="plain-syntax"> != </span><span class="constant-syntax">0x766F7262</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"VORB"</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int16</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">vorbisSig2</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">vorbisSig2</span><span class="plain-syntax"> != </span><span class="constant-syntax">0x6973</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"IS"</span></span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Check Vorbis version is zero</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">version</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">version</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read number of channels</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int8</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="identifier-syntax">pChannels</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read sample rate</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="6-bf.html#SP3" class="function-link"><span class="function-syntax">BinaryFiles::swap_bytes32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax">); </span><span class="comment-syntax"> Ogg Vorbis uses LSB first</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip bitrate maximum</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="constant-syntax">4</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_CUR</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read Nominal Bitrate</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="identifier-syntax">pBitsPerSecond</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="6-bf.html#SP3" class="function-link"><span class="function-syntax">BinaryFiles::swap_bytes32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pBitsPerSecond</span><span class="plain-syntax">); </span><span class="comment-syntax"> Ogg Vorbis uses LSB first</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Encoders can be unhelpful and give no bitrate in the header</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pBitsPerSecond</span><span class="plain-syntax"> == </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Search for the final Ogg page (near the end of the file) to read duration,</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> i.e., read the last 4K of the file and look for the final </span><span class="extract"><span class="extract-syntax">"OggS"</span></span><span class="comment-syntax"> sig</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="constant-syntax">0</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_END</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">fileLength</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">ftell</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fileLength</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">4096</span><span class="plain-syntax">) </span><span class="identifier-syntax">seekPos</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="identifier-syntax">seekPos</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileLength</span><span class="plain-syntax"> - </span><span class="constant-syntax">4096</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lastSig</span><span class="plain-syntax"> = </span><span class="constant-syntax">0xFFFFFFFF</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="identifier-syntax">seekPos</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">fileLength</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, (</span><span class="reserved-syntax">long</span><span class="plain-syntax">) </span><span class="identifier-syntax">seekPos</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_SET</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">bytesToRead</span><span class="plain-syntax"> = </span><span class="identifier-syntax">fileLength</span><span class="plain-syntax"> - </span><span class="identifier-syntax">seekPos</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">bytesToRead</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">256</span><span class="plain-syntax">) </span><span class="identifier-syntax">bytesToRead</span><span class="plain-syntax"> = </span><span class="constant-syntax">256</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fread</span><span class="plain-syntax">(</span><span class="identifier-syntax">buffer</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">bytesToRead</span><span class="plain-syntax">, </span><span class="identifier-syntax">pFile</span><span class="plain-syntax">) != </span><span class="identifier-syntax">bytesToRead</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">for</span><span class="plain-syntax">(</span><span class="identifier-syntax">index</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">; </span><span class="identifier-syntax">index</span><span class="plain-syntax"> &lt; </span><span class="identifier-syntax">bytesToRead</span><span class="plain-syntax">; </span><span class="identifier-syntax">index</span><span class="plain-syntax">++) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">index</span><span class="plain-syntax">] == </span><span class="constant-syntax">0x4F</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">index</span><span class="plain-syntax"> + </span><span class="constant-syntax">1</span><span class="plain-syntax">] == </span><span class="constant-syntax">0x67</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">index</span><span class="plain-syntax"> + </span><span class="constant-syntax">2</span><span class="plain-syntax">] == </span><span class="constant-syntax">0x67</span><span class="plain-syntax">) &amp;&amp;</span>
<span class="plain-syntax"> (</span><span class="identifier-syntax">buffer</span><span class="plain-syntax">[</span><span class="identifier-syntax">index</span><span class="plain-syntax"> + </span><span class="constant-syntax">3</span><span class="plain-syntax">] == </span><span class="constant-syntax">0x53</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">lastSig</span><span class="plain-syntax"> = </span><span class="identifier-syntax">seekPos</span><span class="plain-syntax"> + </span><span class="identifier-syntax">index</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Next place to read from is 256 bytes further on, but to catch</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> sigs that span between these blocks, read the last four bytes again</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">seekPos</span><span class="plain-syntax"> += </span><span class="constant-syntax">256</span><span class="plain-syntax"> - </span><span class="constant-syntax">4</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">lastSig</span><span class="plain-syntax"> == </span><span class="constant-syntax">0xFFFFFFFF</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, (</span><span class="reserved-syntax">long</span><span class="plain-syntax">) </span><span class="identifier-syntax">lastSig</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_SET</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sig</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sig</span><span class="plain-syntax"> != </span><span class="constant-syntax">0x4F676753</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">; </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"OggS"</span></span><span class="comment-syntax"> indicating an OGG file</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Check OGG version is zero</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int8</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">version</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">version</span><span class="plain-syntax"> != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip header Type</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="constant-syntax">1</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_CUR</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int64</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">granulePosition</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><a href="6-bf.html#SP3" class="function-link"><span class="function-syntax">BinaryFiles::swap_bytes64</span></a><span class="plain-syntax">(&amp;</span><span class="identifier-syntax">granulePosition</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> *</span><span class="identifier-syntax">pDuration</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) ((</span><span class="identifier-syntax">granulePosition</span><span class="plain-syntax"> * </span><span class="constant-syntax">100</span><span class="plain-syntax">) /</span>
<span class="plain-syntax"> (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax"> </span><span class="reserved-syntax">long</span><span class="plain-syntax">) *</span><span class="identifier-syntax">pSampleRate</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<p class="commentary firstcommentary"><a id="SP3" class="paragraph-anchor"></a><b>&#167;3. MIDI files. </b>At one time it was proposed that Inform 7 should allow a third sound file
format: MIDI. This provoked considerable debate in July 2007 and enough
doubts were raised that the implementation below was never in fact
officially used. It is preserved here in case we ever revive the issue.
</p>
<p class="commentary">Inform is not really able to decide this for itself, in any case, since
it can only usefully provide sound files which the virtual machines it
compiles for will allow. At present, the Glulx virtual machine does not
officially support MIDI, which makes the question moot.
</p>
<pre class="displayed-code all-displayed-code code-font">
<span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="function-syntax">SoundFiles::get_MIDI_information</span><span class="plain-syntax">(</span><span class="reserved-syntax">FILE</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pType</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> *</span><span class="identifier-syntax">pNumTracks</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sig</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">length</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">pulses</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">frames_per_second</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">subframes_per_frame</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">clocks_per_second</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">start_of_chunk_data</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">status</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">clocks</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">sysex_length</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">non_midi_event_length</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">start_of_non_midi_data</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">non_midi_event</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sig</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"RIFF"</span></span><span class="comment-syntax"> indicating a RIFF file</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sig</span><span class="plain-syntax"> == </span><span class="constant-syntax">0x52494646</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip the filesize and typeID</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="constant-syntax">8</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_CUR</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> now read the real MIDI sig</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sig</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"MThd"</span></span><span class="comment-syntax"> indicating a MIDI file</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sig</span><span class="plain-syntax"> != </span><span class="constant-syntax">0x4D546864</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read length of chunk</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">length</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Make sure we have enough data to read</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">length</span><span class="plain-syntax"> &lt; </span><span class="constant-syntax">6</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read the MIDI type: 0,1 or 2</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> 0 means one track containing up to 16 channels to make a single tune</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> 1 means one or more tracks, commonly each with a single channel, making up a single tune</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> 2 means one or more tracks, where each is a separate tune in it's own right</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int16</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="identifier-syntax">pType</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read the number of tracks</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int16</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="identifier-syntax">pNumTracks</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read "Pulses Per Quarter Note" (PPQN)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int16</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">pulses</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> if top bit set, then number of subframes per second can be deduced</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">pulses</span><span class="plain-syntax"> &gt;= </span><span class="constant-syntax">0x8000</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> First byte is a negative number for the frames per second</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Second byte is the number of subframes in each frame</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">frames_per_second</span><span class="plain-syntax"> = (256 - (</span><span class="identifier-syntax">pulses</span><span class="plain-syntax"> &amp; </span><span class="constant-syntax">0xff</span><span class="plain-syntax">));</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">subframes_per_frame</span><span class="plain-syntax"> = (</span><span class="identifier-syntax">pulses</span><span class="plain-syntax"> &gt;&gt; </span><span class="constant-syntax">8</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">clocks_per_second</span><span class="plain-syntax"> = </span><span class="identifier-syntax">frames_per_second</span><span class="plain-syntax"> * </span><span class="identifier-syntax">subframes_per_frame</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"frames_per_second = %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">frames_per_second</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"subframes_per_frame = %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">subframes_per_frame</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"clocks_per_second = %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">clocks_per_second</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Number of pulses per quarter note unknown</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">pulses</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> unknown values</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">frames_per_second</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">subframes_per_frame</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">clocks_per_second</span><span class="plain-syntax"> = </span><span class="constant-syntax">0</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"pulses per quarter note = %d\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">pulses</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip any remaining bytes in the MThd chunk</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, (</span><span class="reserved-syntax">long</span><span class="plain-syntax">) (</span><span class="identifier-syntax">length</span><span class="plain-syntax"> - </span><span class="constant-syntax">6</span><span class="plain-syntax">), </span><span class="identifier-syntax">SEEK_CUR</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Keep reading chunks, looking for </span><span class="extract"><span class="extract-syntax">"MTrk"</span></span>
<span class="plain-syntax"> </span><span class="reserved-syntax">do</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read chunk signature and length</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sig</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">feof</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int32</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">length</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">start_of_chunk_data</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">ftell</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">sig</span><span class="plain-syntax"> == </span><span class="constant-syntax">0x4D54726B</span><span class="plain-syntax">) { </span><span class="comment-syntax"> </span><span class="extract"><span class="extract-syntax">"MTrk"</span></span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"track starts\n"</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read each event, looking for information before the real tune starts, e.g., tempo</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">do</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read the number of clocks since the previous event</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP4" class="function-link"><span class="function-syntax">BinaryFiles::read_variable_length_integer</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">clocks</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> We bail out when the track starts</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">clocks</span><span class="plain-syntax"> &gt; </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read the MIDI Status byte</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int8</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">status</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Start or continuation of system exclusive data</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> ((</span><span class="identifier-syntax">status</span><span class="plain-syntax"> == </span><span class="constant-syntax">0xF0</span><span class="plain-syntax">) || (</span><span class="identifier-syntax">status</span><span class="plain-syntax"> == </span><span class="constant-syntax">0xF7</span><span class="plain-syntax">)) {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read length of system exclusive event data</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP4" class="function-link"><span class="function-syntax">BinaryFiles::read_variable_length_integer</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">sysex_length</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip sysex event</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, (</span><span class="reserved-syntax">long</span><span class="plain-syntax">) </span><span class="identifier-syntax">sysex_length</span><span class="plain-syntax">, </span><span class="identifier-syntax">SEEK_CUR</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">status</span><span class="plain-syntax"> == </span><span class="constant-syntax">0xFF</span><span class="plain-syntax">) { </span><span class="comment-syntax"> Non-MIDI event</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Read the Non-MIDI event type and length</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP1" class="function-link"><span class="function-syntax">BinaryFiles::read_int8</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">non_midi_event</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP4" class="function-link"><span class="function-syntax">BinaryFiles::read_variable_length_integer</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, &amp;</span><span class="identifier-syntax">non_midi_event_length</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">start_of_non_midi_data</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">ftell</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">switch</span><span class="plain-syntax">(</span><span class="identifier-syntax">non_midi_event</span><span class="plain-syntax">) {</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0x01</span><span class="identifier-syntax">:</span><span class="plain-syntax"> </span><span class="comment-syntax"> Comment text</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0x02</span><span class="identifier-syntax">:</span><span class="plain-syntax"> </span><span class="comment-syntax"> Copyright text</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0x03</span><span class="identifier-syntax">:</span><span class="plain-syntax"> </span><span class="comment-syntax"> Track name</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0x04</span><span class="identifier-syntax">:</span><span class="plain-syntax"> { </span><span class="comment-syntax"> Instrument name</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">char</span><span class="plain-syntax"> </span><span class="identifier-syntax">text</span><span class="plain-syntax">[257];</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (!</span><a href="6-bf.html#SP6" class="function-link"><span class="function-syntax">BinaryFiles::read_string</span></a><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">, </span><span class="identifier-syntax">non_midi_event_length</span><span class="plain-syntax">))</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="identifier-syntax">LOG</span><span class="plain-syntax">(</span><span class="string-syntax">"%d: %s\n"</span><span class="plain-syntax">, </span><span class="identifier-syntax">non_midi_event</span><span class="plain-syntax">, </span><span class="identifier-syntax">text</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0x51</span><span class="identifier-syntax">:</span><span class="plain-syntax"> </span><span class="comment-syntax"> Tempo change</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0x58</span><span class="identifier-syntax">:</span><span class="plain-syntax"> </span><span class="comment-syntax"> Time signature</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">case</span><span class="plain-syntax"> </span><span class="constant-syntax">0x59</span><span class="identifier-syntax">:</span><span class="plain-syntax"> </span><span class="comment-syntax"> Key signature</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Skip non-midi event</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">,</span>
<span class="plain-syntax"> (</span><span class="reserved-syntax">long</span><span class="plain-syntax">) (</span><span class="identifier-syntax">start_of_non_midi_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">non_midi_event_length</span><span class="plain-syntax">), </span><span class="identifier-syntax">SEEK_SET</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">)</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> } </span><span class="reserved-syntax">else</span><span class="plain-syntax"> {</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Real MIDI data found: we've read all we can so bail out at this point</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">break</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="constant-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Seek to start of next chunk</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">fseek</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">, (</span><span class="reserved-syntax">long</span><span class="plain-syntax">) (</span><span class="identifier-syntax">start_of_chunk_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">length</span><span class="plain-syntax">), </span><span class="identifier-syntax">SEEK_SET</span><span class="plain-syntax">) != </span><span class="constant-syntax">0</span><span class="plain-syntax">) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">FALSE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Reached end of file</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">feof</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> </span><span class="comment-syntax"> Did we try to seek beyond the end of the file?</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax"> </span><span class="identifier-syntax">position_in_file</span><span class="plain-syntax"> = (</span><span class="reserved-syntax">unsigned</span><span class="plain-syntax"> </span><span class="reserved-syntax">int</span><span class="plain-syntax">) </span><span class="identifier-syntax">ftell</span><span class="plain-syntax">(</span><span class="identifier-syntax">pFile</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">if</span><span class="plain-syntax"> (</span><span class="identifier-syntax">position_in_file</span><span class="plain-syntax"> &lt; (</span><span class="identifier-syntax">start_of_chunk_data</span><span class="plain-syntax"> + </span><span class="identifier-syntax">length</span><span class="plain-syntax">)) </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax"> }</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">while</span><span class="plain-syntax"> (</span><span class="constant-syntax">TRUE</span><span class="plain-syntax">);</span>
<span class="plain-syntax"> </span><span class="reserved-syntax">return</span><span class="plain-syntax"> </span><span class="constant-syntax">TRUE</span><span class="plain-syntax">;</span>
<span class="plain-syntax">}</span>
</pre>
<nav role="progress"><div class="progresscontainer">
<ul class="progressbar"><li class="progressprev"><a href="6-id.html">&#10094;</a></li><li class="progresschapter"><a href="P-abgtf.html">P</a></li><li class="progresschapter"><a href="1-fm.html">1</a></li><li class="progresschapter"><a href="2-dl.html">2</a></li><li class="progresschapter"><a href="3-em.html">3</a></li><li class="progresschapter"><a href="4-chr.html">4</a></li><li class="progresschapter"><a href="5-htm.html">5</a></li><li class="progresscurrentchapter">6</li><li class="progresssection"><a href="6-bf.html">bf</a></li><li class="progresssection"><a href="6-id.html">id</a></li><li class="progresscurrent">sd</li><li class="progresschapter"><a href="7-vn.html">7</a></li><li class="progresschapter"><a href="8-ws.html">8</a></li><li class="progressnext"><a href="7-vn.html">&#10095;</a></li></ul></div>
</nav><!--End of weave-->
</main>
</body>
</html>