I was able to extract the sound effects/sample data from the Anims.j2a file!
Place Anims.j2a in the same folder as this PHP script, it will create .wav files for each sample.
PHP Code:
error_reporting(E_ALL | E_NOTICE);
$filename = "Anims.j2a";
$AlibStruct = implode('/', array(
"A4Magic",
"VUnknown1",
"VHeaderSize",
"vVersion",
"vUnknown2",
"VFileSize",
"VChecksum",
"VSetCount"
));
$AnimStruct = implode('/', array(
"A4Magic",
"CAnimCount",
"CSampleCount",
"vTotalFrameCount",
"VSampleUnknown",
"VC1",
"VU1",
"VC2",
"VU2",
"VC3",
"VU3",
"VC4",
"VU4"
));
$AnimInfoStruct = implode('/', array(
"vFrameCount",
"vFPS",
"VUnknownZeroes"
));
$AnimFrameStruct = implode('/', array(
"vWidth",
"vHeight",
"vColdspotX",
"vColdspotY",
"vHotspotX",
"vHotspotY",
"vGunspotX",
"vGunspotY",
"VImageAddress",
"VMaskAddress"
));
$RiffStruct = implode('/', array(
"A4Magic",
"VLen",
"A4Format",
"A4SubChunk",
"x44",
"vmul",
"x2",
"Vlength",
"x8",
"Vrate"
));
$WaveStruct = implode('', array(
"A4",
"V",
"A4",
"A4",
"V",
"v",
"v",
"V",
"V",
"V",
"A4",
"V"
));
$f = fopen($filename, 'rb');
$AlibHeader = unpack($AlibStruct, fread($f, 28));
$AlibHeader['SetAddress'] = unpack("V".$AlibHeader['SetCount'], fread($f, $AlibHeader['SetCount']*4)); // Index start at 1
$AnimHeaders = array();
$AnimStreams = array();
$AnimInfo = array();
$AnimImages = array();
$RiffInfo = array();
for($i=0; $i < $AlibHeader['SetCount']; $i++) {
$AnimHeaders[$i] = unpack($AnimStruct, fread($f, 44));
$animStreams[$i] = array();
for($j=0; $j < 4; $j++) {
$animStreams[$i][$j] = gzuncompress(fread($f, $AnimHeaders[$i]['C'.($j+1)]));
}
$AnimInfo[$i] = array();
$AnimImages[$i] = array();
$frameOffset = 0;
for($j=0; $j < $AnimHeaders[$i]['AnimCount']; $j++) {
$AnimInfo[$i][$j] = unpack($AnimInfoStruct, substr($animStreams[$i][0], $j*8, 8));
$minw = 1;
$minh = 1;
$AnimInfo[$i][$j]['Frames'] = array();
for($k=0; $k < $AnimInfo[$i][$j]['FrameCount']; $k++) {
$AnimInfo[$i][$j]['Frames'][$k] = unpack($AnimFrameStruct, substr($animStreams[$i][1], $frameOffset*24, 24));
$frameOffset++;
$minw = max($minw, $AnimInfo[$i][$j]['Frames'][$k]['Width']);
$minh = max($minh, $AnimInfo[$i][$j]['Frames'][$k]['Height']);
}
$AnimInfo[$i][$j]['BoundWidth'] = $minw;
$AnimInfo[$i][$j]['BoundHeight'] = $minh;
/*$AnimImages[$i][$j] = imagecreate($minw, $minh*$AnimInfo[$i][$j]['FrameCount']);
for($k=0; $k < $AnimInfo[$i][$j]['FrameCount']; $k++) {
$imageOffset = $AnimInfo[$i][$j]['Frames'][$k]['ImageAddress'];
}*/
}
$RiffInfo[$i] = array();
$sampleOffset = 0;
for($j=0; $j < $AnimHeaders[$i]['SampleCount']; $j++) {
list(,$sfxLength) = unpack("V", substr($animStreams[$i][3], $sampleOffset, 4));
$RiffInfo[$i][$j] = unpack($RiffStruct, substr($animStreams[$i][3], $sampleOffset+4, $sfxLength-8));
$mul = $RiffInfo[$i][$j]['mul'] / 4 + 1;
$length = $RiffInfo[$i][$j]['length'];
$rate = $RiffInfo[$i][$j]['rate'];
$time = $length / $rate;
$length *= $mul;
$WaveHeader = pack($WaveStruct, "RIFF",
$length + 36,
"WAVE",
"fmt ",
16,
1,
1,
$rate,
$rate * $mul,
$mul * 0x80001,
"data",
$length
);
$sampleData = substr($animStreams[$i][3], $sampleOffset+4+80, $sfxLength-8-80);
for($k=0; $k < strlen($sampleData); $k++) {
$sampleData[$k] = chr(ord($sampleData[$k]) ^ ($mul << 7));
}
echo "writing sfx_".$i."_".$j.".wav ($time s)\n";
file_put_contents('sfx_'.$i.'_'.$j.'.wav', $WaveHeader . $sampleData);
$sampleOffset += $sfxLength;
}
}
fclose($f);
echo "success";