mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
CWAV for 3DS, added as a modification to Wii RWAV/RWAR/RWSD
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@993 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
a4bb71f17d
commit
bed971faf8
@ -294,10 +294,12 @@ bool input_vgmstream::g_is_our_path(const char * p_path,const char * p_extension
|
||||
if(!stricmp_utf8(p_extension,"baka")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"baf")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bar")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bcwav")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bg00")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bgw")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bh2pcm")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bmdx")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bms")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bnk")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bns")) return 1;
|
||||
if(!stricmp_utf8(p_extension,"bnsf")) return 1;
|
||||
@ -610,10 +612,12 @@ DECLARE_MULTIPLE_FILE_TYPE("AUS Audio File (*.AUS)", aus);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BAKA Audio File (*.BAKA)", baka);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BAF Audio File (*.BAF)", baf);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BAR Audio File (*.BAR)", bar);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BCWAV Audio File (*.BCWAV)", bcwav);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BG00 Audio File (*.BG00)", bg00);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BGW Audio File (*.BGW)", bgw);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BH2PCM Audio File (*.BH2PCM)", bh2pcm);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BMDX Audio File (*.BMDX)", bmdx);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BMS Audio File (*.BMS)", bms);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("KLBS Audio File (*.BNK)", bnk);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BNS Audio File (*.BNS)", bns);
|
||||
DECLARE_MULTIPLE_FILE_TYPE("BNSF Audio File (*.BNSF)", bnsf);
|
||||
|
295
src/meta/rwsd.c
295
src/meta/rwsd.c
@ -2,48 +2,86 @@
|
||||
#include "../coding/coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
static off_t read_rwav(off_t offset, int *version, off_t *start_offset, off_t *info_chunkp, STREAMFILE *streamFile)
|
||||
/* Wii RWAV, 3DS CWAV */
|
||||
|
||||
struct rwav_data {
|
||||
// in
|
||||
off_t offset;
|
||||
STREAMFILE *streamFile;
|
||||
int big_endian;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*);
|
||||
|
||||
// out
|
||||
int version;
|
||||
off_t start_offset;
|
||||
off_t info_chunk;
|
||||
off_t wave_offset;
|
||||
};
|
||||
|
||||
static void read_rwav(struct rwav_data * rd)
|
||||
{
|
||||
off_t chunk_table_offset;
|
||||
off_t chunk_table_step;
|
||||
off_t info_chunk;
|
||||
off_t data_chunk;
|
||||
off_t wave_offset;
|
||||
|
||||
if ((uint32_t)read_32bitBE(offset,streamFile)!=0x52574156) /* "RWAV" */
|
||||
goto fail;
|
||||
if ((uint32_t)read_32bitBE(offset+4,streamFile)!=0xFEFF0102) /* version 2 */
|
||||
goto fail;
|
||||
if (rd->big_endian)
|
||||
{
|
||||
/* "RWAV" */
|
||||
if ((uint32_t)read_32bitBE(rd->offset,rd->streamFile)!=0x52574156)
|
||||
return;
|
||||
|
||||
info_chunk = offset+read_32bitBE(offset+0x10,streamFile);
|
||||
if ((uint32_t)read_32bitBE(info_chunk,streamFile)!=0x494e464f) /* "INFO" */
|
||||
goto fail;
|
||||
data_chunk = offset+read_32bitBE(offset+0x18,streamFile);
|
||||
if ((uint32_t)read_32bitBE(data_chunk,streamFile)!=0x44415441) /* "DATA" */
|
||||
goto fail;
|
||||
/* big endian, version 2 */
|
||||
if ((uint32_t)read_32bitBE(rd->offset+4,rd->streamFile)!=0xFEFF0102)
|
||||
return;
|
||||
|
||||
*start_offset = data_chunk + 8;
|
||||
*info_chunkp = info_chunk + 8;
|
||||
*version = 2;
|
||||
wave_offset = info_chunk - 8;
|
||||
chunk_table_offset = rd->offset+0x10;
|
||||
chunk_table_step = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* "CWAV" */
|
||||
if ((uint32_t)read_32bitBE(rd->offset,rd->streamFile)!=0x43574156)
|
||||
return;
|
||||
|
||||
return wave_offset;
|
||||
fail:
|
||||
return -1;
|
||||
/* little endian, version 2 */
|
||||
if ((uint32_t)read_32bitBE(rd->offset+4,rd->streamFile)!=0xFFFE4000 ||
|
||||
(uint32_t)read_32bitBE(rd->offset+8,rd->streamFile)!=0x00000102)
|
||||
return;
|
||||
|
||||
chunk_table_offset = rd->offset+0x18;
|
||||
chunk_table_step = 0xc;
|
||||
}
|
||||
|
||||
info_chunk = rd->offset+rd->read_32bit(chunk_table_offset,rd->streamFile);
|
||||
/* "INFO" */
|
||||
if ((uint32_t)read_32bitBE(info_chunk,rd->streamFile)!=0x494e464f)
|
||||
return;
|
||||
|
||||
data_chunk = rd->offset+rd->read_32bit(chunk_table_offset+chunk_table_step,rd->streamFile);
|
||||
/* "DATA" */
|
||||
if ((uint32_t)read_32bitBE(data_chunk,rd->streamFile)!=0x44415441)
|
||||
return;
|
||||
|
||||
rd->start_offset = data_chunk + 8;
|
||||
rd->info_chunk = info_chunk + 8;
|
||||
rd->version = 2;
|
||||
rd->wave_offset = info_chunk - 8; // pretend to have a WAVE
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static off_t read_rwar(off_t offset, int *version, off_t *start_offset, off_t *info_chunk, STREAMFILE *streamFile)
|
||||
static void read_rwar(struct rwav_data * rd)
|
||||
{
|
||||
off_t wave_offset;
|
||||
if ((uint32_t)read_32bitBE(offset,streamFile)!=0x52574152) /* "RWAR" */
|
||||
goto fail;
|
||||
if ((uint32_t)read_32bitBE(offset+4,streamFile)!=0xFEFF0100) /* version 0 */
|
||||
goto fail;
|
||||
if ((uint32_t)read_32bitBE(rd->offset,rd->streamFile)!=0x52574152) /* "RWAR" */
|
||||
return;
|
||||
if ((uint32_t)read_32bitBE(rd->offset+4,rd->streamFile)!=0xFEFF0100) /* version 0 */
|
||||
return;
|
||||
|
||||
wave_offset = read_rwav(offset+0x60,version,start_offset,info_chunk,streamFile);
|
||||
*version = 0;
|
||||
return wave_offset;
|
||||
|
||||
fail:
|
||||
return -1;
|
||||
rd->offset += 0x60;
|
||||
read_rwav(rd);
|
||||
rd->version = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* RWSD is quite similar to BRSTM, but can contain several streams.
|
||||
@ -55,50 +93,88 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
|
||||
coding_t coding_type;
|
||||
|
||||
off_t info_chunk;
|
||||
off_t wave_offset;
|
||||
size_t wave_length;
|
||||
int codec_number;
|
||||
int channel_count;
|
||||
int loop_flag;
|
||||
int rwar = 0;
|
||||
int rwav = 0;
|
||||
int version = -1;
|
||||
struct rwav_data rwav_data;
|
||||
|
||||
off_t start_offset = 0;
|
||||
size_t stream_size;
|
||||
|
||||
int big_endian = 1;
|
||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
|
||||
|
||||
const char *ext;
|
||||
|
||||
rwav_data.version = -1;
|
||||
rwav_data.start_offset = 0;
|
||||
rwav_data.info_chunk = -1;
|
||||
rwav_data.wave_offset = -1;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("rwsd",filename_extension(filename)))
|
||||
|
||||
ext = filename_extension(filename);
|
||||
|
||||
if (strcasecmp("rwsd",ext))
|
||||
{
|
||||
if (strcasecmp("rwar",filename_extension(filename)))
|
||||
if (strcasecmp("rwar",ext))
|
||||
{
|
||||
if (strcasecmp("rwav",filename_extension(filename)))
|
||||
if (strcasecmp("rwav",ext))
|
||||
{
|
||||
goto fail;
|
||||
if (strcasecmp("bcwav",ext) && strcasecmp("bms",ext))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
// cwav, similar to little endian rwav
|
||||
rwav = 1;
|
||||
big_endian = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// matched rwav
|
||||
rwav = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// matched rwar
|
||||
rwar = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// match rwsd
|
||||
}
|
||||
|
||||
if (big_endian)
|
||||
{
|
||||
read_16bit = read_16bitBE;
|
||||
read_32bit = read_32bitBE;
|
||||
}
|
||||
else
|
||||
{
|
||||
read_16bit = read_16bitLE;
|
||||
read_32bit = read_32bitLE;
|
||||
}
|
||||
|
||||
/* check header */
|
||||
if (rwar)
|
||||
if (rwar || rwav)
|
||||
{
|
||||
wave_offset = read_rwar(0,&version,&start_offset,&info_chunk,streamFile);
|
||||
if (wave_offset < 0) goto fail;
|
||||
}
|
||||
else if (rwav)
|
||||
{
|
||||
wave_offset = read_rwav(0,&version,&start_offset,&info_chunk,streamFile);
|
||||
if (wave_offset < 0) goto fail;
|
||||
rwav_data.offset = 0;
|
||||
rwav_data.streamFile = streamFile;
|
||||
rwav_data.big_endian = big_endian;
|
||||
rwav_data.read_32bit = read_32bit;
|
||||
|
||||
if (rwar) read_rwar(&rwav_data);
|
||||
if (rwav) read_rwav(&rwav_data);
|
||||
if (rwav_data.wave_offset < 0) goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -111,24 +187,29 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
/* ideally we would look through the chunk list for a WAVE chunk,
|
||||
* but it's always in the same order */
|
||||
/* get WAVE offset, check */
|
||||
wave_offset = read_32bitBE(0x18,streamFile);
|
||||
if ((uint32_t)read_32bitBE(wave_offset,streamFile)!=0x57415645) /* "WAVE" */
|
||||
rwav_data.wave_offset = read_32bit(0x18,streamFile);
|
||||
if ((uint32_t)read_32bitBE(rwav_data.wave_offset,streamFile)!=0x57415645) /* "WAVE" */
|
||||
goto fail;
|
||||
/* get WAVE size, check */
|
||||
wave_length = read_32bitBE(0x1c,streamFile);
|
||||
if (read_32bitBE(wave_offset+4,streamFile)!=wave_length)
|
||||
wave_length = read_32bit(0x1c,streamFile);
|
||||
if (read_32bit(rwav_data.wave_offset+4,streamFile)!=wave_length)
|
||||
goto fail;
|
||||
|
||||
/* check wave count */
|
||||
if (read_32bitBE(wave_offset+8,streamFile) != 1)
|
||||
if (read_32bit(rwav_data.wave_offset+8,streamFile) != 1)
|
||||
goto fail; /* only support 1 */
|
||||
|
||||
version = 2;
|
||||
rwav_data.version = 2;
|
||||
|
||||
break;
|
||||
case 0xFEFF0103:
|
||||
wave_offset = read_rwar(0xe0,&version,&start_offset,&info_chunk,streamFile);
|
||||
if (wave_offset < 0) goto fail;
|
||||
rwav_data.offset = 0xe0;
|
||||
rwav_data.streamFile = streamFile;
|
||||
rwav_data.big_endian = big_endian;
|
||||
rwav_data.read_32bit = read_32bit;
|
||||
|
||||
read_rwar(&rwav_data);
|
||||
if (rwav_data.wave_offset < 0) goto fail;
|
||||
|
||||
rwar = 1;
|
||||
break;
|
||||
@ -139,20 +220,29 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
}
|
||||
|
||||
/* get type details */
|
||||
codec_number = read_8bit(wave_offset+0x10,streamFile);
|
||||
loop_flag = read_8bit(wave_offset+0x11,streamFile);
|
||||
channel_count = read_8bit(wave_offset+0x12,streamFile);
|
||||
codec_number = read_8bit(rwav_data.wave_offset+0x10,streamFile);
|
||||
loop_flag = read_8bit(rwav_data.wave_offset+0x11,streamFile);
|
||||
if (big_endian)
|
||||
channel_count = read_8bit(rwav_data.wave_offset+0x12,streamFile);
|
||||
else
|
||||
channel_count = read_32bit(rwav_data.wave_offset+0x24,streamFile);
|
||||
|
||||
switch (codec_number) {
|
||||
case 0:
|
||||
coding_type = coding_PCM8;
|
||||
break;
|
||||
case 1:
|
||||
coding_type = coding_PCM16BE;
|
||||
if (big_endian)
|
||||
coding_type = coding_PCM16BE;
|
||||
else
|
||||
coding_type = coding_PCM16LE;
|
||||
break;
|
||||
case 2:
|
||||
coding_type = coding_NGC_DSP;
|
||||
break;
|
||||
case 3:
|
||||
coding_type = coding_IMA;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
@ -165,10 +255,10 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->num_samples = dsp_nibbles_to_samples(read_32bitBE(wave_offset+0x1c,streamFile));
|
||||
vgmstream->sample_rate = (uint16_t)read_16bitBE(wave_offset+0x14,streamFile);
|
||||
vgmstream->num_samples = dsp_nibbles_to_samples(read_32bit(rwav_data.wave_offset+0x1c,streamFile));
|
||||
vgmstream->sample_rate = (uint16_t)read_16bit(rwav_data.wave_offset+0x14,streamFile);
|
||||
/* channels and loop flag are set by allocate_vgmstream */
|
||||
vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bitBE(wave_offset+0x18,streamFile));
|
||||
vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bit(rwav_data.wave_offset+0x18,streamFile));
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
|
||||
vgmstream->coding_type = coding_type;
|
||||
@ -177,35 +267,73 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
if (rwar)
|
||||
vgmstream->meta_type = meta_RWAR;
|
||||
else if (rwav)
|
||||
vgmstream->meta_type = meta_RWAV;
|
||||
{
|
||||
if (big_endian)
|
||||
vgmstream->meta_type = meta_RWAV;
|
||||
else
|
||||
vgmstream->meta_type = meta_CWAV;
|
||||
}
|
||||
else
|
||||
vgmstream->meta_type = meta_RWSD;
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
off_t coef_offset;
|
||||
{
|
||||
off_t data_start_offset;
|
||||
off_t codec_info_offset;
|
||||
int i,j;
|
||||
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
if (rwar || rwav)
|
||||
{
|
||||
if (big_endian)
|
||||
{
|
||||
/* This is pretty nasty, so an explaination is in order.
|
||||
* At 0x10 in the info_chunk is the offset of a table with
|
||||
* one entry per channel. Each entry in this table is itself
|
||||
* an offset to a set of information for the channel. The
|
||||
* first element in the set is the offset into DATA of the
|
||||
* channel. The stream_size read far below just happens to
|
||||
* hit on this properly for stereo. The second element is the
|
||||
* offset of the coefficient table for the channel. */
|
||||
coef_offset = info_chunk +
|
||||
read_32bitBE(info_chunk +
|
||||
read_32bitBE(info_chunk+
|
||||
read_32bitBE(info_chunk+0x10,streamFile)+j*4,
|
||||
streamFile) + 4, streamFile);
|
||||
* channel.
|
||||
* The second element is the
|
||||
* offset of the codec-specific setup for the channel. */
|
||||
|
||||
off_t channel_info_offset;
|
||||
channel_info_offset = rwav_data.info_chunk +
|
||||
read_32bit(rwav_data.info_chunk+
|
||||
read_32bit(rwav_data.info_chunk+0x10,streamFile)+j*4,
|
||||
streamFile);
|
||||
|
||||
data_start_offset = rwav_data.start_offset +
|
||||
read_32bit(channel_info_offset+0, streamFile);
|
||||
codec_info_offset = rwav_data.info_chunk +
|
||||
read_32bit(channel_info_offset+4, streamFile);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// CWAV uses some relative offsets
|
||||
off_t cur_pos = rwav_data.info_chunk + 0x14; // channel count
|
||||
cur_pos = cur_pos + read_32bit(cur_pos + 4 + j*8 + 4,streamFile);
|
||||
|
||||
// size is at cur_pos + 4
|
||||
data_start_offset = rwav_data.start_offset + read_32bit(cur_pos + 4, streamFile);
|
||||
// codec-specific info is at cur_pos + 0xC
|
||||
codec_info_offset = cur_pos + read_32bit(cur_pos + 0xC,streamFile);
|
||||
}
|
||||
vgmstream->ch[j].channel_start_offset=
|
||||
vgmstream->ch[j].offset=data_start_offset;
|
||||
} else {
|
||||
coef_offset=wave_offset+0x6c+j*0x30;
|
||||
// dummy for RWSD, must be a proper way to work this out
|
||||
codec_info_offset=rwav_data.wave_offset+0x6c+j*0x30;
|
||||
}
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(coef_offset+i*2,streamFile);
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i]=read_16bit(codec_info_offset+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_IMA) {
|
||||
vgmstream->ch[j].adpcm_history1_16 = read_16bit(codec_info_offset,streamFile);
|
||||
vgmstream->ch[j].adpcm_step_index = read_16bit(codec_info_offset+2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,10 +344,10 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (version == 2)
|
||||
start_offset = read_32bitBE(8,streamFile);
|
||||
if (rwav_data.version == 2)
|
||||
rwav_data.start_offset = read_32bit(8,streamFile);
|
||||
}
|
||||
stream_size = read_32bitBE(wave_offset+0x50,streamFile);
|
||||
stream_size = read_32bit(rwav_data.wave_offset+0x50,streamFile);
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
@ -230,9 +358,12 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=
|
||||
start_offset + i*stream_size;
|
||||
if (!(rwar || rwav))
|
||||
{
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=
|
||||
rwav_data.start_offset + i*stream_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2076,6 +2076,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case meta_RWAV:
|
||||
snprintf(temp,TEMPSIZE,"Nintendo RWAV header");
|
||||
break;
|
||||
case meta_CWAV:
|
||||
snprintf(temp,TEMPSIZE,"Nintendo CWAV header");
|
||||
break;
|
||||
case meta_PSX_XA:
|
||||
snprintf(temp,TEMPSIZE,"RIFF/CDXA header");
|
||||
break;
|
||||
|
@ -216,6 +216,7 @@ typedef enum {
|
||||
meta_RWSD, /* single-stream RWSD */
|
||||
meta_RWAR, /* single-stream RWAR */
|
||||
meta_RWAV, /* contents of RWAR */
|
||||
meta_CWAV, /* */
|
||||
meta_RSTM_SPM, /* RSTM with 44->22khz hack */
|
||||
meta_THP,
|
||||
meta_RSTM_shrunken, /* Atlus' mutant shortened RSTM */
|
||||
|
@ -42,10 +42,12 @@ gchar *vgmstream_exts [] = {
|
||||
"baka",
|
||||
"baf",
|
||||
"bar",
|
||||
"bcwav",
|
||||
"bg00",
|
||||
"bgw",
|
||||
"bh2pcm",
|
||||
"bmdx",
|
||||
"bms",
|
||||
"bns",
|
||||
"bnsf",
|
||||
"bo2",
|
||||
|
@ -106,11 +106,13 @@ char * extension_list[] = {
|
||||
"baka\0BAKA Audio File (*.BAKA)\0",
|
||||
"baf\0BAF Audio File (*.BAF)\0",
|
||||
"bar\0BAR Audio File (*.BAR)\0",
|
||||
"bcwav\0BCWAV (*.BCWAV)\0",
|
||||
"bdsp\0BDSP Audio File (*.BDSP)\0",
|
||||
"bg00\0BG00 Audio File (*.BG00)\0",
|
||||
"bgw\0BGW Audio File (*.BGW)\0",
|
||||
"bh2pcm\0BH2PCM Audio File (*.BH2PCM)\0",
|
||||
"bmdx\0BMDX Audio File (*.BMDX)\0",
|
||||
"bms\0BMS (*.BMS)\0",
|
||||
"bnk\0BNK Audio File (*.BNK)\0",
|
||||
"bns\0BNS Audio File (*.BNS)\0",
|
||||
"bnsf\0BNSF Audio File (*.BNSF)\0",
|
||||
|
Loading…
x
Reference in New Issue
Block a user