diff --git a/src/coding/coding.h b/src/coding/coding.h index 0b5d7ecb..fe3d62f5 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -621,8 +621,10 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_raw(STREAMFILE* sf, off_t offset, size_t d ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* out_samples); ffmpeg_codec_data* init_ffmpeg_aac(STREAMFILE* sf, off_t offset, size_t size, int skip_samples); ffmpeg_codec_data* init_ffmpeg_xwma(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int format, int channels, int sample_rate, int avg_bitrate, int block_size); +//TODO: make init_ffmpeg_xwma_fmt(be) too to pass fmt chunk ffmpeg_codec_data* init_ffmpeg_xma1_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int channels, int sample_rate, int stream_mode); +ffmpeg_codec_data* init_ffmpeg_xma2_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int32_t sample_count, int channels, int sample_rate, int block_size, int block_count); ffmpeg_codec_data* init_ffmpeg_xma_chunk(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, uint32_t chunk_offset, uint32_t chunk_size); ffmpeg_codec_data* init_ffmpeg_xma_chunk_split(STREAMFILE* sf_head, STREAMFILE* sf_data, uint32_t data_offset, uint32_t data_size, uint32_t chunk_offset, uint32_t chunk_size); @@ -683,7 +685,6 @@ ffmpeg_codec_data* init_ffmpeg_mp4_custom_lyn(STREAMFILE* sf, mp4_custom_t* mp4) /* coding_utils */ int ffmpeg_make_riff_atrac3plus(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay); -int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size); int ffmpeg_make_riff_xwma(uint8_t* buf, size_t buf_size, int codec, size_t data_size, int channels, int sample_rate, int avg_bps, int block_align); /* MS audio format's sample info (struct to avoid passing so much stuff, separate for reusing) */ diff --git a/src/coding/coding_utils.c b/src/coding/coding_utils.c index 0fd2dc88..427c9c31 100644 --- a/src/coding/coding_utils.c +++ b/src/coding/coding_utils.c @@ -80,65 +80,6 @@ int ffmpeg_make_riff_atrac3plus(uint8_t* buf, size_t buf_size, size_t sample_cou return riff_size; } -int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size) { - uint16_t codec_XMA2 = 0x0166; - size_t riff_size = 4+4+ 4 + 0x3c + 4+4; - size_t bytecount; - int streams; - uint32_t speakers; - - /* info from xma2defs.h, xact3wb.h and audiodefs.h */ - streams = (channels + 1) / 2; - switch (channels) { - case 1: speakers = 0x04; break; /* 1.0: FC */ - case 2: speakers = 0x01 | 0x02; break; /* 2.0: FL FR */ - case 3: speakers = 0x01 | 0x02 | 0x08; break; /* 2.1: FL FR LF */ - case 4: speakers = 0x01 | 0x02 | 0x10 | 0x20; break; /* 4.0: FL FR BL BR */ - case 5: speakers = 0x01 | 0x02 | 0x08 | 0x10 | 0x20; break; /* 4.1: FL FR LF BL BR */ - case 6: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20; break; /* 5.1: FL FR FC LF BL BR */ - case 7: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x0100; break; /* 6.1: FL FR FC LF BL BR BC */ - case 8: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80; break; /* 7.1: FL FR FC LF BL BR FLC FRC */ - default: speakers = 0; break; - } - - if (buf_size < riff_size) - return -1; - - bytecount = sample_count * channels * sizeof(sample); - - memcpy(buf+0x00, "RIFF", 4); - put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ - memcpy(buf+0x08, "WAVE", 4); - - memcpy(buf+0x0c, "fmt ", 4); - put_32bitLE(buf+0x10, 0x34);/*fmt size*/ - put_16bitLE(buf+0x14, codec_XMA2); - put_16bitLE(buf+0x16, channels); - put_32bitLE(buf+0x18, sample_rate); - put_32bitLE(buf+0x1c, sample_rate*channels / sizeof(sample)); /* average bytes per second (wrong, unneeded) */ - put_16bitLE(buf+0x20, (int16_t)(channels*sizeof(sample))); /* block align */ - put_16bitLE(buf+0x22, 16); /* bits per sample */ - - put_16bitLE(buf+0x24, 0x22); /* extra data size */ - put_16bitLE(buf+0x26, streams); /* number of streams */ - put_32bitLE(buf+0x28, speakers); /* speaker position */ - put_32bitLE(buf+0x2c, bytecount); /* PCM samples */ - put_32bitLE(buf+0x30, block_size); /* XMA block size (can be zero, it's for seeking only) */ - /* (looping values not set, expected to be handled externally) */ - put_32bitLE(buf+0x34, 0); /* play begin */ - put_32bitLE(buf+0x38, 0); /* play length */ - put_32bitLE(buf+0x3c, 0); /* loop begin */ - put_32bitLE(buf+0x40, 0); /* loop length */ - put_8bit(buf+0x44, 0); /* loop count */ - put_8bit(buf+0x45, 4); /* encoder version */ - put_16bitLE(buf+0x46, block_count); /* blocks count (entries in seek table, can be zero) */ - - memcpy(buf+0x48, "data", 4); - put_32bitLE(buf+0x4c, data_size); /* data size */ - - return riff_size; -} - int ffmpeg_make_riff_xwma(uint8_t* buf, size_t buf_size, int codec, size_t data_size, int channels, int sample_rate, int avg_bps, int block_align) { size_t riff_size = 4+4+ 4 + 0x1a + 4+4; @@ -754,18 +695,17 @@ void xma2_parse_xma2_chunk(STREAMFILE* sf, off_t chunk_offset, int* out_channels int channels, sample_rate, loop_flag, num_samples, loop_start_sample, loop_end_sample; off_t offset; - xma2_chunk_version = read_8bit(chunk_offset+0x00,sf); - num_streams = read_8bit(chunk_offset+0x01,sf); + xma2_chunk_version = read_u8(chunk_offset+0x00,sf); + num_streams = read_u8(chunk_offset+0x01,sf); loop_start_sample = read_32bit(chunk_offset+0x04,sf); loop_end_sample = read_32bit(chunk_offset+0x08,sf); - loop_flag = (uint8_t)read_8bit(chunk_offset+0x03,sf) > 0 || loop_end_sample; /* rarely not set, encoder default */ + loop_flag = read_u8(chunk_offset+0x03,sf) > 0 || loop_end_sample; /* rarely not set, encoder default */ sample_rate = read_32bit(chunk_offset+0x0c,sf); /* may need loop end +1 */ offset = xma2_chunk_version == 3 ? 0x14 : 0x1C; num_samples = read_32bit(chunk_offset+offset+0x00,sf); - /* pcm_samples in original sample rate (not usable as file may be resampled) */ - /* pcm_samples = read_32bitBE(chunk_offset+offset+0x04,sf)*/ + //pcm_samples = read_32bitBE(chunk_offset+offset+0x04,sf) /* in original sample rate (not usable as file may be resampled) */ offset = xma2_chunk_version == 3 ? 0x20 : 0x28; channels = 0; /* channels is the sum of all streams */ diff --git a/src/coding/ffmpeg_decoder_utils.c b/src/coding/ffmpeg_decoder_utils.c index 67ea1e63..303354b6 100644 --- a/src/coding/ffmpeg_decoder_utils.c +++ b/src/coding/ffmpeg_decoder_utils.c @@ -3,22 +3,22 @@ #ifdef VGM_USE_FFMPEG static int ffmpeg_make_riff_atrac3(uint8_t* buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int joint_stereo, int encoder_delay) { - int buf_max = (0x04 + 0x04) + 0x4 + 0x28 + 0x10 + (0x04 + 0x04); + int buf_max = (0x04 * 2 + 0x4) + (0x04 * 2 + 0x20) + (0x04 * 2 + 0x08) + (0x04 * 2); if (buf_max > buf_size) - return -1; + return 0; memcpy (buf+0x00, "RIFF", 0x04); - put_u32le(buf+0x04, (uint32_t)(buf_max - 0x04 - 0x04 + data_size)); /* riff size */ + put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */ memcpy (buf+0x08, "WAVE", 0x04); memcpy (buf+0x0c, "fmt ", 0x04); - put_u32le(buf+0x10, 0x20);/*fmt size*/ + put_u32le(buf+0x10, 0x20); /* fmt size */ put_u16le(buf+0x14, 0x0270); /* ATRAC3 codec */ put_u16le(buf+0x16, channels); put_u32le(buf+0x18, sample_rate); put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample)); /* average bytes per second (wrong) */ - put_u16le(buf+0x20, (uint16_t)(block_align)); /* block align */ + put_u16le(buf+0x20, block_align); /* block align */ put_u16le(buf+0x24, 0x0e); /* extra data size */ put_u16le(buf+0x26, 1); /* unknown, always 1 */ @@ -29,12 +29,12 @@ static int ffmpeg_make_riff_atrac3(uint8_t* buf, size_t buf_size, size_t sample_ put_u16le(buf+0x30, 1); /* unknown, always 1 (frame_factor?) */ put_u16le(buf+0x32, 0); /* unknown, always 0 */ - memcpy (buf+0x34, "fact", 4); - put_u32le(buf+0x38, 0x8); /* fact size */ + memcpy (buf+0x34, "fact", 0x04); + put_u32le(buf+0x38, 0x08); /* fact size */ put_u32le(buf+0x3c, sample_count); put_u32le(buf+0x40, encoder_delay); - memcpy (buf+0x44, "data", 4); + memcpy (buf+0x44, "data", 0x04); put_u32le(buf+0x48, data_size); /* data size */ return buf_max; @@ -136,7 +136,7 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* p_ implicit_skip = 69; } else if (is_at3p && fact_size == 0x08) { - implicit_skip = 184*2; + implicit_skip = 184 * 2; } else if (is_at3p && fact_size == 0x0c) { implicit_skip = 184; /* first 184 is already added to delay vs field at 0x08 */ @@ -202,8 +202,6 @@ fail: return NULL; } -//TODO: make init_ffmpeg_xwma_fmt(be) too to pass fmt chunk - ffmpeg_codec_data* init_ffmpeg_xwma(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int format, int channels, int sample_rate, int avg_bitrate, int block_size) { ffmpeg_codec_data* data = NULL; uint8_t buf[0x100]; @@ -221,32 +219,29 @@ fail: static int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t data_size, int channels, int sample_rate, int stream_mode) { - uint16_t codec_XMA1 = 0x0165; - size_t riff_size; - int streams, i; /* stream disposition: * 0: default (ex. 5ch = 2ch + 2ch + 1ch = 3 streams) * 1: lineal (ex. 5ch = 1ch + 1ch + 1ch + 1ch + 1ch = 5 streams), unusual but exists * others: not seen (ex. maybe 5ch = 2ch + 1ch + 1ch + 1ch = 4 streams) */ + int streams; switch(stream_mode) { case 0 : streams = (channels + 1) / 2; break; case 1 : streams = channels; break; default: return 0; } - riff_size = 4+4+ 4 + 0x14 + 0x14*streams + 4+4; - - if (buf_size < riff_size) - return -1; + int buf_max = (0x04 * 2 + 0x4) + (0x04 * 2 + 0x0c + 0x14 * streams) + (0x04 * 2); + if (buf_max > buf_size) + return 0; memcpy (buf+0x00, "RIFF", 0x04); - put_u32le(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ + put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */ memcpy (buf+0x08, "WAVE", 0x04); memcpy (buf+0x0c, "fmt ", 0x04); - put_u32le(buf+0x10, 0xc + 0x14*streams);/*fmt size*/ - put_u16le(buf+0x14, codec_XMA1); + put_u32le(buf+0x10, 0x0c + 0x14 * streams); /* fmt size */ + put_u16le(buf+0x14, 0x0165); /* XMA1 */ put_u16le(buf+0x16, 16); /* bits per sample */ put_u16le(buf+0x18, 0x10D6); /* encoder options */ put_u16le(buf+0x1a, 0); /* largest stream skip (wrong, unneeded) */ @@ -254,10 +249,10 @@ static int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t data_size put_u8 (buf+0x1e, 0); /* loop count */ put_u8 (buf+0x1f, 2); /* version */ - for (i = 0; i < streams; i++) { + for (int i = 0; i < streams; i++) { int stream_channels; uint32_t speakers; - off_t off = 0x20 + 0x14*i;/* stream riff offset */ + off_t off = 0x20 + 0x14 * i; /* stream riff offset */ if (stream_mode == 1) { /* lineal */ @@ -298,10 +293,10 @@ static int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t data_size /* xmaencode decoding rejects XMA1 without "seek" chunk, though it doesn't seem to use it * (needs to be have entries but can be bogus, also generates seek for even small sounds) */ - memcpy (buf + riff_size - 0x04 - 0x04, "data", 0x04); - put_u32le(buf + riff_size - 0x04, data_size); /* data size */ + memcpy (buf + buf_max - (0x04 * 2), "data", 0x04); + put_u32le(buf + buf_max - (0x04 * 1), data_size); - return riff_size; + return buf_max; } ffmpeg_codec_data* init_ffmpeg_xma1_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int channels, int sample_rate, int stream_mode) { @@ -323,6 +318,86 @@ fail: } +static int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t data_size, int32_t sample_count, int channels, int sample_rate, int block_size, int block_count) { + size_t bytecount; + int streams; + uint32_t speakers; + + int buf_max = (0x04 * 2 + 0x04) + (0x04 * 2 + 0x34) + (0x04 * 2); + if (buf_max > buf_size) + return 0; + + /* info from xma2defs.h, xact3wb.h and audiodefs.h */ + streams = (channels + 1) / 2; + switch (channels) { + case 1: speakers = 0x04; break; /* 1.0: FC */ + case 2: speakers = 0x01 | 0x02; break; /* 2.0: FL FR */ + case 3: speakers = 0x01 | 0x02 | 0x08; break; /* 2.1: FL FR LF */ + case 4: speakers = 0x01 | 0x02 | 0x10 | 0x20; break; /* 4.0: FL FR BL BR */ + case 5: speakers = 0x01 | 0x02 | 0x08 | 0x10 | 0x20; break; /* 4.1: FL FR LF BL BR */ + case 6: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20; break; /* 5.1: FL FR FC LF BL BR */ + case 7: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x100; break; /* 6.1: FL FR FC LF BL BR BC */ + case 8: speakers = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40 | 0x80; break; /* 7.1: FL FR FC LF BL BR FLC FRC */ + default: speakers = 0; break; + } + + bytecount = sample_count * channels * sizeof(sample); + + memcpy (buf+0x00, "RIFF", 0x04); + put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */ + memcpy (buf+0x08, "WAVE", 0x04); + + memcpy (buf+0x0c, "fmt ", 0x04); + put_u32le(buf+0x10, 0x34); /* fmt size */ + put_u16le(buf+0x14, 0x0166); /* XMA2 */ + put_u16le(buf+0x16, channels); + put_u32le(buf+0x18, sample_rate); + put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample)); /* average bytes per second (wrong, unneeded) */ + put_u16le(buf+0x20, (uint16_t)(channels * sizeof(sample))); /* block align */ + put_u16le(buf+0x22, 16); /* bits per sample */ + + put_u16le(buf+0x24, 0x22); /* extra data size */ + put_u16le(buf+0x26, streams); /* number of streams */ + put_u32le(buf+0x28, speakers); /* speaker position */ + put_u32le(buf+0x2c, bytecount); /* PCM samples */ + put_u32le(buf+0x30, block_size); /* XMA block size (can be zero, for seeking only) */ + /* (looping values not set, expected to be handled externally) */ + put_u32le(buf+0x34, 0); /* play begin */ + put_u32le(buf+0x38, 0); /* play length */ + put_u32le(buf+0x3c, 0); /* loop begin */ + put_u32le(buf+0x40, 0); /* loop length */ + put_u8 (buf+0x44, 0); /* loop count */ + put_u8 (buf+0x45, 4); /* encoder version */ + put_u16le(buf+0x46, block_count); /* blocks count (entries in seek table, can be zero) */ + + memcpy (buf+0x48, "data", 0x04); + put_u32le(buf+0x4c, data_size); /* data size */ + + return buf_max; +} + +ffmpeg_codec_data* init_ffmpeg_xma2_raw(STREAMFILE* sf, uint32_t data_offset, uint32_t data_size, int32_t sample_count, int channels, int sample_rate, int block_size, int block_count) { + ffmpeg_codec_data* data = NULL; + uint8_t buf[0x100]; + int bytes; + + /* seemingly not needed but just in case */ + if (block_size <= 0) + block_size = 0x8000; /* default */ + if (block_count <= 0) + block_count = (data_size / block_size) + (data_size % block_size != 0 ? 1 : 0); /* approx */ + + bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), data_size, sample_count, channels, sample_rate, block_size, block_count); + data = init_ffmpeg_header_offset(sf, buf, bytes, data_offset, data_size); + if (!data) goto fail; + + return data; +fail: + free_ffmpeg(data); + return NULL; +} + + /* swap from LE to BE or the other way around */ static int ffmpeg_fmt_chunk_swap_endian(uint8_t* chunk, uint32_t chunk_size, uint16_t codec) { int i; @@ -383,7 +458,7 @@ fail: /* Makes a XMA1/2 RIFF header using a "fmt " chunk (XMAWAVEFORMAT/XMA2WAVEFORMATEX) or "XMA2" chunk (XMA2WAVEFORMAT), as a base: * Useful to preserve the stream layout */ static int ffmpeg_make_riff_xma_chunk(STREAMFILE* sf, uint8_t* buf, int buf_size, uint32_t data_size, uint32_t chunk_offset, uint32_t chunk_size, int* p_is_xma1) { - int buf_max = (0x04 + 0x04) + 0x04 + (0x04 + 0x04) + chunk_size + (0x04 + 0x04); + int buf_max = (0x04 * 2 + 0x04) + (0x04 * 2 + chunk_size) + (0x04 * 2); if (buf_max > buf_size) return 0; @@ -402,7 +477,7 @@ static int ffmpeg_make_riff_xma_chunk(STREAMFILE* sf, uint8_t* buf, int buf_size } memcpy (buf+0x00, "RIFF", 0x04); - put_u32le(buf+0x04, (buf_max - 0x08 + data_size)); /* riff size */ + put_u32le(buf+0x04, buf_max - (0x04 * 2)+ data_size); /* riff size */ memcpy (buf+0x08, "WAVE", 0x04); memcpy (buf+0x0c, is_xma2_old ? "XMA2" : "fmt ", 0x04); put_u32le(buf+0x10, chunk_size); diff --git a/src/meta/awc.c b/src/meta/awc.c index b3dad4f0..be6ebf8f 100644 --- a/src/meta/awc.c +++ b/src/meta/awc.c @@ -70,9 +70,7 @@ VGMSTREAM* init_vgmstream_awc(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x05: { /* XMA2 (X360) */ - uint8_t buf[0x100]; - size_t bytes, block_size, block_count, substream_size; - off_t substream_offset; + uint32_t substream_size, substream_offset; if (awc.is_music) { /* 1ch XMAs in blocks, we'll use layered layout + custom IO to get multi-FFmpegs working */ @@ -95,26 +93,22 @@ VGMSTREAM* init_vgmstream_awc(STREAMFILE* sf) { data->layers[i] = allocate_vgmstream(layer_channels, 0); if (!data->layers[i]) goto fail; - data->layers[i]->sample_rate = awc.sample_rate; data->layers[i]->meta_type = meta_AWC; data->layers[i]->coding_type = coding_FFmpeg; data->layers[i]->layout_type = layout_none; + data->layers[i]->sample_rate = awc.sample_rate; data->layers[i]->num_samples = awc.num_samples; /* setup custom IO streamfile, pass to FFmpeg and hope it's fooled */ temp_sf = setup_awc_xma_streamfile(sf, awc.stream_offset, awc.stream_size, awc.block_chunk, awc.channels, i); if (!temp_sf) goto fail; - substream_offset = 0; /* where FFmpeg thinks data starts, which our custom sf will clamp */ + substream_offset = 0x00; /* where FFmpeg thinks data starts, which our custom sf will clamp */ substream_size = get_streamfile_size(temp_sf); /* data of one XMA substream without blocks */ - block_size = 0x8000; /* no idea */ - block_count = substream_size / block_size; /* not accurate but not needed */ - - bytes = ffmpeg_make_riff_xma2(buf, 0x100, awc.num_samples, substream_size, layer_channels, awc.sample_rate, block_count, block_size); - data->layers[i]->codec_data = init_ffmpeg_header_offset(temp_sf, buf,bytes, substream_offset,substream_size); - - xma_fix_raw_samples(data->layers[i], temp_sf, substream_offset,substream_size, 0, 0,0); /* samples are ok? */ + data->layers[i]->codec_data = init_ffmpeg_xma2_raw(temp_sf, substream_offset, substream_size, awc.num_samples, layer_channels, awc.sample_rate, 0, 0); + if (data->layers[i]) + xma_fix_raw_samples(data->layers[i], temp_sf, substream_offset, substream_size, 0, 0,0); /* samples are ok? */ close_streamfile(temp_sf); if (!data->layers[i]->codec_data) goto fail; } @@ -125,11 +119,7 @@ VGMSTREAM* init_vgmstream_awc(STREAMFILE* sf) { } else { /* regular XMA for sfx */ - block_size = 0x8000; /* no idea */ - block_count = awc.stream_size / block_size; /* not accurate but not needed */ - - bytes = ffmpeg_make_riff_xma2(buf, 0x100, awc.num_samples, awc.stream_size, awc.channels, awc.sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, awc.stream_offset,awc.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, awc.stream_offset, awc.stream_size, awc.num_samples, awc.channels, awc.sample_rate, 0, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/cxs.c b/src/meta/cxs.c index 2e790126..7dfdc501 100644 --- a/src/meta/cxs.c +++ b/src/meta/cxs.c @@ -32,22 +32,16 @@ VGMSTREAM* init_vgmstream_cxs(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG { - uint8_t buf[0x100]; - size_t bytes, datasize, block_size, block_count; + uint32_t block_count = read_32bitBE(0x1c,sf); + uint32_t block_size = read_32bitBE(0x20,sf); + uint32_t data_size = read_32bitBE(0x24,sf); - block_count = read_32bitBE(0x1c,sf); - block_size = read_32bitBE(0x20,sf); - datasize = read_32bitBE(0x24,sf); - - bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - if (bytes <= 0) goto fail; - - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,datasize); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - xma_fix_raw_samples(vgmstream, sf, start_offset,datasize, 0, 0,1); /* num samples are ok */ + xma_fix_raw_samples(vgmstream, sf, start_offset, data_size, 0, 0,1); /* num samples are ok */ } #else goto fail; diff --git a/src/meta/ea_eaac.c b/src/meta/ea_eaac.c index 39b714ba..ce8e7dd5 100644 --- a/src/meta/ea_eaac.c +++ b/src/meta/ea_eaac.c @@ -1847,8 +1847,7 @@ static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *sf_data, eaac_ /* EA-XMA uses completely separate 1/2ch streams, unlike standard XMA that interleaves 1/2ch * streams with a skip counter to reinterleave (so EA-XMA streams don't have skips set) */ case EAAC_CODEC_EAXMA: { - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size; size_t stream_size; int is_xma1; @@ -1856,8 +1855,7 @@ static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *sf_data, eaac_ if (!temp_sf) goto fail; stream_size = get_streamfile_size(temp_sf); - block_size = 0x10000; /* unused */ - block_count = stream_size / block_size + ((stream_size % block_size) ? 1 : 0); + block_size = 0x10000; /* EA adopted XMA2 when it appeared around 2006, but detection isn't so easy * (SNS with XMA2 do exist). Decoder should work when playing XMA1 as XMA2, but @@ -1867,8 +1865,7 @@ static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *sf_data, eaac_ data->layers[i]->codec_data = init_ffmpeg_xma1_raw(temp_sf, 0x00, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, 0); } else { - bytes = ffmpeg_make_riff_xma2(buf, 0x100, data->layers[i]->num_samples, stream_size, data->layers[i]->channels, data->layers[i]->sample_rate, block_count, block_size); - data->layers[i]->codec_data = init_ffmpeg_header_offset(temp_sf, buf,bytes, 0x00, stream_size); + data->layers[i]->codec_data = init_ffmpeg_xma2_raw(temp_sf, 0x00, stream_size, data->layers[i]->num_samples, data->layers[i]->channels, data->layers[i]->sample_rate, block_size, 0); } if (!data->layers[i]->codec_data) goto fail; diff --git a/src/meta/fsb.c b/src/meta/fsb.c index 8b5cadcb..ab996159 100644 --- a/src/meta/fsb.c +++ b/src/meta/fsb.c @@ -388,19 +388,14 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case XMA: { /* FSB3: The Bourne Conspiracy 2008 (X360), FSB4: Armored Core V (X360), Hard Corps (X360) */ - uint8_t buf[0x100]; - size_t bytes, block_size, block_count; + int block_size = 0x8000; /* FSB default */ if (fsb.version != FMOD_FSB_VERSION_4_0) { /* 3.x, though no actual output changes [ex. Guitar Hero III (X360), The Bourne Conspiracy (X360)] */ vgmstream->codec_data = init_ffmpeg_xma1_raw(sf, fsb.stream_offset, fsb.stream_size, fsb.channels, fsb.sample_rate, 0); } else { - block_size = 0x8000; /* FSB default */ - block_count = fsb.stream_size / block_size; /* not accurate but not needed (custom_data_offset+0x14 -1?) */ - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), fsb.num_samples, fsb.stream_size, fsb.channels, fsb.sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, fsb.stream_offset,fsb.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, fsb.stream_offset, fsb.stream_size, fsb.num_samples, fsb.channels, fsb.sample_rate, block_size, 0); } if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; diff --git a/src/meta/fsb5.c b/src/meta/fsb5.c index 11478bf4..1b893772 100644 --- a/src/meta/fsb5.c +++ b/src/meta/fsb5.c @@ -367,14 +367,9 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0A: {/* FMOD_SOUND_FORMAT_XMA [Minecraft Story Mode (X360)] */ - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size = 0x8000; /* FSB default */ - block_size = 0x8000; /* FSB default */ - block_count = fsb5.stream_size / block_size + (fsb5.stream_size % block_size ? 1 : 0); - - bytes = ffmpeg_make_riff_xma2(buf, 0x100, vgmstream->num_samples, fsb5.stream_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sb, buf,bytes, fsb5.stream_offset, fsb5.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, fsb5.stream_offset, fsb5.stream_size, fsb5.num_samples, fsb5.channels, fsb5.sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/genh.c b/src/meta/genh.c index 17db8554..4220f764 100644 --- a/src/meta/genh.c +++ b/src/meta/genh.c @@ -70,21 +70,21 @@ typedef struct { static int parse_genh(STREAMFILE * streamFile, genh_header * genh); /* GENH is an artificial "generic" header for headerless streams */ -VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_genh(STREAMFILE *sf) { + VGMSTREAM* vgmstream = NULL; genh_header genh = {0}; coding_t coding; int i, j; - /* check extension, case insensitive */ - if (!check_extensions(streamFile,"genh")) goto fail; - - /* check header magic */ - if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail; + /* checks */ + if (!is_id32be(0x0,sf, "GENH")) + goto fail; + if (!check_extensions(sf,"genh")) + goto fail; /* process the header */ - if (!parse_genh(streamFile, &genh)) + if (!parse_genh(sf, &genh)) goto fail; @@ -277,13 +277,13 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { /* normal/split coefs */ if ((genh.coef_type & 1) == 0) { /* normal mode */ for (j = 0; j < 16; j++) { - vgmstream->ch[i].adpcm_coef[j] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, streamFile); + vgmstream->ch[i].adpcm_coef[j] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, sf); } } else { /* split coefs, 8 coefs in the main array, additional offset to 2nd array given at 0x34 for left, 0x38 for right */ for (j = 0; j < 8; j++) { - vgmstream->ch[i].adpcm_coef[j*2] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, streamFile); - vgmstream->ch[i].adpcm_coef[j*2+1] = read_16bit(genh.coef_split_offset + i*genh.coef_split_spacing + j*2, streamFile); + vgmstream->ch[i].adpcm_coef[j*2] = read_16bit(genh.coef_offset + i*genh.coef_spacing + j*2, sf); + vgmstream->ch[i].adpcm_coef[j*2+1] = read_16bit(genh.coef_split_offset + i*genh.coef_split_spacing + j*2, sf); } } } @@ -292,7 +292,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { #ifdef VGM_USE_MPEG case coding_MPEG_layer3: vgmstream->layout_type = layout_none; - vgmstream->codec_data = init_mpeg(streamFile, genh.start_offset, &coding, vgmstream->channels); + vgmstream->codec_data = init_mpeg(sf, genh.start_offset, &coding, vgmstream->channels); if (!vgmstream->codec_data) goto fail; break; @@ -303,7 +303,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { if (genh.codec == FFMPEG || genh.codec == AC3 || genh.codec == AAC) { /* default FFmpeg */ - ffmpeg_data = init_ffmpeg_offset(streamFile, genh.start_offset,genh.data_size); + ffmpeg_data = init_ffmpeg_offset(sf, genh.start_offset,genh.data_size); if ( !ffmpeg_data ) goto fail; //if (vgmstream->num_samples == 0) @@ -320,31 +320,27 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { block_align = genh.interleave; encoder_delay = genh.skip_samples; - ffmpeg_data = init_ffmpeg_atrac3_raw(streamFile, genh.start_offset,genh.data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); + ffmpeg_data = init_ffmpeg_atrac3_raw(sf, genh.start_offset,genh.data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay); if (!ffmpeg_data) goto fail; } else if (genh.codec == ATRAC3PLUS) { int block_size = genh.interleave; bytes = ffmpeg_make_riff_atrac3plus(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_size, genh.skip_samples); - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, genh.start_offset,genh.data_size); + ffmpeg_data = init_ffmpeg_header_offset(sf, buf,bytes, genh.start_offset,genh.data_size); if ( !ffmpeg_data ) goto fail; } else if (genh.codec == XMA1) { int xma_stream_mode = genh.codec_mode == 1 ? 1 : 0; - ffmpeg_data = init_ffmpeg_xma1_raw(streamFile, genh.start_offset, genh.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); - if ( !ffmpeg_data ) goto fail; + ffmpeg_data = init_ffmpeg_xma1_raw(sf, genh.start_offset, genh.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); + if (!ffmpeg_data) goto fail; } else if (genh.codec == XMA2) { - int block_count, block_size; + int block_size = genh.interleave; - block_size = genh.interleave ? genh.interleave : 2048; - block_count = genh.data_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, genh.start_offset,genh.data_size); - if ( !ffmpeg_data ) goto fail; + ffmpeg_data = init_ffmpeg_xma2_raw(sf, genh.start_offset, genh.data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); + if (!ffmpeg_data) goto fail; } else { goto fail; @@ -355,7 +351,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { vgmstream->layout_type = layout_none; if (genh.codec == XMA1 || genh.codec == XMA2) { - xma_fix_raw_samples(vgmstream, streamFile, genh.start_offset,genh.data_size, 0, 0,0); + xma_fix_raw_samples(vgmstream, sf, genh.start_offset,genh.data_size, 0, 0,0); } else if (genh.skip_samples_mode && genh.skip_samples >= 0 && genh.codec != ATRAC3) { /* force encoder delay */ ffmpeg_set_skip_samples(ffmpeg_data, genh.skip_samples); } @@ -372,7 +368,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { vgmstream->allow_dual_stereo = 1; - if ( !vgmstream_open_stream(vgmstream,streamFile,genh.start_offset) ) + if ( !vgmstream_open_stream(vgmstream,sf,genh.start_offset) ) goto fail; return vgmstream; diff --git a/src/meta/idtech.c b/src/meta/idtech.c index 828977bc..bae933ff 100644 --- a/src/meta/idtech.c +++ b/src/meta/idtech.c @@ -13,14 +13,14 @@ VGMSTREAM* init_vgmstream_mzrt_v0(STREAMFILE* sf) { /* checks */ + if (!is_id32be(0x00,sf, "mzrt")) + goto fail; + if (read_u32be(0x04, sf) != 0) /* version */ + goto fail; + if (!check_extensions(sf, "idwav,idmsf,idxma")) goto fail; - if (!is_id32be(0x00,sf, "mzrt")) - goto fail; - - if (read_u32be(0x04, sf) != 0) /* version */ - goto fail; /* this format is bizarrely mis-aligned (and mis-designed too) */ @@ -164,14 +164,14 @@ VGMSTREAM* init_vgmstream_mzrt_v1(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf, "idmsf")) //idmsa: untested - goto fail; - if (!is_id32be(0x00,sf, "mzrt")) goto fail; if (read_u32be(0x04, sf) != 1) /* version */ goto fail; + if (!check_extensions(sf, "idmsf")) //idmsa: untested + goto fail; + type = read_s32be(0x09,sf); if (type == 0) { /* Rage */ /* 0x0d: null */ @@ -311,14 +311,14 @@ VGMSTREAM* init_vgmstream_bsnf(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf, "bsnd")) - goto fail; - if (!is_id32be(0x00,sf, "bsnf")) /* null-terminated string */ goto fail; if (read_u32be(0x05, sf) != 0x00000100) /* version */ goto fail; + if (!check_extensions(sf, "bsnd")) + goto fail; + offset = 0x18; stream_size = read_u32be(offset + 0x00,sf); @@ -427,14 +427,9 @@ VGMSTREAM* init_vgmstream_bsnf(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0166: { - uint8_t buf[0x100]; - size_t bytes, block_size, block_count; + int block_size = 0x800; - block_size = 0x800; - block_count = stream_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), num_samples, stream_size, channels, sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sb, buf, bytes, start_offset, stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, stream_size, num_samples, channels, sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/kwb.c b/src/meta/kwb.c index 04025e2a..3317938f 100644 --- a/src/meta/kwb.c +++ b/src/meta/kwb.c @@ -215,16 +215,11 @@ static VGMSTREAM* init_vgmstream_koei_wavebank(kwb_header* kwb, STREAMFILE* sf_h #ifdef VGM_USE_FFMPEG case XMA2: { - uint8_t buf[0x100]; - size_t bytes, block_size, block_count; + int block_size = 0x800; /* ? */ if (kwb->channels > 1) goto fail; - block_size = 0x800; /* ? */ - block_count = kwb->stream_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), vgmstream->num_samples, kwb->stream_size, kwb->channels, kwb->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf_b, buf,bytes, kwb->stream_offset, kwb->stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf_b, kwb->stream_offset, kwb->stream_size, vgmstream->num_samples, kwb->channels, kwb->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/rsd.c b/src/meta/rsd.c index cb47075f..84651d88 100644 --- a/src/meta/rsd.c +++ b/src/meta/rsd.c @@ -13,9 +13,9 @@ VGMSTREAM* init_vgmstream_rsd(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf,"rsd,rsp")) + if ((read_u32be(0x00,sf) & 0xFFFFFF00) != get_id32be("RSD\00")) goto fail; - if ((read_u32be(0x00,sf) & 0xFFFFFF00) != 0x52534400) /* "RSD\00" */ + if (!check_extensions(sf,"rsd,rsp")) goto fail; loop_flag = 0; @@ -168,40 +168,34 @@ VGMSTREAM* init_vgmstream_rsd(STREAMFILE* sf) { } case 0x584D4120: { /* "XMA " [Crash of the Titans (X360)-v1, Crash: Mind over Mutant (X360)-v2] */ - uint8_t buf[0x100]; - size_t bytes, xma_size, block_size, block_count; - int xma_version; + uint32_t chunk_size = read_32bitBE(0x800, sf); + uint32_t seek_size = read_32bitBE(0x804, sf); + uint32_t stream_size = read_32bitBE(0x808, sf); + uint32_t chunk_offset = 0x80c; + int old_xma2_version = read_u8(chunk_offset + 0x00, sf); + start_offset = chunk_offset + chunk_size + seek_size; - /* skip mini header */ - start_offset = 0x800 + read_32bitBE(0x800, sf) + read_32bitBE(0x804, sf) + 0xc; /* assumed, seek table always at 0x800 */ - xma_size = read_32bitBE(0x808, sf); - xma_version = read_u8(0x80C, sf); + vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, start_offset, stream_size, chunk_offset, chunk_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; - switch (xma_version) { + /* read PCM samples rather than full samples (dev trickery?) */ + switch (old_xma2_version) { case 0x03: - vgmstream->sample_rate = read_32bitBE(0x818, sf); - vgmstream->num_samples = read_32bitBE(0x824, sf); - block_count = read_32bitBE(0x828, sf); - block_size = 0x10000; + vgmstream->sample_rate = read_32bitBE(chunk_offset + 0x0c, sf); + vgmstream->num_samples = read_32bitBE(chunk_offset + 0x18, sf); break; case 0x04: - vgmstream->num_samples = read_32bitBE(0x814, sf); - vgmstream->sample_rate = read_32bitBE(0x818, sf); - block_count = read_32bitBE(0x830, sf); - block_size = 0x10000; + vgmstream->num_samples = read_32bitBE(chunk_offset + 0x08, sf); + vgmstream->sample_rate = read_32bitBE(chunk_offset + 0x0c, sf); break; default: goto fail; } - bytes = ffmpeg_make_riff_xma2(buf,sizeof(buf), vgmstream->num_samples, xma_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, start_offset, xma_size); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - - /* for some reason (dev trickery?) .rsd don't set skip in the bitstream, though they should */ + /* for some reason (dev trickery?) .rsd don't set skips in the bitstream, though they should */ //xma_fix_raw_samples(vgmstream, sf, start_offset,xma_size, 0, 0,0); ffmpeg_set_skip_samples(vgmstream->codec_data, 512+64); break; @@ -218,7 +212,6 @@ VGMSTREAM* init_vgmstream_rsd(STREAMFILE* sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/src/meta/seg.c b/src/meta/seg.c index 87e6f85b..27bed92f 100644 --- a/src/meta/seg.c +++ b/src/meta/seg.c @@ -2,8 +2,8 @@ #include "../coding/coding.h" /* SEG - from Stormfront games [Eragon (multi), Forgotten Realms: Demon Stone (multi) */ -VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_seg(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset; int loop_flag, channel_count; size_t data_size; @@ -12,24 +12,24 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { /* checks */ - if (!check_extensions(streamFile, "seg")) + if (!is_id32be(0x00,sf, "seg\0")) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x73656700) /* "seg\0" */ + if (!check_extensions(sf, "seg")) goto fail; - codec = read_32bitBE(0x04,streamFile); + codec = read_32bitBE(0x04,sf); /* 0x08: version? (2: Eragon, Spiderwick Chronicles Wii / 3: Spiderwick Chronicles X360 / 4: Spiderwick Chronicles PC) */ - if (guess_endianness32bit(0x08,streamFile)) { + if (guess_endianness32bit(0x08,sf)) { read_32bit = read_32bitBE; } else { read_32bit = read_32bitLE; } /* 0x0c: file size */ - data_size = read_32bit(0x10, streamFile); /* including interleave padding */ + data_size = read_32bit(0x10, sf); /* including interleave padding */ /* 0x14: null */ - loop_flag = read_32bit(0x20,streamFile); /* rare */ - channel_count = read_32bit(0x24,streamFile); + loop_flag = read_32bit(0x20,sf); /* rare */ + channel_count = read_32bit(0x24,sf); /* 0x28: extradata 1 entries (0x08 per entry, unknown) */ /* 0x2c: extradata 1 offset */ /* 0x30: extradata 2 entries (0x10 or 0x14 per entry, seek/hist table?) */ @@ -43,13 +43,13 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { if (!vgmstream) goto fail; vgmstream->meta_type = meta_SEG; - vgmstream->sample_rate = read_32bit(0x18,streamFile); - vgmstream->num_samples = read_32bit(0x1c,streamFile); + vgmstream->sample_rate = read_32bit(0x18,sf); + vgmstream->num_samples = read_32bit(0x1c,sf); if (loop_flag) { vgmstream->loop_start_sample = 0; vgmstream->loop_end_sample = vgmstream->num_samples; } - read_string(vgmstream->stream_name,0x20+1, 0x38,streamFile); + read_string(vgmstream->stream_name,0x20+1, 0x38,sf); switch(codec) { case 0x70733200: /* "ps2\0" */ @@ -71,8 +71,8 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { vgmstream->interleave_first_block_size = vgmstream->interleave_block_size - vgmstream->interleave_first_skip; /* standard dsp header at start_offset */ - dsp_read_coefs_be(vgmstream, streamFile, start_offset+0x1c, vgmstream->interleave_block_size); - dsp_read_hist_be(vgmstream, streamFile, start_offset+0x40, vgmstream->interleave_block_size); + dsp_read_coefs_be(vgmstream, sf, start_offset+0x1c, vgmstream->interleave_block_size); + dsp_read_hist_be(vgmstream, sf, start_offset+0x40, vgmstream->interleave_block_size); start_offset += vgmstream->interleave_first_skip; break; @@ -84,19 +84,14 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { #ifdef VGM_USE_FFMPEG case 0x78623300: { /* "xb3\0" */ - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size = 0x4000; - block_size = 0x4000; - block_count = data_size / block_size + (data_size % block_size ? 1 : 0); - - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - xma_fix_raw_samples(vgmstream, streamFile, start_offset,data_size, 0, 0,0); /* samples are ok */ + xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); /* samples are ok */ break; } #endif @@ -105,10 +100,9 @@ VGMSTREAM * init_vgmstream_seg(STREAMFILE *streamFile) { goto fail; } - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/src/meta/smp.c b/src/meta/smp.c index 6dbf31c1..ff567760 100644 --- a/src/meta/smp.c +++ b/src/meta/smp.c @@ -11,9 +11,6 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf, "smp")) - goto fail; - version = read_u32le(0x00,sf); if (version != 0x05 && /* Ghostbusters (PS2), Mushroom Men (Wii) */ version != 0x06 && /* Ghostbusters (PS3/X360/PC) */ @@ -21,6 +18,9 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { version != 0x08) /* Chandragupta (PS2/PSP), Street Cricket Champions 1/2 (PSP), Guilty Party (Wii) */ goto fail; + if (!check_extensions(sf, "smp")) + goto fail; + /* 0x04~14: guid? */ if (read_u32le(0x14,sf) != 0) /* reserved? */ goto fail; @@ -28,6 +28,9 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { start_offset = read_u32le(0x1c,sf); data_size = read_u32le(0x20,sf); codec = read_u32le(0x24,sf); + if (start_offset + data_size != get_streamfile_size(sf)) + goto fail; + /* smaller header found in Guilty Party (Wii) */ if (version == 0x08 && start_offset == 0x80) { channels = read_u8(0x28,sf); @@ -102,17 +105,14 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x07: { - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size, block_count; if (bps != 16) goto fail; - /* 0x34(0x28): XMA config/table? */ + /* 0x34(0x28): XMA config/table? (unknown format) */ + block_size = read_u16le(0x3e,sf); + block_count = read_u16le(0x54,sf); - block_size = 0x8000; /* assumed, @0x3e(2)? */ - block_count = data_size / block_size + (data_size % block_size ? 1 : 0); /* @0x54(2)? */ - - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -130,7 +130,6 @@ VGMSTREAM* init_vgmstream_smp(STREAMFILE* sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/src/meta/str_wav.c b/src/meta/str_wav.c index 331918bc..84e9117c 100644 --- a/src/meta/str_wav.c +++ b/src/meta/str_wav.c @@ -160,16 +160,10 @@ VGMSTREAM* init_vgmstream_str_wav(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case XMA2: { - uint8_t buf[0x100]; - size_t stream_size; - size_t bytes, block_size, block_count; + uint32_t stream_size = get_streamfile_size(sf); + int block_size = 0x10000; - stream_size = get_streamfile_size(sf); - block_size = 0x10000; - block_count = stream_size / block_size; /* not accurate? */ - - bytes = ffmpeg_make_riff_xma2(buf,0x100, strwav.num_samples, stream_size, strwav.channels, strwav.sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, 0x00,stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, 0x00, stream_size, strwav.num_samples, strwav.channels, strwav.sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/ta_aac.c b/src/meta/ta_aac.c index c8eab411..8560b404 100644 --- a/src/meta/ta_aac.c +++ b/src/meta/ta_aac.c @@ -15,11 +15,11 @@ typedef struct { int32_t loop_end; int loop_flag; - off_t stream_offset; - off_t stream_size; - off_t extra_offset; + uint32_t stream_offset; + uint32_t stream_size; + uint32_t extra_offset; - off_t name_offset; + uint32_t name_offset; } aac_header; static int parse_aac(STREAMFILE* sf, aac_header* aac); @@ -32,11 +32,11 @@ VGMSTREAM* init_vgmstream_ta_aac(STREAMFILE* sf) { /* checks */ + if (!is_id32be(0x00, sf, "AAC ") && !is_id32le(0x00, sf, "AAC ")) + goto fail; /* .aac: actual extension, .laac: for players to avoid hijacking MP4/AAC */ if (!check_extensions(sf, "aac,laac")) goto fail; - if (!is_id32be(0x00, sf, "AAC ") && !is_id32le(0x00, sf, "AAC ")) - goto fail; if (!parse_aac(sf, &aac)) goto fail; @@ -55,11 +55,7 @@ VGMSTREAM* init_vgmstream_ta_aac(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x0165: { /* Infinite Undiscovery (X360), Star Ocean 4 (X360), Resonance of Fate (X360) */ - uint8_t buf[0x100]; - size_t bytes; - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), aac.num_samples, aac.stream_size, aac.channels, aac.sample_rate, aac.block_count, aac.block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, aac.stream_offset, aac.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, aac.stream_offset, aac.stream_size, aac.num_samples, aac.channels, aac.sample_rate, aac.block_size, aac.block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -261,7 +257,7 @@ static int parse_aac_v1(STREAMFILE* sf, aac_header* aac) { aac->block_count = read_u32be(offset + 0x2c, sf); /* one UI file has a smaller header, early version? */ - if (read_u32be(offset + 0x30, sf) == 0x7374726D) { + if (is_id32be(offset + 0x30, sf, "strm")) { aac->loop_flag = 0; /* ? */ strm_offset = 0x30; } diff --git a/src/meta/txth.c b/src/meta/txth.c index 1e141552..dae5d062 100644 --- a/src/meta/txth.c +++ b/src/meta/txth.c @@ -575,17 +575,13 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { int xma_stream_mode = txth.codec_mode == 1 ? 1 : 0; ffmpeg_data = init_ffmpeg_xma1_raw(txth.sf_body, txth.start_offset, txth.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); - if ( !ffmpeg_data ) goto fail; + if (!ffmpeg_data) goto fail; } else if (txth.codec == XMA2) { - int block_count, block_size; + int block_size = txth.interleave; - block_size = txth.interleave ? txth.interleave : 2048; - block_count = txth.data_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), vgmstream->num_samples, txth.data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - ffmpeg_data = init_ffmpeg_header_offset(txth.sf_body, buf,bytes, txth.start_offset,txth.data_size); - if ( !ffmpeg_data ) goto fail; + ffmpeg_data = init_ffmpeg_xma2_raw(sf, txth.start_offset, txth.data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); + if (!ffmpeg_data) goto fail; } else { goto fail; diff --git a/src/meta/ubi_hx.c b/src/meta/ubi_hx.c index 6dc4c5a1..2a830ab0 100644 --- a/src/meta/ubi_hx.c +++ b/src/meta/ubi_hx.c @@ -745,14 +745,9 @@ static VGMSTREAM* init_vgmstream_ubi_hx_header(ubi_hx_header* hx, STREAMFILE* sf #ifdef VGM_USE_FFMPEG case XMA2: { - int bytes, block_count, block_size; - uint8_t buf[0x200]; + int block_size = 0x800; - block_size = 0x800; - block_count = hx->stream_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf,0x200, hx->num_samples, hx->stream_size, hx->channels, hx->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sb, buf,bytes, hx->stream_offset,hx->stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sb, hx->stream_offset, hx->stream_size, hx->num_samples, hx->channels, hx->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/ubi_raki.c b/src/meta/ubi_raki.c index 790a0497..82626b29 100644 --- a/src/meta/ubi_raki.c +++ b/src/meta/ubi_raki.c @@ -3,8 +3,8 @@ /* RAKI - Ubisoft audio format [Rayman Legends, Just Dance 2017 (multi)] */ -VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *sf) { - VGMSTREAM * vgmstream = NULL; +VGMSTREAM* init_vgmstream_ubi_raki(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; off_t start_offset, offset, fmt_offset; size_t header_size, data_size; int big_endian; @@ -16,19 +16,22 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *sf) { /* checks */ + + /* some games (ex. Rayman Legends PS3) have a 32b file type before the RAKI data. However offsets are + * absolute and expect the type exists, so it's part of the file and not an extraction defect. + * Type varies between platforms (0x09, 0x0b, etc). */ + if ((is_id32be(0x00,sf, "RAKI"))) + offset = 0x00; + else if (is_id32be(0x04,sf, "RAKI")) + offset = 0x04; + else + goto fail; + /* .rak: Just Dance 2017 * .ckd: Rayman Legends (technically .wav.ckd/rak) */ if (!check_extensions(sf,"rak,ckd")) goto fail; - /* some games (ex. Rayman Legends PS3) have a 32b file type before the RAKI data. However - * offsets are absolute and expect the type exists, so it's part of the file and not an extraction defect. */ - if ((read_32bitBE(0x00,sf) == 0x52414B49)) /* "RAKI" */ - offset = 0x00; - else if ((read_32bitBE(0x04,sf) == 0x52414B49)) /* type varies between platforms (0x09, 0x0b) so ignore */ - offset = 0x04; - else - goto fail; /* 0x04: version? (0x00, 0x07, 0x0a, etc); */ platform = read_32bitBE(offset+0x08,sf); /* string */ @@ -182,20 +185,15 @@ VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE *sf) { #ifdef VGM_USE_FFMPEG case 0x58333630786D6132: { /* "X360xma2" */ /* chunks: "seek" (XMA2 seek table), "data" */ - uint8_t buf[100]; - int bytes, block_count; if (!block_align) goto fail; - block_count = data_size / block_align + (data_size % block_align ? 1 : 0); + vgmstream->num_samples = read_32bit(fmt_offset+0x18,sf); - bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_align); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_align, 0); if ( !vgmstream->codec_data ) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - vgmstream->num_samples = read_32bit(fmt_offset+0x18,sf); - xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); /* should apply to num_samples? */ break; } diff --git a/src/meta/xmv_valve.c b/src/meta/xmv_valve.c index f8fbdf20..599715f9 100644 --- a/src/meta/xmv_valve.c +++ b/src/meta/xmv_valve.c @@ -10,17 +10,16 @@ VGMSTREAM* init_vgmstream_xbox_hlwav(STREAMFILE* sf) { int loop_flag; /* checks */ - if (!check_extensions(sf, "wav,lwav")) - goto fail; - - /* check header and size */ header_size = read_u32le(0x00, sf); if (header_size != 0x14) goto fail; data_size = read_u32le(0x04, sf); start_offset = read_u32le(0x08, sf); - if (data_size != get_streamfile_size(sf) - start_offset) + if (start_offset + data_size != get_streamfile_size(sf)) + goto fail; + + if (!check_extensions(sf, "wav,lwav")) goto fail; loop_start = read_s32le(0x0c, sf); @@ -76,8 +75,8 @@ fail: return NULL; } -/* .360.WAV, .PS3.WAV - from Valve games running on Source Engine, evolution of Xbox .WAV format seen above */ -/* [The Orange Box (X360), Portal 2 (PS3/X360), Counter-Strike: Global Offensive (PS3/X360)] */ +/* XMV - from Valve games running on Source Engine, evolution of Xbox .WAV format seen above + * [The Orange Box (X360), Portal 2 (PS3/X360), Counter-Strike: Global Offensive (PS3/X360)] */ VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; int32_t loop_start; @@ -89,13 +88,13 @@ VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* sf) { /* checks */ if (!is_id32be(0x00, sf, "XMV ")) goto fail; + if (read_u32be(0x04, sf) != 0x04) /* only version 4 is known */ + goto fail; + /* technically .360.WAV, .PS3.WAV */ if (!check_extensions(sf, "wav,lwav")) goto fail; - /* only version 4 is known */ - if (read_u32be(0x04, sf) != 0x04) - goto fail; start_offset = read_u32be(0x10, sf); data_size = read_u32be(0x14, sf); @@ -139,27 +138,23 @@ VGMSTREAM* init_vgmstream_xmv_valve(STREAMFILE* sf) { vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x02; break; + #ifdef VGM_USE_FFMPEG case 0x01: { /* XMA */ - uint8_t buf[0x100]; - int block_count, block_size; - size_t bytes; + int block_size = 0x800; - block_size = 0x800; - block_count = data_size / block_size; - - bytes = ffmpeg_make_riff_xma2(buf, 0x100, num_samples, data_size, channels, sample_rate, block_count, block_size); - - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, start_offset, data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, num_samples, channels, sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; + vgmstream->loop_end_sample -= loop_end_skip; xma_fix_raw_samples(vgmstream, sf, start_offset, data_size, 0, 1, 1); break; } #endif + #ifdef VGM_USE_MPEG case 0x03: { /* MP3 */ coding_t mpeg_coding; diff --git a/src/meta/xnb.c b/src/meta/xnb.c index 0b8152e1..df03784e 100644 --- a/src/meta/xnb.c +++ b/src/meta/xnb.c @@ -259,14 +259,9 @@ VGMSTREAM* init_vgmstream_xnb(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 0x166: { /* Terraria (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; + int block_size = 0x10000; /* guessed */ - block_size = 0x10000; /* guessed */ - block_count = data_size / block_size + (data_size % block_size ? 1 : 0); - - bytes = ffmpeg_make_riff_xma2(buf,0x100, num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf_h, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf_h, start_offset, data_size, num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/xse.c b/src/meta/xse.c index 1b5a4696..ebc26bb1 100644 --- a/src/meta/xse.c +++ b/src/meta/xse.c @@ -14,9 +14,9 @@ VGMSTREAM* init_vgmstream_xse_new(STREAMFILE* sf) { /* checks */ - if (!check_extensions(sf, "xse")) + if (!is_id32be(0x00,sf, "HRDS")) goto fail; - if (read_u32be(0x00,sf) != 0x48524453) /* "HRDS" */ + if (!check_extensions(sf, "xse")) goto fail; /* similar to older version but BE and a bit less complex */ @@ -117,15 +117,11 @@ VGMSTREAM* init_vgmstream_xse_new(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 1: { /* Mindjack (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; - + int block_size = 0x10000; /* XWAV new default */ + int block_count = seek_count; data_size = get_streamfile_size(sf) - start_offset; - block_size = 0x10000; /* XWAV new default */ - block_count = seek_count; - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -148,7 +144,6 @@ VGMSTREAM* init_vgmstream_xse_new(STREAMFILE* sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; @@ -166,11 +161,12 @@ VGMSTREAM* init_vgmstream_xse_old(STREAMFILE* sf) { /* checks */ + if (!is_id32be(0x00,sf, "SDRH")) + goto fail; + /* .xse: assumed */ if (!check_extensions(sf, "xse")) goto fail; - if (read_u32be(0x00,sf) != 0x53445248) /* "SDRH" */ - goto fail; /* similar to older version but LE and a bit more complex */ /* 0x04: version/config? @@ -265,15 +261,12 @@ VGMSTREAM* init_vgmstream_xse_old(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 4: { /* Lost Odyssey (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; + int block_size = 0x8000; /* XWAV old default */ + int block_count = seek_count; data_size = get_streamfile_size(sf) - start_offset; - block_size = 0x8000; /* XWAV old default */ - block_count = seek_count; - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -294,7 +287,6 @@ VGMSTREAM* init_vgmstream_xse_old(STREAMFILE* sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/src/meta/xwav.c b/src/meta/xwav.c index d3a0c8e4..e25ccbc9 100644 --- a/src/meta/xwav.c +++ b/src/meta/xwav.c @@ -12,12 +12,13 @@ VGMSTREAM* init_vgmstream_xwav_new(STREAMFILE* sf) { /* checks */ + if (!is_id32be(0x00,sf, "VAWX")) + goto fail; + /* .xwv: actual extension [Moon Diver (PS3/X360)] * .vawx: header id */ if (!check_extensions(sf, "xwv,vawx")) goto fail; - if (read_u32be(0x00,sf) != 0x56415758) /* "VAWX" */ - goto fail; /* similar to older version but BE and a bit less complex */ /* 0x04: data size @@ -71,15 +72,12 @@ VGMSTREAM* init_vgmstream_xwav_new(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 1: { /* No Nore Heroes (X360), Moon Diver (X360), Ninety-Nine Nights 2 (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; + int block_size = 0x10000; /* XWAV new default */ + int block_count = read_u16be(0x30 + 0x0A, sf); /* also at 0x56 */ data_size = get_streamfile_size(sf) - start_offset; - block_size = 0x10000; /* XWAV new default */ - block_count = read_u16be(0x30 + 0x0A, sf); /* also at 0x56 */ - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -136,11 +134,12 @@ VGMSTREAM* init_vgmstream_xwav_old(STREAMFILE* sf) { /* checks */ + if (!is_id32be(0x00,sf, "XWAV")) + goto fail; + /* .xwv: actual extension [Bullet Witch (X360)] */ if (!check_extensions(sf, "xwv")) goto fail; - if (read_u32be(0x00,sf) != 0x58574156) /* "XWAV" */ - goto fail; /* similar to newer version but LE and a bit more complex */ /* 0x04: data size @@ -224,15 +223,12 @@ VGMSTREAM* init_vgmstream_xwav_old(STREAMFILE* sf) { #ifdef VGM_USE_FFMPEG case 4: { /* Lost Odyssey (X360) */ - uint8_t buf[0x100]; - int32_t bytes, block_size, block_count; + int block_size = 0x8000; /* XWAV old default */ + int block_count = read_u16be(0x30, sf); data_size = get_streamfile_size(sf) - start_offset; - block_size = 0x8000; /* XWAV old default */ - block_count = read_u16be(0x30, sf); - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; @@ -253,7 +249,6 @@ VGMSTREAM* init_vgmstream_xwav_old(STREAMFILE* sf) { if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL; diff --git a/src/meta/xwb.c b/src/meta/xwb.c index e236a000..5753f121 100644 --- a/src/meta/xwb.c +++ b/src/meta/xwb.c @@ -501,14 +501,9 @@ VGMSTREAM* init_vgmstream_xwb(STREAMFILE* sf) { } case XMA2: { /* Blue Dragon (X360) */ - uint8_t buf[0x100]; - int bytes, block_size, block_count; + int block_size = 0x10000; /* XACT default */ - block_size = 0x10000; /* XACT default */ - block_count = xwb.stream_size / block_size + (xwb.stream_size % block_size ? 1 : 0); - - bytes = ffmpeg_make_riff_xma2(buf, sizeof(buf), vgmstream->num_samples, xwb.stream_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, xwb.stream_offset,xwb.stream_size); + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, xwb.stream_offset, xwb.stream_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; diff --git a/src/meta/xwc.c b/src/meta/xwc.c index 9ddbdf89..e3edffac 100644 --- a/src/meta/xwc.c +++ b/src/meta/xwc.c @@ -11,7 +11,7 @@ VGMSTREAM* init_vgmstream_xwc(STREAMFILE* sf) { /* checks */ /* .xwc: extension of the bigfile, individual files don't have one */ - if ( !check_extensions(sf,"xwc")) + if (!check_extensions(sf,"xwc")) goto fail; @@ -73,15 +73,16 @@ VGMSTREAM* init_vgmstream_xwc(STREAMFILE* sf) { #endif #ifdef VGM_USE_FFMPEG case 0x584D4100: { /* "XMA\0" (X360) */ - uint8_t buf[0x100]; - int32_t bytes, seek_size, block_size, block_count, sample_rate, chunk_size; + uint32_t seek_size, chunk_size, chunk_offset; + int block_size, block_count, sample_rate; seek_size = read_32bitLE(extra_offset + 0x00, sf); chunk_size = read_32bitLE(extra_offset + 0x04 + seek_size, sf); + chunk_offset = extra_offset + 0x04 + seek_size + 0x04; - start_offset = extra_offset+ 0x04 + seek_size + chunk_size + 0x08; + data_size = read_32bitLE(chunk_offset + chunk_size + 0x00, sf); + start_offset = chunk_offset + chunk_size + 0x04; start_offset += (start_offset % 0x800) ? 0x800 - (start_offset % 0x800) : 0; /* padded */ - data_size = data_size - start_offset; if (chunk_size == 0x34) { /* new XMA2 */ sample_rate = read_32bitLE(extra_offset+0x04+seek_size+0x08, sf); @@ -89,7 +90,7 @@ VGMSTREAM* init_vgmstream_xwc(STREAMFILE* sf) { block_count = data_size / block_size; /* others: standard RIFF XMA2 fmt? */ } - else if (chunk_size == 0x2c) { /* old XMA2 */ + else if (chunk_size == 0x2c) { /* old XMA2 (not fully valid?) */ sample_rate = read_32bitBE(extra_offset+0x04+seek_size+0x10, sf); block_size = read_32bitBE(extra_offset+0x04+seek_size+0x1c, sf); block_count = read_32bitBE(extra_offset+0x04+seek_size+0x28, sf); @@ -99,14 +100,13 @@ VGMSTREAM* init_vgmstream_xwc(STREAMFILE* sf) { goto fail; } - bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, sample_rate, block_count, block_size); - vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf,bytes, start_offset,data_size); + vgmstream->sample_rate = sample_rate; + + vgmstream->codec_data = init_ffmpeg_xma2_raw(sf, start_offset, data_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, block_count); if (!vgmstream->codec_data) goto fail; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - vgmstream->sample_rate = sample_rate; - xma_fix_raw_samples(vgmstream, sf, start_offset,data_size, 0, 0,0); /* samples are ok, fix delay */ break; } @@ -116,12 +116,13 @@ VGMSTREAM* init_vgmstream_xwc(STREAMFILE* sf) { start_offset = 0x30; data_size = data_size - start_offset; + vgmstream->sample_rate = read_32bitLE(start_offset + 0x28, sf); + vgmstream->codec_data = init_ogg_vorbis(sf, start_offset, data_size, NULL); if ( !vgmstream->codec_data ) goto fail; vgmstream->coding_type = coding_OGG_VORBIS; vgmstream->layout_type = layout_none; - vgmstream->sample_rate = read_32bitLE(start_offset + 0x28, sf); break; } #endif @@ -130,10 +131,9 @@ VGMSTREAM* init_vgmstream_xwc(STREAMFILE* sf) { } - if ( !vgmstream_open_stream(vgmstream, sf, start_offset) ) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; - fail: close_vgmstream(vgmstream); return NULL;