2008-06-02 19:58:08 +02:00
|
|
|
#include "layout.h"
|
|
|
|
#include "../vgmstream.h"
|
|
|
|
|
2008-07-14 21:21:45 +02:00
|
|
|
extern void init_eacs_high_nibble();
|
|
|
|
extern void init_ea_adpcm_nibble();
|
|
|
|
|
2008-06-02 19:58:08 +02:00
|
|
|
/* set up for the block at the given offset */
|
|
|
|
void ea_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
|
|
|
int i;
|
|
|
|
|
2008-07-14 21:21:45 +02:00
|
|
|
init_ea_adpcm_nibble();
|
|
|
|
|
2008-06-02 19:58:08 +02:00
|
|
|
// Search for next SCDL or SCEl block ...
|
|
|
|
do {
|
|
|
|
block_offset+=4;
|
|
|
|
if(block_offset>(off_t)get_streamfile_size(vgmstream->ch[0].streamfile))
|
|
|
|
return;
|
|
|
|
} while (read_32bitBE(block_offset,vgmstream->ch[0].streamfile)!=0x5343446C);
|
|
|
|
|
|
|
|
// reset channel offset
|
|
|
|
for(i=0;i<vgmstream->channels;i++) {
|
|
|
|
vgmstream->ch[i].channel_start_offset=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
vgmstream->current_block_offset = block_offset;
|
|
|
|
vgmstream->next_block_offset = block_offset+read_32bitLE(block_offset+4,vgmstream->ch[0].streamfile)-4;
|
|
|
|
|
|
|
|
if(vgmstream->ea_big_endian) {
|
|
|
|
vgmstream->current_block_size = read_32bitBE(block_offset+8,vgmstream->ch[0].streamfile);
|
|
|
|
|
|
|
|
for(i=0;i<vgmstream->channels;i++) {
|
|
|
|
vgmstream->ch[i].offset=read_32bitBE(block_offset+0x0C+(i*4),vgmstream->ch[0].streamfile)+(4*vgmstream->channels);
|
|
|
|
vgmstream->ch[i].offset+=vgmstream->current_block_offset+0x0C;
|
|
|
|
}
|
2008-07-03 21:09:53 +02:00
|
|
|
vgmstream->current_block_size /= 28;
|
|
|
|
|
2008-06-02 19:58:08 +02:00
|
|
|
} else {
|
|
|
|
if(vgmstream->coding_type==coding_PSX) {
|
|
|
|
vgmstream->ch[0].offset=vgmstream->current_block_offset+0x10;
|
2008-07-03 21:09:53 +02:00
|
|
|
vgmstream->ch[1].offset=(read_32bitLE(block_offset+0x04,vgmstream->ch[0].streamfile)-0x10)/vgmstream->channels;
|
2008-06-02 19:58:08 +02:00
|
|
|
vgmstream->ch[1].offset+=vgmstream->ch[0].offset;
|
2008-07-03 21:09:53 +02:00
|
|
|
vgmstream->current_block_size=read_32bitLE(block_offset+0x04,vgmstream->ch[0].streamfile)-0x10;
|
|
|
|
vgmstream->current_block_size/=vgmstream->channels;
|
2008-06-02 19:58:08 +02:00
|
|
|
} else {
|
2008-07-14 21:21:45 +02:00
|
|
|
|
|
|
|
if(vgmstream->coding_type==coding_EA_ADPCM) {
|
|
|
|
vgmstream->current_block_size = read_32bitLE(block_offset+4,vgmstream->ch[0].streamfile);
|
|
|
|
for(i=0;i<vgmstream->channels;i++) {
|
|
|
|
vgmstream->ch[i].offset=vgmstream->current_block_offset+0x0C+(4*vgmstream->channels);
|
|
|
|
vgmstream->ch[i].adpcm_history1_32=(uint32_t)read_16bitLE(vgmstream->current_block_offset+0x0c+(i*4),vgmstream->ch[0].streamfile);
|
|
|
|
vgmstream->ch[i].adpcm_history2_32=(uint32_t)read_16bitLE(vgmstream->current_block_offset+0x0e+(i*4),vgmstream->ch[0].streamfile);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(vgmstream->coding_type==coding_PCM16LE_NI) {
|
|
|
|
vgmstream->current_block_size = read_32bitLE(block_offset+4,vgmstream->ch[0].streamfile)-0x0C;
|
|
|
|
for(i=0;i<vgmstream->channels;i++) {
|
|
|
|
vgmstream->ch[i].offset=block_offset+0x0C+(i*2);
|
|
|
|
}
|
|
|
|
vgmstream->current_block_size/=2;
|
|
|
|
vgmstream->current_block_size-=2;
|
|
|
|
} else {
|
|
|
|
vgmstream->current_block_size = read_32bitLE(block_offset+8,vgmstream->ch[0].streamfile);
|
|
|
|
for(i=0;i<vgmstream->channels;i++) {
|
|
|
|
vgmstream->ch[i].offset=read_32bitLE(block_offset+0x0C+(i*4),vgmstream->ch[0].streamfile)+(4*vgmstream->channels);
|
|
|
|
vgmstream->ch[i].offset+=vgmstream->current_block_offset+0x0C;
|
|
|
|
}
|
|
|
|
vgmstream->current_block_size /= 28;
|
|
|
|
}
|
2008-06-02 19:58:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-07-14 21:21:45 +02:00
|
|
|
if((vgmstream->ea_compression_version<3) && (vgmstream->coding_type!=coding_PSX) && (vgmstream->coding_type!=coding_EA_ADPCM)) {
|
2008-06-02 19:58:08 +02:00
|
|
|
for(i=0;i<vgmstream->channels;i++) {
|
|
|
|
if(vgmstream->ea_big_endian) {
|
|
|
|
vgmstream->ch[i].adpcm_history1_32=read_16bitBE(vgmstream->ch[i].offset,vgmstream->ch[0].streamfile);
|
|
|
|
vgmstream->ch[i].adpcm_history2_32=read_16bitBE(vgmstream->ch[i].offset+2,vgmstream->ch[0].streamfile);
|
|
|
|
} else {
|
|
|
|
vgmstream->ch[i].adpcm_history1_32=read_16bitLE(vgmstream->ch[i].offset,vgmstream->ch[0].streamfile);
|
|
|
|
vgmstream->ch[i].adpcm_history2_32=read_16bitLE(vgmstream->ch[i].offset+2,vgmstream->ch[0].streamfile);
|
|
|
|
}
|
|
|
|
vgmstream->ch[i].offset+=4;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-07-14 21:21:45 +02:00
|
|
|
|
|
|
|
void eacs_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
|
|
|
int i;
|
|
|
|
off_t block_size=vgmstream->current_block_size;
|
|
|
|
|
|
|
|
if(read_32bitBE(block_offset,vgmstream->ch[0].streamfile)==0x31534E6C) {
|
|
|
|
block_offset+=0x0C;
|
|
|
|
}
|
|
|
|
|
|
|
|
vgmstream->current_block_offset = block_offset;
|
|
|
|
|
|
|
|
if(read_32bitBE(block_offset,vgmstream->ch[0].streamfile)==0x31534E64) { /* 1Snd */
|
|
|
|
block_offset+=4;
|
|
|
|
if(vgmstream->ea_platform==0)
|
|
|
|
block_size=read_32bitLE(vgmstream->current_block_offset+0x04,
|
|
|
|
vgmstream->ch[0].streamfile);
|
|
|
|
else
|
|
|
|
block_size=read_32bitBE(vgmstream->current_block_offset+0x04,
|
|
|
|
vgmstream->ch[0].streamfile);
|
|
|
|
block_offset+=4;
|
|
|
|
}
|
|
|
|
|
|
|
|
vgmstream->current_block_size=block_size-8;
|
|
|
|
|
|
|
|
if(vgmstream->coding_type==coding_EACS_IMA) {
|
|
|
|
init_eacs_high_nibble();
|
|
|
|
vgmstream->current_block_size=read_32bitLE(block_offset,vgmstream->ch[0].streamfile);
|
|
|
|
|
|
|
|
for(i=0;i<vgmstream->channels;i++) {
|
|
|
|
vgmstream->ch[i].adpcm_step_index = read_32bitLE(block_offset+0x04+i*4,vgmstream->ch[0].streamfile);
|
|
|
|
vgmstream->ch[i].adpcm_history1_32 = read_32bitLE(block_offset+0x04+i*4+(4*vgmstream->channels),vgmstream->ch[0].streamfile);
|
|
|
|
vgmstream->ch[i].offset = block_offset+0x14;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if(vgmstream->coding_type==coding_PSX) {
|
|
|
|
for (i=0;i<vgmstream->channels;i++)
|
|
|
|
vgmstream->ch[i].offset = vgmstream->current_block_offset+8+(i*(vgmstream->current_block_size/2));
|
|
|
|
} else {
|
|
|
|
|
|
|
|
for (i=0;i<vgmstream->channels;i++) {
|
|
|
|
if(vgmstream->coding_type==coding_PCM16LE_NI)
|
|
|
|
vgmstream->ch[i].offset = block_offset+(i*2);
|
|
|
|
else
|
|
|
|
vgmstream->ch[i].offset = block_offset+i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vgmstream->current_block_size/=vgmstream->channels;
|
|
|
|
}
|
|
|
|
vgmstream->next_block_offset = vgmstream->current_block_offset +
|
|
|
|
(off_t)block_size;
|
|
|
|
}
|