/** * * @return boolean */ public function getAACADIFheaderFilepointer() { $info =& $this->getid3->info; $info['fileformat'] = 'aac'; $info['audio']['dataformat'] = 'aac'; $info['audio']['lossless'] = false; fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET); $AACheader = fread($this->getid3->fp, 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 = GetId3_Lib_Helper::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'] = GetId3_Lib_Helper::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'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23)); $bitoffset += 23; } else { $info['audio']['bitrate_mode'] = 'cbr'; $info['aac']['header']['bitrate'] = GetId3_Lib_Helper::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 + GetId3_Lib_Helper::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'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 20)); $bitoffset += 20; } $info['aac']['program_configs'][$i]['element_instance_tag'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; $info['aac']['program_configs'][$i]['object_type'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); $bitoffset += 2; $info['aac']['program_configs'][$i]['sampling_frequency_index'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; $info['aac']['program_configs'][$i]['num_front_channel_elements'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; $info['aac']['program_configs'][$i]['num_side_channel_elements'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; $info['aac']['program_configs'][$i]['num_back_channel_elements'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; $info['aac']['program_configs'][$i]['num_lfe_channel_elements'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); $bitoffset += 2; $info['aac']['program_configs'][$i]['num_assoc_data_elements'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3)); $bitoffset += 3; $info['aac']['program_configs'][$i]['num_valid_cc_elements'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; $info['aac']['program_configs'][$i]['mono_mixdown_present'] = (bool) GetId3_Lib_Helper::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'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; } $info['aac']['program_configs'][$i]['stereo_mixdown_present'] = (bool) GetId3_Lib_Helper::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'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; } $info['aac']['program_configs'][$i]['matrix_mixdown_idx_present'] = (bool) GetId3_Lib_Helper::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'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2)); $bitoffset += 2; $info['aac']['program_configs'][$i]['pseudo_surround_enable'] = (bool) GetId3_Lib_Helper::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) GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); $bitoffset += 1; $info['aac']['program_configs'][$i]['front_element_tag_select'][$j] = GetId3_Lib_Helper::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) GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); $bitoffset += 1; $info['aac']['program_configs'][$i]['side_element_tag_select'][$j] = GetId3_Lib_Helper::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) GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); $bitoffset += 1; $info['aac']['program_configs'][$i]['back_element_tag_select'][$j] = GetId3_Lib_Helper::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] = GetId3_Lib_Helper::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] = GetId3_Lib_Helper::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) GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1)); $bitoffset += 1; $info['aac']['program_configs'][$i]['valid_cc_element_tag_select'][$j] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4)); $bitoffset += 4; } $bitoffset = ceil($bitoffset / 8) * 8; $info['aac']['program_configs'][$i]['comment_field_bytes'] = GetId3_Lib_Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 8)); $bitoffset += 8; $info['aac']['program_configs'][$i]['comment_field'] = GetId3_Lib_Helper::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; } }