.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) - .mihb (merged mih+mib)
- .msvp - .msvp
- .musc - .musc
- .musx
- .npsf - .npsf
- .pnb - .pnb
- .psh - .psh
@ -195,6 +194,7 @@ multi:
- .emff (PSX APDCM, GC DSP ADPCM) - .emff (PSX APDCM, GC DSP ADPCM)
- .fsb, .wii (PSX ADPCM, GC DSP ADPCM, Xbox IMA ADPCM) - .fsb, .wii (PSX ADPCM, GC DSP ADPCM, Xbox IMA ADPCM)
- .genh (lots) - .genh (lots)
- .musx (PSX ADPCM, Xbox IMA ADPCM, DAT4 IMA ADPCM)
- .nwa (16 bit PCM, NWA DPCM) - .nwa (16 bit PCM, NWA DPCM)
- .psw (PSX ADPCM, GC DSP ADPCM) - .psw (PSX ADPCM, GC DSP ADPCM)
- .rwar, .rwav (GC DSP ADPCM, 8/16 bit PCM) - .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 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_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_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_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); 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; 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) */ /* 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) { 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; int i=first_sample;

View File

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

View File

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

View File

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