Mercurial > judyates
diff e2gallerypro/e2upload/Backend/Assets/getid3/module.audio.ac3.php @ 3:3f6b44aa6b35 judyates
[svn r4] added ability to buy stuff, from a Prints page, but it doesn't work well with the css, and it also has not been fitted into the perl make system.
author | rlm |
---|---|
date | Mon, 22 Feb 2010 08:02:39 -0500 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/e2gallerypro/e2upload/Backend/Assets/getid3/module.audio.ac3.php Mon Feb 22 08:02:39 2010 -0500 1.3 @@ -0,0 +1,500 @@ 1.4 +<?php 1.5 +// +----------------------------------------------------------------------+ 1.6 +// | PHP version 5 | 1.7 +// +----------------------------------------------------------------------+ 1.8 +// | Copyright (c) 2002-2006 James Heinrich, Allan Hansen | 1.9 +// +----------------------------------------------------------------------+ 1.10 +// | This source file is subject to version 2 of the GPL license, | 1.11 +// | that is bundled with this package in the file license.txt and is | 1.12 +// | available through the world-wide-web at the following url: | 1.13 +// | http://www.gnu.org/copyleft/gpl.html | 1.14 +// +----------------------------------------------------------------------+ 1.15 +// | getID3() - http://getid3.sourceforge.net or http://www.getid3.org | 1.16 +// +----------------------------------------------------------------------+ 1.17 +// | Authors: James Heinrich <infoุgetid3*org> | 1.18 +// | Allan Hansen <ahุartemis*dk> | 1.19 +// +----------------------------------------------------------------------+ 1.20 +// | module.audio.ac3.php | 1.21 +// | Module for analyzing AC-3 (aka Dolby Digital) audio files | 1.22 +// | dependencies: NONE | 1.23 +// +----------------------------------------------------------------------+ 1.24 +// 1.25 +// $Id: module.audio.ac3.php,v 1.3 2006/11/02 10:48:01 ah Exp $ 1.26 + 1.27 + 1.28 + 1.29 +class getid3_ac3 extends getid3_handler 1.30 +{ 1.31 + 1.32 + public function Analyze() { 1.33 + 1.34 + $getid3 = $this->getid3; 1.35 + 1.36 + // http://www.atsc.org/standards/a_52a.pdf 1.37 + 1.38 + $getid3->info['fileformat'] = 'ac3'; 1.39 + $getid3->info['audio']['dataformat'] = 'ac3'; 1.40 + $getid3->info['audio']['bitrate_mode'] = 'cbr'; 1.41 + $getid3->info['audio']['lossless'] = false; 1.42 + 1.43 + $getid3->info['ac3']['raw']['bsi'] = array (); 1.44 + $info_ac3 = &$getid3->info['ac3']; 1.45 + $info_ac3_raw = &$info_ac3['raw']; 1.46 + $info_ac3_raw_bsi = &$info_ac3_raw['bsi']; 1.47 + 1.48 + 1.49 + // An AC-3 serial coded audio bit stream is made up of a sequence of synchronization frames 1.50 + // Each synchronization frame contains 6 coded audio blocks (AB), each of which represent 256 1.51 + // new audio samples per channel. A synchronization information (SI) header at the beginning 1.52 + // of each frame contains information needed to acquire and maintain synchronization. A 1.53 + // bit stream information (BSI) header follows SI, and contains parameters describing the coded 1.54 + // audio service. The coded audio blocks may be followed by an auxiliary data (Aux) field. At the 1.55 + // end of each frame is an error check field that includes a CRC word for error detection. An 1.56 + // additional CRC word is located in the SI header, the use of which, by a decoder, is optional. 1.57 + // 1.58 + // syncinfo() | bsi() | AB0 | AB1 | AB2 | AB3 | AB4 | AB5 | Aux | CRC 1.59 + 1.60 + $this->fseek($getid3->info['avdataoffset'], SEEK_SET); 1.61 + $ac3_header['syncinfo'] = $this->fread(5); 1.62 + $info_ac3_raw['synchinfo']['synchword'] = substr($ac3_header['syncinfo'], 0, 2); 1.63 + 1.64 + if ($info_ac3_raw['synchinfo']['synchword'] != "\x0B\x77") { 1.65 + throw new getid3_exception('Expecting "\x0B\x77" at offset '.$getid3->info['avdataoffset'].', found \x'.strtoupper(dechex($ac3_header['syncinfo']{0})).'\x'.strtoupper(dechex($ac3_header['syncinfo']{1})).' instead'); 1.66 + } 1.67 + 1.68 + 1.69 + // syncinfo() { 1.70 + // syncword 16 1.71 + // crc1 16 1.72 + // fscod 2 1.73 + // frmsizecod 6 1.74 + // } /* end of syncinfo */ 1.75 + 1.76 + $info_ac3_raw['synchinfo']['crc1'] = getid3_lib::LittleEndian2Int(substr($ac3_header['syncinfo'], 2, 2)); 1.77 + $ac3_synchinfo_fscod_frmsizecod = getid3_lib::LittleEndian2Int(substr($ac3_header['syncinfo'], 4, 1)); 1.78 + $info_ac3_raw['synchinfo']['fscod'] = ($ac3_synchinfo_fscod_frmsizecod & 0xC0) >> 6; 1.79 + $info_ac3_raw['synchinfo']['frmsizecod'] = ($ac3_synchinfo_fscod_frmsizecod & 0x3F); 1.80 + 1.81 + $info_ac3['sample_rate'] = getid3_ac3::AC3sampleRateCodeLookup($info_ac3_raw['synchinfo']['fscod']); 1.82 + if ($info_ac3_raw['synchinfo']['fscod'] <= 3) { 1.83 + $getid3->info['audio']['sample_rate'] = $info_ac3['sample_rate']; 1.84 + } 1.85 + 1.86 + $info_ac3['frame_length'] = getid3_ac3::AC3frameSizeLookup($info_ac3_raw['synchinfo']['frmsizecod'], $info_ac3_raw['synchinfo']['fscod']); 1.87 + $info_ac3['bitrate'] = getid3_ac3::AC3bitrateLookup($info_ac3_raw['synchinfo']['frmsizecod']); 1.88 + $getid3->info['audio']['bitrate'] = $info_ac3['bitrate']; 1.89 + 1.90 + $ac3_header['bsi'] = getid3_lib::BigEndian2Bin($this->fread(15)); 1.91 + 1.92 + $info_ac3_raw_bsi['bsid'] = bindec(substr($ac3_header['bsi'], 0, 5)); 1.93 + if ($info_ac3_raw_bsi['bsid'] > 8) { 1.94 + // Decoders which can decode version 8 will thus be able to decode version numbers less than 8. 1.95 + // If this standard is extended by the addition of additional elements or features, a value of bsid greater than 8 will be used. 1.96 + // Decoders built to this version of the standard will not be able to decode versions with bsid greater than 8. 1.97 + throw new getid3_exception('Bit stream identification is version '.$info_ac3_raw_bsi['bsid'].', but getID3() only understands up to version 8'); 1.98 + } 1.99 + 1.100 + $info_ac3_raw_bsi['bsmod'] = bindec(substr($ac3_header['bsi'], 5, 3)); 1.101 + $info_ac3_raw_bsi['acmod'] = bindec(substr($ac3_header['bsi'], 8, 3)); 1.102 + 1.103 + $info_ac3['service_type'] = getid3_ac3::AC3serviceTypeLookup($info_ac3_raw_bsi['bsmod'], $info_ac3_raw_bsi['acmod']); 1.104 + $ac3_coding_mode = getid3_ac3::AC3audioCodingModeLookup($info_ac3_raw_bsi['acmod']); 1.105 + foreach($ac3_coding_mode as $key => $value) { 1.106 + $info_ac3[$key] = $value; 1.107 + } 1.108 + switch ($info_ac3_raw_bsi['acmod']) { 1.109 + case 0: 1.110 + case 1: 1.111 + $getid3->info['audio']['channelmode'] = 'mono'; 1.112 + break; 1.113 + case 3: 1.114 + case 4: 1.115 + $getid3->info['audio']['channelmode'] = 'stereo'; 1.116 + break; 1.117 + default: 1.118 + $getid3->info['audio']['channelmode'] = 'surround'; 1.119 + break; 1.120 + } 1.121 + $getid3->info['audio']['channels'] = $info_ac3['num_channels']; 1.122 + 1.123 + $offset = 11; 1.124 + 1.125 + if ($info_ac3_raw_bsi['acmod'] & 0x01) { 1.126 + // If the lsb of acmod is a 1, center channel is in use and cmixlev follows in the bit stream. 1.127 + $info_ac3_raw_bsi['cmixlev'] = bindec(substr($ac3_header['bsi'], $offset, 2)); 1.128 + $info_ac3['center_mix_level'] = getid3_ac3::AC3centerMixLevelLookup($info_ac3_raw_bsi['cmixlev']); 1.129 + $offset += 2; 1.130 + } 1.131 + 1.132 + if ($info_ac3_raw_bsi['acmod'] & 0x04) { 1.133 + // If the msb of acmod is a 1, surround channels are in use and surmixlev follows in the bit stream. 1.134 + $info_ac3_raw_bsi['surmixlev'] = bindec(substr($ac3_header['bsi'], $offset, 2)); 1.135 + $info_ac3['surround_mix_level'] = getid3_ac3::AC3surroundMixLevelLookup($info_ac3_raw_bsi['surmixlev']); 1.136 + $offset += 2; 1.137 + } 1.138 + 1.139 + if ($info_ac3_raw_bsi['acmod'] == 0x02) { 1.140 + // When operating in the two channel mode, this 2-bit code indicates whether or not the program has been encoded in Dolby Surround. 1.141 + $info_ac3_raw_bsi['dsurmod'] = bindec(substr($ac3_header['bsi'], $offset, 2)); 1.142 + $info_ac3['dolby_surround_mode'] = getid3_ac3::AC3dolbySurroundModeLookup($info_ac3_raw_bsi['dsurmod']); 1.143 + $offset += 2; 1.144 + } 1.145 + 1.146 + $info_ac3_raw_bsi['lfeon'] = $ac3_header['bsi']{$offset++} == '1'; 1.147 + $info_ac3['lfe_enabled'] = $info_ac3_raw_bsi['lfeon']; 1.148 + if ($info_ac3_raw_bsi['lfeon']) { 1.149 + $getid3->info['audio']['channels'] .= '.1'; 1.150 + } 1.151 + 1.152 + $info_ac3['channels_enabled'] = getid3_ac3::AC3channelsEnabledLookup($info_ac3_raw_bsi['acmod'], $info_ac3_raw_bsi['lfeon']); 1.153 + 1.154 + // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 131. 1.155 + // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent. 1.156 + $info_ac3_raw_bsi['dialnorm'] = bindec(substr($ac3_header['bsi'], $offset, 5)); 1.157 + $offset += 5; 1.158 + $info_ac3['dialogue_normalization'] = '-'.$info_ac3_raw_bsi['dialnorm'].'dB'; 1.159 + 1.160 + $info_ac3_raw_bsi['compre_flag'] = $ac3_header['bsi']{$offset++} == '1'; 1.161 + if ($info_ac3_raw_bsi['compre_flag']) { 1.162 + $info_ac3_raw_bsi['compr'] = bindec(substr($ac3_header['bsi'], $offset, 8)); 1.163 + $offset += 8; 1.164 + 1.165 + $info_ac3['heavy_compression'] = getid3_ac3::AC3heavyCompression($info_ac3_raw_bsi['compr']); 1.166 + } 1.167 + 1.168 + $info_ac3_raw_bsi['langcode_flag'] = $ac3_header['bsi']{$offset++} == '1'; 1.169 + if ($info_ac3_raw_bsi['langcode_flag']) { 1.170 + $info_ac3_raw_bsi['langcod'] = bindec(substr($ac3_header['bsi'], $offset, 8)); 1.171 + $offset += 8; 1.172 + } 1.173 + 1.174 + $info_ac3_raw_bsi['audprodie'] = $ac3_header['bsi']{$offset++} == '1'; 1.175 + if ($info_ac3_raw_bsi['audprodie']) { 1.176 + $info_ac3_raw_bsi['mixlevel'] = bindec(substr($ac3_header['bsi'], $offset, 5)); 1.177 + $offset += 5; 1.178 + 1.179 + $info_ac3_raw_bsi['roomtyp'] = bindec(substr($ac3_header['bsi'], $offset, 2)); 1.180 + $offset += 2; 1.181 + 1.182 + $info_ac3['mixing_level'] = (80 + $info_ac3_raw_bsi['mixlevel']).'dB'; 1.183 + $info_ac3['room_type'] = getid3_ac3::AC3roomTypeLookup($info_ac3_raw_bsi['roomtyp']); 1.184 + } 1.185 + 1.186 + if ($info_ac3_raw_bsi['acmod'] == 0x00) { 1.187 + // If acmod is 0, then two completely independent program channels (dual mono) 1.188 + // are encoded into the bit stream, and are referenced as Ch1, Ch2. In this case, 1.189 + // a number of additional items are present in BSI or audblk to fully describe Ch2. 1.190 + 1.191 + 1.192 + // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 131. 1.193 + // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent. 1.194 + $info_ac3_raw_bsi['dialnorm2'] = bindec(substr($ac3_header['bsi'], $offset, 5)); 1.195 + $offset += 5; 1.196 + 1.197 + $info_ac3['dialogue_normalization2'] = '-'.$info_ac3_raw_bsi['dialnorm2'].'dB'; 1.198 + 1.199 + $info_ac3_raw_bsi['compre_flag2'] = $ac3_header['bsi']{$offset++} == '1'; 1.200 + if ($info_ac3_raw_bsi['compre_flag2']) { 1.201 + $info_ac3_raw_bsi['compr2'] = bindec(substr($ac3_header['bsi'], $offset, 8)); 1.202 + $offset += 8; 1.203 + 1.204 + $info_ac3['heavy_compression2'] = getid3_ac3::AC3heavyCompression($info_ac3_raw_bsi['compr2']); 1.205 + } 1.206 + 1.207 + $info_ac3_raw_bsi['langcode_flag2'] = $ac3_header['bsi']{$offset++} == '1'; 1.208 + if ($info_ac3_raw_bsi['langcode_flag2']) { 1.209 + $info_ac3_raw_bsi['langcod2'] = bindec(substr($ac3_header['bsi'], $offset, 8)); 1.210 + $offset += 8; 1.211 + } 1.212 + 1.213 + $info_ac3_raw_bsi['audprodie2'] = $ac3_header['bsi']{$offset++} == '1'; 1.214 + if ($info_ac3_raw_bsi['audprodie2']) { 1.215 + $info_ac3_raw_bsi['mixlevel2'] = bindec(substr($ac3_header['bsi'], $offset, 5)); 1.216 + $offset += 5; 1.217 + 1.218 + $info_ac3_raw_bsi['roomtyp2'] = bindec(substr($ac3_header['bsi'], $offset, 2)); 1.219 + $offset += 2; 1.220 + 1.221 + $info_ac3['mixing_level2'] = (80 + $info_ac3_raw_bsi['mixlevel2']).'dB'; 1.222 + $info_ac3['room_type2'] = getid3_ac3::AC3roomTypeLookup($info_ac3_raw_bsi['roomtyp2']); 1.223 + } 1.224 + 1.225 + } 1.226 + 1.227 + $info_ac3_raw_bsi['copyright'] = $ac3_header['bsi']{$offset++} == '1'; 1.228 + 1.229 + $info_ac3_raw_bsi['original'] = $ac3_header['bsi']{$offset++} == '1'; 1.230 + 1.231 + $info_ac3_raw_bsi['timecode1_flag'] = $ac3_header['bsi']{$offset++} == '1'; 1.232 + if ($info_ac3_raw_bsi['timecode1_flag']) { 1.233 + $info_ac3_raw_bsi['timecode1'] = bindec(substr($ac3_header['bsi'], $offset, 14)); 1.234 + $offset += 14; 1.235 + } 1.236 + 1.237 + $info_ac3_raw_bsi['timecode2_flag'] = $ac3_header['bsi']{$offset++} == '1'; 1.238 + if ($info_ac3_raw_bsi['timecode2_flag']) { 1.239 + $info_ac3_raw_bsi['timecode2'] = bindec(substr($ac3_header['bsi'], $offset, 14)); 1.240 + $offset += 14; 1.241 + } 1.242 + 1.243 + $info_ac3_raw_bsi['addbsi_flag'] = $ac3_header['bsi']{$offset++} == '1'; 1.244 + if ($info_ac3_raw_bsi['addbsi_flag']) { 1.245 + $info_ac3_raw_bsi['addbsi_length'] = bindec(substr($ac3_header['bsi'], $offset, 6)); 1.246 + $offset += 6; 1.247 + 1.248 + $ac3_header['bsi'] .= getid3_lib::BigEndian2Bin($this->fread($info_ac3_raw_bsi['addbsi_length'])); 1.249 + 1.250 + $info_ac3_raw_bsi['addbsi_data'] = substr($ac3_header['bsi'], 119, $info_ac3_raw_bsi['addbsi_length'] * 8); 1.251 + } 1.252 + 1.253 + return true; 1.254 + } 1.255 + 1.256 + 1.257 + 1.258 + public static function AC3sampleRateCodeLookup($fscod) { 1.259 + 1.260 + static $lookup = array ( 1.261 + 0 => 48000, 1.262 + 1 => 44100, 1.263 + 2 => 32000, 1.264 + 3 => 'reserved' // If the reserved code is indicated, the decoder should not attempt to decode audio and should mute. 1.265 + ); 1.266 + return (isset($lookup[$fscod]) ? $lookup[$fscod] : false); 1.267 + } 1.268 + 1.269 + 1.270 + 1.271 + public static function AC3serviceTypeLookup($bsmod, $acmod) { 1.272 + 1.273 + static $lookup = array ( 1.274 + 0 => 'main audio service: complete main (CM)', 1.275 + 1 => 'main audio service: music and effects (ME)', 1.276 + 2 => 'associated service: visually impaired (VI)', 1.277 + 3 => 'associated service: hearing impaired (HI)', 1.278 + 4 => 'associated service: dialogue (D)', 1.279 + 5 => 'associated service: commentary (C)', 1.280 + 6 => 'associated service: emergency (E)', 1.281 + 7 => 'main audio service: karaoke' 1.282 + ); 1.283 + 1.284 + if ($bsmod == 7 && $acmod == 1) { 1.285 + return 'associated service: voice over (VO)'; 1.286 + } 1.287 + 1.288 + return (isset($lookup[$bsmod]) ? $lookup[$bsmod] : false); 1.289 + } 1.290 + 1.291 + 1.292 + 1.293 + public static function AC3audioCodingModeLookup($acmod) { 1.294 + 1.295 + // array (channel configuration, # channels (not incl LFE), channel order) 1.296 + static $lookup = array ( 1.297 + 0 => array ('channel_config'=>'1+1', 'num_channels'=>2, 'channel_order'=>'Ch1,Ch2'), 1.298 + 1 => array ('channel_config'=>'1/0', 'num_channels'=>1, 'channel_order'=>'C'), 1.299 + 2 => array ('channel_config'=>'2/0', 'num_channels'=>2, 'channel_order'=>'L,R'), 1.300 + 3 => array ('channel_config'=>'3/0', 'num_channels'=>3, 'channel_order'=>'L,C,R'), 1.301 + 4 => array ('channel_config'=>'2/1', 'num_channels'=>3, 'channel_order'=>'L,R,S'), 1.302 + 5 => array ('channel_config'=>'3/1', 'num_channels'=>4, 'channel_order'=>'L,C,R,S'), 1.303 + 6 => array ('channel_config'=>'2/2', 'num_channels'=>4, 'channel_order'=>'L,R,SL,SR'), 1.304 + 7 => array ('channel_config'=>'3/2', 'num_channels'=>5, 'channel_order'=>'L,C,R,SL,SR') 1.305 + ); 1.306 + return (isset($lookup[$acmod]) ? $lookup[$acmod] : false); 1.307 + } 1.308 + 1.309 + 1.310 + 1.311 + public static function AC3centerMixLevelLookup($cmixlev) { 1.312 + 1.313 + static $lookup; 1.314 + if (!@$lookup) { 1.315 + $lookup = array ( 1.316 + 0 => pow(2, -3.0 / 6), // 0.707 (3.0 dB) 1.317 + 1 => pow(2, -4.5 / 6), // 0.595 (4.5 dB) 1.318 + 2 => pow(2, -6.0 / 6), // 0.500 (6.0 dB) 1.319 + 3 => 'reserved' 1.320 + ); 1.321 + } 1.322 + return (isset($lookup[$cmixlev]) ? $lookup[$cmixlev] : false); 1.323 + } 1.324 + 1.325 + 1.326 + 1.327 + public static function AC3surroundMixLevelLookup($surmixlev) { 1.328 + 1.329 + static $lookup; 1.330 + if (!@$lookup) { 1.331 + $lookup = array ( 1.332 + 0 => pow(2, -3.0 / 6), 1.333 + 1 => pow(2, -6.0 / 6), 1.334 + 2 => 0, 1.335 + 3 => 'reserved' 1.336 + ); 1.337 + } 1.338 + return (isset($lookup[$surmixlev]) ? $lookup[$surmixlev] : false); 1.339 + } 1.340 + 1.341 + 1.342 + 1.343 + public static function AC3dolbySurroundModeLookup($dsurmod) { 1.344 + 1.345 + static $lookup = array ( 1.346 + 0 => 'not indicated', 1.347 + 1 => 'Not Dolby Surround encoded', 1.348 + 2 => 'Dolby Surround encoded', 1.349 + 3 => 'reserved' 1.350 + ); 1.351 + return (isset($lookup[$dsurmod]) ? $lookup[$dsurmod] : false); 1.352 + } 1.353 + 1.354 + 1.355 + 1.356 + public static function AC3channelsEnabledLookup($acmod, $lfeon) { 1.357 + 1.358 + return array ( 1.359 + 'ch1' => $acmod == 0, 1.360 + 'ch2' => $acmod == 0, 1.361 + 'left' => $acmod > 1, 1.362 + 'right' => $acmod > 1, 1.363 + 'center' => (bool)($acmod & 0x01), 1.364 + 'surround_mono' => $acmod == 4 || $acmod == 5, 1.365 + 'surround_left' => $acmod == 6 || $acmod == 7, 1.366 + 'surround_right' => $acmod == 6 || $acmod == 7, 1.367 + 'lfe' => $lfeon 1.368 + ); 1.369 + } 1.370 + 1.371 + 1.372 + 1.373 + public static function AC3heavyCompression($compre) { 1.374 + 1.375 + // The first four bits indicate gain changes in 6.02dB increments which can be 1.376 + // implemented with an arithmetic shift operation. The following four bits 1.377 + // indicate linear gain changes, and require a 5-bit multiply. 1.378 + // We will represent the two 4-bit fields of compr as follows: 1.379 + // X0 X1 X2 X3 . Y4 Y5 Y6 Y7 1.380 + // The meaning of the X values is most simply described by considering X to represent a 4-bit 1.381 + // signed integer with values from 8 to +7. The gain indicated by X is then (X + 1) * 6.02 dB. The 1.382 + // following table shows this in detail. 1.383 + 1.384 + // Meaning of 4 msb of compr 1.385 + // 7 +48.16 dB 1.386 + // 6 +42.14 dB 1.387 + // 5 +36.12 dB 1.388 + // 4 +30.10 dB 1.389 + // 3 +24.08 dB 1.390 + // 2 +18.06 dB 1.391 + // 1 +12.04 dB 1.392 + // 0 +6.02 dB 1.393 + // -1 0 dB 1.394 + // -2 6.02 dB 1.395 + // -3 12.04 dB 1.396 + // -4 18.06 dB 1.397 + // -5 24.08 dB 1.398 + // -6 30.10 dB 1.399 + // -7 36.12 dB 1.400 + // -8 42.14 dB 1.401 + 1.402 + $fourbit = str_pad(decbin(($compre & 0xF0) >> 4), 4, '0', STR_PAD_LEFT); 1.403 + if ($fourbit{0} == '1') { 1.404 + $log_gain = -8 + bindec(substr($fourbit, 1)); 1.405 + } else { 1.406 + $log_gain = bindec(substr($fourbit, 1)); 1.407 + } 1.408 + $log_gain = ($log_gain + 1) * (20 * log10(2)); 1.409 + 1.410 + // The value of Y is a linear representation of a gain change of up to 6 dB. Y is considered to 1.411 + // be an unsigned fractional integer, with a leading value of 1, or: 0.1 Y4 Y5 Y6 Y7 (base 2). Y can 1.412 + // represent values between 0.111112 (or 31/32) and 0.100002 (or 1/2). Thus, Y can represent gain 1.413 + // changes from 0.28 dB to 6.02 dB. 1.414 + 1.415 + $lin_gain = (16 + ($compre & 0x0F)) / 32; 1.416 + 1.417 + // The combination of X and Y values allows compr to indicate gain changes from 1.418 + // 48.16 0.28 = +47.89 dB, to 1.419 + // 42.14 6.02 = 48.16 dB. 1.420 + 1.421 + return $log_gain - $lin_gain; 1.422 + } 1.423 + 1.424 + 1.425 + 1.426 + public static function AC3roomTypeLookup($roomtyp) { 1.427 + 1.428 + static $lookup = array ( 1.429 + 0 => 'not indicated', 1.430 + 1 => 'large room, X curve monitor', 1.431 + 2 => 'small room, flat monitor', 1.432 + 3 => 'reserved' 1.433 + ); 1.434 + return (isset($lookup[$roomtyp]) ? $lookup[$roomtyp] : false); 1.435 + } 1.436 + 1.437 + 1.438 + 1.439 + public static function AC3frameSizeLookup($frmsizecod, $fscod) { 1.440 + 1.441 + $padding = (bool)($frmsizecod % 2); 1.442 + $frame_size_id = floor($frmsizecod / 2); 1.443 + 1.444 + static $lookup = array ( 1.445 + 0 => array (128, 138, 192), 1.446 + 1 => array (40, 160, 174, 240), 1.447 + 2 => array (48, 192, 208, 288), 1.448 + 3 => array (56, 224, 242, 336), 1.449 + 4 => array (64, 256, 278, 384), 1.450 + 5 => array (80, 320, 348, 480), 1.451 + 6 => array (96, 384, 416, 576), 1.452 + 7 => array (112, 448, 486, 672), 1.453 + 8 => array (128, 512, 556, 768), 1.454 + 9 => array (160, 640, 696, 960), 1.455 + 10 => array (192, 768, 834, 1152), 1.456 + 11 => array (224, 896, 974, 1344), 1.457 + 12 => array (256, 1024, 1114, 1536), 1.458 + 13 => array (320, 1280, 1392, 1920), 1.459 + 14 => array (384, 1536, 1670, 2304), 1.460 + 15 => array (448, 1792, 1950, 2688), 1.461 + 16 => array (512, 2048, 2228, 3072), 1.462 + 17 => array (576, 2304, 2506, 3456), 1.463 + 18 => array (640, 2560, 2786, 3840) 1.464 + ); 1.465 + if (($fscod == 1) && $padding) { 1.466 + // frame lengths are padded by 1 word (16 bits) at 44100 1.467 + $lookup[$frmsizecod] += 2; 1.468 + } 1.469 + return (isset($lookup[$frame_size_id][$fscod]) ? $lookup[$frame_size_id][$fscod] : false); 1.470 + } 1.471 + 1.472 + 1.473 + 1.474 + public static function AC3bitrateLookup($frmsizecod) { 1.475 + 1.476 + static $lookup = array ( 1.477 + 0 => 32000, 1.478 + 1 => 40000, 1.479 + 2 => 48000, 1.480 + 3 => 56000, 1.481 + 4 => 64000, 1.482 + 5 => 80000, 1.483 + 6 => 96000, 1.484 + 7 => 112000, 1.485 + 8 => 128000, 1.486 + 9 => 160000, 1.487 + 10 => 192000, 1.488 + 11 => 224000, 1.489 + 12 => 256000, 1.490 + 13 => 320000, 1.491 + 14 => 384000, 1.492 + 15 => 448000, 1.493 + 16 => 512000, 1.494 + 17 => 576000, 1.495 + 18 => 640000 1.496 + ); 1.497 + $frame_size_id = floor($frmsizecod / 2); 1.498 + return (isset($lookup[$frame_size_id]) ? $lookup[$frame_size_id] : false); 1.499 + } 1.500 + 1.501 +} 1.502 + 1.503 +?> 1.504 \ No newline at end of file