53 // fscod 2 |
53 // fscod 2 |
54 // frmsizecod 6 |
54 // frmsizecod 6 |
55 // } /* end of syncinfo */ |
55 // } /* end of syncinfo */ |
56 |
56 |
57 $this->fseek($info['avdataoffset']); |
57 $this->fseek($info['avdataoffset']); |
58 $this->AC3header['syncinfo'] = $this->fread(5); |
58 $tempAC3header = $this->fread(100); // should be enough to cover all data, there are some variable-length fields...? |
59 |
59 $this->AC3header['syncinfo'] = getid3_lib::BigEndian2Int(substr($tempAC3header, 0, 2)); |
60 if (strpos($this->AC3header['syncinfo'], self::syncword) === 0) { |
60 $this->AC3header['bsi'] = getid3_lib::BigEndian2Bin(substr($tempAC3header, 2)); |
61 $thisfile_ac3_raw['synchinfo']['synchword'] = self::syncword; |
61 $thisfile_ac3_raw_bsi['bsid'] = (getid3_lib::LittleEndian2Int(substr($tempAC3header, 5, 1)) & 0xF8) >> 3; // AC3 and E-AC3 put the "bsid" version identifier in the same place, but unfortnately the 4 bytes between the syncword and the version identifier are interpreted differently, so grab it here so the following code structure can make sense |
62 $offset = 2; |
62 unset($tempAC3header); |
63 } else { |
63 |
|
64 if ($this->AC3header['syncinfo'] !== self::syncword) { |
64 if (!$this->isDependencyFor('matroska')) { |
65 if (!$this->isDependencyFor('matroska')) { |
65 unset($info['fileformat'], $info['ac3']); |
66 unset($info['fileformat'], $info['ac3']); |
66 return $this->error('Expecting "'.getid3_lib::PrintHexBytes(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes(substr($this->AC3header['syncinfo'], 0, 2)).'"'); |
67 return $this->error('Expecting "'.dechex(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.dechex($this->AC3header['syncinfo']).'"'); |
67 } |
68 } |
68 $offset = 0; |
|
69 $this->fseek(-2, SEEK_CUR); |
|
70 } |
69 } |
71 |
70 |
72 $info['audio']['dataformat'] = 'ac3'; |
71 $info['audio']['dataformat'] = 'ac3'; |
73 $info['audio']['bitrate_mode'] = 'cbr'; |
72 $info['audio']['bitrate_mode'] = 'cbr'; |
74 $info['audio']['lossless'] = false; |
73 $info['audio']['lossless'] = false; |
75 |
74 |
76 $thisfile_ac3_raw['synchinfo']['crc1'] = getid3_lib::LittleEndian2Int(substr($this->AC3header['syncinfo'], $offset, 2)); |
75 if ($thisfile_ac3_raw_bsi['bsid'] <= 8) { |
77 $ac3_synchinfo_fscod_frmsizecod = getid3_lib::LittleEndian2Int(substr($this->AC3header['syncinfo'], ($offset + 2), 1)); |
76 |
78 $thisfile_ac3_raw['synchinfo']['fscod'] = ($ac3_synchinfo_fscod_frmsizecod & 0xC0) >> 6; |
77 $thisfile_ac3_raw_bsi['crc1'] = getid3_lib::Bin2Dec($this->readHeaderBSI(16)); |
79 $thisfile_ac3_raw['synchinfo']['frmsizecod'] = ($ac3_synchinfo_fscod_frmsizecod & 0x3F); |
78 $thisfile_ac3_raw_bsi['fscod'] = $this->readHeaderBSI(2); // 5.4.1.3 |
80 |
79 $thisfile_ac3_raw_bsi['frmsizecod'] = $this->readHeaderBSI(6); // 5.4.1.4 |
81 $thisfile_ac3['sample_rate'] = self::sampleRateCodeLookup($thisfile_ac3_raw['synchinfo']['fscod']); |
80 if ($thisfile_ac3_raw_bsi['frmsizecod'] > 37) { // binary: 100101 - see Table 5.18 Frame Size Code Table (1 word = 16 bits) |
82 if ($thisfile_ac3_raw['synchinfo']['fscod'] <= 3) { |
81 $this->warning('Unexpected ac3.bsi.frmsizecod value: '.$thisfile_ac3_raw_bsi['frmsizecod'].', bitrate not set correctly'); |
83 $info['audio']['sample_rate'] = $thisfile_ac3['sample_rate']; |
82 } |
84 } |
83 |
85 |
84 $thisfile_ac3_raw_bsi['bsid'] = $this->readHeaderBSI(5); // we already know this from pre-parsing the version identifier, but re-read it to let the bitstream flow as intended |
86 $thisfile_ac3['frame_length'] = self::frameSizeLookup($thisfile_ac3_raw['synchinfo']['frmsizecod'], $thisfile_ac3_raw['synchinfo']['fscod']); |
85 $thisfile_ac3_raw_bsi['bsmod'] = $this->readHeaderBSI(3); |
87 $thisfile_ac3['bitrate'] = self::bitrateLookup($thisfile_ac3_raw['synchinfo']['frmsizecod']); |
86 $thisfile_ac3_raw_bsi['acmod'] = $this->readHeaderBSI(3); |
88 $info['audio']['bitrate'] = $thisfile_ac3['bitrate']; |
87 |
89 |
88 if ($thisfile_ac3_raw_bsi['acmod'] & 0x01) { |
90 $this->AC3header['bsi'] = getid3_lib::BigEndian2Bin($this->fread(15)); |
89 // If the lsb of acmod is a 1, center channel is in use and cmixlev follows in the bit stream. |
91 $ac3_bsi_offset = 0; |
90 $thisfile_ac3_raw_bsi['cmixlev'] = $this->readHeaderBSI(2); |
92 |
91 $thisfile_ac3['center_mix_level'] = self::centerMixLevelLookup($thisfile_ac3_raw_bsi['cmixlev']); |
93 $thisfile_ac3_raw_bsi['bsid'] = $this->readHeaderBSI(5); |
92 } |
94 if ($thisfile_ac3_raw_bsi['bsid'] > 8) { |
93 |
95 // Decoders which can decode version 8 will thus be able to decode version numbers less than 8. |
94 if ($thisfile_ac3_raw_bsi['acmod'] & 0x04) { |
96 // If this standard is extended by the addition of additional elements or features, a value of bsid greater than 8 will be used. |
95 // If the msb of acmod is a 1, surround channels are in use and surmixlev follows in the bit stream. |
97 // Decoders built to this version of the standard will not be able to decode versions with bsid greater than 8. |
96 $thisfile_ac3_raw_bsi['surmixlev'] = $this->readHeaderBSI(2); |
98 $this->error('Bit stream identification is version '.$thisfile_ac3_raw_bsi['bsid'].', but getID3() only understands up to version 8'); |
97 $thisfile_ac3['surround_mix_level'] = self::surroundMixLevelLookup($thisfile_ac3_raw_bsi['surmixlev']); |
|
98 } |
|
99 |
|
100 if ($thisfile_ac3_raw_bsi['acmod'] == 0x02) { |
|
101 // When operating in the two channel mode, this 2-bit code indicates whether or not the program has been encoded in Dolby Surround. |
|
102 $thisfile_ac3_raw_bsi['dsurmod'] = $this->readHeaderBSI(2); |
|
103 $thisfile_ac3['dolby_surround_mode'] = self::dolbySurroundModeLookup($thisfile_ac3_raw_bsi['dsurmod']); |
|
104 } |
|
105 |
|
106 $thisfile_ac3_raw_bsi['flags']['lfeon'] = (bool) $this->readHeaderBSI(1); |
|
107 |
|
108 // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31. |
|
109 // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent. |
|
110 $thisfile_ac3_raw_bsi['dialnorm'] = $this->readHeaderBSI(5); // 5.4.2.8 dialnorm: Dialogue Normalization, 5 Bits |
|
111 |
|
112 $thisfile_ac3_raw_bsi['flags']['compr'] = (bool) $this->readHeaderBSI(1); // 5.4.2.9 compre: Compression Gain Word Exists, 1 Bit |
|
113 if ($thisfile_ac3_raw_bsi['flags']['compr']) { |
|
114 $thisfile_ac3_raw_bsi['compr'] = $this->readHeaderBSI(8); // 5.4.2.10 compr: Compression Gain Word, 8 Bits |
|
115 $thisfile_ac3['heavy_compression'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr']); |
|
116 } |
|
117 |
|
118 $thisfile_ac3_raw_bsi['flags']['langcod'] = (bool) $this->readHeaderBSI(1); // 5.4.2.11 langcode: Language Code Exists, 1 Bit |
|
119 if ($thisfile_ac3_raw_bsi['flags']['langcod']) { |
|
120 $thisfile_ac3_raw_bsi['langcod'] = $this->readHeaderBSI(8); // 5.4.2.12 langcod: Language Code, 8 Bits |
|
121 } |
|
122 |
|
123 $thisfile_ac3_raw_bsi['flags']['audprodinfo'] = (bool) $this->readHeaderBSI(1); // 5.4.2.13 audprodie: Audio Production Information Exists, 1 Bit |
|
124 if ($thisfile_ac3_raw_bsi['flags']['audprodinfo']) { |
|
125 $thisfile_ac3_raw_bsi['mixlevel'] = $this->readHeaderBSI(5); // 5.4.2.14 mixlevel: Mixing Level, 5 Bits |
|
126 $thisfile_ac3_raw_bsi['roomtyp'] = $this->readHeaderBSI(2); // 5.4.2.15 roomtyp: Room Type, 2 Bits |
|
127 |
|
128 $thisfile_ac3['mixing_level'] = (80 + $thisfile_ac3_raw_bsi['mixlevel']).'dB'; |
|
129 $thisfile_ac3['room_type'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp']); |
|
130 } |
|
131 |
|
132 |
|
133 $thisfile_ac3_raw_bsi['dialnorm2'] = $this->readHeaderBSI(5); // 5.4.2.16 dialnorm2: Dialogue Normalization, ch2, 5 Bits |
|
134 $thisfile_ac3['dialogue_normalization2'] = '-'.$thisfile_ac3_raw_bsi['dialnorm2'].'dB'; // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31. The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent. |
|
135 |
|
136 $thisfile_ac3_raw_bsi['flags']['compr2'] = (bool) $this->readHeaderBSI(1); // 5.4.2.17 compr2e: Compression Gain Word Exists, ch2, 1 Bit |
|
137 if ($thisfile_ac3_raw_bsi['flags']['compr2']) { |
|
138 $thisfile_ac3_raw_bsi['compr2'] = $this->readHeaderBSI(8); // 5.4.2.18 compr2: Compression Gain Word, ch2, 8 Bits |
|
139 $thisfile_ac3['heavy_compression2'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr2']); |
|
140 } |
|
141 |
|
142 $thisfile_ac3_raw_bsi['flags']['langcod2'] = (bool) $this->readHeaderBSI(1); // 5.4.2.19 langcod2e: Language Code Exists, ch2, 1 Bit |
|
143 if ($thisfile_ac3_raw_bsi['flags']['langcod2']) { |
|
144 $thisfile_ac3_raw_bsi['langcod2'] = $this->readHeaderBSI(8); // 5.4.2.20 langcod2: Language Code, ch2, 8 Bits |
|
145 } |
|
146 |
|
147 $thisfile_ac3_raw_bsi['flags']['audprodinfo2'] = (bool) $this->readHeaderBSI(1); // 5.4.2.21 audprodi2e: Audio Production Information Exists, ch2, 1 Bit |
|
148 if ($thisfile_ac3_raw_bsi['flags']['audprodinfo2']) { |
|
149 $thisfile_ac3_raw_bsi['mixlevel2'] = $this->readHeaderBSI(5); // 5.4.2.22 mixlevel2: Mixing Level, ch2, 5 Bits |
|
150 $thisfile_ac3_raw_bsi['roomtyp2'] = $this->readHeaderBSI(2); // 5.4.2.23 roomtyp2: Room Type, ch2, 2 Bits |
|
151 |
|
152 $thisfile_ac3['mixing_level2'] = (80 + $thisfile_ac3_raw_bsi['mixlevel2']).'dB'; |
|
153 $thisfile_ac3['room_type2'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp2']); |
|
154 } |
|
155 |
|
156 $thisfile_ac3_raw_bsi['copyright'] = (bool) $this->readHeaderBSI(1); // 5.4.2.24 copyrightb: Copyright Bit, 1 Bit |
|
157 |
|
158 $thisfile_ac3_raw_bsi['original'] = (bool) $this->readHeaderBSI(1); // 5.4.2.25 origbs: Original Bit Stream, 1 Bit |
|
159 |
|
160 $thisfile_ac3_raw_bsi['flags']['timecod1'] = $this->readHeaderBSI(2); // 5.4.2.26 timecod1e, timcode2e: Time Code (first and second) Halves Exist, 2 Bits |
|
161 if ($thisfile_ac3_raw_bsi['flags']['timecod1'] & 0x01) { |
|
162 $thisfile_ac3_raw_bsi['timecod1'] = $this->readHeaderBSI(14); // 5.4.2.27 timecod1: Time code first half, 14 bits |
|
163 $thisfile_ac3['timecode1'] = 0; |
|
164 $thisfile_ac3['timecode1'] += (($thisfile_ac3_raw_bsi['timecod1'] & 0x3E00) >> 9) * 3600; // The first 5 bits of this 14-bit field represent the time in hours, with valid values of 0�23 |
|
165 $thisfile_ac3['timecode1'] += (($thisfile_ac3_raw_bsi['timecod1'] & 0x01F8) >> 3) * 60; // The next 6 bits represent the time in minutes, with valid values of 0�59 |
|
166 $thisfile_ac3['timecode1'] += (($thisfile_ac3_raw_bsi['timecod1'] & 0x0003) >> 0) * 8; // The final 3 bits represents the time in 8 second increments, with valid values of 0�7 (representing 0, 8, 16, ... 56 seconds) |
|
167 } |
|
168 if ($thisfile_ac3_raw_bsi['flags']['timecod1'] & 0x02) { |
|
169 $thisfile_ac3_raw_bsi['timecod2'] = $this->readHeaderBSI(14); // 5.4.2.28 timecod2: Time code second half, 14 bits |
|
170 $thisfile_ac3['timecode2'] = 0; |
|
171 $thisfile_ac3['timecode2'] += (($thisfile_ac3_raw_bsi['timecod2'] & 0x3800) >> 11) * 1; // The first 3 bits of this 14-bit field represent the time in seconds, with valid values from 0�7 (representing 0-7 seconds) |
|
172 $thisfile_ac3['timecode2'] += (($thisfile_ac3_raw_bsi['timecod2'] & 0x07C0) >> 6) * (1 / 30); // The next 5 bits represents the time in frames, with valid values from 0�29 (one frame = 1/30th of a second) |
|
173 $thisfile_ac3['timecode2'] += (($thisfile_ac3_raw_bsi['timecod2'] & 0x003F) >> 0) * ((1 / 30) / 60); // The final 6 bits represents fractions of 1/64 of a frame, with valid values from 0�63 |
|
174 } |
|
175 |
|
176 $thisfile_ac3_raw_bsi['flags']['addbsi'] = (bool) $this->readHeaderBSI(1); |
|
177 if ($thisfile_ac3_raw_bsi['flags']['addbsi']) { |
|
178 $thisfile_ac3_raw_bsi['addbsi_length'] = $this->readHeaderBSI(6) + 1; // This 6-bit code, which exists only if addbside is a 1, indicates the length in bytes of additional bit stream information. The valid range of addbsil is 0�63, indicating 1�64 additional bytes, respectively. |
|
179 |
|
180 $this->AC3header['bsi'] .= getid3_lib::BigEndian2Bin($this->fread($thisfile_ac3_raw_bsi['addbsi_length'])); |
|
181 |
|
182 $thisfile_ac3_raw_bsi['addbsi_data'] = substr($this->AC3header['bsi'], $this->BSIoffset, $thisfile_ac3_raw_bsi['addbsi_length'] * 8); |
|
183 $this->BSIoffset += $thisfile_ac3_raw_bsi['addbsi_length'] * 8; |
|
184 } |
|
185 |
|
186 |
|
187 } elseif ($thisfile_ac3_raw_bsi['bsid'] <= 16) { // E-AC3 |
|
188 |
|
189 |
|
190 $this->error('E-AC3 parsing is incomplete and experimental in this version of getID3 ('.$this->getid3->version().'). Notably the bitrate calculations are wrong -- value might (or not) be correct, but it is not calculated correctly. Email info@getid3.org if you know how to calculate EAC3 bitrate correctly.'); |
|
191 $info['audio']['dataformat'] = 'eac3'; |
|
192 |
|
193 $thisfile_ac3_raw_bsi['strmtyp'] = $this->readHeaderBSI(2); |
|
194 $thisfile_ac3_raw_bsi['substreamid'] = $this->readHeaderBSI(3); |
|
195 $thisfile_ac3_raw_bsi['frmsiz'] = $this->readHeaderBSI(11); |
|
196 $thisfile_ac3_raw_bsi['fscod'] = $this->readHeaderBSI(2); |
|
197 if ($thisfile_ac3_raw_bsi['fscod'] == 3) { |
|
198 $thisfile_ac3_raw_bsi['fscod2'] = $this->readHeaderBSI(2); |
|
199 $thisfile_ac3_raw_bsi['numblkscod'] = 3; // six blocks per syncframe |
|
200 } else { |
|
201 $thisfile_ac3_raw_bsi['numblkscod'] = $this->readHeaderBSI(2); |
|
202 } |
|
203 $thisfile_ac3['bsi']['blocks_per_sync_frame'] = self::blocksPerSyncFrame($thisfile_ac3_raw_bsi['numblkscod']); |
|
204 $thisfile_ac3_raw_bsi['acmod'] = $this->readHeaderBSI(3); |
|
205 $thisfile_ac3_raw_bsi['flags']['lfeon'] = (bool) $this->readHeaderBSI(1); |
|
206 $thisfile_ac3_raw_bsi['bsid'] = $this->readHeaderBSI(5); // we already know this from pre-parsing the version identifier, but re-read it to let the bitstream flow as intended |
|
207 $thisfile_ac3_raw_bsi['dialnorm'] = $this->readHeaderBSI(5); |
|
208 $thisfile_ac3_raw_bsi['flags']['compr'] = (bool) $this->readHeaderBSI(1); |
|
209 if ($thisfile_ac3_raw_bsi['flags']['compr']) { |
|
210 $thisfile_ac3_raw_bsi['compr'] = $this->readHeaderBSI(8); |
|
211 } |
|
212 if ($thisfile_ac3_raw_bsi['acmod'] == 0) { // if 1+1 mode (dual mono, so some items need a second value) |
|
213 $thisfile_ac3_raw_bsi['dialnorm2'] = $this->readHeaderBSI(5); |
|
214 $thisfile_ac3_raw_bsi['flags']['compr2'] = (bool) $this->readHeaderBSI(1); |
|
215 if ($thisfile_ac3_raw_bsi['flags']['compr2']) { |
|
216 $thisfile_ac3_raw_bsi['compr2'] = $this->readHeaderBSI(8); |
|
217 } |
|
218 } |
|
219 if ($thisfile_ac3_raw_bsi['strmtyp'] == 1) { // if dependent stream |
|
220 $thisfile_ac3_raw_bsi['flags']['chanmap'] = (bool) $this->readHeaderBSI(1); |
|
221 if ($thisfile_ac3_raw_bsi['flags']['chanmap']) { |
|
222 $thisfile_ac3_raw_bsi['chanmap'] = $this->readHeaderBSI(8); |
|
223 } |
|
224 } |
|
225 $thisfile_ac3_raw_bsi['flags']['mixmdat'] = (bool) $this->readHeaderBSI(1); |
|
226 if ($thisfile_ac3_raw_bsi['flags']['mixmdat']) { // Mixing metadata |
|
227 if ($thisfile_ac3_raw_bsi['acmod'] > 2) { // if more than 2 channels |
|
228 $thisfile_ac3_raw_bsi['dmixmod'] = $this->readHeaderBSI(2); |
|
229 } |
|
230 if (($thisfile_ac3_raw_bsi['acmod'] & 0x01) && ($thisfile_ac3_raw_bsi['acmod'] > 2)) { // if three front channels exist |
|
231 $thisfile_ac3_raw_bsi['ltrtcmixlev'] = $this->readHeaderBSI(3); |
|
232 $thisfile_ac3_raw_bsi['lorocmixlev'] = $this->readHeaderBSI(3); |
|
233 } |
|
234 if ($thisfile_ac3_raw_bsi['acmod'] & 0x04) { // if a surround channel exists |
|
235 $thisfile_ac3_raw_bsi['ltrtsurmixlev'] = $this->readHeaderBSI(3); |
|
236 $thisfile_ac3_raw_bsi['lorosurmixlev'] = $this->readHeaderBSI(3); |
|
237 } |
|
238 if ($thisfile_ac3_raw_bsi['flags']['lfeon']) { // if the LFE channel exists |
|
239 $thisfile_ac3_raw_bsi['flags']['lfemixlevcod'] = (bool) $this->readHeaderBSI(1); |
|
240 if ($thisfile_ac3_raw_bsi['flags']['lfemixlevcod']) { |
|
241 $thisfile_ac3_raw_bsi['lfemixlevcod'] = $this->readHeaderBSI(5); |
|
242 } |
|
243 } |
|
244 if ($thisfile_ac3_raw_bsi['strmtyp'] == 0) { // if independent stream |
|
245 $thisfile_ac3_raw_bsi['flags']['pgmscl'] = (bool) $this->readHeaderBSI(1); |
|
246 if ($thisfile_ac3_raw_bsi['flags']['pgmscl']) { |
|
247 $thisfile_ac3_raw_bsi['pgmscl'] = $this->readHeaderBSI(6); |
|
248 } |
|
249 if ($thisfile_ac3_raw_bsi['acmod'] == 0) { // if 1+1 mode (dual mono, so some items need a second value) |
|
250 $thisfile_ac3_raw_bsi['flags']['pgmscl2'] = (bool) $this->readHeaderBSI(1); |
|
251 if ($thisfile_ac3_raw_bsi['flags']['pgmscl2']) { |
|
252 $thisfile_ac3_raw_bsi['pgmscl2'] = $this->readHeaderBSI(6); |
|
253 } |
|
254 } |
|
255 $thisfile_ac3_raw_bsi['flags']['extpgmscl'] = (bool) $this->readHeaderBSI(1); |
|
256 if ($thisfile_ac3_raw_bsi['flags']['extpgmscl']) { |
|
257 $thisfile_ac3_raw_bsi['extpgmscl'] = $this->readHeaderBSI(6); |
|
258 } |
|
259 $thisfile_ac3_raw_bsi['mixdef'] = $this->readHeaderBSI(2); |
|
260 if ($thisfile_ac3_raw_bsi['mixdef'] == 1) { // mixing option 2 |
|
261 $thisfile_ac3_raw_bsi['premixcmpsel'] = (bool) $this->readHeaderBSI(1); |
|
262 $thisfile_ac3_raw_bsi['drcsrc'] = (bool) $this->readHeaderBSI(1); |
|
263 $thisfile_ac3_raw_bsi['premixcmpscl'] = $this->readHeaderBSI(3); |
|
264 } elseif ($thisfile_ac3_raw_bsi['mixdef'] == 2) { // mixing option 3 |
|
265 $thisfile_ac3_raw_bsi['mixdata'] = $this->readHeaderBSI(12); |
|
266 } elseif ($thisfile_ac3_raw_bsi['mixdef'] == 3) { // mixing option 4 |
|
267 $mixdefbitsread = 0; |
|
268 $thisfile_ac3_raw_bsi['mixdeflen'] = $this->readHeaderBSI(5); $mixdefbitsread += 5; |
|
269 $thisfile_ac3_raw_bsi['flags']['mixdata2'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
270 if ($thisfile_ac3_raw_bsi['flags']['mixdata2']) { |
|
271 $thisfile_ac3_raw_bsi['premixcmpsel'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
272 $thisfile_ac3_raw_bsi['drcsrc'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
273 $thisfile_ac3_raw_bsi['premixcmpscl'] = $this->readHeaderBSI(3); $mixdefbitsread += 3; |
|
274 $thisfile_ac3_raw_bsi['flags']['extpgmlscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
275 if ($thisfile_ac3_raw_bsi['flags']['extpgmlscl']) { |
|
276 $thisfile_ac3_raw_bsi['extpgmlscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4; |
|
277 } |
|
278 $thisfile_ac3_raw_bsi['flags']['extpgmcscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
279 if ($thisfile_ac3_raw_bsi['flags']['extpgmcscl']) { |
|
280 $thisfile_ac3_raw_bsi['extpgmcscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4; |
|
281 } |
|
282 $thisfile_ac3_raw_bsi['flags']['extpgmrscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
283 if ($thisfile_ac3_raw_bsi['flags']['extpgmrscl']) { |
|
284 $thisfile_ac3_raw_bsi['extpgmrscl'] = $this->readHeaderBSI(4); |
|
285 } |
|
286 $thisfile_ac3_raw_bsi['flags']['extpgmlsscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
287 if ($thisfile_ac3_raw_bsi['flags']['extpgmlsscl']) { |
|
288 $thisfile_ac3_raw_bsi['extpgmlsscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4; |
|
289 } |
|
290 $thisfile_ac3_raw_bsi['flags']['extpgmrsscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
291 if ($thisfile_ac3_raw_bsi['flags']['extpgmrsscl']) { |
|
292 $thisfile_ac3_raw_bsi['extpgmrsscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4; |
|
293 } |
|
294 $thisfile_ac3_raw_bsi['flags']['extpgmlfescl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
295 if ($thisfile_ac3_raw_bsi['flags']['extpgmlfescl']) { |
|
296 $thisfile_ac3_raw_bsi['extpgmlfescl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4; |
|
297 } |
|
298 $thisfile_ac3_raw_bsi['flags']['dmixscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
299 if ($thisfile_ac3_raw_bsi['flags']['dmixscl']) { |
|
300 $thisfile_ac3_raw_bsi['dmixscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4; |
|
301 } |
|
302 $thisfile_ac3_raw_bsi['flags']['addch'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
303 if ($thisfile_ac3_raw_bsi['flags']['addch']) { |
|
304 $thisfile_ac3_raw_bsi['flags']['extpgmaux1scl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
305 if ($thisfile_ac3_raw_bsi['flags']['extpgmaux1scl']) { |
|
306 $thisfile_ac3_raw_bsi['extpgmaux1scl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4; |
|
307 } |
|
308 $thisfile_ac3_raw_bsi['flags']['extpgmaux2scl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
309 if ($thisfile_ac3_raw_bsi['flags']['extpgmaux2scl']) { |
|
310 $thisfile_ac3_raw_bsi['extpgmaux2scl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4; |
|
311 } |
|
312 } |
|
313 } |
|
314 $thisfile_ac3_raw_bsi['flags']['mixdata3'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
315 if ($thisfile_ac3_raw_bsi['flags']['mixdata3']) { |
|
316 $thisfile_ac3_raw_bsi['spchdat'] = $this->readHeaderBSI(5); $mixdefbitsread += 5; |
|
317 $thisfile_ac3_raw_bsi['flags']['addspchdat'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
318 if ($thisfile_ac3_raw_bsi['flags']['addspchdat']) { |
|
319 $thisfile_ac3_raw_bsi['spchdat1'] = $this->readHeaderBSI(5); $mixdefbitsread += 5; |
|
320 $thisfile_ac3_raw_bsi['spchan1att'] = $this->readHeaderBSI(2); $mixdefbitsread += 2; |
|
321 $thisfile_ac3_raw_bsi['flags']['addspchdat1'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1; |
|
322 if ($thisfile_ac3_raw_bsi['flags']['addspchdat1']) { |
|
323 $thisfile_ac3_raw_bsi['spchdat2'] = $this->readHeaderBSI(5); $mixdefbitsread += 5; |
|
324 $thisfile_ac3_raw_bsi['spchan2att'] = $this->readHeaderBSI(3); $mixdefbitsread += 3; |
|
325 } |
|
326 } |
|
327 } |
|
328 $mixdata_bits = (8 * ($thisfile_ac3_raw_bsi['mixdeflen'] + 2)) - $mixdefbitsread; |
|
329 $mixdata_fill = (($mixdata_bits % 8) ? 8 - ($mixdata_bits % 8) : 0); |
|
330 $thisfile_ac3_raw_bsi['mixdata'] = $this->readHeaderBSI($mixdata_bits); |
|
331 $thisfile_ac3_raw_bsi['mixdatafill'] = $this->readHeaderBSI($mixdata_fill); |
|
332 unset($mixdefbitsread, $mixdata_bits, $mixdata_fill); |
|
333 } |
|
334 if ($thisfile_ac3_raw_bsi['acmod'] < 2) { // if mono or dual mono source |
|
335 $thisfile_ac3_raw_bsi['flags']['paninfo'] = (bool) $this->readHeaderBSI(1); |
|
336 if ($thisfile_ac3_raw_bsi['flags']['paninfo']) { |
|
337 $thisfile_ac3_raw_bsi['panmean'] = $this->readHeaderBSI(8); |
|
338 $thisfile_ac3_raw_bsi['paninfo'] = $this->readHeaderBSI(6); |
|
339 } |
|
340 if ($thisfile_ac3_raw_bsi['acmod'] == 0) { // if 1+1 mode (dual mono, so some items need a second value) |
|
341 $thisfile_ac3_raw_bsi['flags']['paninfo2'] = (bool) $this->readHeaderBSI(1); |
|
342 if ($thisfile_ac3_raw_bsi['flags']['paninfo2']) { |
|
343 $thisfile_ac3_raw_bsi['panmean2'] = $this->readHeaderBSI(8); |
|
344 $thisfile_ac3_raw_bsi['paninfo2'] = $this->readHeaderBSI(6); |
|
345 } |
|
346 } |
|
347 } |
|
348 $thisfile_ac3_raw_bsi['flags']['frmmixcfginfo'] = (bool) $this->readHeaderBSI(1); |
|
349 if ($thisfile_ac3_raw_bsi['flags']['frmmixcfginfo']) { // mixing configuration information |
|
350 if ($thisfile_ac3_raw_bsi['numblkscod'] == 0) { |
|
351 $thisfile_ac3_raw_bsi['blkmixcfginfo'][0] = $this->readHeaderBSI(5); |
|
352 } else { |
|
353 for ($blk = 0; $blk < $thisfile_ac3_raw_bsi['numblkscod']; $blk++) { |
|
354 $thisfile_ac3_raw_bsi['flags']['blkmixcfginfo'.$blk] = (bool) $this->readHeaderBSI(1); |
|
355 if ($thisfile_ac3_raw_bsi['flags']['blkmixcfginfo'.$blk]) { // mixing configuration information |
|
356 $thisfile_ac3_raw_bsi['blkmixcfginfo'][$blk] = $this->readHeaderBSI(5); |
|
357 } |
|
358 } |
|
359 } |
|
360 } |
|
361 } |
|
362 } |
|
363 $thisfile_ac3_raw_bsi['flags']['infomdat'] = (bool) $this->readHeaderBSI(1); |
|
364 if ($thisfile_ac3_raw_bsi['flags']['infomdat']) { // Informational metadata |
|
365 $thisfile_ac3_raw_bsi['bsmod'] = $this->readHeaderBSI(3); |
|
366 $thisfile_ac3_raw_bsi['flags']['copyrightb'] = (bool) $this->readHeaderBSI(1); |
|
367 $thisfile_ac3_raw_bsi['flags']['origbs'] = (bool) $this->readHeaderBSI(1); |
|
368 if ($thisfile_ac3_raw_bsi['acmod'] == 2) { // if in 2/0 mode |
|
369 $thisfile_ac3_raw_bsi['dsurmod'] = $this->readHeaderBSI(2); |
|
370 $thisfile_ac3_raw_bsi['dheadphonmod'] = $this->readHeaderBSI(2); |
|
371 } |
|
372 if ($thisfile_ac3_raw_bsi['acmod'] >= 6) { // if both surround channels exist |
|
373 $thisfile_ac3_raw_bsi['dsurexmod'] = $this->readHeaderBSI(2); |
|
374 } |
|
375 $thisfile_ac3_raw_bsi['flags']['audprodi'] = (bool) $this->readHeaderBSI(1); |
|
376 if ($thisfile_ac3_raw_bsi['flags']['audprodi']) { |
|
377 $thisfile_ac3_raw_bsi['mixlevel'] = $this->readHeaderBSI(5); |
|
378 $thisfile_ac3_raw_bsi['roomtyp'] = $this->readHeaderBSI(2); |
|
379 $thisfile_ac3_raw_bsi['flags']['adconvtyp'] = (bool) $this->readHeaderBSI(1); |
|
380 } |
|
381 if ($thisfile_ac3_raw_bsi['acmod'] == 0) { // if 1+1 mode (dual mono, so some items need a second value) |
|
382 $thisfile_ac3_raw_bsi['flags']['audprodi2'] = (bool) $this->readHeaderBSI(1); |
|
383 if ($thisfile_ac3_raw_bsi['flags']['audprodi2']) { |
|
384 $thisfile_ac3_raw_bsi['mixlevel2'] = $this->readHeaderBSI(5); |
|
385 $thisfile_ac3_raw_bsi['roomtyp2'] = $this->readHeaderBSI(2); |
|
386 $thisfile_ac3_raw_bsi['flags']['adconvtyp2'] = (bool) $this->readHeaderBSI(1); |
|
387 } |
|
388 } |
|
389 if ($thisfile_ac3_raw_bsi['fscod'] < 3) { // if not half sample rate |
|
390 $thisfile_ac3_raw_bsi['flags']['sourcefscod'] = (bool) $this->readHeaderBSI(1); |
|
391 } |
|
392 } |
|
393 if (($thisfile_ac3_raw_bsi['strmtyp'] == 0) && ($thisfile_ac3_raw_bsi['numblkscod'] != 3)) { // if both surround channels exist |
|
394 $thisfile_ac3_raw_bsi['flags']['convsync'] = (bool) $this->readHeaderBSI(1); |
|
395 } |
|
396 if ($thisfile_ac3_raw_bsi['strmtyp'] == 2) { // if bit stream converted from AC-3 |
|
397 if ($thisfile_ac3_raw_bsi['numblkscod'] != 3) { // 6 blocks per syncframe |
|
398 $thisfile_ac3_raw_bsi['flags']['blkid'] = 1; |
|
399 } else { |
|
400 $thisfile_ac3_raw_bsi['flags']['blkid'] = (bool) $this->readHeaderBSI(1); |
|
401 } |
|
402 if ($thisfile_ac3_raw_bsi['flags']['blkid']) { |
|
403 $thisfile_ac3_raw_bsi['frmsizecod'] = $this->readHeaderBSI(6); |
|
404 } |
|
405 } |
|
406 $thisfile_ac3_raw_bsi['flags']['addbsi'] = (bool) $this->readHeaderBSI(1); |
|
407 if ($thisfile_ac3_raw_bsi['flags']['addbsi']) { |
|
408 $thisfile_ac3_raw_bsi['addbsil'] = $this->readHeaderBSI(6); |
|
409 $thisfile_ac3_raw_bsi['addbsi'] = $this->readHeaderBSI(($thisfile_ac3_raw_bsi['addbsil'] + 1) * 8); |
|
410 } |
|
411 |
|
412 } else { |
|
413 |
|
414 $this->error('Bit stream identification is version '.$thisfile_ac3_raw_bsi['bsid'].', but getID3() only understands up to version 16. Please submit a support ticket with a sample file.'); |
99 unset($info['ac3']); |
415 unset($info['ac3']); |
100 return false; |
416 return false; |
101 } |
417 |
102 |
418 } |
103 $thisfile_ac3_raw_bsi['bsmod'] = $this->readHeaderBSI(3); |
419 |
104 $thisfile_ac3_raw_bsi['acmod'] = $this->readHeaderBSI(3); |
420 if (isset($thisfile_ac3_raw_bsi['fscod2'])) { |
|
421 $thisfile_ac3['sample_rate'] = self::sampleRateCodeLookup2($thisfile_ac3_raw_bsi['fscod2']); |
|
422 } else { |
|
423 $thisfile_ac3['sample_rate'] = self::sampleRateCodeLookup($thisfile_ac3_raw_bsi['fscod']); |
|
424 } |
|
425 if ($thisfile_ac3_raw_bsi['fscod'] <= 3) { |
|
426 $info['audio']['sample_rate'] = $thisfile_ac3['sample_rate']; |
|
427 } else { |
|
428 $this->warning('Unexpected ac3.bsi.fscod value: '.$thisfile_ac3_raw_bsi['fscod']); |
|
429 } |
|
430 if (isset($thisfile_ac3_raw_bsi['frmsizecod'])) { |
|
431 $thisfile_ac3['frame_length'] = self::frameSizeLookup($thisfile_ac3_raw_bsi['frmsizecod'], $thisfile_ac3_raw_bsi['fscod']); |
|
432 $thisfile_ac3['bitrate'] = self::bitrateLookup($thisfile_ac3_raw_bsi['frmsizecod']); |
|
433 } elseif (!empty($thisfile_ac3_raw_bsi['frmsiz'])) { |
|
434 // this isn't right, but it's (usually) close, roughly 5% less than it should be. |
|
435 // but WHERE is the actual bitrate value stored in EAC3?? email info@getid3.org if you know! |
|
436 $thisfile_ac3['bitrate'] = ($thisfile_ac3_raw_bsi['frmsiz'] + 1) * 16 * 30; // The frmsiz field shall contain a value one less than the overall size of the coded syncframe in 16-bit words. That is, this field may assume a value ranging from 0 to 2047, and these values correspond to syncframe sizes ranging from 1 to 2048. |
|
437 // kludge-fix to make it approximately the expected value, still not "right": |
|
438 $thisfile_ac3['bitrate'] = round(($thisfile_ac3['bitrate'] * 1.05) / 16000) * 16000; |
|
439 } |
|
440 $info['audio']['bitrate'] = $thisfile_ac3['bitrate']; |
105 |
441 |
106 $thisfile_ac3['service_type'] = self::serviceTypeLookup($thisfile_ac3_raw_bsi['bsmod'], $thisfile_ac3_raw_bsi['acmod']); |
442 $thisfile_ac3['service_type'] = self::serviceTypeLookup($thisfile_ac3_raw_bsi['bsmod'], $thisfile_ac3_raw_bsi['acmod']); |
107 $ac3_coding_mode = self::audioCodingModeLookup($thisfile_ac3_raw_bsi['acmod']); |
443 $ac3_coding_mode = self::audioCodingModeLookup($thisfile_ac3_raw_bsi['acmod']); |
108 foreach($ac3_coding_mode as $key => $value) { |
444 foreach($ac3_coding_mode as $key => $value) { |
109 $thisfile_ac3[$key] = $value; |
445 $thisfile_ac3[$key] = $value; |
121 $info['audio']['channelmode'] = 'surround'; |
457 $info['audio']['channelmode'] = 'surround'; |
122 break; |
458 break; |
123 } |
459 } |
124 $info['audio']['channels'] = $thisfile_ac3['num_channels']; |
460 $info['audio']['channels'] = $thisfile_ac3['num_channels']; |
125 |
461 |
126 if ($thisfile_ac3_raw_bsi['acmod'] & 0x01) { |
462 $thisfile_ac3['lfe_enabled'] = $thisfile_ac3_raw_bsi['flags']['lfeon']; |
127 // If the lsb of acmod is a 1, center channel is in use and cmixlev follows in the bit stream. |
463 if ($thisfile_ac3_raw_bsi['flags']['lfeon']) { |
128 $thisfile_ac3_raw_bsi['cmixlev'] = $this->readHeaderBSI(2); |
|
129 $thisfile_ac3['center_mix_level'] = self::centerMixLevelLookup($thisfile_ac3_raw_bsi['cmixlev']); |
|
130 } |
|
131 |
|
132 if ($thisfile_ac3_raw_bsi['acmod'] & 0x04) { |
|
133 // If the msb of acmod is a 1, surround channels are in use and surmixlev follows in the bit stream. |
|
134 $thisfile_ac3_raw_bsi['surmixlev'] = $this->readHeaderBSI(2); |
|
135 $thisfile_ac3['surround_mix_level'] = self::surroundMixLevelLookup($thisfile_ac3_raw_bsi['surmixlev']); |
|
136 } |
|
137 |
|
138 if ($thisfile_ac3_raw_bsi['acmod'] == 0x02) { |
|
139 // When operating in the two channel mode, this 2-bit code indicates whether or not the program has been encoded in Dolby Surround. |
|
140 $thisfile_ac3_raw_bsi['dsurmod'] = $this->readHeaderBSI(2); |
|
141 $thisfile_ac3['dolby_surround_mode'] = self::dolbySurroundModeLookup($thisfile_ac3_raw_bsi['dsurmod']); |
|
142 } |
|
143 |
|
144 $thisfile_ac3_raw_bsi['lfeon'] = (bool) $this->readHeaderBSI(1); |
|
145 $thisfile_ac3['lfe_enabled'] = $thisfile_ac3_raw_bsi['lfeon']; |
|
146 if ($thisfile_ac3_raw_bsi['lfeon']) { |
|
147 //$info['audio']['channels']++; |
|
148 $info['audio']['channels'] .= '.1'; |
464 $info['audio']['channels'] .= '.1'; |
149 } |
465 } |
150 |
466 |
151 $thisfile_ac3['channels_enabled'] = self::channelsEnabledLookup($thisfile_ac3_raw_bsi['acmod'], $thisfile_ac3_raw_bsi['lfeon']); |
467 $thisfile_ac3['channels_enabled'] = self::channelsEnabledLookup($thisfile_ac3_raw_bsi['acmod'], $thisfile_ac3_raw_bsi['flags']['lfeon']); |
152 |
|
153 // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31. |
|
154 // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent. |
|
155 $thisfile_ac3_raw_bsi['dialnorm'] = $this->readHeaderBSI(5); |
|
156 $thisfile_ac3['dialogue_normalization'] = '-'.$thisfile_ac3_raw_bsi['dialnorm'].'dB'; |
468 $thisfile_ac3['dialogue_normalization'] = '-'.$thisfile_ac3_raw_bsi['dialnorm'].'dB'; |
157 |
|
158 $thisfile_ac3_raw_bsi['compre_flag'] = (bool) $this->readHeaderBSI(1); |
|
159 if ($thisfile_ac3_raw_bsi['compre_flag']) { |
|
160 $thisfile_ac3_raw_bsi['compr'] = $this->readHeaderBSI(8); |
|
161 $thisfile_ac3['heavy_compression'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr']); |
|
162 } |
|
163 |
|
164 $thisfile_ac3_raw_bsi['langcode_flag'] = (bool) $this->readHeaderBSI(1); |
|
165 if ($thisfile_ac3_raw_bsi['langcode_flag']) { |
|
166 $thisfile_ac3_raw_bsi['langcod'] = $this->readHeaderBSI(8); |
|
167 } |
|
168 |
|
169 $thisfile_ac3_raw_bsi['audprodie'] = (bool) $this->readHeaderBSI(1); |
|
170 if ($thisfile_ac3_raw_bsi['audprodie']) { |
|
171 $thisfile_ac3_raw_bsi['mixlevel'] = $this->readHeaderBSI(5); |
|
172 $thisfile_ac3_raw_bsi['roomtyp'] = $this->readHeaderBSI(2); |
|
173 |
|
174 $thisfile_ac3['mixing_level'] = (80 + $thisfile_ac3_raw_bsi['mixlevel']).'dB'; |
|
175 $thisfile_ac3['room_type'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp']); |
|
176 } |
|
177 |
|
178 if ($thisfile_ac3_raw_bsi['acmod'] == 0x00) { |
|
179 // If acmod is 0, then two completely independent program channels (dual mono) |
|
180 // are encoded into the bit stream, and are referenced as Ch1, Ch2. In this case, |
|
181 // a number of additional items are present in BSI or audblk to fully describe Ch2. |
|
182 |
|
183 // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31. |
|
184 // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent. |
|
185 $thisfile_ac3_raw_bsi['dialnorm2'] = $this->readHeaderBSI(5); |
|
186 $thisfile_ac3['dialogue_normalization2'] = '-'.$thisfile_ac3_raw_bsi['dialnorm2'].'dB'; |
|
187 |
|
188 $thisfile_ac3_raw_bsi['compre_flag2'] = (bool) $this->readHeaderBSI(1); |
|
189 if ($thisfile_ac3_raw_bsi['compre_flag2']) { |
|
190 $thisfile_ac3_raw_bsi['compr2'] = $this->readHeaderBSI(8); |
|
191 $thisfile_ac3['heavy_compression2'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr2']); |
|
192 } |
|
193 |
|
194 $thisfile_ac3_raw_bsi['langcode_flag2'] = (bool) $this->readHeaderBSI(1); |
|
195 if ($thisfile_ac3_raw_bsi['langcode_flag2']) { |
|
196 $thisfile_ac3_raw_bsi['langcod2'] = $this->readHeaderBSI(8); |
|
197 } |
|
198 |
|
199 $thisfile_ac3_raw_bsi['audprodie2'] = (bool) $this->readHeaderBSI(1); |
|
200 if ($thisfile_ac3_raw_bsi['audprodie2']) { |
|
201 $thisfile_ac3_raw_bsi['mixlevel2'] = $this->readHeaderBSI(5); |
|
202 $thisfile_ac3_raw_bsi['roomtyp2'] = $this->readHeaderBSI(2); |
|
203 |
|
204 $thisfile_ac3['mixing_level2'] = (80 + $thisfile_ac3_raw_bsi['mixlevel2']).'dB'; |
|
205 $thisfile_ac3['room_type2'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp2']); |
|
206 } |
|
207 |
|
208 } |
|
209 |
|
210 $thisfile_ac3_raw_bsi['copyright'] = (bool) $this->readHeaderBSI(1); |
|
211 |
|
212 $thisfile_ac3_raw_bsi['original'] = (bool) $this->readHeaderBSI(1); |
|
213 |
|
214 $thisfile_ac3_raw_bsi['timecode1_flag'] = (bool) $this->readHeaderBSI(1); |
|
215 if ($thisfile_ac3_raw_bsi['timecode1_flag']) { |
|
216 $thisfile_ac3_raw_bsi['timecode1'] = $this->readHeaderBSI(14); |
|
217 } |
|
218 |
|
219 $thisfile_ac3_raw_bsi['timecode2_flag'] = (bool) $this->readHeaderBSI(1); |
|
220 if ($thisfile_ac3_raw_bsi['timecode2_flag']) { |
|
221 $thisfile_ac3_raw_bsi['timecode2'] = $this->readHeaderBSI(14); |
|
222 } |
|
223 |
|
224 $thisfile_ac3_raw_bsi['addbsi_flag'] = (bool) $this->readHeaderBSI(1); |
|
225 if ($thisfile_ac3_raw_bsi['addbsi_flag']) { |
|
226 $thisfile_ac3_raw_bsi['addbsi_length'] = $this->readHeaderBSI(6); |
|
227 |
|
228 $this->AC3header['bsi'] .= getid3_lib::BigEndian2Bin($this->fread($thisfile_ac3_raw_bsi['addbsi_length'])); |
|
229 |
|
230 $thisfile_ac3_raw_bsi['addbsi_data'] = substr($this->AC3header['bsi'], $this->BSIoffset, $thisfile_ac3_raw_bsi['addbsi_length'] * 8); |
|
231 $this->BSIoffset += $thisfile_ac3_raw_bsi['addbsi_length'] * 8; |
|
232 } |
|
233 |
469 |
234 return true; |
470 return true; |
235 } |
471 } |
236 |
472 |
237 private function readHeaderBSI($length) { |
473 private function readHeaderBSI($length) { |
407 ); |
653 ); |
408 return (isset($roomTypeLookup[$roomtyp]) ? $roomTypeLookup[$roomtyp] : false); |
654 return (isset($roomTypeLookup[$roomtyp]) ? $roomTypeLookup[$roomtyp] : false); |
409 } |
655 } |
410 |
656 |
411 public static function frameSizeLookup($frmsizecod, $fscod) { |
657 public static function frameSizeLookup($frmsizecod, $fscod) { |
412 $padding = (bool) ($frmsizecod % 2); |
658 // LSB is whether padding is used or not |
413 $framesizeid = floor($frmsizecod / 2); |
659 $padding = (bool) ($frmsizecod & 0x01); |
|
660 $framesizeid = ($frmsizecod & 0x3E) >> 1; |
414 |
661 |
415 static $frameSizeLookup = array(); |
662 static $frameSizeLookup = array(); |
416 if (empty($frameSizeLookup)) { |
663 if (empty($frameSizeLookup)) { |
417 $frameSizeLookup = array ( |
664 $frameSizeLookup = array ( |
418 0 => array(128, 138, 192), |
665 0 => array( 128, 138, 192), // 32 kbps |
419 1 => array(40, 160, 174, 240), |
666 1 => array( 160, 174, 240), // 40 kbps |
420 2 => array(48, 192, 208, 288), |
667 2 => array( 192, 208, 288), // 48 kbps |
421 3 => array(56, 224, 242, 336), |
668 3 => array( 224, 242, 336), // 56 kbps |
422 4 => array(64, 256, 278, 384), |
669 4 => array( 256, 278, 384), // 64 kbps |
423 5 => array(80, 320, 348, 480), |
670 5 => array( 320, 348, 480), // 80 kbps |
424 6 => array(96, 384, 416, 576), |
671 6 => array( 384, 416, 576), // 96 kbps |
425 7 => array(112, 448, 486, 672), |
672 7 => array( 448, 486, 672), // 112 kbps |
426 8 => array(128, 512, 556, 768), |
673 8 => array( 512, 556, 768), // 128 kbps |
427 9 => array(160, 640, 696, 960), |
674 9 => array( 640, 696, 960), // 160 kbps |
428 10 => array(192, 768, 834, 1152), |
675 10 => array( 768, 834, 1152), // 192 kbps |
429 11 => array(224, 896, 974, 1344), |
676 11 => array( 896, 974, 1344), // 224 kbps |
430 12 => array(256, 1024, 1114, 1536), |
677 12 => array(1024, 1114, 1536), // 256 kbps |
431 13 => array(320, 1280, 1392, 1920), |
678 13 => array(1280, 1392, 1920), // 320 kbps |
432 14 => array(384, 1536, 1670, 2304), |
679 14 => array(1536, 1670, 2304), // 384 kbps |
433 15 => array(448, 1792, 1950, 2688), |
680 15 => array(1792, 1950, 2688), // 448 kbps |
434 16 => array(512, 2048, 2228, 3072), |
681 16 => array(2048, 2228, 3072), // 512 kbps |
435 17 => array(576, 2304, 2506, 3456), |
682 17 => array(2304, 2506, 3456), // 576 kbps |
436 18 => array(640, 2560, 2786, 3840) |
683 18 => array(2560, 2786, 3840) // 640 kbps |
437 ); |
684 ); |
438 } |
685 } |
439 if (($fscod == 1) && $padding) { |
686 if (($fscod == 1) && $padding) { |
440 // frame lengths are padded by 1 word (16 bits) at 44100 |
687 // frame lengths are padded by 1 word (16 bits) at 44100 |
441 $frameSizeLookup[$frmsizecod] += 2; |
688 $frameSizeLookup[$frmsizecod] += 2; |
442 } |
689 } |
443 return (isset($frameSizeLookup[$framesizeid][$fscod]) ? $frameSizeLookup[$framesizeid][$fscod] : false); |
690 return (isset($frameSizeLookup[$framesizeid][$fscod]) ? $frameSizeLookup[$framesizeid][$fscod] : false); |
444 } |
691 } |
445 |
692 |
446 public static function bitrateLookup($frmsizecod) { |
693 public static function bitrateLookup($frmsizecod) { |
447 $framesizeid = floor($frmsizecod / 2); |
694 // LSB is whether padding is used or not |
|
695 $padding = (bool) ($frmsizecod & 0x01); |
|
696 $framesizeid = ($frmsizecod & 0x3E) >> 1; |
448 |
697 |
449 static $bitrateLookup = array( |
698 static $bitrateLookup = array( |
450 0 => 32000, |
699 0 => 32000, |
451 1 => 40000, |
700 1 => 40000, |
452 2 => 48000, |
701 2 => 48000, |
453 3 => 56000, |
702 3 => 56000, |
454 4 => 64000, |
703 4 => 64000, |
455 5 => 80000, |
704 5 => 80000, |
456 6 => 96000, |
705 6 => 96000, |
457 7 => 112000, |
706 7 => 112000, |
458 8 => 128000, |
707 8 => 128000, |
459 9 => 160000, |
708 9 => 160000, |
460 10 => 192000, |
709 10 => 192000, |
461 11 => 224000, |
710 11 => 224000, |
462 12 => 256000, |
711 12 => 256000, |
463 13 => 320000, |
712 13 => 320000, |
464 14 => 384000, |
713 14 => 384000, |
465 15 => 448000, |
714 15 => 448000, |
466 16 => 512000, |
715 16 => 512000, |
467 17 => 576000, |
716 17 => 576000, |
468 18 => 640000 |
717 18 => 640000, |
469 ); |
718 ); |
470 return (isset($bitrateLookup[$framesizeid]) ? $bitrateLookup[$framesizeid] : false); |
719 return (isset($bitrateLookup[$framesizeid]) ? $bitrateLookup[$framesizeid] : false); |
471 } |
720 } |
472 |
721 |
|
722 public static function blocksPerSyncFrame($numblkscod) { |
|
723 static $blocksPerSyncFrameLookup = array( |
|
724 0 => 1, |
|
725 1 => 2, |
|
726 2 => 3, |
|
727 3 => 6, |
|
728 ); |
|
729 return (isset($blocksPerSyncFrameLookup[$numblkscod]) ? $blocksPerSyncFrameLookup[$numblkscod] : false); |
|
730 } |
|
731 |
473 |
732 |
474 } |
733 } |