Mercurial > judyates
comparison e2gallerypro/e2upload/Backend/Assets/getid3/module.audio.voc.php @ 3:3f6b44aa6b35 judyates
[svn r4] added ability to buy stuff, from a Prints page, but it doesn't work well with the css, and it also has not been fitted into the perl make system.
author | rlm |
---|---|
date | Mon, 22 Feb 2010 08:02:39 -0500 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2:670229c4eb4b | 3:3f6b44aa6b35 |
---|---|
1 <?php | |
2 // +----------------------------------------------------------------------+ | |
3 // | PHP version 5 | | |
4 // +----------------------------------------------------------------------+ | |
5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen | | |
6 // +----------------------------------------------------------------------+ | |
7 // | This source file is subject to version 2 of the GPL license, | | |
8 // | that is bundled with this package in the file license.txt and is | | |
9 // | available through the world-wide-web at the following url: | | |
10 // | http://www.gnu.org/copyleft/gpl.html | | |
11 // +----------------------------------------------------------------------+ | |
12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org | | |
13 // +----------------------------------------------------------------------+ | |
14 // | Authors: James Heinrich <infoØgetid3*org> | | |
15 // | Allan Hansen <ahØartemis*dk> | | |
16 // +----------------------------------------------------------------------+ | |
17 // | module.audio.voc.php | | |
18 // | Module for analyzing Creative VOC Audio files. | | |
19 // | dependencies: NONE | | |
20 // +----------------------------------------------------------------------+ | |
21 // | |
22 // $Id: module.audio.voc.php,v 1.3 2006/11/02 10:48:02 ah Exp $ | |
23 | |
24 | |
25 | |
26 class getid3_voc extends getid3_handler | |
27 { | |
28 | |
29 public function Analyze() { | |
30 | |
31 $getid3 = $this->getid3; | |
32 | |
33 $original_av_data_offset = $getid3->info['avdataoffset']; | |
34 | |
35 fseek($getid3->fp, $getid3->info['avdataoffset'], SEEK_SET); | |
36 $voc_header= fread($getid3->fp, 26); | |
37 | |
38 // Magic bytes: 'Creative Voice File' | |
39 | |
40 $info_audio = &$getid3->info['audio']; | |
41 $getid3->info['voc'] = array (); | |
42 $info_voc = &$getid3->info['voc']; | |
43 | |
44 $getid3->info['fileformat'] = 'voc'; | |
45 $info_audio['dataformat'] = 'voc'; | |
46 $info_audio['bitrate_mode'] = 'cbr'; | |
47 $info_audio['lossless'] = true; | |
48 $info_audio['channels'] = 1; // might be overriden below | |
49 $info_audio['bits_per_sample'] = 8; // might be overriden below | |
50 | |
51 // byte # Description | |
52 // ------ ------------------------------------------ | |
53 // 00-12 'Creative Voice File' | |
54 // 13 1A (eof to abort printing of file) | |
55 // 14-15 Offset of first datablock in .voc file (std 1A 00 in Intel Notation) | |
56 // 16-17 Version number (minor,major) (VOC-HDR puts 0A 01) | |
57 // 18-19 2's Comp of Ver. # + 1234h (VOC-HDR puts 29 11) | |
58 | |
59 getid3_lib::ReadSequence('LittleEndian2Int', $info_voc['header'], $voc_header, 20, | |
60 array ( | |
61 'datablock_offset' => 2, | |
62 'minor_version' => 1, | |
63 'major_version' => 1 | |
64 ) | |
65 ); | |
66 | |
67 do { | |
68 $block_offset = ftell($getid3->fp); | |
69 $block_data = fread($getid3->fp, 4); | |
70 $block_type = ord($block_data{0}); | |
71 $block_size = getid3_lib::LittleEndian2Int(substr($block_data, 1, 3)); | |
72 $this_block = array (); | |
73 | |
74 @$info_voc['blocktypes'][$block_type]++; | |
75 | |
76 switch ($block_type) { | |
77 | |
78 case 0: // Terminator | |
79 // do nothing, we'll break out of the loop down below | |
80 break; | |
81 | |
82 case 1: // Sound data | |
83 $block_data .= fread($getid3->fp, 2); | |
84 if ($getid3->info['avdataoffset'] <= $original_av_data_offset) { | |
85 $getid3->info['avdataoffset'] = ftell($getid3->fp); | |
86 } | |
87 fseek($getid3->fp, $block_size - 2, SEEK_CUR); | |
88 | |
89 getid3_lib::ReadSequence('LittleEndian2Int', $this_block, $block_data, 4, | |
90 array ( | |
91 'sample_rate_id' => 1, | |
92 'compression_type' => 1 | |
93 ) | |
94 ); | |
95 | |
96 $this_block['compression_name'] = getid3_voc::VOCcompressionTypeLookup($this_block['compression_type']); | |
97 if ($this_block['compression_type'] <= 3) { | |
98 $info_voc['compressed_bits_per_sample'] = (int)(str_replace('-bit', '', $this_block['compression_name'])); | |
99 } | |
100 | |
101 // Less accurate sample_rate calculation than the Extended block (#8) data (but better than nothing if Extended Block is not available) | |
102 if (empty($info_audio['sample_rate'])) { | |
103 // SR byte = 256 - (1000000 / sample_rate) | |
104 $info_audio['sample_rate'] = (int)floor((1000000 / (256 - $this_block['sample_rate_id'])) / $info_audio['channels']); | |
105 } | |
106 break; | |
107 | |
108 case 2: // Sound continue | |
109 case 3: // Silence | |
110 case 4: // Marker | |
111 case 6: // Repeat | |
112 case 7: // End repeat | |
113 // nothing useful, just skip | |
114 fseek($getid3->fp, $block_size, SEEK_CUR); | |
115 break; | |
116 | |
117 case 8: // Extended | |
118 $block_data .= fread($getid3->fp, 4); | |
119 | |
120 //00-01 Time Constant: | |
121 // Mono: 65536 - (256000000 / sample_rate) | |
122 // Stereo: 65536 - (256000000 / (sample_rate * 2)) | |
123 getid3_lib::ReadSequence('LittleEndian2Int', $this_block, $block_data, 4, | |
124 array ( | |
125 'time_constant' => 2, | |
126 'pack_method' => 1, | |
127 'stereo' => 1 | |
128 ) | |
129 ); | |
130 $this_block['stereo'] = (bool)$this_block['stereo']; | |
131 | |
132 $info_audio['channels'] = ($this_block['stereo'] ? 2 : 1); | |
133 $info_audio['sample_rate'] = (int)floor((256000000 / (65536 - $this_block['time_constant'])) / $info_audio['channels']); | |
134 break; | |
135 | |
136 case 9: // data block that supersedes blocks 1 and 8. Used for stereo, 16 bit | |
137 $block_data .= fread($getid3->fp, 12); | |
138 if ($getid3->info['avdataoffset'] <= $original_av_data_offset) { | |
139 $getid3->info['avdataoffset'] = ftell($getid3->fp); | |
140 } | |
141 fseek($getid3->fp, $block_size - 12, SEEK_CUR); | |
142 | |
143 getid3_lib::ReadSequence('LittleEndian2Int', $this_block, $block_data, 4, | |
144 array ( | |
145 'sample_rate' => 4, | |
146 'bits_per_sample' => 1, | |
147 'channels' => 1, | |
148 'wFormat' => 2 | |
149 ) | |
150 ); | |
151 | |
152 $this_block['compression_name'] = getid3_voc::VOCwFormatLookup($this_block['wFormat']); | |
153 if (getid3_voc::VOCwFormatActualBitsPerSampleLookup($this_block['wFormat'])) { | |
154 $info_voc['compressed_bits_per_sample'] = getid3_voc::VOCwFormatActualBitsPerSampleLookup($this_block['wFormat']); | |
155 } | |
156 | |
157 $info_audio['sample_rate'] = $this_block['sample_rate']; | |
158 $info_audio['bits_per_sample'] = $this_block['bits_per_sample']; | |
159 $info_audio['channels'] = $this_block['channels']; | |
160 break; | |
161 | |
162 default: | |
163 $getid3->warning('Unhandled block type "'.$block_type.'" at offset '.$block_offset); | |
164 fseek($getid3->fp, $block_size, SEEK_CUR); | |
165 break; | |
166 } | |
167 | |
168 if (!empty($this_block)) { | |
169 $this_block['block_offset'] = $block_offset; | |
170 $this_block['block_size'] = $block_size; | |
171 $this_block['block_type_id'] = $block_type; | |
172 $info_voc['blocks'][] = $this_block; | |
173 } | |
174 | |
175 } while (!feof($getid3->fp) && ($block_type != 0)); | |
176 | |
177 // Terminator block doesn't have size field, so seek back 3 spaces | |
178 fseek($getid3->fp, -3, SEEK_CUR); | |
179 | |
180 ksort($info_voc['blocktypes']); | |
181 | |
182 if (!empty($info_voc['compressed_bits_per_sample'])) { | |
183 $getid3->info['playtime_seconds'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / ($info_voc['compressed_bits_per_sample'] * $info_audio['channels'] * $info_audio['sample_rate']); | |
184 $info_audio['bitrate'] = (($getid3->info['avdataend'] - $getid3->info['avdataoffset']) * 8) / $getid3->info['playtime_seconds']; | |
185 } | |
186 | |
187 return true; | |
188 } | |
189 | |
190 | |
191 | |
192 public static function VOCcompressionTypeLookup($index) { | |
193 | |
194 static $lookup = array ( | |
195 0 => '8-bit', | |
196 1 => '4-bit', | |
197 2 => '2.6-bit', | |
198 3 => '2-bit' | |
199 ); | |
200 return (isset($lookup[$index]) ? $lookup[$index] : 'Multi DAC ('.($index - 3).') channels'); | |
201 } | |
202 | |
203 | |
204 | |
205 public static function VOCwFormatLookup($index) { | |
206 | |
207 static $lookup = array ( | |
208 0x0000 => '8-bit unsigned PCM', | |
209 0x0001 => 'Creative 8-bit to 4-bit ADPCM', | |
210 0x0002 => 'Creative 8-bit to 3-bit ADPCM', | |
211 0x0003 => 'Creative 8-bit to 2-bit ADPCM', | |
212 0x0004 => '16-bit signed PCM', | |
213 0x0006 => 'CCITT a-Law', | |
214 0x0007 => 'CCITT u-Law', | |
215 0x2000 => 'Creative 16-bit to 4-bit ADPCM' | |
216 ); | |
217 return (isset($lookup[$index]) ? $lookup[$index] : false); | |
218 } | |
219 | |
220 | |
221 | |
222 public static function VOCwFormatActualBitsPerSampleLookup($index) { | |
223 | |
224 static $lookup = array ( | |
225 0x0000 => 8, | |
226 0x0001 => 4, | |
227 0x0002 => 3, | |
228 0x0003 => 2, | |
229 0x0004 => 16, | |
230 0x0006 => 8, | |
231 0x0007 => 8, | |
232 0x2000 => 4 | |
233 ); | |
234 return (isset($lookup[$index]) ? $lookup[$index] : false); | |
235 } | |
236 | |
237 } | |
238 | |
239 | |
240 ?> |