cleanup: add xma2 raw init function

This commit is contained in:
bnnm 2023-01-21 13:51:27 +01:00
parent 86dceb51e5
commit 3c7770bbfb
25 changed files with 299 additions and 389 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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