33 {
34 $ThisFileInfo['fileformat'] = 'aac';
35 $ThisFileInfo['audio']['dataformat'] = 'aac';
36 $ThisFileInfo['audio']['lossless'] = false;
37
38 fseek($fd, $ThisFileInfo[
'avdataoffset'], SEEK_SET);
39 $AACheader =
fread($fd, 1024);
40 $offset = 0;
41
42 if (substr($AACheader, 0, 4) == 'ADIF') {
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
65 $bitoffset = 0;
66
67 $ThisFileInfo['aac']['header_type'] = 'ADIF';
68 $bitoffset += 32;
69 $ThisFileInfo['aac']['header']['mpeg_version'] = 4;
70
71 $ThisFileInfo['aac']['header']['copyright'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
72 $bitoffset += 1;
73 if ($ThisFileInfo['aac']['header']['copyright']) {
74 $ThisFileInfo[
'aac'][
'header'][
'copyright_id'] =
getid3_lib::Bin2String(substr($AACheaderBitstream, $bitoffset, 72));
75 $bitoffset += 72;
76 }
77 $ThisFileInfo['aac']['header']['original_copy'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
78 $bitoffset += 1;
79 $ThisFileInfo['aac']['header']['home'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
80 $bitoffset += 1;
81 $ThisFileInfo['aac']['header']['is_vbr'] = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
82 $bitoffset += 1;
83 if ($ThisFileInfo['aac']['header']['is_vbr']) {
84 $ThisFileInfo['audio']['bitrate_mode'] = 'vbr';
85 $ThisFileInfo[
'aac'][
'header'][
'bitrate_max'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23));
86 $bitoffset += 23;
87 } else {
88 $ThisFileInfo['audio']['bitrate_mode'] = 'cbr';
89 $ThisFileInfo[
'aac'][
'header'][
'bitrate'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23));
90 $bitoffset += 23;
91 $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['aac']['header']['bitrate'];
92 }
93 if ($ThisFileInfo['audio']['bitrate'] == 0) {
94 $ThisFileInfo['error'][] = 'Corrupt AAC file: bitrate_audio == zero';
95 return false;
96 }
97 $ThisFileInfo[
'aac'][
'header'][
'num_program_configs'] = 1 +
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
98 $bitoffset += 4;
99
100 for ($i = 0; $i < $ThisFileInfo['aac']['header']['num_program_configs']; $i++) {
101
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 if (!$ThisFileInfo['aac']['header']['is_vbr']) {
150 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'buffer_fullness'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 20));
151 $bitoffset += 20;
152 }
153 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'element_instance_tag'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
154 $bitoffset += 4;
155 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'object_type'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
156 $bitoffset += 2;
157 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'sampling_frequency_index'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
158 $bitoffset += 4;
159 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'num_front_channel_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
160 $bitoffset += 4;
161 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'num_side_channel_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
162 $bitoffset += 4;
163 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'num_back_channel_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
164 $bitoffset += 4;
165 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'num_lfe_channel_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
166 $bitoffset += 2;
167 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'num_assoc_data_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3));
168 $bitoffset += 3;
169 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'num_valid_cc_elements'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
170 $bitoffset += 4;
171 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'mono_mixdown_present'] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
172 $bitoffset += 1;
173 if ($ThisFileInfo['aac']['program_configs'][$i]['mono_mixdown_present']) {
174 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'mono_mixdown_element_number'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
175 $bitoffset += 4;
176 }
177 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'stereo_mixdown_present'] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
178 $bitoffset += 1;
179 if ($ThisFileInfo['aac']['program_configs'][$i]['stereo_mixdown_present']) {
180 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'stereo_mixdown_element_number'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
181 $bitoffset += 4;
182 }
183 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'matrix_mixdown_idx_present'] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
184 $bitoffset += 1;
185 if ($ThisFileInfo['aac']['program_configs'][$i]['matrix_mixdown_idx_present']) {
186 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'matrix_mixdown_idx'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
187 $bitoffset += 2;
188 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'pseudo_surround_enable'] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
189 $bitoffset += 1;
190 }
191 for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_front_channel_elements']; $j++) {
192 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'front_element_is_cpe'][$j] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
193 $bitoffset += 1;
194 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'front_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
195 $bitoffset += 4;
196 }
197 for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_side_channel_elements']; $j++) {
198 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'side_element_is_cpe'][$j] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
199 $bitoffset += 1;
200 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'side_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
201 $bitoffset += 4;
202 }
203 for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_back_channel_elements']; $j++) {
204 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'back_element_is_cpe'][$j] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
205 $bitoffset += 1;
206 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'back_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
207 $bitoffset += 4;
208 }
209 for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_lfe_channel_elements']; $j++) {
210 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'lfe_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
211 $bitoffset += 4;
212 }
213 for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_assoc_data_elements']; $j++) {
214 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'assoc_data_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
215 $bitoffset += 4;
216 }
217 for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_valid_cc_elements']; $j++) {
218 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'cc_element_is_ind_sw'][$j] = (bool)
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
219 $bitoffset += 1;
220 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'valid_cc_element_tag_select'][$j] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
221 $bitoffset += 4;
222 }
223
224 $bitoffset = ceil($bitoffset / 8) * 8;
225
226 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'comment_field_bytes'] =
getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 8));
227 $bitoffset += 8;
228 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'comment_field'] =
getid3_lib::Bin2String(substr($AACheaderBitstream, $bitoffset, 8 * $ThisFileInfo[
'aac'][
'program_configs'][$i][
'comment_field_bytes']));
229 $bitoffset += 8 * $ThisFileInfo['aac']['program_configs'][$i]['comment_field_bytes'];
230
231
232 $ThisFileInfo[
'aac'][
'header'][
'profile_text'] = $this->
AACprofileLookup($ThisFileInfo[
'aac'][
'program_configs'][$i][
'object_type'], $ThisFileInfo[
'aac'][
'header'][
'mpeg_version']);
233 $ThisFileInfo[
'aac'][
'program_configs'][$i][
'sampling_frequency'] = $this->
AACsampleRateLookup($ThisFileInfo[
'aac'][
'program_configs'][$i][
'sampling_frequency_index']);
234 $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency'];
236 if ($ThisFileInfo['aac']['program_configs'][$i]['comment_field']) {
237 $ThisFileInfo['aac']['comments'][] = $ThisFileInfo['aac']['program_configs'][$i]['comment_field'];
238 }
239 }
240 $ThisFileInfo['playtime_seconds'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['audio']['bitrate'];
241
242 $ThisFileInfo['audio']['encoder_options'] = $ThisFileInfo['aac']['header_type'].' '.$ThisFileInfo['aac']['header']['profile_text'];
243
244
245
246 return true;
247
248 } else {
249
250 unset($ThisFileInfo['fileformat']);
251 unset($ThisFileInfo['aac']);
252 $ThisFileInfo['error'][] = 'AAC-ADIF synch not found at offset '.$ThisFileInfo['avdataoffset'].' (expected "ADIF", found "'.substr($AACheader, 0, 4).'" instead)';
253 return false;
254
255 }
256
257 }
AACchannelCountCalculate($program_configs)
AACsampleRateLookup($samplerateid)
AACprofileLookup($profileid, $mpegversion)
Bin2Dec($binstring, $signed=false)