<Website>

getID3

PHK Home

File: /lib/module.audio.wavpack.php

Size:14463
Storage flags:strip

<?php
















class getid3_wavpack extends getid3_handler
{

public function 
Analyze() {
$info = &$this->getid3->info;

$this->fseek($info['avdataoffset']);

while (
true) {

$wavpackheader $this->fread(32);

if (
$this->ftell() >= $info['avdataend']) {
break;
} elseif (
feof($this->getid3->fp)) {
break;
} elseif (
isset(
$info['wavpack']['blockheader']['total_samples']) &&
isset(
$info['wavpack']['blockheader']['block_samples']) &&
(
$info['wavpack']['blockheader']['total_samples'] > 0) &&
(
$info['wavpack']['blockheader']['block_samples'] > 0) &&
(!isset(
$info['wavpack']['riff_trailer_size']) || ($info['wavpack']['riff_trailer_size'] <= 0)) &&
((isset(
$info['wavpack']['config_flags']['md5_checksum']) && ($info['wavpack']['config_flags']['md5_checksum'] === false)) || !empty($info['md5_data_source']))) {
break;
}

$blockheader_offset $this->ftell() - 32;
$blockheader_magic substr($wavpackheader04);
$blockheader_size getid3_lib::LittleEndian2Int(substr($wavpackheader44));

$magic 'wvpk';
if (
$blockheader_magic != $magic) {
$info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes($magic).'" at offset '.$blockheader_offset.', found "'.getid3_lib::PrintHexBytes($blockheader_magic).'"';
switch (isset(
$info['audio']['dataformat']) ? $info['audio']['dataformat'] : '') {
case 
'wavpack':
case 
'wvc':
break;
default:
unset(
$info['fileformat']);
unset(
$info['audio']);
unset(
$info['wavpack']);
break;
}
return 
false;
}

if (empty(
$info['wavpack']['blockheader']['block_samples']) ||
empty(
$info['wavpack']['blockheader']['total_samples']) ||
(
$info['wavpack']['blockheader']['block_samples'] <= 0) ||
(
$info['wavpack']['blockheader']['total_samples'] <= 0)) {

 
 
 


 
 
 


$info['audio']['dataformat'] = 'wavpack';
$info['fileformat'] = 'wavpack';
$info['audio']['lossless'] = true;
$info['audio']['bitrate_mode'] = 'vbr';

$info['wavpack']['blockheader']['offset'] = $blockheader_offset;
$info['wavpack']['blockheader']['magic'] = $blockheader_magic;
$info['wavpack']['blockheader']['size'] = $blockheader_size;

if (
$info['wavpack']['blockheader']['size'] >= 0x100000) {
$info['error'][] = 'Expecting WavPack block size less than "0x100000", found "'.$info['wavpack']['blockheader']['size'].'" at offset '.$info['wavpack']['blockheader']['offset'];
switch (isset(
$info['audio']['dataformat']) ? $info['audio']['dataformat'] : '') {
case 
'wavpack':
case 
'wvc':
break;
default:
unset(
$info['fileformat']);
unset(
$info['audio']);
unset(
$info['wavpack']);
break;
}
return 
false;
}

$info['wavpack']['blockheader']['minor_version'] = ord($wavpackheader{8});
$info['wavpack']['blockheader']['major_version'] = ord($wavpackheader{9});

if ((
$info['wavpack']['blockheader']['major_version'] != 4) ||
((
$info['wavpack']['blockheader']['minor_version'] < 4) &&
(
$info['wavpack']['blockheader']['minor_version'] > 16))) {
$info['error'][] = 'Expecting WavPack version between "4.2" and "4.16", found version "'.$info['wavpack']['blockheader']['major_version'].'.'.$info['wavpack']['blockheader']['minor_version'].'" at offset '.$info['wavpack']['blockheader']['offset'];
switch (isset(
$info['audio']['dataformat']) ? $info['audio']['dataformat'] : '') {
case 
'wavpack':
case 
'wvc':
break;
default:
unset(
$info['fileformat']);
unset(
$info['audio']);
unset(
$info['wavpack']);
break;
}
return 
false;
}

$info['wavpack']['blockheader']['track_number'] = ord($wavpackheader{10}); 
 
$info['wavpack']['blockheader']['index_number'] = ord($wavpackheader{11}); 
 
$info['wavpack']['blockheader']['total_samples'] = getid3_lib::LittleEndian2Int(substr($wavpackheader124));
$info['wavpack']['blockheader']['block_index'] = getid3_lib::LittleEndian2Int(substr($wavpackheader164));
$info['wavpack']['blockheader']['block_samples'] = getid3_lib::LittleEndian2Int(substr($wavpackheader204));
$info['wavpack']['blockheader']['flags_raw'] = getid3_lib::LittleEndian2Int(substr($wavpackheader244));
$info['wavpack']['blockheader']['crc'] = getid3_lib::LittleEndian2Int(substr($wavpackheader284));

$info['wavpack']['blockheader']['flags']['bytes_per_sample'] = + ($info['wavpack']['blockheader']['flags_raw'] & 0x00000003);
$info['wavpack']['blockheader']['flags']['mono'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000004);
$info['wavpack']['blockheader']['flags']['hybrid'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000008);
$info['wavpack']['blockheader']['flags']['joint_stereo'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000010);
$info['wavpack']['blockheader']['flags']['cross_decorrelation'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000020);
$info['wavpack']['blockheader']['flags']['hybrid_noiseshape'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000040);
$info['wavpack']['blockheader']['flags']['ieee_32bit_float'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000080);
$info['wavpack']['blockheader']['flags']['int_32bit'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000100);
$info['wavpack']['blockheader']['flags']['hybrid_bitrate_noise'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000200);
$info['wavpack']['blockheader']['flags']['hybrid_balance_noise'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000400);
$info['wavpack']['blockheader']['flags']['multichannel_initial'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00000800);
$info['wavpack']['blockheader']['flags']['multichannel_final'] = (bool) ($info['wavpack']['blockheader']['flags_raw'] & 0x00001000);

$info['audio']['lossless'] = !$info['wavpack']['blockheader']['flags']['hybrid'];
}

while (!
feof($this->getid3->fp) && ($this->ftell() < ($blockheader_offset $blockheader_size 8))) {

$metablock = array('offset'=>$this->ftell());
$metablockheader $this->fread(2);
if (
feof($this->getid3->fp)) {
break;
}
$metablock['id'] = ord($metablockheader{0});
$metablock['function_id'] = ($metablock['id'] & 0x3F);
$metablock['function_name'] = $this->WavPackMetablockNameLookup($metablock['function_id']);


 
 
 
 
 
 
 
$metablock['non_decoder'] = (bool) ($metablock['id'] & 0x20);

$metablock['padded_data'] = (bool) ($metablock['id'] & 0x40);
$metablock['large_block'] = (bool) ($metablock['id'] & 0x80);
if (
$metablock['large_block']) {
$metablockheader .= $this->fread(2);
}
$metablock['size'] = getid3_lib::LittleEndian2Int(substr($metablockheader1)) * 2
 
$metablock['data'] = null;

if (
$metablock['size'] > 0) {

switch (
$metablock['function_id']) {
case 
0x21
 case 
0x22
 case 
0x23
 case 
0x24
 case 
0x25
 case 
0x26
 
$metablock['data'] = $this->fread($metablock['size']);

if (
$metablock['padded_data']) {

 
$metablock['size']--;
$metablock['data'] = substr($metablock['data'], 0, -1);
}
break;

case 
0x00
 case 
0x01
 case 
0x02
 case 
0x03
 case 
0x04
 case 
0x05
 case 
0x06
 case 
0x07
 case 
0x08
 case 
0x09
 case 
0x0A
 case 
0x0B
 case 
0x0C
 case 
0x0D
 
$this->fseek($metablock['offset'] + ($metablock['large_block'] ? 2) + $metablock['size']);
break;

default:
$info['warning'][] = 'Unexpected metablock type "0x'.str_pad(dechex($metablock['function_id']), 2'0'STR_PAD_LEFT).'" at offset '.$metablock['offset'];
$this->fseek($metablock['offset'] + ($metablock['large_block'] ? 2) + $metablock['size']);
break;
}

switch (
$metablock['function_id']) {
case 
0x21
 
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php'__FILE__true);
$original_wav_filesize getid3_lib::LittleEndian2Int(substr($metablock['data'], 44));

$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_riff = new getid3_riff($getid3_temp);
$getid3_riff->ParseRIFFdata($metablock['data']);
$metablock['riff'] = $getid3_temp->info['riff'];
$info['audio']['sample_rate'] = $getid3_temp->info['riff']['raw']['fmt ']['nSamplesPerSec'];
unset(
$getid3_riff$getid3_temp);

$metablock['riff']['original_filesize'] = $original_wav_filesize;
$info['wavpack']['riff_trailer_size'] = $original_wav_filesize $metablock['riff']['WAVE']['data'][0]['size'] - $metablock['riff']['header_size'];
$info['playtime_seconds'] = $info['wavpack']['blockheader']['total_samples'] / $info['audio']['sample_rate'];


 
$metablockRIFFheader $metablock['data'];
break;


case 
0x22
 
$metablockRIFFfooter $metablockRIFFheader.$metablock['data'];
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php'__FILE__true);

$startoffset $metablock['offset'] + ($metablock['large_block'] ? 2);
$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->info['avdataend'] = $info['avdataend'];

 
$getid3_riff = new getid3_riff($getid3_temp);
$metablock['riff'] = $getid3_riff->ParseRIFF($startoffset$startoffset $metablock['size']);

if (!empty(
$metablock['riff']['INFO'])) {
getid3_riff::parseComments($metablock['riff']['INFO'], $metablock['comments']);
$info['tags']['riff'] = $metablock['comments'];
}
unset(
$getid3_temp$getid3_riff);
break;


case 
0x23
 
$info['warning'][] = 'WavPack "Replay Gain" contents not yet handled by getID3() in metablock at offset '.$metablock['offset'];
break;


case 
0x24
 
$info['warning'][] = 'WavPack "Cuesheet" contents not yet handled by getID3() in metablock at offset '.$metablock['offset'];
break;


case 
0x25
 
$metablock['flags_raw'] = getid3_lib::LittleEndian2Int(substr($metablock['data'], 03));

$metablock['flags']['adobe_mode'] = (bool) ($metablock['flags_raw'] & 0x000001); 
 
$metablock['flags']['fast_flag'] = (bool) ($metablock['flags_raw'] & 0x000002); 
 
$metablock['flags']['very_fast_flag'] = (bool) ($metablock['flags_raw'] & 0x000004); 
 
$metablock['flags']['high_flag'] = (bool) ($metablock['flags_raw'] & 0x000008); 
 
$metablock['flags']['very_high_flag'] = (bool) ($metablock['flags_raw'] & 0x000010); 
 
$metablock['flags']['bitrate_kbps'] = (bool) ($metablock['flags_raw'] & 0x000020); 
 
$metablock['flags']['auto_shaping'] = (bool) ($metablock['flags_raw'] & 0x000040); 
 
$metablock['flags']['shape_override'] = (bool) ($metablock['flags_raw'] & 0x000080); 
 
$metablock['flags']['joint_override'] = (bool) ($metablock['flags_raw'] & 0x000100); 
 
$metablock['flags']['copy_time'] = (bool) ($metablock['flags_raw'] & 0x000200); 
 
$metablock['flags']['create_exe'] = (bool) ($metablock['flags_raw'] & 0x000400); 
 
$metablock['flags']['create_wvc'] = (bool) ($metablock['flags_raw'] & 0x000800); 
 
$metablock['flags']['optimize_wvc'] = (bool) ($metablock['flags_raw'] & 0x001000); 
 
$metablock['flags']['quality_mode'] = (bool) ($metablock['flags_raw'] & 0x002000); 
 
$metablock['flags']['raw_flag'] = (bool) ($metablock['flags_raw'] & 0x004000); 
 
$metablock['flags']['calc_noise'] = (bool) ($metablock['flags_raw'] & 0x008000); 
 
$metablock['flags']['lossy_mode'] = (bool) ($metablock['flags_raw'] & 0x010000); 
 
$metablock['flags']['extra_mode'] = (bool) ($metablock['flags_raw'] & 0x020000); 
 
$metablock['flags']['skip_wvx'] = (bool) ($metablock['flags_raw'] & 0x040000); 
 
$metablock['flags']['md5_checksum'] = (bool) ($metablock['flags_raw'] & 0x080000); 
 
$metablock['flags']['quiet_mode'] = (bool) ($metablock['flags_raw'] & 0x100000); 

$info['wavpack']['config_flags'] = $metablock['flags'];


$info['audio']['encoder_options'] = '';
if (
$info['wavpack']['blockheader']['flags']['hybrid']) {
$info['audio']['encoder_options'] .= ' -b???';
}
$info['audio']['encoder_options'] .= ($metablock['flags']['adobe_mode'] ? ' -a' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['optimize_wvc'] ? ' -cc' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['create_exe'] ? ' -e' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['fast_flag'] ? ' -f' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['joint_override'] ? ' -j?' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['high_flag'] ? ' -h' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['md5_checksum'] ? ' -m' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['calc_noise'] ? ' -n' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['shape_override'] ? ' -s?' '');
$info['audio']['encoder_options'] .= ($metablock['flags']['extra_mode'] ? ' -x?' '');
if (!empty(
$info['audio']['encoder_options'])) {
$info['audio']['encoder_options'] = trim($info['audio']['encoder_options']);
} elseif (isset(
$info['audio']['encoder_options'])) {
unset(
$info['audio']['encoder_options']);
}
break;


case 
0x26
 if (
strlen($metablock['data']) == 16) {
$info['md5_data_source'] = strtolower(getid3_lib::PrintHexBytes($metablock['data'], truefalsefalse));
} else {
$info['warning'][] = 'Expecting 16 bytes of WavPack "MD5 Checksum" in metablock at offset '.$metablock['offset'].', but found '.strlen($metablock['data']).' bytes';
}
break;


case 
0x00
 case 
0x01
 case 
0x02
 case 
0x03
 case 
0x04
 case 
0x05
 case 
0x06
 case 
0x07
 case 
0x08
 case 
0x09
 case 
0x0A
 case 
0x0B
 case 
0x0C
 case 
0x0D
 unset(
$metablock);
break;
}

}
if (!empty(
$metablock)) {
$info['wavpack']['metablocks'][] = $metablock;
}

}

}

$info['audio']['encoder'] = 'WavPack v'.$info['wavpack']['blockheader']['major_version'].'.'.str_pad($info['wavpack']['blockheader']['minor_version'], 2'0'STR_PAD_LEFT);
$info['audio']['bits_per_sample'] = $info['wavpack']['blockheader']['flags']['bytes_per_sample'] * 8;
$info['audio']['channels'] = ($info['wavpack']['blockheader']['flags']['mono'] ? 2);

if (!empty(
$info['playtime_seconds'])) {

$info['audio']['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];

} else {

$info['audio']['dataformat'] = 'wvc';

}

return 
true;
}


public function 
WavPackMetablockNameLookup(&$id) {
static 
$WavPackMetablockNameLookup = array(
0x00 => 'Dummy',
0x01 => 'Encoder Info',
0x02 => 'Decorrelation Terms',
0x03 => 'Decorrelation Weights',
0x04 => 'Decorrelation Samples',
0x05 => 'Entropy Variables',
0x06 => 'Hybrid Profile',
0x07 => 'Shaping Weights',
0x08 => 'Float Info',
0x09 => 'Int32 Info',
0x0A => 'WV Bitstream',
0x0B => 'WVC Bitstream',
0x0C => 'WVX Bitstream',
0x0D => 'Channel Info',
0x21 => 'RIFF header',
0x22 => 'RIFF trailer',
0x23 => 'Replay Gain',
0x24 => 'Cuesheet',
0x25 => 'Config Block',
0x26 => 'MD5 Checksum',
);
return (isset(
$WavPackMetablockNameLookup[$id]) ? $WavPackMetablockNameLookup[$id] : '');
}

}

For more information about the PHK package format: http://phk.tekwire.net