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_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 */

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) {
/* 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) {

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_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"},

View File

@ -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) {

View File

@ -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 */

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
* (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 */

View File

@ -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;

View File

@ -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:

View File

@ -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 */

View File

@ -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;

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;
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;

View File

@ -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;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;
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;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;
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;
}

View File

@ -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:

View File

@ -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:

View File

@ -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;
}

View File

@ -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:

View File

@ -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:

View File

@ -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;i<channel_count;i++) {
vgmstream->ch[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 {

View File

@ -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;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;
/* 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) {

View File

@ -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;

View File

@ -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;

View File

@ -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;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;
/* clean up anything we may have opened */
fail:
if (vgmstream) close_vgmstream(vgmstream);
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -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;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;
}
}
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;
}

View File

@ -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;i<channel_count;i++) {
vgmstream->ch[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;
}

View File

@ -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;i<channel_count;i++,j++) {
if((j&2) && (i!=0)) {
j=0;
start_offset+=36*2;
}
int i, ch;
char filename[PATH_LIMIT];
streamFile->get_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;i<channel_count;i++,ch++) {
if ((ch&2) && (i!=0)) {
ch = 0;
start_offset += 0x24*2;
}
if (!vgmstream->ch[i].streamfile) goto fail;
}
} else {
for (i=0;i<channel_count;i++) {
vgmstream->ch[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;
}

View File

@ -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;

View File

@ -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;chan<vgmstream->channels;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;chan<vgmstream->channels;chan++) {
decode_xbox_ima_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
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_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 */