23 $ThisFileInfo[
'ac3'][
'raw'][
'bsi'] = array();
24 $thisfile_ac3 = &$ThisFileInfo[
'ac3'];
25 $thisfile_ac3_raw = &$thisfile_ac3[
'raw'];
26 $thisfile_ac3_raw_bsi = &$thisfile_ac3_raw[
'bsi'];
31 $ThisFileInfo[
'fileformat'] =
'ac3';
32 $ThisFileInfo[
'audio'][
'dataformat'] =
'ac3';
33 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'cbr';
34 $ThisFileInfo[
'audio'][
'lossless'] =
false;
47 fseek($fd, $ThisFileInfo[
'avdataoffset'], SEEK_SET);
48 $AC3header[
'syncinfo'] = fread($fd, 5);
49 $thisfile_ac3_raw[
'synchinfo'][
'synchword'] = substr($AC3header[
'syncinfo'], 0, 2);
51 if ($thisfile_ac3_raw[
'synchinfo'][
'synchword'] !=
"\x0B\x77") {
53 $ThisFileInfo[
'error'][] =
'Expecting "\x0B\x77" at offset '.$ThisFileInfo[
'avdataoffset'].
', found \x'.strtoupper(dechex($AC3header[
'syncinfo']{0})).
'\x'.strtoupper(dechex($AC3header[
'syncinfo']{1})).
' instead';
68 $thisfile_ac3_raw[
'synchinfo'][
'fscod'] = ($ac3_synchinfo_fscod_frmsizecod & 0xC0) >> 6;
69 $thisfile_ac3_raw[
'synchinfo'][
'frmsizecod'] = ($ac3_synchinfo_fscod_frmsizecod & 0x3F);
72 if ($thisfile_ac3_raw[
'synchinfo'][
'fscod'] <= 3) {
73 $ThisFileInfo[
'audio'][
'sample_rate'] = $thisfile_ac3[
'sample_rate'];
76 $thisfile_ac3[
'frame_length'] = $this->
AC3frameSizeLookup($thisfile_ac3_raw[
'synchinfo'][
'frmsizecod'], $thisfile_ac3_raw[
'synchinfo'][
'fscod']);
77 $thisfile_ac3[
'bitrate'] = $this->
AC3bitrateLookup($thisfile_ac3_raw[
'synchinfo'][
'frmsizecod']);
78 $ThisFileInfo[
'audio'][
'bitrate'] = $thisfile_ac3[
'bitrate'];
83 $thisfile_ac3_raw_bsi[
'bsid'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 5));
85 if ($thisfile_ac3_raw_bsi[
'bsid'] > 8) {
89 $ThisFileInfo[
'error'][] =
'Bit stream identification is version '.$thisfile_ac3_raw_bsi[
'bsid'].
', but getID3() only understands up to version 8';
94 $thisfile_ac3_raw_bsi[
'bsmod'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 3));
96 $thisfile_ac3_raw_bsi[
'acmod'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 3));
99 $thisfile_ac3[
'service_type'] = $this->
AC3serviceTypeLookup($thisfile_ac3_raw_bsi[
'bsmod'], $thisfile_ac3_raw_bsi[
'acmod']);
101 foreach($ac3_coding_mode as $key => $value) {
102 $thisfile_ac3[$key] = $value;
104 switch ($thisfile_ac3_raw_bsi[
'acmod']) {
107 $ThisFileInfo[
'audio'][
'channelmode'] =
'mono';
111 $ThisFileInfo[
'audio'][
'channelmode'] =
'stereo';
114 $ThisFileInfo[
'audio'][
'channelmode'] =
'surround';
117 $ThisFileInfo[
'audio'][
'channels'] = $thisfile_ac3[
'num_channels'];
119 if ($thisfile_ac3_raw_bsi[
'acmod'] & 0x01) {
121 $thisfile_ac3_raw_bsi[
'cmixlev'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 2));
122 $ac3_bsi_offset += 2;
126 if ($thisfile_ac3_raw_bsi[
'acmod'] & 0x04) {
128 $thisfile_ac3_raw_bsi[
'surmixlev'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 2));
129 $ac3_bsi_offset += 2;
133 if ($thisfile_ac3_raw_bsi[
'acmod'] == 0x02) {
135 $thisfile_ac3_raw_bsi[
'dsurmod'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 2));
136 $ac3_bsi_offset += 2;
140 $thisfile_ac3_raw_bsi[
'lfeon'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
141 $ac3_bsi_offset += 1;
142 $thisfile_ac3[
'lfe_enabled'] = $thisfile_ac3_raw_bsi[
'lfeon'];
143 if ($thisfile_ac3_raw_bsi[
'lfeon']) {
145 $ThisFileInfo[
'audio'][
'channels'] .=
'.1';
148 $thisfile_ac3[
'channels_enabled'] = $this->
AC3channelsEnabledLookup($thisfile_ac3_raw_bsi[
'acmod'], $thisfile_ac3_raw_bsi[
'lfeon']);
152 $thisfile_ac3_raw_bsi[
'dialnorm'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 5));
153 $ac3_bsi_offset += 5;
154 $thisfile_ac3[
'dialogue_normalization'] =
'-'.$thisfile_ac3_raw_bsi[
'dialnorm'].
'dB';
156 $thisfile_ac3_raw_bsi[
'compre_flag'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
157 $ac3_bsi_offset += 1;
158 if ($thisfile_ac3_raw_bsi[
'compre_flag']) {
159 $thisfile_ac3_raw_bsi[
'compr'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 8));
160 $ac3_bsi_offset += 8;
161 $thisfile_ac3[
'heavy_compression'] = $this->
AC3heavyCompression($thisfile_ac3_raw_bsi[
'compr']);
164 $thisfile_ac3_raw_bsi[
'langcode_flag'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
165 $ac3_bsi_offset += 1;
166 if ($thisfile_ac3_raw_bsi[
'langcode_flag']) {
167 $thisfile_ac3_raw_bsi[
'langcod'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 8));
168 $ac3_bsi_offset += 8;
171 $thisfile_ac3_raw_bsi[
'audprodie'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
172 $ac3_bsi_offset += 1;
173 if ($thisfile_ac3_raw_bsi[
'audprodie']) {
174 $thisfile_ac3_raw_bsi[
'mixlevel'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 5));
175 $ac3_bsi_offset += 5;
176 $thisfile_ac3_raw_bsi[
'roomtyp'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 2));
177 $ac3_bsi_offset += 2;
179 $thisfile_ac3[
'mixing_level'] = (80 + $thisfile_ac3_raw_bsi[
'mixlevel']).
'dB';
180 $thisfile_ac3[
'room_type'] = $this->
AC3roomTypeLookup($thisfile_ac3_raw_bsi[
'roomtyp']);
183 if ($thisfile_ac3_raw_bsi[
'acmod'] == 0x00) {
191 $thisfile_ac3_raw_bsi[
'dialnorm2'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 5));
192 $ac3_bsi_offset += 5;
193 $thisfile_ac3[
'dialogue_normalization2'] =
'-'.$thisfile_ac3_raw_bsi[
'dialnorm2'].
'dB';
195 $thisfile_ac3_raw_bsi[
'compre_flag2'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
196 $ac3_bsi_offset += 1;
197 if ($thisfile_ac3_raw_bsi[
'compre_flag2']) {
198 $thisfile_ac3_raw_bsi[
'compr2'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 8));
199 $ac3_bsi_offset += 8;
200 $thisfile_ac3[
'heavy_compression2'] = $this->
AC3heavyCompression($thisfile_ac3_raw_bsi[
'compr2']);
203 $thisfile_ac3_raw_bsi[
'langcode_flag2'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
204 $ac3_bsi_offset += 1;
205 if ($thisfile_ac3_raw_bsi[
'langcode_flag2']) {
206 $thisfile_ac3_raw_bsi[
'langcod2'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 8));
207 $ac3_bsi_offset += 8;
210 $thisfile_ac3_raw_bsi[
'audprodie2'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
211 $ac3_bsi_offset += 1;
212 if ($thisfile_ac3_raw_bsi[
'audprodie2']) {
213 $thisfile_ac3_raw_bsi[
'mixlevel2'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 5));
214 $ac3_bsi_offset += 5;
215 $thisfile_ac3_raw_bsi[
'roomtyp2'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 2));
216 $ac3_bsi_offset += 2;
218 $thisfile_ac3[
'mixing_level2'] = (80 + $thisfile_ac3_raw_bsi[
'mixlevel2']).
'dB';
219 $thisfile_ac3[
'room_type2'] = $this->
AC3roomTypeLookup($thisfile_ac3_raw_bsi[
'roomtyp2']);
224 $thisfile_ac3_raw_bsi[
'copyright'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
225 $ac3_bsi_offset += 1;
227 $thisfile_ac3_raw_bsi[
'original'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
228 $ac3_bsi_offset += 1;
230 $thisfile_ac3_raw_bsi[
'timecode1_flag'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
231 $ac3_bsi_offset += 1;
232 if ($thisfile_ac3_raw_bsi[
'timecode1_flag']) {
233 $thisfile_ac3_raw_bsi[
'timecode1'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 14));
234 $ac3_bsi_offset += 14;
237 $thisfile_ac3_raw_bsi[
'timecode2_flag'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
238 $ac3_bsi_offset += 1;
239 if ($thisfile_ac3_raw_bsi[
'timecode2_flag']) {
240 $thisfile_ac3_raw_bsi[
'timecode2'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 14));
241 $ac3_bsi_offset += 14;
244 $thisfile_ac3_raw_bsi[
'addbsi_flag'] = (bool) bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 1));
245 $ac3_bsi_offset += 1;
246 if ($thisfile_ac3_raw_bsi[
'addbsi_flag']) {
247 $thisfile_ac3_raw_bsi[
'addbsi_length'] = bindec(substr($AC3header[
'bsi'], $ac3_bsi_offset, 6));
248 $ac3_bsi_offset += 6;
252 $thisfile_ac3_raw_bsi[
'addbsi_data'] = substr($AC3header[
'bsi'], $ac3_bsi_offset, $thisfile_ac3_raw_bsi[
'addbsi_length'] * 8);
253 $ac3_bsi_offset += $thisfile_ac3_raw_bsi[
'addbsi_length'] * 8;
263 static $AC3sampleRateCodeLookup = array(
269 return (isset($AC3sampleRateCodeLookup[$fscod]) ? $AC3sampleRateCodeLookup[$fscod] :
false);
273 static $AC3serviceTypeLookup = array();
274 if (empty($AC3serviceTypeLookup)) {
275 for ($i = 0; $i <= 7; $i++) {
276 $AC3serviceTypeLookup[0][$i] =
'main audio service: complete main (CM)';
277 $AC3serviceTypeLookup[1][$i] =
'main audio service: music and effects (ME)';
278 $AC3serviceTypeLookup[2][$i] =
'associated service: visually impaired (VI)';
279 $AC3serviceTypeLookup[3][$i] =
'associated service: hearing impaired (HI)';
280 $AC3serviceTypeLookup[4][$i] =
'associated service: dialogue (D)';
281 $AC3serviceTypeLookup[5][$i] =
'associated service: commentary (C)';
282 $AC3serviceTypeLookup[6][$i] =
'associated service: emergency (E)';
285 $AC3serviceTypeLookup[7][1] =
'associated service: voice over (VO)';
286 for ($i = 2; $i <= 7; $i++) {
287 $AC3serviceTypeLookup[7][$i] =
'main audio service: karaoke';
290 return (isset($AC3serviceTypeLookup[$bsmod][$acmod]) ? $AC3serviceTypeLookup[$bsmod][$acmod] :
false);
294 static $AC3audioCodingModeLookup = array();
295 if (empty($AC3audioCodingModeLookup)) {
297 $AC3audioCodingModeLookup = array (
298 0 => array(
'channel_config'=>
'1+1',
'num_channels'=>2,
'channel_order'=>
'Ch1,Ch2'),
299 1 => array(
'channel_config'=>
'1/0',
'num_channels'=>1,
'channel_order'=>
'C'),
300 2 => array(
'channel_config'=>
'2/0',
'num_channels'=>2,
'channel_order'=>
'L,R'),
301 3 => array(
'channel_config'=>
'3/0',
'num_channels'=>3,
'channel_order'=>
'L,C,R'),
302 4 => array(
'channel_config'=>
'2/1',
'num_channels'=>3,
'channel_order'=>
'L,R,S'),
303 5 => array(
'channel_config'=>
'3/1',
'num_channels'=>4,
'channel_order'=>
'L,C,R,S'),
304 6 => array(
'channel_config'=>
'2/2',
'num_channels'=>4,
'channel_order'=>
'L,R,SL,SR'),
305 7 => array(
'channel_config'=>
'3/2',
'num_channels'=>5,
'channel_order'=>
'L,C,R,SL,SR')
308 return (isset($AC3audioCodingModeLookup[$acmod]) ? $AC3audioCodingModeLookup[$acmod] :
false);
312 static $AC3centerMixLevelLookup;
313 if (empty($AC3centerMixLevelLookup)) {
314 $AC3centerMixLevelLookup = array(
315 0 => pow(2, -3.0 / 6),
316 1 => pow(2, -4.5 / 6),
317 2 => pow(2, -6.0 / 6),
321 return (isset($AC3centerMixLevelLookup[$cmixlev]) ? $AC3centerMixLevelLookup[$cmixlev] :
false);
325 static $AC3surroundMixLevelLookup;
326 if (empty($AC3surroundMixLevelLookup)) {
327 $AC3surroundMixLevelLookup = array(
328 0 => pow(2, -3.0 / 6),
329 1 => pow(2, -6.0 / 6),
334 return (isset($AC3surroundMixLevelLookup[$surmixlev]) ? $AC3surroundMixLevelLookup[$surmixlev] :
false);
338 static $AC3dolbySurroundModeLookup = array(
339 0 =>
'not indicated',
340 1 =>
'Not Dolby Surround encoded',
341 2 =>
'Dolby Surround encoded',
344 return (isset($AC3dolbySurroundModeLookup[$dsurmod]) ? $AC3dolbySurroundModeLookup[$dsurmod] :
false);
348 $AC3channelsEnabledLookup = array(
349 'ch1'=>(
bool) ($acmod == 0),
350 'ch2'=>(
bool) ($acmod == 0),
351 'left'=>(
bool) ($acmod > 1),
352 'right'=>(
bool) ($acmod > 1),
353 'center'=>(
bool) ($acmod & 0x01),
354 'surround_mono'=>
false,
355 'surround_left'=>
false,
356 'surround_right'=>
false,
361 $AC3channelsEnabledLookup[
'surround_mono'] =
true;
365 $AC3channelsEnabledLookup[
'surround_left'] =
true;
366 $AC3channelsEnabledLookup[
'surround_right'] =
true;
369 return $AC3channelsEnabledLookup;
400 $fourbit = str_pad(decbin(($compre & 0xF0) >> 4), 4,
'0', STR_PAD_LEFT);
401 if ($fourbit{0} ==
'1') {
402 $log_gain = -8 + bindec(substr($fourbit, 1));
404 $log_gain = bindec(substr($fourbit, 1));
413 $lin_gain = (16 + ($compre & 0x0F)) / 32;
419 return $log_gain - $lin_gain;
423 static $AC3roomTypeLookup = array(
424 0 =>
'not indicated',
425 1 =>
'large room, X curve monitor',
426 2 =>
'small room, flat monitor',
429 return (isset($AC3roomTypeLookup[$roomtyp]) ? $AC3roomTypeLookup[$roomtyp] :
false);
433 $padding = (bool) ($frmsizecod % 2);
434 $framesizeid = floor($frmsizecod / 2);
436 static $AC3frameSizeLookup = array();
437 if (empty($AC3frameSizeLookup)) {
438 $AC3frameSizeLookup = array (
439 0 => array(128, 138, 192),
440 1 => array(40, 160, 174, 240),
441 2 => array(48, 192, 208, 288),
442 3 => array(56, 224, 242, 336),
443 4 => array(64, 256, 278, 384),
444 5 => array(80, 320, 348, 480),
445 6 => array(96, 384, 416, 576),
446 7 => array(112, 448, 486, 672),
447 8 => array(128, 512, 556, 768),
448 9 => array(160, 640, 696, 960),
449 10 => array(192, 768, 834, 1152),
450 11 => array(224, 896, 974, 1344),
451 12 => array(256, 1024, 1114, 1536),
452 13 => array(320, 1280, 1392, 1920),
453 14 => array(384, 1536, 1670, 2304),
454 15 => array(448, 1792, 1950, 2688),
455 16 => array(512, 2048, 2228, 3072),
456 17 => array(576, 2304, 2506, 3456),
457 18 => array(640, 2560, 2786, 3840)
460 if (($fscod == 1) && $padding) {
462 $AC3frameSizeLookup[$frmsizecod] += 2;
464 return (isset($AC3frameSizeLookup[$framesizeid][$fscod]) ? $AC3frameSizeLookup[$framesizeid][$fscod] :
false);
468 $framesizeid = floor($frmsizecod / 2);
470 static $AC3bitrateLookup = array(
491 return (isset($AC3bitrateLookup[$framesizeid]) ? $AC3bitrateLookup[$framesizeid] :
false);