diff --git a/src/meta/btsnd.c b/src/meta/btsnd.c index b0afa30f..8a670140 100644 --- a/src/meta/btsnd.c +++ b/src/meta/btsnd.c @@ -1,68 +1,53 @@ -/* -Wii U boot sound file for each game/app. -*/ - -#include "meta.h" -#include "../util.h" - -VGMSTREAM * init_vgmstream_btsnd(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - int channel_count = 2; - int loop_flag; - off_t start_offset = 0x8; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile, filename, sizeof(filename)); - if (strcasecmp("btsnd", filename_extension(filename))) - goto fail; - - /* Checking for loop start */ - if (read_32bitBE(0x4, streamFile) > 0) - loop_flag = 1; - else - loop_flag = 0; - - if (channel_count < 1) goto fail; - - /* build the VGMSTREAM */ - - vgmstream = allocate_vgmstream(channel_count, loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - vgmstream->sample_rate = 48000; - /* channels and loop flag are set by allocate_vgmstream */ - - // There's probably a better way to get the sample count... - vgmstream->num_samples = vgmstream->loop_end_sample = (get_streamfile_size(streamFile) - 8) / 4; - - vgmstream->loop_start_sample = read_32bitBE(0x4, streamFile); - - vgmstream->coding_type = coding_PCM16BE; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x2; // Constant for this format - vgmstream->meta_type = meta_WIIU_BTSND; - - /* open the file for reading by each channel */ - { - int i; - for (i = 0; ich[i].streamfile = streamFile->open(streamFile, filename, - STREAMFILE_DEFAULT_BUFFER_SIZE); - - if (!vgmstream->ch[i].streamfile) goto fail; - - vgmstream->ch[i].channel_start_offset = - vgmstream->ch[i].offset = - start_offset + i*vgmstream->interleave_block_size; - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + +/* .btsnd - Wii U boot sound file for each game/app */ +VGMSTREAM* init_vgmstream_btsnd(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + int channels, loop_flag; + off_t start_offset, data_size; + int32_t num_samples, loop_start; + + + /* checks */ + if (!check_extensions(sf, "btsnd")) + goto fail; + + if (read_u32be(0x00,sf) != 0x02) + goto fail; + + loop_start = read_s32be(0x04, sf); + start_offset = 0x08; + + channels = 2; + loop_flag = loop_start > 0; + + /* extra check since format is so simple */ + data_size = get_streamfile_size(sf); + num_samples = pcm16_bytes_to_samples(data_size - start_offset, channels); + if (loop_start >= num_samples) + goto fail; + + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_WIIU_BTSND; + vgmstream->sample_rate = 48000; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = vgmstream->num_samples; + + vgmstream->coding_type = coding_PCM16BE; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x02; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/musc.c b/src/meta/musc.c index 0e80203b..3ffa5537 100644 --- a/src/meta/musc.c +++ b/src/meta/musc.c @@ -1,50 +1,50 @@ -#include "meta.h" -#include "../util.h" -#include "../coding/coding.h" -#include "../layout/layout.h" - -/* MUSC - from Krome's PS2 games (The Legend of Spyro, Ty the Tasmanian Tiger) */ -VGMSTREAM * init_vgmstream_musc(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - int loop_flag, channel_count; - off_t start_offset; - size_t data_size; - - /* .mus is the real extension, .musc is the header ID */ - if (!check_extensions(streamFile,"mus,musc")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x4D555343) /* "MUSC" */ - goto fail; - - start_offset = read_32bitLE(0x10,streamFile); - data_size = read_32bitLE(0x14,streamFile); - if (start_offset + data_size != get_streamfile_size(streamFile)) - goto fail; - /* always does full loops unless it ends in silence */ - loop_flag = read_32bitBE(get_streamfile_size(streamFile) - 0x10,streamFile) != 0x0C000000; - channel_count = 2; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = (uint16_t)read_16bitLE(0x06,streamFile); - vgmstream->num_samples = ps_bytes_to_samples(data_size, channel_count); - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = vgmstream->num_samples; - - vgmstream->meta_type = meta_MUSC; - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = read_32bitLE(0x18,streamFile) / 2; - - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" +#include "../layout/layout.h" + +/* MUSC - from Krome's PS2 games (The Legend of Spyro, Ty the Tasmanian Tiger) */ +VGMSTREAM* init_vgmstream_musc(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + int loop_flag, channels; + off_t start_offset; + size_t data_size; + + + /* checks */ + /* .mus: actual extension + * .musc: header ID */ + if (!check_extensions(sf,"mus,musc")) + goto fail; + if (!is_id32be(0x00,sf, "MUSC")) + goto fail; + + start_offset = read_u32le(0x10,sf); + data_size = read_u32le(0x14,sf); + if (start_offset + data_size != get_streamfile_size(sf)) + goto fail; + /* always does full loops unless it ends in silence */ + loop_flag = read_u32be(get_streamfile_size(sf) - 0x10,sf) != 0x0C000000; + channels = 2; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_u16le(0x06,sf); + vgmstream->num_samples = ps_bytes_to_samples(data_size, channels); + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = vgmstream->num_samples; + + vgmstream->meta_type = meta_MUSC; + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = read_u32le(0x18,sf) / 2; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index fa85e4d6..cdae5044 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -24,7 +24,6 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_bfwav, init_vgmstream_bfstm, init_vgmstream_mca, - init_vgmstream_btsnd, init_vgmstream_nds_strm, init_vgmstream_agsc, init_vgmstream_ngc_adpdtk, @@ -533,6 +532,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { /* 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 */ init_vgmstream_encrypted, /* encrypted stuff */ + init_vgmstream_btsnd, /* semi-headerless */ init_vgmstream_raw_int, /* .int raw PCM */ init_vgmstream_ps_headerless, /* tries to detect a bunch of PS-ADPCM formats */ init_vgmstream_raw_snds, /* .snds raw SNDS IMA (*after* ps_headerless) */