From 53fdc569996548b1b5368e38ada9ad7e5f4304fe Mon Sep 17 00:00:00 2001 From: halleyscometsw Date: Sat, 5 Sep 2009 12:18:34 +0000 Subject: [PATCH] Wii BNS git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@689 51a99a44-fe44-0410-b1ba-c3e57ba2b86b --- readme.txt | 1 + src/Makefile | 3 +- src/libvgmstream.vcproj | 4 ++ src/meta/Makefile.unix.am | 1 + src/meta/meta.h | 2 + src/meta/wii_bns.c | 144 ++++++++++++++++++++++++++++++++++++++ src/vgmstream.c | 4 ++ src/vgmstream.h | 1 + unix/data.c | 1 + winamp/in_vgmstream.c | 3 +- 10 files changed, 162 insertions(+), 2 deletions(-) create mode 100644 src/meta/wii_bns.c diff --git a/readme.txt b/readme.txt index 758113e2..820a43b0 100644 --- a/readme.txt +++ b/readme.txt @@ -106,6 +106,7 @@ GC/Wii DSP ADPCM: - .agsc - .amts - .asr +- .bns - .cfn - .dsp - standard, with dual file stereo diff --git a/src/Makefile b/src/Makefile index cbb165d3..6352cfe7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -209,7 +209,8 @@ META_OBJS=meta/adx_header.o \ meta/apple_caff.o \ meta/pc_mxst.o \ meta/pc_sob.o \ - meta/exakt_sc.o + meta/exakt_sc.o \ + meta/wii_bns.o OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS) diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index d95ef6aa..5fa9cce1 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -790,6 +790,10 @@ RelativePath=".\meta\vsf.c" > + + diff --git a/src/meta/Makefile.unix.am b/src/meta/Makefile.unix.am index 383a6fc2..ccdbc45c 100644 --- a/src/meta/Makefile.unix.am +++ b/src/meta/Makefile.unix.am @@ -167,5 +167,6 @@ libmeta_la_SOURCES += apple_caff.c libmeta_la_SOURCES += pc_mxst.c libmeta_la_SOURCES += pc_sob.c libmeta_la_SOURCES += exakt_sc.c +libmeta_la_SOURCES += wii_bns.c EXTRA_DIST = meta.h diff --git a/src/meta/meta.h b/src/meta/meta.h index fa3b1940..1bb020e9 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -413,4 +413,6 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_exakt_sc(STREAMFILE* streamFile); +VGMSTREAM * init_vgmstream_wii_bns(STREAMFILE* streamFile); + #endif diff --git a/src/meta/wii_bns.c b/src/meta/wii_bns.c new file mode 100644 index 00000000..8b5356c6 --- /dev/null +++ b/src/meta/wii_bns.c @@ -0,0 +1,144 @@ +#include "meta.h" +#include "../coding/coding.h" +#include "../util.h" + +/* BNS - Wii "Banner Sound" disc jingle */ +VGMSTREAM * init_vgmstream_wii_bns(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + off_t BNS_offset; + uint32_t info_offset=0,data_offset=0; + uint32_t channel_info_offset_list_offset; + int channel_count; + uint16_t sample_rate; + uint32_t sample_count; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("bns",filename_extension(filename))) goto fail; + + // check header + BNS_offset = 0; + if (read_32bitBE(BNS_offset,streamFile) == 0x494D4435) // IMD5 + { + // Skip IMD5 header if present + BNS_offset = 0x20; + } + + if (read_32bitBE(BNS_offset+0x00,streamFile) != 0x424E5320) goto fail; // "BNS " + if ((uint32_t)read_32bitBE(BNS_offset+0x04,streamFile) != 0xFEFF0100u) goto fail; + + // find chunks, verify + { + // file size as claimed by header + uint32_t header_file_size = read_32bitBE(BNS_offset+0x08,streamFile); + + uint32_t header_size = read_16bitBE(BNS_offset+0xc,streamFile); + uint16_t chunk_count = read_16bitBE(BNS_offset+0xe,streamFile); + + int i; + + // assume BNS is the last thing in the file + if (header_file_size + BNS_offset != get_streamfile_size(streamFile)) + goto fail; + + for (i = 0; i < chunk_count; i++) { + uint32_t chunk_info_offset = BNS_offset+0x10+i*8; + uint32_t chunk_offset, chunk_size; + + // ensure chunk info is within header + if (chunk_info_offset+8 > BNS_offset+header_size) goto fail; + + chunk_offset = BNS_offset + (uint32_t)read_32bitBE(chunk_info_offset,streamFile); + chunk_size = (uint32_t)read_32bitBE(chunk_info_offset+4,streamFile); + + // ensure chunk is within file + if (chunk_offset < BNS_offset+header_size || + chunk_offset+chunk_size > BNS_offset+header_file_size) goto fail; + + // ensure chunk size in header matches that listed in chunk + if ((uint32_t)read_32bitBE(chunk_offset+4,streamFile) != chunk_size) goto fail; + + // handle each chunk type + switch (read_32bitBE(chunk_offset,streamFile)) { + case 0x494E464F: // INFO + info_offset = chunk_offset+8; + break; + case 0x44415441: // DATA + data_offset = chunk_offset+8; + break; + default: + goto fail; + } + } + + /* need both INFO and DATA */ + if (!info_offset || !data_offset) goto fail; + } + + /* parse out basic stuff in INFO */ + { + /* only seen this zero, possibly format, loop flag? */ + if (read_16bitBE(info_offset+0x00,streamFile) != 0) goto fail; + + channel_count = read_8bit(info_offset+0x02,streamFile); + + /* only seen zero, padding? loop flag? */ + if (read_8bit(info_offset+0x03,streamFile) != 0) goto fail; + + sample_rate = (uint16_t)read_16bitBE(info_offset+0x04,streamFile); + + /* only seen this zero, padding? */ + if (read_16bitBE(info_offset+0x06,streamFile) != 0) goto fail; + + /* only seen this zero, loop start? */ + if (read_32bitBE(info_offset+0x08,streamFile) != 0) goto fail; + + sample_count = read_32bitBE(info_offset+0x0c,streamFile); + + channel_info_offset_list_offset = info_offset + (uint32_t)read_32bitBE(info_offset+0x10,streamFile); + } + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,0); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->channels = channel_count; + vgmstream->sample_rate = sample_rate; + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->num_samples = sample_count; + vgmstream->layout_type = layout_none; + vgmstream->meta_type = meta_WII_BNS; + + /* open the file for reading */ + { + 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=channel_data_offset; + + for (j=0;j<16;j++) + vgmstream->ch[i].adpcm_coef[j] = + read_16bitBE(channel_dsp_offset+j*2,streamFile); + } + } + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index 5c67c752..6eea39cc 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -226,6 +226,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_pc_mxst, init_vgmstream_sab, init_vgmstream_exakt_sc, + init_vgmstream_wii_bns, }; #define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0])) @@ -2307,6 +2308,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_EXAKT_SC: snprintf(temp,TEMPSIZE,"assumed Activision / EXAKT SC by extension"); break; + case meta_WII_BNS: + snprintf(temp,TEMPSIZE,"Nintendo BNS header"); + break; default: snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET"); } diff --git a/src/vgmstream.h b/src/vgmstream.h index 49eca30a..97c12919 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -192,6 +192,7 @@ typedef enum { meta_RSTM_shrunken, /* Atlus' mutant shortened RSTM */ meta_NDS_SWAV, /* Asphalt Urban GT 1 & 2 */ meta_NDS_RRDS, /* Ridge Racer DS */ + meta_WII_BNS, /* Wii BNS Banner Sound (similar to RSTM) */ /* CRI ADX */ meta_ADX_03, /* ADX "type 03" */ diff --git a/unix/data.c b/unix/data.c index d3ad271b..d9279092 100644 --- a/unix/data.c +++ b/unix/data.c @@ -186,6 +186,7 @@ gchar *vgmstream_exts [] = { "mxst", "sab", "sc", + "bns", /* terminator */ NULL }; diff --git a/winamp/in_vgmstream.c b/winamp/in_vgmstream.c index 619a27a5..23b73844 100644 --- a/winamp/in_vgmstream.c +++ b/winamp/in_vgmstream.c @@ -80,7 +80,7 @@ char * extension_list[] = { "pdt\0PDT Audio File (*.PDT)\0", /* Mario Party and some other games */ #endif - "2dx\0\2DX Audio File (*.2DX)\0", + "2dx\0""2DX Audio File (*.2DX)\0", "aax\0AAX Audio File (*.AAX)\0", "acm\0ACM Audio File (*.ACM)\0", @@ -108,6 +108,7 @@ char * extension_list[] = { "bg00\0BG00 Audio File (*.BG00)\0", "bgw\0BGW Audio File (*.BGW)\0", "bmdx\0BMDX Audio File (*.BMDX)\0", + "bns\0BNS Audio File (*.BNS)\0", "brstm;brstmspm\0BRSTM Audio File (*.BRSTM)\0", "caf\0CAF Audio File (*.CAF)\0",