123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
<?php
if (!defined('GETID3_INCLUDEPATH')) {
exit;
}
class getid3_mod extends getid3_handler
{
public function Analyze() {
$info = &$this->getid3->info;
$this->fseek($info['avdataoffset']);
$fileheader = $this->fread(1088);
if (preg_match('#^IMPM#', $fileheader)) {
return $this->getITheaderFilepointer();
} elseif (preg_match('#^Extended Module#', $fileheader)) {
return $this->getXMheaderFilepointer();
} elseif (preg_match('#^.{44}SCRM#s', $fileheader)) {
return $this->getS3MheaderFilepointer();
} elseif (preg_match('#^.{1080}(M\\.K\\.)#s', $fileheader)) {
return $this->getMODheaderFilepointer();
}
$this->error('This is not a known type of MOD file');
return false;
}
public function getMODheaderFilepointer() {
$info = &$this->getid3->info;
$this->fseek($info['avdataoffset']);
$filedata = $this->fread(1084);
if (substr($filedata, 1080, 4) == 'M.K.') {
$offset = 0;
$info['mod']['title'] = rtrim(substr($filedata, $offset, 20), "\x00"); $offset += 20;
$info['tags']['mod']['title'] = array($info['mod']['title']);
for ($samplenumber = 0; $samplenumber <= 30; $samplenumber++) {
$sampledata = array();
$sampledata['name'] = substr($filedata, $offset, 22); $offset += 22;
$sampledata['length'] = getid3_lib::BigEndian2Int(substr($filedata, $offset, 2)); $offset += 2;
$sampledata['volume'] = getid3_lib::BigEndian2Int(substr($filedata, $offset, 2)); $offset += 2;
$sampledata['repeat_offset'] = getid3_lib::BigEndian2Int(substr($filedata, $offset, 2)); $offset += 2;
$sampledata['repeat_length'] = getid3_lib::BigEndian2Int(substr($filedata, $offset, 2)); $offset += 2;
$info['mod']['samples'][$samplenumber] = $sampledata;
}
$info['mod']['song_length'] = getid3_lib::BigEndian2Int(substr($filedata, $offset++, 1));
$info['mod']['bpm'] = getid3_lib::BigEndian2Int(substr($filedata, $offset++, 1));
for ($songposition = 0; $songposition <= 127; $songposition++) {
$info['mod']['song_positions'][$songposition] = getid3_lib::BigEndian2Int(substr($filedata, $offset++, 1));
}
} else {
$this->error('unknown MOD ID at offset 1080: '.getid3_lib::PrintHexBytes(substr($filedata, 1080, 4)));
return false;
}
$info['fileformat'] = 'mod';
$this->warning('MOD (SoundTracker) parsing incomplete in this version of getID3() ['.$this->getid3->version().']');
return true;
}
public function getXMheaderFilepointer() {
$info = &$this->getid3->info;
$this->fseek($info['avdataoffset']);
$FormatID = $this->fread(15);
if (!preg_match('#^Extended Module$#', $FormatID)) {
$this->error('This is not a known type of XM-MOD file');
return false;
}
$info['fileformat'] = 'xm';
$this->error('XM-MOD parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
return false;
}
public function getS3MheaderFilepointer() {
$info = &$this->getid3->info;
$this->fseek($info['avdataoffset'] + 44);
$FormatID = $this->fread(4);
if (!preg_match('#^SCRM$#', $FormatID)) {
$this->error('This is not a ScreamTracker MOD file');
return false;
}
$info['fileformat'] = 's3m';
$this->error('ScreamTracker parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
return false;
}
public function getITheaderFilepointer() {
$info = &$this->getid3->info;
$this->fseek($info['avdataoffset']);
$FormatID = $this->fread(4);
if (!preg_match('#^IMPM$#', $FormatID)) {
$this->error('This is not an ImpulseTracker MOD file');
return false;
}
$info['fileformat'] = 'it';
$this->error('ImpulseTracker parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
return false;
}
}