[ Index ]

WordPress Cross Reference

title

Body

[close]

/wp-includes/ID3/ -> module.audio.dts.php (source)

   1  <?php
   2  /////////////////////////////////////////////////////////////////
   3  /// getID3() by James Heinrich <info@getid3.org>               //
   4  //  available at http://getid3.sourceforge.net                 //
   5  //            or http://www.getid3.org                         //
   6  /////////////////////////////////////////////////////////////////
   7  // See readme.txt for more details                             //
   8  /////////////////////////////////////////////////////////////////
   9  //                                                             //
  10  // module.audio.dts.php                                        //
  11  // module for analyzing DTS Audio files                        //
  12  // dependencies: NONE                                          //
  13  //                                                             //
  14  /////////////////////////////////////////////////////////////////
  15  
  16  
  17  /**
  18  * @tutorial http://wiki.multimedia.cx/index.php?title=DTS
  19  */
  20  class getid3_dts extends getid3_handler
  21  {
  22      /**
  23      * Default DTS syncword used in native .cpt or .dts formats
  24      */
  25      const syncword = "\x7F\xFE\x80\x01";
  26  
  27      private $readBinDataOffset = 0;
  28  
  29      /**
  30      * Possible syncwords indicating bitstream encoding
  31      */
  32      public static $syncwords = array(
  33          0 => "\x7F\xFE\x80\x01",  // raw big-endian
  34          1 => "\xFE\x7F\x01\x80",  // raw little-endian
  35          2 => "\x1F\xFF\xE8\x00",  // 14-bit big-endian
  36          3 => "\xFF\x1F\x00\xE8"); // 14-bit little-endian
  37  
  38  	public function Analyze() {
  39          $info = &$this->getid3->info;
  40          $info['fileformat'] = 'dts';
  41  
  42          $this->fseek($info['avdataoffset']);
  43          $DTSheader = $this->fread(20); // we only need 2 words magic + 6 words frame header, but these words may be normal 16-bit words OR 14-bit words with 2 highest bits set to zero, so 8 words can be either 8*16/8 = 16 bytes OR 8*16*(16/14)/8 = 18.3 bytes
  44  
  45          // check syncword
  46          $sync = substr($DTSheader, 0, 4);
  47          if (($encoding = array_search($sync, self::$syncwords)) !== false) {
  48  
  49              $info['dts']['raw']['magic'] = $sync;
  50              $this->readBinDataOffset = 32;
  51  
  52          } elseif ($this->isDependencyFor('matroska')) {
  53  
  54              // Matroska contains DTS without syncword encoded as raw big-endian format
  55              $encoding = 0;
  56              $this->readBinDataOffset = 0;
  57  
  58          } else {
  59  
  60              unset($info['fileformat']);
  61              return $this->error('Expecting "'.implode('| ', array_map('getid3_lib::PrintHexBytes', self::$syncwords)).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($sync).'"');
  62  
  63          }
  64  
  65          // decode header
  66          $fhBS = '';
  67          for ($word_offset = 0; $word_offset <= strlen($DTSheader); $word_offset += 2) {
  68              switch ($encoding) {
  69                  case 0: // raw big-endian
  70                      $fhBS .=        getid3_lib::BigEndian2Bin(       substr($DTSheader, $word_offset, 2) );
  71                      break;
  72                  case 1: // raw little-endian
  73                      $fhBS .=        getid3_lib::BigEndian2Bin(strrev(substr($DTSheader, $word_offset, 2)));
  74                      break;
  75                  case 2: // 14-bit big-endian
  76                      $fhBS .= substr(getid3_lib::BigEndian2Bin(       substr($DTSheader, $word_offset, 2) ), 2, 14);
  77                      break;
  78                  case 3: // 14-bit little-endian
  79                      $fhBS .= substr(getid3_lib::BigEndian2Bin(strrev(substr($DTSheader, $word_offset, 2))), 2, 14);
  80                      break;
  81              }
  82          }
  83  
  84          $info['dts']['raw']['frame_type']             =        $this->readBinData($fhBS,  1);
  85          $info['dts']['raw']['deficit_samples']        =        $this->readBinData($fhBS,  5);
  86          $info['dts']['flags']['crc_present']          = (bool) $this->readBinData($fhBS,  1);
  87          $info['dts']['raw']['pcm_sample_blocks']      =        $this->readBinData($fhBS,  7);
  88          $info['dts']['raw']['frame_byte_size']        =        $this->readBinData($fhBS, 14);
  89          $info['dts']['raw']['channel_arrangement']    =        $this->readBinData($fhBS,  6);
  90          $info['dts']['raw']['sample_frequency']       =        $this->readBinData($fhBS,  4);
  91          $info['dts']['raw']['bitrate']                =        $this->readBinData($fhBS,  5);
  92          $info['dts']['flags']['embedded_downmix']     = (bool) $this->readBinData($fhBS,  1);
  93          $info['dts']['flags']['dynamicrange']         = (bool) $this->readBinData($fhBS,  1);
  94          $info['dts']['flags']['timestamp']            = (bool) $this->readBinData($fhBS,  1);
  95          $info['dts']['flags']['auxdata']              = (bool) $this->readBinData($fhBS,  1);
  96          $info['dts']['flags']['hdcd']                 = (bool) $this->readBinData($fhBS,  1);
  97          $info['dts']['raw']['extension_audio']        =        $this->readBinData($fhBS,  3);
  98          $info['dts']['flags']['extended_coding']      = (bool) $this->readBinData($fhBS,  1);
  99          $info['dts']['flags']['audio_sync_insertion'] = (bool) $this->readBinData($fhBS,  1);
 100          $info['dts']['raw']['lfe_effects']            =        $this->readBinData($fhBS,  2);
 101          $info['dts']['flags']['predictor_history']    = (bool) $this->readBinData($fhBS,  1);
 102          if ($info['dts']['flags']['crc_present']) {
 103              $info['dts']['raw']['crc16']              =        $this->readBinData($fhBS, 16);
 104          }
 105          $info['dts']['flags']['mri_perfect_reconst']  = (bool) $this->readBinData($fhBS,  1);
 106          $info['dts']['raw']['encoder_soft_version']   =        $this->readBinData($fhBS,  4);
 107          $info['dts']['raw']['copy_history']           =        $this->readBinData($fhBS,  2);
 108          $info['dts']['raw']['bits_per_sample']        =        $this->readBinData($fhBS,  2);
 109          $info['dts']['flags']['surround_es']          = (bool) $this->readBinData($fhBS,  1);
 110          $info['dts']['flags']['front_sum_diff']       = (bool) $this->readBinData($fhBS,  1);
 111          $info['dts']['flags']['surround_sum_diff']    = (bool) $this->readBinData($fhBS,  1);
 112          $info['dts']['raw']['dialog_normalization']   =        $this->readBinData($fhBS,  4);
 113  
 114  
 115          $info['dts']['bitrate']              = self::bitrateLookup($info['dts']['raw']['bitrate']);
 116          $info['dts']['bits_per_sample']      = self::bitPerSampleLookup($info['dts']['raw']['bits_per_sample']);
 117          $info['dts']['sample_rate']          = self::sampleRateLookup($info['dts']['raw']['sample_frequency']);
 118          $info['dts']['dialog_normalization'] = self::dialogNormalization($info['dts']['raw']['dialog_normalization'], $info['dts']['raw']['encoder_soft_version']);
 119          $info['dts']['flags']['lossless']    = (($info['dts']['raw']['bitrate'] == 31) ? true  : false);
 120          $info['dts']['bitrate_mode']         = (($info['dts']['raw']['bitrate'] == 30) ? 'vbr' : 'cbr');
 121          $info['dts']['channels']             = self::numChannelsLookup($info['dts']['raw']['channel_arrangement']);
 122          $info['dts']['channel_arrangement']  = self::channelArrangementLookup($info['dts']['raw']['channel_arrangement']);
 123  
 124          $info['audio']['dataformat']          = 'dts';
 125          $info['audio']['lossless']            = $info['dts']['flags']['lossless'];
 126          $info['audio']['bitrate_mode']        = $info['dts']['bitrate_mode'];
 127          $info['audio']['bits_per_sample']     = $info['dts']['bits_per_sample'];
 128          $info['audio']['sample_rate']         = $info['dts']['sample_rate'];
 129          $info['audio']['channels']            = $info['dts']['channels'];
 130          $info['audio']['bitrate']             = $info['dts']['bitrate'];
 131          if (isset($info['avdataend']) && !empty($info['dts']['bitrate']) && is_numeric($info['dts']['bitrate'])) {
 132              $info['playtime_seconds']         = ($info['avdataend'] - $info['avdataoffset']) / ($info['dts']['bitrate'] / 8);
 133              if (($encoding == 2) || ($encoding == 3)) {
 134                  // 14-bit data packed into 16-bit words, so the playtime is wrong because only (14/16) of the bytes in the data portion of the file are used at the specified bitrate
 135                  $info['playtime_seconds'] *= (14 / 16);
 136              }
 137          }
 138          return true;
 139      }
 140  
 141  	private function readBinData($bin, $length) {
 142          $data = substr($bin, $this->readBinDataOffset, $length);
 143          $this->readBinDataOffset += $length;
 144  
 145          return bindec($data);
 146      }
 147  
 148  	public static function bitrateLookup($index) {
 149          static $lookup = array(
 150              0  => 32000,
 151              1  => 56000,
 152              2  => 64000,
 153              3  => 96000,
 154              4  => 112000,
 155              5  => 128000,
 156              6  => 192000,
 157              7  => 224000,
 158              8  => 256000,
 159              9  => 320000,
 160              10 => 384000,
 161              11 => 448000,
 162              12 => 512000,
 163              13 => 576000,
 164              14 => 640000,
 165              15 => 768000,
 166              16 => 960000,
 167              17 => 1024000,
 168              18 => 1152000,
 169              19 => 1280000,
 170              20 => 1344000,
 171              21 => 1408000,
 172              22 => 1411200,
 173              23 => 1472000,
 174              24 => 1536000,
 175              25 => 1920000,
 176              26 => 2048000,
 177              27 => 3072000,
 178              28 => 3840000,
 179              29 => 'open',
 180              30 => 'variable',
 181              31 => 'lossless',
 182          );
 183          return (isset($lookup[$index]) ? $lookup[$index] : false);
 184      }
 185  
 186  	public static function sampleRateLookup($index) {
 187          static $lookup = array(
 188              0  => 'invalid',
 189              1  => 8000,
 190              2  => 16000,
 191              3  => 32000,
 192              4  => 'invalid',
 193              5  => 'invalid',
 194              6  => 11025,
 195              7  => 22050,
 196              8  => 44100,
 197              9  => 'invalid',
 198              10 => 'invalid',
 199              11 => 12000,
 200              12 => 24000,
 201              13 => 48000,
 202              14 => 'invalid',
 203              15 => 'invalid',
 204          );
 205          return (isset($lookup[$index]) ? $lookup[$index] : false);
 206      }
 207  
 208  	public static function bitPerSampleLookup($index) {
 209          static $lookup = array(
 210              0  => 16,
 211              1  => 20,
 212              2  => 24,
 213              3  => 24,
 214          );
 215          return (isset($lookup[$index]) ? $lookup[$index] : false);
 216      }
 217  
 218  	public static function numChannelsLookup($index) {
 219          switch ($index) {
 220              case 0:
 221                  return 1;
 222                  break;
 223              case 1:
 224              case 2:
 225              case 3:
 226              case 4:
 227                  return 2;
 228                  break;
 229              case 5:
 230              case 6:
 231                  return 3;
 232                  break;
 233              case 7:
 234              case 8:
 235                  return 4;
 236                  break;
 237              case 9:
 238                  return 5;
 239                  break;
 240              case 10:
 241              case 11:
 242              case 12:
 243                  return 6;
 244                  break;
 245              case 13:
 246                  return 7;
 247                  break;
 248              case 14:
 249              case 15:
 250                  return 8;
 251                  break;
 252          }
 253          return false;
 254      }
 255  
 256  	public static function channelArrangementLookup($index) {
 257          static $lookup = array(
 258              0  => 'A',
 259              1  => 'A + B (dual mono)',
 260              2  => 'L + R (stereo)',
 261              3  => '(L+R) + (L-R) (sum-difference)',
 262              4  => 'LT + RT (left and right total)',
 263              5  => 'C + L + R',
 264              6  => 'L + R + S',
 265              7  => 'C + L + R + S',
 266              8  => 'L + R + SL + SR',
 267              9  => 'C + L + R + SL + SR',
 268              10 => 'CL + CR + L + R + SL + SR',
 269              11 => 'C + L + R+ LR + RR + OV',
 270              12 => 'CF + CR + LF + RF + LR + RR',
 271              13 => 'CL + C + CR + L + R + SL + SR',
 272              14 => 'CL + CR + L + R + SL1 + SL2 + SR1 + SR2',
 273              15 => 'CL + C+ CR + L + R + SL + S + SR',
 274          );
 275          return (isset($lookup[$index]) ? $lookup[$index] : 'user-defined');
 276      }
 277  
 278  	public static function dialogNormalization($index, $version) {
 279          switch ($version) {
 280              case 7:
 281                  return 0 - $index;
 282                  break;
 283              case 6:
 284                  return 0 - 16 - $index;
 285                  break;
 286          }
 287          return false;
 288      }
 289  
 290  }


Generated: Tue Mar 25 01:41:18 2014 WordPress honlapkészítés: online1.hu