33 {
34 $info = &$this->getid3->info;
35 $info[
'fileformat'] =
'aac';
36 $info[
'audio'][
'dataformat'] =
'aac';
37 $info[
'audio'][
'lossless'] =
false;
38
40 $AACheader = $this->
fread(1024);
41 $offset = 0;
42
43 if (substr($AACheader, 0, 4) == 'ADIF') {
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
66 $bitoffset = 0;
67
68 $info[
'aac'][
'header_type'] =
'ADIF';
69 $bitoffset += 32;
70 $info[
'aac'][
'header'][
'mpeg_version'] = 4;
71
72 $info[
'aac'][
'header'][
'copyright'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) ==
'1');
73 $bitoffset += 1;
74 if (
$info[
'aac'][
'header'][
'copyright']) {
76 $bitoffset += 72;
77 }
78 $info[
'aac'][
'header'][
'original_copy'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) ==
'1');
79 $bitoffset += 1;
80 $info[
'aac'][
'header'][
'home'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) ==
'1');
81 $bitoffset += 1;
82 $info[
'aac'][
'header'][
'is_vbr'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) ==
'1');
83 $bitoffset += 1;
84 if (
$info[
'aac'][
'header'][
'is_vbr']) {
85 $info[
'audio'][
'bitrate_mode'] =
'vbr';
87 $bitoffset += 23;
88 } else {
89 $info[
'audio'][
'bitrate_mode'] =
'cbr';
91 $bitoffset += 23;
92 $info[
'audio'][
'bitrate'] =
$info[
'aac'][
'header'][
'bitrate'];
93 }
94 if (
$info[
'audio'][
'bitrate'] == 0) {
95 $this->
error(
'Corrupt AAC file: bitrate_audio == zero');
96 return false;
97 }
99 $bitoffset += 4;
100
101 for (
$i = 0;
$i <
$info[
'aac'][
'header'][
'num_program_configs'];
$i++) {
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
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 if (!
$info[
'aac'][
'header'][
'is_vbr']) {
152 $bitoffset += 20;
153 }
154 $info[
'aac'][
'program_configs'][
$i][
'element_instance_tag'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
155 $bitoffset += 4;
157 $bitoffset += 2;
158 $info[
'aac'][
'program_configs'][
$i][
'sampling_frequency_index'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
159 $bitoffset += 4;
160 $info[
'aac'][
'program_configs'][
$i][
'num_front_channel_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
161 $bitoffset += 4;
162 $info[
'aac'][
'program_configs'][
$i][
'num_side_channel_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
163 $bitoffset += 4;
164 $info[
'aac'][
'program_configs'][
$i][
'num_back_channel_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
165 $bitoffset += 4;
166 $info[
'aac'][
'program_configs'][
$i][
'num_lfe_channel_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
167 $bitoffset += 2;
168 $info[
'aac'][
'program_configs'][
$i][
'num_assoc_data_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3));
169 $bitoffset += 3;
170 $info[
'aac'][
'program_configs'][
$i][
'num_valid_cc_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
171 $bitoffset += 4;
172 $info[
'aac'][
'program_configs'][
$i][
'mono_mixdown_present'] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
173 $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));
176 $bitoffset += 4;
177 }
178 $info[
'aac'][
'program_configs'][
$i][
'stereo_mixdown_present'] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
179 $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));
182 $bitoffset += 4;
183 }
184 $info[
'aac'][
'program_configs'][
$i][
'matrix_mixdown_idx_present'] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
185 $bitoffset += 1;
186 if (
$info[
'aac'][
'program_configs'][
$i][
'matrix_mixdown_idx_present']) {
188 $bitoffset += 2;
189 $info[
'aac'][
'program_configs'][
$i][
'pseudo_surround_enable'] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
190 $bitoffset += 1;
191 }
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));
194 $bitoffset += 1;
195 $info[
'aac'][
'program_configs'][
$i][
'front_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
196 $bitoffset += 4;
197 }
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));
200 $bitoffset += 1;
201 $info[
'aac'][
'program_configs'][
$i][
'side_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
202 $bitoffset += 4;
203 }
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));
206 $bitoffset += 1;
207 $info[
'aac'][
'program_configs'][
$i][
'back_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
208 $bitoffset += 4;
209 }
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));
212 $bitoffset += 4;
213 }
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));
216 $bitoffset += 4;
217 }
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));
220 $bitoffset += 1;
221 $info[
'aac'][
'program_configs'][
$i][
'valid_cc_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
222 $bitoffset += 4;
223 }
224
225 $bitoffset = ceil($bitoffset / 8) * 8;
226
228 $bitoffset += 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'];
231
232
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'];
239 }
240 }
241 $info[
'playtime_seconds'] = ((
$info[
'avdataend'] -
$info[
'avdataoffset']) * 8) /
$info[
'audio'][
'bitrate'];
242
243 $info[
'audio'][
'encoder_options'] =
$info[
'aac'][
'header_type'].
' '.
$info[
'aac'][
'header'][
'profile'];
244
245
246
247 return true;
248
249 } else {
250
251 unset(
$info[
'fileformat']);
253 $this->
error(
'AAC-ADIF synch not found at offset '.$info[
'avdataoffset'].
' (expected "ADIF", found "'.substr($AACheader, 0, 4).
'" instead)');
254 return false;
255
256 }
257
258 }
static AACprofileLookup($profileid, $mpegversion)
static AACsampleRateLookup($samplerateid)
static AACchannelCountCalculate($program_configs)
static BigEndian2Bin($byteword)
static Bin2String($binstring)
static Bin2Dec($binstring, $signed=false)