.musx support for Dead Space: Extraction (rename from .sfx)

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@718 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
halleyscometsw 2009-12-16 06:12:53 +00:00
parent c7e5a03332
commit 5b0525fed5
6 changed files with 101 additions and 19 deletions

View File

@ -72,7 +72,6 @@ PS2/PSX ADPCM:
- .mihb (merged mih+mib)
- .msvp
- .musc
- .musx
- .npsf
- .pnb
- .psh
@ -195,6 +194,7 @@ multi:
- .emff (PSX APDCM, GC DSP ADPCM)
- .fsb, .wii (PSX ADPCM, GC DSP ADPCM, Xbox IMA ADPCM)
- .genh (lots)
- .musx (PSX ADPCM, Xbox IMA ADPCM, DAT4 IMA ADPCM)
- .nwa (16 bit PCM, NWA DPCM)
- .psw (PSX ADPCM, GC DSP ADPCM)
- .rwar, .rwav (GC DSP ADPCM, 8/16 bit PCM)

View File

@ -12,6 +12,7 @@ void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
void g72x_init_state(struct g72x_state *state_ptr);
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
void decode_int_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
void decode_dvi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);

View File

@ -64,6 +64,43 @@ void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
stream->adpcm_step_index = step_index;
}
void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int i=first_sample;
int32_t sample_count;
int32_t hist1 = stream->adpcm_history1_16;
int step_index = stream->adpcm_step_index;
if (first_sample==0) {
hist1 = read_16bitLE(stream->offset,stream->streamfile);
step_index = read_8bit(stream->offset+2,stream->streamfile);
}
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
int sample_nibble =
(read_8bit(stream->offset+4+i/2,stream->streamfile) >> (i&1?0:4))&0xf;
int delta;
int step = ADPCMTable[step_index];
delta = step >> 3;
if (sample_nibble & 1) delta += step >> 2;
if (sample_nibble & 2) delta += step >> 1;
if (sample_nibble & 4) delta += step;
if (sample_nibble & 8)
outbuf[sample_count] = clamp16(hist1 - delta);
else
outbuf[sample_count] = clamp16(hist1 + delta);
step_index += IMA_IndexTable[sample_nibble];
if (step_index < 0) step_index=0;
if (step_index > 88) step_index=88;
hist1 = outbuf[sample_count];
}
stream->adpcm_history1_16 = hist1;
stream->adpcm_step_index = step_index;
}
/* Xbox IMA is MS IMA, but I'll leave it alone for now (esp as it has > 2 channel support) */
void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
int i=first_sample;

View File

@ -179,6 +179,7 @@ fail:
/* MUSX */
/* New MUSX formats, found in Quantum of Solace, The Mummy 3, possibly more */
/* WII_ in Dead Space: Extraction */
VGMSTREAM * init_vgmstream_musx_v010(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[260];
@ -201,31 +202,61 @@ VGMSTREAM * init_vgmstream_musx_v010(STREAMFILE *streamFile) {
loop_flag = (read_32bitLE(0x34,streamFile)!=0x00000000);
channel_count = 2;
musx_type=(read_32bitBE(0x10,streamFile));
if (musx_type == 0x5749495F && /* WII_ */
read_32bitBE(0x40,streamFile) == 0x44415434) /* DAT4 */
{
channel_count = read_32bitLE(0x48,streamFile);
loop_flag = (read_32bitLE(0x64,streamFile) != -1);
}
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
musx_type=(read_32bitBE(0x10,streamFile));
switch (musx_type) {
case 0x5053325F: /* PS2_ */
start_offset = 0x800;
vgmstream->channels = channel_count;
vgmstream->sample_rate = 32000;
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitLE(0x40,streamFile);
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x80;
vgmstream->meta_type = meta_MUSX_V010;
if (loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x44,streamFile);
vgmstream->loop_end_sample = read_32bitLE(0x40,streamFile);
}
break;
default:
goto fail;
switch (musx_type) {
case 0x5053325F: /* PS2_ */
start_offset = 0x800;
vgmstream->channels = channel_count;
vgmstream->sample_rate = 32000;
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitLE(0x40,streamFile);
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x80;
vgmstream->meta_type = meta_MUSX_V010;
if (loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x44,streamFile);
vgmstream->loop_end_sample = read_32bitLE(0x40,streamFile);
}
break;
case 0x5749495F: /* WII_ */
start_offset = 0x800;
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x4C,streamFile);
switch (read_32bitBE(0x40,streamFile))
{
case 0x44415434: /* DAT4 */
vgmstream->coding_type = coding_DAT4_IMA;
break;
default:
goto fail;
}
vgmstream->num_samples = read_32bitLE(0x60,streamFile);
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x20;
vgmstream->meta_type = meta_MUSX_V010;
if (loop_flag)
{
vgmstream->loop_start_sample = read_32bitLE(0x64,streamFile);
vgmstream->loop_end_sample = read_32bitLE(0x60,streamFile);
}
break;
default:
goto fail;
}
/* open the file for reading */

View File

@ -697,6 +697,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
case coding_SASSC:
return 1;
case coding_NDS_IMA:
case coding_DAT4_IMA:
return (vgmstream->interleave_block_size-4)*2;
case coding_NGC_DTK:
return 28;
@ -782,6 +783,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
case coding_MS_IMA:
case coding_RAD_IMA:
case coding_NDS_IMA:
case coding_DAT4_IMA:
return vgmstream->interleave_block_size;
case coding_NGC_DTK:
return 32;
@ -938,6 +940,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
samples_to_do);
}
break;
case coding_DAT4_IMA:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_dat4_ima(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
vgmstream->channels,vgmstream->samples_into_block,
samples_to_do);
}
break;
case coding_XBOX:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_xbox_ima(vgmstream,&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
@ -1388,6 +1397,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
case coding_NDS_IMA:
snprintf(temp,TEMPSIZE,"NDS-style 4-bit IMA ADPCM");
break;
case coding_DAT4_IMA:
snprintf(temp,TEMPSIZE,"Eurocom DAT4 4-bit IMA ADPCM");
break;
case coding_NGC_DTK:
snprintf(temp,TEMPSIZE,"Gamecube \"ADP\"/\"DTK\" 4-bit ADPCM");
break;

View File

@ -76,6 +76,7 @@ typedef enum {
coding_MS_IMA, /* Microsoft IMA */
coding_RAD_IMA, /* "Radical ADPCM" IMA */
coding_APPLE_IMA4, /* Apple Quicktime IMA4 */
coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */
coding_WS, /* Westwood Studios' custom VBR ADPCM */
#ifdef VGM_USE_MPEG
coding_fake_MPEG2_L2, /* MPEG-2 Layer 2 (AHX), with lying headers */