diff --git a/src/coding/coding.h b/src/coding/coding.h index dbca81d4..d3a350f8 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -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_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); -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 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); /* ngc_dsp_decoder */ diff --git a/src/coding/ima_decoder.c b/src/coding/ima_decoder.c index 6cc343e7..0f00c444 100644 --- a/src/coding/ima_decoder.c +++ b/src/coding/ima_decoder.c @@ -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) { /* 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 + ((bytes % block_align) ? ((bytes % block_align) - 4 * channels) * 2 / channels : 0); } -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 xbox_ima_bytes_to_samples(size_t bytes, int channels) { + int block_align = 0x24 * 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) { diff --git a/src/formats.c b/src/formats.c index 068331c0..d03539d6 100644 --- a/src/formats.c +++ b/src/formats.c @@ -470,8 +470,8 @@ static const coding_info coding_info_list[] = { {coding_DVI_IMA_int, "Intel DVI 4-bit IMA ADPCM (mono/interleave)"}, {coding_3DS_IMA, "3DS IMA 4-bit ADPCM"}, {coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"}, - {coding_XBOX, "XBOX 4-bit IMA ADPCM"}, - {coding_XBOX_int, "XBOX 4-bit IMA ADPCM (mono/interleave)"}, + {coding_XBOX_IMA, "XBOX 4-bit IMA ADPCM"}, + {coding_XBOX_IMA_int, "XBOX 4-bit IMA ADPCM (mono/interleave)"}, {coding_NDS_IMA, "NDS-style 4-bit IMA ADPCM"}, {coding_DAT4_IMA, "Eurocom DAT4 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_ILD, "ILD header"}, {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_DSP_STR, "assumed Conan Gamecube STR File by .str extension"}, {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_V2, "variant of Sega Stream Asset Builder 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_DC_IDVI, "Capcom IDVI header"}, {meta_KRAW, "Geometry Wars: Galaxies KRAW header"}, diff --git a/src/meta/ads.c b/src/meta/ads.c index 43ec72e8..692531ec 100644 --- a/src/meta/ads.c +++ b/src/meta/ads.c @@ -6,38 +6,33 @@ VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; off_t start_offset; - int loop_flag; - int channel_count; - int identifer_byte; + int loop_flag, channel_count, codec; + /* check extension, case insensitive */ if (!check_extensions(streamFile,"ads")) goto fail; - /* check dhSS Header */ - if (read_32bitBE(0x00,streamFile) != 0x64685353) + if (read_32bitBE(0x00,streamFile) != 0x64685353) /* "dhSS" */ goto fail; - - /* check dbSS Header */ - if (read_32bitBE(0x20,streamFile) != 0x64625353) + if (read_32bitBE(0x20,streamFile) != 0x64625353) /* "dbSS" */ goto fail; loop_flag = 1; channel_count = read_32bitBE(0x10,streamFile); - if (channel_count > 0x2) + if (channel_count > 2) goto fail; /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - identifer_byte = read_32bitBE(0x08,streamFile); - switch (identifer_byte) { + vgmstream->sample_rate = read_32bitBE(0x0c,streamFile); + + codec = read_32bitBE(0x08,streamFile); + switch (codec) { case 0x00000020: /* GC */ start_offset = 0x28 + 0x60 * channel_count; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x0c,streamFile); vgmstream->coding_type = coding_NGC_DSP; vgmstream->num_samples = read_32bitBE(0x28,streamFile); if (loop_flag) { @@ -45,9 +40,9 @@ VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) { vgmstream->loop_end_sample = vgmstream->num_samples; } - if (channel_count == 1){ + if (channel_count == 1) { vgmstream->layout_type = layout_none; - } else if (channel_count == 2){ + } else if (channel_count == 2) { vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = read_32bitBE(0x14,streamFile); } @@ -57,10 +52,8 @@ VGMSTREAM * init_vgmstream_ads(STREAMFILE *streamFile) { case 0x00000021: /* Xbox */ start_offset = 0x28; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x0c,streamFile); - vgmstream->coding_type = coding_XBOX_int; - vgmstream->num_samples = (read_32bitBE(0x24,streamFile) / 36 *64 / vgmstream->channels); + vgmstream->coding_type = coding_XBOX_IMA_int; + vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitBE(0x24,streamFile), vgmstream->channels); vgmstream->layout_type = channel_count == 1 ? layout_none : layout_interleave; vgmstream->interleave_block_size = 0x24; if (loop_flag) { diff --git a/src/meta/ea_schl.c b/src/meta/ea_schl.c index 1943a6cd..c6986f66 100644 --- a/src/meta/ea_schl.c +++ b/src/meta/ea_schl.c @@ -292,7 +292,7 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE *streamFile, ea_ break; case EA_CODEC2_XBOXADPCM: /* XBOX IMA (interleaved mono) */ - vgmstream->coding_type = coding_XBOX_int; + vgmstream->coding_type = coding_XBOX_IMA_int; break; case EA_CODEC2_GCADPCM: /* DSP */ diff --git a/src/meta/fsb.c b/src/meta/fsb.c index 6a6bbf53..1e55bc7e 100644 --- a/src/meta/fsb.c +++ b/src/meta/fsb.c @@ -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 * (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; /* "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 */ diff --git a/src/meta/fsb5.c b/src/meta/fsb5.c index 0d79502b..99bf7d51 100644 --- a/src/meta/fsb5.c +++ b/src/meta/fsb5.c @@ -237,7 +237,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) { break; 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; break; diff --git a/src/meta/genh.c b/src/meta/genh.c index d0a451da..ea67480a 100644 --- a/src/meta/genh.c +++ b/src/meta/genh.c @@ -84,7 +84,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { /* type to coding conversion */ switch (genh.codec) { 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 PCM16BE: coding = coding_PCM16BE; break; case PCM16LE: coding = coding_PCM16LE; break; @@ -194,7 +194,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { vgmstream->interleave_block_size = genh.interleave; vgmstream->layout_type = layout_none; break; - case coding_XBOX: + case coding_XBOX_IMA: vgmstream->layout_type = layout_none; break; case coding_NGC_DTK: diff --git a/src/meta/mss.c b/src/meta/mss.c index 3f67310b..c7a1d15e 100644 --- a/src/meta/mss.c +++ b/src/meta/mss.c @@ -18,6 +18,8 @@ VGMSTREAM * init_vgmstream_mss(STREAMFILE *streamFile) { loop_flag = 0; 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 */ vgmstream = allocate_vgmstream(channel_count,loop_flag); @@ -36,14 +38,12 @@ VGMSTREAM * init_vgmstream_mss(STREAMFILE *streamFile) { /* no other way to know */ if (vgmstream->interleave_block_size == 0x4800) { /* interleaved stereo streams (2ch 0x4800 + 2ch 0x4800 = 4ch) */ - vgmstream->coding_type = coding_XBOX; + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_interleave; /* header values are somehow off? */ data_size = get_streamfile_size(streamFile); - vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, 0x24*vgmstream->channels, vgmstream->channels); - - vgmstream->channels = 2; //todo add support for interleave stereo streams + vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels); } else { /* 0x800 interleave */ diff --git a/src/meta/ps2_aus.c b/src/meta/ps2_aus.c index 24bb3883..26a57163 100644 --- a/src/meta/ps2_aus.c +++ b/src/meta/ps2_aus.c @@ -31,7 +31,7 @@ VGMSTREAM * init_vgmstream_aus(STREAMFILE *streamFile) { vgmstream->num_samples = read_32bitLE(0x08,streamFile); if(read_16bitLE(0x06,streamFile)==0x02) { - vgmstream->coding_type = coding_XBOX; + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type=layout_none; } else { vgmstream->coding_type = coding_PSX; diff --git a/src/meta/riff.c b/src/meta/riff.c index 00520b3f..6200fda2 100644 --- a/src/meta/riff.c +++ b/src/meta/riff.c @@ -131,12 +131,12 @@ static int read_fmt(int big_endian, STREAMFILE * streamFile, off_t current_chunk fmt->coding_type = coding_MS_IMA; 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; - fmt->coding_type = coding_MS_IMA; + fmt->coding_type = coding_XBOX_IMA; 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 */ if (!check_extensions(streamFile,"med")) goto fail; @@ -228,8 +228,8 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) { size_t file_size, riff_size, data_size = 0; off_t start_offset = 0; - int fact_sample_count = -1; - int fact_sample_skip = -1; + int fact_sample_count = 0; + int fact_sample_skip = 0; int loop_flag = 0; long loop_start_ms = -1; @@ -355,7 +355,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) { mwv_ctrl_offset = current_chunk; break; 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); } else if ((at3 || at9) && chunk_size == 0x08) { fact_sample_count = read_32bitLE(current_chunk+0x08, streamFile); @@ -443,6 +445,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) { case coding_MS_IMA: vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count); break; + case coding_XBOX_IMA: + vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, fmt.channel_count); + break; case coding_NGC_DSP: if (!sns) goto fail; if (fact_sample_count <= 0) goto fail; diff --git a/src/meta/rsd.c b/src/meta/rsd.c index 34d04156..ca1beed1 100644 --- a/src/meta/rsd.c +++ b/src/meta/rsd.c @@ -142,74 +142,44 @@ fail: } - /* RSD2XADP */ VGMSTREAM * init_vgmstream_rsd2xadp(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; off_t start_offset; + int loop_flag, channel_count; + size_t data_size; - int loop_flag; - int channel_count; - - /* 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 */ + /* check extension */ + if (!check_extensions(streamFile,"rsd")) 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; - 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); 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->coding_type = coding_XBOX; - 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->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels); + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_none; vgmstream->meta_type = meta_RSD2XADP; - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[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; + if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) + goto fail; + return vgmstream; fail: - /* clean up anything we may have opened */ - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } @@ -968,72 +938,44 @@ fail: return NULL; } -/* RSD6XADP */ +/* RSD6XADP - from Crash Tag Team Racing (Xbox) */ VGMSTREAM * init_vgmstream_rsd6xadp(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; off_t start_offset; + int loop_flag, channel_count; + size_t data_size; - int loop_flag; - int channel_count; - - /* 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 */ - goto fail; - if (read_32bitBE(0x4,streamFile) != 0x58414450) /* XADP */ + /* check extension */ + if (!check_extensions(streamFile,"rsd")) goto fail; + if (read_32bitBE(0x0,streamFile) != 0x52534436) /* RSD6 */ + goto fail; + if (read_32bitBE(0x4,streamFile) != 0x58414450) /* XADP */ + goto fail; + + start_offset = 0x800; + data_size = get_streamfile_size(streamFile) - start_offset; loop_flag = 0; channel_count = read_32bitLE(0x8,streamFile); - - /* build the VGMSTREAM */ + + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x800; - vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitLE(0x10,streamFile); - vgmstream->coding_type = coding_XBOX; - 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->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels); + + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_none; vgmstream->meta_type = meta_RSD6XADP; - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[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; + if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) + goto fail; + return vgmstream; fail: - /* clean up anything we may have opened */ - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } diff --git a/src/meta/rws.c b/src/meta/rws.c index 3594eb45..0f4796f1 100644 --- a/src/meta/rws.c +++ b/src/meta/rws.c @@ -189,13 +189,13 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) { vgmstream->num_samples = dsp_bytes_to_samples(stream_size, channel_count); break; - case 0x936538EF: /* MS-IMA PC (936538EF 11B62D43 957FA71A DE44227A) */ - case 0x2BA22F63: /* MS-IMA Xbox (2BA22F63 DD118F45 AA27A5C3 46E9790E) */ + case 0x936538EF: /* XBOX-IMA PC (936538EF 11B62D43 957FA71A DE44227A) */ + case 0x2BA22F63: /* XBOX-IMA Xbox (2BA22F63 DD118F45 AA27A5C3 46E9790E) */ /* ex. Broken Sword 3 (PC), Jacked (PC/Xbox), Burnout 2 (Xbox) */ - vgmstream->coding_type = coding_XBOX; - vgmstream->interleave_block_size = 0; /* uses regular XBOX/MS-IMA interleave */ + vgmstream->coding_type = coding_XBOX_IMA; /* PC and Xbox share the same data */ + 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; default: diff --git a/src/meta/sab.c b/src/meta/sab.c index 8532e478..6ce952b1 100644 --- a/src/meta/sab.c +++ b/src/meta/sab.c @@ -55,7 +55,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) { vgmstream->meta_type = meta_SAB; switch(codec) { - case 0x01: + case 0x01: /* PC */ vgmstream->coding_type = coding_PCM16LE; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = is_stream ? align : 0x02; @@ -66,7 +66,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) { break; - case 0x04: + case 0x04: /* PS2 */ vgmstream->coding_type = coding_PSX; vgmstream->layout_type = layout_interleave; 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); break; - case 0x08: - vgmstream->coding_type = is_stream ? coding_XBOX_int : coding_XBOX; + case 0x08: /* Xbox */ + vgmstream->coding_type = is_stream ? coding_XBOX_IMA_int : coding_XBOX_IMA; vgmstream->layout_type = is_stream ? layout_interleave : layout_none; vgmstream->interleave_block_size = is_stream ? align : 0x00; - vgmstream->num_samples = ms_ima_bytes_to_samples(stream_size, 0x24*vgmstream->channels, vgmstream->channels); - vgmstream->loop_start_sample = ms_ima_bytes_to_samples(loop_start, 0x24*vgmstream->channels, vgmstream->channels); - vgmstream->loop_end_sample = ms_ima_bytes_to_samples(loop_end, 0x24*vgmstream->channels, vgmstream->channels); + vgmstream->num_samples = xbox_ima_bytes_to_samples(stream_size, vgmstream->channels); + vgmstream->loop_start_sample = xbox_ima_bytes_to_samples(loop_start, vgmstream->channels); + vgmstream->loop_end_sample = xbox_ima_bytes_to_samples(loop_end, vgmstream->channels); break; default: diff --git a/src/meta/seg.c b/src/meta/seg.c index 1a15ceda..7aa3cbea 100644 --- a/src/meta/seg.c +++ b/src/meta/seg.c @@ -1,7 +1,8 @@ #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 * vgmstream = NULL; char filename[PATH_LIMIT]; @@ -24,7 +25,7 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { } else if (read_32bitBE(0x04,streamFile) == 0x78627800) /* "xbx\0" */ { - coding = coding_XBOX; + coding = coding_XBOX_IMA; } else goto fail; @@ -60,9 +61,9 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { 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->layout_type = layout_none; } diff --git a/src/meta/txth.c b/src/meta/txth.c index 40f681ce..82d6e560 100644 --- a/src/meta/txth.c +++ b/src/meta/txth.c @@ -95,7 +95,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { /* type to coding conversion */ switch (txth.codec) { 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 PCM16BE: coding = coding_PCM16BE; break; case PCM16LE: coding = coding_PCM16LE; break; @@ -205,7 +205,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { vgmstream->interleave_block_size = txth.interleave; vgmstream->layout_type = layout_none; break; - case coding_XBOX: + case coding_XBOX_IMA: vgmstream->layout_type = layout_none; break; 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; return ms_ima_bytes_to_samples(bytes, txth->interleave, txth->channels); 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: return dsp_bytes_to_samples(bytes, txth->channels); case PSX: diff --git a/src/meta/ubi_sb.c b/src/meta/ubi_sb.c index b5cabd8e..ad0d9abb 100644 --- a/src/meta/ubi_sb.c +++ b/src/meta/ubi_sb.c @@ -155,9 +155,9 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) { break; case RAW_XBOX: - vgmstream->coding_type = coding_XBOX; + vgmstream->coding_type = coding_XBOX_IMA; 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; case RAW_DSP: diff --git a/src/meta/waa_wac_wad_wam.c b/src/meta/waa_wac_wad_wam.c index 0ca8df89..0b7b50d4 100644 --- a/src/meta/waa_wac_wad_wam.c +++ b/src/meta/waa_wac_wad_wam.c @@ -1,146 +1,146 @@ #include "meta.h" -#include "../util.h" +#include "../coding/coding.h" + /* const short wad_coef[16][2] = { - {0x4002,0x2003}, - {0x2016,0xc600}, - {0xC600,0x98ab}, - {0x96bf,0x29c5}, - {0x2003,0x0081}, - {0x0e00,0x2004}, - {0x8e01,0xc500}, - {0x70bf,0x8128}, - {0x288e,0xc600}, - {0x016e,0x0e5b}, - {0xbe20,0x2003}, - {0x03c6,0xc600}, - {0x0048,0xe85a}, - {0xbe28,0x28c6}, - {0xc600,0x00F6}, - {0xbeab,0x5520} + {0x4002,0x2003}, + {0x2016,0xc600}, + {0xC600,0x98ab}, + {0x96bf,0x29c5}, + {0x2003,0x0081}, + {0x0e00,0x2004}, + {0x8e01,0xc500}, + {0x70bf,0x8128}, + {0x288e,0xc600}, + {0x016e,0x0e5b}, + {0xbe20,0x2003}, + {0x03c6,0xc600}, + {0x0048,0xe85a}, + {0xbe28,0x28c6}, + {0xc600,0x00F6}, + {0xbeab,0x5520} };*/ const short wad_coef[16] = { - 0x04ab, 0xfced, - 0x0789, 0xfedf, - 0x09a2, 0xfae5, - 0x0c90, 0xfac1, - 0x084d, 0xfaa4, - 0x0982, 0xfdf7, - 0x0af6, 0xfafa, - 0x0be6, 0xfbf5 + 0x04ab, 0xfced, + 0x0789, 0xfedf, + 0x09a2, 0xfae5, + 0x0c90, 0xfac1, + 0x084d, 0xfaa4, + 0x0982, 0xfdf7, + 0x0af6, 0xfafa, + 0x0be6, 0xfbf5 }; -/* WAC - WAD - WAM (Beyond Good & Evil GC/PS2/Xbox/Wii) */ -/* Note: A "Flat Layout" has no interleave */ +/* WAC/WAD/WAM/WAA - from Beyond Good & Evil (PS2/Xbox/GC/Wii) */ VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; - int i; + int i; off_t start_offset; int loop_flag; - int channel_count; - int coef1_start; - int coef2_start; - int second_channel_start = -1; + int channel_count; + int coef1_start; + int coef2_start; + int second_channel_start = -1; // Check file extensions streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("waa",filename_extension(filename)) && - strcasecmp("wac",filename_extension(filename)) && - strcasecmp("wad",filename_extension(filename)) && - strcasecmp("wam",filename_extension(filename))) goto fail; + strcasecmp("wac",filename_extension(filename)) && + strcasecmp("wad",filename_extension(filename)) && + strcasecmp("wam",filename_extension(filename))) goto fail; /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x52494646 || /* "RIFF" */ - read_32bitBE(0x08,streamFile) != 0x57415645 || /* "WAVE" */ - read_32bitBE(0x0C,streamFile) != 0x666D7420 || /* "fmt\0x20" */ - read_32bitBE(0x10,streamFile) != 0x12000000) /* "0x12000000" */ - goto fail; + if (read_32bitBE(0x00,streamFile) != 0x52494646 || /* "RIFF" */ + read_32bitBE(0x08,streamFile) != 0x57415645 || /* "WAVE" */ + read_32bitBE(0x0C,streamFile) != 0x666D7420 || /* "fmt " */ + read_32bitBE(0x10,streamFile) != 0x12000000) /* "0x12000000" */ + goto fail; - /* files don't contain looping information, - so the looping is not done depending on extension. - wam and waa contain ambient sounds and music, so often they contain - looped music. Change extension to wac or wad to make the sound non-looping. - */ + /* files don't contain looping information, + so the looping is not done depending on extension. + wam and waa contain ambient sounds and music, so often they contain + looped music. Change extension to wac or wad to make the sound non-looping. + */ loop_flag = strcasecmp("wac",filename_extension(filename)) && - strcasecmp("wad",filename_extension(filename)); + strcasecmp("wad",filename_extension(filename)); channel_count = (uint16_t)read_16bitLE(0x16,streamFile); - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* Check what encoder is needed */ - //FIXME: //PC version uses pcm, but which encoder? + /* Check what encoder is needed */ + //FIXME: //PC version uses pcm, but which encoder? - vgmstream->channels = channel_count; + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitLE(0x18,streamFile); - vgmstream->meta_type = meta_WAA_WAC_WAD_WAM; + vgmstream->meta_type = meta_WAA_WAC_WAD_WAM; vgmstream->layout_type = layout_none; - switch((uint16_t)read_16bitLE(0x14,streamFile)) { + switch((uint16_t)read_16bitLE(0x14,streamFile)) { case 0x0069: // XBOX IMA ADPCM - start_offset = 0x2E; - vgmstream->coding_type = coding_XBOX; - vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/36/channel_count*64; - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/36/channel_count*64; - } + start_offset = 0x2E; + vgmstream->coding_type = coding_XBOX_IMA; + vgmstream->num_samples = xbox_ima_bytes_to_samples(read_32bitLE(0x2A,streamFile), channel_count); + if (loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = xbox_ima_bytes_to_samples(read_32bitLE(0x2A,streamFile),channel_count); + } break; case 0xFFFF: // PS2 ADPCM - start_offset = 0x2E; - vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/16*28/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/16*28/channel_count; - } + start_offset = 0x2E; + vgmstream->coding_type = coding_PSX; + vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))/16*28/channel_count; + if (loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))/16*28/channel_count; + } second_channel_start = (read_32bitLE(0x2A,streamFile)/2)+start_offset; break; case 0xFFFE: // GameCube/WII DSP - start_offset = 0x5C; - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))*14/8/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))*14/8/channel_count; - } - if(read_16bitLE(0x24,streamFile)==0x00)//is a wii file with no coeff table - { - //FIXME: WII version of WAM/WAD/WAC need some coeff table from somewhere - for (i=0;i<16;i++) - vgmstream->ch[0].adpcm_coef[i] = wad_coef[i]; - if (channel_count == 2) { - for (i=0;i<16;i++) - vgmstream->ch[1].adpcm_coef[i] = wad_coef[i]; - } - goto fail; - } - else - { - second_channel_start = (read_32bitLE(0x2A,streamFile)/2)+0x8A; - /* Retrieveing the coef tables */ - coef1_start = 0x2E; - coef2_start = (read_32bitLE(0x2A,streamFile)/2)+0x5C; + start_offset = 0x5C; + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->num_samples = (read_32bitLE(0x2A,streamFile))*14/8/channel_count; + if (loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = (read_32bitLE(0x2A,streamFile))*14/8/channel_count; + } + if(read_16bitLE(0x24,streamFile)==0x00)//is a wii file with no coeff table + { + //FIXME: WII version of WAM/WAD/WAC need some coeff table from somewhere + for (i=0;i<16;i++) + vgmstream->ch[0].adpcm_coef[i] = wad_coef[i]; + if (channel_count == 2) { + for (i=0;i<16;i++) + vgmstream->ch[1].adpcm_coef[i] = wad_coef[i]; + } + goto fail; + } + else + { + second_channel_start = (read_32bitLE(0x2A,streamFile)/2)+0x8A; + /* Retrieveing the coef tables */ + coef1_start = 0x2E; + coef2_start = (read_32bitLE(0x2A,streamFile)/2)+0x5C; - { - int i; - for (i=0;i<16;i++) - vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(coef1_start+i*2,streamFile); - if (channel_count == 2) { - for (i=0;i<16;i++) - vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(coef2_start+i*2,streamFile); - } - } - } + { + int i; + for (i=0;i<16;i++) + vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(coef1_start+i*2,streamFile); + if (channel_count == 2) { + for (i=0;i<16;i++) + vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(coef2_start+i*2,streamFile); + } + } + } break; - default: - goto fail; - } + default: + goto fail; + } @@ -154,7 +154,7 @@ VGMSTREAM * init_vgmstream_waa_wac_wad_wam(STREAMFILE *streamFile) { for (i=0;ich[i].streamfile = file; - if (vgmstream->coding_type == coding_XBOX) { + if (vgmstream->coding_type == coding_XBOX_IMA) { /* xbox interleaving is a little odd */ vgmstream->ch[i].channel_start_offset=start_offset; } else { diff --git a/src/meta/wvs.c b/src/meta/wvs.c index 163d93cf..354a5595 100644 --- a/src/meta/wvs.c +++ b/src/meta/wvs.c @@ -1,68 +1,50 @@ #include "meta.h" -#include "../util.h" - -/* - WVS (found in Metal Arms - Glitch in the System) - XBOX and GameCube -*/ +#include "../coding/coding.h" +/* WVS - found in Metal Arms - Glitch in the System (Xbox) */ VGMSTREAM * init_vgmstream_xbox_wvs(STREAMFILE *streamFile) { 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 */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("wvs",filename_extension(filename))) goto fail; + /* check extension */ + if (!check_extensions(streamFile,"wvs")) + goto fail; - if((read_16bitLE(0x0C,streamFile)!=0x69) && - (read_16bitLE(0x08,streamFile)!=0x4400) && - (read_32bitLE(0x0,streamFile)!=get_streamfile_size(streamFile)+0x20)) - goto fail; + if (read_16bitLE(0x0C,streamFile) != 0x69 && /* codec */ + read_16bitLE(0x08,streamFile) != 0x4400) + goto fail; - /* Loop seems to be set if offset(0x0A) == 0x472C */ - loop_flag = (read_16bitLE(0x0A,streamFile)==0x472C); + start_offset = 0x20; + 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 */ - /* Always stereo files */ - channel_count=read_16bitLE(0x0E,streamFile); - - /* build the VGMSTREAM */ + if (data_size + start_offset != get_streamfile_size(streamFile)) + goto fail; + + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); 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->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->num_samples = read_32bitLE(0,streamFile) / 36 * 64 / vgmstream->channels; + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_none; 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;ich[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; - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } @@ -75,7 +57,7 @@ VGMSTREAM * init_vgmstream_ngc_wvs(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; int loop_flag; - int channel_count; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -94,7 +76,7 @@ VGMSTREAM * init_vgmstream_ngc_wvs(STREAMFILE *streamFile) { vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ start_offset = 0x60; if (channel_count == 1) { @@ -103,8 +85,8 @@ VGMSTREAM * init_vgmstream_ngc_wvs(STREAMFILE *streamFile) { vgmstream->sample_rate = 44100; } - vgmstream->channels = channel_count; - + vgmstream->channels = channel_count; + vgmstream->coding_type = coding_NGC_DSP; vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)/8/channel_count*14; //(read_32bitBE(0x0C,streamFile)-start_offset)/8/channel_count*14; if (loop_flag) { diff --git a/src/meta/xau.c b/src/meta/xau.c index 8e12db04..ab663dc8 100644 --- a/src/meta/xau.c +++ b/src/meta/xau.c @@ -58,11 +58,11 @@ VGMSTREAM * init_vgmstream_xau(STREAMFILE *streamFile) { goto fail; 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_end_sample = loop_end; - vgmstream->coding_type = coding_XBOX; + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_none; break; diff --git a/src/meta/xbox_ims.c b/src/meta/xbox_ims.c index 08721d65..89aeef60 100644 --- a/src/meta/xbox_ims.c +++ b/src/meta/xbox_ims.c @@ -29,8 +29,8 @@ VGMSTREAM * init_vgmstream_xbox_matx(STREAMFILE *streamFile) { /* fill in the vital statistics */ vgmstream->channels = channel_count; 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->meta_type = meta_XBOX_MATX; diff --git a/src/meta/xbox_wavm.c b/src/meta/xbox_wavm.c index 0f0853d6..ec1c4106 100644 --- a/src/meta/xbox_wavm.c +++ b/src/meta/xbox_wavm.c @@ -1,62 +1,37 @@ #include "meta.h" -#include "../util.h" - -/* WAVM - - WAVM is an headerless format which can be found on XBOX - known extensions : WAVM - - 2008-05-23 - Fastelbja : First version ... -*/ +#include "../coding/coding.h" +/* WAVM - headerless format which can be found on XBOX */ VGMSTREAM * init_vgmstream_xbox_wavm(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; + off_t start_offset = 0; + int loop_flag, channel_count; - int loop_flag=0; - int channel_count; - int i; + /* check extension */ + if (!check_extensions(streamFile,"wavm")) + goto fail; - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("wavm",filename_extension(filename))) goto fail; - - /* No loop on wavm */ - loop_flag = 0; + start_offset = 0; + loop_flag = 0; + channel_count = 2; - /* Always stereo files */ - channel_count=2; - - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - /* allways 2 channels @ 44100 Hz */ - vgmstream->channels = 2; vgmstream->sample_rate = 44100; + vgmstream->num_samples = xbox_ima_bytes_to_samples(get_streamfile_size(streamFile), vgmstream->channels); - vgmstream->coding_type = coding_XBOX; - vgmstream->num_samples = (int32_t)(get_streamfile_size(streamFile) / 36 * 64 / vgmstream->channels); + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_XBOX_WAVM; - /* open the file for reading by each channel */ - { - for (i=0;ich[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; - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } - diff --git a/src/meta/xbox_xmu.c b/src/meta/xbox_xmu.c index 337674c7..63f5faea 100644 --- a/src/meta/xbox_xmu.c +++ b/src/meta/xbox_xmu.c @@ -1,65 +1,44 @@ #include "meta.h" -#include "../util.h" - -/* XMU - - XMU (found in Alter Echo) -*/ +#include "../coding/coding.h" +/* XMU- found in Alter Echo (Xbox) */ VGMSTREAM * init_vgmstream_xbox_xmu(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; + size_t start_offset; + int loop_flag, channel_count; + size_t data_size; - int loop_flag=0; - int channel_count; - int i; + /* check extension */ + if (!check_extensions(streamFile,"xmu")) + goto fail; - /* 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 && /* "XMU " */ + read_32bitBE(0x08,streamFile) != 0x46524D54) /* "FRMT" */ + goto fail; - if((read_32bitBE(0x00,streamFile)!=0x584D5520) && - (read_32bitBE(0x08,streamFile)!=0x46524D54)) - goto fail; + start_offset = 0x800; + 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" */ - /* No Loop found atm */ - loop_flag = read_8bit(0x16,streamFile);; - - /* Always stereo files */ - channel_count=read_8bit(0x14,streamFile); - - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - vgmstream->channels = channel_count; 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->num_samples = read_32bitLE(0x7FC,streamFile) / 36 * 64 / vgmstream->channels; + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_none; vgmstream->meta_type = meta_XBOX_XMU; - 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;ich[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; return vgmstream; - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } diff --git a/src/meta/xbox_xvas.c b/src/meta/xbox_xvas.c index a17298c3..21ea9be4 100644 --- a/src/meta/xbox_xvas.c +++ b/src/meta/xbox_xvas.c @@ -1,72 +1,52 @@ #include "meta.h" #include "../layout/layout.h" -#include "../util.h" - -/* XVAS - - XVAS (found in TMNT 2 & TMNT 3)) -*/ +#include "../coding/coding.h" +/* XVAS - found in TMNT 2 & TMNT 3 (Xbox) */ VGMSTREAM * init_vgmstream_xbox_xvas(STREAMFILE *streamFile) { 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 */ + if (!check_extensions(streamFile,"xvas")) + goto fail; - /* 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 && /* codec */ + read_32bitLE(0x08,streamFile) != 0x48) /* block size (probably 0x24 for mono) */ + goto fail; - if((read_32bitLE(0x00,streamFile)!=0x69) && - (read_32bitLE(0x08,streamFile)!=0x48)) - goto fail; + start_offset = 0x800; + 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 */ - /* No Loop found atm */ - loop_flag = (read_32bitLE(0x14,streamFile)==read_32bitLE(0x24,streamFile)); - - /* Always stereo files */ - channel_count=read_32bitLE(0x04,streamFile); - - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitLE(0x0c,streamFile); + vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels); + if(loop_flag) { + size_t loop_size = read_32bitLE(0x10,streamFile); + loop_size -= (loop_size / 0x20000) * 0x20; + vgmstream->loop_start_sample = xbox_ima_bytes_to_samples(loop_size, vgmstream->channels); + vgmstream->loop_end_sample = vgmstream->num_samples; + } - 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->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_xvas_blocked; vgmstream->meta_type = meta_XBOX_XVAS; - if(loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x10,streamFile); - vgmstream->loop_start_sample -= ((vgmstream->loop_start_sample/0x20000)*0x20); - vgmstream->loop_start_sample = vgmstream->loop_start_sample / 36 * 64 / vgmstream->channels; - vgmstream->loop_end_sample=vgmstream->num_samples; - } - - /* open the file for reading by each channel */ - { - for (i=0;ich[i].streamfile = streamFile->open(streamFile,filename,36); - vgmstream->ch[i].offset = 0x800; + if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) + goto fail; - if (!vgmstream->ch[i].streamfile) goto fail; - } - } - - xvas_block_update(0x800,vgmstream); + xvas_block_update(start_offset,vgmstream); return vgmstream; - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } diff --git a/src/meta/xbox_xwav.c b/src/meta/xbox_xwav.c index 45f55c52..735a1120 100644 --- a/src/meta/xbox_xwav.c +++ b/src/meta/xbox_xwav.c @@ -1,107 +1,91 @@ #include "meta.h" -#include "../util.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 ... -*/ +#include "../coding/coding.h" +/* 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 * vgmstream = NULL; - char filename[PATH_LIMIT]; - - int loop_flag=0; - int channel_count; + int loop_flag, channel_count; off_t start_offset; - int i,j=0; - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("xwav",filename_extension(filename))) goto fail; + /* check extension */ + if (!check_extensions(streamFile,"xwav")) + 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; + /* check for headers */ + if(!((read_32bitBE(0x00,streamFile) == 0x52494646) && /* "RIFF" */ + (read_32bitBE(0x08,streamFile) == 0x57415645) && /* "WAVE" */ + (read_32bitBE(0x0C,streamFile) == 0x666D7420) && /* "fmt " */ + (read_16bitLE(0x14,streamFile) == 0x0069))) /* codec */ + goto fail; - /* No loop on wavm */ - if(read_32bitBE(0x28,streamFile)==0x77736D70) - loop_flag = 1; - else - loop_flag = 0; - - /* Always stereo files */ - channel_count=read_16bitLE(0x16,streamFile); - - /* build the VGMSTREAM */ + /* 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); + + /* 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 */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* hack for loop wave found on Dynasty warriors */ - if(loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x4C,streamFile); - vgmstream->loop_end_sample = vgmstream->loop_start_sample + read_32bitLE(0x50,streamFile); - } - - /* fill in the vital statistics */ - vgmstream->channels = channel_count; + 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) { + vgmstream->loop_start_sample = read_32bitLE(0x4C,streamFile); + vgmstream->loop_end_sample = vgmstream->loop_start_sample + read_32bitLE(0x50,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->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_none; - 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) { - for (i=0;iget_name(streamFile,filename,sizeof(filename)); - vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,36); - vgmstream->ch[i].offset = start_offset+4; + if (channel_count > 2) { /* multichannel interleaved init */ + for (i=0, ch=0;ich[i].streamfile) goto fail; - } - } else { - for (i=0;ich[i].streamfile = streamFile->open(streamFile,filename,36); - vgmstream->ch[i].offset = start_offset+4; + vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x24); + vgmstream->ch[i].offset = start_offset + 0x04; - if (!vgmstream->ch[i].streamfile) goto fail; - } - } + if (!vgmstream->ch[i].streamfile) goto fail; + } + } + else { + for (i=0; i < channel_count; i++) { + vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x24); + vgmstream->ch[i].offset = start_offset + 0x04; + + if (!vgmstream->ch[i].streamfile) goto fail; + } + } } return vgmstream; - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; } diff --git a/src/meta/xwb.c b/src/meta/xwb.c index 5dc75b45..383b31cc 100644 --- a/src/meta/xwb.c +++ b/src/meta/xwb.c @@ -295,11 +295,11 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { } } else if (xwb.version <= XACT1_1_MAX && xwb.codec == XBOX_ADPCM) { - xwb.block_align = 0x24 * xwb.channels; - xwb.num_samples = ms_ima_bytes_to_samples(xwb.stream_size, xwb.block_align, xwb.channels); + xwb.block_align = 0x24 * xwb.channels; /* not really needed... */ + xwb.num_samples = xbox_ima_bytes_to_samples(xwb.stream_size, xwb.channels); if (xwb.loop_flag) { - xwb.loop_start_sample = ms_ima_bytes_to_samples(xwb.loop_start, xwb.block_align, xwb.channels); - xwb.loop_end_sample = ms_ima_bytes_to_samples(xwb.loop_start + xwb.loop_end, xwb.block_align, xwb.channels); + xwb.loop_start_sample = xbox_ima_bytes_to_samples(xwb.loop_start, 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) { @@ -367,7 +367,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { break; case XBOX_ADPCM: /* Silent Hill 4 (Xbox) */ - vgmstream->coding_type = coding_XBOX; + vgmstream->coding_type = coding_XBOX_IMA; vgmstream->layout_type = layout_none; break; diff --git a/src/vgmstream.c b/src/vgmstream.c index c2327dfd..48618abc 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -1069,8 +1069,8 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) { case coding_DVI_IMA_int: case coding_3DS_IMA: return 2; - case coding_XBOX: - case coding_XBOX_int: + case coding_XBOX_IMA: + case coding_XBOX_IMA_int: case coding_FSB_IMA: return 64; case coding_APPLE_IMA4: @@ -1238,8 +1238,8 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) { return 0; case coding_UBI_IMA: /* variable (PCM then IMA) */ return 0; - case coding_XBOX: - case coding_XBOX_int: + case coding_XBOX_IMA: + case coding_XBOX_IMA_int: case coding_FSB_IMA: return 0x24; case coding_APPLE_IMA4: @@ -1493,14 +1493,14 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to samples_to_do); } break; - case coding_XBOX: + case coding_XBOX_IMA: for (chan=0;chanchannels;chan++) { decode_xbox_ima(vgmstream,&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan, vgmstream->channels,vgmstream->samples_into_block, samples_to_do,chan); } break; - case coding_XBOX_int: + case coding_XBOX_IMA_int: for (chan=0;chanchannels;chan++) { decode_xbox_ima_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan, vgmstream->channels,vgmstream->samples_into_block, diff --git a/src/vgmstream.h b/src/vgmstream.h index 32d70ed1..18dfc9c3 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -127,8 +127,8 @@ typedef enum { coding_DVI_IMA_int, /* DVI IMA ADPCM (mono/interleave, high nibble first) */ coding_3DS_IMA, /* 3DS IMA ADPCM */ coding_MS_IMA, /* Microsoft IMA ADPCM */ - coding_XBOX, /* XBOX IMA ADPCM */ - coding_XBOX_int, /* XBOX IMA ADPCM (interleaved) */ + coding_XBOX_IMA, /* XBOX IMA ADPCM */ + coding_XBOX_IMA_int, /* XBOX IMA ADPCM (interleaved/mono) */ coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */ coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */ coding_RAD_IMA, /* Radical IMA ADPCM */