Separate X360 NUB/PASX from xma.c for cleanup

This commit is contained in:
bnnm 2017-04-22 12:09:43 +02:00
parent 9f184bdfb9
commit 7cc3660fc8
10 changed files with 175 additions and 45 deletions

View File

@ -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

View File

@ -1169,6 +1169,14 @@
<File
RelativePath=".\meta\x360_cxs.c"
>
</File>
<File
RelativePath=".\meta\x360_nub.c"
>
</File>
<File
RelativePath=".\meta\x360_pasx.c"
>
</File>
<File
RelativePath=".\meta\x360_tra.c"

View File

@ -391,6 +391,8 @@
<ClCompile Include="meta\xbox_xmu.c" />
<ClCompile Include="meta\xbox_xvas.c" />
<ClCompile Include="meta\xbox_xwav.c" />
<ClCompile Include="meta\x360_pasx.c" />
<ClCompile Include="meta\x360_nub.c" />
<ClCompile Include="meta\xma.c" />
<ClCompile Include="meta\xss.c" />
<ClCompile Include="meta\xwb.c" />

View File

@ -703,6 +703,12 @@
<ClCompile Include="meta\wwise.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\x360_nub.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\x360_pasx.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\xbox_hlwav.c">
<Filter>meta\Source Files</Filter>
</ClCompile>

View File

@ -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

View File

@ -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*/

78
src/meta/x360_nub.c Normal file
View File

@ -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;
}

68
src/meta/x360_pasx.c Normal file
View File

@ -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;
}

View File

@ -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;
}

View File

@ -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,