mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 16:30:54 +01:00
cleanup: add xma2 raw init function
This commit is contained in:
parent
86dceb51e5
commit
3c7770bbfb
@ -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) */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user