Пример #1
0
 public function getAACADIFheaderFilepointer()
 {
     $info =& $this->getid3->info;
     $info['fileformat'] = 'aac';
     $info['audio']['dataformat'] = 'aac';
     $info['audio']['lossless'] = false;
     $this->fseek($info['avdataoffset']);
     $AACheader = $this->fread(1024);
     $offset = 0;
     if (substr($AACheader, 0, 4) == 'ADIF') {
         // http://faac.sourceforge.net/wiki/index.php?page=ADIF
         // http://libmpeg.org/mpeg4/doc/w2203tfs.pdf
         // adif_header() {
         //     adif_id                                32
         //     copyright_id_present                    1
         //     if( copyright_id_present )
         //         copyright_id                       72
         //     original_copy                           1
         //     home                                    1
         //     bitstream_type                          1
         //     bitrate                                23
         //     num_program_config_elements             4
         //     for (i = 0; i < num_program_config_elements + 1; i++ ) {
         //         if( bitstream_type == '0' )
         //             adif_buffer_fullness           20
         //         program_config_element()
         //     }
         // }
         $AACheaderBitstream = Utils::BigEndian2Bin($AACheader);
         $bitoffset = 0;
         $info['aac']['header_type'] = 'ADIF';
         $bitoffset += 32;
         $info['aac']['header']['mpeg_version'] = 4;
         $info['aac']['header']['copyright'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
         $bitoffset += 1;
         if ($info['aac']['header']['copyright']) {
             $info['aac']['header']['copyright_id'] = Utils::Bin2String(substr($AACheaderBitstream, $bitoffset, 72));
             $bitoffset += 72;
         }
         $info['aac']['header']['original_copy'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
         $bitoffset += 1;
         $info['aac']['header']['home'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
         $bitoffset += 1;
         $info['aac']['header']['is_vbr'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
         $bitoffset += 1;
         if ($info['aac']['header']['is_vbr']) {
             $info['audio']['bitrate_mode'] = 'vbr';
             $info['aac']['header']['bitrate_max'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23));
             $bitoffset += 23;
         } else {
             $info['audio']['bitrate_mode'] = 'cbr';
             $info['aac']['header']['bitrate'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23));
             $bitoffset += 23;
             $info['audio']['bitrate'] = $info['aac']['header']['bitrate'];
         }
         if ($info['audio']['bitrate'] == 0) {
             $info['error'][] = 'Corrupt AAC file: bitrate_audio == zero';
             return false;
         }
         $info['aac']['header']['num_program_configs'] = 1 + Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
         $bitoffset += 4;
         for ($i = 0; $i < $info['aac']['header']['num_program_configs']; $i++) {
             // http://www.audiocoding.com/wiki/index.php?page=program_config_element
             // buffer_fullness                       20
             // element_instance_tag                   4
             // object_type                            2
             // sampling_frequency_index               4
             // num_front_channel_elements             4
             // num_side_channel_elements              4
             // num_back_channel_elements              4
             // num_lfe_channel_elements               2
             // num_assoc_data_elements                3
             // num_valid_cc_elements                  4
             // mono_mixdown_present                   1
             // mono_mixdown_element_number            4   if mono_mixdown_present == 1
             // stereo_mixdown_present                 1
             // stereo_mixdown_element_number          4   if stereo_mixdown_present == 1
             // matrix_mixdown_idx_present             1
             // matrix_mixdown_idx                     2   if matrix_mixdown_idx_present == 1
             // pseudo_surround_enable                 1   if matrix_mixdown_idx_present == 1
             // for (i = 0; i < num_front_channel_elements; i++) {
             //     front_element_is_cpe[i]            1
             //     front_element_tag_select[i]        4
             // }
             // for (i = 0; i < num_side_channel_elements; i++) {
             //     side_element_is_cpe[i]             1
             //     side_element_tag_select[i]         4
             // }
             // for (i = 0; i < num_back_channel_elements; i++) {
             //     back_element_is_cpe[i]             1
             //     back_element_tag_select[i]         4
             // }
             // for (i = 0; i < num_lfe_channel_elements; i++) {
             //     lfe_element_tag_select[i]          4
             // }
             // for (i = 0; i < num_assoc_data_elements; i++) {
             //     assoc_data_element_tag_select[i]   4
             // }
             // for (i = 0; i < num_valid_cc_elements; i++) {
             //     cc_element_is_ind_sw[i]            1
             //     valid_cc_element_tag_select[i]     4
             // }
             // byte_alignment()                       VAR
             // comment_field_bytes                    8
             // for (i = 0; i < comment_field_bytes; i++) {
             //     comment_field_data[i]              8
             // }
             if (!$info['aac']['header']['is_vbr']) {
                 $info['aac']['program_configs'][$i]['buffer_fullness'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 20));
                 $bitoffset += 20;
             }
             $info['aac']['program_configs'][$i]['element_instance_tag'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
             $bitoffset += 4;
             $info['aac']['program_configs'][$i]['object_type'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
             $bitoffset += 2;
             $info['aac']['program_configs'][$i]['sampling_frequency_index'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
             $bitoffset += 4;
             $info['aac']['program_configs'][$i]['num_front_channel_elements'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
             $bitoffset += 4;
             $info['aac']['program_configs'][$i]['num_side_channel_elements'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
             $bitoffset += 4;
             $info['aac']['program_configs'][$i]['num_back_channel_elements'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
             $bitoffset += 4;
             $info['aac']['program_configs'][$i]['num_lfe_channel_elements'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
             $bitoffset += 2;
             $info['aac']['program_configs'][$i]['num_assoc_data_elements'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3));
             $bitoffset += 3;
             $info['aac']['program_configs'][$i]['num_valid_cc_elements'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
             $bitoffset += 4;
             $info['aac']['program_configs'][$i]['mono_mixdown_present'] = (bool) Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
             $bitoffset += 1;
             if ($info['aac']['program_configs'][$i]['mono_mixdown_present']) {
                 $info['aac']['program_configs'][$i]['mono_mixdown_element_number'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
                 $bitoffset += 4;
             }
             $info['aac']['program_configs'][$i]['stereo_mixdown_present'] = (bool) Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
             $bitoffset += 1;
             if ($info['aac']['program_configs'][$i]['stereo_mixdown_present']) {
                 $info['aac']['program_configs'][$i]['stereo_mixdown_element_number'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
                 $bitoffset += 4;
             }
             $info['aac']['program_configs'][$i]['matrix_mixdown_idx_present'] = (bool) Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
             $bitoffset += 1;
             if ($info['aac']['program_configs'][$i]['matrix_mixdown_idx_present']) {
                 $info['aac']['program_configs'][$i]['matrix_mixdown_idx'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
                 $bitoffset += 2;
                 $info['aac']['program_configs'][$i]['pseudo_surround_enable'] = (bool) Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
                 $bitoffset += 1;
             }
             for ($j = 0; $j < $info['aac']['program_configs'][$i]['num_front_channel_elements']; $j++) {
                 $info['aac']['program_configs'][$i]['front_element_is_cpe'][$j] = (bool) Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
                 $bitoffset += 1;
                 $info['aac']['program_configs'][$i]['front_element_tag_select'][$j] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
                 $bitoffset += 4;
             }
             for ($j = 0; $j < $info['aac']['program_configs'][$i]['num_side_channel_elements']; $j++) {
                 $info['aac']['program_configs'][$i]['side_element_is_cpe'][$j] = (bool) Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
                 $bitoffset += 1;
                 $info['aac']['program_configs'][$i]['side_element_tag_select'][$j] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
                 $bitoffset += 4;
             }
             for ($j = 0; $j < $info['aac']['program_configs'][$i]['num_back_channel_elements']; $j++) {
                 $info['aac']['program_configs'][$i]['back_element_is_cpe'][$j] = (bool) Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
                 $bitoffset += 1;
                 $info['aac']['program_configs'][$i]['back_element_tag_select'][$j] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
                 $bitoffset += 4;
             }
             for ($j = 0; $j < $info['aac']['program_configs'][$i]['num_lfe_channel_elements']; $j++) {
                 $info['aac']['program_configs'][$i]['lfe_element_tag_select'][$j] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
                 $bitoffset += 4;
             }
             for ($j = 0; $j < $info['aac']['program_configs'][$i]['num_assoc_data_elements']; $j++) {
                 $info['aac']['program_configs'][$i]['assoc_data_element_tag_select'][$j] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
                 $bitoffset += 4;
             }
             for ($j = 0; $j < $info['aac']['program_configs'][$i]['num_valid_cc_elements']; $j++) {
                 $info['aac']['program_configs'][$i]['cc_element_is_ind_sw'][$j] = (bool) Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
                 $bitoffset += 1;
                 $info['aac']['program_configs'][$i]['valid_cc_element_tag_select'][$j] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
                 $bitoffset += 4;
             }
             $bitoffset = ceil($bitoffset / 8) * 8;
             $info['aac']['program_configs'][$i]['comment_field_bytes'] = Utils::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 8));
             $bitoffset += 8;
             $info['aac']['program_configs'][$i]['comment_field'] = Utils::Bin2String(substr($AACheaderBitstream, $bitoffset, 8 * $info['aac']['program_configs'][$i]['comment_field_bytes']));
             $bitoffset += 8 * $info['aac']['program_configs'][$i]['comment_field_bytes'];
             $info['aac']['header']['profile'] = self::AACprofileLookup($info['aac']['program_configs'][$i]['object_type'], $info['aac']['header']['mpeg_version']);
             $info['aac']['program_configs'][$i]['sampling_frequency'] = self::AACsampleRateLookup($info['aac']['program_configs'][$i]['sampling_frequency_index']);
             $info['audio']['sample_rate'] = $info['aac']['program_configs'][$i]['sampling_frequency'];
             $info['audio']['channels'] = self::AACchannelCountCalculate($info['aac']['program_configs'][$i]);
             if ($info['aac']['program_configs'][$i]['comment_field']) {
                 $info['aac']['comments'][] = $info['aac']['program_configs'][$i]['comment_field'];
             }
         }
         $info['playtime_seconds'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['audio']['bitrate'];
         $info['audio']['encoder_options'] = $info['aac']['header_type'] . ' ' . $info['aac']['header']['profile'];
         return true;
     } else {
         unset($info['fileformat']);
         unset($info['aac']);
         $info['error'][] = 'AAC-ADIF synch not found at offset ' . $info['avdataoffset'] . ' (expected "ADIF", found "' . substr($AACheader, 0, 4) . '" instead)';
         return false;
     }
 }