annotate e2gallerypro/e2upload/Backend/Assets/getid3/module.audio.aac_adif.php @ 25:6a3d04638a89 judyates

mailto links.
author Robert McIntyre <rlm@mit.edu>
date Sat, 19 Jul 2014 14:35:52 -0400
parents 3f6b44aa6b35
children
rev   line source
rlm@3 1 <?php
rlm@3 2 // +----------------------------------------------------------------------+
rlm@3 3 // | PHP version 5 |
rlm@3 4 // +----------------------------------------------------------------------+
rlm@3 5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
rlm@3 6 // +----------------------------------------------------------------------+
rlm@3 7 // | This source file is subject to version 2 of the GPL license, |
rlm@3 8 // | that is bundled with this package in the file license.txt and is |
rlm@3 9 // | available through the world-wide-web at the following url: |
rlm@3 10 // | http://www.gnu.org/copyleft/gpl.html |
rlm@3 11 // +----------------------------------------------------------------------+
rlm@3 12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
rlm@3 13 // +----------------------------------------------------------------------+
rlm@3 14 // | Authors: James Heinrich <infoØgetid3*org> |
rlm@3 15 // | Allan Hansen <ahØartemis*dk> |
rlm@3 16 // +----------------------------------------------------------------------+
rlm@3 17 // | module.audio.aac_adif.php |
rlm@3 18 // | Module for analyzing AAC files with ADIF header. |
rlm@3 19 // | dependencies: NONE |
rlm@3 20 // +----------------------------------------------------------------------+
rlm@3 21 //
rlm@3 22 // $Id: module.audio.aac_adif.php,v 1.3 2006/11/02 10:48:00 ah Exp $
rlm@3 23
rlm@3 24
rlm@3 25
rlm@3 26 class getid3_aac_adif extends getid3_handler
rlm@3 27 {
rlm@3 28
rlm@3 29 public function Analyze() {
rlm@3 30
rlm@3 31 $getid3 = $this->getid3;
rlm@3 32
rlm@3 33 // http://faac.sourceforge.net/wiki/index.php?page=ADIF
rlm@3 34 // http://libmpeg.org/mpeg4/doc/w2203tfs.pdf
rlm@3 35 // adif_header() {
rlm@3 36 // adif_id 32
rlm@3 37 // copyright_id_present 1
rlm@3 38 // if( copyright_id_present )
rlm@3 39 // copyright_id 72
rlm@3 40 // original_copy 1
rlm@3 41 // home 1
rlm@3 42 // bitstream_type 1
rlm@3 43 // bitrate 23
rlm@3 44 // num_program_config_elements 4
rlm@3 45 // for (i = 0; i < num_program_config_elements + 1; i++ ) {
rlm@3 46 // if( bitstream_type == '0' )
rlm@3 47 // adif_buffer_fullness 20
rlm@3 48 // program_config_element()
rlm@3 49 // }
rlm@3 50 // }
rlm@3 51
rlm@3 52
rlm@3 53 $getid3->info['fileformat'] = 'aac';
rlm@3 54 $getid3->info['audio']['dataformat'] = 'aac';
rlm@3 55 $getid3->info['audio']['lossless'] = false;
rlm@3 56
rlm@3 57 $getid3->info['aac']['header'] = array () ;
rlm@3 58 $info_aac = &$getid3->info['aac'];
rlm@3 59 $info_aac_header = & $info_aac['header'];
rlm@3 60
rlm@3 61 fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET);
rlm@3 62 $aac_header_bitstream = getid3_lib::BigEndian2Bin(fread($getid3->fp, 1024));
rlm@3 63
rlm@3 64 $info_aac['header_type'] = 'ADIF';
rlm@3 65 $info_aac_header['mpeg_version'] = 4;
rlm@3 66 $bit_offset = 32;
rlm@3 67
rlm@3 68 $info_aac_header['copyright'] = $aac_header_bitstream{$bit_offset++} == '1';
rlm@3 69 if ($info_aac_header['copyright']) {
rlm@3 70 $info_aac_header['copyright_id'] = getid3_aac_adif::Bin2String(substr($aac_header_bitstream, $bit_offset, 72));
rlm@3 71 $bit_offset += 72;
rlm@3 72 }
rlm@3 73
rlm@3 74 $info_aac_header['original_copy'] = $aac_header_bitstream{$bit_offset++} == '1';
rlm@3 75 $info_aac_header['home'] = $aac_header_bitstream{$bit_offset++} == '1';
rlm@3 76 $info_aac_header['is_vbr'] = $aac_header_bitstream{$bit_offset++} == '1';
rlm@3 77
rlm@3 78 if ($info_aac_header['is_vbr']) {
rlm@3 79 $getid3->info['audio']['bitrate_mode'] = 'vbr';
rlm@3 80 $info_aac_header['bitrate_max'] = bindec(substr($aac_header_bitstream, $bit_offset, 23));
rlm@3 81 $bit_offset += 23;
rlm@3 82 }
rlm@3 83 else {
rlm@3 84 $getid3->info['audio']['bitrate_mode'] = 'cbr';
rlm@3 85 $info_aac_header['bitrate'] = bindec(substr($aac_header_bitstream, $bit_offset, 23));
rlm@3 86 $bit_offset += 23;
rlm@3 87 $getid3->info['audio']['bitrate'] = $info_aac_header['bitrate'];
rlm@3 88 }
rlm@3 89
rlm@3 90 $info_aac_header['num_program_configs'] = 1 + bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 91 $bit_offset += 4;
rlm@3 92
rlm@3 93 for ($i = 0; $i < $info_aac_header['num_program_configs']; $i++) {
rlm@3 94
rlm@3 95 // http://www.audiocoding.com/wiki/index.php?page=program_config_element
rlm@3 96
rlm@3 97 // buffer_fullness 20
rlm@3 98
rlm@3 99 // element_instance_tag 4
rlm@3 100 // object_type 2
rlm@3 101 // sampling_frequency_index 4
rlm@3 102 // num_front_channel_elements 4
rlm@3 103 // num_side_channel_elements 4
rlm@3 104 // num_back_channel_elements 4
rlm@3 105 // num_lfe_channel_elements 2
rlm@3 106 // num_assoc_data_elements 3
rlm@3 107 // num_valid_cc_elements 4
rlm@3 108 // mono_mixdown_present 1
rlm@3 109 // mono_mixdown_element_number 4 if mono_mixdown_present == 1
rlm@3 110 // stereo_mixdown_present 1
rlm@3 111 // stereo_mixdown_element_number 4 if stereo_mixdown_present == 1
rlm@3 112 // matrix_mixdown_idx_present 1
rlm@3 113 // matrix_mixdown_idx 2 if matrix_mixdown_idx_present == 1
rlm@3 114 // pseudo_surround_enable 1 if matrix_mixdown_idx_present == 1
rlm@3 115 // for (i = 0; i < num_front_channel_elements; i++) {
rlm@3 116 // front_element_is_cpe[i] 1
rlm@3 117 // front_element_tag_select[i] 4
rlm@3 118 // }
rlm@3 119 // for (i = 0; i < num_side_channel_elements; i++) {
rlm@3 120 // side_element_is_cpe[i] 1
rlm@3 121 // side_element_tag_select[i] 4
rlm@3 122 // }
rlm@3 123 // for (i = 0; i < num_back_channel_elements; i++) {
rlm@3 124 // back_element_is_cpe[i] 1
rlm@3 125 // back_element_tag_select[i] 4
rlm@3 126 // }
rlm@3 127 // for (i = 0; i < num_lfe_channel_elements; i++) {
rlm@3 128 // lfe_element_tag_select[i] 4
rlm@3 129 // }
rlm@3 130 // for (i = 0; i < num_assoc_data_elements; i++) {
rlm@3 131 // assoc_data_element_tag_select[i] 4
rlm@3 132 // }
rlm@3 133 // for (i = 0; i < num_valid_cc_elements; i++) {
rlm@3 134 // cc_element_is_ind_sw[i] 1
rlm@3 135 // valid_cc_element_tag_select[i] 4
rlm@3 136 // }
rlm@3 137 // byte_alignment() VAR
rlm@3 138 // comment_field_bytes 8
rlm@3 139 // for (i = 0; i < comment_field_bytes; i++) {
rlm@3 140 // comment_field_data[i] 8
rlm@3 141 // }
rlm@3 142
rlm@3 143 $info_aac['program_configs'][$i] = array ();
rlm@3 144 $info_aac_program_configs_i = &$info_aac['program_configs'][$i];
rlm@3 145
rlm@3 146 if (!$info_aac_header['is_vbr']) {
rlm@3 147 $info_aac_program_configs_i['buffer_fullness'] = bindec(substr($aac_header_bitstream, $bit_offset, 20));
rlm@3 148 $bit_offset += 20;
rlm@3 149 }
rlm@3 150
rlm@3 151 $info_aac_program_configs_i['element_instance_tag'] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 152 $info_aac_program_configs_i['object_type'] = bindec(substr($aac_header_bitstream, $bit_offset + 4, 2));
rlm@3 153 $info_aac_program_configs_i['sampling_frequency_index'] = bindec(substr($aac_header_bitstream, $bit_offset + 6, 4));
rlm@3 154 $info_aac_program_configs_i['num_front_channel_elements'] = bindec(substr($aac_header_bitstream, $bit_offset + 10, 4));
rlm@3 155 $info_aac_program_configs_i['num_side_channel_elements'] = bindec(substr($aac_header_bitstream, $bit_offset + 14, 4));
rlm@3 156 $info_aac_program_configs_i['num_back_channel_elements'] = bindec(substr($aac_header_bitstream, $bit_offset + 18, 4));
rlm@3 157 $info_aac_program_configs_i['num_lfe_channel_elements'] = bindec(substr($aac_header_bitstream, $bit_offset + 22, 2));
rlm@3 158 $info_aac_program_configs_i['num_assoc_data_elements'] = bindec(substr($aac_header_bitstream, $bit_offset + 24, 3));
rlm@3 159 $info_aac_program_configs_i['num_valid_cc_elements'] = bindec(substr($aac_header_bitstream, $bit_offset + 27, 4));
rlm@3 160 $bit_offset += 31;
rlm@3 161
rlm@3 162 $info_aac_program_configs_i['mono_mixdown_present'] = $aac_header_bitstream{$bit_offset++} == 1;
rlm@3 163 if ($info_aac_program_configs_i['mono_mixdown_present']) {
rlm@3 164 $info_aac_program_configs_i['mono_mixdown_element_number'] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 165 $bit_offset += 4;
rlm@3 166 }
rlm@3 167
rlm@3 168 $info_aac_program_configs_i['stereo_mixdown_present'] = $aac_header_bitstream{$bit_offset++} == 1;
rlm@3 169 if ($info_aac_program_configs_i['stereo_mixdown_present']) {
rlm@3 170 $info_aac_program_configs_i['stereo_mixdown_element_number'] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 171 $bit_offset += 4;
rlm@3 172 }
rlm@3 173
rlm@3 174 $info_aac_program_configs_i['matrix_mixdown_idx_present'] = $aac_header_bitstream{$bit_offset++} == 1;
rlm@3 175 if ($info_aac_program_configs_i['matrix_mixdown_idx_present']) {
rlm@3 176 $info_aac_program_configs_i['matrix_mixdown_idx'] = bindec(substr($aac_header_bitstream, $bit_offset, 2));
rlm@3 177 $bit_offset += 2;
rlm@3 178 $info_aac_program_configs_i['pseudo_surround_enable'] = $aac_header_bitstream{$bit_offset++} == 1;
rlm@3 179 }
rlm@3 180
rlm@3 181 for ($j = 0; $j < $info_aac_program_configs_i['num_front_channel_elements']; $j++) {
rlm@3 182 $info_aac_program_configs_i['front_element_is_cpe'][$j] = $aac_header_bitstream{$bit_offset++} == 1;
rlm@3 183 $info_aac_program_configs_i['front_element_tag_select'][$j] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 184 $bit_offset += 4;
rlm@3 185 }
rlm@3 186 for ($j = 0; $j < $info_aac_program_configs_i['num_side_channel_elements']; $j++) {
rlm@3 187 $info_aac_program_configs_i['side_element_is_cpe'][$j] = $aac_header_bitstream{$bit_offset++} == 1;
rlm@3 188 $info_aac_program_configs_i['side_element_tag_select'][$j] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 189 $bit_offset += 4;
rlm@3 190 }
rlm@3 191 for ($j = 0; $j < $info_aac_program_configs_i['num_back_channel_elements']; $j++) {
rlm@3 192 $info_aac_program_configs_i['back_element_is_cpe'][$j] = $aac_header_bitstream{$bit_offset++} == 1;
rlm@3 193 $info_aac_program_configs_i['back_element_tag_select'][$j] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 194 $bit_offset += 4;
rlm@3 195 }
rlm@3 196 for ($j = 0; $j < $info_aac_program_configs_i['num_lfe_channel_elements']; $j++) {
rlm@3 197 $info_aac_program_configs_i['lfe_element_tag_select'][$j] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 198 $bit_offset += 4;
rlm@3 199 }
rlm@3 200 for ($j = 0; $j < $info_aac_program_configs_i['num_assoc_data_elements']; $j++) {
rlm@3 201 $info_aac_program_configs_i['assoc_data_element_tag_select'][$j] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 202 $bit_offset += 4;
rlm@3 203 }
rlm@3 204 for ($j = 0; $j < $info_aac_program_configs_i['num_valid_cc_elements']; $j++) {
rlm@3 205 $info_aac_program_configs_i['cc_element_is_ind_sw'][$j] = $aac_header_bitstream{$bit_offset++} == 1;
rlm@3 206 $info_aac_program_configs_i['valid_cc_element_tag_select'][$j] = bindec(substr($aac_header_bitstream, $bit_offset, 4));
rlm@3 207 $bit_offset += 4;
rlm@3 208 }
rlm@3 209
rlm@3 210 $bit_offset = ceil($bit_offset / 8) * 8;
rlm@3 211
rlm@3 212 $info_aac_program_configs_i['comment_field_bytes'] = bindec(substr($aac_header_bitstream, $bit_offset, 8));
rlm@3 213 $bit_offset += 8;
rlm@3 214
rlm@3 215 $info_aac_program_configs_i['comment_field'] = getid3_aac_adif::Bin2String(substr($aac_header_bitstream, $bit_offset, 8 * $info_aac_program_configs_i['comment_field_bytes']));
rlm@3 216 $bit_offset += 8 * $info_aac_program_configs_i['comment_field_bytes'];
rlm@3 217
rlm@3 218 $info_aac_header['profile_text'] = getid3_aac_adif::AACprofileLookup($info_aac_program_configs_i['object_type'], $info_aac_header['mpeg_version']);
rlm@3 219 $info_aac_program_configs_i['sampling_frequency'] = $getid3->info['audio']['sample_rate'] = getid3_aac_adif::AACsampleRateLookup($info_aac_program_configs_i['sampling_frequency_index']);
rlm@3 220 $getid3->info['audio']['channels'] = getid3_aac_adif::AACchannelCountCalculate($info_aac_program_configs_i);
rlm@3 221
rlm@3 222 if ($info_aac_program_configs_i['comment_field']) {
rlm@3 223 $info_aac['comments'][] = $info_aac_program_configs_i['comment_field'];
rlm@3 224 }
rlm@3 225 }
rlm@3 226
rlm@3 227 $getid3->info['playtime_seconds'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / $getid3->info['audio']['bitrate'];
rlm@3 228 $getid3->info['audio']['encoder_options'] = $info_aac['header_type'].' '.$info_aac_header['profile_text'];
rlm@3 229
rlm@3 230 return true;
rlm@3 231 }
rlm@3 232
rlm@3 233
rlm@3 234
rlm@3 235 public static function Bin2String($bin_string) {
rlm@3 236 // return 'hi' for input of '0110100001101001'
rlm@3 237 $string = '';
rlm@3 238 $bin_string_reversed = strrev($bin_string);
rlm@3 239 for ($i = 0; $i < strlen($bin_string_reversed); $i += 8) {
rlm@3 240 $string = chr(bindec(strrev(substr($bin_string_reversed, $i, 8)))).$string;
rlm@3 241 }
rlm@3 242 return $string;
rlm@3 243 }
rlm@3 244
rlm@3 245
rlm@3 246
rlm@3 247 public static function AACsampleRateLookup($samplerate_id) {
rlm@3 248
rlm@3 249 static $lookup = array (
rlm@3 250 0 => 96000,
rlm@3 251 1 => 88200,
rlm@3 252 2 => 64000,
rlm@3 253 3 => 48000,
rlm@3 254 4 => 44100,
rlm@3 255 5 => 32000,
rlm@3 256 6 => 24000,
rlm@3 257 7 => 22050,
rlm@3 258 8 => 16000,
rlm@3 259 9 => 12000,
rlm@3 260 10 => 11025,
rlm@3 261 11 => 8000,
rlm@3 262 12 => 0,
rlm@3 263 13 => 0,
rlm@3 264 14 => 0,
rlm@3 265 15 => 0
rlm@3 266 );
rlm@3 267 return (isset($lookup[$samplerate_id]) ? $lookup[$samplerate_id] : 'invalid');
rlm@3 268 }
rlm@3 269
rlm@3 270
rlm@3 271
rlm@3 272 public static function AACprofileLookup($profile_id, $mpeg_version) {
rlm@3 273
rlm@3 274 static $lookup = array (
rlm@3 275 2 => array (
rlm@3 276 0 => 'Main profile',
rlm@3 277 1 => 'Low Complexity profile (LC)',
rlm@3 278 2 => 'Scalable Sample Rate profile (SSR)',
rlm@3 279 3 => '(reserved)'
rlm@3 280 ),
rlm@3 281 4 => array (
rlm@3 282 0 => 'AAC_MAIN',
rlm@3 283 1 => 'AAC_LC',
rlm@3 284 2 => 'AAC_SSR',
rlm@3 285 3 => 'AAC_LTP'
rlm@3 286 )
rlm@3 287 );
rlm@3 288 return (isset($lookup[$mpeg_version][$profile_id]) ? $lookup[$mpeg_version][$profile_id] : 'invalid');
rlm@3 289 }
rlm@3 290
rlm@3 291
rlm@3 292
rlm@3 293 public static function AACchannelCountCalculate($program_configs) {
rlm@3 294
rlm@3 295 $channels = 0;
rlm@3 296
rlm@3 297 foreach (array ('front', 'side', 'back') as $placement) {
rlm@3 298 for ($i = 0; $i < $program_configs['num_'.$placement.'_channel_elements']; $i++) {
rlm@3 299
rlm@3 300 // Each element is channel pair (CPE = Channel Pair Element)
rlm@3 301 $channels += 1 + ($program_configs[$placement.'_element_is_cpe'][$i] ? 1 : 0);
rlm@3 302 }
rlm@3 303 }
rlm@3 304
rlm@3 305 return $channels + $program_configs['num_lfe_channel_elements'];
rlm@3 306 }
rlm@3 307
rlm@3 308 }
rlm@3 309
rlm@3 310
rlm@3 311 ?>