Add/use xbox_ima_bytes_to_samples, rename coding_XBOX to XBOX_IMA

Currently same as ms_ima_bytes_to_samples, but this will change; renamed
for consistency with all other IMA variations. Also clean a bit some
metas since I was testing anyway.
This commit is contained in:
bnnm 2018-02-17 12:30:14 +01:00
parent 0b2902880c
commit 9cf9416665
28 changed files with 394 additions and 545 deletions

View File

@ -32,8 +32,9 @@ void decode_wwise_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample *
void decode_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel); void decode_ref_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
void decode_awc_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_awc_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_ubi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); void decode_ubi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels);
size_t ima_bytes_to_samples(size_t bytes, int channels); size_t ima_bytes_to_samples(size_t bytes, int channels);
size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels);
size_t xbox_ima_bytes_to_samples(size_t bytes, int channels);
size_t ubi_ima_bytes_to_samples(size_t bytes, int channels, STREAMFILE *streamFile, off_t offset); size_t ubi_ima_bytes_to_samples(size_t bytes, int channels, STREAMFILE *streamFile, off_t offset);
/* ngc_dsp_decoder */ /* ngc_dsp_decoder */

View File

@ -785,15 +785,22 @@ void decode_ubi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
} }
size_t ima_bytes_to_samples(size_t bytes, int channels) {
/* 2 samples per byte (2 nibbles) in stereo or mono config */
return bytes * 2 / channels;
}
size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels) { size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels) {
/* MS IMA blocks have a 4 byte header per channel; 2 samples per byte (2 nibbles) */ /* MS IMA blocks have a 4 byte header per channel; 2 samples per byte (2 nibbles) */
return (bytes / block_align) * (block_align - 4 * channels) * 2 / channels return (bytes / block_align) * (block_align - 4 * channels) * 2 / channels
+ ((bytes % block_align) ? ((bytes % block_align) - 4 * channels) * 2 / channels : 0); + ((bytes % block_align) ? ((bytes % block_align) - 4 * channels) * 2 / channels : 0);
} }
size_t ima_bytes_to_samples(size_t bytes, int channels) { size_t xbox_ima_bytes_to_samples(size_t bytes, int channels) {
/* 2 samples per byte (2 nibbles) in stereo or mono config */ int block_align = 0x24 * channels;
return bytes * 2 / channels; /* XBOX IMA blocks have a 4 byte header per channel; 2 samples per byte (2 nibbles) */
return (bytes / block_align) * (block_align - 4 * channels) * 2 / channels
+ ((bytes % block_align) ? ((bytes % block_align) - 4 * channels) * 2 / channels : 0); //todo probably not possible (aligned)
} }
size_t ubi_ima_bytes_to_samples(size_t bytes, int channels, STREAMFILE *streamFile, off_t offset) { size_t ubi_ima_bytes_to_samples(size_t bytes, int channels, STREAMFILE *streamFile, off_t offset) {

View File

@ -470,8 +470,8 @@ static const coding_info coding_info_list[] = {
{coding_DVI_IMA_int, "Intel DVI 4-bit IMA ADPCM (mono/interleave)"}, {coding_DVI_IMA_int, "Intel DVI 4-bit IMA ADPCM (mono/interleave)"},
{coding_3DS_IMA, "3DS IMA 4-bit ADPCM"}, {coding_3DS_IMA, "3DS IMA 4-bit ADPCM"},
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"}, {coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
{coding_XBOX, "XBOX 4-bit IMA ADPCM"}, {coding_XBOX_IMA, "XBOX 4-bit IMA ADPCM"},
{coding_XBOX_int, "XBOX 4-bit IMA ADPCM (mono/interleave)"}, {coding_XBOX_IMA_int, "XBOX 4-bit IMA ADPCM (mono/interleave)"},
{coding_NDS_IMA, "NDS-style 4-bit IMA ADPCM"}, {coding_NDS_IMA, "NDS-style 4-bit IMA ADPCM"},
{coding_DAT4_IMA, "Eurocom DAT4 4-bit IMA ADPCM"}, {coding_DAT4_IMA, "Eurocom DAT4 4-bit IMA ADPCM"},
{coding_RAD_IMA, "Radical 4-bit IMA ADPCM"}, {coding_RAD_IMA, "Radical 4-bit IMA ADPCM"},
@ -641,7 +641,7 @@ static const meta_info meta_info_list[] = {
{meta_PS2_STR, "assumed STR + STH File by .str & .sth extension"}, {meta_PS2_STR, "assumed STR + STH File by .str & .sth extension"},
{meta_PS2_ILD, "ILD header"}, {meta_PS2_ILD, "ILD header"},
{meta_PS2_PNB, "assumed PNB (PsychoNauts Bgm File) by .pnb extension"}, {meta_PS2_PNB, "assumed PNB (PsychoNauts Bgm File) by .pnb extension"},
{meta_XBOX_WAVM, "assumed Xbox WAVM file by .wavm extension"}, {meta_XBOX_WAVM, "Xbox WAVM raw header"},
{meta_XBOX_RIFF, "Microsoft XWAV RIFF header"}, {meta_XBOX_RIFF, "Microsoft XWAV RIFF header"},
{meta_DSP_STR, "assumed Conan Gamecube STR File by .str extension"}, {meta_DSP_STR, "assumed Conan Gamecube STR File by .str extension"},
{meta_EA_SCHL, "Electronic Arts SCHl header (variable)"}, {meta_EA_SCHL, "Electronic Arts SCHl header (variable)"},
@ -717,7 +717,7 @@ static const meta_info meta_info_list[] = {
{meta_DC_STR, "Sega Stream Asset Builder header"}, {meta_DC_STR, "Sega Stream Asset Builder header"},
{meta_DC_STR_V2, "variant of Sega Stream Asset Builder header"}, {meta_DC_STR_V2, "variant of Sega Stream Asset Builder header"},
{meta_XBOX_XMU, "XMU header"}, {meta_XBOX_XMU, "XMU header"},
{meta_XBOX_XVAS, "assumed TMNT file by .xvas extension"}, {meta_XBOX_XVAS, "Konami .XVAS header"},
{meta_PS2_XA2, "Acclaim XA2 Header"}, {meta_PS2_XA2, "Acclaim XA2 Header"},
{meta_DC_IDVI, "Capcom IDVI header"}, {meta_DC_IDVI, "Capcom IDVI header"},
{meta_KRAW, "Geometry Wars: Galaxies KRAW header"}, {meta_KRAW, "Geometry Wars: Galaxies KRAW header"},

View File

@ -6,38 +6,33 @@
VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
off_t start_offset; off_t start_offset;
int loop_flag; int loop_flag, channel_count, codec;
int channel_count;
int identifer_byte;
/* check extension, case insensitive */ /* check extension, case insensitive */
if (!check_extensions(streamFile,"ads")) goto fail; if (!check_extensions(streamFile,"ads")) goto fail;
/* check dhSS Header */ if (read_32bitBE(0x00,streamFile) != 0x64685353) /* "dhSS" */
if (read_32bitBE(0x00,streamFile) != 0x64685353)
goto fail; goto fail;
if (read_32bitBE(0x20,streamFile) != 0x64625353) /* "dbSS" */
/* check dbSS Header */
if (read_32bitBE(0x20,streamFile) != 0x64625353)
goto fail; goto fail;
loop_flag = 1; loop_flag = 1;
channel_count = read_32bitBE(0x10,streamFile); channel_count = read_32bitBE(0x10,streamFile);
if (channel_count > 0x2) if (channel_count > 2)
goto fail; goto fail;
/* 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 */ vgmstream->sample_rate = read_32bitBE(0x0c,streamFile);
identifer_byte = read_32bitBE(0x08,streamFile);
switch (identifer_byte) { codec = read_32bitBE(0x08,streamFile);
switch (codec) {
case 0x00000020: /* GC */ case 0x00000020: /* GC */
start_offset = 0x28 + 0x60 * channel_count; start_offset = 0x28 + 0x60 * channel_count;
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitBE(0x0c,streamFile);
vgmstream->coding_type = coding_NGC_DSP; vgmstream->coding_type = coding_NGC_DSP;
vgmstream->num_samples = read_32bitBE(0x28,streamFile); vgmstream->num_samples = read_32bitBE(0x28,streamFile);
if (loop_flag) { if (loop_flag) {
@ -57,10 +52,8 @@ VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) {
case 0x00000021: /* Xbox */ case 0x00000021: /* Xbox */
start_offset = 0x28; start_offset = 0x28;
vgmstream->channels = channel_count; vgmstream->coding_type = coding_XBOX_IMA_int;
vgmstream->sample_rate = read_32bitBE(0x0c,streamFile); vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitBE(0x24,streamFile), vgmstream->channels);
vgmstream->coding_type = coding_XBOX_int;
vgmstream->num_samples = (read_32bitBE(0x24,streamFile) / 36 *64 / vgmstream->channels);
vgmstream->layout_type = channel_count == 1 ? layout_none : layout_interleave; vgmstream->layout_type = channel_count == 1 ? layout_none : layout_interleave;
vgmstream->interleave_block_size = 0x24; vgmstream->interleave_block_size = 0x24;
if (loop_flag) { if (loop_flag) {

View File

@ -292,7 +292,7 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE *streamFile, ea_
break; break;
case EA_CODEC2_XBOXADPCM: /* XBOX IMA (interleaved mono) */ case EA_CODEC2_XBOXADPCM: /* XBOX IMA (interleaved mono) */
vgmstream->coding_type = coding_XBOX_int; vgmstream->coding_type = coding_XBOX_IMA_int;
break; break;
case EA_CODEC2_GCADPCM: /* DSP */ case EA_CODEC2_GCADPCM: /* DSP */

View File

@ -288,7 +288,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) {
/* FSOUND_IMAADPCMSTEREO is "noninterleaved, true stereo IMA", but doesn't seem to be any different /* FSOUND_IMAADPCMSTEREO is "noninterleaved, true stereo IMA", but doesn't seem to be any different
* (found in FSB4: Shatter, Blade Kitten (PC), Hard Corps: Uprising (PS3)) */ * (found in FSB4: Shatter, Blade Kitten (PC), Hard Corps: Uprising (PS3)) */
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
/* "interleaved header" IMA, only used with >2ch (ex. Blade Kitten 6ch) /* "interleaved header" IMA, only used with >2ch (ex. Blade Kitten 6ch)
* or (seemingly) when flag is used (ex. Dead to Rights 2 (Xbox) 2ch in FSB3.1 */ * or (seemingly) when flag is used (ex. Dead to Rights 2 (Xbox) 2ch in FSB3.1 */

View File

@ -237,7 +237,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
break; break;
case 0x07: /* FMOD_SOUND_FORMAT_IMAADPCM */ case 0x07: /* FMOD_SOUND_FORMAT_IMAADPCM */
vgmstream->coding_type = (vgmstream->channels > 2) ? coding_FSB_IMA : coding_XBOX; vgmstream->coding_type = (vgmstream->channels > 2) ? coding_FSB_IMA : coding_XBOX_IMA;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
break; break;

View File

@ -84,7 +84,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
/* type to coding conversion */ /* type to coding conversion */
switch (genh.codec) { switch (genh.codec) {
case PSX: coding = coding_PSX; break; case PSX: coding = coding_PSX; break;
case XBOX: coding = coding_XBOX; break; case XBOX: coding = coding_XBOX_IMA; break;
case NGC_DTK: coding = coding_NGC_DTK; break; case NGC_DTK: coding = coding_NGC_DTK; break;
case PCM16BE: coding = coding_PCM16BE; break; case PCM16BE: coding = coding_PCM16BE; break;
case PCM16LE: coding = coding_PCM16LE; break; case PCM16LE: coding = coding_PCM16LE; break;
@ -194,7 +194,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
vgmstream->interleave_block_size = genh.interleave; vgmstream->interleave_block_size = genh.interleave;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
break; break;
case coding_XBOX: case coding_XBOX_IMA:
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
break; break;
case coding_NGC_DTK: case coding_NGC_DTK:

View File

@ -18,6 +18,8 @@ VGMSTREAM * init_vgmstream_mss(STREAMFILE *streamFile) {
loop_flag = 0; loop_flag = 0;
channel_count = read_16bitLE(0x16,streamFile); channel_count = read_16bitLE(0x16,streamFile);
if (read_32bitLE(0x18,streamFile) == 0x4800 && vgmstream->channels > 2)
channel_count = 2; //todo add support for interleave stereo streams
/* build the VGMSTREAM */ /* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag); vgmstream = allocate_vgmstream(channel_count,loop_flag);
@ -36,14 +38,12 @@ VGMSTREAM * init_vgmstream_mss(STREAMFILE *streamFile) {
/* no other way to know */ /* no other way to know */
if (vgmstream->interleave_block_size == 0x4800) { if (vgmstream->interleave_block_size == 0x4800) {
/* interleaved stereo streams (2ch 0x4800 + 2ch 0x4800 = 4ch) */ /* interleaved stereo streams (2ch 0x4800 + 2ch 0x4800 = 4ch) */
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type = layout_interleave; vgmstream->layout_type = layout_interleave;
/* header values are somehow off? */ /* header values are somehow off? */
data_size = get_streamfile_size(streamFile); data_size = get_streamfile_size(streamFile);
vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, 0x24*vgmstream->channels, vgmstream->channels); vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
vgmstream->channels = 2; //todo add support for interleave stereo streams
} }
else { else {
/* 0x800 interleave */ /* 0x800 interleave */

View File

@ -31,7 +31,7 @@ VGMSTREAM * init_vgmstream_aus(STREAMFILE *streamFile) {
vgmstream->num_samples = read_32bitLE(0x08,streamFile); vgmstream->num_samples = read_32bitLE(0x08,streamFile);
if(read_16bitLE(0x06,streamFile)==0x02) { if(read_16bitLE(0x06,streamFile)==0x02) {
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type=layout_none; vgmstream->layout_type=layout_none;
} else { } else {
vgmstream->coding_type = coding_PSX; vgmstream->coding_type = coding_PSX;

View File

@ -131,12 +131,12 @@ static int read_fmt(int big_endian, STREAMFILE * streamFile, off_t current_chunk
fmt->coding_type = coding_MS_IMA; fmt->coding_type = coding_MS_IMA;
break; break;
case 0x69: /* MS IMA ADPCM (XBOX) - Rayman Raving Rabbids 2 (PC) */ case 0x69: /* XBOX IMA ADPCM [Rayman Raving Rabbids 2 (PC) -- waa/wac/wam/wad?] */
if (fmt->bps != 4) goto fail; if (fmt->bps != 4) goto fail;
fmt->coding_type = coding_MS_IMA; fmt->coding_type = coding_XBOX_IMA;
break; break;
case 0x007A: /* MS IMA ADPCM (LA Rush, Psi Ops PC) */ case 0x007A: /* MS IMA ADPCM [LA Rush, Psi Ops (PC)] */
/* 0x007A is apparently "Voxware SC3" but in .MED it's just MS-IMA */ /* 0x007A is apparently "Voxware SC3" but in .MED it's just MS-IMA */
if (!check_extensions(streamFile,"med")) if (!check_extensions(streamFile,"med"))
goto fail; goto fail;
@ -228,8 +228,8 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
size_t file_size, riff_size, data_size = 0; size_t file_size, riff_size, data_size = 0;
off_t start_offset = 0; off_t start_offset = 0;
int fact_sample_count = -1; int fact_sample_count = 0;
int fact_sample_skip = -1; int fact_sample_skip = 0;
int loop_flag = 0; int loop_flag = 0;
long loop_start_ms = -1; long loop_start_ms = -1;
@ -355,7 +355,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
mwv_ctrl_offset = current_chunk; mwv_ctrl_offset = current_chunk;
break; break;
case 0x66616374: /* fact */ case 0x66616374: /* fact */
if (sns && chunk_size == 0x10) { if (chunk_size == 0x04) { /* standard, usually found with ADPCM */
fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile);
} else if (sns && chunk_size == 0x10) {
fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile); fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile);
} else if ((at3 || at9) && chunk_size == 0x08) { } else if ((at3 || at9) && chunk_size == 0x08) {
fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile); fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile);
@ -443,6 +445,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
case coding_MS_IMA: case coding_MS_IMA:
vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count); vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
break; break;
case coding_XBOX_IMA:
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, fmt.channel_count);
break;
case coding_NGC_DSP: case coding_NGC_DSP:
if (!sns) goto fail; if (!sns) goto fail;
if (fact_sample_count <= 0) goto fail; if (fact_sample_count <= 0) goto fail;

View File

@ -142,74 +142,44 @@ fail:
} }
/* RSD2XADP */ /* RSD2XADP */
VGMSTREAM * init_vgmstream_rsd2xadp(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_rsd2xadp(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT];
off_t start_offset; off_t start_offset;
int loop_flag, channel_count;
size_t data_size;
int loop_flag; /* check extension */
int channel_count; if (!check_extensions(streamFile,"rsd"))
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("rsd",filename_extension(filename))) goto fail;
/* check header */
if (read_32bitBE(0x0,streamFile) != 0x52534432) /* RSD2 */
goto fail;
if (read_32bitBE(0x4,streamFile) != 0x58414450) /* XADP */
goto fail; goto fail;
if (read_32bitBE(0x00,streamFile) != 0x52534432) /* RSD2 */
goto fail;
if (read_32bitBE(0x04,streamFile) != 0x58414450) /* XADP */
goto fail;
start_offset = read_32bitLE(0x18,streamFile); /* not sure about this */
data_size = get_streamfile_size(streamFile);
loop_flag = 0; loop_flag = 0;
channel_count = read_32bitLE(0x8,streamFile); channel_count = read_32bitLE(0x08,streamFile);
/* 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 */
start_offset = read_32bitLE(0x18,streamFile); /* not sure about this */
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x10,streamFile); vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
vgmstream->coding_type = coding_XBOX; vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)*64/36/channel_count;
if (loop_flag) {
vgmstream->loop_start_sample = loop_flag;
vgmstream->loop_end_sample = (get_streamfile_size(streamFile)-start_offset)*28/16/channel_count;
}
vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_RSD2XADP; vgmstream->meta_type = meta_RSD2XADP;
/* open the file for reading */ if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
{ goto fail;
int i;
STREAMFILE * file;
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!file) goto fail;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = file;
if (vgmstream->coding_type == coding_XBOX) {
vgmstream->layout_type=layout_none;
vgmstream->ch[i].channel_start_offset=start_offset;
} else {
vgmstream->ch[i].channel_start_offset=
start_offset+vgmstream->interleave_block_size*i;
}
vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;
}
}
return vgmstream; return vgmstream;
fail: fail:
/* clean up anything we may have opened */ close_vgmstream(vgmstream);
if (vgmstream) close_vgmstream(vgmstream);
return NULL; return NULL;
} }
@ -968,25 +938,24 @@ fail:
return NULL; return NULL;
} }
/* RSD6XADP */ /* RSD6XADP - from Crash Tag Team Racing (Xbox) */
VGMSTREAM * init_vgmstream_rsd6xadp(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_rsd6xadp(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT];
off_t start_offset; off_t start_offset;
int loop_flag, channel_count;
size_t data_size;
int loop_flag; /* check extension */
int channel_count; if (!check_extensions(streamFile,"rsd"))
goto fail;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("rsd",filename_extension(filename))) goto fail;
/* check header */
if (read_32bitBE(0x0,streamFile) != 0x52534436) /* RSD6 */ if (read_32bitBE(0x0,streamFile) != 0x52534436) /* RSD6 */
goto fail; goto fail;
if (read_32bitBE(0x4,streamFile) != 0x58414450) /* XADP */ if (read_32bitBE(0x4,streamFile) != 0x58414450) /* XADP */
goto fail; goto fail;
start_offset = 0x800;
data_size = get_streamfile_size(streamFile) - start_offset;
loop_flag = 0; loop_flag = 0;
channel_count = read_32bitLE(0x8,streamFile); channel_count = read_32bitLE(0x8,streamFile);
@ -994,46 +963,19 @@ VGMSTREAM * init_vgmstream_rsd6xadp(STREAMFILE *streamFile) {
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 */
start_offset = 0x800;
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x10,streamFile); vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
vgmstream->coding_type = coding_XBOX; vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)*64/36/channel_count;
if (loop_flag) { vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->loop_start_sample = loop_flag;
vgmstream->loop_end_sample = (get_streamfile_size(streamFile)-start_offset)*28/16/channel_count;
}
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_RSD6XADP; vgmstream->meta_type = meta_RSD6XADP;
/* open the file for reading */ if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
{ goto fail;
int i;
STREAMFILE * file;
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!file) goto fail;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = file;
if (vgmstream->coding_type == coding_XBOX) {
vgmstream->layout_type=layout_none;
vgmstream->ch[i].channel_start_offset=start_offset;
} else {
vgmstream->ch[i].channel_start_offset=
start_offset+vgmstream->interleave_block_size*i;
}
vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;
}
}
return vgmstream; return vgmstream;
fail: fail:
/* clean up anything we may have opened */ close_vgmstream(vgmstream);
if (vgmstream) close_vgmstream(vgmstream);
return NULL; return NULL;
} }

View File

@ -189,13 +189,13 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
vgmstream->num_samples = dsp_bytes_to_samples(stream_size, channel_count); vgmstream->num_samples = dsp_bytes_to_samples(stream_size, channel_count);
break; break;
case 0x936538EF: /* MS-IMA PC (936538EF 11B62D43 957FA71A DE44227A) */ case 0x936538EF: /* XBOX-IMA PC (936538EF 11B62D43 957FA71A DE44227A) */
case 0x2BA22F63: /* MS-IMA Xbox (2BA22F63 DD118F45 AA27A5C3 46E9790E) */ case 0x2BA22F63: /* XBOX-IMA Xbox (2BA22F63 DD118F45 AA27A5C3 46E9790E) */
/* ex. Broken Sword 3 (PC), Jacked (PC/Xbox), Burnout 2 (Xbox) */ /* ex. Broken Sword 3 (PC), Jacked (PC/Xbox), Burnout 2 (Xbox) */
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA; /* PC and Xbox share the same data */
vgmstream->interleave_block_size = 0; /* uses regular XBOX/MS-IMA interleave */ vgmstream->interleave_block_size = 0;
vgmstream->num_samples = ms_ima_bytes_to_samples(stream_size, 0x24 * channel_count, channel_count); vgmstream->num_samples = xbox_ima_bytes_to_samples(stream_size, channel_count);
break; break;
default: default:

View File

@ -55,7 +55,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
vgmstream->meta_type = meta_SAB; vgmstream->meta_type = meta_SAB;
switch(codec) { switch(codec) {
case 0x01: case 0x01: /* PC */
vgmstream->coding_type = coding_PCM16LE; vgmstream->coding_type = coding_PCM16LE;
vgmstream->layout_type = layout_interleave; vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = is_stream ? align : 0x02; vgmstream->interleave_block_size = is_stream ? align : 0x02;
@ -66,7 +66,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
break; break;
case 0x04: case 0x04: /* PS2 */
vgmstream->coding_type = coding_PSX; vgmstream->coding_type = coding_PSX;
vgmstream->layout_type = layout_interleave; vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = is_stream ? align : 0x10; vgmstream->interleave_block_size = is_stream ? align : 0x10;
@ -76,14 +76,14 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
vgmstream->loop_end_sample = ps_bytes_to_samples(loop_end, vgmstream->channels); vgmstream->loop_end_sample = ps_bytes_to_samples(loop_end, vgmstream->channels);
break; break;
case 0x08: case 0x08: /* Xbox */
vgmstream->coding_type = is_stream ? coding_XBOX_int : coding_XBOX; vgmstream->coding_type = is_stream ? coding_XBOX_IMA_int : coding_XBOX_IMA;
vgmstream->layout_type = is_stream ? layout_interleave : layout_none; vgmstream->layout_type = is_stream ? layout_interleave : layout_none;
vgmstream->interleave_block_size = is_stream ? align : 0x00; vgmstream->interleave_block_size = is_stream ? align : 0x00;
vgmstream->num_samples = ms_ima_bytes_to_samples(stream_size, 0x24*vgmstream->channels, vgmstream->channels); vgmstream->num_samples = xbox_ima_bytes_to_samples(stream_size, vgmstream->channels);
vgmstream->loop_start_sample = ms_ima_bytes_to_samples(loop_start, 0x24*vgmstream->channels, vgmstream->channels); vgmstream->loop_start_sample = xbox_ima_bytes_to_samples(loop_start, vgmstream->channels);
vgmstream->loop_end_sample = ms_ima_bytes_to_samples(loop_end, 0x24*vgmstream->channels, vgmstream->channels); vgmstream->loop_end_sample = xbox_ima_bytes_to_samples(loop_end, vgmstream->channels);
break; break;
default: default:

View File

@ -1,7 +1,8 @@
#include "meta.h" #include "meta.h"
#include "../util.h" #include "../coding/coding.h"
/* SEG (found in Eragon) */
/* SEG - found in Eragon */
VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT]; char filename[PATH_LIMIT];
@ -24,7 +25,7 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) {
} }
else if (read_32bitBE(0x04,streamFile) == 0x78627800) /* "xbx\0" */ else if (read_32bitBE(0x04,streamFile) == 0x78627800) /* "xbx\0" */
{ {
coding = coding_XBOX; coding = coding_XBOX_IMA;
} }
else goto fail; else goto fail;
@ -60,9 +61,9 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) {
vgmstream->interleave_block_size = 0x2000; vgmstream->interleave_block_size = 0x2000;
} }
} }
else if (coding_XBOX == coding) else if (coding_XBOX_IMA == coding)
{ {
vgmstream->num_samples = (read_32bitLE(0x0C,streamFile)-start_offset)/36/channel_count*64; vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(0x0C,streamFile)-start_offset, channel_count);
vgmstream->meta_type = meta_XBOX_SEG; vgmstream->meta_type = meta_XBOX_SEG;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
} }

View File

@ -95,7 +95,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
/* type to coding conversion */ /* type to coding conversion */
switch (txth.codec) { switch (txth.codec) {
case PSX: coding = coding_PSX; break; case PSX: coding = coding_PSX; break;
case XBOX: coding = coding_XBOX; break; case XBOX: coding = coding_XBOX_IMA; break;
case NGC_DTK: coding = coding_NGC_DTK; break; case NGC_DTK: coding = coding_NGC_DTK; break;
case PCM16BE: coding = coding_PCM16BE; break; case PCM16BE: coding = coding_PCM16BE; break;
case PCM16LE: coding = coding_PCM16LE; break; case PCM16LE: coding = coding_PCM16LE; break;
@ -205,7 +205,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
vgmstream->interleave_block_size = txth.interleave; vgmstream->interleave_block_size = txth.interleave;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
break; break;
case coding_XBOX: case coding_XBOX_IMA:
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
break; break;
case coding_NGC_DTK: case coding_NGC_DTK:
@ -634,7 +634,7 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) {
if (!txth->interleave) return 0; if (!txth->interleave) return 0;
return ms_ima_bytes_to_samples(bytes, txth->interleave, txth->channels); return ms_ima_bytes_to_samples(bytes, txth->interleave, txth->channels);
case XBOX: case XBOX:
return ms_ima_bytes_to_samples(bytes, 0x24 * txth->channels, txth->channels); return xbox_ima_bytes_to_samples(bytes, txth->channels);
case NGC_DSP: case NGC_DSP:
return dsp_bytes_to_samples(bytes, txth->channels); return dsp_bytes_to_samples(bytes, txth->channels);
case PSX: case PSX:

View File

@ -155,9 +155,9 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
break; break;
case RAW_XBOX: case RAW_XBOX:
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
vgmstream->num_samples = ms_ima_bytes_to_samples(sb.stream_size, 0x24*sb.channels,sb.channels); vgmstream->num_samples = xbox_ima_bytes_to_samples(sb.stream_size, sb.channels);
break; break;
case RAW_DSP: case RAW_DSP:

View File

@ -1,5 +1,6 @@
#include "meta.h" #include "meta.h"
#include "../util.h" #include "../coding/coding.h"
/* /*
const short wad_coef[16][2] = const short wad_coef[16][2] =
{ {
@ -33,8 +34,7 @@ const short wad_coef[16] =
}; };
/* WAC - WAD - WAM (Beyond Good & Evil GC/PS2/Xbox/Wii) */ /* WAC/WAD/WAM/WAA - from Beyond Good & Evil (PS2/Xbox/GC/Wii) */
/* Note: A "Flat Layout" has no interleave */
VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT]; char filename[PATH_LIMIT];
@ -56,7 +56,7 @@ VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) {
/* check header */ /* check header */
if (read_32bitBE(0x00,streamFile) != 0x52494646 || /* "RIFF" */ if (read_32bitBE(0x00,streamFile) != 0x52494646 || /* "RIFF" */
read_32bitBE(0x08,streamFile) != 0x57415645 || /* "WAVE" */ read_32bitBE(0x08,streamFile) != 0x57415645 || /* "WAVE" */
read_32bitBE(0x0C,streamFile) != 0x666D7420 || /* "fmt\0x20" */ read_32bitBE(0x0C,streamFile) != 0x666D7420 || /* "fmt " */
read_32bitBE(0x10,streamFile) != 0x12000000) /* "0x12000000" */ read_32bitBE(0x10,streamFile) != 0x12000000) /* "0x12000000" */
goto fail; goto fail;
@ -84,11 +84,11 @@ VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) {
switch((uint16_t)read_16bitLE(0x14,streamFile)) { switch((uint16_t)read_16bitLE(0x14,streamFile)) {
case 0x0069: // XBOX IMA ADPCM case 0x0069: // XBOX IMA ADPCM
start_offset = 0x2E; start_offset = 0x2E;
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/36/channel_count*64; vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(0x2A,streamFile), channel_count);
if (loop_flag) { if (loop_flag) {
vgmstream->loop_start_sample = 0; vgmstream->loop_start_sample = 0;
vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/36/channel_count*64; vgmstream->loop_end_sample = xbox_ima_bytes_to_samples(read_32bitLE(0x2A,streamFile),channel_count);
} }
break; break;
case 0xFFFF: // PS2 ADPCM case 0xFFFF: // PS2 ADPCM
@ -154,7 +154,7 @@ VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) {
for (i=0;i<channel_count;i++) { for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = file; vgmstream->ch[i].streamfile = file;
if (vgmstream->coding_type == coding_XBOX) { if (vgmstream->coding_type == coding_XBOX_IMA) {
/* xbox interleaving is a little odd */ /* xbox interleaving is a little odd */
vgmstream->ch[i].channel_start_offset=start_offset; vgmstream->ch[i].channel_start_offset=start_offset;
} else { } else {

View File

@ -1,68 +1,50 @@
#include "meta.h" #include "meta.h"
#include "../util.h" #include "../coding/coding.h"
/*
WVS (found in Metal Arms - Glitch in the System)
XBOX and GameCube
*/
/* WVS - found in Metal Arms - Glitch in the System (Xbox) */
VGMSTREAM * init_vgmstream_xbox_wvs(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_xbox_wvs(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT]; off_t start_offset;
int loop_flag, channel_count;
size_t data_size;
int loop_flag=0;
int channel_count;
int i;
/* check extension, case insensitive */ /* check extension */
streamFile->get_name(streamFile,filename,sizeof(filename)); if (!check_extensions(streamFile,"wvs"))
if (strcasecmp("wvs",filename_extension(filename))) goto fail;
if((read_16bitLE(0x0C,streamFile)!=0x69) &&
(read_16bitLE(0x08,streamFile)!=0x4400) &&
(read_32bitLE(0x0,streamFile)!=get_streamfile_size(streamFile)+0x20))
goto fail; goto fail;
/* Loop seems to be set if offset(0x0A) == 0x472C */ if (read_16bitLE(0x0C,streamFile) != 0x69 && /* codec */
loop_flag = (read_16bitLE(0x0A,streamFile)==0x472C); read_16bitLE(0x08,streamFile) != 0x4400)
goto fail;
/* Always stereo files */ start_offset = 0x20;
channel_count=read_16bitLE(0x0E,streamFile); data_size = read_32bitLE(0x00,streamFile);
loop_flag = (read_16bitLE(0x0a,streamFile) == 0x472C); /* loop seems to be like this */
channel_count = read_16bitLE(0x0e,streamFile); /* always stereo files */
if (data_size + start_offset != get_streamfile_size(streamFile))
goto fail;
/* 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 */
/* allways 2 channels @ 44100 Hz */
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x10,streamFile); vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
vgmstream->loop_start_sample = 0;
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->num_samples = read_32bitLE(0,streamFile) / 36 * 64 / vgmstream->channels;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_XBOX_WVS; vgmstream->meta_type = meta_XBOX_WVS;
if(loop_flag) {
vgmstream->loop_start_sample=0;
vgmstream->loop_end_sample=vgmstream->num_samples;
}
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
vgmstream->ch[i].offset = 0x20;
if (!vgmstream->ch[i].streamfile) goto fail;
}
}
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
goto fail;
return vgmstream; return vgmstream;
/* clean up anything we may have opened */
fail: fail:
if (vgmstream) close_vgmstream(vgmstream); close_vgmstream(vgmstream);
return NULL; return NULL;
} }

View File

@ -58,11 +58,11 @@ VGMSTREAM * init_vgmstream_xau(STREAMFILE *streamFile) {
goto fail; goto fail;
vgmstream->sample_rate = read_32bitLE(0x58, streamFile); vgmstream->sample_rate = read_32bitLE(0x58, streamFile);
vgmstream->num_samples = ms_ima_bytes_to_samples(read_32bitLE(start_offset-4, streamFile), read_16bitLE(0x60, streamFile), channel_count); vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(start_offset-4, streamFile), channel_count);
vgmstream->loop_start_sample = loop_start; vgmstream->loop_start_sample = loop_start;
vgmstream->loop_end_sample = loop_end; vgmstream->loop_end_sample = loop_end;
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
break; break;

View File

@ -29,8 +29,8 @@ VGMSTREAM * init_vgmstream_xbox_matx(STREAMFILE *streamFile) {
/* fill in the vital statistics */ /* fill in the vital statistics */
vgmstream->channels = channel_count; vgmstream->channels = channel_count;
vgmstream->sample_rate = read_16bitLE(0x06,streamFile) & 0xffff; vgmstream->sample_rate = read_16bitLE(0x06,streamFile) & 0xffff;
vgmstream->coding_type = coding_XBOX;
vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type = layout_matx_blocked; vgmstream->layout_type = layout_matx_blocked;
vgmstream->meta_type = meta_XBOX_MATX; vgmstream->meta_type = meta_XBOX_MATX;

View File

@ -1,62 +1,37 @@
#include "meta.h" #include "meta.h"
#include "../util.h" #include "../coding/coding.h"
/* WAVM
WAVM is an headerless format which can be found on XBOX
known extensions : WAVM
2008-05-23 - Fastelbja : First version ...
*/
/* WAVM - headerless format which can be found on XBOX */
VGMSTREAM * init_vgmstream_xbox_wavm(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_xbox_wavm(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT]; off_t start_offset = 0;
int loop_flag, channel_count;
int loop_flag=0; /* check extension */
int channel_count; if (!check_extensions(streamFile,"wavm"))
int i; goto fail;
/* check extension, case insensitive */ start_offset = 0;
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("wavm",filename_extension(filename))) goto fail;
/* No loop on wavm */
loop_flag = 0; loop_flag = 0;
/* Always stereo files */
channel_count = 2; channel_count = 2;
/* 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 */
/* allways 2 channels @ 44100 Hz */
vgmstream->channels = 2;
vgmstream->sample_rate = 44100; vgmstream->sample_rate = 44100;
vgmstream->num_samples = xbox_ima_bytes_to_samples(get_streamfile_size(streamFile), vgmstream->channels);
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->num_samples = (int32_t)(get_streamfile_size(streamFile) / 36 * 64 / vgmstream->channels);
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_XBOX_WAVM; vgmstream->meta_type = meta_XBOX_WAVM;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
vgmstream->ch[i].offset = 0;
if (!vgmstream->ch[i].streamfile) goto fail;
}
}
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
goto fail;
return vgmstream; return vgmstream;
/* clean up anything we may have opened */
fail: fail:
if (vgmstream) close_vgmstream(vgmstream); close_vgmstream(vgmstream);
return NULL; return NULL;
} }

View File

@ -1,65 +1,44 @@
#include "meta.h" #include "meta.h"
#include "../util.h" #include "../coding/coding.h"
/* XMU
XMU (found in Alter Echo)
*/
/* XMU- found in Alter Echo (Xbox) */
VGMSTREAM * init_vgmstream_xbox_xmu(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_xbox_xmu(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT]; size_t start_offset;
int loop_flag, channel_count;
size_t data_size;
int loop_flag=0; /* check extension */
int channel_count; if (!check_extensions(streamFile,"xmu"))
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("xmu",filename_extension(filename))) goto fail;
if((read_32bitBE(0x00,streamFile)!=0x584D5520) &&
(read_32bitBE(0x08,streamFile)!=0x46524D54))
goto fail; goto fail;
/* No Loop found atm */ if (read_32bitBE(0x00,streamFile) != 0x584D5520 && /* "XMU " */
loop_flag = read_8bit(0x16,streamFile);; read_32bitBE(0x08,streamFile) != 0x46524D54) /* "FRMT" */
goto fail;
/* Always stereo files */ start_offset = 0x800;
channel_count=read_8bit(0x14,streamFile); channel_count=read_8bit(0x14,streamFile); /* always stereo files */
loop_flag = read_8bit(0x16,streamFile); /* no Loop found atm */
data_size = read_32bitLE(0x7FC,streamFile); /* next to "DATA" */
/* 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 */
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x10,streamFile); vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
vgmstream->loop_start_sample = 0;
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->num_samples = read_32bitLE(0x7FC,streamFile) / 36 * 64 / vgmstream->channels;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_XBOX_XMU; vgmstream->meta_type = meta_XBOX_XMU;
if(loop_flag) { if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
vgmstream->loop_start_sample=0; goto fail;
vgmstream->loop_end_sample=vgmstream->num_samples;
}
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
vgmstream->ch[i].offset = 0x800;
if (!vgmstream->ch[i].streamfile) goto fail;
}
}
return vgmstream; return vgmstream;
/* clean up anything we may have opened */
fail: fail:
if (vgmstream) close_vgmstream(vgmstream); close_vgmstream(vgmstream);
return NULL; return NULL;
} }

View File

@ -1,72 +1,52 @@
#include "meta.h" #include "meta.h"
#include "../layout/layout.h" #include "../layout/layout.h"
#include "../util.h" #include "../coding/coding.h"
/* XVAS
XVAS (found in TMNT 2 & TMNT 3))
*/
/* XVAS - found in TMNT 2 & TMNT 3 (Xbox) */
VGMSTREAM * init_vgmstream_xbox_xvas(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_xbox_xvas(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT]; off_t start_offset;
int loop_flag, channel_count;
size_t data_size;
int loop_flag=0; /* check extension */
int channel_count; if (!check_extensions(streamFile,"xvas"))
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("xvas",filename_extension(filename))) goto fail;
if((read_32bitLE(0x00,streamFile)!=0x69) &&
(read_32bitLE(0x08,streamFile)!=0x48))
goto fail; goto fail;
/* No Loop found atm */ if (read_32bitLE(0x00,streamFile) != 0x69 && /* codec */
loop_flag = (read_32bitLE(0x14,streamFile)==read_32bitLE(0x24,streamFile)); read_32bitLE(0x08,streamFile) != 0x48) /* block size (probably 0x24 for mono) */
goto fail;
/* Always stereo files */ start_offset = 0x800;
channel_count=read_32bitLE(0x04,streamFile); channel_count = read_32bitLE(0x04,streamFile); /* always stereo files */
loop_flag = (read_32bitLE(0x14,streamFile) == read_32bitLE(0x24,streamFile));
data_size = read_32bitLE(0x24,streamFile);
data_size -= (data_size / 0x20000) * 0x20; /* blocks of 0x20000 with padding */
/* 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 */
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x0c,streamFile); vgmstream->sample_rate = read_32bitLE(0x0c,streamFile);
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
vgmstream->coding_type = coding_XBOX;
vgmstream->num_samples = read_32bitLE(0x24,streamFile);
vgmstream->num_samples -= ((vgmstream->num_samples/0x20000)*0x20);
vgmstream->num_samples = vgmstream->num_samples / 36 * 64 / vgmstream->channels;
vgmstream->layout_type = layout_xvas_blocked;
vgmstream->meta_type = meta_XBOX_XVAS;
if(loop_flag) { if(loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x10,streamFile); size_t loop_size = read_32bitLE(0x10,streamFile);
vgmstream->loop_start_sample -= ((vgmstream->loop_start_sample/0x20000)*0x20); loop_size -= (loop_size / 0x20000) * 0x20;
vgmstream->loop_start_sample = vgmstream->loop_start_sample / 36 * 64 / vgmstream->channels; vgmstream->loop_start_sample = xbox_ima_bytes_to_samples(loop_size, vgmstream->channels);
vgmstream->loop_end_sample = vgmstream->num_samples; vgmstream->loop_end_sample = vgmstream->num_samples;
} }
/* open the file for reading by each channel */ vgmstream->coding_type = coding_XBOX_IMA;
{ vgmstream->layout_type = layout_xvas_blocked;
for (i=0;i<channel_count;i++) { vgmstream->meta_type = meta_XBOX_XVAS;
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36);
vgmstream->ch[i].offset = 0x800;
if (!vgmstream->ch[i].streamfile) goto fail; if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
} goto fail;
}
xvas_block_update(0x800,vgmstream); xvas_block_update(start_offset,vgmstream);
return vgmstream; return vgmstream;
/* clean up anything we may have opened */
fail: fail:
if (vgmstream) close_vgmstream(vgmstream); close_vgmstream(vgmstream);
return NULL; return NULL;
} }

View File

@ -1,97 +1,82 @@
#include "meta.h" #include "meta.h"
#include "../util.h" #include "../coding/coding.h"
/* XWAV
XWAV use the common RIFF/WAVE format with Codec ID = 0x0069
It has been renamed to xwav to avoid vgmstream to handle all RIFF/WAV format
known extensions : XWAV
2008-05-24 - Fastelbja : First version ...
*/
/* XWAV - renamed WAV with XBOX-IMA
* (could be parsed as RIFF/.lwav but has a custom loop chunk and multichannel) */
VGMSTREAM * init_vgmstream_xbox_xwav(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_xbox_xwav(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT]; int loop_flag, channel_count;
int loop_flag=0;
int channel_count;
off_t start_offset; off_t start_offset;
int i,j=0;
/* check extension, case insensitive */ /* check extension */
streamFile->get_name(streamFile,filename,sizeof(filename)); if (!check_extensions(streamFile,"xwav"))
if (strcasecmp("xwav",filename_extension(filename))) goto fail;
/* Check for headers */
if(!((read_32bitBE(0x00,streamFile)==0x52494646) &&
(read_32bitBE(0x08,streamFile)==0x57415645) &&
(read_32bitBE(0x0C,streamFile)==0x666D7420) &&
(read_16bitLE(0x14,streamFile)==0x0069)))
goto fail; goto fail;
/* No loop on wavm */ /* check for headers */
if(read_32bitBE(0x28,streamFile)==0x77736D70) if(!((read_32bitBE(0x00,streamFile) == 0x52494646) && /* "RIFF" */
loop_flag = 1; (read_32bitBE(0x08,streamFile) == 0x57415645) && /* "WAVE" */
else (read_32bitBE(0x0C,streamFile) == 0x666D7420) && /* "fmt " */
loop_flag = 0; (read_16bitLE(0x14,streamFile) == 0x0069))) /* codec */
goto fail;
/* Always stereo files */ /* loop chunk found on Koei/Omega Force games [Crimson Sea, Dynasty Warriors 5] */
loop_flag = (read_32bitBE(0x28,streamFile) == 0x77736D70); /* "wsmp" */
channel_count = read_16bitLE(0x16,streamFile); channel_count = read_16bitLE(0x16,streamFile);
/* search for "data" */
start_offset = 0x1C;
do {
if (read_32bitBE(start_offset,streamFile)==0x64617461)
break;
start_offset += 0x04;
} while (start_offset < (off_t)get_streamfile_size(streamFile));
if (start_offset >= (off_t)get_streamfile_size(streamFile))
goto fail;
start_offset += 0x04;
/* 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;
/* hack for loop wave found on Dynasty warriors */ vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(start_offset,streamFile), vgmstream->channels);
vgmstream->sample_rate = read_32bitLE(0x18,streamFile);
if (loop_flag) { if (loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x4C,streamFile); vgmstream->loop_start_sample = read_32bitLE(0x4C,streamFile);
vgmstream->loop_end_sample = vgmstream->loop_start_sample + read_32bitLE(0x50,streamFile); vgmstream->loop_end_sample = vgmstream->loop_start_sample + read_32bitLE(0x50,streamFile);
} }
/* fill in the vital statistics */ vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x18,streamFile);
/* search for "data" */
start_offset=0x1C;
do {
if(read_32bitBE(start_offset,streamFile)==0x64617461)
break;
start_offset+=4;
} while (start_offset<(off_t)get_streamfile_size(streamFile));
if(start_offset>=(off_t)get_streamfile_size(streamFile))
goto fail;
start_offset+=4;
vgmstream->coding_type = coding_XBOX;
vgmstream->num_samples = read_32bitLE(start_offset,streamFile) / 36 * 64 / vgmstream->channels;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_XBOX_RIFF; vgmstream->meta_type = meta_XBOX_RIFF;
/* open the file for reading by each channel */ //if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
// goto fail;
//custom init
{ {
if(channel_count>2) { int i, ch;
for (i=0;i<channel_count;i++,j++) { char filename[PATH_LIMIT];
if((j&2) && (i!=0)) { streamFile->get_name(streamFile,filename,sizeof(filename));
j=0;
start_offset+=36*2; if (channel_count > 2) { /* multichannel interleaved init */
for (i=0, ch=0;i<channel_count;i++,ch++) {
if ((ch&2) && (i!=0)) {
ch = 0;
start_offset += 0x24*2;
} }
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36); vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x24);
vgmstream->ch[i].offset = start_offset+4; vgmstream->ch[i].offset = start_offset + 0x04;
if (!vgmstream->ch[i].streamfile) goto fail; if (!vgmstream->ch[i].streamfile) goto fail;
} }
} else { }
else {
for (i=0; i < channel_count; i++) { for (i=0; i < channel_count; i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36); vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x24);
vgmstream->ch[i].offset = start_offset+4; vgmstream->ch[i].offset = start_offset + 0x04;
if (!vgmstream->ch[i].streamfile) goto fail; if (!vgmstream->ch[i].streamfile) goto fail;
} }
@ -100,8 +85,7 @@ VGMSTREAM * init_vgmstream_xbox_xwav(STREAMFILE *streamFile) {
return vgmstream; return vgmstream;
/* clean up anything we may have opened */
fail: fail:
if (vgmstream) close_vgmstream(vgmstream); close_vgmstream(vgmstream);
return NULL; return NULL;
} }

View File

@ -295,11 +295,11 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
} }
} }
else if (xwb.version <= XACT1_1_MAX && xwb.codec == XBOX_ADPCM) { else if (xwb.version <= XACT1_1_MAX && xwb.codec == XBOX_ADPCM) {
xwb.block_align = 0x24 * xwb.channels; xwb.block_align = 0x24 * xwb.channels; /* not really needed... */
xwb.num_samples = ms_ima_bytes_to_samples(xwb.stream_size, xwb.block_align, xwb.channels); xwb.num_samples = xbox_ima_bytes_to_samples(xwb.stream_size, xwb.channels);
if (xwb.loop_flag) { if (xwb.loop_flag) {
xwb.loop_start_sample = ms_ima_bytes_to_samples(xwb.loop_start, xwb.block_align, xwb.channels); xwb.loop_start_sample = xbox_ima_bytes_to_samples(xwb.loop_start, xwb.channels);
xwb.loop_end_sample = ms_ima_bytes_to_samples(xwb.loop_start + xwb.loop_end, xwb.block_align, xwb.channels); xwb.loop_end_sample = xbox_ima_bytes_to_samples(xwb.loop_start + xwb.loop_end, xwb.channels);
} }
} }
else if (xwb.version <= XACT2_2_MAX && xwb.codec == MS_ADPCM && xwb.loop_flag) { else if (xwb.version <= XACT2_2_MAX && xwb.codec == MS_ADPCM && xwb.loop_flag) {
@ -367,7 +367,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
break; break;
case XBOX_ADPCM: /* Silent Hill 4 (Xbox) */ case XBOX_ADPCM: /* Silent Hill 4 (Xbox) */
vgmstream->coding_type = coding_XBOX; vgmstream->coding_type = coding_XBOX_IMA;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
break; break;

View File

@ -1069,8 +1069,8 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
case coding_DVI_IMA_int: case coding_DVI_IMA_int:
case coding_3DS_IMA: case coding_3DS_IMA:
return 2; return 2;
case coding_XBOX: case coding_XBOX_IMA:
case coding_XBOX_int: case coding_XBOX_IMA_int:
case coding_FSB_IMA: case coding_FSB_IMA:
return 64; return 64;
case coding_APPLE_IMA4: case coding_APPLE_IMA4:
@ -1238,8 +1238,8 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
return 0; return 0;
case coding_UBI_IMA: /* variable (PCM then IMA) */ case coding_UBI_IMA: /* variable (PCM then IMA) */
return 0; return 0;
case coding_XBOX: case coding_XBOX_IMA:
case coding_XBOX_int: case coding_XBOX_IMA_int:
case coding_FSB_IMA: case coding_FSB_IMA:
return 0x24; return 0x24;
case coding_APPLE_IMA4: case coding_APPLE_IMA4:
@ -1493,14 +1493,14 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
samples_to_do); samples_to_do);
} }
break; break;
case coding_XBOX: case coding_XBOX_IMA:
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,
vgmstream->channels,vgmstream->samples_into_block, vgmstream->channels,vgmstream->samples_into_block,
samples_to_do,chan); samples_to_do,chan);
} }
break; break;
case coding_XBOX_int: case coding_XBOX_IMA_int:
for (chan=0;chan<vgmstream->channels;chan++) { for (chan=0;chan<vgmstream->channels;chan++) {
decode_xbox_ima_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan, decode_xbox_ima_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
vgmstream->channels,vgmstream->samples_into_block, vgmstream->channels,vgmstream->samples_into_block,

View File

@ -127,8 +127,8 @@ typedef enum {
coding_DVI_IMA_int, /* DVI IMA ADPCM (mono/interleave, high nibble first) */ coding_DVI_IMA_int, /* DVI IMA ADPCM (mono/interleave, high nibble first) */
coding_3DS_IMA, /* 3DS IMA ADPCM */ coding_3DS_IMA, /* 3DS IMA ADPCM */
coding_MS_IMA, /* Microsoft IMA ADPCM */ coding_MS_IMA, /* Microsoft IMA ADPCM */
coding_XBOX, /* XBOX IMA ADPCM */ coding_XBOX_IMA, /* XBOX IMA ADPCM */
coding_XBOX_int, /* XBOX IMA ADPCM (interleaved) */ coding_XBOX_IMA_int, /* XBOX IMA ADPCM (interleaved/mono) */
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */ coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */ coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */
coding_RAD_IMA, /* Radical IMA ADPCM */ coding_RAD_IMA, /* Radical IMA ADPCM */