Public Member Functions

getid3_shorten Class Reference

getID3() by James Heinrich <info@getid3.org> // More...

Public Member Functions

 getid3_shorten (&$fd, &$ThisFileInfo)

Detailed Description

getID3() by James Heinrich <info@getid3.org> //

Definition at line 17 of file module.audio.shorten.php.


Member Function Documentation

getid3_shorten::getid3_shorten ( &$  fd,
&$  ThisFileInfo 
)

Definition at line 20 of file module.audio.shorten.php.

References getid3_lib::IncludeDependency(), getid3_lib::LittleEndian2Int(), and getid3_riff::RIFFparseWAVEFORMATex().

                                                      {

                fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);

                $ShortenHeader = fread($fd, 8);
                if (substr($ShortenHeader, 0, 4) != 'ajkg') {
                        $ThisFileInfo['error'][] = 'Expecting "ajkg" at offset '.$ThisFileInfo['avdataoffset'].', found "'.substr($ShortenHeader, 0, 4).'"';
                        return false;
                }
                $ThisFileInfo['fileformat']            = 'shn';
                $ThisFileInfo['audio']['dataformat']   = 'shn';
                $ThisFileInfo['audio']['lossless']     = true;
                $ThisFileInfo['audio']['bitrate_mode'] = 'vbr';

                $ThisFileInfo['shn']['version'] = getid3_lib::LittleEndian2Int(substr($ShortenHeader, 4, 1));

                fseek($fd, $ThisFileInfo['avdataend'] - 12, SEEK_SET);
                $SeekTableSignatureTest = fread($fd, 12);
                $ThisFileInfo['shn']['seektable']['present'] = (bool) (substr($SeekTableSignatureTest, 4, 8) == 'SHNAMPSK');
                if ($ThisFileInfo['shn']['seektable']['present']) {
                        $ThisFileInfo['shn']['seektable']['length'] = getid3_lib::LittleEndian2Int(substr($SeekTableSignatureTest, 0, 4));
                        $ThisFileInfo['shn']['seektable']['offset'] = $ThisFileInfo['avdataend'] - $ThisFileInfo['shn']['seektable']['length'];
                        fseek($fd, $ThisFileInfo['shn']['seektable']['offset'], SEEK_SET);
                        $SeekTableMagic = fread($fd, 4);
                        if ($SeekTableMagic != 'SEEK') {

                                $ThisFileInfo['error'][] = 'Expecting "SEEK" at offset '.$ThisFileInfo['shn']['seektable']['offset'].', found "'.$SeekTableMagic.'"';
                                return false;

                        } else {

                                // typedef struct tag_TSeekEntry
                                // {
                                //   unsigned long SampleNumber;
                                //   unsigned long SHNFileByteOffset;
                                //   unsigned long SHNLastBufferReadPosition;
                                //   unsigned short SHNByteGet;
                                //   unsigned short SHNBufferOffset;
                                //   unsigned short SHNFileBitOffset;
                                //   unsigned long SHNGBuffer;
                                //   unsigned short SHNBitShift;
                                //   long CBuf0[3];
                                //   long CBuf1[3];
                                //   long Offset0[4];
                                //   long Offset1[4];
                                // }TSeekEntry;

                                $SeekTableData = fread($fd, $ThisFileInfo['shn']['seektable']['length'] - 16);
                                $ThisFileInfo['shn']['seektable']['entry_count'] = floor(strlen($SeekTableData) / 80);
                                //$ThisFileInfo['shn']['seektable']['entries'] = array();
                                //$SeekTableOffset = 0;
                                //for ($i = 0; $i < $ThisFileInfo['shn']['seektable']['entry_count']; $i++) {
                                //      $SeekTableEntry['sample_number'] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
                                //      $SeekTableOffset += 4;
                                //      $SeekTableEntry['shn_file_byte_offset'] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
                                //      $SeekTableOffset += 4;
                                //      $SeekTableEntry['shn_last_buffer_read_position'] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
                                //      $SeekTableOffset += 4;
                                //      $SeekTableEntry['shn_byte_get'] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
                                //      $SeekTableOffset += 2;
                                //      $SeekTableEntry['shn_buffer_offset'] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
                                //      $SeekTableOffset += 2;
                                //      $SeekTableEntry['shn_file_bit_offset'] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
                                //      $SeekTableOffset += 2;
                                //      $SeekTableEntry['shn_gbuffer'] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
                                //      $SeekTableOffset += 4;
                                //      $SeekTableEntry['shn_bit_shift'] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 2));
                                //      $SeekTableOffset += 2;
                                //      for ($j = 0; $j < 3; $j++) {
                                //              $SeekTableEntry['cbuf0'][$j] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
                                //              $SeekTableOffset += 4;
                                //      }
                                //      for ($j = 0; $j < 3; $j++) {
                                //              $SeekTableEntry['cbuf1'][$j] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
                                //              $SeekTableOffset += 4;
                                //      }
                                //      for ($j = 0; $j < 4; $j++) {
                                //              $SeekTableEntry['offset0'][$j] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
                                //              $SeekTableOffset += 4;
                                //      }
                                //      for ($j = 0; $j < 4; $j++) {
                                //              $SeekTableEntry['offset1'][$j] = getid3_lib::LittleEndian2Int(substr($SeekTableData, $SeekTableOffset, 4));
                                //              $SeekTableOffset += 4;
                                //      }
                //
                                //      $ThisFileInfo['shn']['seektable']['entries'][] = $SeekTableEntry;
                                //}

                        }

                }

                if ((bool) ini_get('safe_mode')) {
                        $ThisFileInfo['error'][] = 'PHP running in Safe Mode - backtick operator not available, cannot run shntool to analyze Shorten files';
                        return false;
                }

                if (GETID3_OS_ISWINDOWS) {

                        $RequiredFiles = array('shorten.exe', 'cygwin1.dll', 'head.exe');
                        foreach ($RequiredFiles as $required_file) {
                                if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
                                        $ThisFileInfo['error'][] = GETID3_HELPERAPPSDIR.$required_file.' does not exist';
                                        return false;
                                }
                        }
                        $commandline = GETID3_HELPERAPPSDIR.'shorten.exe -x "'.$ThisFileInfo['filenamepath'].'" - | '.GETID3_HELPERAPPSDIR.'head.exe -c 44';
                        $commandline = str_replace('/', '\\', $commandline);

                } else {

                static $shorten_present;
                if (!isset($shorten_present)) {
                $shorten_present = file_exists('/usr/local/bin/shorten') || `which shorten`;
            }
            if (!$shorten_present) {
                $ThisFileInfo['error'][] = 'shorten binary was not found in path or /usr/local/bin';
                return false;
            }
            $commandline = (file_exists('/usr/local/bin/shorten') ? '/usr/local/bin/' : '' ) . 'shorten -x '.escapeshellarg($ThisFileInfo['filenamepath']).' - | head -c 44';

                }

                $output = `$commandline`;

                if (!empty($output) && (substr($output, 12, 4) == 'fmt ')) {

                        getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);

                        $DecodedWAVFORMATEX = getid3_riff::RIFFparseWAVEFORMATex(substr($output, 20, 16));
                        $ThisFileInfo['audio']['channels']        = $DecodedWAVFORMATEX['channels'];
                        $ThisFileInfo['audio']['bits_per_sample'] = $DecodedWAVFORMATEX['bits_per_sample'];
                        $ThisFileInfo['audio']['sample_rate']     = $DecodedWAVFORMATEX['sample_rate'];

                        if (substr($output, 36, 4) == 'data') {

                                $ThisFileInfo['playtime_seconds'] = getid3_lib::LittleEndian2Int(substr($output, 40, 4)) / $DecodedWAVFORMATEX['raw']['nAvgBytesPerSec'];

                        } else {

                                $ThisFileInfo['error'][] = 'shorten failed to decode DATA chunk to expected location, cannot determine playtime';
                                return false;

                        }

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

                } else {

                        $ThisFileInfo['error'][] = 'shorten failed to decode file to WAV for parsing';
                        return false;

                }

                return true;
        }

Here is the call graph for this function:


The documentation for this class was generated from the following file: