File indexing completed on 2025-02-02 05:44:55
0001 <?php 0002 ///////////////////////////////////////////////////////////////// 0003 /// getID3() by James Heinrich <info@getid3.org> // 0004 // available at http://getid3.sourceforge.net // 0005 // or http://www.getid3.org // 0006 // also https://github.com/JamesHeinrich/getID3 // 0007 ///////////////////////////////////////////////////////////////// 0008 // See readme.txt for more details // 0009 ///////////////////////////////////////////////////////////////// 0010 // // 0011 // module.misc.cue.php // 0012 // module for analyzing CUEsheet files // 0013 // dependencies: NONE // 0014 // // 0015 ///////////////////////////////////////////////////////////////// 0016 // // 0017 // Module originally written [2009-Mar-25] by // 0018 // Nigel Barnes <ngbarnesĂhotmail*com> // 0019 // Minor reformatting and similar small changes to integrate // 0020 // into getID3 by James Heinrich <info@getid3.org> // 0021 // /// 0022 ///////////////////////////////////////////////////////////////// 0023 0024 /* 0025 * CueSheet parser by Nigel Barnes. 0026 * 0027 * This is a PHP conversion of CueSharp 0.5 by Wyatt O'Day (wyday.com/cuesharp) 0028 */ 0029 0030 /** 0031 * A CueSheet class used to open and parse cuesheets. 0032 * 0033 */ 0034 class getid3_cue extends getid3_handler 0035 { 0036 public $cuesheet = array(); 0037 0038 public function Analyze() { 0039 $info = &$this->getid3->info; 0040 0041 $info['fileformat'] = 'cue'; 0042 $this->readCueSheetFilename($info['filenamepath']); 0043 $info['cue'] = $this->cuesheet; 0044 return true; 0045 } 0046 0047 0048 0049 public function readCueSheetFilename($filename) 0050 { 0051 $filedata = file_get_contents($filename); 0052 return $this->readCueSheet($filedata); 0053 } 0054 0055 /** 0056 * Parses a cue sheet file. 0057 * 0058 * @param $filedata 0059 * 0060 * @return array 0061 */ 0062 public function readCueSheet(&$filedata) 0063 { 0064 $cue_lines = array(); 0065 foreach (explode("\n", str_replace("\r", null, $filedata)) as $line) 0066 { 0067 if ( (strlen($line) > 0) && ($line[0] != '#')) 0068 { 0069 $cue_lines[] = trim($line); 0070 } 0071 } 0072 $this->parseCueSheet($cue_lines); 0073 0074 return $this->cuesheet; 0075 } 0076 0077 /** 0078 * Parses the cue sheet array. 0079 * 0080 * @param array $file - The cuesheet as an array of each line. 0081 */ 0082 public function parseCueSheet($file) 0083 { 0084 //-1 means still global, all others are track specific 0085 $track_on = -1; 0086 0087 for ($i=0; $i < count($file); $i++) 0088 { 0089 list($key) = explode(' ', strtolower($file[$i]), 2); 0090 switch ($key) 0091 { 0092 case 'catalog': 0093 case 'cdtextfile': 0094 case 'isrc': 0095 case 'performer': 0096 case 'songwriter': 0097 case 'title': 0098 $this->parseString($file[$i], $track_on); 0099 break; 0100 case 'file': 0101 $currentFile = $this->parseFile($file[$i]); 0102 break; 0103 case 'flags': 0104 $this->parseFlags($file[$i], $track_on); 0105 break; 0106 case 'index': 0107 case 'postgap': 0108 case 'pregap': 0109 $this->parseIndex($file[$i], $track_on); 0110 break; 0111 case 'rem': 0112 $this->parseComment($file[$i], $track_on); 0113 break; 0114 case 'track': 0115 $track_on++; 0116 $this->parseTrack($file[$i], $track_on); 0117 if (isset($currentFile)) // if there's a file 0118 { 0119 $this->cuesheet['tracks'][$track_on]['datafile'] = $currentFile; 0120 } 0121 break; 0122 default: 0123 //save discarded junk and place string[] with track it was found in 0124 $this->parseGarbage($file[$i], $track_on); 0125 break; 0126 } 0127 } 0128 } 0129 0130 /** 0131 * Parses the REM command. 0132 * 0133 * @param string $line - The line in the cue file that contains the TRACK command. 0134 * @param integer $track_on - The track currently processing. 0135 */ 0136 public function parseComment($line, $track_on) 0137 { 0138 $explodedline = explode(' ', $line, 3); 0139 $comment_REM = (isset($explodedline[0]) ? $explodedline[0] : ''); 0140 $comment_type = (isset($explodedline[1]) ? $explodedline[1] : ''); 0141 $comment_data = (isset($explodedline[2]) ? $explodedline[2] : ''); 0142 if (($comment_REM == 'REM') && $comment_type) { 0143 $comment_type = strtolower($comment_type); 0144 $commment_data = trim($comment_data, ' "'); 0145 if ($track_on != -1) { 0146 $this->cuesheet['tracks'][$track_on]['comments'][$comment_type][] = $comment_data; 0147 } else { 0148 $this->cuesheet['comments'][$comment_type][] = $comment_data; 0149 } 0150 } 0151 } 0152 0153 /** 0154 * Parses the FILE command. 0155 * 0156 * @param string $line - The line in the cue file that contains the FILE command. 0157 * @return array - Array of FILENAME and TYPE of file.. 0158 */ 0159 public function parseFile($line) 0160 { 0161 $line = substr($line, strpos($line, ' ') + 1); 0162 $type = strtolower(substr($line, strrpos($line, ' '))); 0163 0164 //remove type 0165 $line = substr($line, 0, strrpos($line, ' ') - 1); 0166 0167 //if quotes around it, remove them. 0168 $line = trim($line, '"'); 0169 0170 return array('filename'=>$line, 'type'=>$type); 0171 } 0172 0173 /** 0174 * Parses the FLAG command. 0175 * 0176 * @param string $line - The line in the cue file that contains the TRACK command. 0177 * @param integer $track_on - The track currently processing. 0178 */ 0179 public function parseFlags($line, $track_on) 0180 { 0181 if ($track_on != -1) 0182 { 0183 foreach (explode(' ', strtolower($line)) as $type) 0184 { 0185 switch ($type) 0186 { 0187 case 'flags': 0188 // first entry in this line 0189 $this->cuesheet['tracks'][$track_on]['flags'] = array( 0190 '4ch' => false, 0191 'data' => false, 0192 'dcp' => false, 0193 'pre' => false, 0194 'scms' => false, 0195 ); 0196 break; 0197 case 'data': 0198 case 'dcp': 0199 case '4ch': 0200 case 'pre': 0201 case 'scms': 0202 $this->cuesheet['tracks'][$track_on]['flags'][$type] = true; 0203 break; 0204 default: 0205 break; 0206 } 0207 } 0208 } 0209 } 0210 0211 /** 0212 * Collect any unidentified data. 0213 * 0214 * @param string $line - The line in the cue file that contains the TRACK command. 0215 * @param integer $track_on - The track currently processing. 0216 */ 0217 public function parseGarbage($line, $track_on) 0218 { 0219 if ( strlen($line) > 0 ) 0220 { 0221 if ($track_on == -1) 0222 { 0223 $this->cuesheet['garbage'][] = $line; 0224 } 0225 else 0226 { 0227 $this->cuesheet['tracks'][$track_on]['garbage'][] = $line; 0228 } 0229 } 0230 } 0231 0232 /** 0233 * Parses the INDEX command of a TRACK. 0234 * 0235 * @param string $line - The line in the cue file that contains the TRACK command. 0236 * @param integer $track_on - The track currently processing. 0237 */ 0238 public function parseIndex($line, $track_on) 0239 { 0240 $type = strtolower(substr($line, 0, strpos($line, ' '))); 0241 $line = substr($line, strpos($line, ' ') + 1); 0242 0243 if ($type == 'index') 0244 { 0245 //read the index number 0246 $number = intval(substr($line, 0, strpos($line, ' '))); 0247 $line = substr($line, strpos($line, ' ') + 1); 0248 } 0249 0250 //extract the minutes, seconds, and frames 0251 $explodedline = explode(':', $line); 0252 $minutes = (isset($explodedline[0]) ? $explodedline[0] : ''); 0253 $seconds = (isset($explodedline[1]) ? $explodedline[1] : ''); 0254 $frames = (isset($explodedline[2]) ? $explodedline[2] : ''); 0255 0256 switch ($type) { 0257 case 'index': 0258 $this->cuesheet['tracks'][$track_on][$type][$number] = array('minutes'=>intval($minutes), 'seconds'=>intval($seconds), 'frames'=>intval($frames)); 0259 break; 0260 case 'pregap': 0261 case 'postgap': 0262 $this->cuesheet['tracks'][$track_on][$type] = array('minutes'=>intval($minutes), 'seconds'=>intval($seconds), 'frames'=>intval($frames)); 0263 break; 0264 } 0265 } 0266 0267 public function parseString($line, $track_on) 0268 { 0269 $category = strtolower(substr($line, 0, strpos($line, ' '))); 0270 $line = substr($line, strpos($line, ' ') + 1); 0271 0272 //get rid of the quotes 0273 $line = trim($line, '"'); 0274 0275 switch ($category) 0276 { 0277 case 'catalog': 0278 case 'cdtextfile': 0279 case 'isrc': 0280 case 'performer': 0281 case 'songwriter': 0282 case 'title': 0283 if ($track_on == -1) 0284 { 0285 $this->cuesheet[$category] = $line; 0286 } 0287 else 0288 { 0289 $this->cuesheet['tracks'][$track_on][$category] = $line; 0290 } 0291 break; 0292 default: 0293 break; 0294 } 0295 } 0296 0297 /** 0298 * Parses the TRACK command. 0299 * 0300 * @param string $line - The line in the cue file that contains the TRACK command. 0301 * @param integer $track_on - The track currently processing. 0302 */ 0303 public function parseTrack($line, $track_on) 0304 { 0305 $line = substr($line, strpos($line, ' ') + 1); 0306 $track = ltrim(substr($line, 0, strpos($line, ' ')), '0'); 0307 0308 //find the data type. 0309 $datatype = strtolower(substr($line, strpos($line, ' ') + 1)); 0310 0311 $this->cuesheet['tracks'][$track_on] = array('track_number'=>$track, 'datatype'=>$datatype); 0312 } 0313 0314 } 0315