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 }