From 1d2e9793e5ad43874c1fe054853d4285cc3e97ef Mon Sep 17 00:00:00 2001 From: bxaimc Date: Wed, 26 Jun 2019 02:26:44 -0400 Subject: [PATCH] Add preliminary BWAV support [Super Mario Maker 2 (Switch)] --- src/formats.c | 2 ++ src/meta/bwav.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ src/meta/meta.h | 2 ++ src/vgmstream.c | 1 + src/vgmstream.h | 1 + 5 files changed, 68 insertions(+) create mode 100644 src/meta/bwav.c diff --git a/src/formats.c b/src/formats.c index 6aec9876..bb47f437 100644 --- a/src/formats.c +++ b/src/formats.c @@ -101,6 +101,7 @@ static const char* extension_list[] = { "brstmspm", "btsnd", "bvg", + "bwav", "caf", "capdsp", @@ -1189,6 +1190,7 @@ static const meta_info meta_info_list[] = { {meta_MSF_KONAMI, "Konami MSF header"}, {meta_XWMA_KONAMI, "Konami XWMA header"}, {meta_9TAV, "Konami 9TAV header"}, + {meta_BWAV, "Nintendo BWAV header"}, }; diff --git a/src/meta/bwav.c b/src/meta/bwav.c new file mode 100644 index 00000000..2dbaa178 --- /dev/null +++ b/src/meta/bwav.c @@ -0,0 +1,62 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* BWAV - NintendoWare(?) [Super Mario Maker 2 (Switch)] */ +VGMSTREAM * init_vgmstream_bwav(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int channel_count, loop_flag; + int big_endian; + size_t interleave = 0; + int32_t coef_start_offset, coef_spacing; + int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; + int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL; + + /* checks */ + if (!check_extensions(streamFile, "bwav")) + goto fail; + + /* BWAV header */ + if (read_32bitBE(0x00, streamFile) != 0x42574156) /* "BWAV" */ + goto fail; + + if ((uint16_t)read_16bitBE(0x04, streamFile) == 0xFEFF) { /* BE BOM check */ + read_32bit = read_32bitBE; + read_16bit = read_16bitBE; + big_endian = 1; + } else if ((uint16_t)read_16bitBE(0x04, streamFile) == 0xFFFE) { /* LE BOM check */ + read_32bit = read_32bitLE; + read_16bit = read_16bitLE; + big_endian = 0; + } else { + goto fail; + } + + channel_count = 1; //read_8bit(0x0E, streamFile); Needs to be checked + start_offset = read_32bit(0x40, streamFile); + loop_flag = 0; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_32bit(0x14, streamFile); + vgmstream->num_samples = read_32bit(0x18, streamFile); + vgmstream->meta_type = meta_BWAV; + vgmstream->layout_type = (channel_count == 1) ? layout_none : layout_interleave; + vgmstream->interleave_block_size = 0x08; //Maybe half-file? Needs to be checked + vgmstream->coding_type = coding_NGC_DSP; + + coef_start_offset = 0x20; + coef_spacing = 0x4C; + dsp_read_coefs_le(vgmstream, streamFile, coef_start_offset, coef_spacing); + + + if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/meta.h b/src/meta/meta.h index a1111095..1eb4c1e8 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -854,4 +854,6 @@ VGMSTREAM * init_vgmstream_9tav(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_fsb5_fev_bank(STREAMFILE * streamFile); +VGMSTREAM * init_vgmstream_bwav(STREAMFILE * streamFile); + #endif /*_META_H*/ diff --git a/src/vgmstream.c b/src/vgmstream.c index 1cd0be53..c39385ef 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -480,6 +480,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = { init_vgmstream_xwma_konami, init_vgmstream_9tav, init_vgmstream_fsb5_fev_bank, + init_vgmstream_bwav, /* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */ init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */ diff --git a/src/vgmstream.h b/src/vgmstream.h index 3ee515ad..f2c480cf 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -730,6 +730,7 @@ typedef enum { meta_MSF_KONAMI, meta_XWMA_KONAMI, meta_9TAV, + meta_BWAV, } meta_t;