File indexing completed on 2024-12-22 05:33:12
0001 <?php 0002 ///////////////////////////////////////////////////////////////// 0003 /// getID3() by James Heinrich <info@getid3.org> // 0004 // available at http://getid3.sourceforge.net // 0005 // or http://www.getid3.org // 0006 // also https://github.com/JamesHeinrich/getID3 // 0007 ///////////////////////////////////////////////////////////////// 0008 // See readme.txt for more details // 0009 ///////////////////////////////////////////////////////////////// 0010 // // 0011 // module.audio.midi.php // 0012 // module for Midi Audio files // 0013 // dependencies: NONE // 0014 // /// 0015 ///////////////////////////////////////////////////////////////// 0016 0017 define('GETID3_MIDI_MAGIC_MTHD', 'MThd'); // MIDI file header magic 0018 define('GETID3_MIDI_MAGIC_MTRK', 'MTrk'); // MIDI track header magic 0019 0020 class getid3_midi extends getid3_handler 0021 { 0022 public $scanwholefile = true; 0023 0024 public function Analyze() { 0025 $info = &$this->getid3->info; 0026 0027 // shortcut 0028 $info['midi']['raw'] = array(); 0029 $thisfile_midi = &$info['midi']; 0030 $thisfile_midi_raw = &$thisfile_midi['raw']; 0031 0032 $info['fileformat'] = 'midi'; 0033 $info['audio']['dataformat'] = 'midi'; 0034 0035 $this->fseek($info['avdataoffset']); 0036 $MIDIdata = $this->fread($this->getid3->fread_buffer_size()); 0037 $offset = 0; 0038 $MIDIheaderID = substr($MIDIdata, $offset, 4); // 'MThd' 0039 if ($MIDIheaderID != GETID3_MIDI_MAGIC_MTHD) { 0040 $info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes(GETID3_MIDI_MAGIC_MTHD).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($MIDIheaderID).'"'; 0041 unset($info['fileformat']); 0042 return false; 0043 } 0044 $offset += 4; 0045 $thisfile_midi_raw['headersize'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 4)); 0046 $offset += 4; 0047 $thisfile_midi_raw['fileformat'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2)); 0048 $offset += 2; 0049 $thisfile_midi_raw['tracks'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2)); 0050 $offset += 2; 0051 $thisfile_midi_raw['ticksperqnote'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2)); 0052 $offset += 2; 0053 0054 for ($i = 0; $i < $thisfile_midi_raw['tracks']; $i++) { 0055 while ((strlen($MIDIdata) - $offset) < 8) { 0056 if ($buffer = $this->fread($this->getid3->fread_buffer_size())) { 0057 $MIDIdata .= $buffer; 0058 } else { 0059 $info['warning'][] = 'only processed '.($i - 1).' of '.$thisfile_midi_raw['tracks'].' tracks'; 0060 $info['error'][] = 'Unabled to read more file data at '.$this->ftell().' (trying to seek to : '.$offset.'), was expecting at least 8 more bytes'; 0061 return false; 0062 } 0063 } 0064 $trackID = substr($MIDIdata, $offset, 4); 0065 $offset += 4; 0066 if ($trackID == GETID3_MIDI_MAGIC_MTRK) { 0067 $tracksize = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 4)); 0068 $offset += 4; 0069 //$thisfile_midi['tracks'][$i]['size'] = $tracksize; 0070 $trackdataarray[$i] = substr($MIDIdata, $offset, $tracksize); 0071 $offset += $tracksize; 0072 } else { 0073 $info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes(GETID3_MIDI_MAGIC_MTRK).'" at '.($offset - 4).', found "'.getid3_lib::PrintHexBytes($trackID).'" instead'; 0074 return false; 0075 } 0076 } 0077 0078 if (!isset($trackdataarray) || !is_array($trackdataarray)) { 0079 $info['error'][] = 'Cannot find MIDI track information'; 0080 unset($thisfile_midi); 0081 unset($info['fileformat']); 0082 return false; 0083 } 0084 0085 if ($this->scanwholefile) { // this can take quite a long time, so have the option to bypass it if speed is very important 0086 $thisfile_midi['totalticks'] = 0; 0087 $info['playtime_seconds'] = 0; 0088 $CurrentMicroSecondsPerBeat = 500000; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat 0089 $CurrentBeatsPerMinute = 120; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat 0090 $MicroSecondsPerQuarterNoteAfter = array (); 0091 0092 foreach ($trackdataarray as $tracknumber => $trackdata) { 0093 0094 $eventsoffset = 0; 0095 $LastIssuedMIDIcommand = 0; 0096 $LastIssuedMIDIchannel = 0; 0097 $CumulativeDeltaTime = 0; 0098 $TicksAtCurrentBPM = 0; 0099 while ($eventsoffset < strlen($trackdata)) { 0100 $eventid = 0; 0101 if (isset($MIDIevents[$tracknumber]) && is_array($MIDIevents[$tracknumber])) { 0102 $eventid = count($MIDIevents[$tracknumber]); 0103 } 0104 $deltatime = 0; 0105 for ($i = 0; $i < 4; $i++) { 0106 $deltatimebyte = ord(substr($trackdata, $eventsoffset++, 1)); 0107 $deltatime = ($deltatime << 7) + ($deltatimebyte & 0x7F); 0108 if ($deltatimebyte & 0x80) { 0109 // another byte follows 0110 } else { 0111 break; 0112 } 0113 } 0114 $CumulativeDeltaTime += $deltatime; 0115 $TicksAtCurrentBPM += $deltatime; 0116 $MIDIevents[$tracknumber][$eventid]['deltatime'] = $deltatime; 0117 $MIDI_event_channel = ord(substr($trackdata, $eventsoffset++, 1)); 0118 if ($MIDI_event_channel & 0x80) { 0119 // OK, normal event - MIDI command has MSB set 0120 $LastIssuedMIDIcommand = $MIDI_event_channel >> 4; 0121 $LastIssuedMIDIchannel = $MIDI_event_channel & 0x0F; 0122 } else { 0123 // running event - assume last command 0124 $eventsoffset--; 0125 } 0126 $MIDIevents[$tracknumber][$eventid]['eventid'] = $LastIssuedMIDIcommand; 0127 $MIDIevents[$tracknumber][$eventid]['channel'] = $LastIssuedMIDIchannel; 0128 if ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x08) { // Note off (key is released) 0129 0130 $notenumber = ord(substr($trackdata, $eventsoffset++, 1)); 0131 $velocity = ord(substr($trackdata, $eventsoffset++, 1)); 0132 0133 } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x09) { // Note on (key is pressed) 0134 0135 $notenumber = ord(substr($trackdata, $eventsoffset++, 1)); 0136 $velocity = ord(substr($trackdata, $eventsoffset++, 1)); 0137 0138 } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0A) { // Key after-touch 0139 0140 $notenumber = ord(substr($trackdata, $eventsoffset++, 1)); 0141 $velocity = ord(substr($trackdata, $eventsoffset++, 1)); 0142 0143 } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0B) { // Control Change 0144 0145 $controllernum = ord(substr($trackdata, $eventsoffset++, 1)); 0146 $newvalue = ord(substr($trackdata, $eventsoffset++, 1)); 0147 0148 } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0C) { // Program (patch) change 0149 0150 $newprogramnum = ord(substr($trackdata, $eventsoffset++, 1)); 0151 0152 $thisfile_midi_raw['track'][$tracknumber]['instrumentid'] = $newprogramnum; 0153 if ($tracknumber == 10) { 0154 $thisfile_midi_raw['track'][$tracknumber]['instrument'] = $this->GeneralMIDIpercussionLookup($newprogramnum); 0155 } else { 0156 $thisfile_midi_raw['track'][$tracknumber]['instrument'] = $this->GeneralMIDIinstrumentLookup($newprogramnum); 0157 } 0158 0159 } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0D) { // Channel after-touch 0160 0161 $channelnumber = ord(substr($trackdata, $eventsoffset++, 1)); 0162 0163 } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0E) { // Pitch wheel change (2000H is normal or no change) 0164 0165 $changeLSB = ord(substr($trackdata, $eventsoffset++, 1)); 0166 $changeMSB = ord(substr($trackdata, $eventsoffset++, 1)); 0167 $pitchwheelchange = (($changeMSB & 0x7F) << 7) & ($changeLSB & 0x7F); 0168 0169 } elseif (($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0F) && ($MIDIevents[$tracknumber][$eventid]['channel'] == 0x0F)) { 0170 0171 $METAeventCommand = ord(substr($trackdata, $eventsoffset++, 1)); 0172 $METAeventLength = ord(substr($trackdata, $eventsoffset++, 1)); 0173 $METAeventData = substr($trackdata, $eventsoffset, $METAeventLength); 0174 $eventsoffset += $METAeventLength; 0175 switch ($METAeventCommand) { 0176 case 0x00: // Set track sequence number 0177 $track_sequence_number = getid3_lib::BigEndian2Int(substr($METAeventData, 0, $METAeventLength)); 0178 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['seqno'] = $track_sequence_number; 0179 break; 0180 0181 case 0x01: // Text: generic 0182 $text_generic = substr($METAeventData, 0, $METAeventLength); 0183 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['text'] = $text_generic; 0184 $thisfile_midi['comments']['comment'][] = $text_generic; 0185 break; 0186 0187 case 0x02: // Text: copyright 0188 $text_copyright = substr($METAeventData, 0, $METAeventLength); 0189 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['copyright'] = $text_copyright; 0190 $thisfile_midi['comments']['copyright'][] = $text_copyright; 0191 break; 0192 0193 case 0x03: // Text: track name 0194 $text_trackname = substr($METAeventData, 0, $METAeventLength); 0195 $thisfile_midi_raw['track'][$tracknumber]['name'] = $text_trackname; 0196 break; 0197 0198 case 0x04: // Text: track instrument name 0199 $text_instrument = substr($METAeventData, 0, $METAeventLength); 0200 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['instrument'] = $text_instrument; 0201 break; 0202 0203 case 0x05: // Text: lyrics 0204 $text_lyrics = substr($METAeventData, 0, $METAeventLength); 0205 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['lyrics'] = $text_lyrics; 0206 if (!isset($thisfile_midi['lyrics'])) { 0207 $thisfile_midi['lyrics'] = ''; 0208 } 0209 $thisfile_midi['lyrics'] .= $text_lyrics."\n"; 0210 break; 0211 0212 case 0x06: // Text: marker 0213 $text_marker = substr($METAeventData, 0, $METAeventLength); 0214 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['marker'] = $text_marker; 0215 break; 0216 0217 case 0x07: // Text: cue point 0218 $text_cuepoint = substr($METAeventData, 0, $METAeventLength); 0219 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['cuepoint'] = $text_cuepoint; 0220 break; 0221 0222 case 0x2F: // End Of Track 0223 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['EOT'] = $CumulativeDeltaTime; 0224 break; 0225 0226 case 0x51: // Tempo: microseconds / quarter note 0227 $CurrentMicroSecondsPerBeat = getid3_lib::BigEndian2Int(substr($METAeventData, 0, $METAeventLength)); 0228 if ($CurrentMicroSecondsPerBeat == 0) { 0229 $info['error'][] = 'Corrupt MIDI file: CurrentMicroSecondsPerBeat == zero'; 0230 return false; 0231 } 0232 $thisfile_midi_raw['events'][$tracknumber][$CumulativeDeltaTime]['us_qnote'] = $CurrentMicroSecondsPerBeat; 0233 $CurrentBeatsPerMinute = (1000000 / $CurrentMicroSecondsPerBeat) * 60; 0234 $MicroSecondsPerQuarterNoteAfter[$CumulativeDeltaTime] = $CurrentMicroSecondsPerBeat; 0235 $TicksAtCurrentBPM = 0; 0236 break; 0237 0238 case 0x58: // Time signature 0239 $timesig_numerator = getid3_lib::BigEndian2Int($METAeventData{0}); 0240 $timesig_denominator = pow(2, getid3_lib::BigEndian2Int($METAeventData{1})); // $02 -> x/4, $03 -> x/8, etc 0241 $timesig_32inqnote = getid3_lib::BigEndian2Int($METAeventData{2}); // number of 32nd notes to the quarter note 0242 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_32inqnote'] = $timesig_32inqnote; 0243 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_numerator'] = $timesig_numerator; 0244 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_denominator'] = $timesig_denominator; 0245 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_text'] = $timesig_numerator.'/'.$timesig_denominator; 0246 $thisfile_midi['timesignature'][] = $timesig_numerator.'/'.$timesig_denominator; 0247 break; 0248 0249 case 0x59: // Keysignature 0250 $keysig_sharpsflats = getid3_lib::BigEndian2Int($METAeventData{0}); 0251 if ($keysig_sharpsflats & 0x80) { 0252 // (-7 -> 7 flats, 0 ->key of C, 7 -> 7 sharps) 0253 $keysig_sharpsflats -= 256; 0254 } 0255 0256 $keysig_majorminor = getid3_lib::BigEndian2Int($METAeventData{1}); // 0 -> major, 1 -> minor 0257 $keysigs = array(-7=>'Cb', -6=>'Gb', -5=>'Db', -4=>'Ab', -3=>'Eb', -2=>'Bb', -1=>'F', 0=>'C', 1=>'G', 2=>'D', 3=>'A', 4=>'E', 5=>'B', 6=>'F#', 7=>'C#'); 0258 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_sharps'] = (($keysig_sharpsflats > 0) ? abs($keysig_sharpsflats) : 0); 0259 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_flats'] = (($keysig_sharpsflats < 0) ? abs($keysig_sharpsflats) : 0); 0260 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_minor'] = (bool) $keysig_majorminor; 0261 //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_text'] = $keysigs[$keysig_sharpsflats].' '.($thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_minor'] ? 'minor' : 'major'); 0262 0263 // $keysigs[$keysig_sharpsflats] gets an int key (correct) - $keysigs["$keysig_sharpsflats"] gets a string key (incorrect) 0264 $thisfile_midi['keysignature'][] = $keysigs[$keysig_sharpsflats].' '.((bool) $keysig_majorminor ? 'minor' : 'major'); 0265 break; 0266 0267 case 0x7F: // Sequencer specific information 0268 $custom_data = substr($METAeventData, 0, $METAeventLength); 0269 break; 0270 0271 default: 0272 $info['warning'][] = 'Unhandled META Event Command: '.$METAeventCommand; 0273 break; 0274 } 0275 0276 } else { 0277 0278 $info['warning'][] = 'Unhandled MIDI Event ID: '.$MIDIevents[$tracknumber][$eventid]['eventid'].' + Channel ID: '.$MIDIevents[$tracknumber][$eventid]['channel']; 0279 0280 } 0281 } 0282 if (($tracknumber > 0) || (count($trackdataarray) == 1)) { 0283 $thisfile_midi['totalticks'] = max($thisfile_midi['totalticks'], $CumulativeDeltaTime); 0284 } 0285 } 0286 $previoustickoffset = null; 0287 0288 ksort($MicroSecondsPerQuarterNoteAfter); 0289 foreach ($MicroSecondsPerQuarterNoteAfter as $tickoffset => $microsecondsperbeat) { 0290 if (is_null($previoustickoffset)) { 0291 $prevmicrosecondsperbeat = $microsecondsperbeat; 0292 $previoustickoffset = $tickoffset; 0293 continue; 0294 } 0295 if ($thisfile_midi['totalticks'] > $tickoffset) { 0296 0297 if ($thisfile_midi_raw['ticksperqnote'] == 0) { 0298 $info['error'][] = 'Corrupt MIDI file: ticksperqnote == zero'; 0299 return false; 0300 } 0301 0302 $info['playtime_seconds'] += (($tickoffset - $previoustickoffset) / $thisfile_midi_raw['ticksperqnote']) * ($prevmicrosecondsperbeat / 1000000); 0303 0304 $prevmicrosecondsperbeat = $microsecondsperbeat; 0305 $previoustickoffset = $tickoffset; 0306 } 0307 } 0308 if ($thisfile_midi['totalticks'] > $previoustickoffset) { 0309 0310 if ($thisfile_midi_raw['ticksperqnote'] == 0) { 0311 $info['error'][] = 'Corrupt MIDI file: ticksperqnote == zero'; 0312 return false; 0313 } 0314 0315 $info['playtime_seconds'] += (($thisfile_midi['totalticks'] - $previoustickoffset) / $thisfile_midi_raw['ticksperqnote']) * ($microsecondsperbeat / 1000000); 0316 0317 } 0318 } 0319 0320 0321 if (!empty($info['playtime_seconds'])) { 0322 $info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds']; 0323 } 0324 0325 if (!empty($thisfile_midi['lyrics'])) { 0326 $thisfile_midi['comments']['lyrics'][] = $thisfile_midi['lyrics']; 0327 } 0328 0329 return true; 0330 } 0331 0332 public function GeneralMIDIinstrumentLookup($instrumentid) { 0333 0334 $begin = __LINE__; 0335 0336 /** This is not a comment! 0337 0338 0 Acoustic Grand 0339 1 Bright Acoustic 0340 2 Electric Grand 0341 3 Honky-Tonk 0342 4 Electric Piano 1 0343 5 Electric Piano 2 0344 6 Harpsichord 0345 7 Clavier 0346 8 Celesta 0347 9 Glockenspiel 0348 10 Music Box 0349 11 Vibraphone 0350 12 Marimba 0351 13 Xylophone 0352 14 Tubular Bells 0353 15 Dulcimer 0354 16 Drawbar Organ 0355 17 Percussive Organ 0356 18 Rock Organ 0357 19 Church Organ 0358 20 Reed Organ 0359 21 Accordian 0360 22 Harmonica 0361 23 Tango Accordian 0362 24 Acoustic Guitar (nylon) 0363 25 Acoustic Guitar (steel) 0364 26 Electric Guitar (jazz) 0365 27 Electric Guitar (clean) 0366 28 Electric Guitar (muted) 0367 29 Overdriven Guitar 0368 30 Distortion Guitar 0369 31 Guitar Harmonics 0370 32 Acoustic Bass 0371 33 Electric Bass (finger) 0372 34 Electric Bass (pick) 0373 35 Fretless Bass 0374 36 Slap Bass 1 0375 37 Slap Bass 2 0376 38 Synth Bass 1 0377 39 Synth Bass 2 0378 40 Violin 0379 41 Viola 0380 42 Cello 0381 43 Contrabass 0382 44 Tremolo Strings 0383 45 Pizzicato Strings 0384 46 Orchestral Strings 0385 47 Timpani 0386 48 String Ensemble 1 0387 49 String Ensemble 2 0388 50 SynthStrings 1 0389 51 SynthStrings 2 0390 52 Choir Aahs 0391 53 Voice Oohs 0392 54 Synth Voice 0393 55 Orchestra Hit 0394 56 Trumpet 0395 57 Trombone 0396 58 Tuba 0397 59 Muted Trumpet 0398 60 French Horn 0399 61 Brass Section 0400 62 SynthBrass 1 0401 63 SynthBrass 2 0402 64 Soprano Sax 0403 65 Alto Sax 0404 66 Tenor Sax 0405 67 Baritone Sax 0406 68 Oboe 0407 69 English Horn 0408 70 Bassoon 0409 71 Clarinet 0410 72 Piccolo 0411 73 Flute 0412 74 Recorder 0413 75 Pan Flute 0414 76 Blown Bottle 0415 77 Shakuhachi 0416 78 Whistle 0417 79 Ocarina 0418 80 Lead 1 (square) 0419 81 Lead 2 (sawtooth) 0420 82 Lead 3 (calliope) 0421 83 Lead 4 (chiff) 0422 84 Lead 5 (charang) 0423 85 Lead 6 (voice) 0424 86 Lead 7 (fifths) 0425 87 Lead 8 (bass + lead) 0426 88 Pad 1 (new age) 0427 89 Pad 2 (warm) 0428 90 Pad 3 (polysynth) 0429 91 Pad 4 (choir) 0430 92 Pad 5 (bowed) 0431 93 Pad 6 (metallic) 0432 94 Pad 7 (halo) 0433 95 Pad 8 (sweep) 0434 96 FX 1 (rain) 0435 97 FX 2 (soundtrack) 0436 98 FX 3 (crystal) 0437 99 FX 4 (atmosphere) 0438 100 FX 5 (brightness) 0439 101 FX 6 (goblins) 0440 102 FX 7 (echoes) 0441 103 FX 8 (sci-fi) 0442 104 Sitar 0443 105 Banjo 0444 106 Shamisen 0445 107 Koto 0446 108 Kalimba 0447 109 Bagpipe 0448 110 Fiddle 0449 111 Shanai 0450 112 Tinkle Bell 0451 113 Agogo 0452 114 Steel Drums 0453 115 Woodblock 0454 116 Taiko Drum 0455 117 Melodic Tom 0456 118 Synth Drum 0457 119 Reverse Cymbal 0458 120 Guitar Fret Noise 0459 121 Breath Noise 0460 122 Seashore 0461 123 Bird Tweet 0462 124 Telephone Ring 0463 125 Helicopter 0464 126 Applause 0465 127 Gunshot 0466 0467 */ 0468 0469 return getid3_lib::EmbeddedLookup($instrumentid, $begin, __LINE__, __FILE__, 'GeneralMIDIinstrument'); 0470 } 0471 0472 public function GeneralMIDIpercussionLookup($instrumentid) { 0473 0474 $begin = __LINE__; 0475 0476 /** This is not a comment! 0477 0478 35 Acoustic Bass Drum 0479 36 Bass Drum 1 0480 37 Side Stick 0481 38 Acoustic Snare 0482 39 Hand Clap 0483 40 Electric Snare 0484 41 Low Floor Tom 0485 42 Closed Hi-Hat 0486 43 High Floor Tom 0487 44 Pedal Hi-Hat 0488 45 Low Tom 0489 46 Open Hi-Hat 0490 47 Low-Mid Tom 0491 48 Hi-Mid Tom 0492 49 Crash Cymbal 1 0493 50 High Tom 0494 51 Ride Cymbal 1 0495 52 Chinese Cymbal 0496 53 Ride Bell 0497 54 Tambourine 0498 55 Splash Cymbal 0499 56 Cowbell 0500 57 Crash Cymbal 2 0501 59 Ride Cymbal 2 0502 60 Hi Bongo 0503 61 Low Bongo 0504 62 Mute Hi Conga 0505 63 Open Hi Conga 0506 64 Low Conga 0507 65 High Timbale 0508 66 Low Timbale 0509 67 High Agogo 0510 68 Low Agogo 0511 69 Cabasa 0512 70 Maracas 0513 71 Short Whistle 0514 72 Long Whistle 0515 73 Short Guiro 0516 74 Long Guiro 0517 75 Claves 0518 76 Hi Wood Block 0519 77 Low Wood Block 0520 78 Mute Cuica 0521 79 Open Cuica 0522 80 Mute Triangle 0523 81 Open Triangle 0524 0525 */ 0526 0527 return getid3_lib::EmbeddedLookup($instrumentid, $begin, __LINE__, __FILE__, 'GeneralMIDIpercussion'); 0528 } 0529 0530 }