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.shorten.php // 12// module for analyzing Shorten Audio files // 13// dependencies: NONE // 14// /// 15///////////////////////////////////////////////////////////////// 16 17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers 18 exit; 19} 20 21class getid3_rkau extends getid3_handler 22{ 23 /** 24 * @return bool 25 */ 26 public function Analyze() { 27 $info = &$this->getid3->info; 28 29 $this->fseek($info['avdataoffset']); 30 $RKAUHeader = $this->fread(20); 31 $magic = 'RKA'; 32 if (substr($RKAUHeader, 0, 3) != $magic) { 33 $this->error('Expecting "'.getid3_lib::PrintHexBytes($magic).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes(substr($RKAUHeader, 0, 3)).'"'); 34 return false; 35 } 36 37 $info['fileformat'] = 'rkau'; 38 $info['audio']['dataformat'] = 'rkau'; 39 $info['audio']['bitrate_mode'] = 'vbr'; 40 41 $info['rkau']['raw']['version'] = getid3_lib::LittleEndian2Int(substr($RKAUHeader, 3, 1)); 42 $info['rkau']['version'] = '1.'.str_pad($info['rkau']['raw']['version'] & 0x0F, 2, '0', STR_PAD_LEFT); 43 if (($info['rkau']['version'] > 1.07) || ($info['rkau']['version'] < 1.06)) { 44 $this->error('This version of getID3() ['.$this->getid3->version().'] can only parse RKAU files v1.06 and 1.07 (this file is v'.$info['rkau']['version'].')'); 45 unset($info['rkau']); 46 return false; 47 } 48 49 $info['rkau']['source_bytes'] = getid3_lib::LittleEndian2Int(substr($RKAUHeader, 4, 4)); 50 $info['rkau']['sample_rate'] = getid3_lib::LittleEndian2Int(substr($RKAUHeader, 8, 4)); 51 $info['rkau']['channels'] = getid3_lib::LittleEndian2Int(substr($RKAUHeader, 12, 1)); 52 $info['rkau']['bits_per_sample'] = getid3_lib::LittleEndian2Int(substr($RKAUHeader, 13, 1)); 53 54 $info['rkau']['raw']['quality'] = getid3_lib::LittleEndian2Int(substr($RKAUHeader, 14, 1)); 55 $this->RKAUqualityLookup($info['rkau']); 56 57 $info['rkau']['raw']['flags'] = getid3_lib::LittleEndian2Int(substr($RKAUHeader, 15, 1)); 58 $info['rkau']['flags']['joint_stereo'] = !($info['rkau']['raw']['flags'] & 0x01); 59 $info['rkau']['flags']['streaming'] = (bool) ($info['rkau']['raw']['flags'] & 0x02); 60 $info['rkau']['flags']['vrq_lossy_mode'] = (bool) ($info['rkau']['raw']['flags'] & 0x04); 61 62 if ($info['rkau']['flags']['streaming']) { 63 $info['avdataoffset'] += 20; 64 $info['rkau']['compressed_bytes'] = getid3_lib::LittleEndian2Int(substr($RKAUHeader, 16, 4)); 65 } else { 66 $info['avdataoffset'] += 16; 67 $info['rkau']['compressed_bytes'] = $info['avdataend'] - $info['avdataoffset'] - 1; 68 } 69 // Note: compressed_bytes does not always equal what appears to be the actual number of compressed bytes, 70 // sometimes it's more, sometimes less. No idea why(?) 71 72 $info['audio']['lossless'] = $info['rkau']['lossless']; 73 $info['audio']['channels'] = $info['rkau']['channels']; 74 $info['audio']['bits_per_sample'] = $info['rkau']['bits_per_sample']; 75 $info['audio']['sample_rate'] = $info['rkau']['sample_rate']; 76 77 $info['playtime_seconds'] = $info['rkau']['source_bytes'] / ($info['rkau']['sample_rate'] * $info['rkau']['channels'] * ($info['rkau']['bits_per_sample'] / 8)); 78 $info['audio']['bitrate'] = ($info['rkau']['compressed_bytes'] * 8) / $info['playtime_seconds']; 79 80 return true; 81 82 } 83 84 /** 85 * @param array $RKAUdata 86 * 87 * @return bool 88 */ 89 public function RKAUqualityLookup(&$RKAUdata) { 90 $level = ($RKAUdata['raw']['quality'] & 0xF0) >> 4; 91 $quality = $RKAUdata['raw']['quality'] & 0x0F; 92 93 $RKAUdata['lossless'] = (($quality == 0) ? true : false); 94 $RKAUdata['compression_level'] = $level + 1; 95 if (!$RKAUdata['lossless']) { 96 $RKAUdata['quality_setting'] = $quality; 97 } 98 99 return true; 100 } 101 102} 103