summaryrefslogtreecommitdiff
path: root/doxygen/html/MidiFileIn_8cpp-source.html
diff options
context:
space:
mode:
Diffstat (limited to 'doxygen/html/MidiFileIn_8cpp-source.html')
-rwxr-xr-xdoxygen/html/MidiFileIn_8cpp-source.html350
1 files changed, 350 insertions, 0 deletions
diff --git a/doxygen/html/MidiFileIn_8cpp-source.html b/doxygen/html/MidiFileIn_8cpp-source.html
new file mode 100755
index 0000000..a7109dd
--- /dev/null
+++ b/doxygen/html/MidiFileIn_8cpp-source.html
@@ -0,0 +1,350 @@
+<HTML>
+<HEAD>
+<TITLE>The Synthesis ToolKit in C++ (STK)</TITLE>
+<LINK HREF="doxygen.css" REL="stylesheet" TYPE="text/css">
+</HEAD>
+<BODY BGCOLOR="#FFFFFF">
+<CENTER>
+<img src="princeton.gif"> &nbsp; <img src="ccrma.gif"><P>
+<a class="qindex" href="index.html">Home</a> &nbsp; <a class="qindex" href="information.html">Information</a> &nbsp; <a class="qindex" href="classes.html">Classes</a> &nbsp; <a class="qindex" href="download.html">Download</a> &nbsp; <a class="qindex" href="usage.html">Usage</a> &nbsp; <a class="qindex" href="maillist.html">Mail List</a> &nbsp; <a class="qindex" href="system.html">Requirements</a> &nbsp; <a class="qindex" href="links.html">Links</a> &nbsp; <a class="qindex" href="tutorial.html">Tutorial</a></CENTER>
+<HR>
+<!-- Generated by Doxygen 1.3-rc3 -->
+<h1>MidiFileIn.cpp</h1><div class="fragment"><pre>00001 <span class="comment">/**********************************************************************/</span>
+00016 <span class="comment">/**********************************************************************/</span>
+00017
+00018 <span class="preprocessor">#include "MidiFileIn.h"</span>
+00019 <span class="preprocessor">#include &lt;iostream&gt;</span>
+00020
+<a name="l00021"></a><a class="code" href="classMidiFileIn.html#a0">00021</a> <a class="code" href="classMidiFileIn.html#a0">MidiFileIn :: MidiFileIn</a>( std::string fileName )
+00022 {
+00023 <span class="comment">// Attempt to open the file.</span>
+00024 file_.open( fileName.c_str(), std::ios::in );
+00025 <span class="keywordflow">if</span> ( !file_ ) {
+00026 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn: error opening or finding file ("</span> &lt;&lt; fileName &lt;&lt; <span class="stringliteral">")."</span>;
+00027 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FILE_NOT_FOUND );
+00028 }
+00029
+00030 <span class="comment">// Parse header info.</span>
+00031 <span class="keywordtype">char</span> chunkType[4];
+00032 <span class="keywordtype">char</span> buffer[4];
+00033 SINT32 *length;
+00034 <span class="keywordflow">if</span> ( !file_.read( chunkType, 4 ) ) <span class="keywordflow">goto</span> error;
+00035 <span class="keywordflow">if</span> ( !file_.read( buffer, 4 ) ) <span class="keywordflow">goto</span> error;
+00036 length = (SINT32 *) &amp;buffer;
+00037 <span class="keywordflow">if</span> ( strncmp( chunkType, <span class="stringliteral">"MThd"</span>, 4 ) || ( *length != 6 ) ) {
+00038 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn: file ("</span> &lt;&lt; fileName &lt;&lt; <span class="stringliteral">") does not appear to be a MIDI file!"</span>;
+00039 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FILE_UNKNOWN_FORMAT );
+00040 }
+00041
+00042 <span class="comment">// Read the MIDI file format.</span>
+00043 SINT16 *data;
+00044 <span class="keywordflow">if</span> ( !file_.read( buffer, 2 ) ) <span class="keywordflow">goto</span> error;
+00045 data = (SINT16 *) &amp;buffer;
+00046 <span class="keywordflow">if</span> ( *data &lt; 0 || *data &gt; 2 ) {
+00047 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn: the file ("</span> &lt;&lt; fileName &lt;&lt; <span class="stringliteral">") format is invalid!"</span>;
+00048 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FILE_ERROR );
+00049 }
+00050 format_ = *data;
+00051
+00052 <span class="comment">// Read the number of tracks.</span>
+00053 <span class="keywordflow">if</span> ( !file_.read( buffer, 2 ) ) <span class="keywordflow">goto</span> error;
+00054 <span class="keywordflow">if</span> ( format_ == 0 &amp;&amp; *data != 1 ) {
+00055 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn: invalid number of tracks (&gt;1) for a file format = 0!"</span>;
+00056 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FILE_ERROR );
+00057 }
+00058 nTracks_ = *data;
+00059
+00060 <span class="comment">// Read the beat division.</span>
+00061 <span class="keywordflow">if</span> ( !file_.read( buffer, 2 ) ) <span class="keywordflow">goto</span> error;
+00062 division_ = (int) *data;
+00063 <span class="keywordtype">double</span> tickrate;
+00064 usingTimeCode_ = <span class="keyword">false</span>;
+00065 <span class="keywordflow">if</span> ( *data &amp; 0x8000 ) {
+00066 <span class="comment">// Determine ticks per second from time-code formats.</span>
+00067 tickrate = (double) -(*data &amp; 0x7F00);
+00068 <span class="comment">// If frames per second value is 29, it really should be 29.97.</span>
+00069 <span class="keywordflow">if</span> ( tickrate == 29.0 ) tickrate = 29.97;
+00070 tickrate *= (*data &amp; 0x00FF);
+00071 usingTimeCode_ = <span class="keyword">true</span>;
+00072 }
+00073 <span class="keywordflow">else</span> {
+00074 tickrate = (double) (*data &amp; 0x7FFF); <span class="comment">// ticks per quarter note</span>
+00075 }
+00076
+00077 <span class="comment">// Now locate the track offsets and lengths. If not using time</span>
+00078 <span class="comment">// code, we can initialize the "tick time" using a default tempo of</span>
+00079 <span class="comment">// 120 beats per minute. We will then check for tempo meta-events</span>
+00080 <span class="comment">// afterward.</span>
+00081 <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nTracks_; i++ ) {
+00082 <span class="keywordflow">if</span> ( !file_.read( chunkType, 4 ) ) <span class="keywordflow">goto</span> error;
+00083 <span class="keywordflow">if</span> ( strncmp( chunkType, <span class="stringliteral">"MTrk"</span>, 4 ) ) <span class="keywordflow">goto</span> error;
+00084 <span class="keywordflow">if</span> ( !file_.read( buffer, 4 ) ) <span class="keywordflow">goto</span> error;
+00085 length = (SINT32 *) &amp;buffer;
+00086 trackLengths_.push_back( *length );
+00087 trackOffsets_.push_back( file_.tellg() );
+00088 trackPointers_.push_back( file_.tellg() );
+00089 trackStatus_.push_back( 0 );
+00090 file_.seekg( *length, std::ios_base::cur );
+00091 <span class="keywordflow">if</span> ( usingTimeCode_ ) tickSeconds_.push_back( (<span class="keywordtype">double</span>) (1.0 / tickrate) );
+00092 <span class="keywordflow">else</span> tickSeconds_.push_back( (<span class="keywordtype">double</span>) (0.5 / tickrate) );
+00093 }
+00094
+00095 <span class="comment">// Save the initial tickSeconds parameter.</span>
+00096 TempoChange tempoEvent;
+00097 tempoEvent.count = 0;
+00098 tempoEvent.tickSeconds = tickSeconds_[0];
+00099 tempoEvents_.push_back( tempoEvent );
+00100
+00101 <span class="comment">// If format 1 and not using time code, parse and save the tempo map</span>
+00102 <span class="comment">// on track 0.</span>
+00103 <span class="keywordflow">if</span> ( format_ == 1 &amp;&amp; !usingTimeCode_ ) {
+00104 std::vector&lt;unsigned char&gt; event;
+00105 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> value, count;
+00106
+00107 <span class="comment">// We need to temporarily change the usingTimeCode_ value here so</span>
+00108 <span class="comment">// that the getNextEvent() function doesn't try to check the tempo</span>
+00109 <span class="comment">// map (which we're creating here).</span>
+00110 usingTimeCode_ = <span class="keyword">true</span>;
+00111 count = <a class="code" href="classMidiFileIn.html#a7">getNextEvent</a>( &amp;event, 0 );
+00112 <span class="keywordflow">while</span> ( event.size() ) {
+00113 <span class="keywordflow">if</span> ( ( event.size() == 6 ) &amp;&amp; ( event[0] == 0xff ) &amp;&amp;
+00114 ( event[1] == 0x51 ) &amp;&amp; ( event[2] == 0x03 ) ) {
+00115 tempoEvent.count = count;
+00116 value = ( event[3] &lt;&lt; 16 ) + ( event[4] &lt;&lt; 8 ) + event[5];
+00117 tempoEvent.tickSeconds = (double) (0.000001 * value / tickrate);
+00118 <span class="keywordflow">if</span> ( count &gt; tempoEvents_.back().count )
+00119 tempoEvents_.push_back( tempoEvent );
+00120 <span class="keywordflow">else</span>
+00121 tempoEvents_.back() = tempoEvent;
+00122 }
+00123 count += <a class="code" href="classMidiFileIn.html#a7">getNextEvent</a>( &amp;event, 0 );
+00124 }
+00125 <a class="code" href="classMidiFileIn.html#a5">rewindTrack</a>( 0 );
+00126 <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;nTracks_; i++ ) {
+00127 trackCounters_.push_back( 0 );
+00128 trackTempoIndex_.push_back( 0 );
+00129 }
+00130 <span class="comment">// Change the time code flag back!</span>
+00131 usingTimeCode_ = <span class="keyword">false</span>;
+00132 }
+00133
+00134 <span class="keywordflow">return</span>;
+00135
+00136 error:
+00137 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn: error reading from file ("</span> &lt;&lt; fileName &lt;&lt; <span class="stringliteral">")."</span>;
+00138 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FILE_ERROR );
+00139 }
+00140
+<a name="l00141"></a><a class="code" href="classMidiFileIn.html#a1">00141</a> <a class="code" href="classMidiFileIn.html#a1">MidiFileIn :: ~MidiFileIn</a>()
+00142 {
+00143 <span class="comment">// An ifstream object implicitly closes itself during destruction</span>
+00144 <span class="comment">// but we'll make an explicit call to "close" anyway.</span>
+00145 file_.close();
+00146 }
+00147
+<a name="l00148"></a><a class="code" href="classMidiFileIn.html#a2">00148</a> <span class="keywordtype">int</span> <a class="code" href="classMidiFileIn.html#a2">MidiFileIn :: getFileFormat</a>()<span class="keyword"> const</span>
+00149 <span class="keyword"></span>{
+00150 <span class="keywordflow">return</span> format_;
+00151 }
+00152
+<a name="l00153"></a><a class="code" href="classMidiFileIn.html#a3">00153</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="classMidiFileIn.html#a3">MidiFileIn :: getNumberOfTracks</a>()<span class="keyword"> const</span>
+00154 <span class="keyword"></span>{
+00155 <span class="keywordflow">return</span> nTracks_;
+00156 }
+00157
+<a name="l00158"></a><a class="code" href="classMidiFileIn.html#a4">00158</a> <span class="keywordtype">int</span> <a class="code" href="classMidiFileIn.html#a4">MidiFileIn :: getDivision</a>()<span class="keyword"> const</span>
+00159 <span class="keyword"></span>{
+00160 <span class="keywordflow">return</span> division_;
+00161 }
+00162
+<a name="l00163"></a><a class="code" href="classMidiFileIn.html#a5">00163</a> <span class="keywordtype">void</span> <a class="code" href="classMidiFileIn.html#a5">MidiFileIn :: rewindTrack</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> track )
+00164 {
+00165 <span class="keywordflow">if</span> ( track &gt;= nTracks_ ) {
+00166 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn::getNextEvent: invalid track argument ("</span> &lt;&lt; track &lt;&lt; <span class="stringliteral">")."</span>;
+00167 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FUNCTION_ARGUMENT );
+00168 }
+00169
+00170 trackPointers_[track] = trackOffsets_[track];
+00171 trackStatus_[track] = 0;
+00172 tickSeconds_[track] = tempoEvents_[0].tickSeconds;
+00173 }
+00174
+<a name="l00175"></a><a class="code" href="classMidiFileIn.html#a6">00175</a> <span class="keywordtype">double</span> <a class="code" href="classMidiFileIn.html#a6">MidiFileIn :: getTickSeconds</a>( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> track )
+00176 {
+00177 <span class="comment">// Return the current tick value in seconds for the given track.</span>
+00178 <span class="keywordflow">if</span> ( track &gt;= nTracks_ ) {
+00179 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn::getTickSeconds: invalid track argument ("</span> &lt;&lt; track &lt;&lt; <span class="stringliteral">")."</span>;
+00180 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FUNCTION_ARGUMENT );
+00181 }
+00182
+00183 <span class="keywordflow">return</span> tickSeconds_[track];
+00184 }
+00185
+<a name="l00186"></a><a class="code" href="classMidiFileIn.html#a7">00186</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <a class="code" href="classMidiFileIn.html#a7">MidiFileIn :: getNextEvent</a>( std::vector&lt;unsigned char&gt; *event, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> track )
+00187 {
+00188 <span class="comment">// Fill the user-provided vector with the next event in the</span>
+00189 <span class="comment">// specified track (default = 0) and return the event delta time in</span>
+00190 <span class="comment">// ticks. This function assumes that the stored track pointer is</span>
+00191 <span class="comment">// positioned at the start of a track event. If the track has</span>
+00192 <span class="comment">// reached its end, the event vector size will be zero.</span>
+00193 <span class="comment">//</span>
+00194 <span class="comment">// If we have a format 0 or 2 file and we're not using timecode, we</span>
+00195 <span class="comment">// should check every meta-event for tempo changes and make</span>
+00196 <span class="comment">// appropriate updates to the tickSeconds_ parameter if so.</span>
+00197 <span class="comment">//</span>
+00198 <span class="comment">// If we have a format 1 file and we're not using timecode, keep a</span>
+00199 <span class="comment">// running sum of ticks for each track and update the tickSeconds_</span>
+00200 <span class="comment">// parameter as needed based on the stored tempo map.</span>
+00201
+00202 <span class="keywordflow">if</span> ( track &gt;= nTracks_ ) {
+00203 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn::getNextEvent: invalid track argument ("</span> &lt;&lt; track &lt;&lt; <span class="stringliteral">")."</span>;
+00204 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FUNCTION_ARGUMENT );
+00205 }
+00206
+00207 event-&gt;clear();
+00208 <span class="comment">// Check for the end of the track.</span>
+00209 <span class="keywordflow">if</span> ( (trackPointers_[track] - trackOffsets_[track]) &gt;= trackLengths_[track] )
+00210 <span class="keywordflow">return</span> 0;
+00211
+00212 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> ticks = 0, bytes = 0;
+00213 <span class="keywordtype">bool</span> isTempoEvent = <span class="keyword">false</span>;
+00214
+00215 <span class="comment">// Read the event delta time.</span>
+00216 file_.seekg( trackPointers_[track], std::ios_base::beg );
+00217 <span class="keywordflow">if</span> ( !readVariableLength( &amp;ticks ) ) <span class="keywordflow">goto</span> error;
+00218
+00219 <span class="comment">// Parse the event stream to determine the event length.</span>
+00220 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> c;
+00221 <span class="keywordflow">if</span> ( !file_.read( (<span class="keywordtype">char</span> *)&amp;c, 1 ) ) <span class="keywordflow">goto</span> error;
+00222 <span class="keywordflow">switch</span> ( c ) {
+00223
+00224 <span class="keywordflow">case</span> 0xFF: <span class="comment">// A Meta-Event</span>
+00225 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> position;
+00226 trackStatus_[track] = 0;
+00227 event-&gt;push_back( c );
+00228 <span class="keywordflow">if</span> ( !file_.read( (<span class="keywordtype">char</span> *)&amp;c, 1 ) ) <span class="keywordflow">goto</span> error;
+00229 event-&gt;push_back( c );
+00230 <span class="keywordflow">if</span> ( format_ != 1 &amp;&amp; ( c == 0x51 ) ) isTempoEvent = <span class="keyword">true</span>;
+00231 position = file_.tellg();
+00232 <span class="keywordflow">if</span> ( !readVariableLength( &amp;bytes ) ) <span class="keywordflow">goto</span> error;
+00233 bytes += ( (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)file_.tellg() - position );
+00234 file_.seekg( position, std::ios_base::beg );
+00235 <span class="keywordflow">break</span>;
+00236
+00237 <span class="keywordflow">case</span> 0xF0 || 0xF7: <span class="comment">// The start or continuation of a Sysex event</span>
+00238 trackStatus_[track] = 0;
+00239 event-&gt;push_back( c );
+00240 position = file_.tellg();
+00241 <span class="keywordflow">if</span> ( !readVariableLength( &amp;bytes ) ) <span class="keywordflow">goto</span> error;
+00242 bytes += ( (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>)file_.tellg() - position );
+00243 file_.seekg( position, std::ios_base::beg );
+00244 <span class="keywordflow">break</span>;
+00245
+00246 <span class="keywordflow">default</span>: <span class="comment">// Should be a MIDI channel event</span>
+00247 <span class="keywordflow">if</span> ( c &amp; 0x80 ) { <span class="comment">// MIDI status byte</span>
+00248 <span class="keywordflow">if</span> ( c &gt; 0xF0 ) <span class="keywordflow">goto</span> error;
+00249 trackStatus_[track] = c;
+00250 event-&gt;push_back( c );
+00251 c &amp;= 0xF0;
+00252 <span class="keywordflow">if</span> ( (c == 0xC0) || (c == 0xD0) ) bytes = 1;
+00253 <span class="keywordflow">else</span> bytes = 2;
+00254 }
+00255 <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( trackStatus_[track] &amp; 0x80 ) { <span class="comment">// Running status</span>
+00256 event-&gt;push_back( trackStatus_[track] );
+00257 event-&gt;push_back( c );
+00258 c = trackStatus_[track] &amp; 0xF0;
+00259 <span class="keywordflow">if</span> ( (c != 0xC0) &amp;&amp; (c != 0xD0) ) bytes = 1;
+00260 }
+00261 <span class="keywordflow">else</span> <span class="keywordflow">goto</span> error;
+00262
+00263 }
+00264
+00265 <span class="comment">// Read the rest of the event into the event vector.</span>
+00266 <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> i=0; i&lt;bytes; i++ ) {
+00267 <span class="keywordflow">if</span> ( !file_.read( (<span class="keywordtype">char</span> *)&amp;c, 1 ) ) <span class="keywordflow">goto</span> error;
+00268 event-&gt;push_back( c );
+00269 }
+00270
+00271 <span class="keywordflow">if</span> ( !usingTimeCode_ ) {
+00272 <span class="keywordflow">if</span> ( isTempoEvent ) {
+00273 <span class="comment">// Parse the tempo event and update tickSeconds_[track].</span>
+00274 <span class="keywordtype">double</span> tickrate = (double) (division_ &amp; 0x7FFF);
+00275 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> value = ( event-&gt;at(3) &lt;&lt; 16 ) + ( event-&gt;at(4) &lt;&lt; 8 ) + event-&gt;at(5);
+00276 tickSeconds_[track] = (double) (0.000001 * value / tickrate);
+00277 }
+00278
+00279 <span class="keywordflow">if</span> ( format_ == 1 ) {
+00280 <span class="comment">// Update track counter and check the tempo map.</span>
+00281 trackCounters_[track] += ticks;
+00282 TempoChange tempoEvent = tempoEvents_[ trackTempoIndex_[track] ];
+00283 <span class="keywordflow">if</span> ( trackCounters_[track] &gt;= tempoEvent.count ) {
+00284 trackTempoIndex_[track]++;
+00285 tickSeconds_[track] = tempoEvent.tickSeconds;
+00286 }
+00287 }
+00288 }
+00289
+00290 <span class="comment">// Save the current track pointer value.</span>
+00291 trackPointers_[track] = file_.tellg();
+00292
+00293 <span class="keywordflow">return</span> ticks;
+00294
+00295 error:
+00296 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn::getNextEvent: file read error!"</span>;
+00297 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FILE_ERROR );
+00298 <span class="keywordflow">return</span> 0;
+00299 }
+00300
+<a name="l00301"></a><a class="code" href="classMidiFileIn.html#a8">00301</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> <a class="code" href="classMidiFileIn.html#a8">MidiFileIn :: getNextMidiEvent</a>( std::vector&lt;unsigned char&gt; *midiEvent, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> track )
+00302 {
+00303 <span class="comment">// Fill the user-provided vector with the next MIDI event in the</span>
+00304 <span class="comment">// specified track (default = 0) and return the event delta time in</span>
+00305 <span class="comment">// ticks. Meta-Events preceeding this event are skipped and ignored.</span>
+00306 <span class="keywordflow">if</span> ( track &gt;= nTracks_ ) {
+00307 errorString_ &lt;&lt; <span class="stringliteral">"MidiFileIn::getNextMidiEvent: invalid track argument ("</span> &lt;&lt; track &lt;&lt; <span class="stringliteral">")."</span>;
+00308 <a class="code" href="classStk.html#e0">handleError</a>( errorString_.str(), StkError::FUNCTION_ARGUMENT );
+00309 }
+00310
+00311 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> ticks = <a class="code" href="classMidiFileIn.html#a7">getNextEvent</a>( midiEvent, track );
+00312 <span class="keywordflow">while</span> ( midiEvent-&gt;size() &amp;&amp; ( midiEvent-&gt;at(0) &gt;= 0xF0 ) ) {
+00313 <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;midiEvent-&gt;size(); i++ )
+00314 std::cout &lt;&lt; <span class="stringliteral">"event byte = "</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">", value = "</span> &lt;&lt; (int)midiEvent-&gt;at(i) &lt;&lt; std::endl;
+00315 ticks = <a class="code" href="classMidiFileIn.html#a7">getNextEvent</a>( midiEvent, track );
+00316 }
+00317
+00318 <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i=0; i&lt;midiEvent-&gt;size(); i++ )
+00319 std::cout &lt;&lt; <span class="stringliteral">"event byte = "</span> &lt;&lt; i &lt;&lt; <span class="stringliteral">", value = "</span> &lt;&lt; (int)midiEvent-&gt;at(i) &lt;&lt; std::endl;
+00320
+00321 <span class="keywordflow">return</span> ticks;
+00322 }
+00323
+00324 <span class="keywordtype">bool</span> MidiFileIn :: readVariableLength( <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> *value )
+00325 {
+00326 <span class="comment">// It is assumed that this function is called with the file read</span>
+00327 <span class="comment">// pointer positioned at the start of a variable-length value. The</span>
+00328 <span class="comment">// function returns "true" if the value is successfully parsed and</span>
+00329 <span class="comment">// "false" otherwise.</span>
+00330 *value = 0;
+00331 <span class="keywordtype">char</span> c;
+00332
+00333 <span class="keywordflow">if</span> ( !file_.read( &amp;c, 1 ) ) <span class="keywordflow">return</span> <span class="keyword">false</span>;
+00334 *value = (<span class="keywordtype">unsigned</span> <span class="keywordtype">long</span>) c;
+00335 <span class="keywordflow">if</span> ( *value &amp; 0x80 ) {
+00336 *value &amp;= 0x7f;
+00337 <span class="keywordflow">do</span> {
+00338 <span class="keywordflow">if</span> ( !file_.read( &amp;c, 1 ) ) <span class="keywordflow">return</span> <span class="keyword">false</span>;
+00339 *value = ( *value &lt;&lt; 7 ) + ( c &amp; 0x7f );
+00340 } <span class="keywordflow">while</span> ( c &amp; 0x80 );
+00341 }
+00342
+00343 <span class="keywordflow">return</span> <span class="keyword">true</span>;
+00344 }
+</pre></div><HR>
+
+<table>
+ <tr><td><A HREF="http://www-ccrma.stanford.edu/software/stk/"><I>The Synthesis ToolKit in C++ (STK)</I></A></td></tr>
+ <tr><td>&copy;1995-2002 Perry R. Cook and Gary P. Scavone. All Rights Reserved.</td></tr>
+</table>
+
+</BODY>
+</HTML>