Merge pull request #1567 from modusc896d352/ongakukan-adp-v3

fix some ongakukan .adp
This commit is contained in:
bnnm 2024-07-26 21:04:06 +02:00 committed by GitHub
commit e79e0bad3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -9,8 +9,8 @@ VGMSTREAM* init_vgmstream_adp_ongakukan(STREAMFILE* sf) {
bool sound_is_adpcm = false; bool sound_is_adpcm = false;
int32_t fmt_size, fmt_offset; int32_t fmt_size, fmt_offset;
int32_t sample_rate, data_size; int32_t sample_rate, data_size;
int16_t channels; int16_t channels;
int32_t expected_size, pcm_size, diff, fact_offset;
/* checks */ /* checks */
if (!is_id32be(0x00, sf, "RIFF")) if (!is_id32be(0x00, sf, "RIFF"))
@ -24,21 +24,22 @@ VGMSTREAM* init_vgmstream_adp_ongakukan(STREAMFILE* sf) {
data_size = get_streamfile_size(sf) - start_offset; data_size = get_streamfile_size(sf) - start_offset;
/* RIFF size seem to match original PCM .wav, while encoded .adp data equals or is slightly smaller that that */ /* RIFF size seem to match original PCM .wav, while encoded .adp data equals or is slightly smaller that that */
uint32_t expected_size = (read_u32le(0x04, sf) - 0x24); expected_size = (read_u32le(0x04, sf) - 0x24);
uint32_t pcm_size = data_size * 2 * sizeof(short); // * channels pcm_size = data_size * 2 * sizeof(short); // * channels
if (pcm_size > expected_size) diff = expected_size - pcm_size;
if (diff < 0 || diff > 14)
return NULL; return NULL;
if (!is_id32be(0x08, sf, "WAVE")) if (!is_id32be(0x08, sf, "WAVE"))
return NULL; return NULL;
if (!is_id32be(0x0c, sf, "fmt ")) if (!is_id32be(0x0c, sf, "fmt "))
return NULL; return NULL;
fmt_size = read_s32le(0x10, sf); fmt_size = read_s32le(0x10, sf);
/* depending on the adp, fmt_size alternates between 0x10 and 0x12 */ /* depending on the adp, fmt_size alternates between 0x10 and 0x12 */
if (fmt_size < 0x10 || fmt_size > 0x12) if (fmt_size < 0x10 || fmt_size > 0x12)
goto fail; goto fail;
fmt_offset = 0x14; fmt_offset = 0x14;
if (read_s16le(fmt_offset + 0x00, sf) != 0x0001) /* PCM format */ if (read_s16le(fmt_offset + 0x00, sf) != 0x0001) /* PCM format */
goto fail; goto fail;
@ -49,11 +50,17 @@ VGMSTREAM* init_vgmstream_adp_ongakukan(STREAMFILE* sf) {
if (read_s16le(fmt_offset + 0x0e, sf) != 16) /* PCM bit depth */ if (read_s16le(fmt_offset + 0x0e, sf) != 16) /* PCM bit depth */
goto fail; goto fail;
/* rest of fmt header is the usual header for 16-bit PCM wav files: bitrate, block size, and the like (see riff.c) */ /* rest of fmt header is the usual header for 16-bit PCM wav files: bitrate, block size, and the like (see riff.c) */
/* if fmt_size == 0x12 there may be is an additional s16 field that's always zero, but not always. */ /* if fmt_size == 0x12 there is an additional s16 field that may or may not be zero. */
/* next chunk is at fixed offset, regardless of fmt_size (fmt_size 0x12 with "data" at 0x24 is possible). /* depending on the adp, "fact" chunk is "movable" as we'll see later. */
* "data" has chunk size (does not match ADP size but original WAV) and "fact" chunk size 0x04 cut off) */ fact_offset = fmt_offset + fmt_size;
if (!is_id32be(0x24, sf, "data") && !is_id32be(0x26, sf, "fact")) if (fact_offset < 0x24 || fact_offset > 0x28)
goto fail;
/* for next chunk, if "data" then it's at fixed offset (0x24), regardless of fmt_size (fmt_size 0x12 with "data" at 0x24 is possible).
* if "fact" however, offset goes AFTER fmt_size (mostly 0x26 and rarely 0x24).
* "data" has chunk size (does not match ADP size but original WAV) and "fact" chunk size is always 0x04 (whether cut off or otherwise). */
if (!is_id32be(0x24, sf, "data") && !is_id32be(fact_offset, sf, "fact"))
goto fail; goto fail;
/* Ongagukan games using this format just read it by checking "ADP" extension in a provided file name, /* Ongagukan games using this format just read it by checking "ADP" extension in a provided file name,