ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
module.audio-video.riff.php
Go to the documentation of this file.
1<?php
4// available at http://getid3.sourceforge.net //
5// or http://www.getid3.org //
7// See readme.txt for more details //
9// //
10// module.audio-video.riff.php //
11// module for analyzing RIFF files //
12// multiple formats supported by this module: //
13// Wave, AVI, AIFF/AIFC, (MP3,AC3)/RIFF, Wavpack v3, 8SVX //
14// dependencies: module.audio.mp3.php //
15// module.audio.ac3.php (optional) //
16// ///
18
19getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
20
22{
23
24 function getid3_riff(&$fd, &$ThisFileInfo) {
25
26 // initialize these values to an empty array, otherwise they default to NULL
27 // and you can't append array values to a NULL value
28 $ThisFileInfo['riff'] = array('raw'=>array());
29
30 // Shortcuts
31 $thisfile_riff = &$ThisFileInfo['riff'];
32 $thisfile_riff_raw = &$thisfile_riff['raw'];
33 $thisfile_audio = &$ThisFileInfo['audio'];
34 $thisfile_video = &$ThisFileInfo['video'];
35 $thisfile_avdataoffset = &$ThisFileInfo['avdataoffset'];
36 $thisfile_avdataend = &$ThisFileInfo['avdataend'];
37 $thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
38 $thisfile_riff_audio = &$thisfile_riff['audio'];
39 $thisfile_riff_video = &$thisfile_riff['video'];
40
41
42 $Original['avdataoffset'] = $thisfile_avdataoffset;
43 $Original['avdataend'] = $thisfile_avdataend;
44
45 fseek($fd, $thisfile_avdataoffset, SEEK_SET);
46 $RIFFheader = fread($fd, 12);
47 $RIFFsubtype = substr($RIFFheader, 8, 4);
48 switch (substr($RIFFheader, 0, 4)) {
49 case 'FORM':
50 $ThisFileInfo['fileformat'] = 'aiff';
51 $RIFFheaderSize = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($RIFFheader, 4, 4));
52 $thisfile_riff[$RIFFsubtype] = getid3_riff::ParseRIFF($fd, $thisfile_avdataoffset + 12, $thisfile_avdataoffset + $RIFFheaderSize, $ThisFileInfo);
53 $thisfile_riff['header_size'] = $RIFFheaderSize;
54 break;
55
56 case 'RIFF':
57 case 'SDSS': // SDSS is identical to RIFF, just renamed. Used by SmartSound QuickTracks (www.smartsound.com)
58 case 'RMP3': // RMP3 is identical to RIFF, just renamed. Used by [unknown program] when creating RIFF-MP3s
59 if ($RIFFsubtype == 'RMP3') {
60 // RMP3 is identical to WAVE, just renamed. Used by [unknown program] when creating RIFF-MP3s
61 $RIFFsubtype = 'WAVE';
62 }
63
64 $ThisFileInfo['fileformat'] = 'riff';
65 $RIFFheaderSize = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($RIFFheader, 4, 4));
66 $thisfile_riff[$RIFFsubtype] = getid3_riff::ParseRIFF($fd, $thisfile_avdataoffset + 12, $thisfile_avdataoffset + $RIFFheaderSize, $ThisFileInfo);
67 $thisfile_riff['header_size'] = $RIFFheaderSize;
68 if ($RIFFsubtype == 'WAVE') {
69 $thisfile_riff_WAVE = &$thisfile_riff['WAVE'];
70 }
71 break;
72
73 default:
74 $ThisFileInfo['error'][] = 'Cannot parse RIFF (this is maybe not a RIFF / WAV / AVI file?) - expecting "FORM|RIFF|SDSS|RMP3" found "'.$RIFFsubtype.'" instead';
75 unset($ThisFileInfo['fileformat']);
76 return false;
77 break;
78 }
79
80 $streamindex = 0;
81 switch ($RIFFsubtype) {
82 case 'WAVE':
83 if (empty($thisfile_audio['bitrate_mode'])) {
84 $thisfile_audio['bitrate_mode'] = 'cbr';
85 }
86 if (empty($thisfile_audio_dataformat)) {
87 $thisfile_audio_dataformat = 'wav';
88 }
89
90 if (isset($thisfile_riff_WAVE['data'][0]['offset'])) {
91 $thisfile_avdataoffset = $thisfile_riff_WAVE['data'][0]['offset'] + 8;
92 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff_WAVE['data'][0]['size'];
93 }
94 if (isset($thisfile_riff_WAVE['fmt '][0]['data'])) {
95
96 $thisfile_riff_audio[$streamindex] = getid3_riff::RIFFparseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']);
97 $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
98 if (@$thisfile_riff_audio[$streamindex]['bitrate'] == 0) {
99 $ThisFileInfo['error'][] = 'Corrupt RIFF file: bitrate_audio == zero';
100 return false;
101 }
102 $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
103 unset($thisfile_riff_audio[$streamindex]['raw']);
104 $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
105
106 $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
107 if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
108 $ThisFileInfo['warning'][] = 'Audio codec = '.$thisfile_audio['codec'];
109 }
110 $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
111
112 $ThisFileInfo['playtime_seconds'] = (float) ((($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $thisfile_audio['bitrate']);
113
114 $thisfile_audio['lossless'] = false;
115 if (isset($thisfile_riff_WAVE['data'][0]['offset']) && isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
116 switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
117
118 case 0x0001: // PCM
119 $thisfile_audio['lossless'] = true;
120 break;
121
122 case 0x2000: // AC-3
123 $thisfile_audio_dataformat = 'ac3';
124 break;
125
126 default:
127 // do nothing
128 break;
129
130 }
131 }
132 $thisfile_audio['streams'][$streamindex]['wformattag'] = $thisfile_audio['wformattag'];
133 $thisfile_audio['streams'][$streamindex]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
134 $thisfile_audio['streams'][$streamindex]['lossless'] = $thisfile_audio['lossless'];
135 $thisfile_audio['streams'][$streamindex]['dataformat'] = $thisfile_audio_dataformat;
136 }
137
138 if (isset($thisfile_riff_WAVE['rgad'][0]['data'])) {
139
140 // shortcuts
141 $rgadData = &$thisfile_riff_WAVE['rgad'][0]['data'];
142 $thisfile_riff_raw['rgad'] = array('track'=>array(), 'album'=>array());
143 $thisfile_riff_raw_rgad = &$thisfile_riff_raw['rgad'];
144 $thisfile_riff_raw_rgad_track = &$thisfile_riff_raw_rgad['track'];
145 $thisfile_riff_raw_rgad_album = &$thisfile_riff_raw_rgad['album'];
146
147 $thisfile_riff_raw_rgad['fPeakAmplitude'] = getid3_lib::LittleEndian2Float(substr($rgadData, 0, 4));
148 $thisfile_riff_raw_rgad['nRadioRgAdjust'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($rgadData, 4, 2));
149 $thisfile_riff_raw_rgad['nAudiophileRgAdjust'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($rgadData, 6, 2));
150
151 $nRadioRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nRadioRgAdjust']), 16, '0', STR_PAD_LEFT);
152 $nAudiophileRgAdjustBitstring = str_pad(getid3_lib::Dec2Bin($thisfile_riff_raw_rgad['nAudiophileRgAdjust']), 16, '0', STR_PAD_LEFT);
153 $thisfile_riff_raw_rgad_track['name'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 0, 3));
154 $thisfile_riff_raw_rgad_track['originator'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 3, 3));
155 $thisfile_riff_raw_rgad_track['signbit'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 6, 1));
156 $thisfile_riff_raw_rgad_track['adjustment'] = getid3_lib::Bin2Dec(substr($nRadioRgAdjustBitstring, 7, 9));
157 $thisfile_riff_raw_rgad_album['name'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 0, 3));
158 $thisfile_riff_raw_rgad_album['originator'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 3, 3));
159 $thisfile_riff_raw_rgad_album['signbit'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 6, 1));
160 $thisfile_riff_raw_rgad_album['adjustment'] = getid3_lib::Bin2Dec(substr($nAudiophileRgAdjustBitstring, 7, 9));
161
162 $thisfile_riff['rgad']['peakamplitude'] = $thisfile_riff_raw_rgad['fPeakAmplitude'];
163 if (($thisfile_riff_raw_rgad_track['name'] != 0) && ($thisfile_riff_raw_rgad_track['originator'] != 0)) {
164 $thisfile_riff['rgad']['track']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_track['name']);
165 $thisfile_riff['rgad']['track']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_track['originator']);
166 $thisfile_riff['rgad']['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_track['adjustment'], $thisfile_riff_raw_rgad_track['signbit']);
167 }
168 if (($thisfile_riff_raw_rgad_album['name'] != 0) && ($thisfile_riff_raw_rgad_album['originator'] != 0)) {
169 $thisfile_riff['rgad']['album']['name'] = getid3_lib::RGADnameLookup($thisfile_riff_raw_rgad_album['name']);
170 $thisfile_riff['rgad']['album']['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_riff_raw_rgad_album['originator']);
171 $thisfile_riff['rgad']['album']['adjustment'] = getid3_lib::RGADadjustmentLookup($thisfile_riff_raw_rgad_album['adjustment'], $thisfile_riff_raw_rgad_album['signbit']);
172 }
173 }
174
175 if (isset($thisfile_riff_WAVE['fact'][0]['data'])) {
176 $thisfile_riff_raw['fact']['NumberOfSamples'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_WAVE['fact'][0]['data'], 0, 4));
177
178 // This should be a good way of calculating exact playtime,
179 // but some sample files have had incorrect number of samples,
180 // so cannot use this method
181
182 // if (!empty($thisfile_riff_raw['fmt ']['nSamplesPerSec'])) {
183 // $ThisFileInfo['playtime_seconds'] = (float) $thisfile_riff_raw['fact']['NumberOfSamples'] / $thisfile_riff_raw['fmt ']['nSamplesPerSec'];
184 // }
185 }
186 if (!empty($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'])) {
187 $thisfile_audio['bitrate'] = getid3_lib::CastAsInt($thisfile_riff_raw['fmt ']['nAvgBytesPerSec'] * 8);
188 }
189
190 if (isset($thisfile_riff_WAVE['bext'][0]['data'])) {
191 // shortcut
192 $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][0];
193
194 $thisfile_riff_WAVE_bext_0['title'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 0, 256));
195 $thisfile_riff_WAVE_bext_0['author'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 256, 32));
196 $thisfile_riff_WAVE_bext_0['reference'] = trim(substr($thisfile_riff_WAVE_bext_0['data'], 288, 32));
197 $thisfile_riff_WAVE_bext_0['origin_date'] = substr($thisfile_riff_WAVE_bext_0['data'], 320, 10);
198 $thisfile_riff_WAVE_bext_0['origin_time'] = substr($thisfile_riff_WAVE_bext_0['data'], 330, 8);
199 $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338, 8));
200 $thisfile_riff_WAVE_bext_0['bwf_version'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 346, 1));
201 $thisfile_riff_WAVE_bext_0['reserved'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 347, 254));
202 $thisfile_riff_WAVE_bext_0['coding_history'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
203
204 $thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime(
205 substr($thisfile_riff_WAVE_bext_0['origin_time'], 0, 2),
206 substr($thisfile_riff_WAVE_bext_0['origin_time'], 3, 2),
207 substr($thisfile_riff_WAVE_bext_0['origin_time'], 6, 2),
208 substr($thisfile_riff_WAVE_bext_0['origin_date'], 5, 2),
209 substr($thisfile_riff_WAVE_bext_0['origin_date'], 8, 2),
210 substr($thisfile_riff_WAVE_bext_0['origin_date'], 0, 4));
211
212 $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
213 $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_bext_0['title'];
214 }
215
216 if (isset($thisfile_riff_WAVE['MEXT'][0]['data'])) {
217 // shortcut
218 $thisfile_riff_WAVE_MEXT_0 = &$thisfile_riff_WAVE['MEXT'][0];
219
220 $thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 0, 2));
221 $thisfile_riff_WAVE_MEXT_0['flags']['homogenous'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0001);
222 if ($thisfile_riff_WAVE_MEXT_0['flags']['homogenous']) {
223 $thisfile_riff_WAVE_MEXT_0['flags']['padding'] = ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0002) ? false : true;
224 $thisfile_riff_WAVE_MEXT_0['flags']['22_or_44'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0004);
225 $thisfile_riff_WAVE_MEXT_0['flags']['free_format'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['sound_information'] & 0x0008);
226
227 $thisfile_riff_WAVE_MEXT_0['nominal_frame_size'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 2, 2));
228 }
229 $thisfile_riff_WAVE_MEXT_0['anciliary_data_length'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 6, 2));
230 $thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_MEXT_0['data'], 8, 2));
231 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_left'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0001);
232 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_free'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0002);
233 $thisfile_riff_WAVE_MEXT_0['flags']['anciliary_data_right'] = (bool) ($thisfile_riff_WAVE_MEXT_0['raw']['anciliary_data_def'] & 0x0004);
234 }
235
236 if (isset($thisfile_riff_WAVE['cart'][0]['data'])) {
237 // shortcut
238 $thisfile_riff_WAVE_cart_0 = &$thisfile_riff_WAVE['cart'][0];
239
240 $thisfile_riff_WAVE_cart_0['version'] = substr($thisfile_riff_WAVE_cart_0['data'], 0, 4);
241 $thisfile_riff_WAVE_cart_0['title'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 4, 64));
242 $thisfile_riff_WAVE_cart_0['artist'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 68, 64));
243 $thisfile_riff_WAVE_cart_0['cut_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 132, 64));
244 $thisfile_riff_WAVE_cart_0['client_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 196, 64));
245 $thisfile_riff_WAVE_cart_0['category'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 260, 64));
246 $thisfile_riff_WAVE_cart_0['classification'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 324, 64));
247 $thisfile_riff_WAVE_cart_0['out_cue'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 388, 64));
248 $thisfile_riff_WAVE_cart_0['start_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 452, 10));
249 $thisfile_riff_WAVE_cart_0['start_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 462, 8));
250 $thisfile_riff_WAVE_cart_0['end_date'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 470, 10));
251 $thisfile_riff_WAVE_cart_0['end_time'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 480, 8));
252 $thisfile_riff_WAVE_cart_0['producer_app_id'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 488, 64));
253 $thisfile_riff_WAVE_cart_0['producer_app_version'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 552, 64));
254 $thisfile_riff_WAVE_cart_0['user_defined_text'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 616, 64));
255 $thisfile_riff_WAVE_cart_0['zero_db_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 680, 4), true);
256 for ($i = 0; $i < 8; $i++) {
257 $thisfile_riff_WAVE_cart_0['post_time'][$i]['usage_fourcc'] = substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8), 4);
258 $thisfile_riff_WAVE_cart_0['post_time'][$i]['timer_value'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_cart_0['data'], 684 + ($i * 8) + 4, 4));
259 }
260 $thisfile_riff_WAVE_cart_0['url'] = trim(substr($thisfile_riff_WAVE_cart_0['data'], 748, 1024));
261 $thisfile_riff_WAVE_cart_0['tag_text'] = explode("\r\n", trim(substr($thisfile_riff_WAVE_cart_0['data'], 1772)));
262
263 $thisfile_riff['comments']['artist'][] = $thisfile_riff_WAVE_cart_0['artist'];
264 $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_cart_0['title'];
265 }
266
267 if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
268 $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
269 $ThisFileInfo['playtime_seconds'] = (float) ((($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $thisfile_audio['bitrate']);
270 }
271
272 if (!empty($ThisFileInfo['wavpack'])) {
273 $thisfile_audio_dataformat = 'wavpack';
274 $thisfile_audio['bitrate_mode'] = 'vbr';
275 $thisfile_audio['encoder'] = 'WavPack v'.$ThisFileInfo['wavpack']['version'];
276
277 // Reset to the way it was - RIFF parsing will have messed this up
278 $thisfile_avdataend = $Original['avdataend'];
279 $thisfile_audio['bitrate'] = (($thisfile_avdataend - $thisfile_avdataoffset) * 8) / $ThisFileInfo['playtime_seconds'];
280
281 fseek($fd, $thisfile_avdataoffset - 44, SEEK_SET);
282 $RIFFdata = fread($fd, 44);
283 $OrignalRIFFheaderSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 4, 4)) + 8;
284 $OrignalRIFFdataSize = getid3_lib::LittleEndian2Int(substr($RIFFdata, 40, 4)) + 44;
285
286 if ($OrignalRIFFheaderSize > $OrignalRIFFdataSize) {
287 $thisfile_avdataend -= ($OrignalRIFFheaderSize - $OrignalRIFFdataSize);
288 fseek($fd, $thisfile_avdataend, SEEK_SET);
289 $RIFFdata .= fread($fd, $OrignalRIFFheaderSize - $OrignalRIFFdataSize);
290 }
291
292 // move the data chunk after all other chunks (if any)
293 // so that the RIFF parser doesn't see EOF when trying
294 // to skip over the data chunk
295 $RIFFdata = substr($RIFFdata, 0, 36).substr($RIFFdata, 44).substr($RIFFdata, 36, 8);
296 getid3_riff::ParseRIFFdata($RIFFdata, $ThisFileInfo);
297 }
298
299 if (isset($thisfile_riff_raw['fmt ']['wFormatTag'])) {
300 switch ($thisfile_riff_raw['fmt ']['wFormatTag']) {
301 case 0x08AE: // ClearJump LiteWave
302 $thisfile_audio['bitrate_mode'] = 'vbr';
303 $thisfile_audio_dataformat = 'litewave';
304
305 //typedef struct tagSLwFormat {
306 // WORD m_wCompFormat; // low byte defines compression method, high byte is compression flags
307 // DWORD m_dwScale; // scale factor for lossy compression
308 // DWORD m_dwBlockSize; // number of samples in encoded blocks
309 // WORD m_wQuality; // alias for the scale factor
310 // WORD m_wMarkDistance; // distance between marks in bytes
311 // WORD m_wReserved;
312 //
313 // //following paramters are ignored if CF_FILESRC is not set
314 // DWORD m_dwOrgSize; // original file size in bytes
315 // WORD m_bFactExists; // indicates if 'fact' chunk exists in the original file
316 // DWORD m_dwRiffChunkSize; // riff chunk size in the original file
317 //
318 // PCMWAVEFORMAT m_OrgWf; // original wave format
319 // }SLwFormat, *PSLwFormat;
320
321 // shortcut
322 $thisfile_riff['litewave']['raw'] = array();
323 $thisfile_riff_litewave = &$thisfile_riff['litewave'];
324 $thisfile_riff_litewave_raw = &$thisfile_riff_litewave['raw'];
325
326 $thisfile_riff_litewave_raw['compression_method'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 18, 1));
327 $thisfile_riff_litewave_raw['compression_flags'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 19, 1));
328 $thisfile_riff_litewave_raw['m_dwScale'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 20, 4));
329 $thisfile_riff_litewave_raw['m_dwBlockSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 24, 4));
330 $thisfile_riff_litewave_raw['m_wQuality'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 28, 2));
331 $thisfile_riff_litewave_raw['m_wMarkDistance'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 30, 2));
332 $thisfile_riff_litewave_raw['m_wReserved'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 32, 2));
333 $thisfile_riff_litewave_raw['m_dwOrgSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 34, 4));
334 $thisfile_riff_litewave_raw['m_bFactExists'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 38, 2));
335 $thisfile_riff_litewave_raw['m_dwRiffChunkSize'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE['fmt '][0]['data'], 40, 4));
336
337 //$thisfile_riff_litewave['quality_factor'] = intval(round((2000 - $thisfile_riff_litewave_raw['m_dwScale']) / 20));
338 $thisfile_riff_litewave['quality_factor'] = $thisfile_riff_litewave_raw['m_wQuality'];
339
340 $thisfile_riff_litewave['flags']['raw_source'] = ($thisfile_riff_litewave_raw['compression_flags'] & 0x01) ? false : true;
341 $thisfile_riff_litewave['flags']['vbr_blocksize'] = ($thisfile_riff_litewave_raw['compression_flags'] & 0x02) ? false : true;
342 $thisfile_riff_litewave['flags']['seekpoints'] = (bool) ($thisfile_riff_litewave_raw['compression_flags'] & 0x04);
343
344 $thisfile_audio['lossless'] = (($thisfile_riff_litewave_raw['m_wQuality'] == 100) ? true : false);
345 $thisfile_audio['encoder_options'] = '-q'.$thisfile_riff_litewave['quality_factor'];
346 break;
347
348 default:
349 break;
350 }
351 }
352 if ($thisfile_avdataend > $ThisFileInfo['filesize']) {
353 switch (@$thisfile_audio_dataformat) {
354 case 'wavpack': // WavPack
355 case 'lpac': // LPAC
356 case 'ofr': // OptimFROG
357 case 'ofs': // OptimFROG DualStream
358 // lossless compressed audio formats that keep original RIFF headers - skip warning
359 break;
360
361 case 'litewave':
362 if (($thisfile_avdataend - $ThisFileInfo['filesize']) == 1) {
363 // LiteWave appears to incorrectly *not* pad actual output file
364 // to nearest WORD boundary so may appear to be short by one
365 // byte, in which case - skip warning
366 } else {
367 // Short by more than one byte, throw warning
368 $ThisFileInfo['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($ThisFileInfo['filesize'] - $thisfile_avdataoffset).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($ThisFileInfo['filesize'] - $thisfile_avdataoffset)).' bytes)';
369 $thisfile_avdataend = $ThisFileInfo['filesize'];
370 }
371 break;
372
373 default:
374 if ((($thisfile_avdataend - $ThisFileInfo['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($ThisFileInfo['filesize'] - $thisfile_avdataoffset) % 2) == 1)) {
375 // output file appears to be incorrectly *not* padded to nearest WORD boundary
376 // Output less severe warning
377 $ThisFileInfo['warning'][] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($ThisFileInfo['filesize'] - $thisfile_avdataoffset).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($ThisFileInfo['filesize'] - $thisfile_avdataoffset)).' bytes)';
378 $thisfile_avdataend = $ThisFileInfo['filesize'];
379 break;
380 }
381 // Short by more than one byte, throw warning
382 $ThisFileInfo['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($ThisFileInfo['filesize'] - $thisfile_avdataoffset).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($ThisFileInfo['filesize'] - $thisfile_avdataoffset)).' bytes)';
383 $thisfile_avdataend = $ThisFileInfo['filesize'];
384 break;
385 }
386 }
387 if (!empty($ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes'])) {
388 if ((($thisfile_avdataend - $thisfile_avdataoffset) - $ThisFileInfo['mpeg']['audio']['LAME']['audio_bytes']) == 1) {
389 $thisfile_avdataend--;
390 $ThisFileInfo['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
391 }
392 }
393 if (@$thisfile_audio_dataformat == 'ac3') {
394 unset($thisfile_audio['bits_per_sample']);
395 if (!empty($ThisFileInfo['ac3']['bitrate']) && ($ThisFileInfo['ac3']['bitrate'] != $thisfile_audio['bitrate'])) {
396 $thisfile_audio['bitrate'] = $ThisFileInfo['ac3']['bitrate'];
397 }
398 }
399 break;
400
401 case 'AVI ':
402 $thisfile_video['bitrate_mode'] = 'vbr'; // maybe not, but probably
403 $thisfile_video['dataformat'] = 'avi';
404 $ThisFileInfo['mime_type'] = 'video/avi';
405
406 if (isset($thisfile_riff[$RIFFsubtype]['movi']['offset'])) {
407 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype]['movi']['offset'] + 8;
408 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype]['movi']['size'];
409 if ($thisfile_avdataend > $ThisFileInfo['filesize']) {
410 $ThisFileInfo['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['movi']['size'].' bytes of data, only found '.($ThisFileInfo['filesize'] - $thisfile_avdataoffset).' (short by '.($thisfile_riff[$RIFFsubtype]['movi']['size'] - ($ThisFileInfo['filesize'] - $thisfile_avdataoffset)).' bytes)';
411 $thisfile_avdataend = $ThisFileInfo['filesize'];
412 }
413 }
414
415 if (isset($thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'])) {
416 $avihData = $thisfile_riff['AVI ']['hdrl']['avih'][$streamindex]['data'];
417
418 // shortcut
419 $thisfile_riff_raw['avih'] = array();
420 $thisfile_riff_raw_avih = &$thisfile_riff_raw['avih'];
421
422 $thisfile_riff_raw_avih['dwMicroSecPerFrame'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 0, 4)); // frame display rate (or 0L)
423 if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) {
424 $ThisFileInfo['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
425 return false;
426 }
427 $thisfile_riff_raw_avih['dwMaxBytesPerSec'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 4, 4)); // max. transfer rate
428 $thisfile_riff_raw_avih['dwPaddingGranularity'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 8, 4)); // pad to multiples of this size; normally 2K.
429 $thisfile_riff_raw_avih['dwFlags'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 12, 4)); // the ever-present flags
430 $thisfile_riff_raw_avih['dwTotalFrames'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 16, 4)); // # frames in file
431 $thisfile_riff_raw_avih['dwInitialFrames'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 20, 4));
432 $thisfile_riff_raw_avih['dwStreams'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 24, 4));
433 $thisfile_riff_raw_avih['dwSuggestedBufferSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 28, 4));
434 $thisfile_riff_raw_avih['dwWidth'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 32, 4));
435 $thisfile_riff_raw_avih['dwHeight'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 36, 4));
436 $thisfile_riff_raw_avih['dwScale'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 40, 4));
437 $thisfile_riff_raw_avih['dwRate'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 44, 4));
438 $thisfile_riff_raw_avih['dwStart'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 48, 4));
439 $thisfile_riff_raw_avih['dwLength'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($avihData, 52, 4));
440
441 $thisfile_riff_raw_avih['flags']['hasindex'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000010);
442 $thisfile_riff_raw_avih['flags']['mustuseindex'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000020);
443 $thisfile_riff_raw_avih['flags']['interleaved'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000100);
444 $thisfile_riff_raw_avih['flags']['trustcktype'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00000800);
445 $thisfile_riff_raw_avih['flags']['capturedfile'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00010000);
446 $thisfile_riff_raw_avih['flags']['copyrighted'] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & 0x00020010);
447
448 // shortcut
449 $thisfile_riff_video[$streamindex] = array();
450 $thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
451
452 if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
453 $thisfile_riff_video_current['frame_width'] = $thisfile_riff_raw_avih['dwWidth'];
454 $thisfile_video['resolution_x'] = $thisfile_riff_video_current['frame_width'];
455 }
456 if ($thisfile_riff_raw_avih['dwHeight'] > 0) {
457 $thisfile_riff_video_current['frame_height'] = $thisfile_riff_raw_avih['dwHeight'];
458 $thisfile_video['resolution_y'] = $thisfile_riff_video_current['frame_height'];
459 }
460 if ($thisfile_riff_raw_avih['dwTotalFrames'] > 0) {
461 $thisfile_riff_video_current['total_frames'] = $thisfile_riff_raw_avih['dwTotalFrames'];
462 $thisfile_video['total_frames'] = $thisfile_riff_video_current['total_frames'];
463 }
464
465 $thisfile_riff_video_current['frame_rate'] = round(1000000 / $thisfile_riff_raw_avih['dwMicroSecPerFrame'], 3);
466 $thisfile_video['frame_rate'] = $thisfile_riff_video_current['frame_rate'];
467 }
468 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
469 if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
470 for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
471 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
472 $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
473 $strhfccType = substr($strhData, 0, 4);
474
475 if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'])) {
476 $strfData = $thisfile_riff['AVI ']['hdrl']['strl']['strf'][$i]['data'];
477
478 // shortcut
479 $thisfile_riff_raw_strf_strhfccType_streamindex = &$thisfile_riff_raw['strf'][$strhfccType][$streamindex];
480
481 switch ($strhfccType) {
482 case 'auds':
483 $thisfile_audio['bitrate_mode'] = 'cbr';
484 $thisfile_audio_dataformat = 'wav';
485 if (isset($thisfile_riff_audio) && is_array($thisfile_riff_audio)) {
486 $streamindex = count($thisfile_riff_audio);
487 }
488
489 $thisfile_riff_audio[$streamindex] = getid3_riff::RIFFparseWAVEFORMATex($strfData);
490 $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
491
492 // shortcut
493 $thisfile_audio['streams'][$streamindex] = $thisfile_riff_audio[$streamindex];
494 $thisfile_audio_streams_currentstream = &$thisfile_audio['streams'][$streamindex];
495
496 if ($thisfile_audio_streams_currentstream['bits_per_sample'] == 0) {
497 unset($thisfile_audio_streams_currentstream['bits_per_sample']);
498 }
499 $thisfile_audio_streams_currentstream['wformattag'] = $thisfile_audio_streams_currentstream['raw']['wFormatTag'];
500 unset($thisfile_audio_streams_currentstream['raw']);
501
502 // shortcut
503 $thisfile_riff_raw['strf'][$strhfccType][$streamindex] = $thisfile_riff_audio[$streamindex]['raw'];
504
505 unset($thisfile_riff_audio[$streamindex]['raw']);
506 $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
507
508 $thisfile_audio['lossless'] = false;
509 switch ($thisfile_riff_raw_strf_strhfccType_streamindex['wFormatTag']) {
510 case 0x0001: // PCM
511 $thisfile_audio_dataformat = 'wav';
512 $thisfile_audio['lossless'] = true;
513 break;
514
515 case 0x0050: // MPEG Layer 2 or Layer 1
516 $thisfile_audio_dataformat = 'mp2'; // Assume Layer-2
517 break;
518
519 case 0x0055: // MPEG Layer 3
520 $thisfile_audio_dataformat = 'mp3';
521 break;
522
523 case 0x00FF: // AAC
524 $thisfile_audio_dataformat = 'aac';
525 break;
526
527 case 0x0161: // Windows Media v7 / v8 / v9
528 case 0x0162: // Windows Media Professional v9
529 case 0x0163: // Windows Media Lossess v9
530 $thisfile_audio_dataformat = 'wma';
531 break;
532
533 case 0x2000: // AC-3
534 $thisfile_audio_dataformat = 'ac3';
535 break;
536
537 case 0x2001: // DTS
538 $thisfile_audio_dataformat = 'dts';
539 break;
540
541 default:
542 $thisfile_audio_dataformat = 'wav';
543 break;
544 }
545 $thisfile_audio_streams_currentstream['dataformat'] = $thisfile_audio_dataformat;
546 $thisfile_audio_streams_currentstream['lossless'] = $thisfile_audio['lossless'];
547 $thisfile_audio_streams_currentstream['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
548 break;
549
550
551 case 'iavs':
552 case 'vids':
553 // shortcut
554 $thisfile_riff_raw['strh'][$i] = array();
555 $thisfile_riff_raw_strh_current = &$thisfile_riff_raw['strh'][$i];
556
557 $thisfile_riff_raw_strh_current['fccType'] = substr($strhData, 0, 4); // same as $strhfccType;
558 $thisfile_riff_raw_strh_current['fccHandler'] = substr($strhData, 4, 4);
559 $thisfile_riff_raw_strh_current['dwFlags'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 8, 4)); // Contains AVITF_* flags
560 $thisfile_riff_raw_strh_current['wPriority'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 12, 2));
561 $thisfile_riff_raw_strh_current['wLanguage'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 14, 2));
562 $thisfile_riff_raw_strh_current['dwInitialFrames'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 16, 4));
563 $thisfile_riff_raw_strh_current['dwScale'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 20, 4));
564 $thisfile_riff_raw_strh_current['dwRate'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 24, 4));
565 $thisfile_riff_raw_strh_current['dwStart'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 28, 4));
566 $thisfile_riff_raw_strh_current['dwLength'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 32, 4));
567 $thisfile_riff_raw_strh_current['dwSuggestedBufferSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 36, 4));
568 $thisfile_riff_raw_strh_current['dwQuality'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 40, 4));
569 $thisfile_riff_raw_strh_current['dwSampleSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 44, 4));
570 $thisfile_riff_raw_strh_current['rcFrame'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strhData, 48, 4));
571
572 $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strh_current['fccHandler']);
573 $thisfile_video['fourcc'] = $thisfile_riff_raw_strh_current['fccHandler'];
574 if (!$thisfile_riff_video_current['codec'] && isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
575 $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
576 $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
577 }
578 $thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
579 $thisfile_video['pixel_aspect_ratio'] = (float) 1;
580 switch ($thisfile_riff_raw_strh_current['fccHandler']) {
581 case 'HFYU': // Huffman Lossless Codec
582 case 'IRAW': // Intel YUV Uncompressed
583 case 'YUY2': // Uncompressed YUV 4:2:2
584 $thisfile_video['lossless'] = true;
585 break;
586
587 default:
588 $thisfile_video['lossless'] = false;
589 break;
590 }
591
592 switch ($strhfccType) {
593 case 'vids':
594 $thisfile_riff_raw_strf_strhfccType_streamindex['biSize'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 0, 4)); // number of bytes required by the BITMAPINFOHEADER structure
595 $thisfile_riff_raw_strf_strhfccType_streamindex['biWidth'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 4, 4)); // width of the bitmap in pixels
596 $thisfile_riff_raw_strf_strhfccType_streamindex['biHeight'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 8, 4)); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
597 $thisfile_riff_raw_strf_strhfccType_streamindex['biPlanes'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 12, 2)); // number of color planes on the target device. In most cases this value must be set to 1
598 $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 14, 2)); // Specifies the number of bits per pixels
599 $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'] = substr($strfData, 16, 4); //
600 $thisfile_riff_raw_strf_strhfccType_streamindex['biSizeImage'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 20, 4)); // size of the bitmap data section of the image (the actual pixel data, excluding BITMAPINFOHEADER and RGBQUAD structures)
601 $thisfile_riff_raw_strf_strhfccType_streamindex['biXPelsPerMeter'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 24, 4)); // horizontal resolution, in pixels per metre, of the target device
602 $thisfile_riff_raw_strf_strhfccType_streamindex['biYPelsPerMeter'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 28, 4)); // vertical resolution, in pixels per metre, of the target device
603 $thisfile_riff_raw_strf_strhfccType_streamindex['biClrUsed'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 32, 4)); // actual number of color indices in the color table used by the bitmap. If this value is zero, the bitmap uses the maximum number of colors corresponding to the value of the biBitCount member for the compression mode specified by biCompression
604 $thisfile_riff_raw_strf_strhfccType_streamindex['biClrImportant'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($strfData, 36, 4)); // number of color indices that are considered important for displaying the bitmap. If this value is zero, all colors are important
605
606 $thisfile_video['bits_per_sample'] = $thisfile_riff_raw_strf_strhfccType_streamindex['biBitCount'];
607
608 if ($thisfile_riff_video_current['codec'] == 'DV') {
609 $thisfile_riff_video_current['dv_type'] = 2;
610 }
611 break;
612
613 case 'iavs':
614 $thisfile_riff_video_current['dv_type'] = 1;
615 break;
616 }
617 break;
618
619 default:
620 $ThisFileInfo['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
621 break;
622
623 }
624 }
625 }
626
627 if (isset($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) && getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'])) {
628
629 $thisfile_riff_video_current['codec'] = getid3_riff::RIFFfourccLookup($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']);
630 $thisfile_video['codec'] = $thisfile_riff_video_current['codec'];
631 $thisfile_video['fourcc'] = $thisfile_riff_raw_strf_strhfccType_streamindex['fourcc'];
632
633 switch ($thisfile_riff_raw_strf_strhfccType_streamindex['fourcc']) {
634 case 'HFYU': // Huffman Lossless Codec
635 case 'IRAW': // Intel YUV Uncompressed
636 case 'YUY2': // Uncompressed YUV 4:2:2
637 $thisfile_video['lossless'] = true;
638 $thisfile_video['bits_per_sample'] = 24;
639 break;
640
641 default:
642 $thisfile_video['lossless'] = false;
643 $thisfile_video['bits_per_sample'] = 24;
644 break;
645 }
646
647 }
648 }
649 }
650 }
651 break;
652
653 case 'CDDA':
654 $thisfile_audio['bitrate_mode'] = 'cbr';
655 $thisfile_audio_dataformat = 'cda';
656 $thisfile_audio['lossless'] = true;
657 unset($ThisFileInfo['mime_type']);
658
659 $thisfile_avdataoffset = 44;
660
661 if (isset($thisfile_riff['CDDA']['fmt '][0]['data'])) {
662 // shortcut
663 $thisfile_riff_CDDA_fmt_0 = &$thisfile_riff['CDDA']['fmt '][0];
664
665 $thisfile_riff_CDDA_fmt_0['unknown1'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 0, 2));
666 $thisfile_riff_CDDA_fmt_0['track_num'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 2, 2));
667 $thisfile_riff_CDDA_fmt_0['disc_id'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 4, 4));
668 $thisfile_riff_CDDA_fmt_0['start_offset_frame'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 8, 4));
669 $thisfile_riff_CDDA_fmt_0['playtime_frames'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 12, 4));
670 $thisfile_riff_CDDA_fmt_0['unknown6'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 16, 4));
671 $thisfile_riff_CDDA_fmt_0['unknown7'] = getid3_riff::EitherEndian2Int($ThisFileInfo, substr($thisfile_riff_CDDA_fmt_0['data'], 20, 4));
672
673 $thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
674 $thisfile_riff_CDDA_fmt_0['playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
675 $ThisFileInfo['comments']['track'] = $thisfile_riff_CDDA_fmt_0['track_num'];
676 $ThisFileInfo['playtime_seconds'] = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
677
678 // hardcoded data for CD-audio
679 $thisfile_audio['sample_rate'] = 44100;
680 $thisfile_audio['channels'] = 2;
681 $thisfile_audio['bits_per_sample'] = 16;
682 $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $thisfile_audio['channels'] * $thisfile_audio['bits_per_sample'];
683 $thisfile_audio['bitrate_mode'] = 'cbr';
684 }
685 break;
686
687
688 case 'AIFF':
689 case 'AIFC':
690 $thisfile_audio['bitrate_mode'] = 'cbr';
691 $thisfile_audio_dataformat = 'aiff';
692 $thisfile_audio['lossless'] = true;
693 $ThisFileInfo['mime_type'] = 'audio/x-aiff';
694
695 if (isset($thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'])) {
696 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype]['SSND'][0]['offset'] + 8;
697 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype]['SSND'][0]['size'];
698 if ($thisfile_avdataend > $ThisFileInfo['filesize']) {
699 if (($thisfile_avdataend == ($ThisFileInfo['filesize'] + 1)) && (($ThisFileInfo['filesize'] % 2) == 1)) {
700 // structures rounded to 2-byte boundary, but dumb encoders
701 // forget to pad end of file to make this actually work
702 } else {
703 $ThisFileInfo['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($ThisFileInfo['filesize'] - $thisfile_avdataoffset).' bytes found';
704 }
705 $thisfile_avdataend = $ThisFileInfo['filesize'];
706 }
707 }
708
709 if (isset($thisfile_riff[$RIFFsubtype]['COMM'][0]['data'])) {
710
711 // shortcut
712 $thisfile_riff_RIFFsubtype_COMM_0_data = &$thisfile_riff[$RIFFsubtype]['COMM'][0]['data'];
713
714 $thisfile_riff_audio['channels'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 0, 2), true);
715 $thisfile_riff_audio['total_samples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 2, 4), false);
716 $thisfile_riff_audio['bits_per_sample'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 6, 2), true);
717 $thisfile_riff_audio['sample_rate'] = (int) getid3_lib::BigEndian2Float(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 8, 10));
718
719 if ($thisfile_riff[$RIFFsubtype]['COMM'][0]['size'] > 18) {
720 $thisfile_riff_audio['codec_fourcc'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 18, 4);
721 $CodecNameSize = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_COMM_0_data, 22, 1), false);
722 $thisfile_riff_audio['codec_name'] = substr($thisfile_riff_RIFFsubtype_COMM_0_data, 23, $CodecNameSize);
723 switch ($thisfile_riff_audio['codec_name']) {
724 case 'NONE':
725 $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
726 $thisfile_audio['lossless'] = true;
727 break;
728
729 case '':
730 switch ($thisfile_riff_audio['codec_fourcc']) {
731 // http://developer.apple.com/qa/snd/snd07.html
732 case 'sowt':
733 $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Little-Endian PCM';
734 $thisfile_audio['lossless'] = true;
735 break;
736
737 case 'twos':
738 $thisfile_riff_audio['codec_name'] = 'Two\'s Compliment Big-Endian PCM';
739 $thisfile_audio['lossless'] = true;
740 break;
741
742 default:
743 break;
744 }
745 break;
746
747 default:
748 $thisfile_audio['codec'] = $thisfile_riff_audio['codec_name'];
749 $thisfile_audio['lossless'] = false;
750 break;
751 }
752 }
753
754 $thisfile_audio['channels'] = $thisfile_riff_audio['channels'];
755 if ($thisfile_riff_audio['bits_per_sample'] > 0) {
756 $thisfile_audio['bits_per_sample'] = $thisfile_riff_audio['bits_per_sample'];
757 }
758 $thisfile_audio['sample_rate'] = $thisfile_riff_audio['sample_rate'];
759 if ($thisfile_audio['sample_rate'] == 0) {
760 $ThisFileInfo['error'][] = 'Corrupted AIFF file: sample_rate == zero';
761 return false;
762 }
763 $ThisFileInfo['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
764 }
765
766 if (isset($thisfile_riff[$RIFFsubtype]['COMT'])) {
767 $offset = 0;
768 $CommentCount = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
769 $offset += 2;
770 for ($i = 0; $i < $CommentCount; $i++) {
771 $ThisFileInfo['comments_raw'][$i]['timestamp'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 4), false);
772 $offset += 4;
773 $ThisFileInfo['comments_raw'][$i]['marker_id'] = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), true);
774 $offset += 2;
775 $CommentLength = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, 2), false);
776 $offset += 2;
777 $ThisFileInfo['comments_raw'][$i]['comment'] = substr($thisfile_riff[$RIFFsubtype]['COMT'][0]['data'], $offset, $CommentLength);
778 $offset += $CommentLength;
779
780 $ThisFileInfo['comments_raw'][$i]['timestamp_unix'] = getid3_lib::DateMac2Unix($ThisFileInfo['comments_raw'][$i]['timestamp']);
781 $thisfile_riff['comments']['comment'][] = $ThisFileInfo['comments_raw'][$i]['comment'];
782 }
783 }
784
785 $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
786 foreach ($CommentsChunkNames as $key => $value) {
787 if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
788 $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
789 }
790 }
791 break;
792
793 case '8SVX':
794 $thisfile_audio['bitrate_mode'] = 'cbr';
795 $thisfile_audio_dataformat = '8svx';
796 $thisfile_audio['bits_per_sample'] = 8;
797 $thisfile_audio['channels'] = 1; // overridden below, if need be
798 $ThisFileInfo['mime_type'] = 'audio/x-aiff';
799
800 if (isset($thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'])) {
801 $thisfile_avdataoffset = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
802 $thisfile_avdataend = $thisfile_avdataoffset + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
803 if ($thisfile_avdataend > $ThisFileInfo['filesize']) {
804 $ThisFileInfo['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($ThisFileInfo['filesize'] - $thisfile_avdataoffset).' bytes found';
805 }
806 }
807
808 if (isset($thisfile_riff[$RIFFsubtype]['VHDR'][0]['offset'])) {
809 // shortcut
810 $thisfile_riff_RIFFsubtype_VHDR_0 = &$thisfile_riff[$RIFFsubtype]['VHDR'][0];
811
812 $thisfile_riff_RIFFsubtype_VHDR_0['oneShotHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 0, 4));
813 $thisfile_riff_RIFFsubtype_VHDR_0['repeatHiSamples'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 4, 4));
814 $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerHiCycle'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 8, 4));
815 $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 12, 2));
816 $thisfile_riff_RIFFsubtype_VHDR_0['ctOctave'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 14, 1));
817 $thisfile_riff_RIFFsubtype_VHDR_0['sCompression'] = getid3_lib::BigEndian2Int(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 15, 1));
818 $thisfile_riff_RIFFsubtype_VHDR_0['Volume'] = getid3_lib::FixedPoint16_16(substr($thisfile_riff_RIFFsubtype_VHDR_0['data'], 16, 4));
819
820 $thisfile_audio['sample_rate'] = $thisfile_riff_RIFFsubtype_VHDR_0['samplesPerSec'];
821
822 switch ($thisfile_riff_RIFFsubtype_VHDR_0['sCompression']) {
823 case 0:
824 $thisfile_audio['codec'] = 'Pulse Code Modulation (PCM)';
825 $thisfile_audio['lossless'] = true;
826 $ActualBitsPerSample = 8;
827 break;
828
829 case 1:
830 $thisfile_audio['codec'] = 'Fibonacci-delta encoding';
831 $thisfile_audio['lossless'] = false;
832 $ActualBitsPerSample = 4;
833 break;
834
835 default:
836 $ThisFileInfo['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
837 break;
838 }
839 }
840
841 if (isset($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'])) {
842 $ChannelsIndex = getid3_lib::BigEndian2Int(substr($thisfile_riff[$RIFFsubtype]['CHAN'][0]['data'], 0, 4));
843 switch ($ChannelsIndex) {
844 case 6: // Stereo
845 $thisfile_audio['channels'] = 2;
846 break;
847
848 case 2: // Left channel only
849 case 4: // Right channel only
850 $thisfile_audio['channels'] = 1;
851 break;
852
853 default:
854 $ThisFileInfo['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
855 break;
856 }
857
858 }
859
860 $CommentsChunkNames = array('NAME'=>'title', 'author'=>'artist', '(c) '=>'copyright', 'ANNO'=>'comment');
861 foreach ($CommentsChunkNames as $key => $value) {
862 if (isset($thisfile_riff[$RIFFsubtype][$key][0]['data'])) {
863 $thisfile_riff['comments'][$value][] = $thisfile_riff[$RIFFsubtype][$key][0]['data'];
864 }
865 }
866
867 $thisfile_audio['bitrate'] = $thisfile_audio['sample_rate'] * $ActualBitsPerSample * $thisfile_audio['channels'];
868 if (!empty($thisfile_audio['bitrate'])) {
869 $ThisFileInfo['playtime_seconds'] = ($thisfile_avdataend - $thisfile_avdataoffset) / ($thisfile_audio['bitrate'] / 8);
870 }
871 break;
872
873
874 case 'CDXA':
875 $ThisFileInfo['mime_type'] = 'video/mpeg';
876 if (!empty($thisfile_riff['CDXA']['data'][0]['size'])) {
877 $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
878 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, false)) {
879 $dummy = $ThisFileInfo;
880 $dummy['error'] = array();
881 $mpeg_scanner = new getid3_mpeg($fd, $dummy);
882 if (empty($dummy['error'])) {
883 $ThisFileInfo['audio'] = $dummy['audio'];
884 $ThisFileInfo['video'] = $dummy['video'];
885 $ThisFileInfo['mpeg'] = $dummy['mpeg'];
886 $ThisFileInfo['warning'] = $dummy['warning'];
887 }
888 }
889 }
890 break;
891
892
893 default:
894 $ThisFileInfo['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
895 unset($ThisFileInfo['fileformat']);
896 break;
897 }
898
899 if (isset($thisfile_riff_WAVE['DISP']) && is_array($thisfile_riff_WAVE['DISP'])) {
900 $thisfile_riff['comments']['title'][] = trim(substr($thisfile_riff_WAVE['DISP'][count($thisfile_riff_WAVE['DISP']) - 1]['data'], 4));
901 }
902 if (isset($thisfile_riff_WAVE['INFO']) && is_array($thisfile_riff_WAVE['INFO'])) {
903 $this->RIFFcommentsParse($thisfile_riff_WAVE['INFO'], $thisfile_riff['comments']);
904 }
905
906 if (empty($thisfile_audio['encoder']) && !empty($ThisFileInfo['mpeg']['audio']['LAME']['short_version'])) {
907 $thisfile_audio['encoder'] = $ThisFileInfo['mpeg']['audio']['LAME']['short_version'];
908 }
909
910 if (!isset($ThisFileInfo['playtime_seconds'])) {
911 $ThisFileInfo['playtime_seconds'] = 0;
912 }
913 if (isset($thisfile_riff_raw['avih']['dwTotalFrames']) && isset($thisfile_riff_raw['avih']['dwMicroSecPerFrame'])) {
914 $ThisFileInfo['playtime_seconds'] = $thisfile_riff_raw['avih']['dwTotalFrames'] * ($thisfile_riff_raw['avih']['dwMicroSecPerFrame'] / 1000000);
915 }
916
917 if ($ThisFileInfo['playtime_seconds'] > 0) {
918 if (isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
919
920 if (!isset($ThisFileInfo['bitrate'])) {
921 $ThisFileInfo['bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo['playtime_seconds']) * 8);
922 }
923
924 } elseif (isset($thisfile_riff_audio) && !isset($thisfile_riff_video)) {
925
926 if (!isset($thisfile_audio['bitrate'])) {
927 $thisfile_audio['bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo['playtime_seconds']) * 8);
928 }
929
930 } elseif (!isset($thisfile_riff_audio) && isset($thisfile_riff_video)) {
931
932 if (!isset($thisfile_video['bitrate'])) {
933 $thisfile_video['bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo['playtime_seconds']) * 8);
934 }
935
936 }
937 }
938
939
940 if (isset($thisfile_riff_video) && isset($thisfile_audio['bitrate']) && ($thisfile_audio['bitrate'] > 0) && ($ThisFileInfo['playtime_seconds'] > 0)) {
941
942 $ThisFileInfo['bitrate'] = ((($thisfile_avdataend - $thisfile_avdataoffset) / $ThisFileInfo['playtime_seconds']) * 8);
943 $thisfile_audio['bitrate'] = 0;
944 $thisfile_video['bitrate'] = $ThisFileInfo['bitrate'];
945 foreach ($thisfile_riff_audio as $channelnumber => $audioinfoarray) {
946 $thisfile_video['bitrate'] -= $audioinfoarray['bitrate'];
947 $thisfile_audio['bitrate'] += $audioinfoarray['bitrate'];
948 }
949 if ($thisfile_video['bitrate'] <= 0) {
950 unset($thisfile_video['bitrate']);
951 }
952 if ($thisfile_audio['bitrate'] <= 0) {
953 unset($thisfile_audio['bitrate']);
954 }
955 }
956
957 if (isset($ThisFileInfo['mpeg']['audio'])) {
958 $thisfile_audio_dataformat = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
959 $thisfile_audio['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate'];
960 $thisfile_audio['channels'] = $ThisFileInfo['mpeg']['audio']['channels'];
961 $thisfile_audio['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate'];
962 $thisfile_audio['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
963 if (!empty($ThisFileInfo['mpeg']['audio']['codec'])) {
964 $thisfile_audio['codec'] = $ThisFileInfo['mpeg']['audio']['codec'].' '.$thisfile_audio['codec'];
965 }
966 if (!empty($thisfile_audio['streams'])) {
967 foreach ($thisfile_audio['streams'] as $streamnumber => $streamdata) {
968 if ($streamdata['dataformat'] == $thisfile_audio_dataformat) {
969 $thisfile_audio['streams'][$streamnumber]['sample_rate'] = $thisfile_audio['sample_rate'];
970 $thisfile_audio['streams'][$streamnumber]['channels'] = $thisfile_audio['channels'];
971 $thisfile_audio['streams'][$streamnumber]['bitrate'] = $thisfile_audio['bitrate'];
972 $thisfile_audio['streams'][$streamnumber]['bitrate_mode'] = $thisfile_audio['bitrate_mode'];
973 $thisfile_audio['streams'][$streamnumber]['codec'] = $thisfile_audio['codec'];
974 }
975 }
976 }
977 $thisfile_audio['encoder_options'] = getid3_mp3::GuessEncoderOptions($ThisFileInfo);
978 }
979
980
981 if (!empty($thisfile_riff_raw['fmt ']['wBitsPerSample']) && ($thisfile_riff_raw['fmt ']['wBitsPerSample'] > 0)) {
982 switch ($thisfile_audio_dataformat) {
983 case 'ac3':
984 // ignore bits_per_sample
985 break;
986
987 default:
988 $thisfile_audio['bits_per_sample'] = $thisfile_riff_raw['fmt ']['wBitsPerSample'];
989 break;
990 }
991 }
992
993
994 if (empty($thisfile_riff_raw)) {
995 unset($thisfile_riff['raw']);
996 }
997 if (empty($thisfile_riff_audio)) {
998 unset($thisfile_riff['audio']);
999 }
1000 if (empty($thisfile_riff_video)) {
1001 unset($thisfile_riff['video']);
1002 }
1003
1004 return true;
1005 }
1006
1007
1008 function RIFFcommentsParse(&$RIFFinfoArray, &$CommentsTargetArray) {
1009 $RIFFinfoKeyLookup = array(
1010 'IARL'=>'archivallocation',
1011 'IART'=>'artist',
1012 'ICDS'=>'costumedesigner',
1013 'ICMS'=>'commissionedby',
1014 'ICMT'=>'comment',
1015 'ICNT'=>'country',
1016 'ICOP'=>'copyright',
1017 'ICRD'=>'creationdate',
1018 'IDIM'=>'dimensions',
1019 'IDIT'=>'digitizationdate',
1020 'IDPI'=>'resolution',
1021 'IDST'=>'distributor',
1022 'IEDT'=>'editor',
1023 'IENG'=>'engineers',
1024 'IFRM'=>'accountofparts',
1025 'IGNR'=>'genre',
1026 'IKEY'=>'keywords',
1027 'ILGT'=>'lightness',
1028 'ILNG'=>'language',
1029 'IMED'=>'orignalmedium',
1030 'IMUS'=>'composer',
1031 'INAM'=>'title',
1032 'IPDS'=>'productiondesigner',
1033 'IPLT'=>'palette',
1034 'IPRD'=>'product',
1035 'IPRO'=>'producer',
1036 'IPRT'=>'part',
1037 'IRTD'=>'rating',
1038 'ISBJ'=>'subject',
1039 'ISFT'=>'software',
1040 'ISGN'=>'secondarygenre',
1041 'ISHP'=>'sharpness',
1042 'ISRC'=>'sourcesupplier',
1043 'ISRF'=>'digitizationsource',
1044 'ISTD'=>'productionstudio',
1045 'ISTR'=>'starring',
1046 'ITCH'=>'encoded_by',
1047 'IWEB'=>'url',
1048 'IWRI'=>'writer'
1049 );
1050 foreach ($RIFFinfoKeyLookup as $key => $value) {
1051 if (isset($RIFFinfoArray[$key])) {
1052 foreach ($RIFFinfoArray[$key] as $commentid => $commentdata) {
1053 if (trim($commentdata['data']) != '') {
1054 @$CommentsTargetArray[$value][] = trim($commentdata['data']);
1055 }
1056 }
1057 }
1058 }
1059 return true;
1060 }
1061
1062 function ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo) {
1063
1064 $maxoffset = min($maxoffset, $ThisFileInfo['avdataend']);
1065
1066 $RIFFchunk = false;
1067
1068 fseek($fd, $startoffset, SEEK_SET);
1069
1070 while (ftell($fd) < $maxoffset) {
1071 $chunkname = fread($fd, 4);
1072 if (strlen($chunkname) < 4) {
1073 $ThisFileInfo['error'][] = 'Expecting chunk name at offset '.(ftell($fd) - 4).' but found nothing. Aborting RIFF parsing.';
1074 break;
1075 }
1076
1077 $chunksize = getid3_riff::EitherEndian2Int($ThisFileInfo, fread($fd, 4));
1078 if ($chunksize == 0) {
1079 $ThisFileInfo['error'][] = 'Chunk size at offset '.(ftell($fd) - 4).' is zero. Aborting RIFF parsing.';
1080 break;
1081 }
1082 if (($chunksize % 2) != 0) {
1083 // all structures are packed on word boundaries
1084 $chunksize++;
1085 }
1086
1087 switch ($chunkname) {
1088 case 'LIST':
1089 $listname = fread($fd, 4);
1090 switch ($listname) {
1091 case 'movi':
1092 case 'rec ':
1093 $RIFFchunk[$listname]['offset'] = ftell($fd) - 4;
1094 $RIFFchunk[$listname]['size'] = $chunksize;
1095
1096 static $ParsedAudioStream = false;
1097 if ($ParsedAudioStream) {
1098
1099 // skip over
1100
1101 } else {
1102
1103 $WhereWeWere = ftell($fd);
1104 $AudioChunkHeader = fread($fd, 12);
1105 $AudioChunkStreamNum = substr($AudioChunkHeader, 0, 2);
1106 $AudioChunkStreamType = substr($AudioChunkHeader, 2, 2);
1107 $AudioChunkSize = getid3_lib::LittleEndian2Int(substr($AudioChunkHeader, 4, 4));
1108
1109 if ($AudioChunkStreamType == 'wb') {
1110 $FirstFourBytes = substr($AudioChunkHeader, 8, 4);
1111 if (preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', $FirstFourBytes)) {
1112
1113 // MP3
1114 if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
1115 $dummy = $ThisFileInfo;
1116 $dummy['avdataoffset'] = ftell($fd) - 4;
1117 $dummy['avdataend'] = ftell($fd) + $AudioChunkSize;
1118 getid3_mp3::getOnlyMPEGaudioInfo($fd, $dummy, $dummy['avdataoffset'], false);
1119 if (isset($dummy['mpeg']['audio'])) {
1120 $ThisFileInfo = $dummy;
1121 $ThisFileInfo['audio']['dataformat'] = 'mp'.$ThisFileInfo['mpeg']['audio']['layer'];
1122 $ThisFileInfo['audio']['sample_rate'] = $ThisFileInfo['mpeg']['audio']['sample_rate'];
1123 $ThisFileInfo['audio']['channels'] = $ThisFileInfo['mpeg']['audio']['channels'];
1124 $ThisFileInfo['audio']['bitrate'] = $ThisFileInfo['mpeg']['audio']['bitrate'];
1125 $ThisFileInfo['bitrate'] = $ThisFileInfo['audio']['bitrate'];
1126 $ThisFileInfo['audio']['bitrate_mode'] = strtolower($ThisFileInfo['mpeg']['audio']['bitrate_mode']);
1127 }
1128 }
1129
1130 } elseif (preg_match('/^\x0B\x77/s', $FirstFourBytes)) {
1131
1132 // AC3
1133 $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1134 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1135
1136 $dummy = $ThisFileInfo;
1137 $dummy['avdataoffset'] = ftell($fd) - 4;
1138 $dummy['avdataend'] = ftell($fd) + $AudioChunkSize;
1139 $dummy['error'] = array();
1140 $ac3_tag = new getid3_ac3($fd, $dummy);
1141 if (empty($dummy['error'])) {
1142 $ThisFileInfo['audio'] = $dummy['audio'];
1143 $ThisFileInfo['ac3'] = $dummy['ac3'];
1144 $ThisFileInfo['warning'] = $dummy['warning'];
1145 }
1146
1147 }
1148
1149 }
1150
1151 }
1152
1153 $ParsedAudioStream = true;
1154 fseek($fd, $WhereWeWere, SEEK_SET);
1155
1156 }
1157 fseek($fd, $chunksize - 4, SEEK_CUR);
1158 break;
1159
1160 default:
1161 if (!isset($RIFFchunk[$listname])) {
1162 $RIFFchunk[$listname] = array();
1163 }
1164 $LISTchunkParent = $listname;
1165 $LISTchunkMaxOffset = ftell($fd) - 4 + $chunksize;
1166 if ($parsedChunk = getid3_riff::ParseRIFF($fd, ftell($fd), ftell($fd) + $chunksize - 4, $ThisFileInfo)) {
1167 $RIFFchunk[$listname] = array_merge_recursive($RIFFchunk[$listname], $parsedChunk);
1168 }
1169 break;
1170 }
1171 break;
1172
1173 default:
1174 $thisindex = 0;
1175 if (isset($RIFFchunk[$chunkname]) && is_array($RIFFchunk[$chunkname])) {
1176 $thisindex = count($RIFFchunk[$chunkname]);
1177 }
1178 $RIFFchunk[$chunkname][$thisindex]['offset'] = ftell($fd) - 8;
1179 $RIFFchunk[$chunkname][$thisindex]['size'] = $chunksize;
1180 switch ($chunkname) {
1181 case 'data':
1182 $ThisFileInfo['avdataoffset'] = ftell($fd);
1183 $ThisFileInfo['avdataend'] = $ThisFileInfo['avdataoffset'] + $chunksize;
1184
1185 $RIFFdataChunkContentsTest = fread($fd, 36);
1186
1187 if ((strlen($RIFFdataChunkContentsTest) > 0) && preg_match('/^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\xEB]/s', substr($RIFFdataChunkContentsTest, 0, 4))) {
1188
1189 // Probably is MP3 data
1190 if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($RIFFdataChunkContentsTest, 0, 4))) {
1191 getid3_mp3::getOnlyMPEGaudioInfo($fd, $ThisFileInfo, $RIFFchunk[$chunkname][$thisindex]['offset'], false);
1192 }
1193
1194 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 2) == "\x0B\x77")) {
1195
1196 // This is probably AC-3 data
1197 $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1198 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1199
1200 $dummy = $ThisFileInfo;
1201 $dummy['avdataoffset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1202 $dummy['avdataend'] = $dummy['avdataoffset'] + $RIFFchunk[$chunkname][$thisindex]['size'];
1203 $dummy['error'] = array();
1204
1205 $ac3_tag = new getid3_ac3($fd, $dummy);
1206 if (empty($dummy['error'])) {
1207 $ThisFileInfo['audio'] = $dummy['audio'];
1208 $ThisFileInfo['ac3'] = $dummy['ac3'];
1209 $ThisFileInfo['warning'] = $dummy['warning'];
1210 }
1211
1212 }
1213
1214 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 8, 2) == "\x77\x0B")) {
1215
1216 // Dolby Digital WAV
1217 // AC-3 content, but not encoded in same format as normal AC-3 file
1218 // For one thing, byte order is swapped
1219
1220 $GETID3_ERRORARRAY = &$ThisFileInfo['warning'];
1221 if (getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, false)) {
1222
1223 // ok to use tmpfile here - only 56 bytes
1224 if ($fd_temp = tmpfile()) {
1225
1226 for ($i = 0; $i < 28; $i += 2) {
1227 // swap byte order
1228 fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 1, 1));
1229 fwrite($fd_temp, substr($RIFFdataChunkContentsTest, 8 + $i + 0, 1));
1230 }
1231
1232 $dummy = $ThisFileInfo;
1233 $dummy['avdataoffset'] = 0;
1234 $dummy['avdataend'] = 20;
1235 $dummy['error'] = array();
1236 $ac3_tag = new getid3_ac3($fd_temp, $dummy);
1237 fclose($fd_temp);
1238 if (empty($dummy['error'])) {
1239 $ThisFileInfo['audio'] = $dummy['audio'];
1240 $ThisFileInfo['ac3'] = $dummy['ac3'];
1241 $ThisFileInfo['warning'] = $dummy['warning'];
1242 } else {
1243 $ThisFileInfo['error'][] = 'Errors parsing DolbyDigital WAV: '.explode(';', $dummy['error']);
1244 }
1245
1246 } else {
1247
1248 $ThisFileInfo['error'][] = 'Could not create temporary file to analyze DolbyDigital WAV';
1249
1250 }
1251
1252 }
1253
1254 } elseif ((strlen($RIFFdataChunkContentsTest) > 0) && (substr($RIFFdataChunkContentsTest, 0, 4) == 'wvpk')) {
1255
1256 // This is WavPack data
1257 $ThisFileInfo['wavpack']['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1258 $ThisFileInfo['wavpack']['size'] = getid3_lib::LittleEndian2Int(substr($RIFFdataChunkContentsTest, 4, 4));
1259 getid3_riff::RIFFparseWavPackHeader(substr($RIFFdataChunkContentsTest, 8, 28), $ThisFileInfo);
1260
1261 } else {
1262
1263 // This is some other kind of data (quite possibly just PCM)
1264 // do nothing special, just skip it
1265
1266 }
1267 fseek($fd, $RIFFchunk[$chunkname][$thisindex]['offset'] + 8 + $chunksize, SEEK_SET);
1268 break;
1269
1270 case 'bext':
1271 case 'cart':
1272 case 'fmt ':
1273 case 'MEXT':
1274 case 'DISP':
1275 // always read data in
1276 $RIFFchunk[$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1277 break;
1278
1279 default:
1280 if (!empty($LISTchunkParent) && (($RIFFchunk[$chunkname][$thisindex]['offset'] + $RIFFchunk[$chunkname][$thisindex]['size']) <= $LISTchunkMaxOffset)) {
1281 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['offset'] = $RIFFchunk[$chunkname][$thisindex]['offset'];
1282 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['size'] = $RIFFchunk[$chunkname][$thisindex]['size'];
1283 unset($RIFFchunk[$chunkname][$thisindex]['offset']);
1284 unset($RIFFchunk[$chunkname][$thisindex]['size']);
1285 if (isset($RIFFchunk[$chunkname][$thisindex]) && empty($RIFFchunk[$chunkname][$thisindex])) {
1286 unset($RIFFchunk[$chunkname][$thisindex]);
1287 }
1288 if (isset($RIFFchunk[$chunkname]) && empty($RIFFchunk[$chunkname])) {
1289 unset($RIFFchunk[$chunkname]);
1290 }
1291 $RIFFchunk[$LISTchunkParent][$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1292 } elseif ($chunksize < 2048) {
1293 // only read data in if smaller than 2kB
1294 $RIFFchunk[$chunkname][$thisindex]['data'] = fread($fd, $chunksize);
1295 } else {
1296 fseek($fd, $chunksize, SEEK_CUR);
1297 }
1298 break;
1299 }
1300 break;
1301
1302 }
1303
1304 }
1305
1306 return $RIFFchunk;
1307 }
1308
1309
1310 function ParseRIFFdata(&$RIFFdata, &$ThisFileInfo) {
1311 if ($RIFFdata) {
1312
1313 $tempfile = tempnam('*', 'getID3');
1314 $fp_temp = fopen($tempfile, "wb");
1315 $RIFFdataLength = strlen($RIFFdata);
1316 $NewLengthString = getid3_lib::LittleEndian2String($RIFFdataLength, 4);
1317 for ($i = 0; $i < 4; $i++) {
1318 $RIFFdata{$i + 4} = $NewLengthString{$i};
1319 }
1320 fwrite($fp_temp, $RIFFdata);
1321 fclose($fp_temp);
1322
1323 $fp_temp = fopen($tempfile, "rb");
1324 $dummy = array('filesize'=>$RIFFdataLength, 'filenamepath'=>$ThisFileInfo['filenamepath'], 'tags'=>$ThisFileInfo['tags'], 'avdataoffset'=>0, 'avdataend'=>$RIFFdataLength, 'warning'=>$ThisFileInfo['warning'], 'error'=>$ThisFileInfo['error'], 'comments'=>$ThisFileInfo['comments'], 'audio'=>(isset($ThisFileInfo['audio']) ? $ThisFileInfo['audio'] : array()), 'video'=>(isset($ThisFileInfo['video']) ? $ThisFileInfo['video'] : array()));
1325 $riff = new getid3_riff($fp_temp, $dummy);
1326 $ThisFileInfo['riff'] = $dummy['riff'];
1327 $ThisFileInfo['warning'] = $dummy['warning'];
1328 $ThisFileInfo['error'] = $dummy['error'];
1329 $ThisFileInfo['tags'] = $dummy['tags'];
1330 $ThisFileInfo['comments'] = $dummy['comments'];
1331 fclose($fp_temp);
1332 unlink($tempfile);
1333 return true;
1334 }
1335 return false;
1336 }
1337
1338
1339 function RIFFparseWAVEFORMATex($WaveFormatExData) {
1340 // shortcut
1341 $WaveFormatEx['raw'] = array();
1342 $WaveFormatEx_raw = &$WaveFormatEx['raw'];
1343
1344 $WaveFormatEx_raw['wFormatTag'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 0, 2));
1345 $WaveFormatEx_raw['nChannels'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 2, 2));
1346 $WaveFormatEx_raw['nSamplesPerSec'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 4, 4));
1347 $WaveFormatEx_raw['nAvgBytesPerSec'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 8, 4));
1348 $WaveFormatEx_raw['nBlockAlign'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 12, 2));
1349 $WaveFormatEx_raw['wBitsPerSample'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 14, 2));
1350 if (strlen($WaveFormatExData) > 16) {
1351 $WaveFormatEx_raw['cbSize'] = getid3_lib::LittleEndian2Int(substr($WaveFormatExData, 16, 2));
1352 }
1353
1354 $WaveFormatEx['codec'] = getid3_riff::RIFFwFormatTagLookup($WaveFormatEx_raw['wFormatTag']);
1355 $WaveFormatEx['channels'] = $WaveFormatEx_raw['nChannels'];
1356 $WaveFormatEx['sample_rate'] = $WaveFormatEx_raw['nSamplesPerSec'];
1357 $WaveFormatEx['bitrate'] = $WaveFormatEx_raw['nAvgBytesPerSec'] * 8;
1358 $WaveFormatEx['bits_per_sample'] = $WaveFormatEx_raw['wBitsPerSample'];
1359
1360 return $WaveFormatEx;
1361 }
1362
1363
1364 function RIFFparseWavPackHeader($WavPackChunkData, &$ThisFileInfo) {
1365 // typedef struct {
1366 // char ckID [4];
1367 // long ckSize;
1368 // short version;
1369 // short bits; // added for version 2.00
1370 // short flags, shift; // added for version 3.00
1371 // long total_samples, crc, crc2;
1372 // char extension [4], extra_bc, extras [3];
1373 // } WavpackHeader;
1374
1375 // shortcut
1376 $ThisFileInfo['wavpack'] = array();
1377 $thisfile_wavpack = &$ThisFileInfo['wavpack'];
1378
1379 $thisfile_wavpack['version'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 0, 2));
1380 if ($thisfile_wavpack['version'] >= 2) {
1381 $thisfile_wavpack['bits'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 2, 2));
1382 }
1383 if ($thisfile_wavpack['version'] >= 3) {
1384 $thisfile_wavpack['flags_raw'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 4, 2));
1385 $thisfile_wavpack['shift'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 6, 2));
1386 $thisfile_wavpack['total_samples'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 8, 4));
1387 $thisfile_wavpack['crc1'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 12, 4));
1388 $thisfile_wavpack['crc2'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 16, 4));
1389 $thisfile_wavpack['extension'] = substr($WavPackChunkData, 20, 4);
1390 $thisfile_wavpack['extra_bc'] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 24, 1));
1391 for ($i = 0; $i <= 2; $i++) {
1392 $thisfile_wavpack['extras'][] = getid3_lib::LittleEndian2Int(substr($WavPackChunkData, 25 + $i, 1));
1393 }
1394
1395 // shortcut
1396 $thisfile_wavpack['flags'] = array();
1397 $thisfile_wavpack_flags = &$thisfile_wavpack['flags'];
1398
1399 $thisfile_wavpack_flags['mono'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000001);
1400 $thisfile_wavpack_flags['fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000002);
1401 $thisfile_wavpack_flags['raw_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000004);
1402 $thisfile_wavpack_flags['calc_noise'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000008);
1403 $thisfile_wavpack_flags['high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000010);
1404 $thisfile_wavpack_flags['3_byte_samples'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000020);
1405 $thisfile_wavpack_flags['over_20_bits'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000040);
1406 $thisfile_wavpack_flags['use_wvc'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000080);
1407 $thisfile_wavpack_flags['noiseshaping'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000100);
1408 $thisfile_wavpack_flags['very_fast_mode'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000200);
1409 $thisfile_wavpack_flags['new_high_quality'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000400);
1410 $thisfile_wavpack_flags['cancel_extreme'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x000800);
1411 $thisfile_wavpack_flags['cross_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x001000);
1412 $thisfile_wavpack_flags['new_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x002000);
1413 $thisfile_wavpack_flags['joint_stereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x004000);
1414 $thisfile_wavpack_flags['extra_decorrelation'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x008000);
1415 $thisfile_wavpack_flags['override_noiseshape'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x010000);
1416 $thisfile_wavpack_flags['override_jointstereo'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x020000);
1417 $thisfile_wavpack_flags['copy_source_filetime'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x040000);
1418 $thisfile_wavpack_flags['create_exe'] = (bool) ($thisfile_wavpack['flags_raw'] & 0x080000);
1419 }
1420
1421 return true;
1422 }
1423
1424 function RIFFwFormatTagLookup($wFormatTag) {
1425
1426 $begin = __LINE__;
1427
1590 return getid3_lib::EmbeddedLookup('0x'.str_pad(strtoupper(dechex($wFormatTag)), 4, '0', STR_PAD_LEFT), $begin, __LINE__, __FILE__, 'riff-wFormatTag');
1591
1592 }
1593
1594
1595 function RIFFfourccLookup($fourcc) {
1596
1597 $begin = __LINE__;
1598
1982 return getid3_lib::EmbeddedLookup($fourcc, $begin, __LINE__, __FILE__, 'riff-fourcc');
1983 }
1984
1985
1986 function EitherEndian2Int(&$ThisFileInfo, $byteword, $signed=false) {
1987 if ($ThisFileInfo['fileformat'] == 'riff') {
1988 return getid3_lib::LittleEndian2Int($byteword, $signed);
1989 }
1990 return getid3_lib::BigEndian2Int($byteword, false, $signed);
1991 }
1992
1993}
1994
1995?>
getID3() by James Heinrich info@getid3.org //
fseek($bytes, $whence=SEEK_SET)
Definition: getid3.php:1697
fread($bytes)
Definition: getid3.php:1685
LittleEndian2Int($byteword, $signed=false)
Definition: getid3.lib.php:266
Dec2Bin($number)
Definition: getid3.lib.php:302
BigEndian2Float($byteword)
Definition: getid3.lib.php:159
RGADadjustmentLookup($rawadjustment, $signbit)
RGADoriginatorLookup($originatorcode)
EmbeddedLookup($key, $begin, $end, $file, $name)
IncludeDependency($filename, $sourcefile, $DieOnFailure=false)
array_merge_noclobber($array1, $array2)
Definition: getid3.lib.php:376
CastAsInt($floatnum)
Definition: getid3.lib.php:60
RGADnameLookup($namecode)
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Definition: getid3.lib.php:234
LittleEndian2Float($byteword)
Definition: getid3.lib.php:154
FixedPoint16_16($rawdata)
Definition: getid3.lib.php:454
DateMac2Unix($macdate)
Definition: getid3.lib.php:442
LittleEndian2String($number, $minbytes=1, $synchsafe=false)
Definition: getid3.lib.php:343
Bin2Dec($binstring, $signed=false)
Definition: getid3.lib.php:316
getOnlyMPEGaudioInfo($fd, &$ThisFileInfo, $avdataoffset, $BitrateHistogram=false)
MPEGaudioHeaderBytesValid($head4, $allowBitrate15=false)
RIFFparseWAVEFORMATex($WaveFormatExData)
RIFFcommentsParse(&$RIFFinfoArray, &$CommentsTargetArray)
ParseRIFF(&$fd, $startoffset, $maxoffset, &$ThisFileInfo)
RIFFparseWavPackHeader($WavPackChunkData, &$ThisFileInfo)
RIFFwFormatTagLookup($wFormatTag)
getid3_riff(&$fd, &$ThisFileInfo)
ParseRIFFdata(&$RIFFdata, &$ThisFileInfo)
EitherEndian2Int(&$ThisFileInfo, $byteword, $signed=false)