From a24f1c0337855efbaefb6b379b15bc0224a0e47e Mon Sep 17 00:00:00 2001 From: bxaimc Date: Thu, 21 Mar 2019 18:02:17 -0400 Subject: [PATCH 1/4] Add Team Ninja/Koei Tecmo Opus Variant --- src/meta/ktss.c | 69 +++++++++++++++++++++++++++++++------------------ 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/src/meta/ktss.c b/src/meta/ktss.c index 76339eb7..565599cf 100644 --- a/src/meta/ktss.c +++ b/src/meta/ktss.c @@ -4,10 +4,10 @@ VGMSTREAM * init_vgmstream_ktss(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; int loop_flag, channel_count; - int8_t version; + int8_t version, channelMultiplier, codec_id; int32_t loop_length, coef_start_offset, coef_spacing; off_t start_offset; - int8_t channelMultiplier; + size_t data_size, skip = 0; if (!check_extensions(streamFile, "kns,ktss")) goto fail; @@ -15,27 +15,15 @@ VGMSTREAM * init_vgmstream_ktss(STREAMFILE *streamFile) { if (read_32bitBE(0, streamFile) != 0x4B545353) /* "KTSS" */ goto fail; - /* check type details */ - version = read_8bit(0x22, streamFile); - if (version == 1) { - coef_start_offset = 0x40; - coef_spacing = 0x2e; - } - else if (version == 3) { // Fire Emblem Warriors (Switch) - coef_start_offset = 0x5c; - coef_spacing = 0x60; - } - else - goto fail; - + codec_id = read_32bitLE(0x20, streamFile); loop_length = read_32bitLE(0x38, streamFile); loop_flag = loop_length > 0; - // For unknown reasons, a channel multiplier is necessary in Hyrule Warriors (Switch) + // For reasons unknown, a channel multiplier exists in Hyrule Warriors (Switch) // It seems to be present in other Koei Tecmo KNS but the channel count was always // explicitly defined in the 0x29 byte. Here, 10 channel files have '2' in 0x29* // and '5' in 0x28 whereas previous titles usually contained '1' - // This is super meh on KT's part but whatever + // Super hacky on KT's part and ours to implement but it works. channelMultiplier = read_8bit(0x28, streamFile); channel_count = read_8bit(0x29, streamFile) * channelMultiplier; @@ -46,19 +34,50 @@ VGMSTREAM * init_vgmstream_ktss(STREAMFILE *streamFile) { /* fill in the vital statistics */ vgmstream->num_samples = read_32bitLE(0x30, streamFile); - vgmstream->sample_rate = (uint16_t)read_16bitLE(0x2c, streamFile); + vgmstream->sample_rate = read_32bitLE(0x2c, streamFile); vgmstream->loop_start_sample = read_32bitLE(0x34, streamFile); vgmstream->loop_end_sample = vgmstream->loop_start_sample + loop_length; - - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->layout_type = layout_interleave; vgmstream->meta_type = meta_KTSS; - - vgmstream->interleave_block_size = 0x8; - - dsp_read_coefs_le(vgmstream, streamFile, coef_start_offset, coef_spacing); start_offset = read_32bitLE(0x24, streamFile) + 0x20; + switch (codec_id) { + case 0x2: /* DSP ADPCM - Hyrule Warriors, Fire Emblem Warriors, and other Koei Tecmo games */ + /* check type details */ + version = read_8bit(0x22, streamFile); + if (version == 1) { + coef_start_offset = 0x40; + coef_spacing = 0x2e; + } + else if (version == 3) { // Fire Emblem Warriors (Switch) + coef_start_offset = 0x5c; + coef_spacing = 0x60; + } + else + goto fail; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x8; + dsp_read_coefs_le(vgmstream, streamFile, coef_start_offset, coef_spacing); + break; + +#ifdef VGM_USE_FFMPEG + case 0x9: /* Opus - Dead or Alive Xtreme 3: Scarlet */ + data_size = read_32bitLE(0x44, streamFile); + { + vgmstream->codec_data = init_ffmpeg_switch_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 = switch_opus_get_samples(start_offset, data_size, streamFile) - skip; + } + } + break; +#endif + } + if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) goto fail; return vgmstream; From e6208351d43bec67971d975356f619c74da58746 Mon Sep 17 00:00:00 2001 From: bxaimc Date: Thu, 21 Mar 2019 19:07:33 -0400 Subject: [PATCH 2/4] KTSS fixes --- src/meta/ktss.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/meta/ktss.c b/src/meta/ktss.c index 565599cf..b4ed2415 100644 --- a/src/meta/ktss.c +++ b/src/meta/ktss.c @@ -15,7 +15,7 @@ VGMSTREAM * init_vgmstream_ktss(STREAMFILE *streamFile) { if (read_32bitBE(0, streamFile) != 0x4B545353) /* "KTSS" */ goto fail; - codec_id = read_32bitLE(0x20, streamFile); + codec_id = read_8bit(0x20, streamFile); loop_length = read_32bitLE(0x38, streamFile); loop_flag = loop_length > 0; @@ -75,6 +75,10 @@ VGMSTREAM * init_vgmstream_ktss(STREAMFILE *streamFile) { } } break; + + case default: + goto fail; + break; #endif } From e994af85ab99d8226ab748a17b4f98e0b117972b Mon Sep 17 00:00:00 2001 From: bxaimc Date: Thu, 21 Mar 2019 19:18:26 -0400 Subject: [PATCH 3/4] change channelMultiplier to num_layers --- src/meta/ktss.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/meta/ktss.c b/src/meta/ktss.c index b4ed2415..0c82f7ca 100644 --- a/src/meta/ktss.c +++ b/src/meta/ktss.c @@ -4,7 +4,7 @@ VGMSTREAM * init_vgmstream_ktss(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; int loop_flag, channel_count; - int8_t version, channelMultiplier, codec_id; + int8_t version, num_layers, codec_id; int32_t loop_length, coef_start_offset, coef_spacing; off_t start_offset; size_t data_size, skip = 0; @@ -19,14 +19,14 @@ VGMSTREAM * init_vgmstream_ktss(STREAMFILE *streamFile) { loop_length = read_32bitLE(0x38, streamFile); loop_flag = loop_length > 0; - // For reasons unknown, a channel multiplier exists in Hyrule Warriors (Switch) - // It seems to be present in other Koei Tecmo KNS but the channel count was always - // explicitly defined in the 0x29 byte. Here, 10 channel files have '2' in 0x29* - // and '5' in 0x28 whereas previous titles usually contained '1' + // A layered stream/track model seems to be used in Hyrule Warriors (Switch). + // It's also present in other Koei Tecmo KNS but the channel count was always + // explicitly defined in the 0x29 byte and the number of layers was set to 1. + // Here, 10 channel files are set up with 2 channels in 5 layers. // Super hacky on KT's part and ours to implement but it works. - channelMultiplier = read_8bit(0x28, streamFile); + num_layers = read_8bit(0x28, streamFile); - channel_count = read_8bit(0x29, streamFile) * channelMultiplier; + channel_count = read_8bit(0x29, streamFile) * num_layers; /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count, loop_flag); From 3744cd52ceeb9e31fec22a51445df3acef56dbea Mon Sep 17 00:00:00 2001 From: bxaimc Date: Thu, 21 Mar 2019 19:21:55 -0400 Subject: [PATCH 4/4] KTSS fixes --- src/meta/ktss.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/meta/ktss.c b/src/meta/ktss.c index 0c82f7ca..02f36a47 100644 --- a/src/meta/ktss.c +++ b/src/meta/ktss.c @@ -76,9 +76,8 @@ VGMSTREAM * init_vgmstream_ktss(STREAMFILE *streamFile) { } break; - case default: + default: goto fail; - break; #endif }