53 {
54 $info = &$this->getid3->info;
55 $info[
'fileformat'] =
'aac';
56 $info[
'audio'][
'dataformat'] =
'aac';
57 $info[
'audio'][
'lossless'] =
false;
58
59 fseek($this->getid3->fp,
$info[
'avdataoffset'], SEEK_SET);
60 $AACheader =
fread($this->getid3->fp, 1024);
61 $offset = 0;
62
63 if (substr($AACheader, 0, 4) == 'ADIF') {
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
86 $bitoffset = 0;
87
88 $info[
'aac'][
'header_type'] =
'ADIF';
89 $bitoffset += 32;
90 $info[
'aac'][
'header'][
'mpeg_version'] = 4;
91
92 $info[
'aac'][
'header'][
'copyright'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) ==
'1');
93 $bitoffset += 1;
94 if (
$info[
'aac'][
'header'][
'copyright']) {
96 $bitoffset += 72;
97 }
98 $info[
'aac'][
'header'][
'original_copy'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) ==
'1');
99 $bitoffset += 1;
100 $info[
'aac'][
'header'][
'home'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) ==
'1');
101 $bitoffset += 1;
102 $info[
'aac'][
'header'][
'is_vbr'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) ==
'1');
103 $bitoffset += 1;
104 if (
$info[
'aac'][
'header'][
'is_vbr']) {
105 $info[
'audio'][
'bitrate_mode'] =
'vbr';
106 $info[
'aac'][
'header'][
'bitrate_max'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23));
107 $bitoffset += 23;
108 } else {
109 $info[
'audio'][
'bitrate_mode'] =
'cbr';
110 $info[
'aac'][
'header'][
'bitrate'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23));
111 $bitoffset += 23;
112 $info[
'audio'][
'bitrate'] =
$info[
'aac'][
'header'][
'bitrate'];
113 }
114 if (
$info[
'audio'][
'bitrate'] == 0) {
115 $info[
'error'][] =
'Corrupt AAC file: bitrate_audio == zero';
116
117 return false;
118 }
119 $info[
'aac'][
'header'][
'num_program_configs'] = 1 +
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
120 $bitoffset += 4;
121
122 for ($i = 0; $i <
$info[
'aac'][
'header'][
'num_program_configs']; $i++) {
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 if (!
$info[
'aac'][
'header'][
'is_vbr']) {
172 $info[
'aac'][
'program_configs'][$i][
'buffer_fullness'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 20));
173 $bitoffset += 20;
174 }
175 $info[
'aac'][
'program_configs'][$i][
'element_instance_tag'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
176 $bitoffset += 4;
177 $info[
'aac'][
'program_configs'][$i][
'object_type'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
178 $bitoffset += 2;
179 $info[
'aac'][
'program_configs'][$i][
'sampling_frequency_index'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
180 $bitoffset += 4;
181 $info[
'aac'][
'program_configs'][$i][
'num_front_channel_elements'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
182 $bitoffset += 4;
183 $info[
'aac'][
'program_configs'][$i][
'num_side_channel_elements'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
184 $bitoffset += 4;
185 $info[
'aac'][
'program_configs'][$i][
'num_back_channel_elements'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
186 $bitoffset += 4;
187 $info[
'aac'][
'program_configs'][$i][
'num_lfe_channel_elements'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
188 $bitoffset += 2;
189 $info[
'aac'][
'program_configs'][$i][
'num_assoc_data_elements'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3));
190 $bitoffset += 3;
191 $info[
'aac'][
'program_configs'][$i][
'num_valid_cc_elements'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
192 $bitoffset += 4;
193 $info[
'aac'][
'program_configs'][$i][
'mono_mixdown_present'] = (bool)
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
194 $bitoffset += 1;
195 if (
$info[
'aac'][
'program_configs'][$i][
'mono_mixdown_present']) {
196 $info[
'aac'][
'program_configs'][$i][
'mono_mixdown_element_number'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
197 $bitoffset += 4;
198 }
199 $info[
'aac'][
'program_configs'][$i][
'stereo_mixdown_present'] = (bool)
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
200 $bitoffset += 1;
201 if (
$info[
'aac'][
'program_configs'][$i][
'stereo_mixdown_present']) {
202 $info[
'aac'][
'program_configs'][$i][
'stereo_mixdown_element_number'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
203 $bitoffset += 4;
204 }
205 $info[
'aac'][
'program_configs'][$i][
'matrix_mixdown_idx_present'] = (bool)
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
206 $bitoffset += 1;
207 if (
$info[
'aac'][
'program_configs'][$i][
'matrix_mixdown_idx_present']) {
208 $info[
'aac'][
'program_configs'][$i][
'matrix_mixdown_idx'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
209 $bitoffset += 2;
210 $info[
'aac'][
'program_configs'][$i][
'pseudo_surround_enable'] = (bool)
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
211 $bitoffset += 1;
212 }
213 for ($j = 0; $j <
$info[
'aac'][
'program_configs'][$i][
'num_front_channel_elements']; $j++) {
214 $info[
'aac'][
'program_configs'][$i][
'front_element_is_cpe'][$j] = (bool)
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
215 $bitoffset += 1;
216 $info[
'aac'][
'program_configs'][$i][
'front_element_tag_select'][$j] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
217 $bitoffset += 4;
218 }
219 for ($j = 0; $j <
$info[
'aac'][
'program_configs'][$i][
'num_side_channel_elements']; $j++) {
220 $info[
'aac'][
'program_configs'][$i][
'side_element_is_cpe'][$j] = (bool)
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
221 $bitoffset += 1;
222 $info[
'aac'][
'program_configs'][$i][
'side_element_tag_select'][$j] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
223 $bitoffset += 4;
224 }
225 for ($j = 0; $j <
$info[
'aac'][
'program_configs'][$i][
'num_back_channel_elements']; $j++) {
226 $info[
'aac'][
'program_configs'][$i][
'back_element_is_cpe'][$j] = (bool)
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
227 $bitoffset += 1;
228 $info[
'aac'][
'program_configs'][$i][
'back_element_tag_select'][$j] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
229 $bitoffset += 4;
230 }
231 for ($j = 0; $j <
$info[
'aac'][
'program_configs'][$i][
'num_lfe_channel_elements']; $j++) {
232 $info[
'aac'][
'program_configs'][$i][
'lfe_element_tag_select'][$j] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
233 $bitoffset += 4;
234 }
235 for ($j = 0; $j <
$info[
'aac'][
'program_configs'][$i][
'num_assoc_data_elements']; $j++) {
236 $info[
'aac'][
'program_configs'][$i][
'assoc_data_element_tag_select'][$j] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
237 $bitoffset += 4;
238 }
239 for ($j = 0; $j <
$info[
'aac'][
'program_configs'][$i][
'num_valid_cc_elements']; $j++) {
240 $info[
'aac'][
'program_configs'][$i][
'cc_element_is_ind_sw'][$j] = (bool)
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
241 $bitoffset += 1;
242 $info[
'aac'][
'program_configs'][$i][
'valid_cc_element_tag_select'][$j] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
243 $bitoffset += 4;
244 }
245
246 $bitoffset = ceil($bitoffset / 8) * 8;
247
248 $info[
'aac'][
'program_configs'][$i][
'comment_field_bytes'] =
Helper::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 8));
249 $bitoffset += 8;
250 $info[
'aac'][
'program_configs'][$i][
'comment_field'] =
Helper::Bin2String(substr($AACheaderBitstream, $bitoffset, 8 *
$info[
'aac'][
'program_configs'][$i][
'comment_field_bytes']));
251 $bitoffset += 8 *
$info[
'aac'][
'program_configs'][$i][
'comment_field_bytes'];
252
255 $info[
'audio'][
'sample_rate'] =
$info[
'aac'][
'program_configs'][$i][
'sampling_frequency'];
257 if (
$info[
'aac'][
'program_configs'][$i][
'comment_field']) {
258 $info[
'aac'][
'comments'][] =
$info[
'aac'][
'program_configs'][$i][
'comment_field'];
259 }
260 }
261 $info[
'playtime_seconds'] = ((
$info[
'avdataend'] -
$info[
'avdataoffset']) * 8) /
$info[
'audio'][
'bitrate'];
262
263 $info[
'audio'][
'encoder_options'] =
$info[
'aac'][
'header_type'].
' '.
$info[
'aac'][
'header'][
'profile'];
264
265 return true;
266
267 } else {
268
269 unset(
$info[
'fileformat']);
271 $info[
'error'][] =
'AAC-ADIF synch not found at offset '.$info[
'avdataoffset'].
' (expected "ADIF", found "'.substr($AACheader, 0, 4).
'" instead)';
272
273 return false;
274
275 }
276
277 }
static Bin2Dec($binstring, $signed=false)
static Bin2String($binstring)
static BigEndian2Bin($byteword)
static AACsampleRateLookup($samplerateid)
@staticvar array $AACsampleRateLookup
static AACprofileLookup($profileid, $mpegversion)
@staticvar array $AACprofileLookup
static AACchannelCountCalculate($program_configs)