Merge pull request #300 from bnnm/ue4opus-bnsf-csmp

ue4opus bnsf csmp
This commit is contained in:
Christopher Snowhill 2018-09-25 15:15:23 -07:00 committed by GitHub
commit 5b99d40cf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 498 additions and 263 deletions

View File

@ -229,7 +229,6 @@ are used in few games.
- CRI HCA
- Xiph Vorbis (Ogg, FSB5, Wwise, OGL, Silicon Knights)
- MPEG MP1/2/3 (standard, AHX, XVAG, FSB, AWC, P3D, etc)
- ITU-T G.722.1 (Polycom Siren 7)
- ITU-T G.722.1 annex C (Polycom Siren 14)
- ITU G.719 annex B (Polycom Siren 22)
- Electronic Arts EALayer3

View File

@ -172,7 +172,7 @@ Must use autotools (sh configure, make, make install), though some scripts simpl
### libg7221_decode
Adds support for ITU-T G.722.1 and G.722.1 annex C (standardization of Polycom Siren 7/14).
Adds support for ITU-T G.722.1 annex C (standardization of Polycom Siren 14).
- Source: https://github.com/kode54/libg7221_decode
- DLL: `libg7221_decode.dll`
@ -203,14 +203,14 @@ Adds support for ATRAC9.
- Source: https://github.com/Thealexbarney/LibAtrac9
- DLL: `libatrac9.dll`
Use MSCV and `libatrac9.sln`.
Use MSCV and `libatrac9.sln`, or GCC and the Makefile included.
### libcelt
Adds support for FSB CELT versions 0.6.1 and 0.11.0.
- DLL: `libcelt-0061.dll`, `libcelt-0110.dll`
- Source (0.6.1): http://downloads.us.xiph.org/releases/celt/celt-0.6.1.tar.gz
- Source (0.11.0): http://downloads.xiph.org/releases/celt/celt-0.11.0.tar.gz
- DLL: `libcelt-0061.dll`, `libcelt-0110.dll`
FSB uses two incompatible, older libcelt versions. Both libraries export the same symbols so normally can't coexist together. To get them working we need to make sure symbols are renamed first. This may be solved in various ways:
- using dynamic loading (LoadLibrary) but for portability it isn't an option
@ -219,7 +219,7 @@ FSB uses two incompatible, older libcelt versions. Both libraries export the sam
- Use GCC's preprocessor to rename functions on compile
- Rename functions in the source code directly.
To compile we use autotools with GCC preprocessor renaming:
To compile we'll use autotools with GCC preprocessor renaming:
- in the celt-0.6.1 dir:
```
# creates Makefiles with Automake

View File

@ -84,7 +84,10 @@ codec = (codec string)
codec_mode = (number)
# Interleave or block size [REQUIRED/OPTIONAL, depends on codec]
# Interleave 0 means "stereo mode" for some codecs (IMA, AICA, etc)
# For mono/interleaved codecs it's the amount of data between channels.
# For codecs with variable-sized frames (MSADPCM, MS-IMA, ATRAC3/plus)
# it's the block size (size of a single frame).
# Interleave 0 means "stereo mode" for some codecs (IMA, AICA, etc).
interleave = (number)|(offset)
# Validate that id_value matches value at id_offset [OPTIONAL]

View File

@ -109,10 +109,7 @@ void decode_atrac9(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_do,
/* read one raw block (superframe) and advance offsets */
bytes = read_streamfile(data->data_buffer,stream->offset, data->info.superframeSize,stream->streamfile);
if (bytes != data->data_buffer_size) {
VGM_LOG("ATRAC9: read %x vs expected %x bytes at %lx\n", bytes, data->info.superframeSize, stream->offset);
goto decode_fail;
}
if (bytes != data->data_buffer_size) goto decode_fail;
stream->offset += bytes;
@ -131,7 +128,7 @@ void decode_atrac9(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_do,
decode_fail:
/* on error just put some 0 samples */
VGM_LOG("ATRAC9: decode fail at %lx, missing %i samples\n", stream->offset, (samples_to_do - samples_done));
VGM_LOG("ATRAC9: decode fail at %"PRIx64", missing %i samples\n", (off64_t)stream->offset, (samples_to_do - samples_done));
memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample) * channels);
}

View File

@ -122,22 +122,17 @@ void decode_celt_fsb(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_d
/* FSB DLLs do seem to check this fixed value */
if (read_32bitBE(stream->offset+0x00,stream->streamfile) != 0x17C30DF3) {
VGM_LOG("CELT: unknown frame ID at %lx\n",stream->offset);
goto decode_fail;
}
frame_size = read_32bitLE(stream->offset+0x04,stream->streamfile);
if (frame_size > FSB_CELT_MAX_DATA_SIZE) {
VGM_LOG("CELT: frame size %x bigger than expected\n", frame_size);
goto decode_fail;
}
/* read and decode one raw block and advance offsets */
bytes = read_streamfile(data_buffer,stream->offset+0x08, frame_size,stream->streamfile);
if (bytes != frame_size) {
VGM_LOG("CELT: read %x vs expected %x bytes at %lx\n", bytes,frame_size,stream->offset);
goto decode_fail;
}
if (bytes != frame_size) goto decode_fail;
switch(data->version) {
case CELT_0_06_1:
@ -151,10 +146,7 @@ void decode_celt_fsb(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_d
default:
goto decode_fail;
}
if (status != CELT_OK) {
VGM_LOG("CELT: decode failed with %i at %lx\n", status,stream->offset);
goto decode_fail;
}
if (status != CELT_OK) goto decode_fail;
stream->offset += 0x04+0x04+frame_size;
data->samples_filled += FSB_CELT_SAMPLES_PER_FRAME;
@ -165,7 +157,7 @@ void decode_celt_fsb(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_d
decode_fail:
/* on error just put some 0 samples */
VGM_LOG("CELT: decode fail at %lx, missing %i samples\n", stream->offset, (samples_to_do - samples_done));
VGM_LOG("CELT: decode fail at %"PRIx64", missing %i samples\n", (off64_t)stream->offset, (samples_to_do - samples_done));
memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * sizeof(sample) * channels);
}

View File

@ -267,7 +267,6 @@ void free_celt_fsb(celt_codec_data *data);
/* ffmpeg_decoder */
ffmpeg_codec_data *init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
ffmpeg_codec_data *init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size);
ffmpeg_codec_data * init_ffmpeg_switch_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate);
void decode_ffmpeg(VGMSTREAM *stream, sample * outbuf, int32_t samples_to_do, int channels);
void reset_ffmpeg(VGMSTREAM *vgmstream);
@ -276,10 +275,12 @@ void free_ffmpeg(ffmpeg_codec_data *data);
void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples);
/* ffmpeg_decoder_custom_opus.c (helper-things) */
ffmpeg_codec_data * init_ffmpeg_switch_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate);
ffmpeg_codec_data * init_ffmpeg_ue4_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate);
size_t ffmpeg_make_opus_header(uint8_t * buf, int buf_size, int channels, int skip, int sample_rate);
size_t switch_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile);
size_t ue4_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile);
#endif

View File

@ -467,19 +467,19 @@ static void ms_audio_get_samples(ms_sample_data * msd, STREAMFILE *streamFile, i
/* full packet skip, no new frames start in this packet (prev frames can end here) */
if (packet_skip_count == 0x7FF) { /* XMA1, 11b */
VGM_LOG("MS_SAMPLES: XMA1 full packet_skip %i at 0x%lx\n", packet_skip_count, (off_t)offset_b/8);
VGM_LOG("MS_SAMPLES: XMA1 full packet_skip %i at 0x%"PRIx64"\n", packet_skip_count, (off64_t)offset_b/8);
packet_skip_count = 0;
continue;
}
else if (packet_skip_count == 0xFF) { /* XMA2, 8b*/
VGM_LOG("MS_SAMPLES: XMA2 full packet_skip %i at 0x%lx\n", packet_skip_count, (off_t)offset_b/8);
VGM_LOG("MS_SAMPLES: XMA2 full packet_skip %i at 0x%"PRIx64"\n", packet_skip_count, (off64_t)offset_b/8);
packet_skip_count = 0;
continue;
}
offset += packet_size * (packet_skip_count); /* skip packets not owned by the first stream, since we only need samples from it */
/* unusual but not impossible, as the encoder can interleave packets in any way */
VGM_ASSERT(packet_skip_count > 10, "MS_SAMPLES: found big packet skip %i at 0x%lx\n", packet_skip_count, (off_t)offset_b/8);
VGM_ASSERT(packet_skip_count > 10, "MS_SAMPLES: found big packet skip %i at 0x%"PRIx64"\n", packet_skip_count, (off64_t)offset_b/8);
packet_offset_b = header_size_b + first_frame_b;
@ -535,7 +535,7 @@ static void ms_audio_get_samples(ms_sample_data * msd, STREAMFILE *streamFile, i
frame_offset_b += 1;
if (flag) {
int new_skip = read_bitsBE_b(frame_offset_b, 10, streamFile);
VGM_LOG("MS_SAMPLES: start_skip %i at 0x%lx (bit 0x%lx)\n", new_skip, (off_t)frame_offset_b/8, (off_t)frame_offset_b);
VGM_LOG("MS_SAMPLES: start_skip %i at 0x%"PRIx64" (bit 0x%"PRIx64")\n", new_skip, (off64_t)frame_offset_b/8, (off64_t)frame_offset_b);
VGM_ASSERT(start_skip, "MS_SAMPLES: more than one start_skip (%i)\n", new_skip); //ignore, happens due to incorrect tilehdr_size
frame_offset_b += 10;
@ -551,7 +551,7 @@ static void ms_audio_get_samples(ms_sample_data * msd, STREAMFILE *streamFile, i
frame_offset_b += 1;
if (flag) {
int new_skip = read_bitsBE_b(frame_offset_b, 10, streamFile);
VGM_LOG("MS_SAMPLES: end_skip %i at 0x%lx (bit 0x%lx)\n", new_skip, (off_t)frame_offset_b/8, (off_t)frame_offset_b);
VGM_LOG("MS_SAMPLES: end_skip %i at 0x%"PRIx64" (bit 0x%"PRIx64")\n", new_skip, (off64_t)frame_offset_b/8, (off64_t)frame_offset_b);
VGM_ASSERT(end_skip, "MS_SAMPLES: more than one end_skip (%i)\n", new_skip);//ignore, happens due to incorrect tilehdr_size
frame_offset_b += 10;

View File

@ -3,9 +3,9 @@
#include <string.h>
/**
* Transmogrifies Switch Opus (no Ogg layer and custom packet headers) into is Xiph Opus, creating valid
* Ogg pages with single Opus packets. Packet headers seem to come from opus_test and aren't Nintendo-specific.
* Uses an intermediate buffer to make a full Ogg page, since checksums are calculated with the whole page.
* Transmogrifies custom Opus (no Ogg layer and custom packet headers) into is Xiph Opus, creating
* valid Ogg pages with single Opus packets.
* Uses an intermediate buffer to make full Ogg pages, since checksums are calculated with the whole page.
*
* Info, CRC and stuff:
* https://www.opus-codec.org/docs/
@ -15,10 +15,12 @@
static size_t make_oggs_first(uint8_t * buf, int buf_size, int channels, int skip, int sample_rate);
static size_t make_oggs_page(uint8_t * buf, int buf_size, size_t data_size, int page_sequence, int granule);
static uint32_t get_opus_samples_per_frame(const uint8_t * data, int Fs);
static size_t opus_get_packet_samples(const uint8_t * buf, int len);
typedef enum { OPUS_SWITCH, OPUS_UE4 } opus_type_t;
typedef struct {
/* config */
opus_type_t type;
off_t stream_offset;
size_t stream_size;
@ -28,7 +30,7 @@ typedef struct {
size_t block_size; /* current block size */
size_t page_size; /* current OggS page size */
uint8_t page_buffer[0x1000]; /* OggS page */
uint8_t page_buffer[0x2000]; /* OggS page (observed max is ~0xc00) */
size_t sequence; /* OggS sequence */
size_t samples_done; /* OggS granule */
@ -39,7 +41,7 @@ typedef struct {
} opus_io_data;
/* Convers Switch Opus packets to Ogg Opus, so the resulting data is larger than physical data. */
/* Convers custom Opus packets to Ogg Opus, so the resulting data is larger than physical data. */
static size_t opus_io_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, opus_io_data* data) {
size_t total_read = 0;
@ -89,22 +91,33 @@ static size_t opus_io_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset,
if (data->page_size == 0) {
size_t data_size, skip_size, oggs_size;
data_size = read_32bitBE(data->physical_offset, streamfile);
skip_size = 0x08; /* size + Opus state(?) */
switch(data->type) {
case OPUS_SWITCH: /* format seem to come from opus_test and not Nintendo-specific */
data_size = read_32bitBE(data->physical_offset, streamfile);
skip_size = 0x08; /* size + Opus state(?) */
break;
case OPUS_UE4:
data_size = (uint16_t)read_16bitLE(data->physical_offset, streamfile);
skip_size = 0x02;
break;
default:
return 0;
}
oggs_size = 0x1b + (int)(data_size / 0xFF + 1); /* OggS page: base size + lacing values */
data->block_size = data_size + skip_size;
data->page_size = oggs_size + data_size;
if (data->page_size > sizeof(data->page_buffer)) { /* happens on bad reads/EOF too */
VGM_LOG("OPUS: buffer can't hold OggS at %lx\n", data->physical_offset);
VGM_LOG("OPUS: buffer can't hold OggS at %"PRIx64"\n", (off64_t)data->physical_offset);
data->page_size = 0;
break;
}
/* create fake OggS page (full page for checksums) */
read_streamfile(data->page_buffer+oggs_size, data->physical_offset + 0x08, data_size, streamfile); /* store page data */
data->samples_done += get_opus_samples_per_frame(data->page_buffer+oggs_size, 48000);
read_streamfile(data->page_buffer+oggs_size, data->physical_offset + skip_size, data_size, streamfile); /* store page data */
data->samples_done += opus_get_packet_samples(data->page_buffer+oggs_size, data_size);
make_oggs_page(data->page_buffer,sizeof(data->page_buffer), data_size, data->sequence, data->samples_done);
data->sequence++;
}
@ -150,7 +163,7 @@ static size_t opus_io_size(STREAMFILE *streamfile, opus_io_data* data) {
return data->logical_size;
if (data->stream_offset + data->stream_size > get_streamfile_size(streamfile)) {
VGM_LOG("OPUS: wrong streamsize %lx + %x vs %x\n", data->stream_offset, data->stream_size, get_streamfile_size(streamfile));
VGM_LOG("OPUS: wrong streamsize %"PRIx64" + %x vs %x\n", (off64_t)data->stream_offset, data->stream_size, get_streamfile_size(streamfile));
return 0;
}
@ -162,8 +175,18 @@ static size_t opus_io_size(STREAMFILE *streamfile, opus_io_data* data) {
while (physical_offset < max_physical_offset) {
size_t data_size, skip_size, oggs_size;
data_size = read_32bitBE(physical_offset, streamfile);
skip_size = 0x08;
switch(data->type) {
case OPUS_SWITCH:
data_size = read_32bitBE(physical_offset, streamfile);
skip_size = 0x08;
break;
case OPUS_UE4:
data_size = (uint16_t)read_16bitLE(physical_offset, streamfile);
skip_size = 0x02;
break;
default:
return 0;
}
oggs_size = 0x1b + (int)(data_size / 0xFF + 1); /* OggS page: base size + lacing values */
physical_offset += data_size + skip_size;
@ -172,7 +195,7 @@ static size_t opus_io_size(STREAMFILE *streamfile, opus_io_data* data) {
/* logical size can be bigger though */
if (physical_offset > get_streamfile_size(streamfile)) {
VGM_LOG("OPUS: wrong size %lx\n", physical_offset);
VGM_LOG("OPUS: wrong size\n");
return 0;
}
@ -181,12 +204,13 @@ static size_t opus_io_size(STREAMFILE *streamfile, opus_io_data* data) {
}
/* Prepares custom IO for Switch Opus, that is converted to Ogg Opus on the fly */
static STREAMFILE* setup_opus_streamfile(STREAMFILE *streamFile, int channels, int skip, int sample_rate, off_t stream_offset, size_t stream_size) {
/* Prepares custom IO for custom Opus, that is converted to Ogg Opus on the fly */
static STREAMFILE* setup_opus_streamfile(STREAMFILE *streamFile, int channels, int skip, int sample_rate, off_t stream_offset, size_t stream_size, opus_type_t type) {
STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL;
opus_io_data io_data = {0};
size_t io_data_size = sizeof(opus_io_data);
io_data.type = type;
io_data.stream_offset = stream_offset;
io_data.stream_size = stream_size;
io_data.physical_offset = stream_offset;
@ -264,8 +288,8 @@ static uint32_t get_oggs_checksum(uint8_t * data, int bytes) {
return crc_reg;
}
/* from opus_decoder.c */
static uint32_t get_opus_samples_per_frame(const uint8_t * data, int Fs) {
/* from opus_decoder.c's opus_packet_get_samples_per_frame */
static uint32_t opus_packet_get_samples_per_frame(const uint8_t * data, int Fs) {
int audiosize;
if (data[0]&0x80)
{
@ -284,6 +308,22 @@ static uint32_t get_opus_samples_per_frame(const uint8_t * data, int Fs) {
return audiosize;
}
/* from opus_decoder.c's opus_packet_get_nb_frames */
static int opus_packet_get_nb_frames(const uint8_t * packet, int len) {
int count;
if (len<1)
return 0;
count = packet[0]&0x3;
if (count==0)
return 1;
else if (count!=3)
return 2;
else if (len<2)
return 0;
else
return packet[1]&0x3F;
}
/* ******************************** */
static size_t make_oggs_page(uint8_t * buf, int buf_size, size_t data_size, int page_sequence, int granule) {
@ -416,7 +456,11 @@ fail:
#ifdef VGM_USE_FFMPEG
size_t switch_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile) {
static size_t opus_get_packet_samples(const uint8_t * buf, int len) {
return opus_packet_get_nb_frames(buf, len) * opus_packet_get_samples_per_frame(buf, 48000);
}
static size_t custom_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile, opus_type_t type) {
size_t num_samples = 0;
off_t end_offset = offset + data_size;
@ -428,22 +472,43 @@ size_t switch_opus_get_samples(off_t offset, size_t data_size, int sample_rate,
/* count by reading all frames */
while (offset < end_offset) {
uint8_t buf[4];
size_t block_size = read_32bitBE(offset, streamFile);
size_t data_size, skip_size;
read_streamfile(buf, offset+8, 4, streamFile);
num_samples += get_opus_samples_per_frame(buf, sample_rate);
switch(type) {
case OPUS_SWITCH:
data_size = read_32bitBE(offset, streamFile);
skip_size = 0x08;
break;
case OPUS_UE4:
data_size = (uint16_t)read_16bitLE(offset, streamFile);
skip_size = 0x02;
break;
default:
return 0;
}
offset += 0x08 + block_size;
read_streamfile(buf, offset+skip_size, 0x04, streamFile); /* at least 0x02 */
num_samples += opus_get_packet_samples(buf, 0x04);
offset += skip_size + data_size;
}
return num_samples;
}
ffmpeg_codec_data * init_ffmpeg_switch_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate) {
size_t switch_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile) {
return custom_opus_get_samples(offset, data_size, sample_rate, streamFile, OPUS_SWITCH);
}
size_t ue4_opus_get_samples(off_t offset, size_t data_size, int sample_rate, STREAMFILE *streamFile) {
return custom_opus_get_samples(offset, data_size, sample_rate, streamFile, OPUS_UE4);
}
static ffmpeg_codec_data * init_ffmpeg_custom_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate, opus_type_t type) {
ffmpeg_codec_data * ffmpeg_data = NULL;
STREAMFILE *temp_streamFile = NULL;
temp_streamFile = setup_opus_streamfile(streamFile, channels, skip, sample_rate, start_offset, data_size);
temp_streamFile = setup_opus_streamfile(streamFile, channels, skip, sample_rate, start_offset, data_size, type);
if (!temp_streamFile) goto fail;
ffmpeg_data = init_ffmpeg_offset(temp_streamFile, 0x00,get_streamfile_size(temp_streamFile));
@ -460,4 +525,13 @@ fail:
close_streamfile(temp_streamFile);
return NULL;
}
ffmpeg_codec_data * init_ffmpeg_switch_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate) {
return init_ffmpeg_custom_opus(streamFile, start_offset, data_size, channels, skip, sample_rate, OPUS_SWITCH);
}
ffmpeg_codec_data * init_ffmpeg_ue4_opus(STREAMFILE *streamFile, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate) {
return init_ffmpeg_custom_opus(streamFile, start_offset, data_size, channels, skip, sample_rate, OPUS_UE4);
}
#endif

View File

@ -99,14 +99,14 @@ void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do) {
/* read frame */
bytes = read_streamfile(data->data_buffer, offset, blockSize, data->streamfile);
if (bytes != blockSize) {
VGM_LOG("HCA: read %x vs expected %x bytes at %lx\n", bytes, blockSize, offset);
VGM_LOG("HCA: read %x vs expected %x bytes at %"PRIx64"\n", bytes, blockSize, (off64_t)offset);
break;
}
/* decode frame */
status = clHCA_DecodeBlock(data->handle, (void*)(data->data_buffer), blockSize);
if (status < 0) {
VGM_LOG("HCA: decode fail at %lx\n", offset);
VGM_LOG("HCA: decode fail at %"PRIx64", code=%i\n", (off64_t)offset, status);
break;
}

View File

@ -157,7 +157,7 @@ int mpeg_custom_parse_frame_default(VGMSTREAMCHANNEL *stream, mpeg_codec_data *d
}
VGM_ASSERT(data->streams_size > 1 && current_interleave != current_data_size+current_padding,
"MPEG FSB: %i streams with non-constant interleave found @ 0x%08lx\n", data->streams_size, stream->offset);
"MPEG FSB: %i streams with non-constant interleave found @ 0x%08"PRIx64"\n", data->streams_size, (off64_t)stream->offset);
break;
case MPEG_P3D: /* fixed interleave, not frame-aligned (ie. blocks may end/start in part of a frame) */

View File

@ -59,7 +59,7 @@ static size_t get_repeated_data_size(STREAMFILE *streamFile, off_t new_offset, o
}
fail:
VGM_LOG("AWC: can't find repeat size, new=0x%08lx, last=0x%08lx\n", new_offset, last_offset);
VGM_LOG("AWC: can't find repeat size, new=0x%08"PRIx64", last=0x%08"PRIx64"\n", (off64_t)new_offset, (off64_t)last_offset);
return 0; /* keep on truckin' */
}

View File

@ -419,7 +419,7 @@ static int ealayer3_rebuild_mpeg_frame(vgm_bitstream* is_0, ealayer3_frame_info*
|| eaf_0->version != eaf_1->version
|| eaf_0->granule_index == eaf_1->granule_index
|| !eaf_0->common_size || !eaf_1->common_size)) {
VGM_LOG("MPEG EAL3: EA-frames for MPEG1 don't match at 0x%lx\n", os->info_offset);
VGM_LOG("MPEG EAL3: EA-frames for MPEG1 don't match\n");
goto fail;
}
@ -529,7 +529,7 @@ static int ealayer3_rebuild_mpeg_frame(vgm_bitstream* is_0, ealayer3_frame_info*
if (os->b_off/8 > expected_frame_size) {
/* bit reservoir! shouldn't happen with free bitrate, otherwise it's hard to fix as needs complex buffering/calcs */
VGM_LOG("MPEG EAL3: written 0x%lx but expected less than 0x%x at 0x%lx\n", os->b_off/8, expected_frame_size, os->info_offset);
VGM_LOG("MPEG EAL3: written 0x%"PRIx64" but expected less than 0x%x at 0x%"PRIx64"\n", (off64_t)(os->b_off/8), expected_frame_size, (off64_t)os->info_offset);
}
else {
/* fill ancillary data (should be ignored, but 0x00 seems to improve mpg123's free bitrate detection) */
@ -564,8 +564,8 @@ static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *d
if (!eaf->pcm_size)
return 1;
VGM_ASSERT(eaf->v1_pcm_decode_discard > 576, "MPEG EAL3: big discard %i at 0x%lx\n", eaf->v1_pcm_decode_discard, stream->offset);
VGM_ASSERT(eaf->v1_pcm_number > 0x100, "MPEG EAL3: big samples %i at 0x%lx\n", eaf->v1_pcm_number, stream->offset);
VGM_ASSERT(eaf->v1_pcm_decode_discard > 576, "MPEG EAL3: big discard %i at 0x%"PRIx64"\n", eaf->v1_pcm_decode_discard, (off64_t)stream->offset);
VGM_ASSERT(eaf->v1_pcm_number > 0x100, "MPEG EAL3: big samples %i at 0x%"PRIx64"\n", eaf->v1_pcm_number, (off64_t)stream->offset);
/* read + write PCM block samples (always BE) */
for (i = 0; i < eaf->v1_pcm_number * data->channels_per_frame; i++) {

View File

@ -56,11 +56,11 @@ mpeg_codec_data *init_mpeg(STREAMFILE *streamfile, off_t start_offset, coding_t
rc = mpg123_decode(main_m, data->buffer,data->buffer_size, NULL,0, &bytes_done);
if (rc != MPG123_OK && rc != MPG123_NEW_FORMAT && rc != MPG123_NEED_MORE) {
VGM_LOG("MPEG: unable to set up mpg123 @ 0x%08lx to 0x%08lx\n", start_offset, read_offset);
VGM_LOG("MPEG: unable to set up mpg123 at start offset\n");
goto fail; //handle MPG123_DONE?
}
if (read_offset > 0x5000) { /* don't hang in some incorrectly detected formats */
VGM_LOG("MPEG: unable to find mpeg data @ 0x%08lx to 0x%08lx\n", start_offset, read_offset);
VGM_LOG("MPEG: unable to find mpeg data at start offset\n");
goto fail;
}
@ -402,7 +402,7 @@ static void decode_mpeg_custom_stream(VGMSTREAMCHANNEL *stream, mpeg_codec_data
default: ok = mpeg_custom_parse_frame_default(stream, data, num_stream); break;
}
if (!ok) {
VGM_LOG("MPEG: cannot parse frame @ around %lx\n",stream->offset);
VGM_LOG("MPEG: cannot parse frame @ around %"PRIx64"\n",(off64_t)stream->offset);
goto decode_fail; /* mpg123 could resync but custom MPEGs wouldn't need that */
}
//;VGM_LOG("MPEG: read results: bytes_in_buffer=0x%x, new offset=%lx\n", ms->bytes_in_buffer, stream->offset);

View File

@ -79,7 +79,7 @@ static void mta2_block_update(VGMSTREAMCHANNEL * stream) {
}
if (block_size <= 0 || block_tracks < 0) { /* nonsense block (maybe at EOF) */
VGM_LOG("MTA2: bad block @ %08lx\n", stream->offset);
VGM_LOG("MTA2: bad block @ 0x%"PRIx64"\n", (off64_t)stream->offset);
stream->offset += 0x10;
repeat = 0;
}

View File

@ -109,7 +109,7 @@ static void mtaf_block_update(VGMSTREAMCHANNEL * stream) {
}
if (block_size <= 0 || block_tracks < 0) { /* nonsense block (maybe at EOF) */
VGM_LOG("MTAF: bad block @ %08lx\n", stream->offset);
VGM_LOG("MTAF: bad block @ %"PRIx64"\n", (off64_t)stream->offset);
stream->offset += 0x10;
repeat = 0;
}
@ -146,7 +146,7 @@ void decode_mtaf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
int32_t init_idx = read_16bitLE(stream->offset+4+0+c*2, stream->streamfile); /* step-L/R */
int32_t init_hist = read_16bitLE(stream->offset+4+4+c*4, stream->streamfile); /* hist-L/R: hist 16bit + empty 16bit */
VGM_ASSERT(init_idx < 0 || init_idx > 31, "MTAF: bad header idx @ 0x%lx\n", stream->offset);
VGM_ASSERT(init_idx < 0 || init_idx > 31, "MTAF: bad header idx @ 0x%"PRIx64"\n", (off64_t)stream->offset);
/* avoid index out of range in corrupt files */
if (init_idx < 0) {
init_idx = 0;

View File

@ -23,7 +23,7 @@ void decode_ngc_dtk(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
coef_index = ((uint8_t)read_8bit(frame_offset+channel,stream->streamfile) >> 4) & 0xf;
shift_factor = ((uint8_t)read_8bit(frame_offset+channel,stream->streamfile) >> 0) & 0xf;
/* rare but happens, also repeated headers don't match (ex. Ikaruga (GC) SONG02.adp) */
VGM_ASSERT_ONCE(coef_index > 4 || shift_factor > 12, "DTK: incorrect coefs/shift at %lx\n", frame_offset);
VGM_ASSERT_ONCE(coef_index > 4 || shift_factor > 12, "DTK: incorrect coefs/shift at %"PRIx64"\n", (off64_t)frame_offset);
/* decode nibbles */
for (i = first_sample; i < first_sample+samples_to_do; i++) {

View File

@ -63,7 +63,7 @@ void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
shift_factor = ((uint8_t)read_8bit(frame_offset+0x00,stream->streamfile) >> 0) & 0xf;
flag = (uint8_t)read_8bit(frame_offset+0x01,stream->streamfile); /* only lower nibble needed */
VGM_ASSERT_ONCE(coef_index > 5 || shift_factor > 12, "PS-ADPCM: incorrect coefs/shift at %lx\n", frame_offset);
VGM_ASSERT_ONCE(coef_index > 5 || shift_factor > 12, "PS-ADPCM: incorrect coefs/shift at %"PRIx64"\n", (off64_t)frame_offset);
if (coef_index > 5) /* needed by inFamous (PS3) (maybe it's supposed to use more filters?) */
coef_index = 0; /* upper filters aren't used in PS1/PS2, maybe in PSP/PS3? */
if (shift_factor > 12)
@ -71,7 +71,7 @@ void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
if (is_badflags) /* some games store garbage or extra internal logic in the flags, must be ignored */
flag = 0;
VGM_ASSERT_ONCE(flag > 7,"PS-ADPCM: unknown flag at %lx\n", frame_offset); /* meta should set PSX-badflags */
VGM_ASSERT_ONCE(flag > 7,"PS-ADPCM: unknown flag at %"PRIx64"\n", (off64_t)frame_offset); /* meta should use PSX-badflags */
/* decode nibbles */
for (i = first_sample; i < first_sample + samples_to_do; i++) {
@ -123,7 +123,7 @@ void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample * outbuf, int cha
coef_index = ((uint8_t)read_8bit(frame_offset+0x00,stream->streamfile) >> 4) & 0xf;
shift_factor = ((uint8_t)read_8bit(frame_offset+0x00,stream->streamfile) >> 0) & 0xf;
VGM_ASSERT_ONCE(coef_index > 5 || shift_factor > 12, "PS-ADPCM: incorrect coefs/shift at %lx\n", frame_offset);
VGM_ASSERT_ONCE(coef_index > 5 || shift_factor > 12, "PS-ADPCM: incorrect coefs/shift at %"PRIx64"\n", (off64_t)frame_offset);
if (coef_index > 5) /* needed by Afrika (PS3) (maybe it's supposed to use more filters?) */
coef_index = 0; /* upper filters aren't used in PS1/PS2, maybe in PSP/PS3? */
if (shift_factor > 12)
@ -180,7 +180,7 @@ static int ps_find_loop_offsets_internal(STREAMFILE *streamFile, off_t start_off
uint8_t flag = (uint8_t)read_8bit(offset+0x01,streamFile) & 0x0F; /* lower nibble only (for HEVAG) */
/* theoretically possible and would use last 0x06 */
VGM_ASSERT_ONCE(loop_start_found && flag == 0x06, "PS LOOPS: multiple loop start found at %lx\n", offset);
VGM_ASSERT_ONCE(loop_start_found && flag == 0x06, "PS LOOPS: multiple loop start found at %"PRIx64"\n", (off64_t)offset);
if (flag == 0x06 && !loop_start_found) {
loop_start = num_samples; /* loop start before this frame */

View File

@ -69,6 +69,7 @@ vorbis_custom_codec_data * init_vorbis_custom(STREAMFILE *streamFile, off_t star
return data;
fail:
VGM_LOG("VORBIS: init fail at around 0x%"PRIx64"\n", (off64_t)start_offset);
free_vorbis_custom(data);
return NULL;
}
@ -136,7 +137,6 @@ void decode_vorbis_custom(VGMSTREAM * vgmstream, sample * outbuf, int32_t sample
default: goto decode_fail;
}
if(!ok) {
VGM_LOG("Vorbis: cannot parse packet @ around %lx\n",stream->offset);
goto decode_fail;
}
@ -144,20 +144,15 @@ void decode_vorbis_custom(VGMSTREAM * vgmstream, sample * outbuf, int32_t sample
/* parse the fake ogg packet into a logical vorbis block */
rc = vorbis_synthesis(&data->vb,&data->op);
if (rc == OV_ENOTAUDIO) {
VGM_LOG("Vorbis: not an audio packet (size=0x%x) @ %lx\n",(size_t)data->op.bytes,stream->offset);
VGM_LOG("Vorbis: not an audio packet (size=0x%x) @ %"PRIx64"\n",(size_t)data->op.bytes,(off64_t)stream->offset);
//VGM_LOGB(data->op.packet, (size_t)data->op.bytes,0);
continue; /* seems ok? */
} else if (rc != 0) {
VGM_LOG("Vorbis: cannot parse Vorbis block @ %lx\n",stream->offset);
goto decode_fail;
}
continue; /* rarely happens, seems ok? */
} else if (rc != 0) goto decode_fail;
/* finally decode the logical block into samples */
rc = vorbis_synthesis_blockin(&data->vd,&data->vb);
if (rc != 0) {
VGM_LOG("Vorbis: cannot decode Vorbis block @ %lx\n",stream->offset);
goto decode_fail; /* ? */
}
if (rc != 0) goto decode_fail; /* ? */
data->samples_full = 1;
}
@ -167,6 +162,7 @@ void decode_vorbis_custom(VGMSTREAM * vgmstream, sample * outbuf, int32_t sample
decode_fail:
/* on error just put some 0 samples */
VGM_LOG("VORBIS: decode fail at %"PRIx64", missing %i samples\n", (off64_t)stream->offset, (samples_to_do - samples_done));
memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * channels * sizeof(sample));
}

View File

@ -60,18 +60,12 @@ int vorbis_custom_parse_packet_fsb(VGMSTREAMCHANNEL *stream, vorbis_custom_codec
/* get next packet size from the FSB 16b header (doesn't count this 16b) */
data->op.bytes = (uint16_t)read_16bitLE(stream->offset, stream->streamfile);
stream->offset += 2;
if (data->op.bytes == 0 || data->op.bytes == 0xFFFF || data->op.bytes > data->buffer_size) {
VGM_LOG("FSB Vorbis: wrong packet (0x%lx) @ %lx\n", data->op.bytes, stream->offset-2);
goto fail; /* EOF or end padding */
}
if (data->op.bytes == 0 || data->op.bytes == 0xFFFF || data->op.bytes > data->buffer_size) goto fail; /* EOF or end padding */
/* read raw block */
bytes = read_streamfile(data->buffer,stream->offset, data->op.bytes,stream->streamfile);
stream->offset += data->op.bytes;
if (bytes != data->op.bytes) {
VGM_LOG("Wwise Vorbis: wrong bytes (0x%lx) @ %lx\n", data->op.bytes, stream->offset-bytes);
goto fail; /* wrong packet? */
}
if (bytes != data->op.bytes) goto fail; /* wrong packet? */
return 1;

View File

@ -55,18 +55,12 @@ int vorbis_custom_parse_packet_ogl(VGMSTREAMCHANNEL *stream, vorbis_custom_codec
/* get next packet size from the OGL 16b header (upper 14b) */
data->op.bytes = (uint16_t)read_16bitLE(stream->offset, stream->streamfile) >> 2;
stream->offset += 2;
if (data->op.bytes == 0 || data->op.bytes == 0xFFFF || data->op.bytes > data->buffer_size) {
VGM_LOG("OGL Vorbis: wrong packet (0x%lx) @ %lx\n", data->op.bytes, stream->offset-2);
goto fail; /* EOF or end padding */
}
if (data->op.bytes == 0 || data->op.bytes == 0xFFFF || data->op.bytes > data->buffer_size) goto fail; /* EOF or end padding */
/* read raw block */
bytes = read_streamfile(data->buffer,stream->offset, data->op.bytes,stream->streamfile);
stream->offset += data->op.bytes;
if (bytes != data->op.bytes) {
VGM_LOG("OGL Vorbis: wrong bytes (0x%lx) @ %lx\n", data->op.bytes, stream->offset-bytes);
goto fail; /* wrong packet? */
}
if (bytes != data->op.bytes) goto fail; /* wrong packet? */
return 1;

View File

@ -61,7 +61,6 @@ int vorbis_custom_setup_init_sk(STREAMFILE *streamFile, off_t start_offset, vorb
return 1;
fail:
VGM_LOG("SK Vorbis: failed to setup init packets @ around 0x%08lx\n", offset);
return 0;
}
@ -75,31 +74,22 @@ int vorbis_custom_parse_packet_sk(VGMSTREAMCHANNEL *stream, vorbis_custom_codec_
/* read OggS/SK page and get current packet */
res = get_page_info(stream->streamfile, stream->offset, &packet_offset, &packet_size, &page_packets, data->current_packet);
data->current_packet++;
if (!res || packet_size > data->buffer_size) {
VGM_LOG("FSB Vorbis: wrong packet (0x%x) @ %lx\n", packet_size, stream->offset);
goto fail;
}
if (!res || packet_size > data->buffer_size) goto fail;
/* read raw block */
data->op.bytes = read_streamfile(data->buffer, packet_offset, packet_size, stream->streamfile);
if (data->op.bytes != packet_size) {
VGM_LOG("SK Vorbis: read error, 0x%x packet size vs 0x%lx bytes @ %lx\n", packet_size, data->op.bytes, packet_offset);
goto fail; /* wrong packet? */
}
if (data->op.bytes != packet_size) goto fail; /* wrong packet? */
/* go next page when processed all packets in page */
if (data->current_packet >= page_packets) {
/* processed all packets in page, go to next */
if (!get_page_info(stream->streamfile, stream->offset, &packet_offset, &packet_size, &page_packets, -1)) goto fail;
stream->offset = packet_offset + packet_size;
data->current_packet = 0;
}
return 1;
fail:
VGM_LOG("SK Vorbis: failed to parse packet @ around 0x%08lx\n", stream->offset);
return 0;
}
@ -175,7 +165,7 @@ static int get_page_info(STREAMFILE *streamFile, off_t page_offset, off_t *out_p
return 1;
fail:
VGM_LOG("SK Vorbis: failed to read page @ 0x%08lx\n", page_offset);
//VGM_LOG("SK Vorbis: failed to read page @ 0x%08lx\n", page_offset);
return 0;
}
@ -188,10 +178,8 @@ static int build_header(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile, o
put_8bit (buf+0x00, read_8bit(packet_offset,streamFile)); /* packet_type */
memcpy (buf+0x01, "vorbis", 6); /* id */
bytes = read_streamfile(buf+0x07,packet_offset+0x03, packet_size-0x03,streamFile); /* copy rest (all except id+"SK") */
if (packet_size-0x03 != bytes) {
VGM_LOG("SK Vorbis: packet (size 0x%x) not copied correctly (bytes=%x) @ 0x%lx\n", packet_size, bytes, packet_offset);
if (packet_size-0x03 != bytes)
return 0;
}
return 0x07+packet_size-0x03;
}

View File

@ -68,27 +68,20 @@ int vorbis_custom_parse_packet_vid1(VGMSTREAMCHANNEL *stream, vorbis_custom_code
/* get packet info the VID1 header */
get_packet_header(stream->streamfile, &stream->offset, (uint32_t*)&data->op.bytes);
if (data->op.bytes == 0 || data->op.bytes > data->buffer_size) {
VGM_LOG("VID1 Vorbis: wrong packet (0x%lx) @ %lx\n", data->op.bytes, stream->offset);
goto fail; /* EOF or end padding */
}
if (data->op.bytes == 0 || data->op.bytes > data->buffer_size) goto fail; /* EOF or end padding */
/* read raw block */
bytes = read_streamfile(data->buffer,stream->offset, data->op.bytes,stream->streamfile);
stream->offset += data->op.bytes;
if (bytes != data->op.bytes) {
VGM_LOG("VID1 Vorbis: wrong bytes (0x%lx) @ %lx\n", data->op.bytes, stream->offset-bytes);
goto fail; /* wrong packet? */
}
//todo: sometimes there are short packets like 01be590000 and Vorbis complains and skips, no idea
if (bytes != data->op.bytes) goto fail; /* wrong packet? */
//todo: sometimes there are short packets like 01be590000 and Vorbis complains and skips, no idea
/* test block end (weird size calc but seems ok) */
if ((stream->offset - (data->block_offset + 0x34)) >= (data->block_size - 0x06)) {
stream->offset = data->block_offset + read_32bitBE(data->block_offset + 0x04,stream->streamfile);
}
return 1;
fail:

View File

@ -103,17 +103,11 @@ int vorbis_custom_parse_packet_wwise(VGMSTREAMCHANNEL *stream, vorbis_custom_cod
/* reconstruct a Wwise packet, if needed; final bytes may be bigger than packet_size so we get the header offsets here */
header_size = get_packet_header(stream->streamfile, stream->offset, data->config.header_type, (int*)&data->op.granulepos, &packet_size, data->config.big_endian);
if (!header_size || packet_size > data->buffer_size) {
VGM_LOG("Wwise Vorbis: wrong packet (0x%x) @ %lx\n", packet_size, stream->offset);
goto fail;
}
if (!header_size || packet_size > data->buffer_size) goto fail;
data->op.bytes = rebuild_packet(data->buffer, data->buffer_size, stream->streamfile,stream->offset, data, data->config.big_endian);
stream->offset += header_size + packet_size;
if (!data->op.bytes || data->op.bytes >= 0xFFFF) {
VGM_LOG("Wwise Vorbis: wrong bytes (0x%lx) @ %lx\n", data->op.bytes, stream->offset-header_size-packet_size);
goto fail;
}
if (!data->op.bytes || data->op.bytes >= 0xFFFF) goto fail;
return 1;
@ -184,7 +178,7 @@ static size_t rebuild_packet(uint8_t * obuf, size_t obufsize, STREAMFILE *stream
if (!rc) goto fail;
if (ow.b_off % 8 != 0) {
VGM_LOG("Wwise Vorbis: didn't write exactly audio packet: 0x%lx + %li bits\n", ow.b_off / 8, ow.b_off % 8);
//VGM_LOG("Wwise Vorbis: didn't write exactly audio packet: 0x%lx + %li bits\n", ow.b_off / 8, ow.b_off % 8);
goto fail;
}
@ -228,7 +222,7 @@ static size_t rebuild_setup(uint8_t * obuf, size_t obufsize, STREAMFILE *streamF
if (!rc) goto fail;
if (ow.b_off % 8 != 0) {
VGM_LOG("Wwise Vorbis: didn't write exactly setup packet: 0x%lx + %li bits\n", ow.b_off / 8, ow.b_off % 8);
//VGM_LOG("Wwise Vorbis: didn't write exactly setup packet: 0x%lx + %li bits\n", ow.b_off / 8, ow.b_off % 8);
goto fail;
}
@ -1024,7 +1018,7 @@ static int ww2ogg_codebook_library_rebuild(vgm_bitstream * ow, vgm_bitstream * i
/* check that we used exactly all bytes */
/* note: if all bits are used in the last byte there will be one extra 0 byte */
if ( 0 != cb_size && iw->b_off/8+1 != cb_size ) {
VGM_LOG("Wwise Vorbis: codebook size mistach (expected 0x%x, wrote 0x%lx)\n", cb_size, iw->b_off/8+1);
//VGM_LOG("Wwise Vorbis: codebook size mistach (expected 0x%x, wrote 0x%lx)\n", cb_size, iw->b_off/8+1);
goto fail;
}

View File

@ -2,7 +2,7 @@
#include "../util.h"
// todo this is based on Kazzuya's old code; different emus (PCSX, Mame, Mednafen, etc) do
// XA coefs int math in different ways (see comments below), not be 100% accurate.
// XA coefs int math in different ways (see comments below), not 100% accurate.
// May be implemented like the SNES/SPC700 BRR.
/* XA ADPCM gain values */
@ -76,7 +76,7 @@ void decode_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, i
if (read_32bitBE(frame_offset+0x00,stream->streamfile) != read_32bitBE(frame_offset+0x04,stream->streamfile) ||
read_32bitBE(frame_offset+0x08,stream->streamfile) != read_32bitBE(frame_offset+0x0c,stream->streamfile)) {
VGM_LOG("bad frames at %lx\n", frame_offset);
VGM_LOG("bad frames at %"PRIx64"\n", (off64_t)frame_offset);
}
@ -90,7 +90,7 @@ void decode_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, i
coef_index = ((uint8_t)read_8bit(sp_offset,stream->streamfile) >> 4) & 0xf;
shift_factor = ((uint8_t)read_8bit(sp_offset,stream->streamfile) >> 0) & 0xf;
VGM_ASSERT(coef_index > 4 || shift_factor > 12, "XA: incorrect coefs/shift at %lx\n", sp_offset);
VGM_ASSERT(coef_index > 4 || shift_factor > 12, "XA: incorrect coefs/shift at %"PRIx64"\n", (off64_t)sp_offset);
if (coef_index > 4)
coef_index = 0; /* only 4 filters are used, rest is apparently 0 */
if (shift_factor > 12)

View File

@ -103,6 +103,7 @@ static const char* extension_list[] = {
"cks",
"cnk",
"cps",
"csmp",
"cvs",
"cxs",
@ -380,6 +381,7 @@ static const char* extension_list[] = {
"txtp",
"tydsp",
"ue4opus",
"ulw",
"um3",
"utk",
@ -602,7 +604,6 @@ static const coding_info coding_info_list[] = {
{coding_MPEG_layer3, "MPEG Layer III Audio (MP3)"},
#endif
#ifdef VGM_USE_G7221
{coding_G7221, "ITU G.722.1 (Polycom Siren 7)"},
{coding_G7221C, "ITU G.722.1 annex C (Polycom Siren 14)"},
#endif
#ifdef VGM_USE_G719
@ -1092,6 +1093,8 @@ static const meta_info meta_info_list[] = {
{meta_DERF, "Xilam DERF header"},
{meta_UTK, "Maxis UTK header"},
{meta_NXA, "Entergram NXA header"},
{meta_ADPCM_CAPCOM, "Capcom .ADPCM header"},
{meta_UE4OPUS, "Epic Games UE4OPUS header"},
};

View File

@ -40,7 +40,7 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
if (samples_this_block < 0) {
/* probably block bug or EOF, next calcs would give wrong values/segfaults/infinite loop */
VGM_LOG("layout_blocked: wrong block samples at 0x%lx\n", vgmstream->current_block_offset);
VGM_LOG("layout_blocked: wrong block samples at 0x%"PRIx64"\n", (off64_t)vgmstream->current_block_offset);
memset(buffer + samples_written*vgmstream->channels, 0, (sample_count - samples_written) * vgmstream->channels * sizeof(sample));
break;
}

View File

@ -54,8 +54,6 @@ void block_update_ea_1snh(off_t block_offset, VGMSTREAM * vgmstream) {
block_offset += block_size;
}
VGM_LOG("of=%lx, next=%lx, data=%x\n", block_offset, block_offset + block_size, block_size);//getchar();
vgmstream->current_block_offset = block_offset;
vgmstream->next_block_offset = block_offset + block_size;
vgmstream->current_block_size = block_size - block_header;
@ -99,8 +97,8 @@ void block_update_ea_1snh(off_t block_offset, VGMSTREAM * vgmstream) {
vgmstream->ch[i].offset = adpcm_offset + 0x08*vgmstream->channels;
}
VGM_ASSERT(vgmstream->current_block_samples != (block_size - block_header - 0x04 - 0x08*vgmstream->channels) * 2 / vgmstream->channels,
"EA 1SHN blocked: different expected vs block num samples at %lx\n", block_offset);
//VGM_ASSERT(vgmstream->current_block_samples != (block_size - block_header - 0x04 - 0x08*vgmstream->channels) * 2 / vgmstream->channels,
// "EA 1SHN blocked: different expected vs block num samples at %lx\n", block_offset);
}
else {
for(i = 0; i < vgmstream->channels; i++) {

View File

@ -48,7 +48,7 @@ void block_update_h4m(off_t block_offset, VGMSTREAM * vgmstream) {
block_skip += (audio_bytes / vgmstream->num_streams) * (vgmstream->stream_index-1);
}
VGM_ASSERT(frame_format == 1, "H4M: unknown frame_format %x at %lx\n", frame_format, block_offset);
VGM_ASSERT(frame_format == 1, "H4M: unknown frame_format %x at %"PRIx64"\n", frame_format, (off64_t)block_offset);
/* pass current mode to the decoder */
vgmstream->codec_config = (frame_format << 8) | (vgmstream->codec_config & 0xFF);

View File

@ -26,7 +26,7 @@ void block_update_xa(off_t block_offset, VGMSTREAM * vgmstream) {
VGM_ASSERT(block_offset + 0x930 < get_streamfile_size(streamFile) &&
(uint8_t)read_8bit(block_offset + 0x000 + 0x11,streamFile) !=
(uint8_t)read_8bit(block_offset + 0x930 + 0x11,streamFile),
"XA block: subchannel change at %lx\n", block_offset);
"XA block: subchannel change at %"PRIx64"\n", (off64_t)block_offset);
/* submode flag bits (typical audio value = 0x64 01100100)
* - 7 (0x80 10000000): end of file
@ -53,7 +53,7 @@ void block_update_xa(off_t block_offset, VGMSTREAM * vgmstream) {
}
else {
;VGM_ASSERT_ONCE(block_offset < get_streamfile_size(streamFile),
"XA block: non audio block found at %lx\n", block_offset);
"XA block: non audio block found at %"PRIx64"\n", (off64_t)block_offset);
block_samples = 0; /* not an audio sector */
}

View File

@ -332,6 +332,10 @@
RelativePath=".\meta\acm.c"
>
</File>
<File
RelativePath=".\meta\adpcm_capcom.c"
>
</File>
<File
RelativePath=".\meta\ads.c"
>
@ -1438,6 +1442,10 @@
RelativePath=".\meta\ubi_sb.c"
>
</File>
<File
RelativePath=".\meta\ue4opus.c"
>
</File>
<File
RelativePath=".\meta\utk.c"
>
@ -1715,7 +1723,7 @@
>
</File>
<File
RelativePath=".\coding\ffmpeg_decoder_utils_switch_opus.c"
RelativePath=".\coding\ffmpeg_decoder_custom_opus.c"
>
</File>
<File

View File

@ -125,7 +125,7 @@
<ClCompile Include="coding\celt_fsb_decoder.c" />
<ClCompile Include="coding\coding_utils.c" />
<ClCompile Include="coding\ffmpeg_decoder.c" />
<ClCompile Include="coding\ffmpeg_decoder_utils_switch_opus.c" />
<ClCompile Include="coding\ffmpeg_decoder_custom_opus.c" />
<ClCompile Include="coding\lsf_decoder.c" />
<ClCompile Include="coding\mp4_aac_decoder.c" />
<ClCompile Include="coding\mtaf_decoder.c" />
@ -204,6 +204,7 @@
<ClCompile Include="meta\xau_konami.c" />
<ClCompile Include="meta\aax.c" />
<ClCompile Include="meta\acm.c" />
<ClCompile Include="meta\adpcm_capcom.c" />
<ClCompile Include="meta\ads.c" />
<ClCompile Include="meta\adx.c" />
<ClCompile Include="meta\afc.c" />
@ -437,6 +438,7 @@
<ClCompile Include="meta\ubi_lyn.c" />
<ClCompile Include="meta\ubi_raki.c" />
<ClCompile Include="meta\ubi_sb.c" />
<ClCompile Include="meta\ue4opus.c" />
<ClCompile Include="meta\utk.c" />
<ClCompile Include="meta\vs.c" />
<ClCompile Include="meta\vsf.c" />

View File

@ -211,6 +211,9 @@
<ClCompile Include="meta\acm.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\adpcm_capcom.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ads.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -886,6 +889,9 @@
<ClCompile Include="meta\ubi_sb.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\ue4opus.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\utk.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
@ -1411,7 +1417,7 @@
<ClCompile Include="coding\ffmpeg_decoder.c">
<Filter>coding\Source Files</Filter>
</ClCompile>
<ClCompile Include="coding\ffmpeg_decoder_utils_switch_opus.c">
<ClCompile Include="coding\ffmpeg_decoder_custom_opus.c">
<Filter>coding\Source Files</Filter>
</ClCompile>
<ClCompile Include="coding\coding_utils.c">

49
src/meta/adpcm_capcom.c Normal file
View File

@ -0,0 +1,49 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../util.h"
/* .ADX - from Capcom games [Resident Evil: Revelations (Switch), Monster Hunter XX (Switch)] */
VGMSTREAM * init_vgmstream_adpcm_capcom(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag, channel_count;
/* checks */
if (!check_extensions(streamFile,"adpcm"))
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x02000000)
goto fail;
channel_count = read_16bitLE(0x04, streamFile);
if (channel_count > 2) goto fail; /* header size seems fixed for mono/stereo */
/* 0x08: channel size */
/* 0x0c-14: some config/id? (may be shared between files) */
loop_flag = read_16bitLE(0x68, streamFile);
start_offset = 0xd8; /* also fixed for mono/stereo */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
vgmstream->meta_type = meta_ADPCM_CAPCOM;
vgmstream->sample_rate = read_32bitLE(0x64,streamFile); /* from first headerm repeated at +0x60 */
vgmstream->num_samples = read_32bitLE(0x60, streamFile);
vgmstream->loop_start_sample = read_32bitLE(0x6c, streamFile);
vgmstream->loop_end_sample = read_32bitLE(0x70, streamFile) + 1;
vgmstream->coding_type = coding_NGC_DSP;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = read_16bitLE(0x06, streamFile);
dsp_read_coefs_le(vgmstream,streamFile, 0x18, 0x60);
if (!vgmstream_open_stream(vgmstream,streamFile, start_offset))
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -182,6 +182,9 @@ static const adxkey_info adxkey8_list[] = {
/* Bakumatsu Renka - Karyuu Kenshiden (PS2) */
{0x4919,0x612d,0x4919, "RENRENKA22",0},
/* Tensei Hakkenshi - Fuumaroku (PS2) */
{0x5761,0x6283,0x4531, "HAKKEN",0},
};
static const adxkey_info adxkey9_list[] = {

View File

@ -333,7 +333,7 @@ static int parse_awc_header(STREAMFILE* streamFile, awc_header* awc) {
/* If music, data is divided into blocks of block_chunk size with padding.
* Each block has a header/seek table and interleaved data for all channels */
if (awc->is_music && read_32bit(awc->stream_offset, streamFile) != 0) {
VGM_LOG("AWC: music found, but block doesn't start with seek table at %lx\n", awc->stream_offset);
VGM_LOG("AWC: music found, but block doesn't start with seek table at %"PRIx64"\n", (off64_t)awc->stream_offset);
goto fail;
}

View File

@ -2,17 +2,18 @@
#include "../coding/coding.h"
#include "../util.h"
/* BNSF - Namco Bandai's Bandai Namco Sound Format/File */
/* BNSF - Namco Bandai's Bandai Namco Sound Format/File [Tales of Graces (Wii), Tales of Berseria (PS4)] */
VGMSTREAM * init_vgmstream_bnsf(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset = 0, first_offset = 0x0C;
int loop_flag = 0, channel_count = 0;
int sample_rate, num_samples, loop_start = 0, loop_end = 0, block_size;
int loop_flag = 0, channel_count = 0, sample_rate;
int num_samples, loop_start = 0, loop_end = 0, loop_adjust, block_samples;
uint32_t codec, subcodec = 0;
size_t sdat_size;
size_t bnsf_size, sdat_size, block_size;
off_t loop_chunk = 0, sfmt_chunk, sdat_chunk;
/* checks */
if (!check_extensions(streamFile,"bnsf"))
goto fail;
if (read_32bitBE(0,streamFile) != 0x424E5346) /* "BNSF" */
@ -20,8 +21,9 @@ VGMSTREAM * init_vgmstream_bnsf(STREAMFILE *streamFile) {
codec = read_32bitBE(0x08,streamFile);
/* check RIFF size (for siren22 it's full size) */
if (read_32bitBE(0x04,streamFile) + (codec == 0x49533232 ? 0 : 8) != get_streamfile_size(streamFile))
/* check file size (siren22 uses full size) */
bnsf_size = read_32bitBE(0x04,streamFile);
if (bnsf_size + (codec == 0x49533232 ? 0x00 : 0x08) != get_streamfile_size(streamFile))
goto fail;
if (!find_chunk_be(streamFile, 0x73666d74,first_offset,0, &sfmt_chunk,NULL)) /* "sfmt" */
@ -30,21 +32,25 @@ VGMSTREAM * init_vgmstream_bnsf(STREAMFILE *streamFile) {
goto fail;
if ( find_chunk_be(streamFile, 0x6C6F6F70,first_offset,0, &loop_chunk,NULL)) { /* "loop" */
loop_flag = 1;
loop_start = read_32bitBE(loop_chunk+0x00, streamFile);
loop_end = read_32bitBE(loop_chunk+0x04,streamFile);
loop_start = read_32bitBE(loop_chunk+0x00, streamFile); /* block-aligned */
loop_end = read_32bitBE(loop_chunk+0x04,streamFile) + 1;
}
subcodec = read_16bitBE(sfmt_chunk+0x00,streamFile);
subcodec = read_16bitBE(sfmt_chunk+0x00,streamFile);
channel_count = read_16bitBE(sfmt_chunk+0x02,streamFile);
sample_rate = read_32bitBE(sfmt_chunk+0x04,streamFile);
num_samples = read_32bitBE(sfmt_chunk+0x08,streamFile);
/* 0x0c: some kind of sample count (skip?), can be 0 when no loops */
block_size = read_16bitBE(sfmt_chunk+0x10,streamFile);
//block_samples = read_16bitBE(sfmt_chunk+0x12,streamFile);
/* max_samples = sdat_size/block_size*block_samples //num_samples is smaller */
sample_rate = read_32bitBE(sfmt_chunk+0x04,streamFile);
num_samples = read_32bitBE(sfmt_chunk+0x08,streamFile);
loop_adjust = read_32bitBE(sfmt_chunk+0x0c,streamFile); /* 0 if no looping */
block_size = read_16bitBE(sfmt_chunk+0x10,streamFile);
block_samples = read_16bitBE(sfmt_chunk+0x12,streamFile);
//max_samples = sdat_size / block_size * block_samples /* num_samples is smaller */
start_offset = sdat_chunk;
/* without adjust some files have a small pop when looping */
if (loop_adjust >= block_samples)
goto fail; /* shouldn't happen, plus decoder can't handle it */
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
@ -52,15 +58,15 @@ VGMSTREAM * init_vgmstream_bnsf(STREAMFILE *streamFile) {
vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = num_samples;
vgmstream->loop_start_sample = loop_start;
vgmstream->loop_start_sample = loop_start + loop_adjust;
vgmstream->loop_end_sample = loop_end;
vgmstream->meta_type = meta_BNSF;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = block_size/channel_count;
/* some IS14 voice files have 0x02 (Tales of Zestiria, The Idolm@ster 2); data looks normal and silent
* frames decode ok but rest fails, must be some subtle decoding variation (not encryption) */
/* Late IS14 voice/ambient files use subcodec 0x02 [Tales of Zestiria (PS3/PC), The Idolm@ster 2 (PS3)].
* Bitstream looks modified (most noticeable in silent frames), probably not encrypted, still 1ch frames */
if (subcodec != 0)
goto fail;

View File

@ -330,7 +330,7 @@ static VGMSTREAM * parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint1
if (ast_offset == 0xFFFFFFFF) {
/* RAM asset */
sns_offset = snr_offset + get_snr_size(streamFile, snr_offset);
;VGM_LOG("EA S10A: RAM at sns=%lx, sns=%lx\n", snr_offset, sns_offset);
//;VGM_LOG("EA S10A: RAM at sns=%lx, sns=%lx\n", snr_offset, sns_offset);
vgmstream = init_vgmstream_eaaudiocore_header(streamFile, streamFile, snr_offset, sns_offset, meta_EA_SNR_SNS);
if (!vgmstream)
goto fail;
@ -345,7 +345,7 @@ static VGMSTREAM * parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint1
goto fail;
sns_offset = ast_offset;
;VGM_LOG("EA S10A: stream at sns=%lx, sns=%lx\n", snr_offset, sns_offset);
//;VGM_LOG("EA S10A: stream at sns=%lx, sns=%lx\n", snr_offset, sns_offset);
vgmstream = init_vgmstream_eaaudiocore_header(streamFile, astFile, snr_offset, sns_offset, meta_EA_SNR_SNS);
if (!vgmstream)
goto fail;

View File

@ -238,7 +238,7 @@ static size_t eaac_io_size(STREAMFILE *streamfile, eaac_io_data* data) {
/* logical size can be bigger in EA-XMA though */
if (physical_offset > get_streamfile_size(streamfile)) {
VGM_LOG("EA EAAC: wrong size %lx\n", physical_offset);
VGM_LOG("EA EAAC: wrong size\n");
return 0;
}

View File

@ -1039,7 +1039,7 @@ static int parse_variable_header(STREAMFILE* streamFile, ea_header* ea, off_t be
break;
default:
VGM_LOG("EA SCHl: unknown patch 0x%02x at 0x%04lx\n", patch_type, (offset-1));
VGM_LOG("EA SCHl: unknown patch 0x%02x\n", patch_type);
goto fail;
}
}

View File

@ -94,7 +94,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
/* get offset inside data section */
/* up to 0x07FFFFFF * 0x20 = full 32b offset 0xFFFFFFE0 */
data_offset = ((sample_mode2 & 0x03) << 25) | ((sample_mode1 >> 7) & 0x1FFFFFF) << 5; /* bits2: 1..0 (2) | bits1: 31..8 (25) */
data_offset = (((sample_mode2 & 0x03) << 25) | ((sample_mode1 >> 7) & 0x1FFFFFF)) << 5; /* bits2: 1..0 (2) | bits1: 31..8 (25) */
/* get channels */
switch ((sample_mode1 >> 5) & 0x03) { /* bits1: 7..6 (2) */
@ -182,7 +182,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
// /* found in some XMA2/Vorbis/FADPCM */
// break;
default:
VGM_LOG("FSB5: unknown extraflag 0x%x at %lx + 0x04 (size 0x%x)\n", extraflag_type, extraflag_offset, extraflag_size);
VGM_LOG("FSB5: unknown extraflag 0x%x at %"PRIx64" + 0x04 (size 0x%x)\n", extraflag_type, (off64_t)extraflag_offset, extraflag_size);
break;
}
@ -204,7 +204,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
uint32_t next_sample_mode1, next_sample_mode2;
next_sample_mode1 = (uint32_t)read_32bitLE(fsb5.sample_header_offset+stream_header_size+0x00,streamFile);
next_sample_mode2 = (uint32_t)read_32bitLE(fsb5.sample_header_offset+stream_header_size+0x04,streamFile);
next_data_offset = ((next_sample_mode2 & 0x03) << 25) | ((next_sample_mode1 >> 7) & 0x1FFFFFF) << 5;
next_data_offset = (((next_sample_mode2 & 0x03) << 25) | ((next_sample_mode1 >> 7) & 0x1FFFFFF)) << 5;
fsb5.stream_size = next_data_offset - data_offset;
}

View File

@ -789,4 +789,8 @@ VGMSTREAM * init_vgmstream_derf(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_utk(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_adpcm_capcom(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ue4opus(STREAMFILE *streamFile);
#endif /*_META_H*/

View File

@ -101,7 +101,7 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) {
total_subsongs++;
if (total_subsongs == target_subsong) {
;VGM_LOG("NUS3BANK: subsong header offset %lx\n", header_offset);
//;VGM_LOG("NUS3BANK: subsong header offset %lx\n", header_offset);
subfile_offset = stream_offset;
subfile_size = stream_size;
name_size = stream_name_size;
@ -142,7 +142,7 @@ VGMSTREAM * init_vgmstream_nus3bank(STREAMFILE *streamFile) {
}
}
;VGM_LOG("NUS3BANK: subfile=%lx, size=%x\n", subfile_offset, subfile_size);
//;VGM_LOG("NUS3BANK: subfile=%lx, size=%x\n", subfile_offset, subfile_size);
temp_streamFile = setup_nus3bank_streamfile(streamFile, subfile_offset,subfile_size, fake_ext);
if (!temp_streamFile) goto fail;

View File

@ -1,62 +1,104 @@
#include "meta.h"
#include "../coding/coding.h"
/* RFTM - Retro Studios format [Donkey Kong Country Tropical Freeze (WiiU)] */
VGMSTREAM *init_vgmstream_rfrm(STREAMFILE *streamFile)
{
/* RFTM - Retro Studios format [Donkey Kong Country Tropical Freeze (WiiU/Switch)] */
VGMSTREAM *init_vgmstream_rfrm(STREAMFILE *streamFile) {
VGMSTREAM *vgmstream = NULL;
off_t fmta_offset = 0x20, header_offset, start_offset;
size_t stream_size, interleave;
int loop_flag, channel_count;
off_t fmta_offset = 0, data_offset = 0, header_offset, start_offset;
size_t data_size = 0, interleave;
int loop_flag, channel_count, version;
int big_endian;
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
/* checks */
if (!check_extensions(streamFile, "csmp"))
goto fail;
/* format uses weird-sized chunks, quick hack until I get enough files */
if (read_32bitBE(0x00, streamFile) != 0x5246524D) /* "RFRM" */
goto fail;
/* 0x08: file size but not exact */
if (read_32bitBE(0x14, streamFile) != 0x43534D50) /* "CSMP" */
goto fail;
version = read_32bitBE(0x18,streamFile); /* assumed, also at 0x1c */
stream_size = read_32bitBE(0x08, streamFile) - 0x38; /* stream size is counted from FMTA or LABL, the fixed size FMTA part can already be removed */
if (read_32bitBE(fmta_offset, streamFile) == 0x4C41424C) /* "LABL" */
{
size_t labl_size = 0x18 + read_32bitBE(0x28, streamFile); /* the size of the LABL part is variable */
fmta_offset += labl_size; /* the FMTA part have been moved by the LABL part */
stream_size -= labl_size; /* remove the LABL part */
if (version == 0x0a) { /* Wii U */
read_32bit = read_32bitBE;
read_16bit = read_16bitBE;
big_endian = 1;
}
else if (version == 0x12) { /* Switch */
read_32bit = read_32bitLE;
read_16bit = read_16bitLE;
big_endian = 0;
}
else {
goto fail;
}
header_offset = fmta_offset + 0x38; /* where the first DSP sub-file starts */
start_offset = header_offset + 0x60; /* skip DSP header */
channel_count = read_32bitBE(fmta_offset + 0x15, streamFile);
loop_flag = read_16bitBE(header_offset + 0x0C, streamFile); /* read loop flag in the first DSP sub-file */
/* parse chunks (always BE) */
{
off_t chunk_offset = 0x20;
off_t file_size = get_streamfile_size(streamFile);
while (chunk_offset < file_size) {
uint32_t chunk_type = read_32bitBE(chunk_offset+0x00,streamFile);
size_t chunk_size = read_32bitBE(chunk_offset+0x08,streamFile); /* maybe 64b from 0x04? */
switch(chunk_type) {
case 0x464D5441: /* "FMTA" */
fmta_offset = chunk_offset + 0x18;
break;
case 0x44415441: /* "DATA" */
data_offset = chunk_offset + 0x18;
data_size = chunk_size;
break;
default: /* known: "LABL" (usually before "FMTA"), "META" (usually after "DATA") */
break;
}
chunk_offset += 0x18 + chunk_size;
}
if (!fmta_offset || !data_offset || !data_size)
goto fail;
}
/* parse FMTA / DATA (fully interleaved standard DSPs) */
channel_count = read_8bit(fmta_offset+0x00, streamFile);
/* FMTA 0x08: channel mapping */
header_offset = data_offset;
if (version == 0x0a) {
size_t align = 0x03; /* possibly 32b align */
header_offset += align;
data_size -= align;
}
start_offset = header_offset + 0x60;
loop_flag = read_16bit(header_offset + 0x0C, streamFile);
interleave = data_size / channel_count;
interleave = stream_size / channel_count; /* each DSP sub-file is a channel */
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream)
goto fail;
if (!vgmstream) goto fail;
vgmstream->meta_type = meta_RFRM;
/* read DSP header */
vgmstream->sample_rate = read_32bitBE(header_offset + 0x08, streamFile);
vgmstream->num_samples = read_32bitBE(header_offset + 0x00, streamFile);
vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bitBE(header_offset + 0x10, streamFile));
vgmstream->loop_end_sample = dsp_nibbles_to_samples(read_32bitBE(header_offset + 0x14, streamFile)) + 1;
vgmstream->sample_rate = read_32bit(header_offset + 0x08, streamFile);
vgmstream->num_samples = read_32bit(header_offset + 0x00, streamFile);
vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bit(header_offset + 0x10, streamFile));
vgmstream->loop_end_sample = dsp_nibbles_to_samples(read_32bit(header_offset + 0x14, streamFile)) + 1;
if (vgmstream->loop_end_sample > vgmstream->num_samples) /* ? */
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->coding_type = coding_NGC_DSP;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = interleave;
dsp_read_coefs_be(vgmstream, streamFile, header_offset + 0x1C, interleave);
dsp_read_hist_be(vgmstream, streamFile, header_offset + 0x40, interleave);
dsp_read_coefs(vgmstream, streamFile, header_offset + 0x1C, interleave, big_endian);
dsp_read_hist (vgmstream, streamFile, header_offset + 0x40, interleave, big_endian);
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
goto fail;

View File

@ -96,15 +96,14 @@ static int read_fmt(int big_endian, STREAMFILE * streamFile, off_t current_chunk
int16_t (*read_16bit)(off_t,STREAMFILE*) = big_endian ? read_16bitBE : read_16bitLE;
fmt->offset = current_chunk;
fmt->size = read_32bit(current_chunk+0x4,streamFile);
fmt->size = read_32bit(current_chunk+0x04,streamFile);
fmt->codec = (uint16_t)read_16bit(current_chunk+0x08,streamFile);
fmt->sample_rate = read_32bit(current_chunk+0x0c,streamFile);
fmt->channel_count = read_16bit(current_chunk+0x0a,streamFile);
fmt->block_size = read_16bit(current_chunk+0x14,streamFile);
fmt->interleave = 0;
fmt->bps = read_16bit(current_chunk+0x16,streamFile);
fmt->codec = (uint16_t)read_16bit(current_chunk+0x8,streamFile);
fmt->interleave = 0;
switch (fmt->codec) {
case 0x00: /* Yamaha ADPCM (raw) [Headhunter (DC), Bomber hehhe (DC)] (unofficial) */
@ -130,8 +129,15 @@ static int read_fmt(int big_endian, STREAMFILE * streamFile, off_t current_chunk
break;
case 0x02: /* MS ADPCM */
if (fmt->bps != 4) goto fail;
fmt->coding_type = coding_MSADPCM;
if (fmt->bps == 4) {
fmt->coding_type = coding_MSADPCM;
}
else if (fmt->bps == 16 && fmt->block_size == 0x02 * fmt->channel_count && fmt->size == 0x14) {
fmt->coding_type = coding_IMA; /* MX vs ATV Unleashed (PC) codec hijack */
}
else {
goto fail;
}
break;
case 0x11: /* MS IMA ADPCM [Layton Brothers: Mystery Room (iOS/Android)] */
@ -295,10 +301,9 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
riff_size = read_32bitLE(0x04,streamFile);
file_size = get_streamfile_size(streamFile);
/* for some of Liar-soft's buggy RIFF+Ogg made with Soundforge [Shikkoku no Sharnoth (PC)] */
/* some of Liar-soft's buggy RIFF+Ogg made with Soundforge [Shikkoku no Sharnoth (PC)] */
if (riff_size+0x08+0x01 == file_size)
riff_size += 0x01;
/* some Xbox games do this [Dynasty Warriors 3 (Xbox), BloodRayne (Xbox)] */
if (riff_size == file_size && read_16bitLE(0x14,streamFile)==0x0069)
riff_size -= 0x08;
@ -540,6 +545,10 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
vgmstream->num_samples = fact_sample_count; /* some (converted?) Xbox games have bigger fact_samples */
break;
case coding_IMA:
vgmstream->num_samples = ima_bytes_to_samples(data_size, fmt.channel_count);
break;
#ifdef VGM_USE_FFMPEG
case coding_FFmpeg: {
ffmpeg_codec_data *ffmpeg_data = init_ffmpeg_offset(streamFile, 0x00, streamFile->get_size(streamFile));
@ -607,6 +616,7 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
case coding_MS_IMA:
case coding_AICA:
case coding_XBOX_IMA:
case coding_IMA:
#ifdef VGM_USE_FFMPEG
case coding_FFmpeg:
#endif

View File

@ -389,7 +389,7 @@ static int parse_pk_header(ubi_bao_header * bao, STREAMFILE *streamFile) {
goto fail;
}
;VGM_LOG("BAO stream: id=%x, offset=%lx, size=%x, res=%s\n", bao->stream_id, bao->stream_offset, bao->stream_size, (bao->is_external ? bao->resource_name : "internal"));
;VGM_LOG("BAO stream: id=%x, offset=%"PRIx64", size=%x, res=%s\n", bao->stream_id, (off64_t)bao->stream_offset, bao->stream_size, (bao->is_external ? bao->resource_name : "internal"));
return 1;
fail:
@ -432,7 +432,7 @@ static int parse_bao(ubi_bao_header * bao, STREAMFILE *streamFile, off_t offset)
case 0x70000000: bao->types_count[7]++; break; /* project info? (sometimes special id 0x7fffffff) */
case 0x80000000: bao->types_count[8]++; break; /* unknown (some id/info?) */
default:
VGM_LOG("UBI BAO: unknown type %x at %lx (%lx)\n", descriptor_type, offset, offset+0x20);
VGM_LOG("UBI BAO: unknown type %x at %"PRIx64" + %x\n", descriptor_type, (off64_t)offset, 0x20);
goto fail;
}
@ -451,7 +451,7 @@ static int parse_bao(ubi_bao_header * bao, STREAMFILE *streamFile, off_t offset)
case 0x00000007: bao->subtypes_count[7]++; break; /* related to other header BAOs? */
case 0x00000008: bao->subtypes_count[8]++; break; /* ? (almost empty with some unknown value) */
default:
VGM_LOG("UBI BAO: unknown subtype %x at %lx (%lx)\n", descriptor_subtype, offset, offset+header_size+0x04);
VGM_LOG("UBI BAO: unknown subtype %x at %"PRIx64" + %x\n", descriptor_subtype, (off64_t)offset, header_size+0x04);
goto fail;
}
//;VGM_ASSERT(descriptor_subtype != 0x01, "UBI BAO: subtype %x at %lx (%lx)\n", descriptor_subtype, offset, offset+header_size+0x04);
@ -475,7 +475,7 @@ static int parse_bao(ubi_bao_header * bao, STREAMFILE *streamFile, off_t offset)
* - channels, ?, sample rate, average bit rate?, samples, full stream_size?, codec, etc
* - subtable entries, subtable size (may contain offsets/ids, cues, etc)
* - extra data per codec (ex. XMA header in some versions) */
;VGM_LOG("BAO header at %lx\n", offset);
;VGM_LOG("BAO header at %"PRIx64"\n", (off64_t)offset);
bao->version = bao_version;
switch(bao->version) {
@ -501,7 +501,7 @@ static int parse_bao(ubi_bao_header * bao, STREAMFILE *streamFile, off_t offset)
case 0x03: bao->codec = UBI_ADPCM; break;
case 0x05: bao->codec = RAW_XMA1; break;
case 0x09: bao->codec = RAW_DSP; break;
default: VGM_LOG("UBI BAO: unknown codec at %lx\n", offset); goto fail;
default: VGM_LOG("UBI BAO: unknown codec at %"PRIx64"\n", (off64_t)offset); goto fail;
}
bao->prefetch_size = read_32bit(offset + header_size + 0x74, streamFile);
@ -533,11 +533,11 @@ static int parse_bao(ubi_bao_header * bao, STREAMFILE *streamFile, off_t offset)
switch(bao->header_codec) {
case 0x06: bao->codec = RAW_PSX; break;
case 0x07: bao->codec = FMT_AT3; break;
default: VGM_LOG("UBI BAO: unknown codec at %lx\n", offset); goto fail;
default: VGM_LOG("UBI BAO: unknown codec at %"PRIx64"\n", (off64_t)offset); goto fail;
}
if (read_32bit(offset+header_size+0x20, streamFile) & 0x10) {
VGM_LOG("UBI BAO: possible full loop at %lx\n", offset);
VGM_LOG("UBI BAO: possible full loop at %"PRIx64"\n", (off64_t)offset);
/* RIFFs may have "smpl" and this flag, even when data shouldn't loop... */
}
@ -562,7 +562,7 @@ static int parse_bao(ubi_bao_header * bao, STREAMFILE *streamFile, off_t offset)
case 0x02: bao->codec = UBI_ADPCM; break;
case 0x03: bao->codec = FMT_OGG; break;
case 0x04: bao->codec = RAW_XMA2; break;
default: VGM_LOG("UBI BAO: unknown codec at %lx\n", offset); goto fail;
default: VGM_LOG("UBI BAO: unknown codec at %"PRIx64"\n", (off64_t)offset); goto fail;
}
bao->prefetch_size = read_32bit(offset+header_size+0x84, streamFile);
@ -596,7 +596,7 @@ static int parse_bao(ubi_bao_header * bao, STREAMFILE *streamFile, off_t offset)
case 0x04: bao->codec = RAW_XMA2; break;
case 0x05: bao->codec = RAW_PSX; break;
case 0x06: bao->codec = RAW_AT3; break;
default: VGM_LOG("UBI BAO: unknown codec at %lx\n", offset); goto fail;
default: VGM_LOG("UBI BAO: unknown codec at %"PRIx64"\n", (off64_t)offset); goto fail;
}
bao->prefetch_size = read_32bit(offset + header_size + 0x78, streamFile);
@ -613,7 +613,7 @@ static int parse_bao(ubi_bao_header * bao, STREAMFILE *streamFile, off_t offset)
case 0x00280306: /* Far Cry 3: Blood Dragon (X360)-file */
case 0x00290106: /* Splinter Cell Blacklist? */
default: /* others possibly using BAO: Avatar X360/PS3/PC, Just Dance, Watch_Dogs, Far Cry Primal, Far Cry 4 */
VGM_LOG("UBI BAO: unknown BAO version at %lx\n", offset);
VGM_LOG("UBI BAO: unknown BAO version at %"PRIx64"\n", (off64_t)offset);
goto fail;
}

View File

@ -297,7 +297,7 @@ static int get_loop_points(STREAMFILE *streamFile, int *out_loop_start, int *out
break;
default:
VGM_LOG("Jade: unknown LIST chunk at %lx\n", offset);
VGM_LOG("Jade: unknown LIST chunk\n");
goto fail;
}

68
src/meta/ue4opus.c Normal file
View File

@ -0,0 +1,68 @@
#include "meta.h"
#include "../coding/coding.h"
/* UE4OPUS - from Unreal Engine 4 games [ARK: Survival Evolved (PC), Fortnite (PC)] */
VGMSTREAM * init_vgmstream_ue4opus(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag = 0, channel_count, sample_rate, num_samples, skip;
size_t data_size;
/* checks*/
/* .opus/lopus: possible real extension
* .ue4opus: header id */
if (!check_extensions(streamFile, "opus,lopus,ue4opus"))
goto fail;
if (read_32bitBE(0x00, streamFile) != 0x5545344F && /* "UE4O" */
read_32bitBE(0x00, streamFile) != 0x50555300) /* "PUS\0" */
goto fail;
sample_rate = (uint16_t)read_16bitLE(0x08, streamFile);
num_samples = read_32bitLE(0x0a, streamFile); /* may be less or equal to file num_samples */
channel_count = read_8bit(0x0e, streamFile);
/* 0x0f(2): frame count */
loop_flag = 0;
/* UE4Opus encodes 60ms (music) or 120ms (voice) frames, and encoder delay seems 1/8
* of samples per frame (may be more complex but wave looks ok-ish) */
//todo does UE4 actually care about encoder delay?
skip = (60 * 48000 / 1000) / 8; /* 48000 is the internal/resampled rate */
start_offset = 0x11;
data_size = get_streamfile_size(streamFile) - start_offset;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
vgmstream->meta_type = meta_UE4OPUS;
vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = num_samples - skip;
#ifdef VGM_USE_FFMPEG
{
vgmstream->codec_data = init_ffmpeg_ue4_opus(streamFile, start_offset,data_size, vgmstream->channels, skip, vgmstream->sample_rate);
if (!vgmstream->codec_data) goto fail;
vgmstream->coding_type = coding_FFmpeg;
vgmstream->layout_type = layout_none;
if (vgmstream->num_samples == 0) {
vgmstream->num_samples = ue4_opus_get_samples(start_offset, data_size, vgmstream->sample_rate, streamFile) - skip;
}
}
#else
goto fail;
#endif
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -771,7 +771,7 @@ static int get_xsb_name(char * buf, size_t maxsize, int target_subsong, xwb_head
size = 0x14;
if (flag != 0x01) {
VGM_LOG("XSB: xsb flag 0x%x at offset 0x%08lx not implemented\n", flag, off);
//VGM_LOG("XSB: xsb flag 0x%x at offset 0x%08lx not implemented\n", flag, off);
goto fail;
}
@ -802,7 +802,7 @@ static int get_xsb_name(char * buf, size_t maxsize, int target_subsong, xwb_head
//} else if (flag==0x11) { /* Stardew Valley (Switch) */
// suboff = size; //???
} else {
VGM_LOG("XSB: xsb flag 0x%x (size=%x) at offset 0x%08lx not implemented\n", flag, size, off);
//VGM_LOG("XSB: xsb flag 0x%x (size=%x) at offset 0x%08lx not implemented\n", flag, size, off);
goto fail;
}
}
@ -813,7 +813,7 @@ static int get_xsb_name(char * buf, size_t maxsize, int target_subsong, xwb_head
}
if (s->wavebank+1 > xsb.xsb_wavebanks_count) {
VGM_LOG("XSB: unknown xsb wavebank id %i at offset 0x%lx\n", s->wavebank, off);
//VGM_LOG("XSB: unknown xsb wavebank id %i at offset 0x%lx\n", s->wavebank, off);
goto fail;
}
@ -883,7 +883,7 @@ static int get_xsb_name(char * buf, size_t maxsize, int target_subsong, xwb_head
if (w->sound_count == xwb->total_subsongs) {
if (!cfg__selected_wavebank) {
VGM_LOG("XSB: multiple xsb wavebanks with the same number of sounds, use -w to specify one of the wavebanks\n");
//VGM_LOG("XSB: multiple xsb wavebanks with the same number of sounds, use -w to specify one of the wavebanks\n");
goto fail;
}
@ -898,17 +898,17 @@ static int get_xsb_name(char * buf, size_t maxsize, int target_subsong, xwb_head
}
if (!cfg__selected_wavebank) {
VGM_LOG("XSB: multiple xsb wavebanks but autodetect didn't work\n");
//VGM_LOG("XSB: multiple xsb wavebanks but autodetect didn't work\n");
goto fail;
}
if (xsb.xsb_wavebanks[cfg__selected_wavebank-1].sound_count == 0) {
VGM_LOG("XSB: xsb selected wavebank %i has no sounds\n", cfg__selected_wavebank);
//VGM_LOG("XSB: xsb selected wavebank %i has no sounds\n", cfg__selected_wavebank);
goto fail;
}
if (cfg__start_sound) {
if (xsb.xsb_wavebanks[cfg__selected_wavebank-1].sound_count - (cfg__start_sound-1) < xwb->total_subsongs) {
VGM_LOG("XSB: starting sound too high (max in selected wavebank is %i)\n", xsb.xsb_wavebanks[cfg__selected_wavebank-1].sound_count - xwb->total_subsongs + 1);
//VGM_LOG("XSB: starting sound too high (max in selected wavebank is %i)\n", xsb.xsb_wavebanks[cfg__selected_wavebank-1].sound_count - xwb->total_subsongs + 1);
goto fail;
}

View File

@ -53,7 +53,7 @@ static size_t read_stdio(STDIOSTREAMFILE *streamfile,uint8_t * dest, off_t offse
/* ignore requests at EOF */
if (offset >= streamfile->filesize) {
//offset = streamfile->filesize; /* seems fseek doesn't clamp offset */
VGM_ASSERT_ONCE(offset > streamfile->filesize, "STDIO: reading over filesize 0x%x @ 0x%lx + 0x%x\n", streamfile->filesize, offset, length);
VGM_ASSERT_ONCE(offset > streamfile->filesize, "STDIO: reading over filesize 0x%x @ 0x%"PRIx64" + 0x%x\n", streamfile->filesize, (off64_t)offset, length);
break;
}
@ -169,8 +169,9 @@ static STREAMFILE * open_stdio_streamfile_buffer_by_file(FILE *infile,const char
fseeko(streamfile->infile,0,SEEK_END);
streamfile->filesize = ftello(streamfile->infile);
/* some compilers/flags may use ftell, which only handles up to ~2.14GB
* (possible for banks like FSB, though unlikely). */
/* Typically fseek(o)/ftell(o) may only handle up to ~2.14GB, signed 32b = 0x7FFFFFFF
* (happens in banks like FSB, though rarely). Can be remedied with the
* preprocessor (-D_FILE_OFFSET_BITS=64 in GCC) but it's not well tested. */
if (streamfile->filesize == 0xFFFFFFFF) { /* -1 on error */
VGM_LOG("STREAMFILE: ftell error\n");
goto fail; /* can be ignored but may result in strange/unexpected behaviors */
@ -253,7 +254,7 @@ static size_t buffer_read(BUFFER_STREAMFILE *streamfile, uint8_t * dest, off_t o
/* ignore requests at EOF */
if (offset >= streamfile->filesize) {
//offset = streamfile->filesize; /* seems fseek doesn't clamp offset */
VGM_ASSERT_ONCE(offset > streamfile->filesize, "BUFFER: reading over filesize 0x%x @ 0x%lx + 0x%x\n", streamfile->filesize, offset, length);
VGM_ASSERT_ONCE(offset > streamfile->filesize, "BUFFER: reading over filesize 0x%x @ 0x%"PRIx64" + 0x%x\n", streamfile->filesize, (off64_t)offset, length);
break;
}

View File

@ -16,16 +16,29 @@
#include "streamtypes.h"
#include "util.h"
/* MSVC fixes (though mingw uses MSVCRT but not MSC_VER, maybe use AND?) */
#if defined(__MSVCRT__) || defined(_MSC_VER)
#include <io.h>
#define fseeko fseek
#define ftello ftell
#define dup _dup
#ifdef fileno
#undef fileno
#endif
#define fileno _fileno
#define fdopen _fdopen
#include <io.h>
#ifndef fseeko
#define fseeko fseek
#endif
#ifndef ftello
#define ftello ftell
#endif
#define dup _dup
#ifdef fileno
#undef fileno
#endif
#define fileno _fileno
#define fdopen _fdopen
// #ifndef off64_t
// #define off_t __int64
// #endif
#endif
#if defined(XBMC)

View File

@ -439,6 +439,8 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
init_vgmstream_xau_konami,
init_vgmstream_derf,
init_vgmstream_utk,
init_vgmstream_adpcm_capcom,
init_vgmstream_ue4opus,
/* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */
@ -597,8 +599,7 @@ void reset_vgmstream(VGMSTREAM * vgmstream) {
#endif
#ifdef VGM_USE_G7221
if (vgmstream->coding_type==coding_G7221 ||
vgmstream->coding_type==coding_G7221C) {
if (vgmstream->coding_type==coding_G7221C) {
reset_g7221(vgmstream);
}
#endif
@ -781,8 +782,7 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
#endif
#ifdef VGM_USE_G7221
if (vgmstream->coding_type == coding_G7221 ||
vgmstream->coding_type == coding_G7221C) {
if (vgmstream->coding_type == coding_G7221C) {
free_g7221(vgmstream);
vgmstream->codec_data = NULL;
}
@ -1193,9 +1193,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
#ifdef VGM_USE_G7221
case coding_G7221C:
return 32000/50;
case coding_G7221:
return 16000/50;
return 32000/50; /* Siren7: 16000/50 */
#endif
#ifdef VGM_USE_G719
case coding_G719:
@ -1371,7 +1369,6 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
#ifdef VGM_USE_G7221
case coding_G7221C:
case coding_G7221:
#endif
#ifdef VGM_USE_G719
case coding_G719:
@ -1846,7 +1843,6 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
break;
#endif
#ifdef VGM_USE_G7221
case coding_G7221:
case coding_G7221C:
for (ch = 0; ch < vgmstream->channels; ch++) {
decode_g7221(vgmstream, buffer+samples_written*vgmstream->channels+ch,

View File

@ -177,7 +177,6 @@ typedef enum {
#endif
#ifdef VGM_USE_G7221
coding_G7221, /* ITU G.722.1 (Polycom Siren 7) */
coding_G7221C, /* ITU G.722.1 annex C (Polycom Siren 14) */
#endif
@ -705,6 +704,8 @@ typedef enum {
meta_DERF, /* Stupid Invaders (PC) */
meta_UTK,
meta_NXA,
meta_ADPCM_CAPCOM,
meta_UE4OPUS,
} meta_t;