mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
Wii BNS
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@689 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
896e91eefc
commit
53fdc56999
@ -106,6 +106,7 @@ GC/Wii DSP ADPCM:
|
||||
- .agsc
|
||||
- .amts
|
||||
- .asr
|
||||
- .bns
|
||||
- .cfn
|
||||
- .dsp
|
||||
- standard, with dual file stereo
|
||||
|
@ -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)
|
||||
|
||||
|
@ -790,6 +790,10 @@
|
||||
RelativePath=".\meta\vsf.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\wii_bns.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\wii_mus.c"
|
||||
>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
144
src/meta/wii_bns.c
Normal file
144
src/meta/wii_bns.c
Normal file
@ -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;i<channel_count;i++) {
|
||||
uint32_t channel_info_offset = info_offset + read_32bitBE(channel_info_offset_list_offset+4*i,streamFile);
|
||||
uint32_t channel_data_offset = data_offset + (uint32_t)read_32bitBE(channel_info_offset+0,streamFile);
|
||||
uint32_t channel_dsp_offset = info_offset + (uint32_t)read_32bitBE(channel_info_offset+4,streamFile);
|
||||
int j;
|
||||
|
||||
/* always been 0... */
|
||||
if (read_32bitBE(channel_info_offset+8,streamFile) != 0) goto fail;
|
||||
|
||||
vgmstream->ch[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;
|
||||
}
|
@ -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");
|
||||
}
|
||||
|
@ -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" */
|
||||
|
@ -186,6 +186,7 @@ gchar *vgmstream_exts [] = {
|
||||
"mxst",
|
||||
"sab",
|
||||
"sc",
|
||||
"bns",
|
||||
/* terminator */
|
||||
NULL
|
||||
};
|
||||
|
@ -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",
|
||||
|
Loading…
x
Reference in New Issue
Block a user