522 lines
18 KiB
PHP
522 lines
18 KiB
PHP
|
<?php
|
||
|
/////////////////////////////////////////////////////////////////
|
||
|
/// getID3() by James Heinrich <info@getid3.org> //
|
||
|
// available at http://getid3.sourceforge.net //
|
||
|
// or http://www.getid3.org //
|
||
|
/////////////////////////////////////////////////////////////////
|
||
|
// See readme.txt for more details //
|
||
|
/////////////////////////////////////////////////////////////////
|
||
|
// //
|
||
|
// module.audio.midi.php //
|
||
|
// module for Midi Audio files //
|
||
|
// dependencies: NONE //
|
||
|
// ///
|
||
|
/////////////////////////////////////////////////////////////////
|
||
|
|
||
|
|
||
|
class getid3_midi
|
||
|
{
|
||
|
|
||
|
function getid3_midi(&$fd, &$ThisFileInfo, $scanwholefile=true) {
|
||
|
|
||
|
// shortcut
|
||
|
$ThisFileInfo['midi']['raw'] = array();
|
||
|
$thisfile_midi = &$ThisFileInfo['midi'];
|
||
|
$thisfile_midi_raw = &$thisfile_midi['raw'];
|
||
|
|
||
|
$ThisFileInfo['fileformat'] = 'midi';
|
||
|
$ThisFileInfo['audio']['dataformat'] = 'midi';
|
||
|
|
||
|
fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
|
||
|
$MIDIdata = fread($fd, GETID3_FREAD_BUFFER_SIZE);
|
||
|
$offset = 0;
|
||
|
$MIDIheaderID = substr($MIDIdata, $offset, 4); // 'MThd'
|
||
|
if ($MIDIheaderID != 'MThd') {
|
||
|
$ThisFileInfo['error'][] = 'Expecting "MThd" at offset '.$ThisFileInfo['avdataoffset'].', found "'.$MIDIheaderID.'"';
|
||
|
unset($ThisFileInfo['fileformat']);
|
||
|
return false;
|
||
|
}
|
||
|
$offset += 4;
|
||
|
$thisfile_midi_raw['headersize'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 4));
|
||
|
$offset += 4;
|
||
|
$thisfile_midi_raw['fileformat'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
|
||
|
$offset += 2;
|
||
|
$thisfile_midi_raw['tracks'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
|
||
|
$offset += 2;
|
||
|
$thisfile_midi_raw['ticksperqnote'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
|
||
|
$offset += 2;
|
||
|
|
||
|
for ($i = 0; $i < $thisfile_midi_raw['tracks']; $i++) {
|
||
|
if ((strlen($MIDIdata) - $offset) < 8) {
|
||
|
$MIDIdata .= fread($fd, GETID3_FREAD_BUFFER_SIZE);
|
||
|
}
|
||
|
$trackID = substr($MIDIdata, $offset, 4);
|
||
|
$offset += 4;
|
||
|
if ($trackID == 'MTrk') {
|
||
|
$tracksize = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 4));
|
||
|
$offset += 4;
|
||
|
// $thisfile_midi['tracks'][$i]['size'] = $tracksize;
|
||
|
$trackdataarray[$i] = substr($MIDIdata, $offset, $tracksize);
|
||
|
$offset += $tracksize;
|
||
|
} else {
|
||
|
$ThisFileInfo['error'][] = 'Expecting "MTrk" at '.$offset.', found '.$trackID.' instead';
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!isset($trackdataarray) || !is_array($trackdataarray)) {
|
||
|
$ThisFileInfo['error'][] = 'Cannot find MIDI track information';
|
||
|
unset($thisfile_midi);
|
||
|
unset($ThisFileInfo['fileformat']);
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
if ($scanwholefile) { // this can take quite a long time, so have the option to bypass it if speed is very important
|
||
|
$thisfile_midi['totalticks'] = 0;
|
||
|
$ThisFileInfo['playtime_seconds'] = 0;
|
||
|
$CurrentMicroSecondsPerBeat = 500000; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat
|
||
|
$CurrentBeatsPerMinute = 120; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat
|
||
|
$MicroSecondsPerQuarterNoteAfter = array ();
|
||
|
|
||
|
foreach ($trackdataarray as $tracknumber => $trackdata) {
|
||
|
|
||
|
$eventsoffset = 0;
|
||
|
$LastIssuedMIDIcommand = 0;
|
||
|
$LastIssuedMIDIchannel = 0;
|
||
|
$CumulativeDeltaTime = 0;
|
||
|
$TicksAtCurrentBPM = 0;
|
||
|
while ($eventsoffset < strlen($trackdata)) {
|
||
|
$eventid = 0;
|
||
|
if (isset($MIDIevents[$tracknumber]) && is_array($MIDIevents[$tracknumber])) {
|
||
|
$eventid = count($MIDIevents[$tracknumber]);
|
||
|
}
|
||
|
$deltatime = 0;
|
||
|
for ($i = 0; $i < 4; $i++) {
|
||
|
$deltatimebyte = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$deltatime = ($deltatime << 7) + ($deltatimebyte & 0x7F);
|
||
|
if ($deltatimebyte & 0x80) {
|
||
|
// another byte follows
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
$CumulativeDeltaTime += $deltatime;
|
||
|
$TicksAtCurrentBPM += $deltatime;
|
||
|
$MIDIevents[$tracknumber][$eventid]['deltatime'] = $deltatime;
|
||
|
$MIDI_event_channel = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
if ($MIDI_event_channel & 0x80) {
|
||
|
// OK, normal event - MIDI command has MSB set
|
||
|
$LastIssuedMIDIcommand = $MIDI_event_channel >> 4;
|
||
|
$LastIssuedMIDIchannel = $MIDI_event_channel & 0x0F;
|
||
|
} else {
|
||
|
// running event - assume last command
|
||
|
$eventsoffset--;
|
||
|
}
|
||
|
$MIDIevents[$tracknumber][$eventid]['eventid'] = $LastIssuedMIDIcommand;
|
||
|
$MIDIevents[$tracknumber][$eventid]['channel'] = $LastIssuedMIDIchannel;
|
||
|
if ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x08) { // Note off (key is released)
|
||
|
|
||
|
$notenumber = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$velocity = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
|
||
|
} elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x09) { // Note on (key is pressed)
|
||
|
|
||
|
$notenumber = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$velocity = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
|
||
|
} elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0A) { // Key after-touch
|
||
|
|
||
|
$notenumber = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$velocity = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
|
||
|
} elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0B) { // Control Change
|
||
|
|
||
|
$controllernum = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$newvalue = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
|
||
|
} elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0C) { // Program (patch) change
|
||
|
|
||
|
$newprogramnum = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
|
||
|
$thisfile_midi_raw['track'][$tracknumber]['instrumentid'] = $newprogramnum;
|
||
|
if ($tracknumber == 10) {
|
||
|
$thisfile_midi_raw['track'][$tracknumber]['instrument'] = $this->GeneralMIDIpercussionLookup($newprogramnum);
|
||
|
} else {
|
||
|
$thisfile_midi_raw['track'][$tracknumber]['instrument'] = $this->GeneralMIDIinstrumentLookup($newprogramnum);
|
||
|
}
|
||
|
|
||
|
} elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0D) { // Channel after-touch
|
||
|
|
||
|
$channelnumber = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
|
||
|
} elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0E) { // Pitch wheel change (2000H is normal or no change)
|
||
|
|
||
|
$changeLSB = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$changeMSB = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$pitchwheelchange = (($changeMSB & 0x7F) << 7) & ($changeLSB & 0x7F);
|
||
|
|
||
|
} elseif (($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0F) && ($MIDIevents[$tracknumber][$eventid]['channel'] == 0x0F)) {
|
||
|
|
||
|
$METAeventCommand = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$METAeventLength = ord(substr($trackdata, $eventsoffset++, 1));
|
||
|
$METAeventData = substr($trackdata, $eventsoffset, $METAeventLength);
|
||
|
$eventsoffset += $METAeventLength;
|
||
|
switch ($METAeventCommand) {
|
||
|
case 0x00: // Set track sequence number
|
||
|
$track_sequence_number = getid3_lib::BigEndian2Int(substr($METAeventData, 0, $METAeventLength));
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['seqno'] = $track_sequence_number;
|
||
|
break;
|
||
|
|
||
|
case 0x01: // Text: generic
|
||
|
$text_generic = substr($METAeventData, 0, $METAeventLength);
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['text'] = $text_generic;
|
||
|
$thisfile_midi['comments']['comment'][] = $text_generic;
|
||
|
break;
|
||
|
|
||
|
case 0x02: // Text: copyright
|
||
|
$text_copyright = substr($METAeventData, 0, $METAeventLength);
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['copyright'] = $text_copyright;
|
||
|
$thisfile_midi['comments']['copyright'][] = $text_copyright;
|
||
|
break;
|
||
|
|
||
|
case 0x03: // Text: track name
|
||
|
$text_trackname = substr($METAeventData, 0, $METAeventLength);
|
||
|
$thisfile_midi_raw['track'][$tracknumber]['name'] = $text_trackname;
|
||
|
break;
|
||
|
|
||
|
case 0x04: // Text: track instrument name
|
||
|
$text_instrument = substr($METAeventData, 0, $METAeventLength);
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['instrument'] = $text_instrument;
|
||
|
break;
|
||
|
|
||
|
case 0x05: // Text: lyrics
|
||
|
$text_lyrics = substr($METAeventData, 0, $METAeventLength);
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['lyrics'] = $text_lyrics;
|
||
|
if (!isset($thisfile_midi['lyrics'])) {
|
||
|
$thisfile_midi['lyrics'] = '';
|
||
|
}
|
||
|
$thisfile_midi['lyrics'] .= $text_lyrics."\n";
|
||
|
break;
|
||
|
|
||
|
case 0x06: // Text: marker
|
||
|
$text_marker = substr($METAeventData, 0, $METAeventLength);
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['marker'] = $text_marker;
|
||
|
break;
|
||
|
|
||
|
case 0x07: // Text: cue point
|
||
|
$text_cuepoint = substr($METAeventData, 0, $METAeventLength);
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['cuepoint'] = $text_cuepoint;
|
||
|
break;
|
||
|
|
||
|
case 0x2F: // End Of Track
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['EOT'] = $CumulativeDeltaTime;
|
||
|
break;
|
||
|
|
||
|
case 0x51: // Tempo: microseconds / quarter note
|
||
|
$CurrentMicroSecondsPerBeat = getid3_lib::BigEndian2Int(substr($METAeventData, 0, $METAeventLength));
|
||
|
if ($CurrentMicroSecondsPerBeat == 0) {
|
||
|
$ThisFileInfo['error'][] = 'Corrupt MIDI file: CurrentMicroSecondsPerBeat == zero';
|
||
|
return false;
|
||
|
}
|
||
|
$thisfile_midi_raw['events'][$tracknumber][$CumulativeDeltaTime]['us_qnote'] = $CurrentMicroSecondsPerBeat;
|
||
|
$CurrentBeatsPerMinute = (1000000 / $CurrentMicroSecondsPerBeat) * 60;
|
||
|
$MicroSecondsPerQuarterNoteAfter[$CumulativeDeltaTime] = $CurrentMicroSecondsPerBeat;
|
||
|
$TicksAtCurrentBPM = 0;
|
||
|
break;
|
||
|
|
||
|
case 0x58: // Time signature
|
||
|
$timesig_numerator = getid3_lib::BigEndian2Int($METAeventData{0});
|
||
|
$timesig_denominator = pow(2, getid3_lib::BigEndian2Int($METAeventData{1})); // $02 -> x/4, $03 -> x/8, etc
|
||
|
$timesig_32inqnote = getid3_lib::BigEndian2Int($METAeventData{2}); // number of 32nd notes to the quarter note
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_32inqnote'] = $timesig_32inqnote;
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_numerator'] = $timesig_numerator;
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_denominator'] = $timesig_denominator;
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_text'] = $timesig_numerator.'/'.$timesig_denominator;
|
||
|
$thisfile_midi['timesignature'][] = $timesig_numerator.'/'.$timesig_denominator;
|
||
|
break;
|
||
|
|
||
|
case 0x59: // Keysignature
|
||
|
$keysig_sharpsflats = getid3_lib::BigEndian2Int($METAeventData{0});
|
||
|
if ($keysig_sharpsflats & 0x80) {
|
||
|
// (-7 -> 7 flats, 0 ->key of C, 7 -> 7 sharps)
|
||
|
$keysig_sharpsflats -= 256;
|
||
|
}
|
||
|
|
||
|
$keysig_majorminor = getid3_lib::BigEndian2Int($METAeventData{1}); // 0 -> major, 1 -> minor
|
||
|
$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#');
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_sharps'] = (($keysig_sharpsflats > 0) ? abs($keysig_sharpsflats) : 0);
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_flats'] = (($keysig_sharpsflats < 0) ? abs($keysig_sharpsflats) : 0);
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_minor'] = (bool) $keysig_majorminor;
|
||
|
//$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_text'] = $keysigs[$keysig_sharpsflats].' '.($thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_minor'] ? 'minor' : 'major');
|
||
|
|
||
|
// $keysigs[$keysig_sharpsflats] gets an int key (correct) - $keysigs["$keysig_sharpsflats"] gets a string key (incorrect)
|
||
|
$thisfile_midi['keysignature'][] = $keysigs[$keysig_sharpsflats].' '.((bool) $keysig_majorminor ? 'minor' : 'major');
|
||
|
break;
|
||
|
|
||
|
case 0x7F: // Sequencer specific information
|
||
|
$custom_data = substr($METAeventData, 0, $METAeventLength);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
$ThisFileInfo['warning'][] = 'Unhandled META Event Command: '.$METAeventCommand;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} else {
|
||
|
|
||
|
$ThisFileInfo['warning'][] = 'Unhandled MIDI Event ID: '.$MIDIevents[$tracknumber][$eventid]['eventid'].' + Channel ID: '.$MIDIevents[$tracknumber][$eventid]['channel'];
|
||
|
|
||
|
}
|
||
|
}
|
||
|
if (($tracknumber > 0) || (count($trackdataarray) == 1)) {
|
||
|
$thisfile_midi['totalticks'] = max($thisfile_midi['totalticks'], $CumulativeDeltaTime);
|
||
|
}
|
||
|
}
|
||
|
$previoustickoffset = null;
|
||
|
|
||
|
ksort($MicroSecondsPerQuarterNoteAfter);
|
||
|
foreach ($MicroSecondsPerQuarterNoteAfter as $tickoffset => $microsecondsperbeat) {
|
||
|
if (is_null($previoustickoffset)) {
|
||
|
$prevmicrosecondsperbeat = $microsecondsperbeat;
|
||
|
$previoustickoffset = $tickoffset;
|
||
|
continue;
|
||
|
}
|
||
|
if ($thisfile_midi['totalticks'] > $tickoffset) {
|
||
|
|
||
|
if ($thisfile_midi_raw['ticksperqnote'] == 0) {
|
||
|
$ThisFileInfo['error'][] = 'Corrupt MIDI file: ticksperqnote == zero';
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$ThisFileInfo['playtime_seconds'] += (($tickoffset - $previoustickoffset) / $thisfile_midi_raw['ticksperqnote']) * ($prevmicrosecondsperbeat / 1000000);
|
||
|
|
||
|
$prevmicrosecondsperbeat = $microsecondsperbeat;
|
||
|
$previoustickoffset = $tickoffset;
|
||
|
}
|
||
|
}
|
||
|
if ($thisfile_midi['totalticks'] > $previoustickoffset) {
|
||
|
|
||
|
if ($thisfile_midi_raw['ticksperqnote'] == 0) {
|
||
|
$ThisFileInfo['error'][] = 'Corrupt MIDI file: ticksperqnote == zero';
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
$ThisFileInfo['playtime_seconds'] += (($thisfile_midi['totalticks'] - $previoustickoffset) / $thisfile_midi_raw['ticksperqnote']) * ($microsecondsperbeat / 1000000);
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if (@$ThisFileInfo['playtime_seconds'] > 0) {
|
||
|
$ThisFileInfo['bitrate'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds'];
|
||
|
}
|
||
|
|
||
|
if (!empty($thisfile_midi['lyrics'])) {
|
||
|
$thisfile_midi['comments']['lyrics'][] = $thisfile_midi['lyrics'];
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
function GeneralMIDIinstrumentLookup($instrumentid) {
|
||
|
|
||
|
$begin = __LINE__;
|
||
|
|
||
|
/** This is not a comment!
|
||
|
|
||
|
0 Acoustic Grand
|
||
|
1 Bright Acoustic
|
||
|
2 Electric Grand
|
||
|
3 Honky-Tonk
|
||
|
4 Electric Piano 1
|
||
|
5 Electric Piano 2
|
||
|
6 Harpsichord
|
||
|
7 Clavier
|
||
|
8 Celesta
|
||
|
9 Glockenspiel
|
||
|
10 Music Box
|
||
|
11 Vibraphone
|
||
|
12 Marimba
|
||
|
13 Xylophone
|
||
|
14 Tubular Bells
|
||
|
15 Dulcimer
|
||
|
16 Drawbar Organ
|
||
|
17 Percussive Organ
|
||
|
18 Rock Organ
|
||
|
19 Church Organ
|
||
|
20 Reed Organ
|
||
|
21 Accordian
|
||
|
22 Harmonica
|
||
|
23 Tango Accordian
|
||
|
24 Acoustic Guitar (nylon)
|
||
|
25 Acoustic Guitar (steel)
|
||
|
26 Electric Guitar (jazz)
|
||
|
27 Electric Guitar (clean)
|
||
|
28 Electric Guitar (muted)
|
||
|
29 Overdriven Guitar
|
||
|
30 Distortion Guitar
|
||
|
31 Guitar Harmonics
|
||
|
32 Acoustic Bass
|
||
|
33 Electric Bass (finger)
|
||
|
34 Electric Bass (pick)
|
||
|
35 Fretless Bass
|
||
|
36 Slap Bass 1
|
||
|
37 Slap Bass 2
|
||
|
38 Synth Bass 1
|
||
|
39 Synth Bass 2
|
||
|
40 Violin
|
||
|
41 Viola
|
||
|
42 Cello
|
||
|
43 Contrabass
|
||
|
44 Tremolo Strings
|
||
|
45 Pizzicato Strings
|
||
|
46 Orchestral Strings
|
||
|
47 Timpani
|
||
|
48 String Ensemble 1
|
||
|
49 String Ensemble 2
|
||
|
50 SynthStrings 1
|
||
|
51 SynthStrings 2
|
||
|
52 Choir Aahs
|
||
|
53 Voice Oohs
|
||
|
54 Synth Voice
|
||
|
55 Orchestra Hit
|
||
|
56 Trumpet
|
||
|
57 Trombone
|
||
|
58 Tuba
|
||
|
59 Muted Trumpet
|
||
|
60 French Horn
|
||
|
61 Brass Section
|
||
|
62 SynthBrass 1
|
||
|
63 SynthBrass 2
|
||
|
64 Soprano Sax
|
||
|
65 Alto Sax
|
||
|
66 Tenor Sax
|
||
|
67 Baritone Sax
|
||
|
68 Oboe
|
||
|
69 English Horn
|
||
|
70 Bassoon
|
||
|
71 Clarinet
|
||
|
72 Piccolo
|
||
|
73 Flute
|
||
|
74 Recorder
|
||
|
75 Pan Flute
|
||
|
76 Blown Bottle
|
||
|
77 Shakuhachi
|
||
|
78 Whistle
|
||
|
79 Ocarina
|
||
|
80 Lead 1 (square)
|
||
|
81 Lead 2 (sawtooth)
|
||
|
82 Lead 3 (calliope)
|
||
|
83 Lead 4 (chiff)
|
||
|
84 Lead 5 (charang)
|
||
|
85 Lead 6 (voice)
|
||
|
86 Lead 7 (fifths)
|
||
|
87 Lead 8 (bass + lead)
|
||
|
88 Pad 1 (new age)
|
||
|
89 Pad 2 (warm)
|
||
|
90 Pad 3 (polysynth)
|
||
|
91 Pad 4 (choir)
|
||
|
92 Pad 5 (bowed)
|
||
|
93 Pad 6 (metallic)
|
||
|
94 Pad 7 (halo)
|
||
|
95 Pad 8 (sweep)
|
||
|
96 FX 1 (rain)
|
||
|
97 FX 2 (soundtrack)
|
||
|
98 FX 3 (crystal)
|
||
|
99 FX 4 (atmosphere)
|
||
|
100 FX 5 (brightness)
|
||
|
101 FX 6 (goblins)
|
||
|
102 FX 7 (echoes)
|
||
|
103 FX 8 (sci-fi)
|
||
|
104 Sitar
|
||
|
105 Banjo
|
||
|
106 Shamisen
|
||
|
107 Koto
|
||
|
108 Kalimba
|
||
|
109 Bagpipe
|
||
|
110 Fiddle
|
||
|
111 Shanai
|
||
|
112 Tinkle Bell
|
||
|
113 Agogo
|
||
|
114 Steel Drums
|
||
|
115 Woodblock
|
||
|
116 Taiko Drum
|
||
|
117 Melodic Tom
|
||
|
118 Synth Drum
|
||
|
119 Reverse Cymbal
|
||
|
120 Guitar Fret Noise
|
||
|
121 Breath Noise
|
||
|
122 Seashore
|
||
|
123 Bird Tweet
|
||
|
124 Telephone Ring
|
||
|
125 Helicopter
|
||
|
126 Applause
|
||
|
127 Gunshot
|
||
|
|
||
|
*/
|
||
|
|
||
|
return getid3_lib::EmbeddedLookup($instrumentid, $begin, __LINE__, __FILE__, 'GeneralMIDIinstrument');
|
||
|
}
|
||
|
|
||
|
function GeneralMIDIpercussionLookup($instrumentid) {
|
||
|
|
||
|
$begin = __LINE__;
|
||
|
|
||
|
/** This is not a comment!
|
||
|
|
||
|
35 Acoustic Bass Drum
|
||
|
36 Bass Drum 1
|
||
|
37 Side Stick
|
||
|
38 Acoustic Snare
|
||
|
39 Hand Clap
|
||
|
40 Electric Snare
|
||
|
41 Low Floor Tom
|
||
|
42 Closed Hi-Hat
|
||
|
43 High Floor Tom
|
||
|
44 Pedal Hi-Hat
|
||
|
45 Low Tom
|
||
|
46 Open Hi-Hat
|
||
|
47 Low-Mid Tom
|
||
|
48 Hi-Mid Tom
|
||
|
49 Crash Cymbal 1
|
||
|
50 High Tom
|
||
|
51 Ride Cymbal 1
|
||
|
52 Chinese Cymbal
|
||
|
53 Ride Bell
|
||
|
54 Tambourine
|
||
|
55 Splash Cymbal
|
||
|
56 Cowbell
|
||
|
57 Crash Cymbal 2
|
||
|
59 Ride Cymbal 2
|
||
|
60 Hi Bongo
|
||
|
61 Low Bongo
|
||
|
62 Mute Hi Conga
|
||
|
63 Open Hi Conga
|
||
|
64 Low Conga
|
||
|
65 High Timbale
|
||
|
66 Low Timbale
|
||
|
67 High Agogo
|
||
|
68 Low Agogo
|
||
|
69 Cabasa
|
||
|
70 Maracas
|
||
|
71 Short Whistle
|
||
|
72 Long Whistle
|
||
|
73 Short Guiro
|
||
|
74 Long Guiro
|
||
|
75 Claves
|
||
|
76 Hi Wood Block
|
||
|
77 Low Wood Block
|
||
|
78 Mute Cuica
|
||
|
79 Open Cuica
|
||
|
80 Mute Triangle
|
||
|
81 Open Triangle
|
||
|
|
||
|
*/
|
||
|
|
||
|
return getid3_lib::EmbeddedLookup($instrumentid, $begin, __LINE__, __FILE__, 'GeneralMIDIpercussion');
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
?>
|