[ Index ]

PHP Cross Reference of WordPress

title

Body

[close]

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

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


Generated: Sun Sep 15 01:00:03 2019 Cross-referenced by PHPXref 0.7.1