Mercurial > judyates
comparison 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 |
comparison
equal
deleted
inserted
replaced
2:670229c4eb4b | 3:3f6b44aa6b35 |
---|---|
1 <?php | |
2 // +----------------------------------------------------------------------+ | |
3 // | PHP version 5 | | |
4 // +----------------------------------------------------------------------+ | |
5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen | | |
6 // +----------------------------------------------------------------------+ | |
7 // | This source file is subject to version 2 of the GPL license, | | |
8 // | that is bundled with this package in the file license.txt and is | | |
9 // | available through the world-wide-web at the following url: | | |
10 // | http://www.gnu.org/copyleft/gpl.html | | |
11 // +----------------------------------------------------------------------+ | |
12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org | | |
13 // +----------------------------------------------------------------------+ | |
14 // | Authors: James Heinrich <infoØgetid3*org> | | |
15 // | Allan Hansen <ahØartemis*dk> | | |
16 // +----------------------------------------------------------------------+ | |
17 // | module.audio.midi.php | | |
18 // | Module for analyzing midi audio files | | |
19 // | dependencies: NONE | | |
20 // +----------------------------------------------------------------------+ | |
21 // | |
22 // $Id: module.audio.midi.php,v 1.5 2006/11/02 10:48:01 ah Exp $ | |
23 | |
24 | |
25 | |
26 class getid3_midi extends getid3_handler | |
27 { | |
28 | |
29 public function Analyze() { | |
30 | |
31 $getid3 = $this->getid3; | |
32 | |
33 $getid3->info['midi']['raw'] = array (); | |
34 $info_midi = &$getid3->info['midi']; | |
35 $info_midi_raw = &$info_midi['raw']; | |
36 | |
37 $getid3->info['fileformat'] = 'midi'; | |
38 $getid3->info['audio']['dataformat'] = 'midi'; | |
39 | |
40 fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET); | |
41 $midi_data = fread($getid3->fp, getid3::FREAD_BUFFER_SIZE); | |
42 | |
43 // Magic bytes: 'MThd' | |
44 | |
45 getid3_lib::ReadSequence('BigEndian2Int', $info_midi_raw, $midi_data, 4, | |
46 array ( | |
47 'headersize' => 4, | |
48 'fileformat' => 2, | |
49 'tracks' => 2, | |
50 'ticksperqnote' => 2 | |
51 ) | |
52 ); | |
53 | |
54 $offset = 14; | |
55 | |
56 for ($i = 0; $i < $info_midi_raw['tracks']; $i++) { | |
57 | |
58 if ((strlen($midi_data) - $offset) < 8) { | |
59 $midi_data .= fread($getid3->fp, getid3::FREAD_BUFFER_SIZE); | |
60 } | |
61 | |
62 $track_id = substr($midi_data, $offset, 4); | |
63 $offset += 4; | |
64 | |
65 if ($track_id != 'MTrk') { | |
66 throw new getid3_exception('Expecting "MTrk" at '.$offset.', found '.$track_id.' instead'); | |
67 } | |
68 | |
69 $track_size = getid3_lib::BigEndian2Int(substr($midi_data, $offset, 4)); | |
70 $offset += 4; | |
71 | |
72 $track_data_array[$i] = substr($midi_data, $offset, $track_size); | |
73 $offset += $track_size; | |
74 } | |
75 | |
76 if (!isset($track_data_array) || !is_array($track_data_array)) { | |
77 throw new getid3_exception('Cannot find MIDI track information'); | |
78 } | |
79 | |
80 | |
81 $info_midi['totalticks'] = 0; | |
82 $getid3->info['playtime_seconds'] = 0; | |
83 $current_ms_per_beat = 500000; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat | |
84 $current_beats_per_min = 120; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat | |
85 $ms_per_quarter_note_after = array (); | |
86 | |
87 foreach ($track_data_array as $track_number => $track_data) { | |
88 | |
89 $events_offset = $last_issued_midi_command = $last_issued_midi_channel = $cumulative_delta_time = $ticks_at_current_bpm = 0; | |
90 | |
91 while ($events_offset < strlen($track_data)) { | |
92 | |
93 $event_id = 0; | |
94 if (isset($midi_events[$track_number]) && is_array($midi_events[$track_number])) { | |
95 $event_id = count($midi_events[$track_number]); | |
96 } | |
97 $delta_time = 0; | |
98 for ($i = 0; $i < 4; $i++) { | |
99 $delta_time_byte = ord($track_data{$events_offset++}); | |
100 $delta_time = ($delta_time << 7) + ($delta_time_byte & 0x7F); | |
101 if ($delta_time_byte & 0x80) { | |
102 // another byte follows | |
103 } else { | |
104 break; | |
105 } | |
106 } | |
107 | |
108 $cumulative_delta_time += $delta_time; | |
109 $ticks_at_current_bpm += $delta_time; | |
110 | |
111 $midi_events[$track_number][$event_id]['deltatime'] = $delta_time; | |
112 | |
113 $midi_event_channel = ord($track_data{$events_offset++}); | |
114 | |
115 // OK, normal event - MIDI command has MSB set | |
116 if ($midi_event_channel & 0x80) { | |
117 $last_issued_midi_command = $midi_event_channel >> 4; | |
118 $last_issued_midi_channel = $midi_event_channel & 0x0F; | |
119 } | |
120 | |
121 // Running event - assume last command | |
122 else { | |
123 $events_offset--; | |
124 } | |
125 | |
126 $midi_events[$track_number][$event_id]['eventid'] = $last_issued_midi_command; | |
127 $midi_events[$track_number][$event_id]['channel'] = $last_issued_midi_channel; | |
128 | |
129 switch ($midi_events[$track_number][$event_id]['eventid']) { | |
130 | |
131 case 0x8: // Note off (key is released) | |
132 case 0x9: // Note on (key is pressed) | |
133 case 0xA: // Key after-touch | |
134 | |
135 //$notenumber = ord($track_data{$events_offset++}); | |
136 //$velocity = ord($track_data{$events_offset++}); | |
137 $events_offset += 2; | |
138 break; | |
139 | |
140 | |
141 case 0xB: // Control Change | |
142 | |
143 //$controllernum = ord($track_data{$events_offset++}); | |
144 //$newvalue = ord($track_data{$events_offset++}); | |
145 $events_offset += 2; | |
146 break; | |
147 | |
148 | |
149 case 0xC: // Program (patch) change | |
150 | |
151 $new_program_num = ord($track_data{$events_offset++}); | |
152 | |
153 $info_midi_raw['track'][$track_number]['instrumentid'] = $new_program_num; | |
154 $info_midi_raw['track'][$track_number]['instrument'] = $track_number == 10 ? getid3_midi::GeneralMIDIpercussionLookup($new_program_num) : getid3_midi::GeneralMIDIinstrumentLookup($new_program_num); | |
155 break; | |
156 | |
157 | |
158 case 0xD: // Channel after-touch | |
159 | |
160 //$channelnumber = ord($track_data{$events_offset++}); | |
161 break; | |
162 | |
163 | |
164 case 0xE: // Pitch wheel change (2000H is normal or no change) | |
165 | |
166 //$changeLSB = ord($track_data{$events_offset++}); | |
167 //$changeMSB = ord($track_data{$events_offset++}); | |
168 //$pitchwheelchange = (($changeMSB & 0x7F) << 7) & ($changeLSB & 0x7F); | |
169 $events_offset += 2; | |
170 break; | |
171 | |
172 | |
173 case 0xF: | |
174 | |
175 if ($midi_events[$track_number][$event_id]['channel'] == 0xF) { | |
176 | |
177 $meta_event_command = ord($track_data{$events_offset++}); | |
178 $meta_event_length = ord($track_data{$events_offset++}); | |
179 $meta_event_data = substr($track_data, $events_offset, $meta_event_length); | |
180 $events_offset += $meta_event_length; | |
181 | |
182 switch ($meta_event_command) { | |
183 | |
184 case 0x00: // Set track sequence number | |
185 | |
186 //$track_sequence_number = getid3_lib::BigEndian2Int(substr($meta_event_data, 0, $meta_event_length)); | |
187 //$info_midi_raw['events'][$track_number][$event_id]['seqno'] = $track_sequence_number; | |
188 break; | |
189 | |
190 | |
191 case 0x01: // Text: generic | |
192 | |
193 $text_generic = substr($meta_event_data, 0, $meta_event_length); | |
194 //$info_midi_raw['events'][$track_number][$event_id]['text'] = $text_generic; | |
195 $info_midi['comments']['comment'][] = $text_generic; | |
196 break; | |
197 | |
198 | |
199 case 0x02: // Text: copyright | |
200 | |
201 $text_copyright = substr($meta_event_data, 0, $meta_event_length); | |
202 //$info_midi_raw['events'][$track_number][$event_id]['copyright'] = $text_copyright; | |
203 $info_midi['comments']['copyright'][] = $text_copyright; | |
204 break; | |
205 | |
206 | |
207 case 0x03: // Text: track name | |
208 | |
209 $text_trackname = substr($meta_event_data, 0, $meta_event_length); | |
210 $info_midi_raw['track'][$track_number]['name'] = $text_trackname; | |
211 break; | |
212 | |
213 | |
214 case 0x04: // Text: track instrument name | |
215 | |
216 //$text_instrument = substr($meta_event_data, 0, $meta_event_length); | |
217 //$info_midi_raw['events'][$track_number][$event_id]['instrument'] = $text_instrument; | |
218 break; | |
219 | |
220 | |
221 case 0x05: // Text: lyrics | |
222 | |
223 $text_lyrics = substr($meta_event_data, 0, $meta_event_length); | |
224 //$info_midi_raw['events'][$track_number][$event_id]['lyrics'] = $text_lyrics; | |
225 if (!isset($info_midi['lyrics'])) { | |
226 $info_midi['lyrics'] = ''; | |
227 } | |
228 $info_midi['lyrics'] .= $text_lyrics . "\n"; | |
229 break; | |
230 | |
231 | |
232 case 0x06: // Text: marker | |
233 | |
234 //$text_marker = substr($meta_event_data, 0, $meta_event_length); | |
235 //$info_midi_raw['events'][$track_number][$event_id]['marker'] = $text_marker; | |
236 break; | |
237 | |
238 | |
239 case 0x07: // Text: cue point | |
240 | |
241 //$text_cuepoint = substr($meta_event_data, 0, $meta_event_length); | |
242 //$info_midi_raw['events'][$track_number][$event_id]['cuepoint'] = $text_cuepoint; | |
243 break; | |
244 | |
245 | |
246 case 0x2F: // End Of Track | |
247 | |
248 //$info_midi_raw['events'][$track_number][$event_id]['EOT'] = $cumulative_delta_time; | |
249 break; | |
250 | |
251 | |
252 case 0x51: // Tempo: microseconds / quarter note | |
253 | |
254 $current_ms_per_beat = getid3_lib::BigEndian2Int(substr($meta_event_data, 0, $meta_event_length)); | |
255 $info_midi_raw['events'][$track_number][$cumulative_delta_time]['us_qnote'] = $current_ms_per_beat; | |
256 $current_beats_per_min = (1000000 / $current_ms_per_beat) * 60; | |
257 $ms_per_quarter_note_after[$cumulative_delta_time] = $current_ms_per_beat; | |
258 $ticks_at_current_bpm = 0; | |
259 break; | |
260 | |
261 | |
262 case 0x58: // Time signature | |
263 $timesig_numerator = getid3_lib::BigEndian2Int($meta_event_data[0]); | |
264 $timesig_denominator = pow(2, getid3_lib::BigEndian2Int($meta_event_data[1])); // $02 -> x/4, $03 -> x/8, etc | |
265 //$timesig_32inqnote = getid3_lib::BigEndian2Int($meta_event_data[2]); // number of 32nd notes to the quarter note | |
266 //$info_midi_raw['events'][$track_number][$event_id]['timesig_32inqnote'] = $timesig_32inqnote; | |
267 //$info_midi_raw['events'][$track_number][$event_id]['timesig_numerator'] = $timesig_numerator; | |
268 //$info_midi_raw['events'][$track_number][$event_id]['timesig_denominator'] = $timesig_denominator; | |
269 //$info_midi_raw['events'][$track_number][$event_id]['timesig_text'] = $timesig_numerator.'/'.$timesig_denominator; | |
270 $info_midi['timesignature'][] = $timesig_numerator.'/'.$timesig_denominator; | |
271 break; | |
272 | |
273 | |
274 case 0x59: // Keysignature | |
275 | |
276 $keysig_sharpsflats = getid3_lib::BigEndian2Int($meta_event_data{0}); | |
277 if ($keysig_sharpsflats & 0x80) { | |
278 // (-7 -> 7 flats, 0 ->key of C, 7 -> 7 sharps) | |
279 $keysig_sharpsflats -= 256; | |
280 } | |
281 | |
282 $keysig_majorminor = getid3_lib::BigEndian2Int($meta_event_data{1}); // 0 -> major, 1 -> minor | |
283 $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#'); | |
284 //$info_midi_raw['events'][$track_number][$event_id]['keysig_sharps'] = (($keysig_sharpsflats > 0) ? abs($keysig_sharpsflats) : 0); | |
285 //$info_midi_raw['events'][$track_number][$event_id]['keysig_flats'] = (($keysig_sharpsflats < 0) ? abs($keysig_sharpsflats) : 0); | |
286 //$info_midi_raw['events'][$track_number][$event_id]['keysig_minor'] = (bool)$keysig_majorminor; | |
287 //$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'); | |
288 | |
289 // $keysigs[$keysig_sharpsflats] gets an int key (correct) - $keysigs["$keysig_sharpsflats"] gets a string key (incorrect) | |
290 $info_midi['keysignature'][] = $keysigs[$keysig_sharpsflats].' '.((bool)$keysig_majorminor ? 'minor' : 'major'); | |
291 break; | |
292 | |
293 | |
294 case 0x7F: // Sequencer specific information | |
295 | |
296 $custom_data = substr($meta_event_data, 0, $meta_event_length); | |
297 break; | |
298 | |
299 | |
300 default: | |
301 | |
302 $getid3->warning('Unhandled META Event Command: '.$meta_event_command); | |
303 } | |
304 } | |
305 break; | |
306 | |
307 | |
308 default: | |
309 $getid3->warning('Unhandled MIDI Event ID: '.$midi_events[$track_number][$event_id]['eventid']); | |
310 } | |
311 } | |
312 | |
313 if (($track_number > 0) || (count($track_data_array) == 1)) { | |
314 $info_midi['totalticks'] = max($info_midi['totalticks'], $cumulative_delta_time); | |
315 } | |
316 } | |
317 | |
318 $previous_tick_offset = null; | |
319 | |
320 ksort($ms_per_quarter_note_after); | |
321 foreach ($ms_per_quarter_note_after as $tick_offset => $ms_per_beat) { | |
322 | |
323 if (is_null($previous_tick_offset)) { | |
324 $prev_ms_per_beat = $ms_per_beat; | |
325 $previous_tick_offset = $tick_offset; | |
326 continue; | |
327 } | |
328 | |
329 if ($info_midi['totalticks'] > $tick_offset) { | |
330 $getid3->info['playtime_seconds'] += (($tick_offset - $previous_tick_offset) / $info_midi_raw['ticksperqnote']) * ($prev_ms_per_beat / 1000000); | |
331 | |
332 $prev_ms_per_beat = $ms_per_beat; | |
333 $previous_tick_offset = $tick_offset; | |
334 } | |
335 } | |
336 | |
337 if ($info_midi['totalticks'] > $previous_tick_offset) { | |
338 $getid3->info['playtime_seconds'] += (($info_midi['totalticks'] - $previous_tick_offset) / $info_midi_raw['ticksperqnote']) * ($ms_per_beat / 1000000); | |
339 } | |
340 | |
341 if (@$getid3->info['playtime_seconds'] > 0) { | |
342 $getid3->info['bitrate'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / $getid3->info['playtime_seconds']; | |
343 } | |
344 | |
345 if (!empty($info_midi['lyrics'])) { | |
346 $info_midi['comments']['lyrics'][] = $info_midi['lyrics']; | |
347 } | |
348 | |
349 return true; | |
350 } | |
351 | |
352 | |
353 | |
354 public static function GeneralMIDIinstrumentLookup($instrument_id) { | |
355 | |
356 static $lookup = array ( | |
357 | |
358 0 => 'Acoustic Grand', | |
359 1 => 'Bright Acoustic', | |
360 2 => 'Electric Grand', | |
361 3 => 'Honky-Tonk', | |
362 4 => 'Electric Piano 1', | |
363 5 => 'Electric Piano 2', | |
364 6 => 'Harpsichord', | |
365 7 => 'Clavier', | |
366 8 => 'Celesta', | |
367 9 => 'Glockenspiel', | |
368 10 => 'Music Box', | |
369 11 => 'Vibraphone', | |
370 12 => 'Marimba', | |
371 13 => 'Xylophone', | |
372 14 => 'Tubular Bells', | |
373 15 => 'Dulcimer', | |
374 16 => 'Drawbar Organ', | |
375 17 => 'Percussive Organ', | |
376 18 => 'Rock Organ', | |
377 19 => 'Church Organ', | |
378 20 => 'Reed Organ', | |
379 21 => 'Accordian', | |
380 22 => 'Harmonica', | |
381 23 => 'Tango Accordian', | |
382 24 => 'Acoustic Guitar (nylon)', | |
383 25 => 'Acoustic Guitar (steel)', | |
384 26 => 'Electric Guitar (jazz)', | |
385 27 => 'Electric Guitar (clean)', | |
386 28 => 'Electric Guitar (muted)', | |
387 29 => 'Overdriven Guitar', | |
388 30 => 'Distortion Guitar', | |
389 31 => 'Guitar Harmonics', | |
390 32 => 'Acoustic Bass', | |
391 33 => 'Electric Bass (finger)', | |
392 34 => 'Electric Bass (pick)', | |
393 35 => 'Fretless Bass', | |
394 36 => 'Slap Bass 1', | |
395 37 => 'Slap Bass 2', | |
396 38 => 'Synth Bass 1', | |
397 39 => 'Synth Bass 2', | |
398 40 => 'Violin', | |
399 41 => 'Viola', | |
400 42 => 'Cello', | |
401 43 => 'Contrabass', | |
402 44 => 'Tremolo Strings', | |
403 45 => 'Pizzicato Strings', | |
404 46 => 'Orchestral Strings', | |
405 47 => 'Timpani', | |
406 48 => 'String Ensemble 1', | |
407 49 => 'String Ensemble 2', | |
408 50 => 'SynthStrings 1', | |
409 51 => 'SynthStrings 2', | |
410 52 => 'Choir Aahs', | |
411 53 => 'Voice Oohs', | |
412 54 => 'Synth Voice', | |
413 55 => 'Orchestra Hit', | |
414 56 => 'Trumpet', | |
415 57 => 'Trombone', | |
416 58 => 'Tuba', | |
417 59 => 'Muted Trumpet', | |
418 60 => 'French Horn', | |
419 61 => 'Brass Section', | |
420 62 => 'SynthBrass 1', | |
421 63 => 'SynthBrass 2', | |
422 64 => 'Soprano Sax', | |
423 65 => 'Alto Sax', | |
424 66 => 'Tenor Sax', | |
425 67 => 'Baritone Sax', | |
426 68 => 'Oboe', | |
427 69 => 'English Horn', | |
428 70 => 'Bassoon', | |
429 71 => 'Clarinet', | |
430 72 => 'Piccolo', | |
431 73 => 'Flute', | |
432 74 => 'Recorder', | |
433 75 => 'Pan Flute', | |
434 76 => 'Blown Bottle', | |
435 77 => 'Shakuhachi', | |
436 78 => 'Whistle', | |
437 79 => 'Ocarina', | |
438 80 => 'Lead 1 (square)', | |
439 81 => 'Lead 2 (sawtooth)', | |
440 82 => 'Lead 3 (calliope)', | |
441 83 => 'Lead 4 (chiff)', | |
442 84 => 'Lead 5 (charang)', | |
443 85 => 'Lead 6 (voice)', | |
444 86 => 'Lead 7 (fifths)', | |
445 87 => 'Lead 8 (bass + lead)', | |
446 88 => 'Pad 1 (new age)', | |
447 89 => 'Pad 2 (warm)', | |
448 90 => 'Pad 3 (polysynth)', | |
449 91 => 'Pad 4 (choir)', | |
450 92 => 'Pad 5 (bowed)', | |
451 93 => 'Pad 6 (metallic)', | |
452 94 => 'Pad 7 (halo)', | |
453 95 => 'Pad 8 (sweep)', | |
454 96 => 'FX 1 (rain)', | |
455 97 => 'FX 2 (soundtrack)', | |
456 98 => 'FX 3 (crystal)', | |
457 99 => 'FX 4 (atmosphere)', | |
458 100 => 'FX 5 (brightness)', | |
459 101 => 'FX 6 (goblins)', | |
460 102 => 'FX 7 (echoes)', | |
461 103 => 'FX 8 (sci-fi)', | |
462 104 => 'Sitar', | |
463 105 => 'Banjo', | |
464 106 => 'Shamisen', | |
465 107 => 'Koto', | |
466 108 => 'Kalimba', | |
467 109 => 'Bagpipe', | |
468 110 => 'Fiddle', | |
469 111 => 'Shanai', | |
470 112 => 'Tinkle Bell', | |
471 113 => 'Agogo', | |
472 114 => 'Steel Drums', | |
473 115 => 'Woodblock', | |
474 116 => 'Taiko Drum', | |
475 117 => 'Melodic Tom', | |
476 118 => 'Synth Drum', | |
477 119 => 'Reverse Cymbal', | |
478 120 => 'Guitar Fret Noise', | |
479 121 => 'Breath Noise', | |
480 122 => 'Seashore', | |
481 123 => 'Bird Tweet', | |
482 124 => 'Telephone Ring', | |
483 125 => 'Helicopter', | |
484 126 => 'Applause', | |
485 127 => 'Gunshot' | |
486 ); | |
487 | |
488 return @$lookup[$instrument_id]; | |
489 } | |
490 | |
491 | |
492 | |
493 public static function GeneralMIDIpercussionLookup($instrument_id) { | |
494 | |
495 static $lookup = array ( | |
496 | |
497 35 => 'Acoustic Bass Drum', | |
498 36 => 'Bass Drum 1', | |
499 37 => 'Side Stick', | |
500 38 => 'Acoustic Snare', | |
501 39 => 'Hand Clap', | |
502 40 => 'Electric Snare', | |
503 41 => 'Low Floor Tom', | |
504 42 => 'Closed Hi-Hat', | |
505 43 => 'High Floor Tom', | |
506 44 => 'Pedal Hi-Hat', | |
507 45 => 'Low Tom', | |
508 46 => 'Open Hi-Hat', | |
509 47 => 'Low-Mid Tom', | |
510 48 => 'Hi-Mid Tom', | |
511 49 => 'Crash Cymbal 1', | |
512 50 => 'High Tom', | |
513 51 => 'Ride Cymbal 1', | |
514 52 => 'Chinese Cymbal', | |
515 53 => 'Ride Bell', | |
516 54 => 'Tambourine', | |
517 55 => 'Splash Cymbal', | |
518 56 => 'Cowbell', | |
519 57 => 'Crash Cymbal 2', | |
520 59 => 'Ride Cymbal 2', | |
521 60 => 'Hi Bongo', | |
522 61 => 'Low Bongo', | |
523 62 => 'Mute Hi Conga', | |
524 63 => 'Open Hi Conga', | |
525 64 => 'Low Conga', | |
526 65 => 'High Timbale', | |
527 66 => 'Low Timbale', | |
528 67 => 'High Agogo', | |
529 68 => 'Low Agogo', | |
530 69 => 'Cabasa', | |
531 70 => 'Maracas', | |
532 71 => 'Short Whistle', | |
533 72 => 'Long Whistle', | |
534 73 => 'Short Guiro', | |
535 74 => 'Long Guiro', | |
536 75 => 'Claves', | |
537 76 => 'Hi Wood Block', | |
538 77 => 'Low Wood Block', | |
539 78 => 'Mute Cuica', | |
540 79 => 'Open Cuica', | |
541 80 => 'Mute Triangle', | |
542 81 => 'Open Triangle' | |
543 ); | |
544 | |
545 return @$lookup[$instrument_id]; | |
546 } | |
547 | |
548 | |
549 } | |
550 | |
551 | |
552 ?> |