Merge pull request #128 from bnnm/opus-fixes

Opus, fixes
This commit is contained in:
Christopher Snowhill 2017-09-30 14:13:17 -07:00 committed by GitHub
commit 8604198bb3
28 changed files with 344 additions and 145 deletions

View File

@ -207,6 +207,7 @@ VGMSTREAM_DECLARE_FILE_TYPE("NWA", nwa);
VGMSTREAM_DECLARE_FILE_TYPE("OGL", ogl);
VGMSTREAM_DECLARE_FILE_TYPE("OMA", oma);
VGMSTREAM_DECLARE_FILE_TYPE("OMU", omu);
VGMSTREAM_DECLARE_FILE_TYPE("OPUS", opus);
VGMSTREAM_DECLARE_FILE_TYPE("OTM", otm);
VGMSTREAM_DECLARE_FILE_TYPE("P2BT", p2bt);

View File

@ -214,7 +214,10 @@ void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples);
size_t ffmpeg_make_opus_header(uint8_t * buf, int buf_size, int channels, int skip, int sample_rate);
size_t ffmpeg_get_eaxma_virtual_size(off_t real_offset, size_t real_size, STREAMFILE *streamFile);
size_t ffmpeg_get_eaxma_virtual_size(int channels, off_t real_offset, size_t real_size, STREAMFILE *streamFile);
size_t switch_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile);
#endif
/* coding_utils */

View File

@ -243,7 +243,7 @@ int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, s
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 */
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 */
@ -251,7 +251,7 @@ int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, s
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 */
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 */

View File

@ -218,11 +218,11 @@ static int ffmpeg_read(void *opaque, uint8_t *buf, int buf_size) {
/* main read */
switch(data->config.type) {
case FFMPEG_EA_XMA: ret = ffmpeg_custom_read_eaxma(data, buf, buf_size); break;
case FFMPEG_WWISE_OPUS: ret = ffmpeg_custom_read_wwise_opus(data, buf, buf_size); break;
//case FFMPEG_EA_SCHL: ret = ffmpeg_custom_read_ea_schl(data, buf, buf_size); break;
//case FFMPEG_SFH: ret = ffmpeg_custom_read_sfh(data, buf, buf_size); break;
default: ret = ffmpeg_custom_read_standard(data, buf, buf_size); break;
case FFMPEG_EA_XMA: ret = ffmpeg_custom_read_eaxma(data, buf, buf_size); break;
case FFMPEG_SWITCH_OPUS: ret = ffmpeg_custom_read_switch_opus(data, buf, buf_size); break;
//case FFMPEG_EA_SCHL: ret = ffmpeg_custom_read_ea_schl(data, buf, buf_size); break;
//case FFMPEG_SFH: ret = ffmpeg_custom_read_sfh(data, buf, buf_size); break;
default: ret = ffmpeg_custom_read_standard(data, buf, buf_size); break;
}
data->virtual_offset += ret;
//data->real_offset = ; /* must be updated in function */
@ -285,11 +285,11 @@ static int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
/* main seek */
switch(data->config.type) {
case FFMPEG_EA_XMA: offset = ffmpeg_custom_seek_eaxma(data, offset); break;
case FFMPEG_WWISE_OPUS: offset = ffmpeg_custom_seek_wwise_opus(data, offset); break;
//case FFMPEG_EA_SCHL: offset = ffmpeg_custom_seek_ea_schl(data, offset); break;
//case FFMPEG_SFH: offset = ffmpeg_custom_seek_sfh(data, offset); break;
default: offset = ffmpeg_custom_seek_standard(data, offset); break;
case FFMPEG_EA_XMA: offset = ffmpeg_custom_seek_eaxma(data, offset); break;
case FFMPEG_SWITCH_OPUS: offset = ffmpeg_custom_seek_switch_opus(data, offset); break;
//case FFMPEG_EA_SCHL: offset = ffmpeg_custom_seek_ea_schl(data, offset); break;
//case FFMPEG_SFH: offset = ffmpeg_custom_seek_sfh(data, offset); break;
default: offset = ffmpeg_custom_seek_standard(data, offset); break;
}
data->virtual_offset = offset;
//data->real_offset = ; /* must be updated in function */
@ -302,11 +302,11 @@ static int64_t ffmpeg_seek(void *opaque, int64_t offset, int whence) {
static int64_t ffmpeg_size(ffmpeg_codec_data * data) {
int64_t bytes;
switch(data->config.type) {
case FFMPEG_EA_XMA: bytes = ffmpeg_custom_size_eaxma(data); break;
case FFMPEG_WWISE_OPUS: bytes = ffmpeg_custom_size_wwise_opus(data); break;
//case FFMPEG_EA_SCHL: bytes = ffmpeg_custom_size_ea_schl(data); break;
//case FFMPEG_SFH: bytes = ffmpeg_custom_size_sfh(data); break;
default: bytes = ffmpeg_custom_size_standard(data); break;
case FFMPEG_EA_XMA: bytes = ffmpeg_custom_size_eaxma(data); break;
case FFMPEG_SWITCH_OPUS: bytes = ffmpeg_custom_size_switch_opus(data); break;
//case FFMPEG_EA_SCHL: bytes = ffmpeg_custom_size_ea_schl(data); break;
//case FFMPEG_SFH: bytes = ffmpeg_custom_size_sfh(data); break;
default: bytes = ffmpeg_custom_size_standard(data); break;
}
return bytes;

View File

@ -27,9 +27,9 @@ int ffmpeg_custom_read_eaxma(ffmpeg_codec_data *data, uint8_t *buf, int buf_size
int64_t ffmpeg_custom_seek_eaxma(ffmpeg_codec_data *data, int64_t virtual_offset);
int64_t ffmpeg_custom_size_eaxma(ffmpeg_codec_data *data);
int ffmpeg_custom_read_wwise_opus(ffmpeg_codec_data *data, uint8_t *buf, int buf_size);
int64_t ffmpeg_custom_seek_wwise_opus(ffmpeg_codec_data *data, int64_t virtual_offset);
int64_t ffmpeg_custom_size_wwise_opus(ffmpeg_codec_data *data);
int ffmpeg_custom_read_switch_opus(ffmpeg_codec_data *data, uint8_t *buf, int buf_size);
int64_t ffmpeg_custom_seek_switch_opus(ffmpeg_codec_data *data, int64_t virtual_offset);
int64_t ffmpeg_custom_size_switch_opus(ffmpeg_codec_data *data);
//int ffmpeg_custom_read_ea_schl(ffmpeg_codec_data *data, uint8_t *buf, int buf_size);
//int64_t ffmpeg_custom_seek_ea_schl(ffmpeg_codec_data *data, int64_t virtual_offset);

View File

@ -3,58 +3,121 @@
#ifdef VGM_USE_FFMPEG
#define EAXMA_XMA_BLOCK_SIZE 0x800
#define EAXMA_XMA_MAX_PACKETS_PER_SNS_BLOCK 3 /* only seen up to 3 (Dante's Inferno) */
#define EAXMA_XMA_MAX_STREAMS_PER_SNS_BLOCK 4 /* XMA2 max is 8ch = 4 * 2ch */
#define EAXMA_XMA_PACKET_SIZE 0x800
#define EAXMA_XMA_BUFFER_SIZE (EAXMA_XMA_MAX_PACKETS_PER_SNS_BLOCK * EAXMA_XMA_MAX_STREAMS_PER_SNS_BLOCK * EAXMA_XMA_PACKET_SIZE)
/**
* EA-XMA is XMA with padding removed (so a real 0x450 block would be padded to a virtual 0x800 block).
* //todo missing multichannel (packet multistream) support, unknown layout
* EA-XMA is XMA2 with padding removed (so a real 0x450 block would be padded to a virtual 0x800 block).
* Each EA-XMA SNS block contains 1~3 packets per stream, and multistream uses fully separate streams
* (no packet_skip set). We'll pad and reinterleave packets so it resembles standard XMA2.
*
* XMA2 data layout (XMA1 is the same but doesn't use blocks, they are only for seeking):
* - frames (containing 1..4 subframes): decode into 128*4 samples
* - packets: size 0x800, containing N frames (last frame can spill into next packet), must be padded
* - blocks: fixed size, containing N packets (last packet's frames won't spill into next block)
* - stream: N interleaved packets (1/2ch) for multichannel (Nch) audio. Interleave is not fixed:
* at file start/new block has one packet per stream, then must follow the "packet_skip" value
* in the XMA packet header to find its next packet (skiping packets from other streams).
* ex.: s1_p1 skip1, s2_p1 skip2, s1_p2 skip0 s1_p3 skip1, s2_p2 skip1, s1_p4...
*/
static int get_block_max_packets(int num_streams, off_t packets_offset, STREAMFILE * streamfile);
int ffmpeg_custom_read_eaxma(ffmpeg_codec_data *data, uint8_t *buf, int buf_size) {
uint8_t v_buf[0x8000]; /* intermediate buffer, could be simplified */
uint8_t v_buf[EAXMA_XMA_BUFFER_SIZE]; /* intermediate buffer, could be simplified */
int buf_done = 0;
uint64_t real_offset = data->real_offset;
uint64_t virtual_offset = data->virtual_offset - data->header_size;
uint64_t virtual_base = data->virtual_base;
/* EA-XMA always uses late XMA2 streams (2ch + ... + 1/2ch) */
int num_streams = (data->config.channels / 2) + (data->config.channels % 2 ? 1 : 0);
/* read and transform SNS/EA-XMA block into XMA block by adding padding */
/* read and transform SNS/EA-XMA blocks into XMA packets */
while (buf_done < buf_size) {
int bytes_to_copy;
size_t data_size, extra_size = 0, gap_size = 0;
int s, p, bytes_to_copy, max_packets;
size_t data_size = 0, gap_size = 0;
size_t block_size = read_32bitBE(real_offset, data->streamfile);
/* 0x04(4): some kind of size? 0x08(4): decoded samples */
/* 0x04(4): decoded samples */
off_t packets_offset = real_offset + 0x08;
/* setup */
data_size = (block_size & 0x00FFFFFF) - 0x0c; //todo last block size may be slightly off?
if (data_size % EAXMA_XMA_BLOCK_SIZE) /* aligned padding */
extra_size = EAXMA_XMA_BLOCK_SIZE - (data_size % EAXMA_XMA_BLOCK_SIZE);
if (buf_done == 0) /* first read */
gap_size = virtual_offset - virtual_base; /* might start a few bytes into the block */
max_packets = get_block_max_packets(num_streams, packets_offset, data->streamfile);
if (max_packets == 0) goto fail;
if (data_size + extra_size > 0x8000) {
VGM_LOG("EA-XMA: total size bigger than buffer at %lx\n", (off_t)real_offset);
return 0;
if (max_packets * num_streams * EAXMA_XMA_PACKET_SIZE > EAXMA_XMA_BUFFER_SIZE) {
VGM_LOG("EA XMA: block too big at %lx\n", (off_t)real_offset);
goto fail;
}
bytes_to_copy = data_size + extra_size - gap_size;
/* data is divided into a sub-block per stream (N packets), can be smaller than block_size (= has padding)
* copy XMA data re-interleaving for multichannel. To simplify some calcs fills the same number of packets
* per stream and adjusts packet headers (see above for XMA2 multichannel layout). */
//to-do this doesn't make correct blocks sizes (but blocks are not needed to decode)
for (s = 0; s < num_streams; s++) {
size_t packets_size;
size_t packets_size4 = read_32bitBE(packets_offset, data->streamfile); /* size * 4, no idea */
packets_size = (packets_size4 / 4) - 0x04;
/* Re-interleave all packets in order, one per stream. If one stream has more packets than
* others we add empty packets to keep the same number for all, avoiding packet_skip calcs */
for (p = 0; p < max_packets; p++) {
off_t packet_offset = packets_offset + 0x04 + p * EAXMA_XMA_PACKET_SIZE; /* can be off but will copy 0 */
off_t v_buf_offset = p * EAXMA_XMA_PACKET_SIZE * num_streams + s * EAXMA_XMA_PACKET_SIZE;
size_t packet_to_do = packets_size - p * EAXMA_XMA_PACKET_SIZE;
size_t extra_size = 0;
uint32_t header;
if (packets_size < p * EAXMA_XMA_PACKET_SIZE)
packet_to_do = 0; /* empty packet */
else if (packet_to_do > EAXMA_XMA_PACKET_SIZE)
packet_to_do = EAXMA_XMA_PACKET_SIZE;
/* padding will be full size if packet_to_do is 0 */
if (packet_to_do < EAXMA_XMA_PACKET_SIZE)
extra_size = EAXMA_XMA_PACKET_SIZE - (packet_to_do % EAXMA_XMA_PACKET_SIZE);
/* copy data (or fully pad if empty packet) */
read_streamfile(v_buf + v_buf_offset, packet_offset, packet_to_do, data->streamfile);
memset(v_buf + v_buf_offset + packet_to_do, 0xFF, extra_size); /* add padding, typically 0xFF */
/* rewrite packet header to add packet skips for multichannel (EA XMA streams are fully separate and have none)
* header bits: 6=num_frames, 15=first_frame_bits_offset, 3=metadata, 8=packet_skip */
if (packet_to_do == 0)
header = 0x3FFF800; /* new empty packet header (0 num_frames, first_frame_bits_offset set to max) */
else
header = (uint32_t)read_32bitBE(packet_offset, data->streamfile);
/* get base header + change packet_skip since we know interleave is always 1 packet per stream */
header = (header & 0xFFFFFF00) | ((header & 0x000000FF) + num_streams - 1);
put_32bitBE(v_buf + v_buf_offset, header);
}
packets_offset += (packets_size4 / 4);
}
if (buf_done == 0) /* first read */
gap_size = virtual_offset - virtual_base; /* might start a few bytes into the XMA */
data_size = max_packets * num_streams * EAXMA_XMA_PACKET_SIZE;
bytes_to_copy = data_size - gap_size;
if (bytes_to_copy > buf_size - buf_done)
bytes_to_copy = buf_size - buf_done;
/* transform */
read_streamfile(v_buf, real_offset + 0x0c, data_size, data->streamfile);
memset(v_buf + data_size, 0xFF, extra_size); /* padding can be any value, typically 0xFF */
/* pad + copy */
memcpy(buf + buf_done, v_buf + gap_size, bytes_to_copy);
buf_done += bytes_to_copy;
/* move when block is fully done */
if (data_size + extra_size == bytes_to_copy + gap_size) {
if (data_size == bytes_to_copy + gap_size) {
real_offset += (block_size & 0x00FFFFFF);
virtual_base += data_size + extra_size;
virtual_base += data_size;
}
buf_done += bytes_to_copy;
/* exit on last block just in case, though should reach file size */
if (block_size & 0x80000000)
break;
@ -64,6 +127,9 @@ int ffmpeg_custom_read_eaxma(ffmpeg_codec_data *data, uint8_t *buf, int buf_size
data->real_offset = real_offset;
data->virtual_base = virtual_base;
return buf_size;
fail:
return 0;
}
int64_t ffmpeg_custom_seek_eaxma(ffmpeg_codec_data *data, int64_t virtual_offset) {
@ -89,8 +155,8 @@ int64_t ffmpeg_custom_seek_eaxma(ffmpeg_codec_data *data, int64_t virtual_offset
size_t block_size = read_32bitBE(real_offset, data->streamfile);
data_size = (block_size & 0x00FFFFFF) - 0x0c;
if (data_size % EAXMA_XMA_BLOCK_SIZE)
extra_size = EAXMA_XMA_BLOCK_SIZE - (data_size % EAXMA_XMA_BLOCK_SIZE);
if (data_size % EAXMA_XMA_PACKET_SIZE)
extra_size = EAXMA_XMA_PACKET_SIZE - (data_size % EAXMA_XMA_PACKET_SIZE);
/* stop if virtual_offset lands inside current block */
if (data_size + extra_size > virtual_offset)
@ -117,26 +183,32 @@ int64_t ffmpeg_custom_size_eaxma(ffmpeg_codec_data *data) {
}
/* needed to know in meta for fake RIFF */
size_t ffmpeg_get_eaxma_virtual_size(off_t real_offset, size_t real_size, STREAMFILE *streamFile) {
size_t ffmpeg_get_eaxma_virtual_size(int channels, off_t real_offset, size_t real_size, STREAMFILE *streamFile) {
size_t virtual_size = 0;
size_t real_end_offset = real_offset + real_size;
/* EA-XMA always uses late XMA2 streams (2ch + ... + 1/2ch) */
int num_streams = (channels / 2) + (channels % 2 ? 1 : 0);
/* count all SNS/EAXMA blocks size + padding size */
while (real_offset < real_size) {
size_t data_size;
size_t block_size = read_32bitBE(real_offset, streamFile);
data_size = (block_size & 0x00FFFFFF) - 0x0c;
while (real_offset < real_end_offset) {
int max_packets;
size_t block_size = read_32bitBE(real_offset + 0x00, streamFile);
/* 0x04(4): decoded samples */
off_t packets_offset = real_offset + 0x08;
if ((block_size & 0xFF000000) && !(block_size & 0x80000000)) {
VGM_LOG("EA-XMA: unknown flag found at %lx\n", (off_t)real_offset);
goto fail;
}
real_offset += (block_size & 0x00FFFFFF);
max_packets = get_block_max_packets(num_streams, packets_offset, streamFile);
if (max_packets == 0) goto fail;
virtual_size += data_size;
if (data_size % EAXMA_XMA_BLOCK_SIZE) /* XMA block padding */
virtual_size += EAXMA_XMA_BLOCK_SIZE - (data_size % EAXMA_XMA_BLOCK_SIZE);
/* fixed data_size per block for multichannel, see reads */
virtual_size += max_packets * num_streams * EAXMA_XMA_PACKET_SIZE;
real_offset += (block_size & 0x00FFFFFF);
/* exit on last block just in case, though should reach real_size */
if (block_size & 0x80000000)
@ -147,7 +219,33 @@ size_t ffmpeg_get_eaxma_virtual_size(off_t real_offset, size_t real_size, STREAM
fail:
return 0;
}
/* a block can have N streams each with a varying number of packets, get max */
static int get_block_max_packets(int num_streams, off_t packets_offset, STREAMFILE * streamfile) {
int s;
int max_packets = 0;
for (s = 0; s < num_streams; s++) {
size_t packets_size;
size_t packets_size4 = read_32bitBE(packets_offset, streamfile); /* size * 4, no idea */
int num_packets;
if (packets_size4 == 0) {
VGM_LOG("EA XMA: null packets in stream %i at %lx\n", s, (off_t)packets_offset);
goto fail;
}
packets_size = (packets_size4 / 4) - 0x04;
num_packets = (int)(packets_size / EAXMA_XMA_PACKET_SIZE) + 1;
if (num_packets > max_packets)
max_packets = num_packets;
}
return max_packets;
fail:
return 0;
}
#endif

View File

@ -44,7 +44,7 @@ fail:
}
int ffmpeg_custom_read_wwise_opus(ffmpeg_codec_data *data, uint8_t *buf, int buf_size) {
int ffmpeg_custom_read_switch_opus(ffmpeg_codec_data *data, uint8_t *buf, int buf_size) {
uint8_t v_buf[0x8000]; /* intermediate buffer, could be simplified */
int buf_done = 0;
uint64_t real_offset = data->real_offset;
@ -98,7 +98,7 @@ int ffmpeg_custom_read_wwise_opus(ffmpeg_codec_data *data, uint8_t *buf, int buf
return buf_size;
}
int64_t ffmpeg_custom_seek_wwise_opus(ffmpeg_codec_data *data, int64_t virtual_offset) {
int64_t ffmpeg_custom_seek_switch_opus(ffmpeg_codec_data *data, int64_t virtual_offset) {
int64_t real_offset, virtual_base;
int64_t current_virtual_offset = data->virtual_offset;
@ -138,13 +138,13 @@ int64_t ffmpeg_custom_seek_wwise_opus(ffmpeg_codec_data *data, int64_t virtual_o
return virtual_offset;
}
int64_t ffmpeg_custom_size_wwise_opus(ffmpeg_codec_data *data) {
int64_t ffmpeg_custom_size_switch_opus(ffmpeg_codec_data *data) {
uint64_t real_offset = data->real_start;
uint64_t real_size = data->real_size;
uint64_t real_end_offset = data->real_start + data->real_size;
uint64_t virtual_size = data->header_size;
/* count all Wwise Opus blocks size + OggS page size */
while (real_offset < real_size) {
while (real_offset < real_end_offset) {
size_t extra_size;
size_t data_size = read_32bitBE(real_offset, data->streamfile);
/* 0x00: data size, 0x04: ? (not a sequence or CRC), 0x08+: data */
@ -159,7 +159,23 @@ int64_t ffmpeg_custom_size_wwise_opus(ffmpeg_codec_data *data) {
return virtual_size;
}
size_t switch_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile) {
size_t num_samples = 0;
off_t end_offset = offset + data_size;
/* count by reading all frames */
while (offset < end_offset) {
uint8_t buf[4];
size_t block_size = read_32bitBE(offset, streamFile);
read_streamfile(buf, offset+4, 4, streamFile);
num_samples += get_opus_samples_per_frame(buf, sample_rate);
offset += 0x08 + block_size;
}
return num_samples;
}
/* ************************************************** */
@ -316,8 +332,8 @@ fail:
static size_t make_opus_comment(uint8_t * buf, int buf_size) {
size_t comment_size;
int vendor_string_length, user_comment_0_length;
char * vendor_string = "libopus 1.0.2";
char * user_comment_0_string = "ENCODER=opusenc from opus-tools 0.1.6";
char * vendor_string = "vgmstream";
char * user_comment_0_string = "vgmstream Opus converter";
vendor_string_length = strlen(vendor_string);
user_comment_0_length = strlen(user_comment_0_string);
@ -342,5 +358,4 @@ fail:
return 0;
}
#endif

View File

@ -200,6 +200,7 @@ static const char* extension_list[] = {
"ogl",
"oma", //FFmpeg, not parsed (ATRAC3/ATRAC3PLUS/MP3/LPCM/WMA)
"omu",
"opus",
"otm",
"p1d", //txth/reserved [Farming Simulator 18 (3DS)]
@ -811,7 +812,7 @@ static const meta_info meta_info_list[] = {
{meta_FFW, "Freedom Fighters BGM header"},
{meta_DSP_DSPW, "DSPW dsp header"},
{meta_PS2_JSTM, "JSTM Header"},
{meta_PS3_XVAG, "XVAG Header"},
{meta_XVAG, "Sony XVAG header"},
{meta_PS3_CPS, "tri-Crescendo CPS Header"},
{meta_SQEX_SCD, "Square-Enix SCD header"},
{meta_NGC_NST_DSP, "Animaniacs NST header"},
@ -888,6 +889,7 @@ static const meta_info meta_info_list[] = {
{meta_BINK, "RAD Game Tools Bink header"},
{meta_EA_SNU, "Electronic Arts SNU header"},
{meta_AWC, "Rockstar AWC header"},
{meta_NSW_OPUS, ".OPUS header"},
#ifdef VGM_USE_VORBIS
{meta_OGG_VORBIS, "Ogg Vorbis"},

View File

@ -622,10 +622,18 @@
RelativePath=".\meta\ngca.c"
>
</File>
<File
RelativePath=".\meta\nsw_opus.c"
>
</File>
<File
RelativePath=".\meta\nub_vag.c"
>
</File>
<File
RelativePath=".\meta\nub_xma.c"
>
</File>
<File
RelativePath=".\meta\nwa.c"
>
@ -998,10 +1006,6 @@
RelativePath=".\meta\vawx.c"
>
</File>
<File
RelativePath=".\meta\ps3_xvag.c"
>
</File>
<File
RelativePath=".\meta\psx_cdxa.c"
>
@ -1230,10 +1234,6 @@
RelativePath=".\meta\x360_cxs.c"
>
</File>
<File
RelativePath=".\meta\x360_nub.c"
>
</File>
<File
RelativePath=".\meta\x360_pasx.c"
>
@ -1278,6 +1278,10 @@
RelativePath=".\meta\xss.c"
>
</File>
<File
RelativePath=".\meta\xvag.c"
>
</File>
<File
RelativePath=".\meta\xwb.c"
>
@ -1379,7 +1383,7 @@
>
</File>
<File
RelativePath=".\coding\ffmpeg_decoder_utils_wwise_opus.c"
RelativePath=".\coding\ffmpeg_decoder_utils_switch_opus.c"
>
</File>
<File

View File

@ -133,7 +133,7 @@
<ClCompile Include="coding\coding_utils.c" />
<ClCompile Include="coding\ffmpeg_decoder.c" />
<ClCompile Include="coding\ffmpeg_decoder_utils_ea_xma.c" />
<ClCompile Include="coding\ffmpeg_decoder_utils_wwise_opus.c" />
<ClCompile Include="coding\ffmpeg_decoder_utils_switch_opus.c" />
<ClCompile Include="coding\ffmpeg_decoder_utils.c" />
<ClCompile Include="coding\lsf_decoder.c" />
<ClCompile Include="coding\mp4_aac_decoder.c" />
@ -157,6 +157,7 @@
<ClCompile Include="meta\mn_str.c" />
<ClCompile Include="meta\mp4.c" />
<ClCompile Include="meta\ngca.c" />
<ClCompile Include="meta\nsw_opus.c" />
<ClCompile Include="meta\nub_vag.c" />
<ClCompile Include="meta\pc_adp.c" />
<ClCompile Include="meta\pc_snds.c" />
@ -281,6 +282,7 @@
<ClCompile Include="meta\ngc_tydsp.c" />
<ClCompile Include="meta\ngc_ymf.c" />
<ClCompile Include="meta\ngc_ulw.c" />
<ClCompile Include="meta\nub_xma.c" />
<ClCompile Include="meta\nwa.c" />
<ClCompile Include="meta\ogg_vorbis_file.c" />
<ClCompile Include="meta\ogl.c" />
@ -359,7 +361,6 @@
<ClCompile Include="meta\ps3_cps.c" />
<ClCompile Include="meta\ps3_msf.c" />
<ClCompile Include="meta\ps3_mta2.c" />
<ClCompile Include="meta\ps3_xvag.c" />
<ClCompile Include="meta\psx_cdxa.c" />
<ClCompile Include="meta\psx_fag.c" />
<ClCompile Include="meta\psx_gms.c" />
@ -416,9 +417,9 @@
<ClCompile Include="meta\xbox_xvas.c" />
<ClCompile Include="meta\xbox_xwav.c" />
<ClCompile Include="meta\x360_pasx.c" />
<ClCompile Include="meta\x360_nub.c" />
<ClCompile Include="meta\xma.c" />
<ClCompile Include="meta\xss.c" />
<ClCompile Include="meta\xvag.c" />
<ClCompile Include="meta\xwb.c" />
<ClCompile Include="meta\ydsp.c" />
<ClCompile Include="meta\zsd.c" />

View File

@ -373,6 +373,9 @@
<ClCompile Include="meta\ngc_ulw.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\nub_xma.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\nwa.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -607,9 +610,6 @@
<ClCompile Include="meta\ps3_mta2.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ps3_xvag.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\psx_cdxa.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -754,9 +754,6 @@
<ClCompile Include="meta\wwise.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\x360_nub.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\x360_pasx.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -784,6 +781,9 @@
<ClCompile Include="meta\xss.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\xvag.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\xwb.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -1012,6 +1012,9 @@
<ClCompile Include="meta\ngca.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\nsw_opus.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ps2_mtaf.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -1147,7 +1150,7 @@
<ClCompile Include="coding\ffmpeg_decoder_utils_ea_xma.c">
<Filter>coding\Source Files</Filter>
</ClCompile>
<ClCompile Include="coding\ffmpeg_decoder_utils_wwise_opus.c">
<ClCompile Include="coding\ffmpeg_decoder_utils_switch_opus.c">
<Filter>coding\Source Files</Filter>
</ClCompile>
<ClCompile Include="coding\ffmpeg_decoder_utils.c">

View File

@ -18,15 +18,15 @@ VGMSTREAM * init_vgmstream_ea_snu(STREAMFILE *streamFile) {
/* check header (the first 0x10 are BE/LE depending on platform) */
/* 0x00(1): related to sample rate? (03=48000)
* 0x01(1): flags? (when set seems to be a bank and has extra data before start_offset) //todo
* 0x01(1): flags/count? (when set has extra block data before start_offset)
* 0x02(1): always 0?
* 0x03(1): channels? (usually matches but rarely may be 0)
* 0x04(4): some size, maybe >>2 ~= number of frames
* 0x08(4): start offset
* 0x0c(4): some sub-offset? (0x20, found when 0x01 is set) */
* 0x0c(4): some sub-offset? (0x20, found when @0x01 is set) */
/* use start offset as endianness flag */
if ((uint32_t)read_32bitLE(0x08,streamFile) > 0x00F00000) {
/* use start_offset as endianness flag */
if ((uint32_t)read_32bitLE(0x08,streamFile) > 0x0000FFFF) {
read_32bit = read_32bitBE;
} else {
read_32bit = read_32bitLE;
@ -48,6 +48,7 @@ VGMSTREAM * init_vgmstream_ea_snu(STREAMFILE *streamFile) {
#if 0
//todo not working ok with blocks in XAS
//todo check if EA-XMA loops (Dante's Inferno doesn't)
if (flags & 0x60) { /* full loop, seen in ambient tracks */
loop_flag = 1;
loop_start = 0;
@ -81,7 +82,7 @@ VGMSTREAM * init_vgmstream_ea_snu(STREAMFILE *streamFile) {
vgmstream->meta_type = meta_EA_SNU;
switch(codec) {
case 0x04: /* "Xas1": EA-XAS (Dead Space) */
case 0x04: /* "Xas1": EA-XAS (Dead Space PC/PS3) */
vgmstream->coding_type = coding_EA_XAS;
vgmstream->layout_type = layout_ea_sns_blocked;
break;
@ -112,8 +113,8 @@ VGMSTREAM * init_vgmstream_ea_snu(STREAMFILE *streamFile) {
ffmpeg_custom_config cfg;
stream_size = get_streamfile_size(streamFile) - start_offset;
virtual_size = ffmpeg_get_eaxma_virtual_size(start_offset,stream_size, streamFile);
block_size = 0x8000; /* ? */
virtual_size = ffmpeg_get_eaxma_virtual_size(vgmstream->channels, start_offset,stream_size, streamFile);
block_size = 0x10000; /* todo unused and not correctly done by the parser */
block_count = stream_size / block_size + (stream_size % block_size ? 1 : 0);
bytes = ffmpeg_make_riff_xma2(buf, 0x100, vgmstream->num_samples, virtual_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
@ -122,6 +123,7 @@ VGMSTREAM * init_vgmstream_ea_snu(STREAMFILE *streamFile) {
memset(&cfg, 0, sizeof(ffmpeg_custom_config));
cfg.type = FFMPEG_EA_XMA;
cfg.virtual_size = virtual_size;
cfg.channels = vgmstream->channels;
vgmstream->codec_data = init_ffmpeg_config(streamFile, buf,bytes, start_offset,stream_size, &cfg);
if (!vgmstream->codec_data) goto fail;

View File

@ -332,7 +332,7 @@ VGMSTREAM * init_vgmstream_fsb_offset(STREAMFILE *streamFile, off_t offset) {
uint8_t buf[FAKE_RIFF_BUFFER_SIZE];
size_t bytes, block_size, block_count;
/* not accurate but not needed by FFmpeg */
block_size = 2048;
block_size = 0x8000; /* FSB default */
block_count = fsbh.datasize / block_size; /* read_32bitLE(custom_data_offset +0x14) -1? */
/* make a fake riff so FFmpeg can parse the XMA2 */

View File

@ -251,13 +251,13 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
#ifdef VGM_USE_FFMPEG
case 0x0A: {/* FMOD_SOUND_FORMAT_XMA */
uint8_t buf[100];
uint8_t buf[0x100];
int bytes, block_size, block_count;
block_size = 0x10000; /* XACT default */
block_size = 0x8000; /* FSB default */
block_count = StreamSize / block_size + (StreamSize % block_size ? 1 : 0);
bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, StreamSize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
bytes = ffmpeg_make_riff_xma2(buf, 0x100, vgmstream->num_samples, StreamSize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
if (bytes <= 0) goto fail;
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, StartOffset,StreamSize);

View File

@ -95,7 +95,7 @@ fail:
* clipped samples, as it's common for invalid keys (though possible with valid keys in poorly mastered files). */
static void find_hca_key(hca_codec_data * hca_data, clHCA * hca, uint8_t * buffer, int header_size, unsigned int * out_key1, unsigned int * out_key2) {
sample *testbuf = NULL, *temp;
int i, j;
int i, j, bufsize = 0, tempsize;
size_t keys_length = sizeof(hcakey_list) / sizeof(hcakey_info);
int min_clip_count = -1;
@ -123,13 +123,15 @@ static void find_hca_key(hca_codec_data * hca_data, clHCA * hca, uint8_t * buffe
clHCA_clear(hca, key1, key2);
if (clHCA_Decode(hca, buffer, header_size, 0) < 0) continue;
if (clHCA_getInfo(hca, &hca_data->info) < 0) continue;
if (hca_data->info.channelCount > 32) continue; /* nonsense don't alloc too much */
temp = (sample *)realloc(testbuf, sizeof(sample) * clHCA_samplesPerBlock * hca_data->info.channelCount);
if (!temp) {
if (testbuf) free(testbuf);
return;
tempsize = sizeof(sample) * clHCA_samplesPerBlock * hca_data->info.channelCount;
if (tempsize > bufsize) { /* should happen once */
temp = (sample *)realloc(testbuf, tempsize);
if (!temp) goto end;
testbuf = temp;
bufsize = tempsize;
}
testbuf = temp;
/* test enough frames, but not too many */
while (f < HCA_KEY_MAX_TEST_FRAMES && f < hca_data->info.blockCount) {
@ -173,7 +175,9 @@ static void find_hca_key(hca_codec_data * hca_data, clHCA * hca, uint8_t * buffe
hca_data->sample_ptr = clHCA_samplesPerBlock;
read_streamfile(buffer, hca_data->start, header_size, hca_data->streamfile);
end:
VGM_LOG("HCA: best key=%08x%08x (clips=%i)\n", best_key2,best_key1, min_clip_count);
*out_key2 = best_key2;
*out_key1 = best_key1;
free(testbuf);//free(temp);
}

View File

@ -5,7 +5,11 @@ typedef struct {
uint64_t key;
} hcakey_info;
/* CRI's tools expect an unsigned 64 bit number, but keys are commonly found online in hex form */
/**
* List of known keys, extracted from the game files (mostly found in 2ch.net).
* CRI's tools expect an unsigned 64 bit number string, but keys are commonly found online in hex form.
* Keys only use 56 bits though, so the upper 8 bits can be ignored.
*/
static const hcakey_info hcakey_list[] = {
// HCA Decoder default
@ -14,8 +18,6 @@ static const hcakey_info hcakey_list[] = {
// Phantasy Star Online 2 (multi?)
// used by most console games
{0xCC55463930DBE1AB}, // CC55463930DBE1AB / 14723751768204501419
// variation from VGAudio, but some 2ch poster says the above works with CRI's tools; seems to decode the same
{24002584467202475}, // 0055463930DBE1AB
// Old Phantasy Star Online 2 (multi?)
{61891147883431481}, // 30DBE1ABCC554639

View File

@ -536,7 +536,7 @@ VGMSTREAM * init_vgmstream_dsp_dspw(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_ps2_jstm(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_xvag(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_ps3_cps(STREAMFILE* streamFile);
@ -645,7 +645,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_x360_nub(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_nub_xma(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_x360_pasx(STREAMFILE *streamFile);
@ -682,4 +682,6 @@ VGMSTREAM * init_vgmstream_ea_snu(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_awc(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_nsw_opus(STREAMFILE * streamFile);
#endif /*_META_H*/

64
src/meta/nsw_opus.c Normal file
View File

@ -0,0 +1,64 @@
#include "meta.h"
#include "../util.h"
#include "../coding/coding.h"
/* .OPUS - from Lego City Undercover (Switch) */
VGMSTREAM * init_vgmstream_nsw_opus(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag = 0, channel_count;
/* check extension, case insensitive */
if ( !check_extensions(streamFile,"opus")) /* no relation to Ogg Opus */
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x01000080)
goto fail;
start_offset = 0x28;
channel_count = read_8bit(0x09,streamFile); /* assumed */
/* other values in the header: no idea */
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = read_32bitLE(0x0c,streamFile);
vgmstream->meta_type = meta_NSW_OPUS;
#ifdef VGM_USE_FFMPEG
{
uint8_t buf[0x100];
size_t bytes, skip, data_size;
ffmpeg_custom_config cfg;
data_size = get_streamfile_size(streamFile) - start_offset;
skip = 0; //todo
bytes = ffmpeg_make_opus_header(buf,0x100, vgmstream->channels, skip, vgmstream->sample_rate);
if (bytes <= 0) goto fail;
memset(&cfg, 0, sizeof(ffmpeg_custom_config));
cfg.type = FFMPEG_SWITCH_OPUS;
vgmstream->codec_data = init_ffmpeg_config(streamFile, buf,bytes, start_offset,data_size, &cfg);
if (!vgmstream->codec_data) goto fail;
vgmstream->coding_type = coding_FFmpeg;
vgmstream->layout_type = layout_none;
vgmstream->num_samples = switch_opus_get_samples(start_offset, data_size, vgmstream->sample_rate, streamFile);
}
#else
goto fail;
#endif
/* open the file for reading */
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -2,7 +2,7 @@
#include "../coding/coding.h"
/* Namco NUB xma - from Tekken 6, Galaga Legions DX */
VGMSTREAM * init_vgmstream_x360_nub(STREAMFILE *streamFile) {
VGMSTREAM * init_vgmstream_nub_xma(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset, chunk_offset;
size_t data_size, chunk_size;

View File

@ -8,7 +8,7 @@ VGMSTREAM * init_vgmstream_ps2_rxws(STREAMFILE *streamFile) {
STREAMFILE * streamHeader = NULL;
off_t start_offset, chunk_offset, name_offset = 0;
size_t data_size, chunk_size;
int loop_flag = 0, channel_count, is_separate = false, type, sample_rate;
int loop_flag = 0, channel_count, is_separate = 0, type, sample_rate;
int32_t loop_start, loop_end;
int total_streams, target_stream = streamFile->stream_index;

View File

@ -11,7 +11,7 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) {
off_t start_offset, data_offset, chunk_offset, name_offset = 0;
size_t data_size;
int is_sgx, is_sgb = false;
int is_sgx, is_sgb = 0;
int loop_flag, channels, type;
int sample_rate, num_samples, loop_start_sample, loop_end_sample;
int total_streams, target_stream = streamFile->stream_index;

View File

@ -1,14 +1,11 @@
#include "meta.h"
#include "../coding/coding.h"
#define FAKE_RIFF_BUFFER_SIZE 100
/**
* VAWX - found in feelplus games: No More Heroes Heroes Paradise, Moon Diver
*/
/* VAWX - found in feelplus games (No More Heroes Heroes Paradise, Moon Diver) */
VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset, datasize;
off_t start_offset, data_size;
int loop_flag = 0, channel_count, type;
@ -52,17 +49,17 @@ VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) {
#ifdef VGM_USE_FFMPEG
case 1: { /* XMA2 */
ffmpeg_codec_data *ffmpeg_data = NULL;
uint8_t buf[FAKE_RIFF_BUFFER_SIZE];
uint8_t buf[0x100];
int32_t bytes, block_size, block_count;
/* todo not accurate (needed for >2ch) */
datasize = get_streamfile_size(streamFile)-start_offset;
block_size = 2048;
block_count = datasize / block_size; /* read_32bitLE(custom_data_offset +0x14) -1? */
bytes = ffmpeg_make_riff_xma2(buf, FAKE_RIFF_BUFFER_SIZE, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
data_size = get_streamfile_size(streamFile)-start_offset;
block_size = 0x10000; /* VAWX default */
block_count = (uint16_t)read_16bitBE(0x3A, streamFile); /* also at 0x56 */
bytes = ffmpeg_make_riff_xma2(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
if (bytes <= 0) goto fail;
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);
if ( !ffmpeg_data ) goto fail;
vgmstream->codec_data = ffmpeg_data;
vgmstream->coding_type = coding_FFmpeg;
@ -75,22 +72,22 @@ VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) {
}
case 7: { /* ATRAC3 */
uint8_t buf[FAKE_RIFF_BUFFER_SIZE];
uint8_t buf[0x100];
int32_t bytes, block_size, encoder_delay, joint_stereo, max_samples;
datasize = read_32bitBE(0x54,streamFile);
data_size = read_32bitBE(0x54,streamFile);
block_size = 0x98 * vgmstream->channels;
joint_stereo = 0;
max_samples = atrac3_bytes_to_samples(datasize, block_size);
max_samples = atrac3_bytes_to_samples(data_size, block_size);
encoder_delay = 0x0; //max_samples - vgmstream->num_samples; /* todo not correct */
vgmstream->num_samples = max_samples; /* use calc samples since loop points are too, breaks looping in some files otherwise */
/* make a fake riff so FFmpeg can parse the ATRAC3 */
bytes = ffmpeg_make_riff_atrac3(buf, FAKE_RIFF_BUFFER_SIZE, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay);
bytes = ffmpeg_make_riff_atrac3(buf,0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay);
if (bytes <= 0)
goto fail;
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);
if (!vgmstream->codec_data) goto fail;
vgmstream->coding_type = coding_FFmpeg;
vgmstream->layout_type = layout_none;

View File

@ -265,6 +265,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
cfg.blocksize_1_exp = read_8bit(vorb_offset + block_offsets + 0x00, streamFile); /* small */
cfg.blocksize_0_exp = read_8bit(vorb_offset + block_offsets + 0x01, streamFile); /* big */
}
ww.data_size -= audio_offset;
/* detect setup type:
* - full inline: ~2009, ex. The King of Fighters XII X360, The Saboteur PC
@ -284,8 +285,6 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
}
}
//ww.data_size -= audio_offset; //todo test
vgmstream->codec_data = init_vorbis_custom_codec_data(streamFile, start_offset + setup_offset, VORBIS_WWISE, &cfg);
if (!vgmstream->codec_data) goto fail;
}
@ -319,6 +318,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
audio_offset = read_32bit(extra_offset + data_offsets + 0x04, streamFile); /* within data */
cfg.blocksize_1_exp = read_8bit(extra_offset + block_offsets + 0x00, streamFile); /* small */
cfg.blocksize_0_exp = read_8bit(extra_offset + block_offsets + 0x01, streamFile); /* big */
ww.data_size -= audio_offset;
/* Normal packets are used rarely (ex. Oddworld New 'n' Tasty! PSV). They are hard to detect (decoding
* will mostly work with garbage results) but we'll try. Setup size and "fmt" bitrate fields may matter too. */
@ -329,8 +329,6 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
cfg.packet_type = STANDARD;
}
//ww.data_size -= audio_offset; //todo test
/* try with the selected codebooks */
vgmstream->codec_data = init_vorbis_custom_codec_data(streamFile, start_offset + setup_offset, VORBIS_WWISE, &cfg);
if (!vgmstream->codec_data) {
@ -349,7 +347,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
/* Vorbis is VBR so this is very approximate, meh */
if (ww.truncated)
vgmstream->num_samples = vgmstream->num_samples * (ww.file_size - start_offset) / ww.data_size;
VGM_LOG("so=%lx, ds=%x\n", start_offset, ww.data_size);
break;
}
#endif
@ -482,7 +480,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
size_t seek_size;
vgmstream->num_samples += read_32bit(ww.fmt_offset + 0x18, streamFile);
//todo 0x1c and 0x20: related to samples/looping?
/* 0x1c: null? 0x20: data_size without seek_size */
seek_size = read_32bit(ww.fmt_offset + 0x24, streamFile);
start_offset += seek_size;
@ -498,7 +496,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) {
if (bytes <= 0) goto fail;
memset(&cfg, 0, sizeof(ffmpeg_custom_config));
cfg.type = FFMPEG_WWISE_OPUS;
cfg.type = FFMPEG_SWITCH_OPUS;
//cfg.big_endian = ww.big_endian; /* internally BE */
vgmstream->codec_data = init_ffmpeg_config(streamFile, buf,bytes, start_offset,ww.data_size, &cfg);

View File

@ -5,7 +5,7 @@
static int ps_adpcm_find_loop_offsets(STREAMFILE *streamFile, int channel_count, off_t start_offset, off_t * loop_start, off_t * loop_end);
/* XVAG - Sony's (second party?) format (God of War III, Ratchet & Clank Future, The Last of Us, Uncharted) */
VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
VGMSTREAM * init_vgmstream_xvag(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
int loop_flag = 0, channel_count, codec;
@ -57,7 +57,7 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE *streamFile) {
vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = num_samples;
vgmstream->meta_type = meta_PS3_XVAG;
vgmstream->meta_type = meta_XVAG;
switch (codec) {
case 0x06: /* PS ADPCM: God of War III, Uncharted 1/2, Ratchet and Clank Future */

View File

@ -455,7 +455,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
}
start_offset = xwb.data_offset;
start_offset = xwb.stream_offset;
if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset) )
goto fail;

View File

@ -292,7 +292,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
init_vgmstream_ffw,
init_vgmstream_dsp_dspw,
init_vgmstream_ps2_jstm,
init_vgmstream_ps3_xvag,
init_vgmstream_xvag,
init_vgmstream_ps3_cps,
init_vgmstream_sqex_scd,
init_vgmstream_ngc_nst_dsp,
@ -350,7 +350,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
init_vgmstream_wwise,
init_vgmstream_ubi_raki,
init_vgmstream_x360_pasx,
init_vgmstream_x360_nub,
init_vgmstream_nub_xma,
init_vgmstream_xma,
init_vgmstream_sxd,
init_vgmstream_ogl,
@ -369,6 +369,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
init_vgmstream_stm,
init_vgmstream_ea_snu,
init_vgmstream_awc,
init_vgmstream_nsw_opus,
init_vgmstream_txth, /* should go at the end (lower priority) */
#ifdef VGM_USE_FFMPEG

View File

@ -556,7 +556,7 @@ typedef enum {
meta_SQEX_SCD, /* Square-Enix SCD */
meta_NGC_NST_DSP, /* Animaniacs [NGC] */
meta_BAF, /* Bizarre Creations (Blur, James Bond) */
meta_PS3_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */
meta_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */
meta_PS3_CPS, /* Eternal Sonata (PS3) */
meta_PS3_MSF, /* MSF header */
meta_NUB_VAG, /* Namco VAG from NUB archives */
@ -626,6 +626,7 @@ typedef enum {
meta_BINK, /* RAD Game Tools BINK audio/video */
meta_EA_SNU, /* Electronic Arts SNU (Dead Space) */
meta_AWC, /* Rockstar AWC (GTA5, RDR) */
meta_NSW_OPUS, /* Lego City Undercover (Switch) */
#ifdef VGM_USE_VORBIS
meta_OGG_VORBIS, /* Ogg Vorbis */
@ -1028,8 +1029,8 @@ typedef struct {
/* Custom FFMPEG modes */
typedef enum {
FFMPEG_STANDARD, /* default FFmpeg */
FFMPEG_WWISE_OPUS, /* Opus without Ogg layer */
FFMPEG_EA_XMA, /* XMA with padding removed in SNS blocks */
FFMPEG_SWITCH_OPUS, /* Opus without Ogg layer */
FFMPEG_EA_XMA, /* XMA with padding removed and custom streams in SNS blocks */
//FFMPEG_EA_SCHL, /* Normal header+data (ex. ATRAC3) in SCxx blocks */
//FFMPEG_SFH, /* ATRAC3plus header+data in SFH blocks */
//FFMPEG_AWC_XMA, /* XMA data in AWC blocks, 1 streams per channel */
@ -1039,6 +1040,7 @@ typedef enum {
typedef struct {
int stream_index; /* FFmpeg's sub-stream (as opposed to an internal stream in custom read/seeks) */
int codec_endian;
int channels;
ffmpeg_custom_t type; /* ffmpeg subtype */
size_t virtual_size; /* external value, if meta needs to know/supply it */

View File

@ -5,7 +5,7 @@
/* Normally Winamp opens unicode files by their DOS 8.3 name. #define this to use wchar_t filenames,
* which must be opened with _wfopen in a WINAMP_STREAMFILE (needed for dual files like .pos).
* Only for Winamp paths, other parts would need #define UNICODE for Windows. */
#define UNICODE_INPUT_PLUGIN
//#define UNICODE_INPUT_PLUGIN
#ifdef _MSC_VER
@ -106,7 +106,7 @@ in_char lastfn[PATH_LIMIT] = {0}; /* name of the currently playing file */
#define wa_strlen wcslen
#define wa_strchr wcschr
#define wa_sscanf swscanf
#define wa_snprintf snwprintf
#define wa_snprintf _snwprintf
#define wa_fileinfo fileinfoW
#define wa_IPC_PE_INSERTFILENAME IPC_PE_INSERTFILENAMEW
#define wa_L(x) L ##x