diff e2gallerypro/e2upload/Backend/Assets/getid3/module.audio.midi.php @ 3:3f6b44aa6b35 judyates

[svn r4] added ability to buy stuff, from a Prints page, but it doesn't work well with the css, and it also has not been fitted into the perl make system.
author rlm
date Mon, 22 Feb 2010 08:02:39 -0500
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/e2gallerypro/e2upload/Backend/Assets/getid3/module.audio.midi.php	Mon Feb 22 08:02:39 2010 -0500
     1.3 @@ -0,0 +1,552 @@
     1.4 +<?php
     1.5 +// +----------------------------------------------------------------------+
     1.6 +// | PHP version 5                                                        |
     1.7 +// +----------------------------------------------------------------------+
     1.8 +// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen                 |
     1.9 +// +----------------------------------------------------------------------+
    1.10 +// | This source file is subject to version 2 of the GPL license,         |
    1.11 +// | that is bundled with this package in the file license.txt and is     |
    1.12 +// | available through the world-wide-web at the following url:           |
    1.13 +// | http://www.gnu.org/copyleft/gpl.html                                 |
    1.14 +// +----------------------------------------------------------------------+
    1.15 +// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org    |
    1.16 +// +----------------------------------------------------------------------+
    1.17 +// | Authors: James Heinrich <infoØgetid3*org>                            |
    1.18 +// |          Allan Hansen <ahØartemis*dk>                                |
    1.19 +// +----------------------------------------------------------------------+
    1.20 +// | module.audio.midi.php                                                |
    1.21 +// | Module for analyzing midi audio files                                |
    1.22 +// | dependencies: NONE                                                   |
    1.23 +// +----------------------------------------------------------------------+
    1.24 +//
    1.25 +// $Id: module.audio.midi.php,v 1.5 2006/11/02 10:48:01 ah Exp $
    1.26 +
    1.27 +        
    1.28 +        
    1.29 +class getid3_midi extends getid3_handler
    1.30 +{
    1.31 +
    1.32 +    public function Analyze() {
    1.33 +
    1.34 +        $getid3 = $this->getid3;
    1.35 +        
    1.36 +        $getid3->info['midi']['raw'] = array ();
    1.37 +        $info_midi     = &$getid3->info['midi'];
    1.38 +        $info_midi_raw = &$info_midi['raw'];
    1.39 +
    1.40 +        $getid3->info['fileformat']          = 'midi';
    1.41 +        $getid3->info['audio']['dataformat'] = 'midi';
    1.42 +
    1.43 +        fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
    1.44 +        $midi_data = fread($getid3->fp, getid3::FREAD_BUFFER_SIZE);
    1.45 +                
    1.46 +        // Magic bytes: 'MThd'
    1.47 +        
    1.48 +        getid3_lib::ReadSequence('BigEndian2Int', $info_midi_raw, $midi_data, 4, 
    1.49 +            array (
    1.50 +                'headersize'    => 4,
    1.51 +                'fileformat'    => 2,
    1.52 +                'tracks'        => 2,
    1.53 +                'ticksperqnote' => 2
    1.54 +            )
    1.55 +        );
    1.56 +        
    1.57 +        $offset = 14;
    1.58 +
    1.59 +        for ($i = 0; $i < $info_midi_raw['tracks']; $i++) {
    1.60 +            
    1.61 +            if ((strlen($midi_data) - $offset) < 8) {
    1.62 +                $midi_data .= fread($getid3->fp, getid3::FREAD_BUFFER_SIZE);
    1.63 +            }
    1.64 +            
    1.65 +            $track_id = substr($midi_data, $offset, 4);
    1.66 +            $offset += 4;
    1.67 +            
    1.68 +            if ($track_id != 'MTrk') {
    1.69 +                throw new getid3_exception('Expecting "MTrk" at '.$offset.', found '.$track_id.' instead');
    1.70 +            }
    1.71 +            
    1.72 +            $track_size = getid3_lib::BigEndian2Int(substr($midi_data, $offset, 4));
    1.73 +            $offset += 4;
    1.74 +                
    1.75 +            $track_data_array[$i] = substr($midi_data, $offset, $track_size);
    1.76 +            $offset += $track_size;
    1.77 +        }
    1.78 +
    1.79 +        if (!isset($track_data_array) || !is_array($track_data_array)) {
    1.80 +            throw new getid3_exception('Cannot find MIDI track information');
    1.81 +        }
    1.82 +
    1.83 +        
    1.84 +        $info_midi['totalticks']          = 0;
    1.85 +        $getid3->info['playtime_seconds'] = 0;
    1.86 +        $current_ms_per_beat              = 500000; // 120 beats per minute;  60,000,000 microseconds per minute -> 500,000 microseconds per beat
    1.87 +        $current_beats_per_min            = 120;    // 120 beats per minute;  60,000,000 microseconds per minute -> 500,000 microseconds per beat
    1.88 +        $ms_per_quarter_note_after        = array ();
    1.89 +
    1.90 +        foreach ($track_data_array as $track_number => $track_data) {
    1.91 +
    1.92 +            $events_offset = $last_issued_midi_command = $last_issued_midi_channel = $cumulative_delta_time = $ticks_at_current_bpm = 0;
    1.93 +            
    1.94 +            while ($events_offset < strlen($track_data)) {
    1.95 +                
    1.96 +                $event_id = 0;
    1.97 +                if (isset($midi_events[$track_number]) && is_array($midi_events[$track_number])) {
    1.98 +                    $event_id = count($midi_events[$track_number]);
    1.99 +                }
   1.100 +                $delta_time = 0;
   1.101 +                for ($i = 0; $i < 4; $i++) {
   1.102 +                    $delta_time_byte = ord($track_data{$events_offset++});
   1.103 +                    $delta_time = ($delta_time << 7) + ($delta_time_byte & 0x7F);
   1.104 +                    if ($delta_time_byte & 0x80) {
   1.105 +                        // another byte follows
   1.106 +                    } else {
   1.107 +                        break;
   1.108 +                    }
   1.109 +                }
   1.110 +                
   1.111 +                $cumulative_delta_time += $delta_time;
   1.112 +                $ticks_at_current_bpm  += $delta_time;
   1.113 +                
   1.114 +                $midi_events[$track_number][$event_id]['deltatime'] = $delta_time;
   1.115 +                
   1.116 +                $midi_event_channel                                 = ord($track_data{$events_offset++});
   1.117 +                
   1.118 +                // OK, normal event - MIDI command has MSB set
   1.119 +                if ($midi_event_channel & 0x80) {
   1.120 +                    $last_issued_midi_command = $midi_event_channel >> 4;
   1.121 +                    $last_issued_midi_channel = $midi_event_channel & 0x0F;
   1.122 +                } 
   1.123 +                
   1.124 +                // Running event - assume last command
   1.125 +                else {
   1.126 +                    $events_offset--;
   1.127 +                }
   1.128 +                
   1.129 +                $midi_events[$track_number][$event_id]['eventid'] = $last_issued_midi_command;
   1.130 +                $midi_events[$track_number][$event_id]['channel'] = $last_issued_midi_channel;
   1.131 +                
   1.132 +                switch ($midi_events[$track_number][$event_id]['eventid']) {
   1.133 +                    
   1.134 +                    case 0x8:       // Note off (key is released)
   1.135 +                    case 0x9:       // Note on (key is pressed)
   1.136 +                    case 0xA:       // Key after-touch
   1.137 +
   1.138 +                        //$notenumber = ord($track_data{$events_offset++});
   1.139 +                        //$velocity   = ord($track_data{$events_offset++});
   1.140 +                        $events_offset += 2;
   1.141 +                        break;
   1.142 +                        
   1.143 +                        
   1.144 +                    case 0xB:       // Control Change
   1.145 +                        
   1.146 +                        //$controllernum = ord($track_data{$events_offset++});
   1.147 +                        //$newvalue      = ord($track_data{$events_offset++});
   1.148 +                        $events_offset += 2;
   1.149 +                        break;
   1.150 +                        
   1.151 +                        
   1.152 +                    case 0xC:       // Program (patch) change
   1.153 +                    
   1.154 +                        $new_program_num = ord($track_data{$events_offset++});
   1.155 +
   1.156 +                        $info_midi_raw['track'][$track_number]['instrumentid'] = $new_program_num;
   1.157 +                        $info_midi_raw['track'][$track_number]['instrument']   = $track_number == 10 ? getid3_midi::GeneralMIDIpercussionLookup($new_program_num) : getid3_midi::GeneralMIDIinstrumentLookup($new_program_num);
   1.158 +                        break;
   1.159 +                        
   1.160 +                    
   1.161 +                    case 0xD:       // Channel after-touch
   1.162 +                        
   1.163 +                        //$channelnumber = ord($track_data{$events_offset++});
   1.164 +                        break;
   1.165 +                        
   1.166 +                        
   1.167 +                    case 0xE:       // Pitch wheel change (2000H is normal or no change)
   1.168 +
   1.169 +                        //$changeLSB = ord($track_data{$events_offset++});
   1.170 +                        //$changeMSB = ord($track_data{$events_offset++});
   1.171 +                        //$pitchwheelchange = (($changeMSB & 0x7F) << 7) & ($changeLSB & 0x7F);
   1.172 +                        $events_offset += 2;
   1.173 +                        break;
   1.174 +                        
   1.175 +    
   1.176 +                    case 0xF:
   1.177 +
   1.178 +                        if ($midi_events[$track_number][$event_id]['channel'] == 0xF) {
   1.179 +    
   1.180 +                            $meta_event_command = ord($track_data{$events_offset++});
   1.181 +                            $meta_event_length  = ord($track_data{$events_offset++});
   1.182 +                            $meta_event_data    = substr($track_data, $events_offset, $meta_event_length);
   1.183 +                            $events_offset += $meta_event_length;
   1.184 +                            
   1.185 +                            switch ($meta_event_command) {
   1.186 +                            
   1.187 +                                case 0x00: // Set track sequence number
   1.188 +    
   1.189 +                                    //$track_sequence_number = getid3_lib::BigEndian2Int(substr($meta_event_data, 0, $meta_event_length));
   1.190 +                                    //$info_midi_raw['events'][$track_number][$event_id]['seqno'] = $track_sequence_number;
   1.191 +                                    break;
   1.192 +    
   1.193 +    
   1.194 +                                case 0x01: // Text: generic
   1.195 +                                
   1.196 +                                    $text_generic = substr($meta_event_data, 0, $meta_event_length);
   1.197 +                                    //$info_midi_raw['events'][$track_number][$event_id]['text'] = $text_generic;
   1.198 +                                    $info_midi['comments']['comment'][] = $text_generic;
   1.199 +                                    break;
   1.200 +    
   1.201 +    
   1.202 +                                case 0x02: // Text: copyright
   1.203 +    
   1.204 +                                    $text_copyright = substr($meta_event_data, 0, $meta_event_length);
   1.205 +                                    //$info_midi_raw['events'][$track_number][$event_id]['copyright'] = $text_copyright;
   1.206 +                                    $info_midi['comments']['copyright'][] = $text_copyright;
   1.207 +                                    break;
   1.208 +    
   1.209 +    
   1.210 +                                case 0x03: // Text: track name
   1.211 +                                
   1.212 +                                    $text_trackname = substr($meta_event_data, 0, $meta_event_length);
   1.213 +                                    $info_midi_raw['track'][$track_number]['name'] = $text_trackname;
   1.214 +                                    break;
   1.215 +                                    
   1.216 +    
   1.217 +                                case 0x04: // Text: track instrument name
   1.218 +    
   1.219 +                                    //$text_instrument = substr($meta_event_data, 0, $meta_event_length);
   1.220 +                                    //$info_midi_raw['events'][$track_number][$event_id]['instrument'] = $text_instrument;
   1.221 +                                    break;
   1.222 +    
   1.223 +    
   1.224 +                                case 0x05: // Text: lyrics
   1.225 +    
   1.226 +                                    $text_lyrics = substr($meta_event_data, 0, $meta_event_length);
   1.227 +                                    //$info_midi_raw['events'][$track_number][$event_id]['lyrics'] = $text_lyrics;
   1.228 +                                    if (!isset($info_midi['lyrics'])) {
   1.229 +                                        $info_midi['lyrics'] = '';
   1.230 +                                    }
   1.231 +                                    $info_midi['lyrics'] .= $text_lyrics . "\n";
   1.232 +                                    break;
   1.233 +    
   1.234 +    
   1.235 +                                case 0x06: // Text: marker
   1.236 +    
   1.237 +                                    //$text_marker = substr($meta_event_data, 0, $meta_event_length);
   1.238 +                                    //$info_midi_raw['events'][$track_number][$event_id]['marker'] = $text_marker;
   1.239 +                                    break;
   1.240 +    
   1.241 +    
   1.242 +                                case 0x07: // Text: cue point
   1.243 +
   1.244 +                                    //$text_cuepoint = substr($meta_event_data, 0, $meta_event_length);
   1.245 +                                    //$info_midi_raw['events'][$track_number][$event_id]['cuepoint'] = $text_cuepoint;
   1.246 +                                    break;
   1.247 +
   1.248 +    
   1.249 +                                case 0x2F: // End Of Track
   1.250 +                                    
   1.251 +                                    //$info_midi_raw['events'][$track_number][$event_id]['EOT'] = $cumulative_delta_time;
   1.252 +                                    break;
   1.253 +    
   1.254 +    
   1.255 +                                case 0x51: // Tempo: microseconds / quarter note
   1.256 +    
   1.257 +                                    $current_ms_per_beat = getid3_lib::BigEndian2Int(substr($meta_event_data, 0, $meta_event_length));
   1.258 +                                    $info_midi_raw['events'][$track_number][$cumulative_delta_time]['us_qnote'] = $current_ms_per_beat;
   1.259 +                                    $current_beats_per_min = (1000000 / $current_ms_per_beat) * 60;
   1.260 +                                    $ms_per_quarter_note_after[$cumulative_delta_time] = $current_ms_per_beat;
   1.261 +                                    $ticks_at_current_bpm = 0;
   1.262 +                                    break;
   1.263 +    
   1.264 +    
   1.265 +                                case 0x58: // Time signature
   1.266 +                                    $timesig_numerator   = getid3_lib::BigEndian2Int($meta_event_data[0]);
   1.267 +                                    $timesig_denominator = pow(2, getid3_lib::BigEndian2Int($meta_event_data[1])); // $02 -> x/4, $03 -> x/8, etc
   1.268 +                                    //$timesig_32inqnote   = getid3_lib::BigEndian2Int($meta_event_data[2]);         // number of 32nd notes to the quarter note
   1.269 +                                    //$info_midi_raw['events'][$track_number][$event_id]['timesig_32inqnote']   = $timesig_32inqnote;
   1.270 +                                    //$info_midi_raw['events'][$track_number][$event_id]['timesig_numerator']   = $timesig_numerator;
   1.271 +                                    //$info_midi_raw['events'][$track_number][$event_id]['timesig_denominator'] = $timesig_denominator;
   1.272 +                                    //$info_midi_raw['events'][$track_number][$event_id]['timesig_text']        = $timesig_numerator.'/'.$timesig_denominator;
   1.273 +                                    $info_midi['timesignature'][] = $timesig_numerator.'/'.$timesig_denominator;
   1.274 +                                    break;
   1.275 +    
   1.276 +    
   1.277 +                                case 0x59: // Keysignature
   1.278 +                                    
   1.279 +                                    $keysig_sharpsflats = getid3_lib::BigEndian2Int($meta_event_data{0});
   1.280 +                                    if ($keysig_sharpsflats & 0x80) {
   1.281 +                                        // (-7 -> 7 flats, 0 ->key of C, 7 -> 7 sharps)
   1.282 +                                        $keysig_sharpsflats -= 256;
   1.283 +                                    }
   1.284 +    
   1.285 +                                    $keysig_majorminor  = getid3_lib::BigEndian2Int($meta_event_data{1}); // 0 -> major, 1 -> minor
   1.286 +                                    $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#');
   1.287 +                                    //$info_midi_raw['events'][$track_number][$event_id]['keysig_sharps'] = (($keysig_sharpsflats > 0) ? abs($keysig_sharpsflats) : 0);
   1.288 +                                    //$info_midi_raw['events'][$track_number][$event_id]['keysig_flats']  = (($keysig_sharpsflats < 0) ? abs($keysig_sharpsflats) : 0);
   1.289 +                                    //$info_midi_raw['events'][$track_number][$event_id]['keysig_minor']  = (bool)$keysig_majorminor;
   1.290 +                                    //$info_midi_raw['events'][$track_number][$event_id]['keysig_text']   = $keysigs[$keysig_sharpsflats].' '.($info_midi_raw['events'][$track_number][$event_id]['keysig_minor'] ? 'minor' : 'major');
   1.291 +    
   1.292 +                                    // $keysigs[$keysig_sharpsflats] gets an int key (correct) - $keysigs["$keysig_sharpsflats"] gets a string key (incorrect)
   1.293 +                                    $info_midi['keysignature'][] = $keysigs[$keysig_sharpsflats].' '.((bool)$keysig_majorminor ? 'minor' : 'major');
   1.294 +                                    break;
   1.295 +    
   1.296 +    
   1.297 +                                case 0x7F: // Sequencer specific information
   1.298 +    
   1.299 +                                    $custom_data = substr($meta_event_data, 0, $meta_event_length);
   1.300 +                                    break;
   1.301 +    
   1.302 +    
   1.303 +                                default:
   1.304 +    
   1.305 +                                    $getid3->warning('Unhandled META Event Command: '.$meta_event_command);
   1.306 +                            }
   1.307 +                        }
   1.308 +                        break;
   1.309 +                            
   1.310 +                            
   1.311 +                    default:                                
   1.312 +                        $getid3->warning('Unhandled MIDI Event ID: '.$midi_events[$track_number][$event_id]['eventid']);
   1.313 +                }
   1.314 +            }
   1.315 +            
   1.316 +            if (($track_number > 0) || (count($track_data_array) == 1)) {
   1.317 +                $info_midi['totalticks'] = max($info_midi['totalticks'], $cumulative_delta_time);
   1.318 +            }
   1.319 +        }
   1.320 +        
   1.321 +        $previous_tick_offset = null;
   1.322 +
   1.323 +        ksort($ms_per_quarter_note_after); 
   1.324 +        foreach ($ms_per_quarter_note_after as $tick_offset => $ms_per_beat) {
   1.325 +        
   1.326 +            if (is_null($previous_tick_offset)) {
   1.327 +                $prev_ms_per_beat     = $ms_per_beat;
   1.328 +                $previous_tick_offset = $tick_offset;
   1.329 +                continue;
   1.330 +            }
   1.331 +            
   1.332 +            if ($info_midi['totalticks'] > $tick_offset) {
   1.333 +                $getid3->info['playtime_seconds'] += (($tick_offset - $previous_tick_offset) / $info_midi_raw['ticksperqnote']) * ($prev_ms_per_beat / 1000000);
   1.334 +
   1.335 +                $prev_ms_per_beat     = $ms_per_beat;
   1.336 +                $previous_tick_offset = $tick_offset;
   1.337 +            }
   1.338 +        }
   1.339 +        
   1.340 +        if ($info_midi['totalticks'] > $previous_tick_offset) {
   1.341 +            $getid3->info['playtime_seconds'] += (($info_midi['totalticks'] - $previous_tick_offset) / $info_midi_raw['ticksperqnote']) * ($ms_per_beat / 1000000);
   1.342 +        }
   1.343 +
   1.344 +        if (@$getid3->info['playtime_seconds'] > 0) {
   1.345 +            $getid3->info['bitrate'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / $getid3->info['playtime_seconds'];
   1.346 +        }
   1.347 +
   1.348 +        if (!empty($info_midi['lyrics'])) {
   1.349 +            $info_midi['comments']['lyrics'][] = $info_midi['lyrics'];
   1.350 +        }
   1.351 +
   1.352 +        return true;
   1.353 +    }
   1.354 +
   1.355 +
   1.356 +         
   1.357 +    public static function GeneralMIDIinstrumentLookup($instrument_id) {
   1.358 +
   1.359 +        static $lookup = array (
   1.360 +        
   1.361 +              0 => 'Acoustic Grand',
   1.362 +              1 => 'Bright Acoustic',
   1.363 +              2 => 'Electric Grand',
   1.364 +              3 => 'Honky-Tonk',
   1.365 +              4 => 'Electric Piano 1',
   1.366 +              5 => 'Electric Piano 2',
   1.367 +              6 => 'Harpsichord',
   1.368 +              7 => 'Clavier',
   1.369 +              8 => 'Celesta',
   1.370 +              9 => 'Glockenspiel',
   1.371 +             10 => 'Music Box',
   1.372 +             11 => 'Vibraphone',
   1.373 +             12 => 'Marimba',
   1.374 +             13 => 'Xylophone',
   1.375 +             14 => 'Tubular Bells',
   1.376 +             15 => 'Dulcimer',
   1.377 +             16 => 'Drawbar Organ',
   1.378 +             17 => 'Percussive Organ',
   1.379 +             18 => 'Rock Organ',
   1.380 +             19 => 'Church Organ',
   1.381 +             20 => 'Reed Organ',
   1.382 +             21 => 'Accordian',
   1.383 +             22 => 'Harmonica',
   1.384 +             23 => 'Tango Accordian',
   1.385 +             24 => 'Acoustic Guitar (nylon)',
   1.386 +             25 => 'Acoustic Guitar (steel)',
   1.387 +             26 => 'Electric Guitar (jazz)',
   1.388 +             27 => 'Electric Guitar (clean)',
   1.389 +             28 => 'Electric Guitar (muted)',
   1.390 +             29 => 'Overdriven Guitar',
   1.391 +             30 => 'Distortion Guitar',
   1.392 +             31 => 'Guitar Harmonics',
   1.393 +             32 => 'Acoustic Bass',
   1.394 +             33 => 'Electric Bass (finger)',
   1.395 +             34 => 'Electric Bass (pick)',
   1.396 +             35 => 'Fretless Bass',
   1.397 +             36 => 'Slap Bass 1',
   1.398 +             37 => 'Slap Bass 2',
   1.399 +             38 => 'Synth Bass 1',
   1.400 +             39 => 'Synth Bass 2',
   1.401 +             40 => 'Violin',
   1.402 +             41 => 'Viola',
   1.403 +             42 => 'Cello',
   1.404 +             43 => 'Contrabass',
   1.405 +             44 => 'Tremolo Strings',
   1.406 +             45 => 'Pizzicato Strings',
   1.407 +             46 => 'Orchestral Strings',
   1.408 +             47 => 'Timpani',
   1.409 +             48 => 'String Ensemble 1',
   1.410 +             49 => 'String Ensemble 2',
   1.411 +             50 => 'SynthStrings 1',
   1.412 +             51 => 'SynthStrings 2',
   1.413 +             52 => 'Choir Aahs',
   1.414 +             53 => 'Voice Oohs',
   1.415 +             54 => 'Synth Voice',
   1.416 +             55 => 'Orchestra Hit',
   1.417 +             56 => 'Trumpet',
   1.418 +             57 => 'Trombone',
   1.419 +             58 => 'Tuba',
   1.420 +             59 => 'Muted Trumpet',
   1.421 +             60 => 'French Horn',
   1.422 +             61 => 'Brass Section',
   1.423 +             62 => 'SynthBrass 1',
   1.424 +             63 => 'SynthBrass 2',
   1.425 +             64 => 'Soprano Sax',
   1.426 +             65 => 'Alto Sax',
   1.427 +             66 => 'Tenor Sax',
   1.428 +             67 => 'Baritone Sax',
   1.429 +             68 => 'Oboe',
   1.430 +             69 => 'English Horn',
   1.431 +             70 => 'Bassoon',
   1.432 +             71 => 'Clarinet',
   1.433 +             72 => 'Piccolo',
   1.434 +             73 => 'Flute',
   1.435 +             74 => 'Recorder',
   1.436 +             75 => 'Pan Flute',
   1.437 +             76 => 'Blown Bottle',
   1.438 +             77 => 'Shakuhachi',
   1.439 +             78 => 'Whistle',
   1.440 +             79 => 'Ocarina',
   1.441 +             80 => 'Lead 1 (square)',
   1.442 +             81 => 'Lead 2 (sawtooth)',
   1.443 +             82 => 'Lead 3 (calliope)',
   1.444 +             83 => 'Lead 4 (chiff)',
   1.445 +             84 => 'Lead 5 (charang)',
   1.446 +             85 => 'Lead 6 (voice)',
   1.447 +             86 => 'Lead 7 (fifths)',
   1.448 +             87 => 'Lead 8 (bass + lead)',
   1.449 +             88 => 'Pad 1 (new age)',
   1.450 +             89 => 'Pad 2 (warm)',
   1.451 +             90 => 'Pad 3 (polysynth)',
   1.452 +             91 => 'Pad 4 (choir)',
   1.453 +             92 => 'Pad 5 (bowed)',
   1.454 +             93 => 'Pad 6 (metallic)',
   1.455 +             94 => 'Pad 7 (halo)',
   1.456 +             95 => 'Pad 8 (sweep)',
   1.457 +             96 => 'FX 1 (rain)',
   1.458 +             97 => 'FX 2 (soundtrack)',
   1.459 +             98 => 'FX 3 (crystal)',
   1.460 +             99 => 'FX 4 (atmosphere)',
   1.461 +            100 => 'FX 5 (brightness)',
   1.462 +            101 => 'FX 6 (goblins)',
   1.463 +            102 => 'FX 7 (echoes)',
   1.464 +            103 => 'FX 8 (sci-fi)',
   1.465 +            104 => 'Sitar',
   1.466 +            105 => 'Banjo',
   1.467 +            106 => 'Shamisen',
   1.468 +            107 => 'Koto',
   1.469 +            108 => 'Kalimba',
   1.470 +            109 => 'Bagpipe',
   1.471 +            110 => 'Fiddle',
   1.472 +            111 => 'Shanai',
   1.473 +            112 => 'Tinkle Bell',
   1.474 +            113 => 'Agogo',
   1.475 +            114 => 'Steel Drums',
   1.476 +            115 => 'Woodblock',
   1.477 +            116 => 'Taiko Drum',
   1.478 +            117 => 'Melodic Tom',
   1.479 +            118 => 'Synth Drum',
   1.480 +            119 => 'Reverse Cymbal',
   1.481 +            120 => 'Guitar Fret Noise',
   1.482 +            121 => 'Breath Noise',
   1.483 +            122 => 'Seashore',
   1.484 +            123 => 'Bird Tweet',
   1.485 +            124 => 'Telephone Ring',
   1.486 +            125 => 'Helicopter',
   1.487 +            126 => 'Applause',
   1.488 +            127 => 'Gunshot'
   1.489 +        );
   1.490 +
   1.491 +        return @$lookup[$instrument_id];
   1.492 +    }   
   1.493 +   
   1.494 +        
   1.495 +        
   1.496 +    public static function GeneralMIDIpercussionLookup($instrument_id) {
   1.497 +        
   1.498 +        static $lookup = array (
   1.499 +        
   1.500 +            35 => 'Acoustic Bass Drum',
   1.501 +            36 => 'Bass Drum 1',
   1.502 +            37 => 'Side Stick',
   1.503 +            38 => 'Acoustic Snare',
   1.504 +            39 => 'Hand Clap',
   1.505 +            40 => 'Electric Snare',
   1.506 +            41 => 'Low Floor Tom',
   1.507 +            42 => 'Closed Hi-Hat',
   1.508 +            43 => 'High Floor Tom',
   1.509 +            44 => 'Pedal Hi-Hat',
   1.510 +            45 => 'Low Tom',
   1.511 +            46 => 'Open Hi-Hat',
   1.512 +            47 => 'Low-Mid Tom',
   1.513 +            48 => 'Hi-Mid Tom',
   1.514 +            49 => 'Crash Cymbal 1',
   1.515 +            50 => 'High Tom',
   1.516 +            51 => 'Ride Cymbal 1',
   1.517 +            52 => 'Chinese Cymbal',
   1.518 +            53 => 'Ride Bell',
   1.519 +            54 => 'Tambourine',
   1.520 +            55 => 'Splash Cymbal',
   1.521 +            56 => 'Cowbell',
   1.522 +            57 => 'Crash Cymbal 2',
   1.523 +            59 => 'Ride Cymbal 2',
   1.524 +            60 => 'Hi Bongo',
   1.525 +            61 => 'Low Bongo',
   1.526 +            62 => 'Mute Hi Conga',
   1.527 +            63 => 'Open Hi Conga',
   1.528 +            64 => 'Low Conga',
   1.529 +            65 => 'High Timbale',
   1.530 +            66 => 'Low Timbale',
   1.531 +            67 => 'High Agogo',
   1.532 +            68 => 'Low Agogo',
   1.533 +            69 => 'Cabasa',
   1.534 +            70 => 'Maracas',
   1.535 +            71 => 'Short Whistle',
   1.536 +            72 => 'Long Whistle',
   1.537 +            73 => 'Short Guiro',
   1.538 +            74 => 'Long Guiro',
   1.539 +            75 => 'Claves',
   1.540 +            76 => 'Hi Wood Block',
   1.541 +            77 => 'Low Wood Block',
   1.542 +            78 => 'Mute Cuica',
   1.543 +            79 => 'Open Cuica',
   1.544 +            80 => 'Mute Triangle',
   1.545 +            81 => 'Open Triangle'
   1.546 +        );
   1.547 +
   1.548 +        return @$lookup[$instrument_id];
   1.549 +    }   
   1.550 +
   1.551 +        
   1.552 +}       
   1.553 +        
   1.554 +        
   1.555 +?>
   1.556 \ No newline at end of file