mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 08:20:54 +01:00
riff: fix codecs with some libs disabled, cleanup
This commit is contained in:
parent
630cb09f47
commit
8819cbf0b3
117
src/meta/riff.c
117
src/meta/riff.c
@ -27,8 +27,8 @@ static void parse_adtl(off_t adtl_offset, off_t adtl_length, STREAMFILE* sf, lon
|
||||
off_t current_chunk = adtl_offset+0x04;
|
||||
|
||||
while (current_chunk < adtl_offset + adtl_length) {
|
||||
uint32_t chunk_type = read_32bitBE(current_chunk+0x00,sf);
|
||||
off_t chunk_size = read_32bitLE(current_chunk+0x04,sf);
|
||||
uint32_t chunk_type = read_u32be(current_chunk+0x00,sf);
|
||||
uint32_t chunk_size = read_u32le(current_chunk+0x04,sf);
|
||||
|
||||
if (current_chunk+0x08+chunk_size > adtl_offset+adtl_length)
|
||||
return;
|
||||
@ -81,7 +81,7 @@ typedef struct {
|
||||
off_t size;
|
||||
uint32_t codec;
|
||||
int sample_rate;
|
||||
int channel_count;
|
||||
int channels;
|
||||
uint32_t block_size;
|
||||
int bps;
|
||||
off_t extra_size;
|
||||
@ -95,38 +95,38 @@ typedef struct {
|
||||
int is_at9;
|
||||
} riff_fmt_chunk;
|
||||
|
||||
static int read_fmt(int big_endian, STREAMFILE* sf, off_t current_chunk, riff_fmt_chunk* fmt, int mwv) {
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = big_endian ? read_32bitBE : read_32bitLE;
|
||||
int16_t (*read_16bit)(off_t,STREAMFILE*) = big_endian ? read_16bitBE : read_16bitLE;
|
||||
static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk* fmt, int mwv) {
|
||||
uint32_t (*read_u32)(off_t,STREAMFILE*) = big_endian ? read_u32be : read_u32le;
|
||||
uint16_t (*read_u16)(off_t,STREAMFILE*) = big_endian ? read_u16be : read_u16le;
|
||||
|
||||
fmt->offset = current_chunk;
|
||||
fmt->size = read_32bit(current_chunk+0x04,sf);
|
||||
fmt->offset = offset;
|
||||
fmt->size = read_u32(offset+0x04,sf);
|
||||
|
||||
/* WAVEFORMAT */
|
||||
fmt->codec = (uint16_t)read_16bit(current_chunk+0x08,sf);
|
||||
fmt->channel_count = read_16bit(current_chunk+0x0a,sf);
|
||||
fmt->sample_rate = read_32bit(current_chunk+0x0c,sf);
|
||||
//fmt->avg_bps = read_32bit(current_chunk+0x10,sf);
|
||||
fmt->block_size = read_16bit(current_chunk+0x14,sf);
|
||||
fmt->bps = read_16bit(current_chunk+0x16,sf);
|
||||
fmt->codec = read_u16(offset+0x08,sf);
|
||||
fmt->channels = read_u16(offset+0x0a,sf);
|
||||
fmt->sample_rate = read_u32(offset+0x0c,sf);
|
||||
//fmt->avg_bps = read_u32(offset+0x10,sf);
|
||||
fmt->block_size = read_u16(offset+0x14,sf);
|
||||
fmt->bps = read_u16(offset+0x16,sf);
|
||||
/* WAVEFORMATEX */
|
||||
if (fmt->size >= 0x10) {
|
||||
fmt->extra_size = read_16bit(current_chunk+0x18,sf);
|
||||
fmt->extra_size = read_u16(offset+0x18,sf);
|
||||
/* 0x1a+ depends on codec (ex. coef table for MSADPCM, samples_per_frame in MS-IMA, etc) */
|
||||
}
|
||||
/* WAVEFORMATEXTENSIBLE */
|
||||
if (fmt->codec == 0xFFFE && fmt->extra_size >= 0x16) {
|
||||
//fmt->extra_samples = read_16bit(current_chunk+0x1a,sf); /* valid_bits_per_sample or samples_per_block */
|
||||
fmt->channel_layout = read_32bit(current_chunk+0x1c,sf);
|
||||
//fmt->extra_samples = read_u16(offset+0x1a,sf); /* valid_bits_per_sample or samples_per_block */
|
||||
fmt->channel_layout = read_u32(offset+0x1c,sf);
|
||||
/* 0x10 guid at 0x20 */
|
||||
|
||||
/* happens in various .at3/at9, may be a bug in their encoder b/c MS's defs set mono as FC */
|
||||
if (fmt->channel_count == 1 && fmt->channel_layout == speaker_FL) { /* other channels are fine */
|
||||
if (fmt->channels == 1 && fmt->channel_layout == speaker_FL) { /* other channels are fine */
|
||||
fmt->channel_layout = speaker_FC;
|
||||
}
|
||||
|
||||
/* happens in few at3p, may be a bug in older tools as other games have ok flags [Ridge Racer 7 (PS3)] */
|
||||
if (fmt->channel_count == 6 && fmt->channel_layout == 0x013f) {
|
||||
if (fmt->channels == 6 && fmt->channel_layout == 0x013f) {
|
||||
fmt->channel_layout = 0x3f;
|
||||
}
|
||||
}
|
||||
@ -134,8 +134,8 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t current_chunk, riff_fm
|
||||
switch (fmt->codec) {
|
||||
case 0x00: /* Yamaha AICA ADPCM [Headhunter (DC), Bomber hehhe (DC), Rayman 2 (DC)] (unofficial) */
|
||||
if (fmt->bps != 4) goto fail;
|
||||
if (fmt->block_size != 0x02*fmt->channel_count &&
|
||||
fmt->block_size != 0x01*fmt->channel_count) goto fail;
|
||||
if (fmt->block_size != 0x02*fmt->channels &&
|
||||
fmt->block_size != 0x01*fmt->channels) goto fail;
|
||||
fmt->coding_type = coding_AICA_int;
|
||||
fmt->interleave = 0x01;
|
||||
break;
|
||||
@ -161,7 +161,7 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t current_chunk, riff_fm
|
||||
if (!msadpcm_check_coefs(sf, fmt->offset + 0x08 + 0x14))
|
||||
goto fail;
|
||||
}
|
||||
else if (fmt->bps == 16 && fmt->block_size == 0x02 * fmt->channel_count && fmt->size == 0x14) {
|
||||
else if (fmt->bps == 16 && fmt->block_size == 0x02 * fmt->channels && fmt->size == 0x14) {
|
||||
fmt->coding_type = coding_IMA; /* MX vs ATV Unleashed (PC) codec hijack */
|
||||
}
|
||||
else {
|
||||
@ -201,9 +201,9 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t current_chunk, riff_fm
|
||||
|
||||
case 0x0300: /* IMA ADPCM [Chrono Ma:gia (Android)] (unofficial) */
|
||||
if (fmt->bps != 4) goto fail;
|
||||
if (fmt->block_size != 0x0400*fmt->channel_count) goto fail;
|
||||
if (fmt->block_size != 0x0400*fmt->channels) goto fail;
|
||||
if (fmt->size != 0x14) goto fail;
|
||||
if (fmt->channel_count != 1) goto fail; /* not seen */
|
||||
if (fmt->channels != 1) goto fail; /* not seen */
|
||||
fmt->coding_type = coding_DVI_IMA;
|
||||
/* real 0x300 is "Fujitsu FM Towns SND" with block align 0x01 */
|
||||
break;
|
||||
@ -218,25 +218,21 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t current_chunk, riff_fm
|
||||
case 0x6771: /* Ogg Vorbis (mode 3+) */
|
||||
fmt->coding_type = coding_OGG_VORBIS;
|
||||
break;
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
case 0x0270: /* ATRAC3 */
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case 0x0270: /* ATRAC3 */
|
||||
fmt->coding_type = coding_FFmpeg;
|
||||
fmt->is_at3 = 1;
|
||||
break;
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
case 0xFFFE: { /* WAVEFORMATEXTENSIBLE (see ksmedia.h for known GUIDs) */
|
||||
uint32_t guid1 = (uint32_t)read_32bit (current_chunk+0x20,sf);
|
||||
uint32_t guid2 = ((uint16_t)read_16bit (current_chunk+0x24,sf) << 16u) |
|
||||
((uint16_t)read_16bit (current_chunk+0x26,sf));
|
||||
uint32_t guid3 = (uint32_t)read_32bitBE(current_chunk+0x28,sf);
|
||||
uint32_t guid4 = (uint32_t)read_32bitBE(current_chunk+0x2c,sf);
|
||||
uint32_t guid1 = read_u32 (offset+0x20,sf);
|
||||
uint32_t guid2 = (read_u16 (offset+0x24,sf) << 16u) |
|
||||
(read_u16 (offset+0x26,sf));
|
||||
uint32_t guid3 = read_u32be(offset+0x28,sf);
|
||||
uint32_t guid4 = read_u32be(offset+0x2c,sf);
|
||||
//;VGM_LOG("RIFF: guid %08x %08x %08x %08x\n", guid1, guid2, guid3, guid4);
|
||||
|
||||
/* PCM GUID (0x00000001,0000,0010,80,00,00,AA,00,38,9B,71) */
|
||||
@ -254,32 +250,30 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t current_chunk, riff_fm
|
||||
|
||||
/* ATRAC3plus GUID (0xE923AABF,CB58,4471,A1,19,FF,FA,01,E4,CE,62) */
|
||||
if (guid1 == 0xE923AABF && guid2 == 0xCB584471 && guid3 == 0xA119FFFA && guid4 == 0x01E4CE62) {
|
||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||
uint16_t bztmp = read_16bit(current_chunk+0x32,sf);
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
fmt->coding_type = coding_FFmpeg;
|
||||
fmt->is_at3p = 1;
|
||||
break;
|
||||
#elif defined(VGM_USE_MAIATRAC3PLUS)
|
||||
uint16_t bztmp = read_u16(offset+0x32,sf);
|
||||
bztmp = (bztmp >> 8) | (bztmp << 8);
|
||||
fmt->coding_type = coding_AT3plus;
|
||||
fmt->block_size = (bztmp & 0x3FF) * 8 + 8; /* should match fmt->block_size */
|
||||
fmt->is_at3p = 1;
|
||||
break;
|
||||
#elif defined(VGM_USE_FFMPEG)
|
||||
fmt->coding_type = coding_FFmpeg;
|
||||
fmt->is_at3p = 1;
|
||||
break;
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_ATRAC9
|
||||
/* ATRAC9 GUID (0x47E142D2,36BA,4D8D,88,FC,61,65,4F,8C,83,6C) */
|
||||
if (guid1 == 0x47E142D2 && guid2 == 0x36BA4D8D && guid3 == 0x88FC6165 && guid4 == 0x4F8C836C) {
|
||||
#ifdef VGM_USE_ATRAC9
|
||||
fmt->coding_type = coding_ATRAC9;
|
||||
fmt->is_at9 = 1;
|
||||
break;
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
goto fail; /* unknown GUID */
|
||||
}
|
||||
@ -370,7 +364,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
||||
|
||||
/* some games have wonky sizes, selectively fix to catch bad rips and new mutations */
|
||||
if (file_size != riff_size + 0x08) {
|
||||
uint16_t codec = read_16bitLE(0x14,sf);
|
||||
uint16_t codec = read_u16le(0x14,sf);
|
||||
|
||||
if (codec == 0x6771 && riff_size + 0x08 + 0x01 == file_size)
|
||||
riff_size += 0x01; /* [Shikkoku no Sharnoth (PC)] (Sony Sound Forge?) */
|
||||
@ -397,11 +391,10 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
||||
riff_size += 0x18; /* [F1 2011 (Vita)] (adds a "pada" chunk but RIFF size wasn't updated) */
|
||||
|
||||
else if (mwv) {
|
||||
int channels = read_16bitLE(0x16, sf); /* [Dragon Quest VIII (PS2), Rogue Galaxy (PS2)] */
|
||||
int channels = read_u16le(0x16, sf); /* [Dragon Quest VIII (PS2), Rogue Galaxy (PS2)] */
|
||||
size_t file_size_fixed = riff_size + 0x08 + 0x04 * (channels - 1);
|
||||
|
||||
if (file_size_fixed <= file_size && file_size - file_size_fixed < 0x10)
|
||||
{
|
||||
if (file_size_fixed <= file_size && file_size - file_size_fixed < 0x10) {
|
||||
/* files inside HD6/DAT are also padded to 0x10 so need to fix file_size */
|
||||
file_size = file_size_fixed;
|
||||
riff_size = file_size - 0x08;
|
||||
@ -617,7 +610,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(fmt.channel_count,loop_flag);
|
||||
vgmstream = allocate_vgmstream(fmt.channels,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = fmt.sample_rate;
|
||||
@ -661,7 +654,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
||||
/* samples, codec init (after setting coding to ensure proper close on failure) */
|
||||
switch (fmt.coding_type) {
|
||||
case coding_PCM16LE:
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(data_size, fmt.channel_count, 16);
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(data_size, fmt.channels, 16);
|
||||
break;
|
||||
|
||||
case coding_PCM8_U:
|
||||
@ -670,7 +663,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
||||
|
||||
case coding_L5_555:
|
||||
if (!mwv) goto fail;
|
||||
vgmstream->num_samples = data_size / 0x12 / fmt.channel_count * 32;
|
||||
vgmstream->num_samples = data_size / 0x12 / fmt.channels * 32;
|
||||
|
||||
/* coefs */
|
||||
{
|
||||
@ -684,7 +677,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
||||
read_32bitLE(mwv_pflt_offset+0x04, sf) < 8 + filter_count * 4 * filter_order)
|
||||
goto fail;
|
||||
|
||||
for (ch = 0; ch < fmt.channel_count; ch++) {
|
||||
for (ch = 0; ch < fmt.channels; ch++) {
|
||||
for (i = 0; i < filter_count * filter_order; i++) {
|
||||
int coef = read_32bitLE(mwv_pflt_offset+0x10+i*0x04, sf);
|
||||
vgmstream->ch[ch].adpcm_coef_3by32[i] = coef;
|
||||
@ -695,31 +688,31 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
||||
break;
|
||||
|
||||
case coding_MSADPCM:
|
||||
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
|
||||
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, fmt.block_size, fmt.channels);
|
||||
if (fact_sample_count && fact_sample_count < vgmstream->num_samples)
|
||||
vgmstream->num_samples = fact_sample_count;
|
||||
break;
|
||||
|
||||
case coding_MS_IMA:
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
|
||||
vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, fmt.block_size, fmt.channels);
|
||||
if (fact_sample_count && fact_sample_count < vgmstream->num_samples)
|
||||
vgmstream->num_samples = fact_sample_count;
|
||||
break;
|
||||
|
||||
case coding_AICA:
|
||||
case coding_AICA_int:
|
||||
vgmstream->num_samples = yamaha_bytes_to_samples(data_size, fmt.channel_count);
|
||||
vgmstream->num_samples = yamaha_bytes_to_samples(data_size, fmt.channels);
|
||||
break;
|
||||
|
||||
case coding_XBOX_IMA:
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, fmt.channel_count);
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, fmt.channels);
|
||||
if (fact_sample_count && fact_sample_count < vgmstream->num_samples)
|
||||
vgmstream->num_samples = fact_sample_count; /* some (converted?) Xbox games have bigger fact_samples */
|
||||
break;
|
||||
|
||||
case coding_IMA:
|
||||
case coding_DVI_IMA:
|
||||
vgmstream->num_samples = ima_bytes_to_samples(data_size, fmt.channel_count);
|
||||
vgmstream->num_samples = ima_bytes_to_samples(data_size, fmt.channels);
|
||||
break;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
@ -873,7 +866,7 @@ fail:
|
||||
static int is_ue4_msadpcm(STREAMFILE* sf, riff_fmt_chunk* fmt, int fact_sample_count, off_t start) {
|
||||
|
||||
/* multichannel ok */
|
||||
if (fmt->channel_count < 2)
|
||||
if (fmt->channels < 2)
|
||||
goto fail;
|
||||
|
||||
/* UE4 class is "ADPCM", assume it's the extension too */
|
||||
@ -902,7 +895,7 @@ static int is_ue4_msadpcm(STREAMFILE* sf, riff_fmt_chunk* fmt, int fact_sample_c
|
||||
/* their encoder doesn't calculate optimal coefs and uses fixed values every frame
|
||||
* (could do it for fmt size 0x36 too but maybe they'll fix it in the future) */
|
||||
while (offset <= max_offset) {
|
||||
if (read_8bit(offset+0x00, sf) != 0 || read_16bitLE(offset+0x01, sf) != 0x00E6)
|
||||
if (read_u8(offset+0x00, sf) != 0 || read_u16le(offset+0x01, sf) != 0x00E6)
|
||||
goto fail;
|
||||
offset += fmt->block_size;
|
||||
}
|
||||
@ -916,7 +909,7 @@ fail:
|
||||
/* for maximum annoyance later UE4 versions (~v4.2x?) interleave single frames instead of
|
||||
* half interleave, but don't have flags to detect so we need some heuristics */
|
||||
static size_t get_ue4_msadpcm_interleave(STREAMFILE* sf, riff_fmt_chunk* fmt, off_t start, size_t size) {
|
||||
size_t v1_interleave = size / fmt->channel_count;
|
||||
size_t v1_interleave = size / fmt->channels;
|
||||
size_t v2_interleave = fmt->block_size;
|
||||
uint8_t nibbles1[0x08] = {0};
|
||||
uint8_t nibbles2[0x08] = {0};
|
||||
@ -927,7 +920,7 @@ static size_t get_ue4_msadpcm_interleave(STREAMFILE* sf, riff_fmt_chunk* fmt, of
|
||||
return v1_interleave;
|
||||
|
||||
/* 6ch only observed in later versions [Fortnite (PC)], not padded */
|
||||
if (fmt->channel_count > 2)
|
||||
if (fmt->channels > 2)
|
||||
return v2_interleave;
|
||||
|
||||
read_streamfile(nibbles1, start + size - 0x08, sizeof(nibbles2), sf);
|
||||
@ -1053,7 +1046,7 @@ VGMSTREAM* init_vgmstream_rifx(STREAMFILE* sf) {
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(fmt.channel_count,loop_flag);
|
||||
vgmstream = allocate_vgmstream(fmt.channels,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = fmt.sample_rate;
|
||||
|
Loading…
Reference in New Issue
Block a user