From 331bc187fa3d70eda9128ffed75af56ebaf24094 Mon Sep 17 00:00:00 2001 From: bnnm Date: Tue, 26 Dec 2017 18:17:59 +0100 Subject: [PATCH] Move XNB from riff.c to xnb.c (cleanup) --- src/libvgmstream.vcproj | 4 + src/libvgmstream.vcxproj | 1 + src/libvgmstream.vcxproj.filters | 3 + src/meta/meta.h | 2 +- src/meta/riff.c | 143 ------------------------------- src/meta/xnb.c | 123 ++++++++++++++++++++++++++ src/vgmstream.c | 2 +- 7 files changed, 133 insertions(+), 145 deletions(-) create mode 100644 src/meta/xnb.c diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index 3b307b75..f7a09870 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -1341,6 +1341,10 @@ + + + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 01811bf0..9abfc79c 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1216,6 +1216,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files diff --git a/src/meta/meta.h b/src/meta/meta.h index bc0ba6b0..c26f5f80 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -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); diff --git a/src/meta/riff.c b/src/meta/riff.c index c7c4265b..56e6afec 100644 --- a/src/meta/riff.c +++ b/src/meta/riff.c @@ -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; -} - diff --git a/src/meta/xnb.c b/src/meta/xnb.c new file mode 100644 index 00000000..c0034a71 --- /dev/null +++ b/src/meta/xnb.c @@ -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; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index 50015c89..9297713f 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -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,