<Website>

getID3

PHK Home

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

Size:5693
Storage flags:strip

<?php
















class getid3_voc extends getid3_handler
{

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

$OriginalAVdataOffset $info['avdataoffset'];
$this->fseek($info['avdataoffset']);
$VOCheader $this->fread(26);

$magic 'Creative Voice File';
if (
substr($VOCheader019) != $magic) {
$info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes($magic).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes(substr($VOCheader019)).'"';
return 
false;
}


 
$thisfile_audio = &$info['audio'];
$info['voc'] = array();
$thisfile_voc = &$info['voc'];

$info['fileformat'] = 'voc';
$thisfile_audio['dataformat'] = 'voc';
$thisfile_audio['bitrate_mode'] = 'cbr';
$thisfile_audio['lossless'] = true;
$thisfile_audio['channels'] = 1
 
$thisfile_audio['bits_per_sample'] = 8


 
 
 
 
 
 

$thisfile_voc['header']['datablock_offset'] = getid3_lib::LittleEndian2Int(substr($VOCheader202));
$thisfile_voc['header']['minor_version'] = getid3_lib::LittleEndian2Int(substr($VOCheader221));
$thisfile_voc['header']['major_version'] = getid3_lib::LittleEndian2Int(substr($VOCheader231));

do {

$BlockOffset $this->ftell();
$BlockData $this->fread(4);
$BlockType ord($BlockData{0});
$BlockSize getid3_lib::LittleEndian2Int(substr($BlockData13));
$ThisBlock = array();

getid3_lib::safe_inc($thisfile_voc['blocktypes'][$BlockType], 1);
switch (
$BlockType) {
case 
0
 
 break;

case 
1
 
$BlockData .= $this->fread(2);
if (
$info['avdataoffset'] <= $OriginalAVdataOffset) {
$info['avdataoffset'] = $this->ftell();
}
$this->fseek($BlockSize 2SEEK_CUR);

$ThisBlock['sample_rate_id'] = getid3_lib::LittleEndian2Int(substr($BlockData41));
$ThisBlock['compression_type'] = getid3_lib::LittleEndian2Int(substr($BlockData51));

$ThisBlock['compression_name'] = $this->VOCcompressionTypeLookup($ThisBlock['compression_type']);
if (
$ThisBlock['compression_type'] <= 3) {
$thisfile_voc['compressed_bits_per_sample'] = getid3_lib::CastAsInt(str_replace('-bit'''$ThisBlock['compression_name']));
}


 if (empty(
$thisfile_audio['sample_rate'])) {

 
$thisfile_audio['sample_rate'] = getid3_lib::trunc((1000000 / (256 $ThisBlock['sample_rate_id'])) / $thisfile_audio['channels']);
}
break;

case 
2
 case 
3
 case 
4
 case 
6
 case 
7
 
 
$this->fseek($BlockSizeSEEK_CUR);
break;

case 
8
 
$BlockData .= $this->fread(4);


 
 
 
$ThisBlock['time_constant'] = getid3_lib::LittleEndian2Int(substr($BlockData42));
$ThisBlock['pack_method'] = getid3_lib::LittleEndian2Int(substr($BlockData61));
$ThisBlock['stereo'] = (bool) getid3_lib::LittleEndian2Int(substr($BlockData71));

$thisfile_audio['channels'] = ($ThisBlock['stereo'] ? 1);
$thisfile_audio['sample_rate'] = getid3_lib::trunc((256000000 / (65536 $ThisBlock['time_constant'])) / $thisfile_audio['channels']);
break;

case 
9
 
$BlockData .= $this->fread(12);
if (
$info['avdataoffset'] <= $OriginalAVdataOffset) {
$info['avdataoffset'] = $this->ftell();
}
$this->fseek($BlockSize 12SEEK_CUR);

$ThisBlock['sample_rate'] = getid3_lib::LittleEndian2Int(substr($BlockData44));
$ThisBlock['bits_per_sample'] = getid3_lib::LittleEndian2Int(substr($BlockData81));
$ThisBlock['channels'] = getid3_lib::LittleEndian2Int(substr($BlockData91));
$ThisBlock['wFormat'] = getid3_lib::LittleEndian2Int(substr($BlockData102));

$ThisBlock['compression_name'] = $this->VOCwFormatLookup($ThisBlock['wFormat']);
if (
$this->VOCwFormatActualBitsPerSampleLookup($ThisBlock['wFormat'])) {
$thisfile_voc['compressed_bits_per_sample'] = $this->VOCwFormatActualBitsPerSampleLookup($ThisBlock['wFormat']);
}

$thisfile_audio['sample_rate'] = $ThisBlock['sample_rate'];
$thisfile_audio['bits_per_sample'] = $ThisBlock['bits_per_sample'];
$thisfile_audio['channels'] = $ThisBlock['channels'];
break;

default:
$info['warning'][] = 'Unhandled block type "'.$BlockType.'" at offset '.$BlockOffset;
$this->fseek($BlockSizeSEEK_CUR);
break;
}

if (!empty(
$ThisBlock)) {
$ThisBlock['block_offset'] = $BlockOffset;
$ThisBlock['block_size'] = $BlockSize;
$ThisBlock['block_type_id'] = $BlockType;
$thisfile_voc['blocks'][] = $ThisBlock;
}

} while (!
feof($this->getid3->fp) && ($BlockType != 0));


 
$this->fseek(-3SEEK_CUR);

ksort($thisfile_voc['blocktypes']);

if (!empty(
$thisfile_voc['compressed_bits_per_sample'])) {
$info['playtime_seconds'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / ($thisfile_voc['compressed_bits_per_sample'] * $thisfile_audio['channels'] * $thisfile_audio['sample_rate']);
$thisfile_audio['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
}

return 
true;
}

public function 
VOCcompressionTypeLookup($index) {
static 
$VOCcompressionTypeLookup = array(
=> '8-bit',
=> '4-bit',
=> '2.6-bit',
=> '2-bit'
);
return (isset(
$VOCcompressionTypeLookup[$index]) ? $VOCcompressionTypeLookup[$index] : 'Multi DAC ('.($index 3).') channels');
}

public function 
VOCwFormatLookup($index) {
static 
$VOCwFormatLookup = array(
0x0000 => '8-bit unsigned PCM',
0x0001 => 'Creative 8-bit to 4-bit ADPCM',
0x0002 => 'Creative 8-bit to 3-bit ADPCM',
0x0003 => 'Creative 8-bit to 2-bit ADPCM',
0x0004 => '16-bit signed PCM',
0x0006 => 'CCITT a-Law',
0x0007 => 'CCITT u-Law',
0x2000 => 'Creative 16-bit to 4-bit ADPCM'
);
return (isset(
$VOCwFormatLookup[$index]) ? $VOCwFormatLookup[$index] : false);
}

public function 
VOCwFormatActualBitsPerSampleLookup($index) {
static 
$VOCwFormatLookup = array(
0x0000 => 8,
0x0001 => 4,
0x0002 => 3,
0x0003 => 2,
0x0004 => 16,
0x0006 => 8,
0x0007 => 8,
0x2000 => 4
);
return (isset(
$VOCwFormatLookup[$index]) ? $VOCwFormatLookup[$index] : false);
}

}

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