ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
getid3_midi Class Reference

getID3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g // More...

+ Inheritance diagram for getid3_midi:
+ Collaboration diagram for getid3_midi:

Public Member Functions

 getid3_midi (&$fd, &$ThisFileInfo, $scanwholefile=true)
 
 GeneralMIDIinstrumentLookup ($instrumentid)
 
 GeneralMIDIpercussionLookup ($instrumentid)
 
 Analyze ()
 
 GeneralMIDIinstrumentLookup ($instrumentid)
 
 GeneralMIDIpercussionLookup ($instrumentid)
 
- Public Member Functions inherited from getid3_handler
 __construct (getID3 $getid3, $call_module=null)
 
 Analyze ()
 
 AnalyzeString ($string)
 
 setStringMode ($string)
 
 saveAttachment ($name, $offset, $length, $image_mime=null)
 

Data Fields

 $scanwholefile = true
 

Additional Inherited Members

- Protected Member Functions inherited from getid3_handler
 ftell ()
 
 fread ($bytes)
 
 fseek ($bytes, $whence=SEEK_SET)
 
 feof ()
 
 isDependencyFor ($module)
 
 error ($text)
 
 warning ($text)
 
 notice ($text)
 
- Protected Attributes inherited from getid3_handler
 $getid3
 
 $data_string_flag = false
 
 $data_string = ''
 
 $data_string_position = 0
 
 $data_string_length = 0
 

Detailed Description

getID3() by James Heinrich info@.nosp@m.geti.nosp@m.d3.or.nosp@m.g //

Definition at line 17 of file module.audio.midi.php.

Member Function Documentation

◆ Analyze()

getid3_midi::Analyze ( )

Definition at line 24 of file module.audio.midi.php.

References $info, getid3_lib\BigEndian2Int(), getid3_handler\fread(), getid3_handler\fseek(), GeneralMIDIinstrumentLookup(), GeneralMIDIpercussionLookup(), GETID3_MIDI_MAGIC_MTHD, GETID3_MIDI_MAGIC_MTRK, and getid3_lib\PrintHexBytes().

24  {
25  $info = &$this->getid3->info;
26 
27  // shortcut
28  $info['midi']['raw'] = array();
29  $thisfile_midi = &$info['midi'];
30  $thisfile_midi_raw = &$thisfile_midi['raw'];
31 
32  $info['fileformat'] = 'midi';
33  $info['audio']['dataformat'] = 'midi';
34 
35  $this->fseek($info['avdataoffset']);
36  $MIDIdata = $this->fread($this->getid3->fread_buffer_size());
37  $offset = 0;
38  $MIDIheaderID = substr($MIDIdata, $offset, 4); // 'MThd'
39  if ($MIDIheaderID != GETID3_MIDI_MAGIC_MTHD) {
40  $info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes(GETID3_MIDI_MAGIC_MTHD).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($MIDIheaderID).'"';
41  unset($info['fileformat']);
42  return false;
43  }
44  $offset += 4;
45  $thisfile_midi_raw['headersize'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 4));
46  $offset += 4;
47  $thisfile_midi_raw['fileformat'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
48  $offset += 2;
49  $thisfile_midi_raw['tracks'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
50  $offset += 2;
51  $thisfile_midi_raw['ticksperqnote'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
52  $offset += 2;
53 
54  for ($i = 0; $i < $thisfile_midi_raw['tracks']; $i++) {
55  while ((strlen($MIDIdata) - $offset) < 8) {
56  if ($buffer = $this->fread($this->getid3->fread_buffer_size())) {
57  $MIDIdata .= $buffer;
58  } else {
59  $info['warning'][] = 'only processed '.($i - 1).' of '.$thisfile_midi_raw['tracks'].' tracks';
60  $info['error'][] = 'Unabled to read more file data at '.$this->ftell().' (trying to seek to : '.$offset.'), was expecting at least 8 more bytes';
61  return false;
62  }
63  }
64  $trackID = substr($MIDIdata, $offset, 4);
65  $offset += 4;
66  if ($trackID == GETID3_MIDI_MAGIC_MTRK) {
67  $tracksize = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 4));
68  $offset += 4;
69  //$thisfile_midi['tracks'][$i]['size'] = $tracksize;
70  $trackdataarray[$i] = substr($MIDIdata, $offset, $tracksize);
71  $offset += $tracksize;
72  } else {
73  $info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes(GETID3_MIDI_MAGIC_MTRK).'" at '.($offset - 4).', found "'.getid3_lib::PrintHexBytes($trackID).'" instead';
74  return false;
75  }
76  }
77 
78  if (!isset($trackdataarray) || !is_array($trackdataarray)) {
79  $info['error'][] = 'Cannot find MIDI track information';
80  unset($thisfile_midi);
81  unset($info['fileformat']);
82  return false;
83  }
84 
85  if ($this->scanwholefile) { // this can take quite a long time, so have the option to bypass it if speed is very important
86  $thisfile_midi['totalticks'] = 0;
87  $info['playtime_seconds'] = 0;
88  $CurrentMicroSecondsPerBeat = 500000; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat
89  $CurrentBeatsPerMinute = 120; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat
90  $MicroSecondsPerQuarterNoteAfter = array ();
91 
92  foreach ($trackdataarray as $tracknumber => $trackdata) {
93 
94  $eventsoffset = 0;
95  $LastIssuedMIDIcommand = 0;
96  $LastIssuedMIDIchannel = 0;
97  $CumulativeDeltaTime = 0;
98  $TicksAtCurrentBPM = 0;
99  while ($eventsoffset < strlen($trackdata)) {
100  $eventid = 0;
101  if (isset($MIDIevents[$tracknumber]) && is_array($MIDIevents[$tracknumber])) {
102  $eventid = count($MIDIevents[$tracknumber]);
103  }
104  $deltatime = 0;
105  for ($i = 0; $i < 4; $i++) {
106  $deltatimebyte = ord(substr($trackdata, $eventsoffset++, 1));
107  $deltatime = ($deltatime << 7) + ($deltatimebyte & 0x7F);
108  if ($deltatimebyte & 0x80) {
109  // another byte follows
110  } else {
111  break;
112  }
113  }
114  $CumulativeDeltaTime += $deltatime;
115  $TicksAtCurrentBPM += $deltatime;
116  $MIDIevents[$tracknumber][$eventid]['deltatime'] = $deltatime;
117  $MIDI_event_channel = ord(substr($trackdata, $eventsoffset++, 1));
118  if ($MIDI_event_channel & 0x80) {
119  // OK, normal event - MIDI command has MSB set
120  $LastIssuedMIDIcommand = $MIDI_event_channel >> 4;
121  $LastIssuedMIDIchannel = $MIDI_event_channel & 0x0F;
122  } else {
123  // running event - assume last command
124  $eventsoffset--;
125  }
126  $MIDIevents[$tracknumber][$eventid]['eventid'] = $LastIssuedMIDIcommand;
127  $MIDIevents[$tracknumber][$eventid]['channel'] = $LastIssuedMIDIchannel;
128  if ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x08) { // Note off (key is released)
129 
130  $notenumber = ord(substr($trackdata, $eventsoffset++, 1));
131  $velocity = ord(substr($trackdata, $eventsoffset++, 1));
132 
133  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x09) { // Note on (key is pressed)
134 
135  $notenumber = ord(substr($trackdata, $eventsoffset++, 1));
136  $velocity = ord(substr($trackdata, $eventsoffset++, 1));
137 
138  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0A) { // Key after-touch
139 
140  $notenumber = ord(substr($trackdata, $eventsoffset++, 1));
141  $velocity = ord(substr($trackdata, $eventsoffset++, 1));
142 
143  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0B) { // Control Change
144 
145  $controllernum = ord(substr($trackdata, $eventsoffset++, 1));
146  $newvalue = ord(substr($trackdata, $eventsoffset++, 1));
147 
148  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0C) { // Program (patch) change
149 
150  $newprogramnum = ord(substr($trackdata, $eventsoffset++, 1));
151 
152  $thisfile_midi_raw['track'][$tracknumber]['instrumentid'] = $newprogramnum;
153  if ($tracknumber == 10) {
154  $thisfile_midi_raw['track'][$tracknumber]['instrument'] = $this->GeneralMIDIpercussionLookup($newprogramnum);
155  } else {
156  $thisfile_midi_raw['track'][$tracknumber]['instrument'] = $this->GeneralMIDIinstrumentLookup($newprogramnum);
157  }
158 
159  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0D) { // Channel after-touch
160 
161  $channelnumber = ord(substr($trackdata, $eventsoffset++, 1));
162 
163  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0E) { // Pitch wheel change (2000H is normal or no change)
164 
165  $changeLSB = ord(substr($trackdata, $eventsoffset++, 1));
166  $changeMSB = ord(substr($trackdata, $eventsoffset++, 1));
167  $pitchwheelchange = (($changeMSB & 0x7F) << 7) & ($changeLSB & 0x7F);
168 
169  } elseif (($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0F) && ($MIDIevents[$tracknumber][$eventid]['channel'] == 0x0F)) {
170 
171  $METAeventCommand = ord(substr($trackdata, $eventsoffset++, 1));
172  $METAeventLength = ord(substr($trackdata, $eventsoffset++, 1));
173  $METAeventData = substr($trackdata, $eventsoffset, $METAeventLength);
174  $eventsoffset += $METAeventLength;
175  switch ($METAeventCommand) {
176  case 0x00: // Set track sequence number
177  $track_sequence_number = getid3_lib::BigEndian2Int(substr($METAeventData, 0, $METAeventLength));
178  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['seqno'] = $track_sequence_number;
179  break;
180 
181  case 0x01: // Text: generic
182  $text_generic = substr($METAeventData, 0, $METAeventLength);
183  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['text'] = $text_generic;
184  $thisfile_midi['comments']['comment'][] = $text_generic;
185  break;
186 
187  case 0x02: // Text: copyright
188  $text_copyright = substr($METAeventData, 0, $METAeventLength);
189  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['copyright'] = $text_copyright;
190  $thisfile_midi['comments']['copyright'][] = $text_copyright;
191  break;
192 
193  case 0x03: // Text: track name
194  $text_trackname = substr($METAeventData, 0, $METAeventLength);
195  $thisfile_midi_raw['track'][$tracknumber]['name'] = $text_trackname;
196  break;
197 
198  case 0x04: // Text: track instrument name
199  $text_instrument = substr($METAeventData, 0, $METAeventLength);
200  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['instrument'] = $text_instrument;
201  break;
202 
203  case 0x05: // Text: lyrics
204  $text_lyrics = substr($METAeventData, 0, $METAeventLength);
205  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['lyrics'] = $text_lyrics;
206  if (!isset($thisfile_midi['lyrics'])) {
207  $thisfile_midi['lyrics'] = '';
208  }
209  $thisfile_midi['lyrics'] .= $text_lyrics."\n";
210  break;
211 
212  case 0x06: // Text: marker
213  $text_marker = substr($METAeventData, 0, $METAeventLength);
214  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['marker'] = $text_marker;
215  break;
216 
217  case 0x07: // Text: cue point
218  $text_cuepoint = substr($METAeventData, 0, $METAeventLength);
219  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['cuepoint'] = $text_cuepoint;
220  break;
221 
222  case 0x2F: // End Of Track
223  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['EOT'] = $CumulativeDeltaTime;
224  break;
225 
226  case 0x51: // Tempo: microseconds / quarter note
227  $CurrentMicroSecondsPerBeat = getid3_lib::BigEndian2Int(substr($METAeventData, 0, $METAeventLength));
228  if ($CurrentMicroSecondsPerBeat == 0) {
229  $info['error'][] = 'Corrupt MIDI file: CurrentMicroSecondsPerBeat == zero';
230  return false;
231  }
232  $thisfile_midi_raw['events'][$tracknumber][$CumulativeDeltaTime]['us_qnote'] = $CurrentMicroSecondsPerBeat;
233  $CurrentBeatsPerMinute = (1000000 / $CurrentMicroSecondsPerBeat) * 60;
234  $MicroSecondsPerQuarterNoteAfter[$CumulativeDeltaTime] = $CurrentMicroSecondsPerBeat;
235  $TicksAtCurrentBPM = 0;
236  break;
237 
238  case 0x58: // Time signature
239  $timesig_numerator = getid3_lib::BigEndian2Int($METAeventData{0});
240  $timesig_denominator = pow(2, getid3_lib::BigEndian2Int($METAeventData{1})); // $02 -> x/4, $03 -> x/8, etc
241  $timesig_32inqnote = getid3_lib::BigEndian2Int($METAeventData{2}); // number of 32nd notes to the quarter note
242  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_32inqnote'] = $timesig_32inqnote;
243  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_numerator'] = $timesig_numerator;
244  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_denominator'] = $timesig_denominator;
245  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_text'] = $timesig_numerator.'/'.$timesig_denominator;
246  $thisfile_midi['timesignature'][] = $timesig_numerator.'/'.$timesig_denominator;
247  break;
248 
249  case 0x59: // Keysignature
250  $keysig_sharpsflats = getid3_lib::BigEndian2Int($METAeventData{0});
251  if ($keysig_sharpsflats & 0x80) {
252  // (-7 -> 7 flats, 0 ->key of C, 7 -> 7 sharps)
253  $keysig_sharpsflats -= 256;
254  }
255 
256  $keysig_majorminor = getid3_lib::BigEndian2Int($METAeventData{1}); // 0 -> major, 1 -> minor
257  $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#');
258  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_sharps'] = (($keysig_sharpsflats > 0) ? abs($keysig_sharpsflats) : 0);
259  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_flats'] = (($keysig_sharpsflats < 0) ? abs($keysig_sharpsflats) : 0);
260  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_minor'] = (bool) $keysig_majorminor;
261  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_text'] = $keysigs[$keysig_sharpsflats].' '.($thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_minor'] ? 'minor' : 'major');
262 
263  // $keysigs[$keysig_sharpsflats] gets an int key (correct) - $keysigs["$keysig_sharpsflats"] gets a string key (incorrect)
264  $thisfile_midi['keysignature'][] = $keysigs[$keysig_sharpsflats].' '.((bool) $keysig_majorminor ? 'minor' : 'major');
265  break;
266 
267  case 0x7F: // Sequencer specific information
268  $custom_data = substr($METAeventData, 0, $METAeventLength);
269  break;
270 
271  default:
272  $info['warning'][] = 'Unhandled META Event Command: '.$METAeventCommand;
273  break;
274  }
275 
276  } else {
277 
278  $info['warning'][] = 'Unhandled MIDI Event ID: '.$MIDIevents[$tracknumber][$eventid]['eventid'].' + Channel ID: '.$MIDIevents[$tracknumber][$eventid]['channel'];
279 
280  }
281  }
282  if (($tracknumber > 0) || (count($trackdataarray) == 1)) {
283  $thisfile_midi['totalticks'] = max($thisfile_midi['totalticks'], $CumulativeDeltaTime);
284  }
285  }
286  $previoustickoffset = null;
287 
288  ksort($MicroSecondsPerQuarterNoteAfter);
289  foreach ($MicroSecondsPerQuarterNoteAfter as $tickoffset => $microsecondsperbeat) {
290  if (is_null($previoustickoffset)) {
291  $prevmicrosecondsperbeat = $microsecondsperbeat;
292  $previoustickoffset = $tickoffset;
293  continue;
294  }
295  if ($thisfile_midi['totalticks'] > $tickoffset) {
296 
297  if ($thisfile_midi_raw['ticksperqnote'] == 0) {
298  $info['error'][] = 'Corrupt MIDI file: ticksperqnote == zero';
299  return false;
300  }
301 
302  $info['playtime_seconds'] += (($tickoffset - $previoustickoffset) / $thisfile_midi_raw['ticksperqnote']) * ($prevmicrosecondsperbeat / 1000000);
303 
304  $prevmicrosecondsperbeat = $microsecondsperbeat;
305  $previoustickoffset = $tickoffset;
306  }
307  }
308  if ($thisfile_midi['totalticks'] > $previoustickoffset) {
309 
310  if ($thisfile_midi_raw['ticksperqnote'] == 0) {
311  $info['error'][] = 'Corrupt MIDI file: ticksperqnote == zero';
312  return false;
313  }
314 
315  $info['playtime_seconds'] += (($thisfile_midi['totalticks'] - $previoustickoffset) / $thisfile_midi_raw['ticksperqnote']) * ($microsecondsperbeat / 1000000);
316 
317  }
318  }
319 
320 
321  if (!empty($info['playtime_seconds'])) {
322  $info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
323  }
324 
325  if (!empty($thisfile_midi['lyrics'])) {
326  $thisfile_midi['comments']['lyrics'][] = $thisfile_midi['lyrics'];
327  }
328 
329  return true;
330  }
const GETID3_MIDI_MAGIC_MTRK
GeneralMIDIinstrumentLookup($instrumentid)
$info
Definition: example_052.php:80
GeneralMIDIpercussionLookup($instrumentid)
fread($bytes)
Definition: getid3.php:1685
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
PrintHexBytes($string, $hex=true, $spaces=true, $htmlsafe=true)
Definition: getid3.lib.php:17
const GETID3_MIDI_MAGIC_MTHD
getID3() by James Heinrich info@getid3.org //
+ Here is the call graph for this function:

◆ GeneralMIDIinstrumentLookup() [1/2]

getid3_midi::GeneralMIDIinstrumentLookup (   $instrumentid)

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

Definition at line 319 of file module.audio.midi.php.

References getid3_lib\EmbeddedLookup().

Referenced by Analyze(), and getid3_midi().

319  {
320 
321  $begin = __LINE__;
322 
456  return getid3_lib::EmbeddedLookup($instrumentid, $begin, __LINE__, __FILE__, 'GeneralMIDIinstrument');
457  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GeneralMIDIinstrumentLookup() [2/2]

getid3_midi::GeneralMIDIinstrumentLookup (   $instrumentid)

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

Definition at line 332 of file module.audio.midi.php.

References getid3_lib\EmbeddedLookup().

332  {
333 
334  $begin = __LINE__;
335 
469  return getid3_lib::EmbeddedLookup($instrumentid, $begin, __LINE__, __FILE__, 'GeneralMIDIinstrument');
470  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ Here is the call graph for this function:

◆ GeneralMIDIpercussionLookup() [1/2]

getid3_midi::GeneralMIDIpercussionLookup (   $instrumentid)

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

Definition at line 459 of file module.audio.midi.php.

References getid3_lib\EmbeddedLookup().

Referenced by Analyze(), and getid3_midi().

459  {
460 
461  $begin = __LINE__;
462 
514  return getid3_lib::EmbeddedLookup($instrumentid, $begin, __LINE__, __FILE__, 'GeneralMIDIpercussion');
515  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ GeneralMIDIpercussionLookup() [2/2]

getid3_midi::GeneralMIDIpercussionLookup (   $instrumentid)

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

Definition at line 472 of file module.audio.midi.php.

References getid3_lib\EmbeddedLookup().

472  {
473 
474  $begin = __LINE__;
475 
527  return getid3_lib::EmbeddedLookup($instrumentid, $begin, __LINE__, __FILE__, 'GeneralMIDIpercussion');
528  }
EmbeddedLookup($key, $begin, $end, $file, $name)
+ Here is the call graph for this function:

◆ getid3_midi()

getid3_midi::getid3_midi ( $fd,
$ThisFileInfo,
  $scanwholefile = true 
)

Definition at line 20 of file module.audio.midi.php.

References $scanwholefile, getid3_lib\BigEndian2Int(), getid3_handler\fread(), getid3_handler\fseek(), GeneralMIDIinstrumentLookup(), GeneralMIDIpercussionLookup(), and GETID3_FREAD_BUFFER_SIZE.

20  {
21 
22  // shortcut
23  $ThisFileInfo['midi']['raw'] = array();
24  $thisfile_midi = &$ThisFileInfo['midi'];
25  $thisfile_midi_raw = &$thisfile_midi['raw'];
26 
27  $ThisFileInfo['fileformat'] = 'midi';
28  $ThisFileInfo['audio']['dataformat'] = 'midi';
29 
30  fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
31  $MIDIdata = fread($fd, GETID3_FREAD_BUFFER_SIZE);
32  $offset = 0;
33  $MIDIheaderID = substr($MIDIdata, $offset, 4); // 'MThd'
34  if ($MIDIheaderID != 'MThd') {
35  $ThisFileInfo['error'][] = 'Expecting "MThd" at offset '.$ThisFileInfo['avdataoffset'].', found "'.$MIDIheaderID.'"';
36  unset($ThisFileInfo['fileformat']);
37  return false;
38  }
39  $offset += 4;
40  $thisfile_midi_raw['headersize'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 4));
41  $offset += 4;
42  $thisfile_midi_raw['fileformat'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
43  $offset += 2;
44  $thisfile_midi_raw['tracks'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
45  $offset += 2;
46  $thisfile_midi_raw['ticksperqnote'] = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 2));
47  $offset += 2;
48 
49  for ($i = 0; $i < $thisfile_midi_raw['tracks']; $i++) {
50  if ((strlen($MIDIdata) - $offset) < 8) {
51  $MIDIdata .= fread($fd, GETID3_FREAD_BUFFER_SIZE);
52  }
53  $trackID = substr($MIDIdata, $offset, 4);
54  $offset += 4;
55  if ($trackID == 'MTrk') {
56  $tracksize = getid3_lib::BigEndian2Int(substr($MIDIdata, $offset, 4));
57  $offset += 4;
58  // $thisfile_midi['tracks'][$i]['size'] = $tracksize;
59  $trackdataarray[$i] = substr($MIDIdata, $offset, $tracksize);
60  $offset += $tracksize;
61  } else {
62  $ThisFileInfo['error'][] = 'Expecting "MTrk" at '.$offset.', found '.$trackID.' instead';
63  return false;
64  }
65  }
66 
67  if (!isset($trackdataarray) || !is_array($trackdataarray)) {
68  $ThisFileInfo['error'][] = 'Cannot find MIDI track information';
69  unset($thisfile_midi);
70  unset($ThisFileInfo['fileformat']);
71  return false;
72  }
73 
74  if ($scanwholefile) { // this can take quite a long time, so have the option to bypass it if speed is very important
75  $thisfile_midi['totalticks'] = 0;
76  $ThisFileInfo['playtime_seconds'] = 0;
77  $CurrentMicroSecondsPerBeat = 500000; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat
78  $CurrentBeatsPerMinute = 120; // 120 beats per minute; 60,000,000 microseconds per minute -> 500,000 microseconds per beat
79 
80  foreach ($trackdataarray as $tracknumber => $trackdata) {
81 
82  $eventsoffset = 0;
83  $LastIssuedMIDIcommand = 0;
84  $LastIssuedMIDIchannel = 0;
85  $CumulativeDeltaTime = 0;
86  $TicksAtCurrentBPM = 0;
87  while ($eventsoffset < strlen($trackdata)) {
88  $eventid = 0;
89  if (isset($MIDIevents[$tracknumber]) && is_array($MIDIevents[$tracknumber])) {
90  $eventid = count($MIDIevents[$tracknumber]);
91  }
92  $deltatime = 0;
93  for ($i = 0; $i < 4; $i++) {
94  $deltatimebyte = ord(substr($trackdata, $eventsoffset++, 1));
95  $deltatime = ($deltatime << 7) + ($deltatimebyte & 0x7F);
96  if ($deltatimebyte & 0x80) {
97  // another byte follows
98  } else {
99  break;
100  }
101  }
102  $CumulativeDeltaTime += $deltatime;
103  $TicksAtCurrentBPM += $deltatime;
104  $MIDIevents[$tracknumber][$eventid]['deltatime'] = $deltatime;
105  $MIDI_event_channel = ord(substr($trackdata, $eventsoffset++, 1));
106  if ($MIDI_event_channel & 0x80) {
107  // OK, normal event - MIDI command has MSB set
108  $LastIssuedMIDIcommand = $MIDI_event_channel >> 4;
109  $LastIssuedMIDIchannel = $MIDI_event_channel & 0x0F;
110  } else {
111  // running event - assume last command
112  $eventsoffset--;
113  }
114  $MIDIevents[$tracknumber][$eventid]['eventid'] = $LastIssuedMIDIcommand;
115  $MIDIevents[$tracknumber][$eventid]['channel'] = $LastIssuedMIDIchannel;
116  if ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x08) { // Note off (key is released)
117 
118  $notenumber = ord(substr($trackdata, $eventsoffset++, 1));
119  $velocity = ord(substr($trackdata, $eventsoffset++, 1));
120 
121  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x09) { // Note on (key is pressed)
122 
123  $notenumber = ord(substr($trackdata, $eventsoffset++, 1));
124  $velocity = ord(substr($trackdata, $eventsoffset++, 1));
125 
126  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0A) { // Key after-touch
127 
128  $notenumber = ord(substr($trackdata, $eventsoffset++, 1));
129  $velocity = ord(substr($trackdata, $eventsoffset++, 1));
130 
131  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0B) { // Control Change
132 
133  $controllernum = ord(substr($trackdata, $eventsoffset++, 1));
134  $newvalue = ord(substr($trackdata, $eventsoffset++, 1));
135 
136  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0C) { // Program (patch) change
137 
138  $newprogramnum = ord(substr($trackdata, $eventsoffset++, 1));
139 
140  $thisfile_midi_raw['track'][$tracknumber]['instrumentid'] = $newprogramnum;
141  if ($tracknumber == 10) {
142  $thisfile_midi_raw['track'][$tracknumber]['instrument'] = $this->GeneralMIDIpercussionLookup($newprogramnum);
143  } else {
144  $thisfile_midi_raw['track'][$tracknumber]['instrument'] = $this->GeneralMIDIinstrumentLookup($newprogramnum);
145  }
146 
147  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0D) { // Channel after-touch
148 
149  $channelnumber = ord(substr($trackdata, $eventsoffset++, 1));
150 
151  } elseif ($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0E) { // Pitch wheel change (2000H is normal or no change)
152 
153  $changeLSB = ord(substr($trackdata, $eventsoffset++, 1));
154  $changeMSB = ord(substr($trackdata, $eventsoffset++, 1));
155  $pitchwheelchange = (($changeMSB & 0x7F) << 7) & ($changeLSB & 0x7F);
156 
157  } elseif (($MIDIevents[$tracknumber][$eventid]['eventid'] == 0x0F) && ($MIDIevents[$tracknumber][$eventid]['channel'] == 0x0F)) {
158 
159  $METAeventCommand = ord(substr($trackdata, $eventsoffset++, 1));
160  $METAeventLength = ord(substr($trackdata, $eventsoffset++, 1));
161  $METAeventData = substr($trackdata, $eventsoffset, $METAeventLength);
162  $eventsoffset += $METAeventLength;
163  switch ($METAeventCommand) {
164  case 0x00: // Set track sequence number
165  $track_sequence_number = getid3_lib::BigEndian2Int(substr($METAeventData, 0, $METAeventLength));
166  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['seqno'] = $track_sequence_number;
167  break;
168 
169  case 0x01: // Text: generic
170  $text_generic = substr($METAeventData, 0, $METAeventLength);
171  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['text'] = $text_generic;
172  $thisfile_midi['comments']['comment'][] = $text_generic;
173  break;
174 
175  case 0x02: // Text: copyright
176  $text_copyright = substr($METAeventData, 0, $METAeventLength);
177  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['copyright'] = $text_copyright;
178  $thisfile_midi['comments']['copyright'][] = $text_copyright;
179  break;
180 
181  case 0x03: // Text: track name
182  $text_trackname = substr($METAeventData, 0, $METAeventLength);
183  $thisfile_midi_raw['track'][$tracknumber]['name'] = $text_trackname;
184  break;
185 
186  case 0x04: // Text: track instrument name
187  $text_instrument = substr($METAeventData, 0, $METAeventLength);
188  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['instrument'] = $text_instrument;
189  break;
190 
191  case 0x05: // Text: lyrics
192  $text_lyrics = substr($METAeventData, 0, $METAeventLength);
193  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['lyrics'] = $text_lyrics;
194  if (!isset($thisfile_midi['lyrics'])) {
195  $thisfile_midi['lyrics'] = '';
196  }
197  $thisfile_midi['lyrics'] .= $text_lyrics."\n";
198  break;
199 
200  case 0x06: // Text: marker
201  $text_marker = substr($METAeventData, 0, $METAeventLength);
202  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['marker'] = $text_marker;
203  break;
204 
205  case 0x07: // Text: cue point
206  $text_cuepoint = substr($METAeventData, 0, $METAeventLength);
207  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['cuepoint'] = $text_cuepoint;
208  break;
209 
210  case 0x2F: // End Of Track
211  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['EOT'] = $CumulativeDeltaTime;
212  break;
213 
214  case 0x51: // Tempo: microseconds / quarter note
215  $CurrentMicroSecondsPerBeat = getid3_lib::BigEndian2Int(substr($METAeventData, 0, $METAeventLength));
216  if ($CurrentMicroSecondsPerBeat == 0) {
217  $ThisFileInfo['error'][] = 'Corrupt MIDI file: CurrentMicroSecondsPerBeat == zero';
218  return false;
219  }
220  $thisfile_midi_raw['events'][$tracknumber][$CumulativeDeltaTime]['us_qnote'] = $CurrentMicroSecondsPerBeat;
221  $CurrentBeatsPerMinute = (1000000 / $CurrentMicroSecondsPerBeat) * 60;
222  $MicroSecondsPerQuarterNoteAfter[$CumulativeDeltaTime] = $CurrentMicroSecondsPerBeat;
223  $TicksAtCurrentBPM = 0;
224  break;
225 
226  case 0x58: // Time signature
227  $timesig_numerator = getid3_lib::BigEndian2Int($METAeventData{0});
228  $timesig_denominator = pow(2, getid3_lib::BigEndian2Int($METAeventData{1})); // $02 -> x/4, $03 -> x/8, etc
229  $timesig_32inqnote = getid3_lib::BigEndian2Int($METAeventData{2}); // number of 32nd notes to the quarter note
230  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_32inqnote'] = $timesig_32inqnote;
231  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_numerator'] = $timesig_numerator;
232  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_denominator'] = $timesig_denominator;
233  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['timesig_text'] = $timesig_numerator.'/'.$timesig_denominator;
234  $thisfile_midi['timesignature'][] = $timesig_numerator.'/'.$timesig_denominator;
235  break;
236 
237  case 0x59: // Keysignature
238  $keysig_sharpsflats = getid3_lib::BigEndian2Int($METAeventData{0});
239  if ($keysig_sharpsflats & 0x80) {
240  // (-7 -> 7 flats, 0 ->key of C, 7 -> 7 sharps)
241  $keysig_sharpsflats -= 256;
242  }
243 
244  $keysig_majorminor = getid3_lib::BigEndian2Int($METAeventData{1}); // 0 -> major, 1 -> minor
245  $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#');
246  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_sharps'] = (($keysig_sharpsflats > 0) ? abs($keysig_sharpsflats) : 0);
247  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_flats'] = (($keysig_sharpsflats < 0) ? abs($keysig_sharpsflats) : 0);
248  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_minor'] = (bool) $keysig_majorminor;
249  //$thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_text'] = $keysigs[$keysig_sharpsflats].' '.($thisfile_midi_raw['events'][$tracknumber][$eventid]['keysig_minor'] ? 'minor' : 'major');
250 
251  // $keysigs[$keysig_sharpsflats] gets an int key (correct) - $keysigs["$keysig_sharpsflats"] gets a string key (incorrect)
252  $thisfile_midi['keysignature'][] = $keysigs[$keysig_sharpsflats].' '.((bool) $keysig_majorminor ? 'minor' : 'major');
253  break;
254 
255  case 0x7F: // Sequencer specific information
256  $custom_data = substr($METAeventData, 0, $METAeventLength);
257  break;
258 
259  default:
260  $ThisFileInfo['warning'][] = 'Unhandled META Event Command: '.$METAeventCommand;
261  break;
262  }
263 
264  } else {
265 
266  $ThisFileInfo['warning'][] = 'Unhandled MIDI Event ID: '.$MIDIevents[$tracknumber][$eventid]['eventid'].' + Channel ID: '.$MIDIevents[$tracknumber][$eventid]['channel'];
267 
268  }
269  }
270  if (($tracknumber > 0) || (count($trackdataarray) == 1)) {
271  $thisfile_midi['totalticks'] = max($thisfile_midi['totalticks'], $CumulativeDeltaTime);
272  }
273  }
274  $previoustickoffset = null;
275 
276  ksort($MicroSecondsPerQuarterNoteAfter);
277  foreach ($MicroSecondsPerQuarterNoteAfter as $tickoffset => $microsecondsperbeat) {
278  if (is_null($previoustickoffset)) {
279  $prevmicrosecondsperbeat = $microsecondsperbeat;
280  $previoustickoffset = $tickoffset;
281  continue;
282  }
283  if ($thisfile_midi['totalticks'] > $tickoffset) {
284 
285  if ($thisfile_midi_raw['ticksperqnote'] == 0) {
286  $ThisFileInfo['error'][] = 'Corrupt MIDI file: ticksperqnote == zero';
287  return false;
288  }
289 
290  $ThisFileInfo['playtime_seconds'] += (($tickoffset - $previoustickoffset) / $thisfile_midi_raw['ticksperqnote']) * ($prevmicrosecondsperbeat / 1000000);
291 
292  $prevmicrosecondsperbeat = $microsecondsperbeat;
293  $previoustickoffset = $tickoffset;
294  }
295  }
296  if ($thisfile_midi['totalticks'] > $previoustickoffset) {
297 
298  if ($thisfile_midi_raw['ticksperqnote'] == 0) {
299  $ThisFileInfo['error'][] = 'Corrupt MIDI file: ticksperqnote == zero';
300  return false;
301  }
302 
303  $ThisFileInfo['playtime_seconds'] += (($thisfile_midi['totalticks'] - $previoustickoffset) / $thisfile_midi_raw['ticksperqnote']) * ($microsecondsperbeat / 1000000);
304 
305  }
306  }
307 
308  if ($ThisFileInfo['playtime_seconds'] > 0) {
309  $ThisFileInfo['bitrate'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds'];
310  }
311 
312  if (!empty($thisfile_midi['lyrics'])) {
313  $thisfile_midi['comments']['lyrics'][] = $thisfile_midi['lyrics'];
314  }
315 
316  return true;
317  }
const GETID3_FREAD_BUFFER_SIZE
Definition: getid3.php:14
GeneralMIDIinstrumentLookup($instrumentid)
GeneralMIDIpercussionLookup($instrumentid)
fread($bytes)
Definition: getid3.php:1685
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
+ Here is the call graph for this function:

Field Documentation

◆ $scanwholefile

getid3_midi::$scanwholefile = true

Definition at line 22 of file module.audio.midi.php.

Referenced by getid3_midi().


The documentation for this class was generated from the following file: