riff: fix codecs with some libs disabled, cleanup

This commit is contained in:
bnnm 2021-08-22 12:17:45 +02:00
parent 630cb09f47
commit 8819cbf0b3

View File

@ -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; off_t current_chunk = adtl_offset+0x04;
while (current_chunk < adtl_offset + adtl_length) { while (current_chunk < adtl_offset + adtl_length) {
uint32_t chunk_type = read_32bitBE(current_chunk+0x00,sf); uint32_t chunk_type = read_u32be(current_chunk+0x00,sf);
off_t chunk_size = read_32bitLE(current_chunk+0x04,sf); uint32_t chunk_size = read_u32le(current_chunk+0x04,sf);
if (current_chunk+0x08+chunk_size > adtl_offset+adtl_length) if (current_chunk+0x08+chunk_size > adtl_offset+adtl_length)
return; return;
@ -81,7 +81,7 @@ typedef struct {
off_t size; off_t size;
uint32_t codec; uint32_t codec;
int sample_rate; int sample_rate;
int channel_count; int channels;
uint32_t block_size; uint32_t block_size;
int bps; int bps;
off_t extra_size; off_t extra_size;
@ -95,38 +95,38 @@ typedef struct {
int is_at9; int is_at9;
} riff_fmt_chunk; } riff_fmt_chunk;
static int read_fmt(int big_endian, STREAMFILE* sf, off_t current_chunk, riff_fmt_chunk* fmt, int mwv) { static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk* fmt, int mwv) {
int32_t (*read_32bit)(off_t,STREAMFILE*) = big_endian ? read_32bitBE : read_32bitLE; uint32_t (*read_u32)(off_t,STREAMFILE*) = big_endian ? read_u32be : read_u32le;
int16_t (*read_16bit)(off_t,STREAMFILE*) = big_endian ? read_16bitBE : read_16bitLE; uint16_t (*read_u16)(off_t,STREAMFILE*) = big_endian ? read_u16be : read_u16le;
fmt->offset = current_chunk; fmt->offset = offset;
fmt->size = read_32bit(current_chunk+0x04,sf); fmt->size = read_u32(offset+0x04,sf);
/* WAVEFORMAT */ /* WAVEFORMAT */
fmt->codec = (uint16_t)read_16bit(current_chunk+0x08,sf); fmt->codec = read_u16(offset+0x08,sf);
fmt->channel_count = read_16bit(current_chunk+0x0a,sf); fmt->channels = read_u16(offset+0x0a,sf);
fmt->sample_rate = read_32bit(current_chunk+0x0c,sf); fmt->sample_rate = read_u32(offset+0x0c,sf);
//fmt->avg_bps = read_32bit(current_chunk+0x10,sf); //fmt->avg_bps = read_u32(offset+0x10,sf);
fmt->block_size = read_16bit(current_chunk+0x14,sf); fmt->block_size = read_u16(offset+0x14,sf);
fmt->bps = read_16bit(current_chunk+0x16,sf); fmt->bps = read_u16(offset+0x16,sf);
/* WAVEFORMATEX */ /* WAVEFORMATEX */
if (fmt->size >= 0x10) { 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) */ /* 0x1a+ depends on codec (ex. coef table for MSADPCM, samples_per_frame in MS-IMA, etc) */
} }
/* WAVEFORMATEXTENSIBLE */ /* WAVEFORMATEXTENSIBLE */
if (fmt->codec == 0xFFFE && fmt->extra_size >= 0x16) { 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->extra_samples = read_u16(offset+0x1a,sf); /* valid_bits_per_sample or samples_per_block */
fmt->channel_layout = read_32bit(current_chunk+0x1c,sf); fmt->channel_layout = read_u32(offset+0x1c,sf);
/* 0x10 guid at 0x20 */ /* 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 */ /* 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; 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)] */ /* 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; 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) { switch (fmt->codec) {
case 0x00: /* Yamaha AICA ADPCM [Headhunter (DC), Bomber hehhe (DC), Rayman 2 (DC)] (unofficial) */ case 0x00: /* Yamaha AICA ADPCM [Headhunter (DC), Bomber hehhe (DC), Rayman 2 (DC)] (unofficial) */
if (fmt->bps != 4) goto fail; if (fmt->bps != 4) goto fail;
if (fmt->block_size != 0x02*fmt->channel_count && if (fmt->block_size != 0x02*fmt->channels &&
fmt->block_size != 0x01*fmt->channel_count) goto fail; fmt->block_size != 0x01*fmt->channels) goto fail;
fmt->coding_type = coding_AICA_int; fmt->coding_type = coding_AICA_int;
fmt->interleave = 0x01; fmt->interleave = 0x01;
break; 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)) if (!msadpcm_check_coefs(sf, fmt->offset + 0x08 + 0x14))
goto fail; 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 */ fmt->coding_type = coding_IMA; /* MX vs ATV Unleashed (PC) codec hijack */
} }
else { 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) */ case 0x0300: /* IMA ADPCM [Chrono Ma:gia (Android)] (unofficial) */
if (fmt->bps != 4) goto fail; 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->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; fmt->coding_type = coding_DVI_IMA;
/* real 0x300 is "Fujitsu FM Towns SND" with block align 0x01 */ /* real 0x300 is "Fujitsu FM Towns SND" with block align 0x01 */
break; 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+) */ case 0x6771: /* Ogg Vorbis (mode 3+) */
fmt->coding_type = coding_OGG_VORBIS; fmt->coding_type = coding_OGG_VORBIS;
break; break;
#else
goto fail;
#endif #endif
case 0x0270: /* ATRAC3 */
#ifdef VGM_USE_FFMPEG #ifdef VGM_USE_FFMPEG
case 0x0270: /* ATRAC3 */
fmt->coding_type = coding_FFmpeg; fmt->coding_type = coding_FFmpeg;
fmt->is_at3 = 1; fmt->is_at3 = 1;
break; break;
#else
goto fail;
#endif #endif
case 0xFFFE: { /* WAVEFORMATEXTENSIBLE (see ksmedia.h for known GUIDs) */ case 0xFFFE: { /* WAVEFORMATEXTENSIBLE (see ksmedia.h for known GUIDs) */
uint32_t guid1 = (uint32_t)read_32bit (current_chunk+0x20,sf); uint32_t guid1 = read_u32 (offset+0x20,sf);
uint32_t guid2 = ((uint16_t)read_16bit (current_chunk+0x24,sf) << 16u) | uint32_t guid2 = (read_u16 (offset+0x24,sf) << 16u) |
((uint16_t)read_16bit (current_chunk+0x26,sf)); (read_u16 (offset+0x26,sf));
uint32_t guid3 = (uint32_t)read_32bitBE(current_chunk+0x28,sf); uint32_t guid3 = read_u32be(offset+0x28,sf);
uint32_t guid4 = (uint32_t)read_32bitBE(current_chunk+0x2c,sf); uint32_t guid4 = read_u32be(offset+0x2c,sf);
//;VGM_LOG("RIFF: guid %08x %08x %08x %08x\n", guid1, guid2, guid3, guid4); //;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) */ /* 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) */ /* ATRAC3plus GUID (0xE923AABF,CB58,4471,A1,19,FF,FA,01,E4,CE,62) */
if (guid1 == 0xE923AABF && guid2 == 0xCB584471 && guid3 == 0xA119FFFA && guid4 == 0x01E4CE62) { if (guid1 == 0xE923AABF && guid2 == 0xCB584471 && guid3 == 0xA119FFFA && guid4 == 0x01E4CE62) {
#ifdef VGM_USE_MAIATRAC3PLUS #ifdef VGM_USE_FFMPEG
uint16_t bztmp = read_16bit(current_chunk+0x32,sf); 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); bztmp = (bztmp >> 8) | (bztmp << 8);
fmt->coding_type = coding_AT3plus; fmt->coding_type = coding_AT3plus;
fmt->block_size = (bztmp & 0x3FF) * 8 + 8; /* should match fmt->block_size */ fmt->block_size = (bztmp & 0x3FF) * 8 + 8; /* should match fmt->block_size */
fmt->is_at3p = 1; fmt->is_at3p = 1;
break; break;
#elif defined(VGM_USE_FFMPEG)
fmt->coding_type = coding_FFmpeg;
fmt->is_at3p = 1;
break;
#else #else
goto fail; goto fail;
#endif #endif
} }
#ifdef VGM_USE_ATRAC9
/* ATRAC9 GUID (0x47E142D2,36BA,4D8D,88,FC,61,65,4F,8C,83,6C) */ /* ATRAC9 GUID (0x47E142D2,36BA,4D8D,88,FC,61,65,4F,8C,83,6C) */
if (guid1 == 0x47E142D2 && guid2 == 0x36BA4D8D && guid3 == 0x88FC6165 && guid4 == 0x4F8C836C) { if (guid1 == 0x47E142D2 && guid2 == 0x36BA4D8D && guid3 == 0x88FC6165 && guid4 == 0x4F8C836C) {
#ifdef VGM_USE_ATRAC9
fmt->coding_type = coding_ATRAC9; fmt->coding_type = coding_ATRAC9;
fmt->is_at9 = 1; fmt->is_at9 = 1;
break; break;
#else
goto fail;
#endif
} }
#endif
goto fail; /* unknown GUID */ 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 */ /* some games have wonky sizes, selectively fix to catch bad rips and new mutations */
if (file_size != riff_size + 0x08) { 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) if (codec == 0x6771 && riff_size + 0x08 + 0x01 == file_size)
riff_size += 0x01; /* [Shikkoku no Sharnoth (PC)] (Sony Sound Forge?) */ 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) */ riff_size += 0x18; /* [F1 2011 (Vita)] (adds a "pada" chunk but RIFF size wasn't updated) */
else if (mwv) { 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); 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 */ /* files inside HD6/DAT are also padded to 0x10 so need to fix file_size */
file_size = file_size_fixed; file_size = file_size_fixed;
riff_size = file_size - 0x08; riff_size = file_size - 0x08;
@ -617,7 +610,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
/* build the VGMSTREAM */ /* build the VGMSTREAM */
vgmstream = allocate_vgmstream(fmt.channel_count,loop_flag); vgmstream = allocate_vgmstream(fmt.channels,loop_flag);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
vgmstream->sample_rate = fmt.sample_rate; 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) */ /* samples, codec init (after setting coding to ensure proper close on failure) */
switch (fmt.coding_type) { switch (fmt.coding_type) {
case coding_PCM16LE: 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; break;
case coding_PCM8_U: case coding_PCM8_U:
@ -670,7 +663,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
case coding_L5_555: case coding_L5_555:
if (!mwv) goto fail; if (!mwv) goto fail;
vgmstream->num_samples = data_size / 0x12 / fmt.channel_count * 32; vgmstream->num_samples = data_size / 0x12 / fmt.channels * 32;
/* coefs */ /* coefs */
{ {
@ -684,7 +677,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
read_32bitLE(mwv_pflt_offset+0x04, sf) < 8 + filter_count * 4 * filter_order) read_32bitLE(mwv_pflt_offset+0x04, sf) < 8 + filter_count * 4 * filter_order)
goto fail; 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++) { for (i = 0; i < filter_count * filter_order; i++) {
int coef = read_32bitLE(mwv_pflt_offset+0x10+i*0x04, sf); int coef = read_32bitLE(mwv_pflt_offset+0x10+i*0x04, sf);
vgmstream->ch[ch].adpcm_coef_3by32[i] = coef; vgmstream->ch[ch].adpcm_coef_3by32[i] = coef;
@ -695,31 +688,31 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
break; break;
case coding_MSADPCM: 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) if (fact_sample_count && fact_sample_count < vgmstream->num_samples)
vgmstream->num_samples = fact_sample_count; vgmstream->num_samples = fact_sample_count;
break; break;
case coding_MS_IMA: 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) if (fact_sample_count && fact_sample_count < vgmstream->num_samples)
vgmstream->num_samples = fact_sample_count; vgmstream->num_samples = fact_sample_count;
break; break;
case coding_AICA: case coding_AICA:
case coding_AICA_int: 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; break;
case coding_XBOX_IMA: 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) if (fact_sample_count && fact_sample_count < vgmstream->num_samples)
vgmstream->num_samples = fact_sample_count; /* some (converted?) Xbox games have bigger fact_samples */ vgmstream->num_samples = fact_sample_count; /* some (converted?) Xbox games have bigger fact_samples */
break; break;
case coding_IMA: case coding_IMA:
case coding_DVI_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; break;
#ifdef VGM_USE_FFMPEG #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) { static int is_ue4_msadpcm(STREAMFILE* sf, riff_fmt_chunk* fmt, int fact_sample_count, off_t start) {
/* multichannel ok */ /* multichannel ok */
if (fmt->channel_count < 2) if (fmt->channels < 2)
goto fail; goto fail;
/* UE4 class is "ADPCM", assume it's the extension too */ /* 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 /* 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) */ * (could do it for fmt size 0x36 too but maybe they'll fix it in the future) */
while (offset <= max_offset) { 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; goto fail;
offset += fmt->block_size; offset += fmt->block_size;
} }
@ -916,7 +909,7 @@ fail:
/* for maximum annoyance later UE4 versions (~v4.2x?) interleave single frames instead of /* 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 */ * 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) { 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; size_t v2_interleave = fmt->block_size;
uint8_t nibbles1[0x08] = {0}; uint8_t nibbles1[0x08] = {0};
uint8_t nibbles2[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; return v1_interleave;
/* 6ch only observed in later versions [Fortnite (PC)], not padded */ /* 6ch only observed in later versions [Fortnite (PC)], not padded */
if (fmt->channel_count > 2) if (fmt->channels > 2)
return v2_interleave; return v2_interleave;
read_streamfile(nibbles1, start + size - 0x08, sizeof(nibbles2), sf); read_streamfile(nibbles1, start + size - 0x08, sizeof(nibbles2), sf);
@ -1053,7 +1046,7 @@ VGMSTREAM* init_vgmstream_rifx(STREAMFILE* sf) {
/* build the VGMSTREAM */ /* build the VGMSTREAM */
vgmstream = allocate_vgmstream(fmt.channel_count,loop_flag); vgmstream = allocate_vgmstream(fmt.channels,loop_flag);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
vgmstream->sample_rate = fmt.sample_rate; vgmstream->sample_rate = fmt.sample_rate;