Move XNB from riff.c to xnb.c (cleanup)

This commit is contained in:
bnnm 2017-12-26 18:17:59 +01:00
parent a818f7adfe
commit 331bc187fa
7 changed files with 133 additions and 145 deletions

View File

@ -1341,6 +1341,10 @@
<File
RelativePath=".\meta\xma.c"
>
</File>
<File
RelativePath=".\meta\xnb.c"
>
</File>
<File
RelativePath=".\meta\xss.c"

View File

@ -436,6 +436,7 @@
<ClCompile Include="meta\xbox_xwav.c" />
<ClCompile Include="meta\x360_pasx.c" />
<ClCompile Include="meta\xma.c" />
<ClCompile Include="meta\xnb.c" />
<ClCompile Include="meta\xss.c" />
<ClCompile Include="meta\xvag.c" />
<ClCompile Include="meta\xwb.c" />

View File

@ -1216,6 +1216,9 @@
<ClCompile Include="meta\xma.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\xnb.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\x360_cxs.c">
<Filter>meta\Source Files</Filter>
</ClCompile>

View File

@ -152,7 +152,7 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_rifx(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_xnbm(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_xnb(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_pos(STREAMFILE * streamFile);

View File

@ -840,146 +840,3 @@ fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}
//todo move
/* XNB - Microsoft XNA Game Studio 4.0 format */
VGMSTREAM * init_vgmstream_xnbm(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag = 0, version, flags, num_samples = 0;
size_t xnb_size, data_size;
struct riff_fmt_chunk fmt;
/* check extension, case insensitive */
if ( !check_extensions(streamFile,"xnb"))
goto fail;
/* check header */
if ((read_32bitBE(0,streamFile) & 0xFFFFFF00) != 0x584E4200) /* "XNB" */
goto fail;
/* 0x04: platform: w = Microsoft Windows, m = Windows Phone 7, x = Xbox 360, 'a' = Android */
version = read_8bit(0x04,streamFile);
if (version != 5) goto fail; /* XNA 4.0 only */
flags = read_8bit(0x05,streamFile);
if (flags & 0x80) goto fail; /* compressed with XMemCompress, not public */
//if (flags & 0x01) goto fail; /* XMA flag? */
/* "check for truncated XNB" (???) */
xnb_size = read_32bitLE(0x06,streamFile);
if (get_streamfile_size(streamFile) < xnb_size) goto fail;
/* XNB contains "type reader" class references to parse "shared resource" data (can be any implemented filetype) */
{
char reader_name[255+1];
off_t current_chunk = 0xa;
int reader_string_len;
uint32_t fmt_chunk_size;
const char * type_sound = "Microsoft.Xna.Framework.Content.SoundEffectReader"; /* partial "fmt" chunk or XMA */
//const char * type_song = "Microsoft.Xna.Framework.Content.SongReader"; /* just references a companion .wma */
/* type reader count, accept only one for now */
if (read_8bit(current_chunk++, streamFile) != 1)
goto fail;
reader_string_len = read_8bit(current_chunk++, streamFile); /* doesn't count null */
if (reader_string_len > 255) goto fail;
/* check SoundEffect type string */
if (read_string(reader_name,reader_string_len+1,current_chunk,streamFile) != reader_string_len)
goto fail;
if ( strcmp(reader_name, type_sound) != 0 )
goto fail;
current_chunk += reader_string_len + 1;
current_chunk += 4; /* reader version */
/* shared resource count */
if (read_8bit(current_chunk++, streamFile) != 1)
goto fail;
/* shared resource: partial "fmt" chunk */
fmt_chunk_size = read_32bitLE(current_chunk, streamFile);
current_chunk += 4;
if (-1 == read_fmt(0, /* big endian == false */
streamFile,
current_chunk-8, /* read_fmt() expects to skip "fmt "+size */
&fmt,
0, /* sns == false */
0)) /* mwv == false */
goto fail;
current_chunk += fmt_chunk_size;
data_size = read_32bitLE(current_chunk, streamFile);
current_chunk += 4;
start_offset = current_chunk;
}
switch (fmt.coding_type) {
case coding_PCM16LE:
num_samples = pcm_bytes_to_samples(data_size, fmt.channel_count, 16);
break;
case coding_PCM8_U_int:
num_samples = pcm_bytes_to_samples(data_size, fmt.channel_count, 8);
break;
case coding_MSADPCM:
num_samples = msadpcm_bytes_to_samples(data_size, fmt.block_size, fmt.channel_count);
break;
case coding_MS_IMA:
num_samples = (data_size / fmt.block_size) * (fmt.block_size - 4 * fmt.channel_count) * 2 / fmt.channel_count +
((data_size % fmt.block_size) ? (data_size % fmt.block_size - 4 * fmt.channel_count) * 2 / fmt.channel_count : 0);
break;
default:
VGM_LOG("XNB: unknown codec 0x%x\n", fmt.coding_type);
goto fail;
}
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(fmt.channel_count,loop_flag);
if (!vgmstream) goto fail;
vgmstream->num_samples = num_samples;
vgmstream->sample_rate = fmt.sample_rate;
vgmstream->meta_type = meta_XNB;
vgmstream->coding_type = fmt.coding_type;
if (fmt.channel_count > 1) {
switch (fmt.coding_type) {
case coding_PCM8_U_int:
case coding_MS_IMA:
case coding_MSADPCM:
vgmstream->layout_type = layout_none;
break;
default:
vgmstream->layout_type = layout_interleave;
break;
}
}
switch (fmt.coding_type) {
case coding_MSADPCM:
case coding_MS_IMA:
vgmstream->interleave_block_size = fmt.block_size;
break;
default:
vgmstream->interleave_block_size = fmt.interleave;
break;
}
if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset) )
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

123
src/meta/xnb.c Normal file
View File

@ -0,0 +1,123 @@
#include "meta.h"
#include "../coding/coding.h"
/* XNB - Microsoft XNA Game Studio 4.0 format */
VGMSTREAM * init_vgmstream_xnb(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag = 0, channel_count;
int flags, codec, sample_rate, block_size, bps;
size_t xnb_size, data_size;
/* check extension, case insensitive */
if ( !check_extensions(streamFile,"xnb"))
goto fail;
/* check header */
if ((read_32bitBE(0,streamFile) & 0xFFFFFF00) != 0x584E4200) /* "XNB" */
goto fail;
/* 0x04: platform: w = Microsoft Windows, m = Windows Phone 7, x = Xbox 360, 'a' = Android */
if (read_8bit(0x04,streamFile) != 0x05) /* XNA 4.0 version only */
goto fail;
flags = read_8bit(0x05,streamFile);
if (flags & 0x80) goto fail; /* compressed with XMemCompress */
//if (flags & 0x01) goto fail; /* XMA/big endian flag? */
/* "check for truncated XNB" (???) */
xnb_size = read_32bitLE(0x06,streamFile);
if (get_streamfile_size(streamFile) < xnb_size) goto fail;
/* XNB contains "type reader" class references to parse "shared resource" data (can be any implemented filetype) */
{
char reader_name[255+1];
off_t current_chunk = 0xa;
int reader_string_len;
uint32_t fmt_chunk_size;
const char * type_sound = "Microsoft.Xna.Framework.Content.SoundEffectReader"; /* partial "fmt" chunk or XMA */
//const char * type_song = "Microsoft.Xna.Framework.Content.SongReader"; /* just references a companion .wma */
/* type reader count, accept only one for now */
if (read_8bit(current_chunk++, streamFile) != 1)
goto fail;
reader_string_len = read_8bit(current_chunk++, streamFile); /* doesn't count null */
if (reader_string_len > 255) goto fail;
/* check SoundEffect type string */
if (read_string(reader_name,reader_string_len+1,current_chunk,streamFile) != reader_string_len)
goto fail;
if ( strcmp(reader_name, type_sound) != 0 )
goto fail;
current_chunk += reader_string_len + 1;
current_chunk += 4; /* reader version */
/* shared resource count */
if (read_8bit(current_chunk++, streamFile) != 1)
goto fail;
/* shared resource: partial "fmt" chunk */
fmt_chunk_size = read_32bitLE(current_chunk, streamFile);
current_chunk += 4;
{
codec = read_16bitLE(current_chunk+0x00, streamFile);
channel_count = read_16bitLE(current_chunk+0x02, streamFile);
sample_rate = read_32bitLE(current_chunk+0x04, streamFile);
block_size = read_16bitLE(current_chunk+0x0c, streamFile);
bps = read_16bitLE(current_chunk+0x0e, streamFile);
}
current_chunk += fmt_chunk_size;
data_size = read_32bitLE(current_chunk, streamFile);
current_chunk += 4;
start_offset = current_chunk;
}
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = sample_rate;
vgmstream->meta_type = meta_XNB;
switch (codec) {
case 0x01:
vgmstream->coding_type = bps == 8 ? coding_PCM8_U_int : coding_PCM16LE;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = block_size / channel_count;
vgmstream->num_samples = pcm_bytes_to_samples(data_size, channel_count, bps);
break;
case 0x02:
vgmstream->coding_type = coding_MSADPCM;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = block_size;
vgmstream->num_samples = msadpcm_bytes_to_samples(data_size, block_size, channel_count);
break;
case 0x11:
vgmstream->coding_type = coding_MS_IMA;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = block_size;
vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, block_size, channel_count);
break;
default:
VGM_LOG("XNB: unknown codec 0x%x\n", codec);
goto fail;
}
if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset) )
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -316,7 +316,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
init_vgmstream_ps2_hsf,
init_vgmstream_ps3_ivag,
init_vgmstream_ps2_2pfs,
init_vgmstream_xnbm,
init_vgmstream_xnb,
init_vgmstream_rsd6oogv,
init_vgmstream_ubi_ckd,
init_vgmstream_ps2_vbk,