source: branches/MootoolsFileManager-Update/plugins/MootoolsFileManager/mootools-filemanager/Assets/Connector/Assets/getid3/module.audio.aac.php @ 1300

Last change on this file since 1300 was 1300, checked in by gogo, 9 years ago

Update the MootoolsFileManager? to the latest cpojer with some modifications.
Add a demo for the MFM examples/mootools-file-manager.php
Change the default config for ImageManager? and ExtendedFileManager? for added security.

File size: 24.7 KB
RevLine 
[1300]1<?php
2/////////////////////////////////////////////////////////////////
3/// getID3() by James Heinrich <info@getid3.org>               //
4//  available at http://getid3.sourceforge.net                 //
5//            or http://www.getid3.org                         //
6/////////////////////////////////////////////////////////////////
7// See readme.txt for more details                             //
8/////////////////////////////////////////////////////////////////
9//                                                             //
10// module.audio.aac.php                                        //
11// module for analyzing AAC Audio files                        //
12// dependencies: NONE                                          //
13//                                                            ///
14/////////////////////////////////////////////////////////////////
15
16
17class getid3_aac
18{
19
20        // new combined constructor
21        function getid3_aac(&$fd, &$ThisFileInfo, $option) {
22                if ($option === 'adif') {
23                        $this->getAACADIFheaderFilepointer($fd, $ThisFileInfo);
24                } elseif ($option === 'adts') {
25                        $this->getAACADTSheaderFilepointer($fd, $ThisFileInfo);
26                }
27                return true;
28        }
29
30
31
32        function getAACADIFheaderFilepointer(&$fd, &$ThisFileInfo) {
33                $ThisFileInfo['fileformat']          = 'aac';
34                $ThisFileInfo['audio']['dataformat'] = 'aac';
35                $ThisFileInfo['audio']['lossless']   = false;
36
37                fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
38                $AACheader = fread($fd, 1024);
39                $offset    = 0;
40
41                if (substr($AACheader, 0, 4) == 'ADIF') {
42
43                        // http://faac.sourceforge.net/wiki/index.php?page=ADIF
44
45                        // http://libmpeg.org/mpeg4/doc/w2203tfs.pdf
46                        // adif_header() {
47                        //     adif_id                                32
48                        //     copyright_id_present                    1
49                        //     if( copyright_id_present )
50                        //         copyright_id                       72
51                        //     original_copy                           1
52                        //     home                                    1
53                        //     bitstream_type                          1
54                        //     bitrate                                23
55                        //     num_program_config_elements             4
56                        //     for (i = 0; i < num_program_config_elements + 1; i++ ) {
57                        //         if( bitstream_type == '0' )
58                        //             adif_buffer_fullness           20
59                        //         program_config_element()
60                        //     }
61                        // }
62
63                        $AACheaderBitstream = getid3_lib::BigEndian2Bin($AACheader);
64                        $bitoffset          = 0;
65
66                        $ThisFileInfo['aac']['header_type']                   = 'ADIF';
67                        $bitoffset += 32;
68                        $ThisFileInfo['aac']['header']['mpeg_version']        = 4;
69
70                        $ThisFileInfo['aac']['header']['copyright']           = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
71                        $bitoffset += 1;
72                        if ($ThisFileInfo['aac']['header']['copyright']) {
73                                $ThisFileInfo['aac']['header']['copyright_id']    = getid3_lib::Bin2String(substr($AACheaderBitstream, $bitoffset, 72));
74                                $bitoffset += 72;
75                        }
76                        $ThisFileInfo['aac']['header']['original_copy']       = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
77                        $bitoffset += 1;
78                        $ThisFileInfo['aac']['header']['home']                = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
79                        $bitoffset += 1;
80                        $ThisFileInfo['aac']['header']['is_vbr']              = (bool) (substr($AACheaderBitstream, $bitoffset, 1) == '1');
81                        $bitoffset += 1;
82                        if ($ThisFileInfo['aac']['header']['is_vbr']) {
83                                $ThisFileInfo['audio']['bitrate_mode']            = 'vbr';
84                                $ThisFileInfo['aac']['header']['bitrate_max']     = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23));
85                                $bitoffset += 23;
86                        } else {
87                                $ThisFileInfo['audio']['bitrate_mode']            = 'cbr';
88                                $ThisFileInfo['aac']['header']['bitrate']         = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 23));
89                                $bitoffset += 23;
90                                $ThisFileInfo['audio']['bitrate']                 = $ThisFileInfo['aac']['header']['bitrate'];
91                        }
92                        if ($ThisFileInfo['audio']['bitrate'] == 0) {
93                                $ThisFileInfo['error'][] = 'Corrupt AAC file: bitrate_audio == zero';
94                                return false;
95                        }
96                        $ThisFileInfo['aac']['header']['num_program_configs'] = 1 + getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
97                        $bitoffset += 4;
98
99                        for ($i = 0; $i < $ThisFileInfo['aac']['header']['num_program_configs']; $i++) {
100                                // http://www.audiocoding.com/wiki/index.php?page=program_config_element
101
102                                // buffer_fullness                       20
103
104                                // element_instance_tag                   4
105                                // object_type                            2
106                                // sampling_frequency_index               4
107                                // num_front_channel_elements             4
108                                // num_side_channel_elements              4
109                                // num_back_channel_elements              4
110                                // num_lfe_channel_elements               2
111                                // num_assoc_data_elements                3
112                                // num_valid_cc_elements                  4
113                                // mono_mixdown_present                   1
114                                // mono_mixdown_element_number            4   if mono_mixdown_present == 1
115                                // stereo_mixdown_present                 1
116                                // stereo_mixdown_element_number          4   if stereo_mixdown_present == 1
117                                // matrix_mixdown_idx_present             1
118                                // matrix_mixdown_idx                     2   if matrix_mixdown_idx_present == 1
119                                // pseudo_surround_enable                 1   if matrix_mixdown_idx_present == 1
120                                // for (i = 0; i < num_front_channel_elements; i++) {
121                                //     front_element_is_cpe[i]            1
122                                //     front_element_tag_select[i]        4
123                                // }
124                                // for (i = 0; i < num_side_channel_elements; i++) {
125                                //     side_element_is_cpe[i]             1
126                                //     side_element_tag_select[i]         4
127                                // }
128                                // for (i = 0; i < num_back_channel_elements; i++) {
129                                //     back_element_is_cpe[i]             1
130                                //     back_element_tag_select[i]         4
131                                // }
132                                // for (i = 0; i < num_lfe_channel_elements; i++) {
133                                //     lfe_element_tag_select[i]          4
134                                // }
135                                // for (i = 0; i < num_assoc_data_elements; i++) {
136                                //     assoc_data_element_tag_select[i]   4
137                                // }
138                                // for (i = 0; i < num_valid_cc_elements; i++) {
139                                //     cc_element_is_ind_sw[i]            1
140                                //     valid_cc_element_tag_select[i]     4
141                                // }
142                                // byte_alignment()                       VAR
143                                // comment_field_bytes                    8
144                                // for (i = 0; i < comment_field_bytes; i++) {
145                                //     comment_field_data[i]              8
146                                // }
147
148                                if (!$ThisFileInfo['aac']['header']['is_vbr']) {
149                                        $ThisFileInfo['aac']['program_configs'][$i]['buffer_fullness']        = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 20));
150                                        $bitoffset += 20;
151                                }
152                                $ThisFileInfo['aac']['program_configs'][$i]['element_instance_tag']       = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
153                                $bitoffset += 4;
154                                $ThisFileInfo['aac']['program_configs'][$i]['object_type']                = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
155                                $bitoffset += 2;
156                                $ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency_index']   = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
157                                $bitoffset += 4;
158                                $ThisFileInfo['aac']['program_configs'][$i]['num_front_channel_elements'] = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
159                                $bitoffset += 4;
160                                $ThisFileInfo['aac']['program_configs'][$i]['num_side_channel_elements']  = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
161                                $bitoffset += 4;
162                                $ThisFileInfo['aac']['program_configs'][$i]['num_back_channel_elements']  = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
163                                $bitoffset += 4;
164                                $ThisFileInfo['aac']['program_configs'][$i]['num_lfe_channel_elements']   = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
165                                $bitoffset += 2;
166                                $ThisFileInfo['aac']['program_configs'][$i]['num_assoc_data_elements']    = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3));
167                                $bitoffset += 3;
168                                $ThisFileInfo['aac']['program_configs'][$i]['num_valid_cc_elements']      = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
169                                $bitoffset += 4;
170                                $ThisFileInfo['aac']['program_configs'][$i]['mono_mixdown_present']       = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
171                                $bitoffset += 1;
172                                if ($ThisFileInfo['aac']['program_configs'][$i]['mono_mixdown_present']) {
173                                        $ThisFileInfo['aac']['program_configs'][$i]['mono_mixdown_element_number']    = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
174                                        $bitoffset += 4;
175                                }
176                                $ThisFileInfo['aac']['program_configs'][$i]['stereo_mixdown_present']             = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
177                                $bitoffset += 1;
178                                if ($ThisFileInfo['aac']['program_configs'][$i]['stereo_mixdown_present']) {
179                                        $ThisFileInfo['aac']['program_configs'][$i]['stereo_mixdown_element_number']  = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
180                                        $bitoffset += 4;
181                                }
182                                $ThisFileInfo['aac']['program_configs'][$i]['matrix_mixdown_idx_present']         = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
183                                $bitoffset += 1;
184                                if ($ThisFileInfo['aac']['program_configs'][$i]['matrix_mixdown_idx_present']) {
185                                        $ThisFileInfo['aac']['program_configs'][$i]['matrix_mixdown_idx']             = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
186                                        $bitoffset += 2;
187                                        $ThisFileInfo['aac']['program_configs'][$i]['pseudo_surround_enable']         = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
188                                        $bitoffset += 1;
189                                }
190                                for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_front_channel_elements']; $j++) {
191                                        $ThisFileInfo['aac']['program_configs'][$i]['front_element_is_cpe'][$j]     = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
192                                        $bitoffset += 1;
193                                        $ThisFileInfo['aac']['program_configs'][$i]['front_element_tag_select'][$j] = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
194                                        $bitoffset += 4;
195                                }
196                                for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_side_channel_elements']; $j++) {
197                                        $ThisFileInfo['aac']['program_configs'][$i]['side_element_is_cpe'][$j]     = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
198                                        $bitoffset += 1;
199                                        $ThisFileInfo['aac']['program_configs'][$i]['side_element_tag_select'][$j] = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
200                                        $bitoffset += 4;
201                                }
202                                for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_back_channel_elements']; $j++) {
203                                        $ThisFileInfo['aac']['program_configs'][$i]['back_element_is_cpe'][$j]     = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
204                                        $bitoffset += 1;
205                                        $ThisFileInfo['aac']['program_configs'][$i]['back_element_tag_select'][$j] = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
206                                        $bitoffset += 4;
207                                }
208                                for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_lfe_channel_elements']; $j++) {
209                                        $ThisFileInfo['aac']['program_configs'][$i]['lfe_element_tag_select'][$j] = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
210                                        $bitoffset += 4;
211                                }
212                                for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_assoc_data_elements']; $j++) {
213                                        $ThisFileInfo['aac']['program_configs'][$i]['assoc_data_element_tag_select'][$j] = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
214                                        $bitoffset += 4;
215                                }
216                                for ($j = 0; $j < $ThisFileInfo['aac']['program_configs'][$i]['num_valid_cc_elements']; $j++) {
217                                        $ThisFileInfo['aac']['program_configs'][$i]['cc_element_is_ind_sw'][$j]          = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
218                                        $bitoffset += 1;
219                                        $ThisFileInfo['aac']['program_configs'][$i]['valid_cc_element_tag_select'][$j]   = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
220                                        $bitoffset += 4;
221                                }
222
223                                $bitoffset = ceil($bitoffset / 8) * 8;
224
225                                $ThisFileInfo['aac']['program_configs'][$i]['comment_field_bytes'] = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 8));
226                                $bitoffset += 8;
227                                $ThisFileInfo['aac']['program_configs'][$i]['comment_field']       = getid3_lib::Bin2String(substr($AACheaderBitstream, $bitoffset, 8 * $ThisFileInfo['aac']['program_configs'][$i]['comment_field_bytes']));
228                                $bitoffset += 8 * $ThisFileInfo['aac']['program_configs'][$i]['comment_field_bytes'];
229
230
231                                $ThisFileInfo['aac']['header']['profile_text']                      = $this->AACprofileLookup($ThisFileInfo['aac']['program_configs'][$i]['object_type'], $ThisFileInfo['aac']['header']['mpeg_version']);
232                                $ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency']   = $this->AACsampleRateLookup($ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency_index']);
233                                $ThisFileInfo['audio']['sample_rate']                               = $ThisFileInfo['aac']['program_configs'][$i]['sampling_frequency'];
234                                $ThisFileInfo['audio']['channels']                                  = $this->AACchannelCountCalculate($ThisFileInfo['aac']['program_configs'][$i]);
235                                if ($ThisFileInfo['aac']['program_configs'][$i]['comment_field']) {
236                                        $ThisFileInfo['aac']['comments'][]                          = $ThisFileInfo['aac']['program_configs'][$i]['comment_field'];
237                                }
238                        }
239                        $ThisFileInfo['playtime_seconds'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['audio']['bitrate'];
240
241                        $ThisFileInfo['audio']['encoder_options'] = $ThisFileInfo['aac']['header_type'].' '.$ThisFileInfo['aac']['header']['profile_text'];
242
243
244
245                        return true;
246
247                } else {
248
249                        unset($ThisFileInfo['fileformat']);
250                        unset($ThisFileInfo['aac']);
251                        $ThisFileInfo['error'][] = 'AAC-ADIF synch not found at offset '.$ThisFileInfo['avdataoffset'].' (expected "ADIF", found "'.substr($AACheader, 0, 4).'" instead)';
252                        return false;
253
254                }
255
256        }
257
258
259        function getAACADTSheaderFilepointer(&$fd, &$ThisFileInfo, $MaxFramesToScan=1000000, $ReturnExtendedInfo=false) {
260                // based loosely on code from AACfile by Jurgen Faul  <jfaulØgmx.de>
261                // http://jfaul.de/atl  or  http://j-faul.virtualave.net/atl/atl.html
262
263
264                // http://faac.sourceforge.net/wiki/index.php?page=ADTS
265
266                // * ADTS Fixed Header: these don't change from frame to frame
267                // syncword                                       12    always: '111111111111'
268                // ID                                              1    0: MPEG-4, 1: MPEG-2
269                // layer                                           2    always: '00'
270                // protection_absent                               1
271                // profile                                         2
272                // sampling_frequency_index                        4
273                // private_bit                                     1
274                // channel_configuration                           3
275                // original/copy                                   1
276                // home                                            1
277                // emphasis                                        2    only if ID == 0 (ie MPEG-4)
278
279                // * ADTS Variable Header: these can change from frame to frame
280                // copyright_identification_bit                    1
281                // copyright_identification_start                  1
282                // aac_frame_length                               13    length of the frame including header (in bytes)
283                // adts_buffer_fullness                           11    0x7FF indicates VBR
284                // no_raw_data_blocks_in_frame                     2
285
286                // * ADTS Error check
287                // crc_check                                      16    only if protection_absent == 0
288
289                $byteoffset  = 0;
290                $framenumber = 0;
291
292                // Init bit pattern array
293                static $decbin = array();
294
295                // Populate $bindec
296                for ($i = 0; $i < 256; $i++) {
297                        $decbin[chr($i)] = str_pad(decbin($i), 8, '0', STR_PAD_LEFT);
298                }
299
300                // used to calculate bitrate below
301                $BitrateCache = array();
302
303
304                while (true) {
305                        // breaks out when end-of-file encountered, or invalid data found,
306                        // or MaxFramesToScan frames have been scanned
307
308                        if (!getid3_lib::intValueSupported($byteoffset)) {
309                                $ThisFileInfo['warning'][] = 'Unable to parse AAC file beyond '.ftell($fd).' (PHP does not support file operations beyond '.round(PHP_INT_MAX / 1073741824).'GB)';
310                                return false;
311                        }
312                        fseek($fd, $byteoffset, SEEK_SET);
313
314                        // First get substring
315                        $substring = fread($fd, 10);
316                        $substringlength = strlen($substring);
317                        if ($substringlength != 10) {
318                                $ThisFileInfo['error'][] = 'Failed to read 10 bytes at offset '.(ftell($fd) - $substringlength).' (only read '.$substringlength.' bytes)';
319                                return false;
320                        }
321
322                        // Initialise $AACheaderBitstream
323                        $AACheaderBitstream = '';
324
325                        // Loop thru substring chars
326                        for ($i = 0; $i < 10; $i++) {
327                                $AACheaderBitstream .= $decbin[$substring{$i}];
328                        }
329
330                        $bitoffset = 0;
331
332                        $synctest = bindec(substr($AACheaderBitstream, $bitoffset, 12));
333
334                        $bitoffset += 12;
335                        if ($synctest != 0x0FFF) {
336                                $ThisFileInfo['error'][] = 'Synch pattern (0x0FFF) not found at offset '.(ftell($fd) - 10).' (found 0x0'.strtoupper(dechex($synctest)).' instead)';
337                                if ($ThisFileInfo['fileformat'] == 'aac') {
338                                        return true;
339                                }
340                                return false;
341                        }
342
343                        // Gather info for first frame only - this takes time to do 1000 times!
344                        if ($framenumber > 0) {
345
346                                if (!$AACheaderBitstream[$bitoffset]) {
347
348                                        // MPEG-4
349                                        $bitoffset += 20;
350
351                                } else {
352
353                                        // MPEG-2
354                                        $bitoffset += 18;
355
356                                }
357
358                        } else {
359
360                                $ThisFileInfo['aac']['header_type']                      = 'ADTS';
361                                $ThisFileInfo['aac']['header']['synch']                  = $synctest;
362                                $ThisFileInfo['fileformat']                              = 'aac';
363                                $ThisFileInfo['audio']['dataformat']                     = 'aac';
364
365                                $ThisFileInfo['aac']['header']['mpeg_version']           = ((substr($AACheaderBitstream, $bitoffset, 1) == '0') ? 4 : 2);
366                                $bitoffset += 1;
367                                $ThisFileInfo['aac']['header']['layer']                  = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
368                                $bitoffset += 2;
369                                if ($ThisFileInfo['aac']['header']['layer'] != 0) {
370                                        $ThisFileInfo['error'][] = 'Layer error - expected 0x00, found 0x'.dechex($ThisFileInfo['aac']['header']['layer']).' instead';
371                                        return false;
372                                }
373                                $ThisFileInfo['aac']['header']['crc_present']            = ((substr($AACheaderBitstream, $bitoffset, 1) == '0') ? true : false);
374                                $bitoffset += 1;
375                                $ThisFileInfo['aac']['header']['profile_id']             = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
376                                $bitoffset += 2;
377                                $ThisFileInfo['aac']['header']['profile_text']           = $this->AACprofileLookup($ThisFileInfo['aac']['header']['profile_id'], $ThisFileInfo['aac']['header']['mpeg_version']);
378
379                                $ThisFileInfo['aac']['header']['sample_frequency_index'] = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 4));
380                                $bitoffset += 4;
381                                $ThisFileInfo['aac']['header']['sample_frequency']       = $this->AACsampleRateLookup($ThisFileInfo['aac']['header']['sample_frequency_index']);
382                                if ($ThisFileInfo['aac']['header']['sample_frequency'] == 0) {
383                                        $ThisFileInfo['error'][] = 'Corrupt AAC file: sample_frequency == zero';
384                                        return false;
385                                }
386                                $ThisFileInfo['audio']['sample_rate']                    = $ThisFileInfo['aac']['header']['sample_frequency'];
387
388                                $ThisFileInfo['aac']['header']['private']                = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
389                                $bitoffset += 1;
390                                $ThisFileInfo['aac']['header']['channel_configuration']  = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 3));
391                                $bitoffset += 3;
392                                $ThisFileInfo['audio']['channels']                       = $ThisFileInfo['aac']['header']['channel_configuration'];
393                                $ThisFileInfo['aac']['header']['original']               = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
394                                $bitoffset += 1;
395                                $ThisFileInfo['aac']['header']['home']                   = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
396                                $bitoffset += 1;
397
398                                if ($ThisFileInfo['aac']['header']['mpeg_version'] == 4) {
399                                        $ThisFileInfo['aac']['header']['emphasis']           = getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 2));
400                                        $bitoffset += 2;
401                                }
402
403                                if ($ReturnExtendedInfo) {
404
405                                        $ThisFileInfo['aac'][$framenumber]['copyright_id_bit']   = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
406                                        $bitoffset += 1;
407                                        $ThisFileInfo['aac'][$framenumber]['copyright_id_start'] = (bool) getid3_lib::Bin2Dec(substr($AACheaderBitstream, $bitoffset, 1));
408                                        $bitoffset += 1;
409
410                                } else {
411
412                                        $bitoffset += 2;
413
414                                }
415
416                        }
417
418                        $FrameLength = bindec(substr($AACheaderBitstream, $bitoffset, 13));
419
420                        if (!isset($BitrateCache[$FrameLength])) {
421                                $BitrateCache[$FrameLength] = ($ThisFileInfo['aac']['header']['sample_frequency'] / 1024) * $FrameLength * 8;
422                        }
423                        getid3_lib::safe_inc($ThisFileInfo['aac']['bitrate_distribution'][$BitrateCache[$FrameLength]], 1);
424
425                        $ThisFileInfo['aac'][$framenumber]['aac_frame_length']     = $FrameLength;
426                        $bitoffset += 13;
427                        $ThisFileInfo['aac'][$framenumber]['adts_buffer_fullness'] = bindec(substr($AACheaderBitstream, $bitoffset, 11));
428                        $bitoffset += 11;
429                        if ($ThisFileInfo['aac'][$framenumber]['adts_buffer_fullness'] == 0x07FF) {
430                                $ThisFileInfo['audio']['bitrate_mode'] = 'vbr';
431                        } else {
432                                $ThisFileInfo['audio']['bitrate_mode'] = 'cbr';
433                        }
434                        $ThisFileInfo['aac'][$framenumber]['num_raw_data_blocks']  = bindec(substr($AACheaderBitstream, $bitoffset, 2));
435                        $bitoffset += 2;
436
437                        if ($ThisFileInfo['aac']['header']['crc_present']) {
438                                //$ThisFileInfo['aac'][$framenumber]['crc']              = bindec(substr($AACheaderBitstream, $bitoffset, 16));
439                                $bitoffset += 16;
440                        }
441
442                        if (!$ReturnExtendedInfo) {
443                                unset($ThisFileInfo['aac'][$framenumber]);
444                        }
445
446                        $byteoffset += $FrameLength;
447                        if ((++$framenumber < $MaxFramesToScan) && (($byteoffset + 10) < $ThisFileInfo['avdataend'])) {
448
449                                // keep scanning
450
451                        } else {
452
453                                $ThisFileInfo['aac']['frames']    = $framenumber;
454                                $ThisFileInfo['playtime_seconds'] = ($ThisFileInfo['avdataend'] / $byteoffset) * (($framenumber * 1024) / $ThisFileInfo['aac']['header']['sample_frequency']);  // (1 / % of file scanned) * (samples / (samples/sec)) = seconds
455                                if ($ThisFileInfo['playtime_seconds'] == 0) {
456                                        $ThisFileInfo['error'][] = 'Corrupt AAC file: playtime_seconds == zero';
457                                        return false;
458                                }
459                                $ThisFileInfo['audio']['bitrate']    = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / $ThisFileInfo['playtime_seconds'];
460                                ksort($ThisFileInfo['aac']['bitrate_distribution']);
461
462                                $ThisFileInfo['audio']['encoder_options'] = $ThisFileInfo['aac']['header_type'].' '.$ThisFileInfo['aac']['header']['profile_text'];
463
464                                return true;
465
466                        }
467                }
468                // should never get here.
469        }
470
471        function AACsampleRateLookup($samplerateid) {
472                static $AACsampleRateLookup = array();
473                if (empty($AACsampleRateLookup)) {
474                        $AACsampleRateLookup[0]  = 96000;
475                        $AACsampleRateLookup[1]  = 88200;
476                        $AACsampleRateLookup[2]  = 64000;
477                        $AACsampleRateLookup[3]  = 48000;
478                        $AACsampleRateLookup[4]  = 44100;
479                        $AACsampleRateLookup[5]  = 32000;
480                        $AACsampleRateLookup[6]  = 24000;
481                        $AACsampleRateLookup[7]  = 22050;
482                        $AACsampleRateLookup[8]  = 16000;
483                        $AACsampleRateLookup[9]  = 12000;
484                        $AACsampleRateLookup[10] = 11025;
485                        $AACsampleRateLookup[11] = 8000;
486                        $AACsampleRateLookup[12] = 0;
487                        $AACsampleRateLookup[13] = 0;
488                        $AACsampleRateLookup[14] = 0;
489                        $AACsampleRateLookup[15] = 0;
490                }
491                return (isset($AACsampleRateLookup[$samplerateid]) ? $AACsampleRateLookup[$samplerateid] : 'invalid');
492        }
493
494        function AACprofileLookup($profileid, $mpegversion) {
495                static $AACprofileLookup = array();
496                if (empty($AACprofileLookup)) {
497                        $AACprofileLookup[2][0]  = 'Main profile';
498                        $AACprofileLookup[2][1]  = 'Low Complexity profile (LC)';
499                        $AACprofileLookup[2][2]  = 'Scalable Sample Rate profile (SSR)';
500                        $AACprofileLookup[2][3]  = '(reserved)';
501                        $AACprofileLookup[4][0]  = 'AAC_MAIN';
502                        $AACprofileLookup[4][1]  = 'AAC_LC';
503                        $AACprofileLookup[4][2]  = 'AAC_SSR';
504                        $AACprofileLookup[4][3]  = 'AAC_LTP';
505                }
506                return (isset($AACprofileLookup[$mpegversion][$profileid]) ? $AACprofileLookup[$mpegversion][$profileid] : 'invalid');
507        }
508
509        function AACchannelCountCalculate($program_configs) {
510                $channels = 0;
511                for ($i = 0; $i < $program_configs['num_front_channel_elements']; $i++) {
512                        $channels++;
513                        if ($program_configs['front_element_is_cpe'][$i]) {
514                                // each front element is channel pair (CPE = Channel Pair Element)
515                                $channels++;
516                        }
517                }
518                for ($i = 0; $i < $program_configs['num_side_channel_elements']; $i++) {
519                        $channels++;
520                        if ($program_configs['side_element_is_cpe'][$i]) {
521                                // each side element is channel pair (CPE = Channel Pair Element)
522                                $channels++;
523                        }
524                }
525                for ($i = 0; $i < $program_configs['num_back_channel_elements']; $i++) {
526                        $channels++;
527                        if ($program_configs['back_element_is_cpe'][$i]) {
528                                // each back element is channel pair (CPE = Channel Pair Element)
529                                $channels++;
530                        }
531                }
532                for ($i = 0; $i < $program_configs['num_lfe_channel_elements']; $i++) {
533                        $channels++;
534                }
535                return $channels;
536        }
537
538}
539
540
541?>
Note: See TracBrowser for help on using the repository browser.