22 fseek($fd, $ThisFileInfo[
'avdataoffset'], SEEK_SET);
24 $ShortenHeader = fread($fd, 8);
25 if (substr($ShortenHeader, 0, 4) !=
'ajkg') {
26 $ThisFileInfo[
'error'][] =
'Expecting "ajkg" at offset '.$ThisFileInfo[
'avdataoffset'].
', found "'.substr($ShortenHeader, 0, 4).
'"';
29 $ThisFileInfo[
'fileformat'] =
'shn';
30 $ThisFileInfo[
'audio'][
'dataformat'] =
'shn';
31 $ThisFileInfo[
'audio'][
'lossless'] =
true;
32 $ThisFileInfo[
'audio'][
'bitrate_mode'] =
'vbr';
36 fseek($fd, $ThisFileInfo[
'avdataend'] - 12, SEEK_SET);
37 $SeekTableSignatureTest = fread($fd, 12);
38 $ThisFileInfo[
'shn'][
'seektable'][
'present'] = (bool) (substr($SeekTableSignatureTest, 4, 8) ==
'SHNAMPSK');
39 if ($ThisFileInfo[
'shn'][
'seektable'][
'present']) {
41 $ThisFileInfo[
'shn'][
'seektable'][
'offset'] = $ThisFileInfo[
'avdataend'] - $ThisFileInfo[
'shn'][
'seektable'][
'length'];
42 fseek($fd, $ThisFileInfo[
'shn'][
'seektable'][
'offset'], SEEK_SET);
43 $SeekTableMagic = fread($fd, 4);
44 if ($SeekTableMagic !=
'SEEK') {
46 $ThisFileInfo[
'error'][] =
'Expecting "SEEK" at offset '.$ThisFileInfo[
'shn'][
'seektable'][
'offset'].
', found "'.$SeekTableMagic.
'"';
67 $SeekTableData = fread($fd, $ThisFileInfo[
'shn'][
'seektable'][
'length'] - 16);
68 $ThisFileInfo[
'shn'][
'seektable'][
'entry_count'] = floor(strlen($SeekTableData) / 80);
112 if ((
bool) ini_get(
'safe_mode')) {
113 $ThisFileInfo[
'error'][] =
'PHP running in Safe Mode - backtick operator not available, cannot run shntool to analyze Shorten files';
117 if (GETID3_OS_ISWINDOWS) {
119 $RequiredFiles = array(
'shorten.exe',
'cygwin1.dll',
'head.exe');
120 foreach ($RequiredFiles as $required_file) {
121 if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
122 $ThisFileInfo[
'error'][] = GETID3_HELPERAPPSDIR.$required_file.
' does not exist';
126 $commandline = GETID3_HELPERAPPSDIR.
'shorten.exe -x "'.$ThisFileInfo[
'filenamepath'].
'" - | '.GETID3_HELPERAPPSDIR.
'head.exe -c 44';
127 $commandline = str_replace(
'/',
'\\', $commandline);
131 static $shorten_present;
132 if (!isset($shorten_present)) {
133 $shorten_present = file_exists(
'/usr/local/bin/shorten') || `which shorten`;
135 if (!$shorten_present) {
136 $ThisFileInfo[
'error'][] =
'shorten binary was not found in path or /usr/local/bin';
139 $commandline = (file_exists(
'/usr/local/bin/shorten') ?
'/usr/local/bin/' :
'' ) .
'shorten -x '.escapeshellarg($ThisFileInfo[
'filenamepath']).
' - | head -c 44';
143 $output = `$commandline`;
145 if (!empty($output) && (substr($output, 12, 4) ==
'fmt ')) {
150 $ThisFileInfo[
'audio'][
'channels'] = $DecodedWAVFORMATEX[
'channels'];
151 $ThisFileInfo[
'audio'][
'bits_per_sample'] = $DecodedWAVFORMATEX[
'bits_per_sample'];
152 $ThisFileInfo[
'audio'][
'sample_rate'] = $DecodedWAVFORMATEX[
'sample_rate'];
154 if (substr($output, 36, 4) ==
'data') {
156 $ThisFileInfo[
'playtime_seconds'] =
getid3_lib::LittleEndian2Int(substr($output, 40, 4)) / $DecodedWAVFORMATEX[
'raw'][
'nAvgBytesPerSec'];
160 $ThisFileInfo[
'error'][] =
'shorten failed to decode DATA chunk to expected location, cannot determine playtime';
165 $ThisFileInfo[
'audio'][
'bitrate'] = (($ThisFileInfo[
'avdataend'] - $ThisFileInfo[
'avdataoffset']) / $ThisFileInfo[
'playtime_seconds']) * 8;
169 $ThisFileInfo[
'error'][] =
'shorten failed to decode file to WAV for parsing';