changeset 16 | a86126ab1dd4 |
parent 7 | cf61fcea0001 |
15:3d4e9c994f10 | 16:a86126ab1dd4 |
---|---|
1 <?php |
1 <?php |
2 |
|
2 ///////////////////////////////////////////////////////////////// |
3 ///////////////////////////////////////////////////////////////// |
3 /// getID3() by James Heinrich <info@getid3.org> // |
4 /// getID3() by James Heinrich <info@getid3.org> // |
4 // available at http://getid3.sourceforge.net // |
5 // available at https://github.com/JamesHeinrich/getID3 // |
5 // or http://www.getid3.org // |
6 // or https://www.getid3.org // |
6 // also https://github.com/JamesHeinrich/getID3 // |
7 // or http://getid3.sourceforge.net // |
7 ///////////////////////////////////////////////////////////////// |
8 // see readme.txt for more details // |
8 // See readme.txt for more details // |
|
9 ///////////////////////////////////////////////////////////////// |
9 ///////////////////////////////////////////////////////////////// |
10 // // |
10 // // |
11 // module.audio.dts.php // |
11 // module.audio.dts.php // |
12 // module for analyzing DTS Audio files // |
12 // module for analyzing DTS Audio files // |
13 // dependencies: NONE // |
13 // dependencies: NONE // |
14 // // |
14 // // |
15 ///////////////////////////////////////////////////////////////// |
15 ///////////////////////////////////////////////////////////////// |
16 |
16 |
17 if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers |
|
18 exit; |
|
19 } |
|
17 |
20 |
18 /** |
21 /** |
19 * @tutorial http://wiki.multimedia.cx/index.php?title=DTS |
22 * @tutorial http://wiki.multimedia.cx/index.php?title=DTS |
20 */ |
23 */ |
21 class getid3_dts extends getid3_handler |
24 class getid3_dts extends getid3_handler |
22 { |
25 { |
23 /** |
26 /** |
24 * Default DTS syncword used in native .cpt or .dts formats |
27 * Default DTS syncword used in native .cpt or .dts formats. |
25 */ |
28 */ |
26 const syncword = "\x7F\xFE\x80\x01"; |
29 const syncword = "\x7F\xFE\x80\x01"; |
27 |
30 |
31 /** |
|
32 * @var int |
|
33 */ |
|
28 private $readBinDataOffset = 0; |
34 private $readBinDataOffset = 0; |
29 |
35 |
30 /** |
36 /** |
31 * Possible syncwords indicating bitstream encoding |
37 * Possible syncwords indicating bitstream encoding. |
32 */ |
38 */ |
33 public static $syncwords = array( |
39 public static $syncwords = array( |
34 0 => "\x7F\xFE\x80\x01", // raw big-endian |
40 0 => "\x7F\xFE\x80\x01", // raw big-endian |
35 1 => "\xFE\x7F\x01\x80", // raw little-endian |
41 1 => "\xFE\x7F\x01\x80", // raw little-endian |
36 2 => "\x1F\xFF\xE8\x00", // 14-bit big-endian |
42 2 => "\x1F\xFF\xE8\x00", // 14-bit big-endian |
37 3 => "\xFF\x1F\x00\xE8"); // 14-bit little-endian |
43 3 => "\xFF\x1F\x00\xE8"); // 14-bit little-endian |
38 |
44 |
45 /** |
|
46 * @return bool |
|
47 */ |
|
39 public function Analyze() { |
48 public function Analyze() { |
40 $info = &$this->getid3->info; |
49 $info = &$this->getid3->info; |
41 $info['fileformat'] = 'dts'; |
50 $info['fileformat'] = 'dts'; |
42 |
51 |
43 $this->fseek($info['avdataoffset']); |
52 $this->fseek($info['avdataoffset']); |
44 $DTSheader = $this->fread(20); // we only need 2 words magic + 6 words frame header, but these words may be normal 16-bit words OR 14-bit words with 2 highest bits set to zero, so 8 words can be either 8*16/8 = 16 bytes OR 8*16*(16/14)/8 = 18.3 bytes |
53 $DTSheader = $this->fread(20); // we only need 2 words magic + 6 words frame header, but these words may be normal 16-bit words OR 14-bit words with 2 highest bits set to zero, so 8 words can be either 8*16/8 = 16 bytes OR 8*16*(16/14)/8 = 18.3 bytes |
45 |
54 |
46 // check syncword |
55 // check syncword |
47 $sync = substr($DTSheader, 0, 4); |
56 $sync = substr($DTSheader, 0, 4); |
48 if (($encoding = array_search($sync, self::$syncwords)) !== false) { |
57 if (($encoding = array_search($sync, self::$syncwords)) !== false) { |
49 |
58 |
50 $info['dts']['raw']['magic'] = $sync; |
59 $info['dts']['raw']['magic'] = $sync; |
51 $this->readBinDataOffset = 32; |
60 $this->readBinDataOffset = 32; |
52 |
61 |
53 } elseif ($this->isDependencyFor('matroska')) { |
62 } elseif ($this->isDependencyFor('matroska')) { |
54 |
63 |
55 // Matroska contains DTS without syncword encoded as raw big-endian format |
64 // Matroska contains DTS without syncword encoded as raw big-endian format |
56 $encoding = 0; |
65 $encoding = 0; |
57 $this->readBinDataOffset = 0; |
66 $this->readBinDataOffset = 0; |
58 |
67 |
59 } else { |
68 } else { |
60 |
69 |
61 unset($info['fileformat']); |
70 unset($info['fileformat']); |
62 return $this->error('Expecting "'.implode('| ', array_map('getid3_lib::PrintHexBytes', self::$syncwords)).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($sync).'"'); |
71 return $this->error('Expecting "'.implode('| ', array_map('getid3_lib::PrintHexBytes', self::$syncwords)).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($sync).'"'); |
63 |
72 |
64 } |
73 } |
137 } |
146 } |
138 } |
147 } |
139 return true; |
148 return true; |
140 } |
149 } |
141 |
150 |
151 /** |
|
152 * @param string $bin |
|
153 * @param int $length |
|
154 * |
|
155 * @return int |
|
156 */ |
|
142 private function readBinData($bin, $length) { |
157 private function readBinData($bin, $length) { |
143 $data = substr($bin, $this->readBinDataOffset, $length); |
158 $data = substr($bin, $this->readBinDataOffset, $length); |
144 $this->readBinDataOffset += $length; |
159 $this->readBinDataOffset += $length; |
145 |
160 |
146 return bindec($data); |
161 return bindec($data); |
147 } |
162 } |
148 |
163 |
164 /** |
|
165 * @param int $index |
|
166 * |
|
167 * @return int|string|false |
|
168 */ |
|
149 public static function bitrateLookup($index) { |
169 public static function bitrateLookup($index) { |
150 static $lookup = array( |
170 static $lookup = array( |
151 0 => 32000, |
171 0 => 32000, |
152 1 => 56000, |
172 1 => 56000, |
153 2 => 64000, |
173 2 => 64000, |
182 31 => 'lossless', |
202 31 => 'lossless', |
183 ); |
203 ); |
184 return (isset($lookup[$index]) ? $lookup[$index] : false); |
204 return (isset($lookup[$index]) ? $lookup[$index] : false); |
185 } |
205 } |
186 |
206 |
207 /** |
|
208 * @param int $index |
|
209 * |
|
210 * @return int|string|false |
|
211 */ |
|
187 public static function sampleRateLookup($index) { |
212 public static function sampleRateLookup($index) { |
188 static $lookup = array( |
213 static $lookup = array( |
189 0 => 'invalid', |
214 0 => 'invalid', |
190 1 => 8000, |
215 1 => 8000, |
191 2 => 16000, |
216 2 => 16000, |
204 15 => 'invalid', |
229 15 => 'invalid', |
205 ); |
230 ); |
206 return (isset($lookup[$index]) ? $lookup[$index] : false); |
231 return (isset($lookup[$index]) ? $lookup[$index] : false); |
207 } |
232 } |
208 |
233 |
234 /** |
|
235 * @param int $index |
|
236 * |
|
237 * @return int|false |
|
238 */ |
|
209 public static function bitPerSampleLookup($index) { |
239 public static function bitPerSampleLookup($index) { |
210 static $lookup = array( |
240 static $lookup = array( |
211 0 => 16, |
241 0 => 16, |
212 1 => 20, |
242 1 => 20, |
213 2 => 24, |
243 2 => 24, |
214 3 => 24, |
244 3 => 24, |
215 ); |
245 ); |
216 return (isset($lookup[$index]) ? $lookup[$index] : false); |
246 return (isset($lookup[$index]) ? $lookup[$index] : false); |
217 } |
247 } |
218 |
248 |
249 /** |
|
250 * @param int $index |
|
251 * |
|
252 * @return int|false |
|
253 */ |
|
219 public static function numChannelsLookup($index) { |
254 public static function numChannelsLookup($index) { |
220 switch ($index) { |
255 switch ($index) { |
221 case 0: |
256 case 0: |
222 return 1; |
257 return 1; |
223 break; |
|
224 case 1: |
258 case 1: |
225 case 2: |
259 case 2: |
226 case 3: |
260 case 3: |
227 case 4: |
261 case 4: |
228 return 2; |
262 return 2; |
229 break; |
|
230 case 5: |
263 case 5: |
231 case 6: |
264 case 6: |
232 return 3; |
265 return 3; |
233 break; |
|
234 case 7: |
266 case 7: |
235 case 8: |
267 case 8: |
236 return 4; |
268 return 4; |
237 break; |
|
238 case 9: |
269 case 9: |
239 return 5; |
270 return 5; |
240 break; |
|
241 case 10: |
271 case 10: |
242 case 11: |
272 case 11: |
243 case 12: |
273 case 12: |
244 return 6; |
274 return 6; |
245 break; |
|
246 case 13: |
275 case 13: |
247 return 7; |
276 return 7; |
248 break; |
|
249 case 14: |
277 case 14: |
250 case 15: |
278 case 15: |
251 return 8; |
279 return 8; |
252 break; |
|
253 } |
280 } |
254 return false; |
281 return false; |
255 } |
282 } |
256 |
283 |
284 /** |
|
285 * @param int $index |
|
286 * |
|
287 * @return string |
|
288 */ |
|
257 public static function channelArrangementLookup($index) { |
289 public static function channelArrangementLookup($index) { |
258 static $lookup = array( |
290 static $lookup = array( |
259 0 => 'A', |
291 0 => 'A', |
260 1 => 'A + B (dual mono)', |
292 1 => 'A + B (dual mono)', |
261 2 => 'L + R (stereo)', |
293 2 => 'L + R (stereo)', |
274 15 => 'CL + C+ CR + L + R + SL + S + SR', |
306 15 => 'CL + C+ CR + L + R + SL + S + SR', |
275 ); |
307 ); |
276 return (isset($lookup[$index]) ? $lookup[$index] : 'user-defined'); |
308 return (isset($lookup[$index]) ? $lookup[$index] : 'user-defined'); |
277 } |
309 } |
278 |
310 |
311 /** |
|
312 * @param int $index |
|
313 * @param int $version |
|
314 * |
|
315 * @return int|false |
|
316 */ |
|
279 public static function dialogNormalization($index, $version) { |
317 public static function dialogNormalization($index, $version) { |
280 switch ($version) { |
318 switch ($version) { |
281 case 7: |
319 case 7: |
282 return 0 - $index; |
320 return 0 - $index; |
283 break; |
|
284 case 6: |
321 case 6: |
285 return 0 - 16 - $index; |
322 return 0 - 16 - $index; |
286 break; |
|
287 } |
323 } |
288 return false; |
324 return false; |
289 } |
325 } |
290 |
326 |
291 } |
327 } |