21                $info = &$this->getid3->info;
 
   23                if ($this->
fread(4) == 
'ADIF') {
 
   34                $info = &$this->getid3->info;
 
   35                $info[
'fileformat']          = 
'aac';
 
   36                $info[
'audio'][
'dataformat'] = 
'aac';
 
   37                $info[
'audio'][
'lossless']   = 
false;
 
   40                $AACheader = $this->
fread(1024);
 
   43                if (substr($AACheader, 0, 4) == 
'ADIF') {
 
   68                        $info[
'aac'][
'header_type']                   = 
'ADIF';
 
   70                        $info[
'aac'][
'header'][
'mpeg_version']        = 4;
 
   72                        $info[
'aac'][
'header'][
'copyright']           = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == 
'1');
 
   74                        if (
$info[
'aac'][
'header'][
'copyright']) {
 
   78                        $info[
'aac'][
'header'][
'original_copy']       = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == 
'1');
 
   80                        $info[
'aac'][
'header'][
'home']                = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == 
'1');
 
   82                        $info[
'aac'][
'header'][
'is_vbr']              = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == 
'1');
 
   84                        if (
$info[
'aac'][
'header'][
'is_vbr']) {
 
   85                                $info[
'audio'][
'bitrate_mode']            = 
'vbr';
 
   89                                $info[
'audio'][
'bitrate_mode']            = 
'cbr';
 
   92                                $info[
'audio'][
'bitrate']                 = 
$info[
'aac'][
'header'][
'bitrate'];
 
   94                        if (
$info[
'audio'][
'bitrate'] == 0) {
 
   95                                $this->
error(
'Corrupt AAC file: bitrate_audio == zero');
 
  101                        for (
$i = 0; 
$i < 
$info[
'aac'][
'header'][
'num_program_configs']; 
$i++) {
 
  150                                if (!
$info[
'aac'][
'header'][
'is_vbr']) {
 
  154                                $info[
'aac'][
'program_configs'][
$i][
'element_instance_tag']       = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  158                                $info[
'aac'][
'program_configs'][
$i][
'sampling_frequency_index']   = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  160                                $info[
'aac'][
'program_configs'][
$i][
'num_front_channel_elements'] = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  162                                $info[
'aac'][
'program_configs'][
$i][
'num_side_channel_elements']  = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  164                                $info[
'aac'][
'program_configs'][
$i][
'num_back_channel_elements']  = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  166                                $info[
'aac'][
'program_configs'][
$i][
'num_lfe_channel_elements']   = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
 
  168                                $info[
'aac'][
'program_configs'][
$i][
'num_assoc_data_elements']    = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3));
 
  170                                $info[
'aac'][
'program_configs'][
$i][
'num_valid_cc_elements']      = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  172                                $info[
'aac'][
'program_configs'][
$i][
'mono_mixdown_present']       = (bool) 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
 
  174                                if (
$info[
'aac'][
'program_configs'][
$i][
'mono_mixdown_present']) {
 
  175                                        $info[
'aac'][
'program_configs'][
$i][
'mono_mixdown_element_number']    = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  178                                $info[
'aac'][
'program_configs'][
$i][
'stereo_mixdown_present']             = (bool) 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
 
  180                                if (
$info[
'aac'][
'program_configs'][
$i][
'stereo_mixdown_present']) {
 
  181                                        $info[
'aac'][
'program_configs'][
$i][
'stereo_mixdown_element_number']  = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  184                                $info[
'aac'][
'program_configs'][
$i][
'matrix_mixdown_idx_present']         = (bool) 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
 
  186                                if (
$info[
'aac'][
'program_configs'][
$i][
'matrix_mixdown_idx_present']) {
 
  189                                        $info[
'aac'][
'program_configs'][
$i][
'pseudo_surround_enable']         = (bool) 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
 
  192                                for ($j = 0; $j < 
$info[
'aac'][
'program_configs'][
$i][
'num_front_channel_elements']; $j++) {
 
  193                                        $info[
'aac'][
'program_configs'][
$i][
'front_element_is_cpe'][$j]     = (bool) 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
 
  195                                        $info[
'aac'][
'program_configs'][
$i][
'front_element_tag_select'][$j] = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  198                                for ($j = 0; $j < 
$info[
'aac'][
'program_configs'][
$i][
'num_side_channel_elements']; $j++) {
 
  199                                        $info[
'aac'][
'program_configs'][
$i][
'side_element_is_cpe'][$j]     = (bool) 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
 
  201                                        $info[
'aac'][
'program_configs'][
$i][
'side_element_tag_select'][$j] = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  204                                for ($j = 0; $j < 
$info[
'aac'][
'program_configs'][
$i][
'num_back_channel_elements']; $j++) {
 
  205                                        $info[
'aac'][
'program_configs'][
$i][
'back_element_is_cpe'][$j]     = (bool) 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
 
  207                                        $info[
'aac'][
'program_configs'][
$i][
'back_element_tag_select'][$j] = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  210                                for ($j = 0; $j < 
$info[
'aac'][
'program_configs'][
$i][
'num_lfe_channel_elements']; $j++) {
 
  211                                        $info[
'aac'][
'program_configs'][
$i][
'lfe_element_tag_select'][$j] = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  214                                for ($j = 0; $j < 
$info[
'aac'][
'program_configs'][
$i][
'num_assoc_data_elements']; $j++) {
 
  215                                        $info[
'aac'][
'program_configs'][
$i][
'assoc_data_element_tag_select'][$j] = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  218                                for ($j = 0; $j < 
$info[
'aac'][
'program_configs'][
$i][
'num_valid_cc_elements']; $j++) {
 
  219                                        $info[
'aac'][
'program_configs'][
$i][
'cc_element_is_ind_sw'][$j]          = (bool) 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
 
  221                                        $info[
'aac'][
'program_configs'][
$i][
'valid_cc_element_tag_select'][$j]   = 
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
 
  225                                $bitoffset = ceil($bitoffset / 8) * 8;
 
  229                                $info[
'aac'][
'program_configs'][
$i][
'comment_field']       = 
getid3_lib::Bin2String(substr($AACheaderBitstream, $bitoffset, 8 * 
$info[
'aac'][
'program_configs'][
$i][
'comment_field_bytes']));
 
  230                                $bitoffset += 8 * 
$info[
'aac'][
'program_configs'][
$i][
'comment_field_bytes'];
 
  235                                $info[
'audio'][
'sample_rate']                               = 
$info[
'aac'][
'program_configs'][
$i][
'sampling_frequency'];
 
  237                                if (
$info[
'aac'][
'program_configs'][
$i][
'comment_field']) {
 
  238                                        $info[
'aac'][
'comments'][]                          = 
$info[
'aac'][
'program_configs'][
$i][
'comment_field'];
 
  241                        $info[
'playtime_seconds'] = ((
$info[
'avdataend'] - 
$info[
'avdataoffset']) * 8) / 
$info[
'audio'][
'bitrate'];
 
  243                        $info[
'audio'][
'encoder_options'] = 
$info[
'aac'][
'header_type'].
' '.
$info[
'aac'][
'header'][
'profile'];
 
  251                        unset(
$info[
'fileformat']);
 
  253                        $this->
error(
'AAC-ADIF synch not found at offset '.
$info[
'avdataoffset'].
' (expected "ADIF", found "'.substr($AACheader, 0, 4).
'" instead)');
 
  262                $info = &$this->getid3->info;
 
  294                $byteoffset  = 
$info[
'avdataoffset'];
 
  298                static $decbin = array();
 
  301                for (
$i = 0; 
$i < 256; 
$i++) {
 
  302                        $decbin[chr(
$i)] = str_pad(decbin(
$i), 8, 
'0', STR_PAD_LEFT);
 
  306                $BitrateCache = array();
 
  314                                $this->
warning(
'Unable to parse AAC file beyond '.$this->
ftell().
' (PHP does not support file operations beyond '.round(PHP_INT_MAX / 1073741824).
'GB)');
 
  317                        $this->
fseek($byteoffset);
 
  320                        $substring = $this->
fread(9); 
 
  321                        $substringlength = strlen($substring);
 
  322                        if ($substringlength != 9) {
 
  323                                $this->
error(
'Failed to read 7 bytes at offset '.($this->
ftell() - $substringlength).
' (only read '.$substringlength.
' bytes)');
 
  331                        $info[
'aac'][
'header'][
'raw'][
'syncword']          = ($header1 & 0xFFF0) >> 4;
 
  332                        if (
$info[
'aac'][
'header'][
'raw'][
'syncword'] != 0x0FFF) {
 
  333                                $this->
error(
'Synch pattern (0x0FFF) not found at offset '.($this->
ftell() - $substringlength).
' (found 0x0'.strtoupper(dechex(
$info[
'aac'][
'header'][
'raw'][
'syncword'])).
' instead)');
 
  342                        if ($framenumber == 0) {
 
  343                                $info[
'aac'][
'header_type']                      = 
'ADTS';
 
  344                                $info[
'fileformat']                              = 
'aac';
 
  345                                $info[
'audio'][
'dataformat']                     = 
'aac';
 
  347                                $info[
'aac'][
'header'][
'raw'][
'mpeg_version']      = ($header1 & 0x0008) >> 3;
 
  348                                $info[
'aac'][
'header'][
'raw'][
'mpeg_layer']        = ($header1 & 0x0006) >> 1;
 
  349                                $info[
'aac'][
'header'][
'raw'][
'protection_absent'] = ($header1 & 0x0001) >> 0;
 
  351                                $info[
'aac'][
'header'][
'raw'][
'profile_code']      = ($header2 & 0xC0000000) >> 30;
 
  352                                $info[
'aac'][
'header'][
'raw'][
'sample_rate_code']  = ($header2 & 0x3C000000) >> 26;
 
  353                                $info[
'aac'][
'header'][
'raw'][
'private_stream']    = ($header2 & 0x02000000) >> 25;
 
  354                                $info[
'aac'][
'header'][
'raw'][
'channels_code']     = ($header2 & 0x01C00000) >> 22;
 
  355                                $info[
'aac'][
'header'][
'raw'][
'original']          = ($header2 & 0x00200000) >> 21;
 
  356                                $info[
'aac'][
'header'][
'raw'][
'home']              = ($header2 & 0x00100000) >> 20;
 
  357                                $info[
'aac'][
'header'][
'raw'][
'copyright_stream']  = ($header2 & 0x00080000) >> 19;
 
  358                                $info[
'aac'][
'header'][
'raw'][
'copyright_start']   = ($header2 & 0x00040000) >> 18;
 
  359                                $info[
'aac'][
'header'][
'raw'][
'frame_length']      = ($header2 & 0x0003FFE0) >>  5;
 
  361                                $info[
'aac'][
'header'][
'mpeg_version']     = (
$info[
'aac'][
'header'][
'raw'][
'mpeg_version']      ? 2    : 4);
 
  362                                $info[
'aac'][
'header'][
'crc_present']      = (
$info[
'aac'][
'header'][
'raw'][
'protection_absent'] ? 
false: 
true);
 
  365                                $info[
'aac'][
'header'][
'private']          = (bool) 
$info[
'aac'][
'header'][
'raw'][
'private_stream'];
 
  366                                $info[
'aac'][
'header'][
'original']         = (bool) 
$info[
'aac'][
'header'][
'raw'][
'original'];
 
  367                                $info[
'aac'][
'header'][
'home']             = (bool) 
$info[
'aac'][
'header'][
'raw'][
'home'];
 
  368                                $info[
'aac'][
'header'][
'channels']         = ((
$info[
'aac'][
'header'][
'raw'][
'channels_code'] == 7) ? 8 : 
$info[
'aac'][
'header'][
'raw'][
'channels_code']);
 
  369                                if ($ReturnExtendedInfo) {
 
  370                                        $info[
'aac'][$framenumber][
'copyright_id_bit']   = (bool) 
$info[
'aac'][
'header'][
'raw'][
'copyright_stream'];
 
  371                                        $info[
'aac'][$framenumber][
'copyright_id_start'] = (bool) 
$info[
'aac'][
'header'][
'raw'][
'copyright_start'];
 
  374                                if (
$info[
'aac'][
'header'][
'raw'][
'mpeg_layer'] != 0) {
 
  375                                        $this->
warning(
'Layer error - expected "0", found "'.
$info[
'aac'][
'header'][
'raw'][
'mpeg_layer'].
'" instead');
 
  377                                if (
$info[
'aac'][
'header'][
'sample_frequency'] == 0) {
 
  378                                        $this->
error(
'Corrupt AAC file: sample_frequency == zero');
 
  382                                $info[
'audio'][
'sample_rate'] = 
$info[
'aac'][
'header'][
'sample_frequency'];
 
  383                                $info[
'audio'][
'channels']    = 
$info[
'aac'][
'header'][
'channels'];
 
  386                        $FrameLength = ($header2 & 0x0003FFE0) >>  5;
 
  388                        if (!isset($BitrateCache[$FrameLength])) {
 
  389                                $BitrateCache[$FrameLength] = (
$info[
'aac'][
'header'][
'sample_frequency'] / 1024) * $FrameLength * 8;
 
  393                        $info[
'aac'][$framenumber][
'aac_frame_length']     = $FrameLength;
 
  395                        $info[
'aac'][$framenumber][
'adts_buffer_fullness'] = (($header2 & 0x0000001F) << 6) & (($header3 & 0xFC) >> 2);
 
  396                        if (
$info[
'aac'][$framenumber][
'adts_buffer_fullness'] == 0x07FF) {
 
  397                                $info[
'audio'][
'bitrate_mode'] = 
'vbr';
 
  399                                $info[
'audio'][
'bitrate_mode'] = 
'cbr';
 
  401                        $info[
'aac'][$framenumber][
'num_raw_data_blocks']  = (($header3 & 0x03) >> 0);
 
  403                        if (
$info[
'aac'][
'header'][
'crc_present']) {
 
  407                        if (!$ReturnExtendedInfo) {
 
  408                                unset(
$info[
'aac'][$framenumber]);
 
  421                        $byteoffset += $FrameLength;
 
  422                        if ((++$framenumber < $MaxFramesToScan) && (($byteoffset + 10) < 
$info[
'avdataend'])) {
 
  428                                $info[
'aac'][
'frames']    = $framenumber;
 
  429                                $info[
'playtime_seconds'] = (
$info[
'avdataend'] / $byteoffset) * (($framenumber * 1024) / 
$info[
'aac'][
'header'][
'sample_frequency']);  
 
  430                                if (
$info[
'playtime_seconds'] == 0) {
 
  431                                        $this->
error(
'Corrupt AAC file: playtime_seconds == zero');
 
  434                                $info[
'audio'][
'bitrate']    = ((
$info[
'avdataend'] - 
$info[
'avdataoffset']) * 8) / 
$info[
'playtime_seconds'];
 
  435                                ksort(
$info[
'aac'][
'bitrate_distribution']);
 
  437                                $info[
'audio'][
'encoder_options'] = 
$info[
'aac'][
'header_type'].
' '.
$info[
'aac'][
'header'][
'profile'];
 
  447                static $AACsampleRateLookup = array();
 
  448                if (empty($AACsampleRateLookup)) {
 
  449                        $AACsampleRateLookup[0]  = 96000;
 
  450                        $AACsampleRateLookup[1]  = 88200;
 
  451                        $AACsampleRateLookup[2]  = 64000;
 
  452                        $AACsampleRateLookup[3]  = 48000;
 
  453                        $AACsampleRateLookup[4]  = 44100;
 
  454                        $AACsampleRateLookup[5]  = 32000;
 
  455                        $AACsampleRateLookup[6]  = 24000;
 
  456                        $AACsampleRateLookup[7]  = 22050;
 
  457                        $AACsampleRateLookup[8]  = 16000;
 
  458                        $AACsampleRateLookup[9]  = 12000;
 
  459                        $AACsampleRateLookup[10] = 11025;
 
  460                        $AACsampleRateLookup[11] = 8000;
 
  461                        $AACsampleRateLookup[12] = 0;
 
  462                        $AACsampleRateLookup[13] = 0;
 
  463                        $AACsampleRateLookup[14] = 0;
 
  464                        $AACsampleRateLookup[15] = 0;
 
  466                return (isset($AACsampleRateLookup[$samplerateid]) ? $AACsampleRateLookup[$samplerateid] : 
'invalid');
 
  470                static $AACprofileLookup = array();
 
  471                if (empty($AACprofileLookup)) {
 
  472                        $AACprofileLookup[2][0]  = 
'Main profile';
 
  473                        $AACprofileLookup[2][1]  = 
'Low Complexity profile (LC)';
 
  474                        $AACprofileLookup[2][2]  = 
'Scalable Sample Rate profile (SSR)';
 
  475                        $AACprofileLookup[2][3]  = 
'(reserved)';
 
  476                        $AACprofileLookup[4][0]  = 
'AAC_MAIN';
 
  477                        $AACprofileLookup[4][1]  = 
'AAC_LC';
 
  478                        $AACprofileLookup[4][2]  = 
'AAC_SSR';
 
  479                        $AACprofileLookup[4][3]  = 
'AAC_LTP';
 
  481                return (isset($AACprofileLookup[$mpegversion][$profileid]) ? $AACprofileLookup[$mpegversion][$profileid] : 
'invalid');
 
  486                for (
$i = 0; 
$i < $program_configs[
'num_front_channel_elements']; 
$i++) {
 
  488                        if ($program_configs[
'front_element_is_cpe'][
$i]) {
 
  493                for (
$i = 0; 
$i < $program_configs[
'num_side_channel_elements']; 
$i++) {
 
  495                        if ($program_configs[
'side_element_is_cpe'][
$i]) {
 
  500                for (
$i = 0; 
$i < $program_configs[
'num_back_channel_elements']; 
$i++) {
 
  502                        if ($program_configs[
'back_element_is_cpe'][
$i]) {
 
  507                for (
$i = 0; 
$i < $program_configs[
'num_lfe_channel_elements']; 
$i++) {
 
An exception for terminatinating execution or to throw for unit testing.
getID3() by James Heinrich info@getid3.org //
static AACprofileLookup($profileid, $mpegversion)
static AACsampleRateLookup($samplerateid)
static AACchannelCountCalculate($program_configs)
getAACADTSheaderFilepointer($MaxFramesToScan=1000000, $ReturnExtendedInfo=false)
getAACADIFheaderFilepointer()
fseek($bytes, $whence=SEEK_SET)
static intValueSupported($num)
static safe_inc(&$variable, $increment=1)
static BigEndian2Bin($byteword)
static Bin2String($binstring)
static Bin2Dec($binstring, $signed=false)
static BigEndian2Int($byteword, $synchsafe=false, $signed=false)