diff options
author | Alib <aliboba@free.fr> | 2010-03-15 17:56:22 +0100 |
---|---|---|
committer | Alib <aliboba@free.fr> | 2010-03-15 17:56:22 +0100 |
commit | 438912c0c4a4075a5cd74cf9689451c9df4bbe34 (patch) | |
tree | 334e03bbba01b002a34d3cbf81ee7e600ec7bff6 /getid3/module.audio.midi.php | |
parent | a8012963c23e7e5eaf487ee9e192ae5c4d4ccff2 (diff) | |
download | istreamdev-438912c0c4a4075a5cd74cf9689451c9df4bbe34.tar.gz istreamdev-438912c0c4a4075a5cd74cf9689451c9df4bbe34.tar.bz2 |
New Jquery branch. Initial development version for istreamdev 1.0
Diffstat (limited to 'getid3/module.audio.midi.php')
-rw-r--r-- | getid3/module.audio.midi.php | 522 |
1 files changed, 0 insertions, 522 deletions
diff --git a/getid3/module.audio.midi.php b/getid3/module.audio.midi.php deleted file mode 100644 index 0fd7c9b..0000000 --- a/getid3/module.audio.midi.php +++ /dev/null @@ -1,522 +0,0 @@ -<?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'); - } - -} - - -?>
\ No newline at end of file |