28 $ThisFileInfo[
'riff'] = array(
'raw'=>array());
31 $thisfile_riff = &$ThisFileInfo[
'riff'];
32 $thisfile_riff_raw = &$thisfile_riff[
'raw'];
33 $thisfile_audio = &$ThisFileInfo[
'audio'];
34 $thisfile_video = &$ThisFileInfo[
'video'];
35 $thisfile_avdataoffset = &$ThisFileInfo[
'avdataoffset'];
36 $thisfile_avdataend = &$ThisFileInfo[
'avdataend'];
37 $thisfile_audio_dataformat = &$thisfile_audio[
'dataformat'];
38 $thisfile_riff_audio = &$thisfile_riff[
'audio'];
39 $thisfile_riff_video = &$thisfile_riff[
'video'];
42 $Original[
'avdataoffset'] = $thisfile_avdataoffset;
43 $Original[
'avdataend'] = $thisfile_avdataend;
45 fseek($fd, $thisfile_avdataoffset, SEEK_SET);
46 $RIFFheader = fread($fd, 12);
47 $RIFFsubtype = substr($RIFFheader, 8, 4);
48 switch (substr($RIFFheader, 0, 4)) {
50 $ThisFileInfo[
'fileformat'] =
'aiff';
52 $thisfile_riff[$RIFFsubtype] =
getid3_riff::ParseRIFF($fd, $thisfile_avdataoffset + 12, $thisfile_avdataoffset + $RIFFheaderSize, $ThisFileInfo);
53 $thisfile_riff[
'header_size'] = $RIFFheaderSize;
59 if ($RIFFsubtype ==
'RMP3') {
61 $RIFFsubtype =
'WAVE';
64 $ThisFileInfo[
'fileformat'] =
'riff';
66 $thisfile_riff[$RIFFsubtype] =
getid3_riff::ParseRIFF($fd, $thisfile_avdataoffset + 12, $thisfile_avdataoffset + $RIFFheaderSize, $ThisFileInfo);
67 $thisfile_riff[
'header_size'] = $RIFFheaderSize;
68 if ($RIFFsubtype ==
'WAVE') {
69 $thisfile_riff_WAVE = &$thisfile_riff[
'WAVE'];
74 $ThisFileInfo[
'error'][] =
'Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.
'" instead';
75 unset($ThisFileInfo[
'fileformat']);
81 switch ($RIFFsubtype) {
83 if (empty($thisfile_audio[
'bitrate_mode'])) {
84 $thisfile_audio[
'bitrate_mode'] =
'cbr';
86 if (empty($thisfile_audio_dataformat)) {
87 $thisfile_audio_dataformat =
'wav';
90 if (isset($thisfile_riff_WAVE[
'data'][0][
'offset'])) {
91 $thisfile_avdataoffset = $thisfile_riff_WAVE[
'data'][0][
'offset'] + 8;
92 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff_WAVE[
'data'][0][
'size'];
94 if (isset($thisfile_riff_WAVE[
'fmt '][0][
'data'])) {
97 $thisfile_audio[
'wformattag'] = $thisfile_riff_audio[$streamindex][
'raw'][
'wFormatTag'];
98 if (@$thisfile_riff_audio[$streamindex][
'bitrate'] == 0) {
99 $ThisFileInfo[
'error'][] =
'Corrupt RIFF file: bitrate_audio == zero';
102 $thisfile_riff_raw[
'fmt '] = $thisfile_riff_audio[$streamindex][
'raw'];
103 unset($thisfile_riff_audio[$streamindex][
'raw']);
104 $thisfile_audio[
'streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
107 if (substr($thisfile_audio[
'codec'], 0, strlen(
'unknown: 0x')) ==
'unknown: 0x') {
108 $ThisFileInfo[
'warning'][] =
'Audio codec = '.$thisfile_audio[
'codec'];
110 $thisfile_audio[
'bitrate'] = $thisfile_riff_audio[$streamindex][
'bitrate'];
112 $ThisFileInfo[
'playtime_seconds'] = (float) ((($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $thisfile_audio[
'bitrate']);
114 $thisfile_audio[
'lossless'] =
false;
115 if (isset($thisfile_riff_WAVE[
'data'][0][
'offset']) && isset($thisfile_riff_raw[
'fmt '][
'wFormatTag'])) {
116 switch ($thisfile_riff_raw[
'fmt '][
'wFormatTag']) {
119 $thisfile_audio[
'lossless'] =
true;
123 $thisfile_audio_dataformat =
'ac3';
132 $thisfile_audio[
'streams'][$streamindex][
'wformattag'] = $thisfile_audio[
'wformattag'];
133 $thisfile_audio[
'streams'][$streamindex][
'bitrate_mode'] = $thisfile_audio[
'bitrate_mode'];
134 $thisfile_audio[
'streams'][$streamindex][
'lossless'] = $thisfile_audio[
'lossless'];
135 $thisfile_audio[
'streams'][$streamindex][
'dataformat'] = $thisfile_audio_dataformat;
138 if (isset($thisfile_riff_WAVE[
'rgad'][0][
'data'])) {
141 $rgadData = &$thisfile_riff_WAVE[
'rgad'][0][
'data'];
142 $thisfile_riff_raw[
'rgad'] = array(
'track'=>array(),
'album'=>array());
143 $thisfile_riff_raw_rgad = &$thisfile_riff_raw[
'rgad'];
144 $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad[
'track'];
145 $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad[
'album'];
151 $nRadioRgAdjustBitstring = str_pad(
getid3_lib::Dec2Bin($thisfile_riff_raw_rgad[
'nRadioRgAdjust']), 16,
'0', STR_PAD_LEFT);
152 $nAudiophileRgAdjustBitstring = str_pad(
getid3_lib::Dec2Bin($thisfile_riff_raw_rgad[
'nAudiophileRgAdjust']), 16,
'0', STR_PAD_LEFT);
153 $thisfile_riff_raw_rgad_track[
'name'] =
getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3));
154 $thisfile_riff_raw_rgad_track[
'originator'] =
getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3));
155 $thisfile_riff_raw_rgad_track[
'signbit'] =
getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1));
156 $thisfile_riff_raw_rgad_track[
'adjustment'] =
getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9));
157 $thisfile_riff_raw_rgad_album[
'name'] =
getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3));
158 $thisfile_riff_raw_rgad_album[
'originator'] =
getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3));
159 $thisfile_riff_raw_rgad_album[
'signbit'] =
getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1));
160 $thisfile_riff_raw_rgad_album[
'adjustment'] =
getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9));
162 $thisfile_riff[
'rgad'][
'peakamplitude'] = $thisfile_riff_raw_rgad[
'fPeakAmplitude'];
163 if (($thisfile_riff_raw_rgad_track[
'name'] != 0) && ($thisfile_riff_raw_rgad_track[
'originator'] != 0)) {
166 $thisfile_riff[
'rgad'][
'track'][
'adjustment'] =
getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track[
'adjustment'], $thisfile_riff_raw_rgad_track[
'signbit']);
168 if (($thisfile_riff_raw_rgad_album[
'name'] != 0) && ($thisfile_riff_raw_rgad_album[
'originator'] != 0)) {
171 $thisfile_riff[
'rgad'][
'album'][
'adjustment'] =
getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album[
'adjustment'], $thisfile_riff_raw_rgad_album[
'signbit']);
175 if (isset($thisfile_riff_WAVE[
'fact'][0][
'data'])) {
176 $thisfile_riff_raw[
'fact'][
'NumberOfSamples'] =
getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_WAVE[
'fact'][0][
'data'], 0, 4));
186 if (!empty($thisfile_riff_raw[
'fmt '][
'nAvgBytesPerSec'])) {
187 $thisfile_audio[
'bitrate'] =
getid3_lib::CastAsInt($thisfile_riff_raw[
'fmt '][
'nAvgBytesPerSec'] * 8);
190 if (isset($thisfile_riff_WAVE[
'bext'][0][
'data'])) {
192 $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE[
'bext'][0];
194 $thisfile_riff_WAVE_bext_0[
'title'] = trim(substr($thisfile_riff_WAVE_bext_0[
'data'], 0, 256));
195 $thisfile_riff_WAVE_bext_0[
'author'] = trim(substr($thisfile_riff_WAVE_bext_0[
'data'], 256, 32));
196 $thisfile_riff_WAVE_bext_0[
'reference'] = trim(substr($thisfile_riff_WAVE_bext_0[
'data'], 288, 32));
197 $thisfile_riff_WAVE_bext_0[
'origin_date'] = substr($thisfile_riff_WAVE_bext_0[
'data'], 320, 10);
198 $thisfile_riff_WAVE_bext_0[
'origin_time'] = substr($thisfile_riff_WAVE_bext_0[
'data'], 330, 8);
202 $thisfile_riff_WAVE_bext_0[
'coding_history'] = explode(
"\r\n", trim(substr($thisfile_riff_WAVE_bext_0[
'data'], 601)));
204 $thisfile_riff_WAVE_bext_0[
'origin_date_unix'] = gmmktime(
205 substr($thisfile_riff_WAVE_bext_0[
'origin_time'], 0, 2),
206 substr($thisfile_riff_WAVE_bext_0[
'origin_time'], 3, 2),
207 substr($thisfile_riff_WAVE_bext_0[
'origin_time'], 6, 2),
208 substr($thisfile_riff_WAVE_bext_0[
'origin_date'], 5, 2),
209 substr($thisfile_riff_WAVE_bext_0[
'origin_date'], 8, 2),
210 substr($thisfile_riff_WAVE_bext_0[
'origin_date'], 0, 4));
212 $thisfile_riff[
'comments'][
'author'][] = $thisfile_riff_WAVE_bext_0[
'author'];
213 $thisfile_riff[
'comments'][
'title'][] = $thisfile_riff_WAVE_bext_0[
'title'];
216 if (isset($thisfile_riff_WAVE[
'MEXT'][0][
'data'])) {
218 $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE[
'MEXT'][0];
220 $thisfile_riff_WAVE_MEXT_0[
'raw'][
'sound_information'] =
getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0[
'data'], 0, 2));
221 $thisfile_riff_WAVE_MEXT_0[
'flags'][
'homogenous'] = (bool) ($thisfile_riff_WAVE_MEXT_0[
'raw'][
'sound_information'] & 0x0001);
222 if ($thisfile_riff_WAVE_MEXT_0[
'flags'][
'homogenous']) {
223 $thisfile_riff_WAVE_MEXT_0[
'flags'][
'padding'] = ($thisfile_riff_WAVE_MEXT_0[
'raw'][
'sound_information'] & 0x0002) ?
false :
true;
224 $thisfile_riff_WAVE_MEXT_0[
'flags'][
'22_or_44'] = (bool) ($thisfile_riff_WAVE_MEXT_0[
'raw'][
'sound_information'] & 0x0004);
225 $thisfile_riff_WAVE_MEXT_0[
'flags'][
'free_format'] = (bool) ($thisfile_riff_WAVE_MEXT_0[
'raw'][
'sound_information'] & 0x0008);
230 $thisfile_riff_WAVE_MEXT_0[
'raw'][
'anciliary_data_def'] =
getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0[
'data'], 8, 2));
231 $thisfile_riff_WAVE_MEXT_0[
'flags'][
'anciliary_data_left'] = (bool) ($thisfile_riff_WAVE_MEXT_0[
'raw'][
'anciliary_data_def'] & 0x0001);
232 $thisfile_riff_WAVE_MEXT_0[
'flags'][
'anciliary_data_free'] = (bool) ($thisfile_riff_WAVE_MEXT_0[
'raw'][
'anciliary_data_def'] & 0x0002);
233 $thisfile_riff_WAVE_MEXT_0[
'flags'][
'anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0[
'raw'][
'anciliary_data_def'] & 0x0004);
236 if (isset($thisfile_riff_WAVE[
'cart'][0][
'data'])) {
238 $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE[
'cart'][0];
240 $thisfile_riff_WAVE_cart_0[
'version'] = substr($thisfile_riff_WAVE_cart_0[
'data'], 0, 4);
241 $thisfile_riff_WAVE_cart_0[
'title'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 4, 64));
242 $thisfile_riff_WAVE_cart_0[
'artist'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 68, 64));
243 $thisfile_riff_WAVE_cart_0[
'cut_id'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 132, 64));
244 $thisfile_riff_WAVE_cart_0[
'client_id'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 196, 64));
245 $thisfile_riff_WAVE_cart_0[
'category'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 260, 64));
246 $thisfile_riff_WAVE_cart_0[
'classification'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 324, 64));
247 $thisfile_riff_WAVE_cart_0[
'out_cue'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 388, 64));
248 $thisfile_riff_WAVE_cart_0[
'start_date'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 452, 10));
249 $thisfile_riff_WAVE_cart_0[
'start_time'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 462, 8));
250 $thisfile_riff_WAVE_cart_0[
'end_date'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 470, 10));
251 $thisfile_riff_WAVE_cart_0[
'end_time'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 480, 8));
252 $thisfile_riff_WAVE_cart_0[
'producer_app_id'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 488, 64));
253 $thisfile_riff_WAVE_cart_0[
'producer_app_version'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 552, 64));
254 $thisfile_riff_WAVE_cart_0[
'user_defined_text'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 616, 64));
255 $thisfile_riff_WAVE_cart_0[
'zero_db_reference'] =
getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0[
'data'], 680, 4),
true);
256 for ($i = 0; $i < 8; $i++) {
257 $thisfile_riff_WAVE_cart_0[
'post_time'][$i][
'usage_fourcc'] = substr($thisfile_riff_WAVE_cart_0[
'data'], 684 + ($i * 8), 4);
258 $thisfile_riff_WAVE_cart_0[
'post_time'][$i][
'timer_value'] =
getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0[
'data'], 684 + ($i * 8) + 4, 4));
260 $thisfile_riff_WAVE_cart_0[
'url'] = trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 748, 1024));
261 $thisfile_riff_WAVE_cart_0[
'tag_text'] = explode(
"\r\n", trim(substr($thisfile_riff_WAVE_cart_0[
'data'], 1772)));
263 $thisfile_riff[
'comments'][
'artist'][] = $thisfile_riff_WAVE_cart_0[
'artist'];
264 $thisfile_riff[
'comments'][
'title'][] = $thisfile_riff_WAVE_cart_0[
'title'];
267 if (!isset($thisfile_audio[
'bitrate']) && isset($thisfile_riff_audio[$streamindex][
'bitrate'])) {
268 $thisfile_audio[
'bitrate'] = $thisfile_riff_audio[$streamindex][
'bitrate'];
269 $ThisFileInfo[
'playtime_seconds'] = (float) ((($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $thisfile_audio[
'bitrate']);
272 if (!empty($ThisFileInfo[
'wavpack'])) {
273 $thisfile_audio_dataformat =
'wavpack';
274 $thisfile_audio[
'bitrate_mode'] =
'vbr';
275 $thisfile_audio[
'encoder'] =
'WavPack v'.$ThisFileInfo[
'wavpack'][
'version'];
278 $thisfile_avdataend = $Original[
'avdataend'];
279 $thisfile_audio[
'bitrate'] = (($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $ThisFileInfo[
'playtime_seconds'];
281 fseek($fd, $thisfile_avdataoffset - 44, SEEK_SET);
282 $RIFFdata = fread($fd, 44);
286 if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
287 $thisfile_avdataend -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
288 fseek($fd, $thisfile_avdataend, SEEK_SET);
289 $RIFFdata .= fread($fd, $OrignalRIFFheaderSize - $OrignalRIFFdataSize);
295 $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8);
299 if (isset($thisfile_riff_raw[
'fmt '][
'wFormatTag'])) {
300 switch ($thisfile_riff_raw[
'fmt '][
'wFormatTag']) {
302 $thisfile_audio[
'bitrate_mode'] =
'vbr';
303 $thisfile_audio_dataformat =
'litewave';
322 $thisfile_riff[
'litewave'][
'raw'] = array();
323 $thisfile_riff_litewave = &$thisfile_riff[
'litewave'];
324 $thisfile_riff_litewave_raw = &$thisfile_riff_litewave[
'raw'];
326 $thisfile_riff_litewave_raw[
'compression_method'] =
getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE[
'fmt '][0][
'data'], 18, 1));
338 $thisfile_riff_litewave[
'quality_factor'] = $thisfile_riff_litewave_raw[
'm_wQuality'];
340 $thisfile_riff_litewave[
'flags'][
'raw_source'] = ($thisfile_riff_litewave_raw[
'compression_flags'] & 0x01) ?
false :
true;
341 $thisfile_riff_litewave[
'flags'][
'vbr_blocksize'] = ($thisfile_riff_litewave_raw[
'compression_flags'] & 0x02) ?
false :
true;
342 $thisfile_riff_litewave[
'flags'][
'seekpoints'] = (bool) ($thisfile_riff_litewave_raw[
'compression_flags'] & 0x04);
344 $thisfile_audio[
'lossless'] = (($thisfile_riff_litewave_raw[
'm_wQuality'] == 100) ?
true :
false);
345 $thisfile_audio[
'encoder_options'] =
'-q'.$thisfile_riff_litewave[
'quality_factor'];
352 if ($thisfile_avdataend > $ThisFileInfo[
'filesize']) {
353 switch (@$thisfile_audio_dataformat) {
362 if (($thisfile_avdataend - $ThisFileInfo[
'filesize']) == 1) {
368 $ThisFileInfo[
'warning'][] =
'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype][
'data'][0][
'size'].
' bytes of data, only found '.($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset).
' (short by '.($thisfile_riff[$RIFFsubtype][
'data'][0][
'size'] - ($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset)).
' bytes)';
369 $thisfile_avdataend = $ThisFileInfo[
'filesize'];
374 if ((($thisfile_avdataend - $ThisFileInfo[
'filesize']) == 1) && (($thisfile_riff[$RIFFsubtype][
'data'][0][
'size'] % 2) == 0) && ((($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset) % 2) == 1)) {
377 $ThisFileInfo[
'warning'][] =
'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype][
'data'][0][
'size'].
' bytes of data, only found '.($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset).
' therefore short by '.($thisfile_riff[$RIFFsubtype][
'data'][0][
'size'] - ($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset)).
' bytes)';
378 $thisfile_avdataend = $ThisFileInfo[
'filesize'];
382 $ThisFileInfo[
'warning'][] =
'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype][
'data'][0][
'size'].
' bytes of data, only found '.($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset).
' (short by '.($thisfile_riff[$RIFFsubtype][
'data'][0][
'size'] - ($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset)).
' bytes)';
383 $thisfile_avdataend = $ThisFileInfo[
'filesize'];
387 if (!empty($ThisFileInfo[
'mpeg'][
'audio'][
'LAME'][
'audio_bytes'])) {
388 if ((($thisfile_avdataend - $thisfile_avdataoffset) - $ThisFileInfo[
'mpeg'][
'audio'][
'LAME'][
'audio_bytes']) == 1) {
389 $thisfile_avdataend--;
390 $ThisFileInfo[
'warning'][] =
'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
393 if (@$thisfile_audio_dataformat ==
'ac3') {
394 unset($thisfile_audio[
'bits_per_sample']);
395 if (!empty($ThisFileInfo[
'ac3'][
'bitrate']) && ($ThisFileInfo[
'ac3'][
'bitrate'] != $thisfile_audio[
'bitrate'])) {
396 $thisfile_audio[
'bitrate'] = $ThisFileInfo[
'ac3'][
'bitrate'];
402 $thisfile_video[
'bitrate_mode'] =
'vbr';
403 $thisfile_video[
'dataformat'] =
'avi';
404 $ThisFileInfo[
'mime_type'] =
'video/avi';
406 if (isset($thisfile_riff[$RIFFsubtype][
'movi'][
'offset'])) {
407 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype][
'movi'][
'offset'] + 8;
408 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype][
'movi'][
'size'];
409 if ($thisfile_avdataend > $ThisFileInfo[
'filesize']) {
410 $ThisFileInfo[
'warning'][] =
'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype][
'movi'][
'size'].
' bytes of data, only found '.($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset).
' (short by '.($thisfile_riff[$RIFFsubtype][
'movi'][
'size'] - ($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset)).
' bytes)';
411 $thisfile_avdataend = $ThisFileInfo[
'filesize'];
415 if (isset($thisfile_riff[
'AVI '][
'hdrl'][
'avih'][$streamindex][
'data'])) {
416 $avihData = $thisfile_riff[
'AVI '][
'hdrl'][
'avih'][$streamindex][
'data'];
419 $thisfile_riff_raw[
'avih'] = array();
420 $thisfile_riff_raw_avih = &$thisfile_riff_raw[
'avih'];
423 if ($thisfile_riff_raw_avih[
'dwMicroSecPerFrame'] == 0) {
424 $ThisFileInfo[
'error'][] =
'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
441 $thisfile_riff_raw_avih[
'flags'][
'hasindex'] = (bool) ($thisfile_riff_raw_avih[
'dwFlags'] & 0x00000010);
442 $thisfile_riff_raw_avih[
'flags'][
'mustuseindex'] = (bool) ($thisfile_riff_raw_avih[
'dwFlags'] & 0x00000020);
443 $thisfile_riff_raw_avih[
'flags'][
'interleaved'] = (bool) ($thisfile_riff_raw_avih[
'dwFlags'] & 0x00000100);
444 $thisfile_riff_raw_avih[
'flags'][
'trustcktype'] = (bool) ($thisfile_riff_raw_avih[
'dwFlags'] & 0x00000800);
445 $thisfile_riff_raw_avih[
'flags'][
'capturedfile'] = (bool) ($thisfile_riff_raw_avih[
'dwFlags'] & 0x00010000);
446 $thisfile_riff_raw_avih[
'flags'][
'copyrighted'] = (bool) ($thisfile_riff_raw_avih[
'dwFlags'] & 0x00020010);
449 $thisfile_riff_video[$streamindex] = array();
450 $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
452 if ($thisfile_riff_raw_avih[
'dwWidth'] > 0) {
453 $thisfile_riff_video_current[
'frame_width'] = $thisfile_riff_raw_avih[
'dwWidth'];
454 $thisfile_video[
'resolution_x'] = $thisfile_riff_video_current[
'frame_width'];
456 if ($thisfile_riff_raw_avih[
'dwHeight'] > 0) {
457 $thisfile_riff_video_current[
'frame_height'] = $thisfile_riff_raw_avih[
'dwHeight'];
458 $thisfile_video[
'resolution_y'] = $thisfile_riff_video_current[
'frame_height'];
460 if ($thisfile_riff_raw_avih[
'dwTotalFrames'] > 0) {
461 $thisfile_riff_video_current[
'total_frames'] = $thisfile_riff_raw_avih[
'dwTotalFrames'];
462 $thisfile_video[
'total_frames'] = $thisfile_riff_video_current[
'total_frames'];
465 $thisfile_riff_video_current[
'frame_rate'] = round(1000000 / $thisfile_riff_raw_avih[
'dwMicroSecPerFrame'], 3);
466 $thisfile_video[
'frame_rate'] = $thisfile_riff_video_current[
'frame_rate'];
468 if (isset($thisfile_riff[
'AVI '][
'hdrl'][
'strl'][
'strh'][0][
'data'])) {
469 if (is_array($thisfile_riff[
'AVI '][
'hdrl'][
'strl'][
'strh'])) {
470 for ($i = 0; $i < count($thisfile_riff[
'AVI '][
'hdrl'][
'strl'][
'strh']); $i++) {
471 if (isset($thisfile_riff[
'AVI '][
'hdrl'][
'strl'][
'strh'][$i][
'data'])) {
472 $strhData = $thisfile_riff[
'AVI '][
'hdrl'][
'strl'][
'strh'][$i][
'data'];
473 $strhfccType = substr($strhData, 0, 4);
475 if (isset($thisfile_riff[
'AVI '][
'hdrl'][
'strl'][
'strf'][$i][
'data'])) {
476 $strfData = $thisfile_riff[
'AVI '][
'hdrl'][
'strl'][
'strf'][$i][
'data'];
479 $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw[
'strf'][$strhfccType][$streamindex];
481 switch ($strhfccType) {
483 $thisfile_audio[
'bitrate_mode'] =
'cbr';
484 $thisfile_audio_dataformat =
'wav';
485 if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) {
486 $streamindex = count($thisfile_riff_audio);
490 $thisfile_audio[
'wformattag'] = $thisfile_riff_audio[$streamindex][
'raw'][
'wFormatTag'];
493 $thisfile_audio[
'streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
494 $thisfile_audio_streams_currentstream = &$thisfile_audio[
'streams'][$streamindex];
496 if ($thisfile_audio_streams_currentstream[
'bits_per_sample'] == 0) {
497 unset($thisfile_audio_streams_currentstream[
'bits_per_sample']);
499 $thisfile_audio_streams_currentstream[
'wformattag'] = $thisfile_audio_streams_currentstream[
'raw'][
'wFormatTag'];
500 unset($thisfile_audio_streams_currentstream[
'raw']);
503 $thisfile_riff_raw[
'strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex][
'raw'];
505 unset($thisfile_riff_audio[$streamindex][
'raw']);
508 $thisfile_audio[
'lossless'] =
false;
509 switch ($thisfile_riff_raw_strf_strhfccType_streamindex[
'wFormatTag']) {
511 $thisfile_audio_dataformat =
'wav';
512 $thisfile_audio[
'lossless'] =
true;
516 $thisfile_audio_dataformat =
'mp2';
520 $thisfile_audio_dataformat =
'mp3';
524 $thisfile_audio_dataformat =
'aac';
530 $thisfile_audio_dataformat =
'wma';
534 $thisfile_audio_dataformat =
'ac3';
538 $thisfile_audio_dataformat =
'dts';
542 $thisfile_audio_dataformat =
'wav';
545 $thisfile_audio_streams_currentstream[
'dataformat'] = $thisfile_audio_dataformat;
546 $thisfile_audio_streams_currentstream[
'lossless'] = $thisfile_audio[
'lossless'];
547 $thisfile_audio_streams_currentstream[
'bitrate_mode'] = $thisfile_audio[
'bitrate_mode'];
554 $thisfile_riff_raw[
'strh'][$i] = array();
555 $thisfile_riff_raw_strh_current = &$thisfile_riff_raw[
'strh'][$i];
557 $thisfile_riff_raw_strh_current[
'fccType'] = substr($strhData, 0, 4);
558 $thisfile_riff_raw_strh_current[
'fccHandler'] = substr($strhData, 4, 4);
573 $thisfile_video[
'fourcc'] = $thisfile_riff_raw_strh_current[
'fccHandler'];
574 if (!$thisfile_riff_video_current[
'codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex[
'fourcc']) &&
getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex[
'fourcc'])) {
576 $thisfile_video[
'fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex[
'fourcc'];
578 $thisfile_video[
'codec'] = $thisfile_riff_video_current[
'codec'];
579 $thisfile_video[
'pixel_aspect_ratio'] = (float) 1;
580 switch ($thisfile_riff_raw_strh_current[
'fccHandler']) {
584 $thisfile_video[
'lossless'] =
true;
588 $thisfile_video[
'lossless'] =
false;
592 switch ($strhfccType) {
599 $thisfile_riff_raw_strf_strhfccType_streamindex[
'fourcc'] = substr($strfData, 16, 4);
606 $thisfile_video[
'bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex[
'biBitCount'];
608 if ($thisfile_riff_video_current[
'codec'] ==
'DV') {
609 $thisfile_riff_video_current[
'dv_type'] = 2;
614 $thisfile_riff_video_current[
'dv_type'] = 1;
620 $ThisFileInfo[
'warning'][] =
'Unhandled fccType for stream ('.$i.
'): "'.$strhfccType.
'"';
627 if (isset($thisfile_riff_raw_strf_strhfccType_streamindex[
'fourcc']) &&
getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex[
'fourcc'])) {
630 $thisfile_video[
'codec'] = $thisfile_riff_video_current[
'codec'];
631 $thisfile_video[
'fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex[
'fourcc'];
633 switch ($thisfile_riff_raw_strf_strhfccType_streamindex[
'fourcc']) {
637 $thisfile_video[
'lossless'] =
true;
638 $thisfile_video[
'bits_per_sample'] = 24;
642 $thisfile_video[
'lossless'] =
false;
643 $thisfile_video[
'bits_per_sample'] = 24;
654 $thisfile_audio[
'bitrate_mode'] =
'cbr';
655 $thisfile_audio_dataformat =
'cda';
656 $thisfile_audio[
'lossless'] =
true;
657 unset($ThisFileInfo[
'mime_type']);
659 $thisfile_avdataoffset = 44;
661 if (isset($thisfile_riff[
'CDDA'][
'fmt '][0][
'data'])) {
663 $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff[
'CDDA'][
'fmt '][0];
668 $thisfile_riff_CDDA_fmt_0[
'start_offset_frame'] =
getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0[
'data'], 8, 4));
669 $thisfile_riff_CDDA_fmt_0[
'playtime_frames'] =
getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0[
'data'], 12, 4));
673 $thisfile_riff_CDDA_fmt_0[
'start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0[
'start_offset_frame'] / 75;
674 $thisfile_riff_CDDA_fmt_0[
'playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0[
'playtime_frames'] / 75;
675 $ThisFileInfo[
'comments'][
'track'] = $thisfile_riff_CDDA_fmt_0[
'track_num'];
676 $ThisFileInfo[
'playtime_seconds'] = $thisfile_riff_CDDA_fmt_0[
'playtime_seconds'];
679 $thisfile_audio[
'sample_rate'] = 44100;
680 $thisfile_audio[
'channels'] = 2;
681 $thisfile_audio[
'bits_per_sample'] = 16;
682 $thisfile_audio[
'bitrate'] = $thisfile_audio[
'sample_rate'] * $thisfile_audio[
'channels'] * $thisfile_audio[
'bits_per_sample'];
683 $thisfile_audio[
'bitrate_mode'] =
'cbr';
690 $thisfile_audio[
'bitrate_mode'] =
'cbr';
691 $thisfile_audio_dataformat =
'aiff';
692 $thisfile_audio[
'lossless'] =
true;
693 $ThisFileInfo[
'mime_type'] =
'audio/x-aiff';
695 if (isset($thisfile_riff[$RIFFsubtype][
'SSND'][0][
'offset'])) {
696 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype][
'SSND'][0][
'offset'] + 8;
697 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype][
'SSND'][0][
'size'];
698 if ($thisfile_avdataend > $ThisFileInfo[
'filesize']) {
699 if (($thisfile_avdataend == ($ThisFileInfo[
'filesize'] + 1)) && (($ThisFileInfo[
'filesize'] % 2) == 1)) {
703 $ThisFileInfo[
'warning'][] =
'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype][
'SSND'][0][
'size'].
' bytes of audio data, only '.($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset).
' bytes found';
705 $thisfile_avdataend = $ThisFileInfo[
'filesize'];
709 if (isset($thisfile_riff[$RIFFsubtype][
'COMM'][0][
'data'])) {
712 $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype][
'COMM'][0][
'data'];
714 $thisfile_riff_audio[
'channels'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 0, 2),
true);
715 $thisfile_riff_audio[
'total_samples'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 2, 4),
false);
716 $thisfile_riff_audio[
'bits_per_sample'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 6, 2),
true);
719 if ($thisfile_riff[$RIFFsubtype][
'COMM'][0][
'size'] > 18) {
720 $thisfile_riff_audio[
'codec_fourcc'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18, 4);
722 $thisfile_riff_audio[
'codec_name'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23, $CodecNameSize);
723 switch ($thisfile_riff_audio[
'codec_name']) {
725 $thisfile_audio[
'codec'] =
'Pulse Code Modulation (PCM)';
726 $thisfile_audio[
'lossless'] =
true;
730 switch ($thisfile_riff_audio[
'codec_fourcc']) {
733 $thisfile_riff_audio[
'codec_name'] =
'Two\'s Compliment Little-Endian PCM';
734 $thisfile_audio[
'lossless'] =
true;
738 $thisfile_riff_audio[
'codec_name'] =
'Two\'s Compliment Big-Endian PCM';
739 $thisfile_audio[
'lossless'] =
true;
748 $thisfile_audio[
'codec'] = $thisfile_riff_audio[
'codec_name'];
749 $thisfile_audio[
'lossless'] =
false;
754 $thisfile_audio[
'channels'] = $thisfile_riff_audio[
'channels'];
755 if ($thisfile_riff_audio[
'bits_per_sample'] > 0) {
756 $thisfile_audio[
'bits_per_sample'] = $thisfile_riff_audio[
'bits_per_sample'];
758 $thisfile_audio[
'sample_rate'] = $thisfile_riff_audio[
'sample_rate'];
759 if ($thisfile_audio[
'sample_rate'] == 0) {
760 $ThisFileInfo[
'error'][] =
'Corrupted AIFF file: sample_rate == zero';
763 $ThisFileInfo[
'playtime_seconds'] = $thisfile_riff_audio[
'total_samples'] / $thisfile_audio[
'sample_rate'];
766 if (isset($thisfile_riff[$RIFFsubtype][
'COMT'])) {
770 for ($i = 0; $i < $CommentCount; $i++) {
771 $ThisFileInfo[
'comments_raw'][$i][
'timestamp'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype][
'COMT'][0][
'data'], $offset, 4),
false);
773 $ThisFileInfo[
'comments_raw'][$i][
'marker_id'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype][
'COMT'][0][
'data'], $offset, 2),
true);
777 $ThisFileInfo[
'comments_raw'][$i][
'comment'] = substr($thisfile_riff[$RIFFsubtype][
'COMT'][0][
'data'], $offset, $CommentLength);
778 $offset += $CommentLength;
780 $ThisFileInfo[
'comments_raw'][$i][
'timestamp_unix'] =
getid3_lib::DateMac2Unix($ThisFileInfo[
'comments_raw'][$i][
'timestamp']);
781 $thisfile_riff[
'comments'][
'comment'][] = $ThisFileInfo[
'comments_raw'][$i][
'comment'];
785 $CommentsChunkNames = array(
'NAME'=>
'title',
'author'=>
'artist',
'(c) '=>
'copyright',
'ANNO'=>
'comment');
786 foreach ($CommentsChunkNames as $key => $value) {
787 if (isset($thisfile_riff[$RIFFsubtype][$key][0][
'data'])) {
788 $thisfile_riff[
'comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0][
'data'];
794 $thisfile_audio[
'bitrate_mode'] =
'cbr';
795 $thisfile_audio_dataformat =
'8svx';
796 $thisfile_audio[
'bits_per_sample'] = 8;
797 $thisfile_audio[
'channels'] = 1;
798 $ThisFileInfo[
'mime_type'] =
'audio/x-aiff';
800 if (isset($thisfile_riff[$RIFFsubtype][
'BODY'][0][
'offset'])) {
801 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype][
'BODY'][0][
'offset'] + 8;
802 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype][
'BODY'][0][
'size'];
803 if ($thisfile_avdataend > $ThisFileInfo[
'filesize']) {
804 $ThisFileInfo[
'warning'][] =
'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype][
'BODY'][0][
'size'].
' bytes of audio data, only '.($ThisFileInfo[
'filesize'] - $thisfile_avdataoffset).
' bytes found';
808 if (isset($thisfile_riff[$RIFFsubtype][
'VHDR'][0][
'offset'])) {
810 $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype][
'VHDR'][0];
812 $thisfile_riff_RIFFsubtype_VHDR_0[
'oneShotHiSamples'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0[
'data'], 0, 4));
813 $thisfile_riff_RIFFsubtype_VHDR_0[
'repeatHiSamples'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0[
'data'], 4, 4));
814 $thisfile_riff_RIFFsubtype_VHDR_0[
'samplesPerHiCycle'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0[
'data'], 8, 4));
815 $thisfile_riff_RIFFsubtype_VHDR_0[
'samplesPerSec'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0[
'data'], 12, 2));
816 $thisfile_riff_RIFFsubtype_VHDR_0[
'ctOctave'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0[
'data'], 14, 1));
817 $thisfile_riff_RIFFsubtype_VHDR_0[
'sCompression'] =
getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0[
'data'], 15, 1));
818 $thisfile_riff_RIFFsubtype_VHDR_0[
'Volume'] =
getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0[
'data'], 16, 4));
820 $thisfile_audio[
'sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0[
'samplesPerSec'];
822 switch ($thisfile_riff_RIFFsubtype_VHDR_0[
'sCompression']) {
824 $thisfile_audio[
'codec'] =
'Pulse Code Modulation (PCM)';
825 $thisfile_audio[
'lossless'] =
true;
826 $ActualBitsPerSample = 8;
830 $thisfile_audio[
'codec'] =
'Fibonacci-delta encoding';
831 $thisfile_audio[
'lossless'] =
false;
832 $ActualBitsPerSample = 4;
836 $ThisFileInfo[
'warning'][] =
'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.
'"';
841 if (isset($thisfile_riff[$RIFFsubtype][
'CHAN'][0][
'data'])) {
843 switch ($ChannelsIndex) {
845 $thisfile_audio[
'channels'] = 2;
850 $thisfile_audio[
'channels'] = 1;
854 $ThisFileInfo[
'warning'][] =
'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.
'"';
860 $CommentsChunkNames = array(
'NAME'=>
'title',
'author'=>
'artist',
'(c) '=>
'copyright',
'ANNO'=>
'comment');
861 foreach ($CommentsChunkNames as $key => $value) {
862 if (isset($thisfile_riff[$RIFFsubtype][$key][0][
'data'])) {
863 $thisfile_riff[
'comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0][
'data'];
867 $thisfile_audio[
'bitrate'] = $thisfile_audio[
'sample_rate'] * $ActualBitsPerSample * $thisfile_audio[
'channels'];
868 if (!empty($thisfile_audio[
'bitrate'])) {
869 $ThisFileInfo[
'playtime_seconds'] = ($thisfile_avdataend - $thisfile_avdataoffset) / ($thisfile_audio[
'bitrate'] / 8);
875 $ThisFileInfo[
'mime_type'] =
'video/mpeg';
876 if (!empty($thisfile_riff[
'CDXA'][
'data'][0][
'size'])) {
877 $GETID3_ERRORARRAY = &$ThisFileInfo[
'warning'];
879 $dummy = $ThisFileInfo;
880 $dummy[
'error'] = array();
882 if (empty($dummy[
'error'])) {
883 $ThisFileInfo[
'audio'] = $dummy[
'audio'];
884 $ThisFileInfo[
'video'] = $dummy[
'video'];
885 $ThisFileInfo[
'mpeg'] = $dummy[
'mpeg'];
886 $ThisFileInfo[
'warning'] = $dummy[
'warning'];
894 $ThisFileInfo[
'error'][] =
'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.
'" instead';
895 unset($ThisFileInfo[
'fileformat']);
899 if (isset($thisfile_riff_WAVE[
'DISP']) && is_array($thisfile_riff_WAVE[
'DISP'])) {
900 $thisfile_riff[
'comments'][
'title'][] = trim(substr($thisfile_riff_WAVE[
'DISP'][count($thisfile_riff_WAVE[
'DISP']) - 1][
'data'], 4));
902 if (isset($thisfile_riff_WAVE[
'INFO']) && is_array($thisfile_riff_WAVE[
'INFO'])) {
903 $this->
RIFFcommentsParse($thisfile_riff_WAVE[
'INFO'], $thisfile_riff[
'comments']);
906 if (empty($thisfile_audio[
'encoder']) && !empty($ThisFileInfo[
'mpeg'][
'audio'][
'LAME'][
'short_version'])) {
907 $thisfile_audio[
'encoder'] = $ThisFileInfo[
'mpeg'][
'audio'][
'LAME'][
'short_version'];
910 if (!isset($ThisFileInfo[
'playtime_seconds'])) {
911 $ThisFileInfo[
'playtime_seconds'] = 0;
913 if (isset($thisfile_riff_raw[
'avih'][
'dwTotalFrames']) && isset($thisfile_riff_raw[
'avih'][
'dwMicroSecPerFrame'])) {
914 $ThisFileInfo[
'playtime_seconds'] = $thisfile_riff_raw[
'avih'][
'dwTotalFrames'] * ($thisfile_riff_raw[
'avih'][
'dwMicroSecPerFrame'] / 1000000);
917 if ($ThisFileInfo[
'playtime_seconds'] > 0) {
918 if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
920 if (!isset($ThisFileInfo[
'bitrate'])) {
921 $ThisFileInfo[
'bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo[
'playtime_seconds']) * 8);
924 } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
926 if (!isset($thisfile_audio[
'bitrate'])) {
927 $thisfile_audio[
'bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo[
'playtime_seconds']) * 8);
930 } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
932 if (!isset($thisfile_video[
'bitrate'])) {
933 $thisfile_video[
'bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo[
'playtime_seconds']) * 8);
940 if (isset($thisfile_riff_video) && isset($thisfile_audio[
'bitrate']) && ($thisfile_audio[
'bitrate'] > 0) && ($ThisFileInfo[
'playtime_seconds'] > 0)) {
942 $ThisFileInfo[
'bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo[
'playtime_seconds']) * 8);
943 $thisfile_audio[
'bitrate'] = 0;
944 $thisfile_video[
'bitrate'] = $ThisFileInfo[
'bitrate'];
945 foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) {
946 $thisfile_video[
'bitrate'] -= $audioinfoarray[
'bitrate'];
947 $thisfile_audio[
'bitrate'] += $audioinfoarray[
'bitrate'];
949 if ($thisfile_video[
'bitrate'] <= 0) {
950 unset($thisfile_video[
'bitrate']);
952 if ($thisfile_audio[
'bitrate'] <= 0) {
953 unset($thisfile_audio[
'bitrate']);
957 if (isset($ThisFileInfo[
'mpeg'][
'audio'])) {
958 $thisfile_audio_dataformat =
'mp'.$ThisFileInfo[
'mpeg'][
'audio'][
'layer'];
959 $thisfile_audio[
'sample_rate'] = $ThisFileInfo[
'mpeg'][
'audio'][
'sample_rate'];
960 $thisfile_audio[
'channels'] = $ThisFileInfo[
'mpeg'][
'audio'][
'channels'];
961 $thisfile_audio[
'bitrate'] = $ThisFileInfo[
'mpeg'][
'audio'][
'bitrate'];
962 $thisfile_audio[
'bitrate_mode'] = strtolower($ThisFileInfo[
'mpeg'][
'audio'][
'bitrate_mode']);
963 if (!empty($ThisFileInfo[
'mpeg'][
'audio'][
'codec'])) {
964 $thisfile_audio[
'codec'] = $ThisFileInfo[
'mpeg'][
'audio'][
'codec'].
' '.$thisfile_audio[
'codec'];
966 if (!empty($thisfile_audio[
'streams'])) {
967 foreach ($thisfile_audio[
'streams'] as $streamnumber => $streamdata) {
968 if ($streamdata[
'dataformat'] == $thisfile_audio_dataformat) {
969 $thisfile_audio[
'streams'][$streamnumber][
'sample_rate'] = $thisfile_audio[
'sample_rate'];
970 $thisfile_audio[
'streams'][$streamnumber][
'channels'] = $thisfile_audio[
'channels'];
971 $thisfile_audio[
'streams'][$streamnumber][
'bitrate'] = $thisfile_audio[
'bitrate'];
972 $thisfile_audio[
'streams'][$streamnumber][
'bitrate_mode'] = $thisfile_audio[
'bitrate_mode'];
973 $thisfile_audio[
'streams'][$streamnumber][
'codec'] = $thisfile_audio[
'codec'];
981 if (!empty($thisfile_riff_raw[
'fmt '][
'wBitsPerSample']) && ($thisfile_riff_raw[
'fmt '][
'wBitsPerSample'] > 0)) {
982 switch ($thisfile_audio_dataformat) {
988 $thisfile_audio[
'bits_per_sample'] = $thisfile_riff_raw[
'fmt '][
'wBitsPerSample'];
994 if (empty($thisfile_riff_raw)) {
995 unset($thisfile_riff[
'raw']);
997 if (empty($thisfile_riff_audio)) {
998 unset($thisfile_riff[
'audio']);
1000 if (empty($thisfile_riff_video)) {
1001 unset($thisfile_riff[
'video']);
1009 $RIFFinfoKeyLookup = array(
1010 'IARL'=>
'archivallocation',
1012 'ICDS'=>
'costumedesigner',
1013 'ICMS'=>
'commissionedby',
1016 'ICOP'=>
'copyright',
1017 'ICRD'=>
'creationdate',
1018 'IDIM'=>
'dimensions',
1019 'IDIT'=>
'digitizationdate',
1020 'IDPI'=>
'resolution',
1021 'IDST'=>
'distributor',
1023 'IENG'=>
'engineers',
1024 'IFRM'=>
'accountofparts',
1027 'ILGT'=>
'lightness',
1029 'IMED'=>
'orignalmedium',
1032 'IPDS'=>
'productiondesigner',
1040 'ISGN'=>
'secondarygenre',
1041 'ISHP'=>
'sharpness',
1042 'ISRC'=>
'sourcesupplier',
1043 'ISRF'=>
'digitizationsource',
1044 'ISTD'=>
'productionstudio',
1046 'ITCH'=>
'encoded_by',
1050 foreach ($RIFFinfoKeyLookup as $key => $value) {
1051 if (isset($RIFFinfoArray[$key])) {
1052 foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1053 if (trim($commentdata[
'data']) !=
'') {
1054 @$CommentsTargetArray[$value][] = trim($commentdata[
'data']);
1062 function ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo) {
1064 $maxoffset = min($maxoffset, $ThisFileInfo[
'avdataend']);
1068 fseek($fd, $startoffset, SEEK_SET);
1070 while (ftell($fd) < $maxoffset) {
1071 $chunkname = fread($fd, 4);
1072 if (strlen($chunkname) < 4) {
1073 $ThisFileInfo[
'error'][] =
'Expecting chunk name at offset '.(ftell($fd) - 4).
' but found nothing. Aborting RIFF parsing.';
1078 if ($chunksize == 0) {
1079 $ThisFileInfo[
'error'][] =
'Chunk size at offset '.(ftell($fd) - 4).
' is zero. Aborting RIFF parsing.';
1082 if (($chunksize % 2) != 0) {
1087 switch ($chunkname) {
1089 $listname = fread($fd, 4);
1090 switch ($listname) {
1093 $RIFFchunk[$listname][
'offset'] = ftell($fd) - 4;
1094 $RIFFchunk[$listname][
'size'] = $chunksize;
1096 static $ParsedAudioStream =
false;
1097 if ($ParsedAudioStream) {
1103 $WhereWeWere = ftell($fd);
1104 $AudioChunkHeader = fread($fd, 12);
1105 $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2);
1106 $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2);
1109 if ($AudioChunkStreamType ==
'wb') {
1110 $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1111 if (preg_match(
'/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1115 $dummy = $ThisFileInfo;
1116 $dummy[
'avdataoffset'] = ftell($fd) - 4;
1117 $dummy[
'avdataend'] = ftell($fd) + $AudioChunkSize;
1119 if (isset($dummy[
'mpeg'][
'audio'])) {
1120 $ThisFileInfo = $dummy;
1121 $ThisFileInfo[
'audio'][
'dataformat'] =
'mp'.$ThisFileInfo[
'mpeg'][
'audio'][
'layer'];
1122 $ThisFileInfo[
'audio'][
'sample_rate'] = $ThisFileInfo[
'mpeg'][
'audio'][
'sample_rate'];
1123 $ThisFileInfo[
'audio'][
'channels'] = $ThisFileInfo[
'mpeg'][
'audio'][
'channels'];
1124 $ThisFileInfo[
'audio'][
'bitrate'] = $ThisFileInfo[
'mpeg'][
'audio'][
'bitrate'];
1125 $ThisFileInfo[
'bitrate'] = $ThisFileInfo[
'audio'][
'bitrate'];
1126 $ThisFileInfo[
'audio'][
'bitrate_mode'] = strtolower($ThisFileInfo[
'mpeg'][
'audio'][
'bitrate_mode']);
1130 } elseif (preg_match(
'/^\x0B\x77/s', $FirstFourBytes)) {
1133 $GETID3_ERRORARRAY = &$ThisFileInfo[
'warning'];
1136 $dummy = $ThisFileInfo;
1137 $dummy[
'avdataoffset'] = ftell($fd) - 4;
1138 $dummy[
'avdataend'] = ftell($fd) + $AudioChunkSize;
1139 $dummy[
'error'] = array();
1141 if (empty($dummy[
'error'])) {
1142 $ThisFileInfo[
'audio'] = $dummy[
'audio'];
1143 $ThisFileInfo[
'ac3'] = $dummy[
'ac3'];
1144 $ThisFileInfo[
'warning'] = $dummy[
'warning'];
1153 $ParsedAudioStream =
true;
1154 fseek($fd, $WhereWeWere, SEEK_SET);
1157 fseek($fd, $chunksize - 4, SEEK_CUR);
1161 if (!isset($RIFFchunk[$listname])) {
1162 $RIFFchunk[$listname] = array();
1164 $LISTchunkParent = $listname;
1165 $LISTchunkMaxOffset = ftell($fd) - 4 + $chunksize;
1166 if ($parsedChunk =
getid3_riff::ParseRIFF($fd, ftell($fd), ftell($fd) + $chunksize - 4, $ThisFileInfo)) {
1167 $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1175 if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1176 $thisindex = count($RIFFchunk[$chunkname]);
1178 $RIFFchunk[$chunkname][$thisindex][
'offset'] = ftell($fd) - 8;
1179 $RIFFchunk[$chunkname][$thisindex][
'size'] = $chunksize;
1180 switch ($chunkname) {
1182 $ThisFileInfo[
'avdataoffset'] = ftell($fd);
1183 $ThisFileInfo[
'avdataend'] = $ThisFileInfo[
'avdataoffset'] + $chunksize;
1185 $RIFFdataChunkContentsTest = fread($fd, 36);
1187 if ((strlen($RIFFdataChunkContentsTest) > 0) && preg_match(
'/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($RIFFdataChunkContentsTest, 0, 4))) {
1194 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 2) ==
"\x0B\x77")) {
1197 $GETID3_ERRORARRAY = &$ThisFileInfo[
'warning'];
1200 $dummy = $ThisFileInfo;
1201 $dummy[
'avdataoffset'] = $RIFFchunk[$chunkname][$thisindex][
'offset'];
1202 $dummy[
'avdataend'] = $dummy[
'avdataoffset'] + $RIFFchunk[$chunkname][$thisindex][
'size'];
1203 $dummy[
'error'] = array();
1206 if (empty($dummy[
'error'])) {
1207 $ThisFileInfo[
'audio'] = $dummy[
'audio'];
1208 $ThisFileInfo[
'ac3'] = $dummy[
'ac3'];
1209 $ThisFileInfo[
'warning'] = $dummy[
'warning'];
1214 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 8, 2) ==
"\x77\x0B")) {
1220 $GETID3_ERRORARRAY = &$ThisFileInfo[
'warning'];
1224 if ($fd_temp = tmpfile()) {
1226 for ($i = 0; $i < 28; $i += 2) {
1228 fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 1, 1));
1229 fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 0, 1));
1232 $dummy = $ThisFileInfo;
1233 $dummy[
'avdataoffset'] = 0;
1234 $dummy[
'avdataend'] = 20;
1235 $dummy[
'error'] = array();
1238 if (empty($dummy[
'error'])) {
1239 $ThisFileInfo[
'audio'] = $dummy[
'audio'];
1240 $ThisFileInfo[
'ac3'] = $dummy[
'ac3'];
1241 $ThisFileInfo[
'warning'] = $dummy[
'warning'];
1243 $ThisFileInfo[
'error'][] =
'Errors parsing DolbyDigital WAV: '.explode(
';', $dummy[
'error']);
1248 $ThisFileInfo[
'error'][] =
'Could not create temporary file to analyze DolbyDigital WAV';
1254 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 4) ==
'wvpk')) {
1257 $ThisFileInfo[
'wavpack'][
'offset'] = $RIFFchunk[$chunkname][$thisindex][
'offset'];
1267 fseek($fd, $RIFFchunk[$chunkname][$thisindex][
'offset'] + 8 + $chunksize, SEEK_SET);
1276 $RIFFchunk[$chunkname][$thisindex][
'data'] = fread($fd, $chunksize);
1280 if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex][
'offset'] + $RIFFchunk[$chunkname][$thisindex][
'size']) <= $LISTchunkMaxOffset)) {
1281 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex][
'offset'] = $RIFFchunk[$chunkname][$thisindex][
'offset'];
1282 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex][
'size'] = $RIFFchunk[$chunkname][$thisindex][
'size'];
1283 unset($RIFFchunk[$chunkname][$thisindex][
'offset']);
1284 unset($RIFFchunk[$chunkname][$thisindex][
'size']);
1285 if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1286 unset($RIFFchunk[$chunkname][$thisindex]);
1288 if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1289 unset($RIFFchunk[$chunkname]);
1291 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex][
'data'] = fread($fd, $chunksize);
1292 } elseif ($chunksize < 2048) {
1294 $RIFFchunk[$chunkname][$thisindex][
'data'] = fread($fd, $chunksize);
1296 fseek($fd, $chunksize, SEEK_CUR);
1313 $tempfile = tempnam(
'*',
'getID3');
1314 $fp_temp = fopen($tempfile,
"wb");
1315 $RIFFdataLength = strlen($RIFFdata);
1317 for ($i = 0; $i < 4; $i++) {
1318 $RIFFdata{$i + 4} = $NewLengthString{$i};
1320 fwrite($fp_temp, $RIFFdata);
1323 $fp_temp = fopen($tempfile,
"rb");
1324 $dummy = array(
'filesize'=>$RIFFdataLength,
'filenamepath'=>$ThisFileInfo[
'filenamepath'],
'tags'=>$ThisFileInfo[
'tags'],
'avdataoffset'=>0,
'avdataend'=>$RIFFdataLength,
'warning'=>$ThisFileInfo[
'warning'],
'error'=>$ThisFileInfo[
'error'],
'comments'=>$ThisFileInfo[
'comments'],
'audio'=>(isset($ThisFileInfo[
'audio']) ? $ThisFileInfo[
'audio'] : array()),
'video'=>(isset($ThisFileInfo[
'video']) ? $ThisFileInfo[
'video'] : array()));
1326 $ThisFileInfo[
'riff'] = $dummy[
'riff'];
1327 $ThisFileInfo[
'warning'] = $dummy[
'warning'];
1328 $ThisFileInfo[
'error'] = $dummy[
'error'];
1329 $ThisFileInfo[
'tags'] = $dummy[
'tags'];
1330 $ThisFileInfo[
'comments'] = $dummy[
'comments'];
1341 $WaveFormatEx[
'raw'] = array();
1342 $WaveFormatEx_raw = &$WaveFormatEx[
'raw'];
1350 if (strlen($WaveFormatExData) > 16) {
1355 $WaveFormatEx[
'channels'] = $WaveFormatEx_raw[
'nChannels'];
1356 $WaveFormatEx[
'sample_rate'] = $WaveFormatEx_raw[
'nSamplesPerSec'];
1357 $WaveFormatEx[
'bitrate'] = $WaveFormatEx_raw[
'nAvgBytesPerSec'] * 8;
1358 $WaveFormatEx[
'bits_per_sample'] = $WaveFormatEx_raw[
'wBitsPerSample'];
1360 return $WaveFormatEx;
1376 $ThisFileInfo[
'wavpack'] = array();
1377 $thisfile_wavpack = &$ThisFileInfo[
'wavpack'];
1380 if ($thisfile_wavpack[
'version'] >= 2) {
1383 if ($thisfile_wavpack[
'version'] >= 3) {
1389 $thisfile_wavpack[
'extension'] = substr($WavPackChunkData, 20, 4);
1391 for ($i = 0; $i <= 2; $i++) {
1396 $thisfile_wavpack[
'flags'] = array();
1397 $thisfile_wavpack_flags = &$thisfile_wavpack[
'flags'];
1399 $thisfile_wavpack_flags[
'mono'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000001);
1400 $thisfile_wavpack_flags[
'fast_mode'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000002);
1401 $thisfile_wavpack_flags[
'raw_mode'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000004);
1402 $thisfile_wavpack_flags[
'calc_noise'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000008);
1403 $thisfile_wavpack_flags[
'high_quality'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000010);
1404 $thisfile_wavpack_flags[
'3_byte_samples'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000020);
1405 $thisfile_wavpack_flags[
'over_20_bits'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000040);
1406 $thisfile_wavpack_flags[
'use_wvc'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000080);
1407 $thisfile_wavpack_flags[
'noiseshaping'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000100);
1408 $thisfile_wavpack_flags[
'very_fast_mode'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000200);
1409 $thisfile_wavpack_flags[
'new_high_quality'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000400);
1410 $thisfile_wavpack_flags[
'cancel_extreme'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x000800);
1411 $thisfile_wavpack_flags[
'cross_decorrelation'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x001000);
1412 $thisfile_wavpack_flags[
'new_decorrelation'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x002000);
1413 $thisfile_wavpack_flags[
'joint_stereo'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x004000);
1414 $thisfile_wavpack_flags[
'extra_decorrelation'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x008000);
1415 $thisfile_wavpack_flags[
'override_noiseshape'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x010000);
1416 $thisfile_wavpack_flags[
'override_jointstereo'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x020000);
1417 $thisfile_wavpack_flags[
'copy_source_filetime'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x040000);
1418 $thisfile_wavpack_flags[
'create_exe'] = (bool) ($thisfile_wavpack[
'flags_raw'] & 0x080000);
1590 return getid3_lib::EmbeddedLookup(
'0x'.str_pad(strtoupper(dechex($wFormatTag)), 4,
'0', STR_PAD_LEFT), $begin, __LINE__, __FILE__,
'riff-wFormatTag');
1987 if ($ThisFileInfo[
'fileformat'] ==
'riff') {