40 $info = &$this->getid3->info;
43 fseek($this->getid3->fp,
$info[
'avdataoffset'], SEEK_SET);
44 $rawdata =
fread($this->getid3->fp, $this->getid3->fread_buffer_size());
46 switch (substr($rawdata, $offset, 4)) {
50 $info[
'fileformat'] =
'la';
51 $info[
'audio'][
'dataformat'] =
'la';
52 $info[
'audio'][
'lossless'] =
true;
54 $info[
'la'][
'version_major'] = (int) substr($rawdata, $offset + 2, 1);
55 $info[
'la'][
'version_minor'] = (int) substr($rawdata, $offset + 3, 1);
56 $info[
'la'][
'version'] = (float)
$info[
'la'][
'version_major'] + (
$info[
'la'][
'version_minor'] / 10);
61 if (
$info[
'la'][
'uncompressed_size'] == 0) {
62 $info[
'error'][] =
'Corrupt LA file: uncompressed_size == zero';
67 $WAVEchunk = substr($rawdata, $offset, 4);
68 if ($WAVEchunk !==
'WAVE') {
69 $info[
'error'][] =
'Expected "WAVE" ('.Helper::PrintHexBytes(
'WAVE').
') at offset '.$offset.
', found "'.$WAVEchunk.
'" ('.
Helper::PrintHexBytes($WAVEchunk).
') instead.';
75 $info[
'la'][
'fmt_size'] = 24;
76 if (
$info[
'la'][
'version'] >= 0.3) {
79 $info[
'la'][
'header_size'] = 49 +
$info[
'la'][
'fmt_size'] - 24;
85 $info[
'la'][
'header_size'] = 41;
89 $fmt_chunk = substr($rawdata, $offset, 4);
90 if ($fmt_chunk !==
'fmt ') {
91 $info[
'error'][] =
'Expected "fmt " ('.Helper::PrintHexBytes(
'fmt ').
') at offset '.$offset.
', found "'.$fmt_chunk.
'" ('.
Helper::PrintHexBytes($fmt_chunk).
') instead.';
104 if (
$info[
'la'][
'channels'] == 0) {
105 $info[
'error'][] =
'Corrupt LA file: channels == zero';
112 if (
$info[
'la'][
'sample_rate'] == 0) {
113 $info[
'error'][] =
'Corrupt LA file: sample_rate == zero';
130 $info[
'la'][
'flags'][
'seekable'] = (bool) (
$info[
'la'][
'raw'][
'flags'] & 0x01);
131 if (
$info[
'la'][
'version'] >= 0.4) {
132 $info[
'la'][
'flags'][
'high_compression'] = (bool) (
$info[
'la'][
'raw'][
'flags'] & 0x02);
144 if (
$info[
'la'][
'version'] >= 0.4) {
145 $info[
'la'][
'blocksize'] = 61440;
146 $info[
'la'][
'seekevery'] = 19;
148 $info[
'la'][
'blocksize'] = 73728;
149 $info[
'la'][
'seekevery'] = 16;
152 $info[
'la'][
'seekpoint_count'] = 0;
153 if (
$info[
'la'][
'flags'][
'seekable']) {
154 $info[
'la'][
'seekpoint_count'] = floor(
$info[
'la'][
'samples'] / (
$info[
'la'][
'blocksize'] *
$info[
'la'][
'seekevery']));
156 for ($i = 0; $i < $info[
'la'][
'seekpoint_count']; $i++) {
162 if (
$info[
'la'][
'version'] >= 0.3) {
170 if (
$info[
'la'][
'footerstart'] >
$info[
'filesize']) {
171 $info[
'warning'][] =
'FooterStart value points to offset '.$info[
'la'][
'footerstart'].
' which is beyond end-of-file ('.
$info[
'filesize'].
')';
172 $info[
'la'][
'footerstart'] =
$info[
'filesize'];
178 $info[
'la'][
'footerstart'] =
$info[
'avdataend'];
182 if (
$info[
'la'][
'footerstart'] <
$info[
'avdataend']) {
184 if ($RIFF_fp = fopen($RIFFtempfilename,
'w+b')) {
186 if (
$info[
'la'][
'version'] == 0.2) {
187 $RIFFdata .= substr($rawdata, 12, 24);
189 $RIFFdata .= substr($rawdata, 16, 24);
191 if (
$info[
'la'][
'footerstart'] <
$info[
'avdataend']) {
192 fseek($this->getid3->fp,
$info[
'la'][
'footerstart'], SEEK_SET);
193 $RIFFdata .=
fread($this->getid3->fp,
$info[
'avdataend'] -
$info[
'la'][
'footerstart']);
195 $RIFFdata =
'RIFF'.Helper::LittleEndian2String(strlen($RIFFdata), 4,
false).$RIFFdata;
196 fwrite($RIFF_fp, $RIFFdata, strlen($RIFFdata));
200 $getid3_temp->openfile($RIFFtempfilename);
201 $getid3_riff =
new Riff($getid3_temp);
202 $getid3_riff->analyze();
204 if (empty($getid3_temp->info[
'error'])) {
205 $info[
'riff'] = $getid3_temp->info[
'riff'];
207 $info[
'warning'][] =
'Error parsing RIFF portion of La file: '.implode($getid3_temp->info[
'error']);
209 unset($getid3_temp, $getid3_riff);
211 unlink($RIFFtempfilename);
216 $info[
'avdataend'] =
$info[
'avdataoffset'] +
$info[
'la'][
'footerstart'];
217 $info[
'avdataoffset'] = $info[
'avdataoffset'] + $offset;
220 $info[
'la'][
'compression_ratio'] = (float) (($info[
'avdataend'] - $info[
'avdataoffset']) / $info[
'la'][
'uncompressed_size']);
221 $info[
'playtime_seconds'] = (float) ($info[
'la'][
'samples'] / $info[
'la'][
'sample_rate']) / $info[
'la'][
'channels'];
222 if ($info[
'playtime_seconds'] == 0) {
223 $info[
'error'][] =
'Corrupt LA file: playtime_seconds == zero';
228 $info[
'audio'][
'bitrate'] = ($info[
'avdataend'] - $info[
'avdataoffset']) * 8 / $info[
'playtime_seconds'];
230 $info[
'audio'][
'bits_per_sample'] = $info[
'la'][
'bits_per_sample'];
234 if (substr($rawdata, $offset, 2) ==
'LA') {
235 $info[
'error'][] =
'This version of GetId3Core() ['.$this->getid3->version().
'] does not support LA version '.substr($rawdata, $offset + 2, 1).
'.'.substr($rawdata, $offset + 3, 1).
' which this appears to be - check http://getid3.sourceforge.net for updates.';
237 $info[
'error'][] =
'Not a LA (Lossless-Audio) file';
244 $info[
'audio'][
'channels'] =
$info[
'la'][
'channels'];
245 $info[
'audio'][
'sample_rate'] = (int)
$info[
'la'][
'sample_rate'];
246 $info[
'audio'][
'encoder'] =
'LA v'.$info[
'la'][
'version'];
GetId3() by James Heinrich info@getid3.org //.
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
GetId3() by James Heinrich info@getid3.org //.
fseek($bytes, $whence=SEEK_SET)
GetId3() by James Heinrich info@getid3.org //.
static LittleEndian2Int($byteword, $signed=false)
GetId3() by James Heinrich info@getid3.org //.