From 7cc3660fc8839a90d49434bd0a8b6dddc9d36fd6 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 22 Apr 2017 12:09:43 +0200 Subject: [PATCH] Separate X360 NUB/PASX from xma.c for cleanup --- src/Makefile | 4 +- src/libvgmstream.vcproj | 8 ++++ src/libvgmstream.vcxproj | 2 + src/libvgmstream.vcxproj.filters | 6 +++ src/meta/Makefile.unix.am | 2 + src/meta/meta.h | 4 ++ src/meta/x360_nub.c | 78 ++++++++++++++++++++++++++++++++ src/meta/x360_pasx.c | 68 ++++++++++++++++++++++++++++ src/meta/xma.c | 46 +------------------ src/vgmstream.c | 2 + 10 files changed, 175 insertions(+), 45 deletions(-) create mode 100644 src/meta/x360_nub.c create mode 100644 src/meta/x360_pasx.c diff --git a/src/Makefile b/src/Makefile index 631deb3b..6d32fbff 100644 --- a/src/Makefile +++ b/src/Makefile @@ -319,7 +319,9 @@ META_OBJS=meta/adx.o \ meta/akb.o \ meta/x360_ast.o \ meta/wwise.o \ - meta/ubi_raki.o + meta/ubi_raki.o \ + meta/x360_nub.o \ + meta/x360_pasx.o EXT_LIBS = ../ext_libs/clHCA.o diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index 60bcaec9..2a2c022d 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -1169,6 +1169,14 @@ + + + + + + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 68aaa360..95747e48 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -703,6 +703,12 @@ meta\Source Files + + meta\Source Files + + + meta\Source Files + meta\Source Files diff --git a/src/meta/Makefile.unix.am b/src/meta/Makefile.unix.am index da591e71..52f0d14b 100644 --- a/src/meta/Makefile.unix.am +++ b/src/meta/Makefile.unix.am @@ -256,5 +256,7 @@ libmeta_la_SOURCES += akb.c libmeta_la_SOURCES += x360_ast.c libmeta_la_SOURCES += wwise.c libmeta_la_SOURCES += ubi_raki.c +libmeta_la_SOURCES += x360_pasx.c +libmeta_la_SOURCES += x360_nub.c EXTRA_DIST = meta.h diff --git a/src/meta/meta.h b/src/meta/meta.h index fa03b6f2..c3a9fc37 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -678,4 +678,8 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_ubi_raki(STREAMFILE* streamFile); +VGMSTREAM * init_vgmstream_x360_nub(STREAMFILE *streamFile); + +VGMSTREAM * init_vgmstream_x360_pasx(STREAMFILE *streamFile); + #endif /*_META_H*/ diff --git a/src/meta/x360_nub.c b/src/meta/x360_nub.c new file mode 100644 index 00000000..3c4cae95 --- /dev/null +++ b/src/meta/x360_nub.c @@ -0,0 +1,78 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* Namco NUB xma - from Tekken 6, Galaga Legions DX */ +VGMSTREAM * init_vgmstream_x360_nub(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset, chunk_offset; + size_t data_size, chunk_size; + int loop_flag, channel_count, sample_rate, chunk_type; + int num_samples, loop_start_sample, loop_end_sample; + + + /* check extension, case insensitive */ + if ( !check_extensions(streamFile,"xma")) /* (probably meant to be .nub) */ + goto fail; + + if (read_32bitBE(0x00,streamFile) != 0x786D6100) /* "xma\0" */ + goto fail; + + + /* custom header with a "XMA2" or "fmt " chunk inside; most other values are unknown */ + chunk_type = read_32bitBE(0xC,streamFile); + start_offset = 0x100; + data_size = read_32bitBE(0x14,streamFile); + chunk_offset = 0xBC; + chunk_size = read_32bitBE(0x24,streamFile); + if (chunk_type == 0x4) { /* "XMA2" */ + xma2_parse_xma2_chunk(streamFile, chunk_offset, &channel_count,&sample_rate, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample); + } else if (chunk_type == 0x8) { /* "fmt " */ + channel_count = read_16bitBE(chunk_offset+0x02,streamFile); + sample_rate = read_32bitBE(chunk_offset+0x04,streamFile); + xma2_parse_fmt_chunk_extra(streamFile, chunk_offset, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample, 1); + } else { + goto fail; + } + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start_sample; + vgmstream->loop_end_sample = loop_end_sample; + vgmstream->meta_type = meta_NUB_XMA; + +#ifdef VGM_USE_FFMPEG + { + uint8_t buf[0x100]; + size_t bytes; + + if (chunk_type == 0x4) { /* "XMA2" */ + bytes = ffmpeg_make_riff_xma2_from_xma2_chunk(buf,0x100, chunk_offset,chunk_size, data_size, streamFile); + } else { /* "fmt " */ + bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset,chunk_size, data_size, streamFile, 1); + } + if (bytes <= 0) goto fail; + + vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size);; + if ( !vgmstream->codec_data ) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + } +#else + goto fail; +#endif + + + /* open the file for reading */ + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/x360_pasx.c b/src/meta/x360_pasx.c new file mode 100644 index 00000000..bee4fdbf --- /dev/null +++ b/src/meta/x360_pasx.c @@ -0,0 +1,68 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* PASX - from SoulCalibur II HD (X360) */ +VGMSTREAM * init_vgmstream_x360_pasx(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset, chunk_offset; + size_t data_size, chunk_size; + int loop_flag, channel_count, sample_rate; + int num_samples, loop_start_sample, loop_end_sample; + + + /* check extension, case insensitive */ + if ( !check_extensions(streamFile,"past")) + goto fail; + + if (read_32bitBE(0x00,streamFile) != 0x50415358) /* "PASX" */ + goto fail; + + + /* custom header with a "fmt " data chunk inside */ + chunk_size = read_32bitBE(0x08,streamFile); + data_size = read_32bitBE(0x0c,streamFile); + chunk_offset = read_32bitBE(0x10,streamFile); /* 0x14: fmt offset end */ + start_offset = read_32bitBE(0x18,streamFile); + + channel_count = read_16bitBE(chunk_offset+0x02,streamFile); + sample_rate = read_32bitBE(chunk_offset+0x04,streamFile); + xma2_parse_fmt_chunk_extra(streamFile, chunk_offset, &loop_flag, &num_samples, &loop_start_sample, &loop_end_sample, 1); + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start_sample; + vgmstream->loop_end_sample = loop_end_sample; + vgmstream->meta_type = meta_X360_PASX; + +#ifdef VGM_USE_FFMPEG + { + uint8_t buf[0x100]; + size_t bytes; + + bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf,0x100, chunk_offset,chunk_size, data_size, streamFile, 1); + if (bytes <= 0) goto fail; + + vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); + if ( !vgmstream->codec_data ) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + } +#else + goto fail; +#endif + + + /* open the file for reading */ + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/xma.c b/src/meta/xma.c index 8cc28271..c05de8fc 100644 --- a/src/meta/xma.c +++ b/src/meta/xma.c @@ -56,8 +56,8 @@ VGMSTREAM * init_vgmstream_xma(STREAMFILE *streamFile) { /* check extension, case insensitive */ - /* .xma2: Skullgirls, .nps: Beautiful Katamari, .past: SoulCalibur II HD */ - if ( !check_extensions(streamFile, "xma,xma2,nps,past") ) + /* .xma2: Skullgirls, .nps: Beautiful Katamari */ + if ( !check_extensions(streamFile, "xma,xma2,nps") ) goto fail; /* check header */ @@ -134,8 +134,6 @@ static int parse_header(xma_header_data * xma, STREAMFILE *streamFile) { int big_endian = 0; enum { id_RIFF = UINT32_C(0x52494646), /* "RIFF" */ - id_NXMA = UINT32_C(0x786D6100), /* "xma\0" */ - id_PASX = UINT32_C(0x50415358), /* "PASX" */ }; @@ -144,10 +142,6 @@ static int parse_header(xma_header_data * xma, STREAMFILE *streamFile) { switch (id) { case id_RIFF: break; - case id_NXMA: - case id_PASX: - big_endian = 1; - break; default: goto fail; } @@ -224,42 +218,6 @@ static int parse_header(xma_header_data * xma, STREAMFILE *streamFile) { goto fail; } } - else if (id == id_NXMA) { /* Namco NUB xma (Tekken 6, Galaga Legions DX) */ - /* Custom header with a "XMA2" or "fmt " data chunk inside; most other values are unknown - * It's here rather than its own meta to reuse the chunk parsing (probably intended to be .nub) */ - uint32_t chunk_type = read_32bit(0xC,streamFile); - - xma->meta = meta_NUB_XMA; - xma->data_offset = 0x100; - xma->data_size = read_32bit(0x14,streamFile); - xma->chunk_offset = 0xBC; - xma->chunk_size = read_32bit(0x24,streamFile); - if (chunk_type == 0x4) { /* "XMA2" */ - xma->xma2_version = read_8bit(xma->chunk_offset,streamFile); - } else if (chunk_type == 0x8) { /* "fmt " */ - xma->fmt_codec = read_16bit(xma->chunk_offset,streamFile); - xma->force_little_endian = 1; - } else { - goto fail; - } - xma->needs_header = 1; - - if (xma->data_size + xma->data_offset > xma->file_size) goto fail; - } - else if (id == id_PASX) { /* SoulCalibur II HD */ - /* Custom header with a "fmt " data chunk inside - * It's here rather than its own meta to reuse the chunk parsing */ - - xma->meta = meta_X360_PASX; - xma->chunk_size = read_32bit(0x08,streamFile); - xma->data_size = read_32bit(0x0c,streamFile); - xma->chunk_offset = read_32bit(0x10,streamFile); - /* 0x14: chunk offset end */ - xma->data_offset = read_32bit(0x18,streamFile); - xma->fmt_codec = read_16bit(xma->chunk_offset,streamFile); - xma->needs_header = 1; - xma->force_little_endian = 1; - } else { goto fail; } diff --git a/src/vgmstream.c b/src/vgmstream.c index 7dadd54e..e6d0707d 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -343,6 +343,8 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_x360_ast, init_vgmstream_wwise, init_vgmstream_ubi_raki, + init_vgmstream_x360_pasx, + init_vgmstream_x360_nub, #ifdef VGM_USE_FFMPEG init_vgmstream_xma,