Mercurial > judyates
diff e2gallerypro/e2upload/Backend/Assets/getid3/module.audio.aac_adts.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.aac_adts.php Mon Feb 22 08:02:39 2010 -0500 1.3 @@ -0,0 +1,282 @@ 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.aac_adts.php | 1.21 +// | Module for analyzing AAC files with ADTS header. | 1.22 +// | dependencies: NONE | 1.23 +// +----------------------------------------------------------------------+ 1.24 +// 1.25 +// $Id: module.audio.aac_adts.php,v 1.4 2006/11/02 10:48:01 ah Exp $ 1.26 + 1.27 + 1.28 + 1.29 +class getid3_aac_adts extends getid3_handler 1.30 +{ 1.31 + 1.32 + public $option_max_frames_to_scan = 1000000; 1.33 + public $option_return_extended_info = false; 1.34 + 1.35 + 1.36 + private $decbin_cache; 1.37 + private $bitrate_cache; 1.38 + 1.39 + 1.40 + 1.41 + public function __construct(getID3 $getid3) { 1.42 + 1.43 + parent::__construct($getid3); 1.44 + 1.45 + // Populate bindec_cache 1.46 + for ($i = 0; $i < 256; $i++) { 1.47 + $this->decbin_cache[chr($i)] = str_pad(decbin($i), 8, '0', STR_PAD_LEFT); 1.48 + } 1.49 + 1.50 + // Init cache 1.51 + $this->bitrate_cache = array (); 1.52 + 1.53 + // Fast scanning? 1.54 + if (!$getid3->option_accurate_results) { 1.55 + $this->option_max_frames_to_scan = 200; 1.56 + $getid3->warning('option_accurate_results set to false - bitrate and playing time are not accurate.'); 1.57 + } 1.58 + } 1.59 + 1.60 + 1.61 + 1.62 + public function Analyze() { 1.63 + 1.64 + $getid3 = $this->getid3; 1.65 + 1.66 + // based loosely on code from AACfile by Jurgen Faul <jfaulØgmx.de> 1.67 + // http://jfaul.de/atl or http://j-faul.virtualave.net/atl/atl.html 1.68 + 1.69 + 1.70 + // http://faac.sourceforge.net/wiki/index.php?page=ADTS 1.71 + 1.72 + // * ADTS Fixed Header: these don't change from frame to frame 1.73 + // syncword 12 always: '111111111111' 1.74 + // ID 1 0: MPEG-4, 1: MPEG-2 1.75 + // layer 2 always: '00' 1.76 + // protection_absent 1 1.77 + // profile 2 1.78 + // sampling_frequency_index 4 1.79 + // private_bit 1 1.80 + // channel_configuration 3 1.81 + // original/copy 1 1.82 + // home 1 1.83 + // emphasis 2 only if ID == 0 (ie MPEG-4) 1.84 + 1.85 + // * ADTS Variable Header: these can change from frame to frame 1.86 + // copyright_identification_bit 1 1.87 + // copyright_identification_start 1 1.88 + // aac_frame_length 13 length of the frame including header (in bytes) 1.89 + // adts_buffer_fullness 11 0x7FF indicates VBR 1.90 + // no_raw_data_blocks_in_frame 2 1.91 + 1.92 + // * ADTS Error check 1.93 + // crc_check 16 only if protection_absent == 0 1.94 + 1.95 + $getid3->info['aac']['header'] = array () ; 1.96 + $info_aac = &$getid3->info['aac']; 1.97 + $info_aac_header = & $info_aac['header']; 1.98 + 1.99 + $byte_offset = $frame_number = 0; 1.100 + 1.101 + while (true) { 1.102 + 1.103 + // Breaks out when end-of-file encountered, or invalid data found, 1.104 + // or MaxFramesToScan frames have been scanned 1.105 + 1.106 + fseek($getid3->fp, $byte_offset, SEEK_SET); 1.107 + 1.108 + // First get substring 1.109 + $sub_string = fread($getid3->fp, 10); 1.110 + $sub_string_length = strlen($sub_string); 1.111 + if ($sub_string_length != 10) { 1.112 + throw new getid3_exception('Failed to read 10 bytes at offset '.(ftell($getid3->fp) - $sub_string_length).' (only read '.$sub_string_length.' bytes)'); 1.113 + } 1.114 + 1.115 + // Initialise $aac_header_bitstream 1.116 + $aac_header_bitstream = ''; 1.117 + 1.118 + // Loop thru substring chars 1.119 + for ($i = 0; $i < 10; $i++) { 1.120 + $aac_header_bitstream .= $this->decbin_cache[$sub_string[$i]]; 1.121 + } 1.122 + 1.123 + $sync_test = bindec(substr($aac_header_bitstream, 0, 12)); 1.124 + $bit_offset = 12; 1.125 + 1.126 + if ($sync_test != 0x0FFF) { 1.127 + throw new getid3_exception('Synch pattern (0x0FFF) not found at offset '.(ftell($getid3->fp) - 10).' (found 0x0'.strtoupper(dechex($sync_test)).' instead)'); 1.128 + } 1.129 + 1.130 + // Only gather info once - this takes time to do 1000 times! 1.131 + if ($frame_number > 0) { 1.132 + 1.133 + // MPEG-4: 20, // MPEG-2: 18 1.134 + $bit_offset += $aac_header_bitstream[$bit_offset] ? 18 : 20; 1.135 + } 1.136 + 1.137 + // Gather info for first frame only - this takes time to do 1000 times! 1.138 + else { 1.139 + 1.140 + $info_aac['header_type'] = 'ADTS'; 1.141 + $info_aac_header['synch'] = $sync_test; 1.142 + $getid3->info['fileformat'] = 'aac'; 1.143 + $getid3->info['audio']['dataformat'] = 'aac'; 1.144 + 1.145 + $info_aac_header['mpeg_version'] = $aac_header_bitstream{$bit_offset++} == '0' ? 4 : 2; 1.146 + $info_aac_header['layer'] = bindec(substr($aac_header_bitstream, $bit_offset, 2)); 1.147 + $bit_offset += 2; 1.148 + 1.149 + if ($info_aac_header['layer'] != 0) { 1.150 + throw new getid3_exception('Layer error - expected 0x00, found 0x'.dechex($info_aac_header['layer']).' instead'); 1.151 + } 1.152 + 1.153 + $info_aac_header['crc_present'] = $aac_header_bitstream{$bit_offset++} == '0' ? true : false; 1.154 + 1.155 + $info_aac_header['profile_id'] = bindec(substr($aac_header_bitstream, $bit_offset, 2)); 1.156 + $bit_offset += 2; 1.157 + 1.158 + $info_aac_header['profile_text'] = getid3_aac_adts::AACprofileLookup($info_aac_header['profile_id'], $info_aac_header['mpeg_version']); 1.159 + 1.160 + $info_aac_header['sample_frequency_index'] = bindec(substr($aac_header_bitstream, $bit_offset, 4)); 1.161 + $bit_offset += 4; 1.162 + 1.163 + $info_aac_header['sample_frequency'] = getid3_aac_adts::AACsampleRateLookup($info_aac_header['sample_frequency_index']); 1.164 + 1.165 + $getid3->info['audio']['sample_rate'] = $info_aac_header['sample_frequency']; 1.166 + 1.167 + $info_aac_header['private'] = $aac_header_bitstream{$bit_offset++} == 1; 1.168 + 1.169 + $info_aac_header['channel_configuration'] = $getid3->info['audio']['channels'] = bindec(substr($aac_header_bitstream, $bit_offset, 3)); 1.170 + $bit_offset += 3; 1.171 + 1.172 + $info_aac_header['original'] = $aac_header_bitstream{$bit_offset++} == 1; 1.173 + $info_aac_header['home'] = $aac_header_bitstream{$bit_offset++} == 1; 1.174 + 1.175 + if ($info_aac_header['mpeg_version'] == 4) { 1.176 + $info_aac_header['emphasis'] = bindec(substr($aac_header_bitstream, $bit_offset, 2)); 1.177 + $bit_offset += 2; 1.178 + } 1.179 + 1.180 + if ($this->option_return_extended_info) { 1.181 + 1.182 + $info_aac[$frame_number]['copyright_id_bit'] = $aac_header_bitstream{$bit_offset++} == 1; 1.183 + $info_aac[$frame_number]['copyright_id_start'] = $aac_header_bitstream{$bit_offset++} == 1; 1.184 + 1.185 + } else { 1.186 + $bit_offset += 2; 1.187 + } 1.188 + } 1.189 + 1.190 + $frame_length = bindec(substr($aac_header_bitstream, $bit_offset, 13)); 1.191 + 1.192 + if (!isset($this->bitrate_cache[$frame_length])) { 1.193 + $this->bitrate_cache[$frame_length] = ($info_aac_header['sample_frequency'] / 1024) * $frame_length * 8; 1.194 + } 1.195 + @$info_aac['bitrate_distribution'][$this->bitrate_cache[$frame_length]]++; 1.196 + 1.197 + $info_aac[$frame_number]['aac_frame_length'] = $frame_length; 1.198 + $bit_offset += 13; 1.199 + 1.200 + $info_aac[$frame_number]['adts_buffer_fullness'] = bindec(substr($aac_header_bitstream, $bit_offset, 11)); 1.201 + $bit_offset += 11; 1.202 + 1.203 + $getid3->info['audio']['bitrate_mode'] = ($info_aac[$frame_number]['adts_buffer_fullness'] == 0x07FF) ? 'vbr' : 'cbr'; 1.204 + 1.205 + $info_aac[$frame_number]['num_raw_data_blocks'] = bindec(substr($aac_header_bitstream, $bit_offset, 2)); 1.206 + $bit_offset += 2; 1.207 + 1.208 + if ($info_aac_header['crc_present']) { 1.209 + $bit_offset += 16; 1.210 + } 1.211 + 1.212 + if (!$this->option_return_extended_info) { 1.213 + unset($info_aac[$frame_number]); 1.214 + } 1.215 + 1.216 + $byte_offset += $frame_length; 1.217 + if ((++$frame_number < $this->option_max_frames_to_scan) && (($byte_offset + 10) < $getid3->info['avdataend'])) { 1.218 + 1.219 + // keep scanning 1.220 + 1.221 + } else { 1.222 + 1.223 + $info_aac['frames'] = $frame_number; 1.224 + $getid3->info['playtime_seconds'] = ($getid3->info['avdataend'] / $byte_offset) * (($frame_number * 1024) / $info_aac_header['sample_frequency']); // (1 / % of file scanned) * (samples / (samples/sec)) = seconds 1.225 + $getid3->info['audio']['bitrate'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / $getid3->info['playtime_seconds']; 1.226 + ksort($info_aac['bitrate_distribution']); 1.227 + 1.228 + $getid3->info['audio']['encoder_options'] = $info_aac['header_type'].' '.$info_aac_header['profile_text']; 1.229 + 1.230 + return true; 1.231 + } 1.232 + } 1.233 + } 1.234 + 1.235 + 1.236 + 1.237 + public static function AACsampleRateLookup($samplerate_id) { 1.238 + 1.239 + static $lookup = array ( 1.240 + 0 => 96000, 1.241 + 1 => 88200, 1.242 + 2 => 64000, 1.243 + 3 => 48000, 1.244 + 4 => 44100, 1.245 + 5 => 32000, 1.246 + 6 => 24000, 1.247 + 7 => 22050, 1.248 + 8 => 16000, 1.249 + 9 => 12000, 1.250 + 10 => 11025, 1.251 + 11 => 8000, 1.252 + 12 => 0, 1.253 + 13 => 0, 1.254 + 14 => 0, 1.255 + 15 => 0 1.256 + ); 1.257 + return (isset($lookup[$samplerate_id]) ? $lookup[$samplerate_id] : 'invalid'); 1.258 + } 1.259 + 1.260 + 1.261 + 1.262 + public static function AACprofileLookup($profile_id, $mpeg_version) { 1.263 + 1.264 + static $lookup = array ( 1.265 + 2 => array ( 1.266 + 0 => 'Main profile', 1.267 + 1 => 'Low Complexity profile (LC)', 1.268 + 2 => 'Scalable Sample Rate profile (SSR)', 1.269 + 3 => '(reserved)' 1.270 + ), 1.271 + 4 => array ( 1.272 + 0 => 'AAC_MAIN', 1.273 + 1 => 'AAC_LC', 1.274 + 2 => 'AAC_SSR', 1.275 + 3 => 'AAC_LTP' 1.276 + ) 1.277 + ); 1.278 + return (isset($lookup[$mpeg_version][$profile_id]) ? $lookup[$mpeg_version][$profile_id] : 'invalid'); 1.279 + } 1.280 + 1.281 + 1.282 +} 1.283 + 1.284 + 1.285 +?> 1.286 \ No newline at end of file