mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
Add RSD6XMA and tri-Ace's PS3/X360 support (by bxaimc)
This commit is contained in:
parent
e2cc352238
commit
a79b874f82
@ -681,6 +681,7 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_RSD6VAG, "RSD6/VAG Header"},
|
||||
{meta_RSD6WADP, "RSD6/WADP Header"},
|
||||
{meta_RSD6RADP, "RSD6/RADP Header"},
|
||||
{meta_RSD6XMA, "RSD6/XMA Header"},
|
||||
{meta_DC_ASD, "ASD Header"},
|
||||
{meta_NAOMI_SPSD, "SPSD Header"},
|
||||
{meta_FFXI_BGW, "BGW BGMStream header"},
|
||||
@ -853,6 +854,8 @@ static const meta_info meta_info_list[] = {
|
||||
{meta_OGL, "Shin'en OGL header"},
|
||||
{meta_MC3, "Paradigm MC3 header"},
|
||||
{meta_GTD, "GTD/GHS header"},
|
||||
{meta_TA_AAC_X360, "tri-Ace AAC (X360) header"},
|
||||
{meta_TA_AAC_PS3, "tri-Ace AAC (PS3) header"},
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
{meta_OGG_VORBIS, "Ogg Vorbis"},
|
||||
|
@ -1101,6 +1101,10 @@
|
||||
<File
|
||||
RelativePath=".\meta\sxd.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ta_aac.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\thp.c"
|
||||
|
@ -372,6 +372,7 @@
|
||||
<ClCompile Include="meta\stx.c" />
|
||||
<ClCompile Include="meta\svs.c" />
|
||||
<ClCompile Include="meta\sxd.c" />
|
||||
<ClCompile Include="meta\ta_aac.c" />
|
||||
<ClCompile Include="meta\thp.c" />
|
||||
<ClCompile Include="meta\vgs.c" />
|
||||
<ClCompile Include="meta\ubi_ckd.c" />
|
||||
|
@ -667,6 +667,9 @@
|
||||
<ClCompile Include="meta\sxd.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\ta_aac.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="meta\thp.c">
|
||||
<Filter>meta\Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
@ -690,5 +690,10 @@ VGMSTREAM * init_vgmstream_mc3(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_gtd(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_rsd6xma(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ta_aac_x360(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ta_aac_ps3(STREAMFILE *streamFile);
|
||||
|
||||
#endif /*_META_H*/
|
||||
|
118
src/meta/rsd.c
118
src/meta/rsd.c
@ -1,5 +1,6 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* RSD */
|
||||
/* RSD2VAG */
|
||||
@ -1068,70 +1069,99 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
/* RSD6XMA */
|
||||
VGMSTREAM * init_vgmstream_rsd6xma(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
uint32_t version;
|
||||
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("rsd",filename_extension(filename))) goto fail;
|
||||
/* check extension, case insensitive */
|
||||
if (!check_extensions(streamFile,"rsd"))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x52534436) /* RSD6 */
|
||||
if (read_32bitBE(0x0, streamFile) != 0x52534436) /* RSD6 */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x4,streamFile) != 0x584D4120) /* XMA */
|
||||
if (read_32bitBE(0x04,streamFile) != 0x584D4120) /* XMA */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = read_32bitLE(0x8,streamFile);
|
||||
loop_flag = 0;
|
||||
channel_count = read_32bitLE(0x8, streamFile);
|
||||
version = read_32bitBE(0x80C, streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x800;
|
||||
start_offset = read_32bitBE(0x800, streamFile) + read_32bitBE(0x804, streamFile) + 0xc; /* assumed, seek table always at 0x800 */
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->coding_type = coding_XMA;
|
||||
vgmstream->num_samples = (get_streamfile_size(streamFile)-start_offset)*64/36/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = loop_flag;
|
||||
vgmstream->loop_end_sample = (get_streamfile_size(streamFile)-start_offset)*28/16/channel_count;
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x10;
|
||||
vgmstream->meta_type = meta_RSD6XMA;
|
||||
vgmstream->sample_rate = read_32bitBE(0x818, streamFile);
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = file;
|
||||
switch (version) {
|
||||
case 0x03010000: {
|
||||
vgmstream->num_samples = read_32bitBE(0x824, streamFile);
|
||||
|
||||
|
||||
if (vgmstream->coding_type == coding_XMA) {
|
||||
vgmstream->layout_type=layout_none;
|
||||
vgmstream->ch[i].channel_start_offset=start_offset;
|
||||
} else {
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
start_offset+vgmstream->interleave_block_size*i;
|
||||
}
|
||||
vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{
|
||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||
uint8_t buf[100];
|
||||
size_t bytes, datasize, block_size, block_count;
|
||||
|
||||
block_count = read_32bitBE(0x828, streamFile);
|
||||
block_size = 0x10000;
|
||||
datasize = read_32bitBE(0x808, streamFile);
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, datasize);
|
||||
if (!ffmpeg_data) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 0x04010000: {
|
||||
vgmstream->num_samples = read_32bitBE(0x814, streamFile);
|
||||
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{
|
||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||
uint8_t buf[100];
|
||||
size_t bytes, datasize, block_size, block_count;
|
||||
|
||||
block_count = read_32bitBE(0x830, streamFile);
|
||||
block_size = 0x10000;
|
||||
datasize = read_32bitBE(0x808, streamFile);
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf, 100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, datasize);
|
||||
if (!ffmpeg_data) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* open the file for reading */
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
@ -1139,5 +1169,3 @@ fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
210
src/meta/ta_aac.c
Normal file
210
src/meta/ta_aac.c
Normal file
@ -0,0 +1,210 @@
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* AAC - Tri-Ace Audio Container */
|
||||
|
||||
/* Xbox 360 Variants (Star Ocean 4, End of Eternity, Infinite Undiscovery) */
|
||||
VGMSTREAM * init_vgmstream_ta_aac_x360(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
size_t sampleRate, numSamples, startSample, dataSize, blockSize, blockCount; // A mess
|
||||
|
||||
/* check extension, case insensitive */
|
||||
/* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */
|
||||
if ( !check_extensions(streamFile,"aac,laac,ace"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00,streamFile) != 0x41414320) /* "AAC " */
|
||||
goto fail;
|
||||
|
||||
/* Ok, let's check what's behind door number 1 */
|
||||
if (read_32bitBE(0x1000, streamFile) == 0x41534320) /* "ASC " */
|
||||
{
|
||||
loop_flag = read_32bitBE(0x1118, streamFile);
|
||||
|
||||
/*Funky Channel Count Checking */
|
||||
if (read_32bitBE(0x1184, streamFile) == 0x7374726D)
|
||||
channel_count = 6;
|
||||
else if (read_32bitBE(0x1154, streamFile) == 0x7374726D)
|
||||
channel_count = 4;
|
||||
else
|
||||
channel_count = read_8bit(0x1134, streamFile);
|
||||
|
||||
sampleRate = read_32bitBE(0x10F4, streamFile);
|
||||
numSamples = read_32bitBE(0x10FC, streamFile);
|
||||
startSample = read_32bitBE(0x10F8, streamFile);
|
||||
dataSize = read_32bitBE(0x10F0, streamFile);
|
||||
blockSize = read_32bitBE(0x1100, streamFile);
|
||||
blockCount = read_32bitBE(0x110C, streamFile);
|
||||
}
|
||||
else if (read_32bitBE(0x1000, streamFile) == 0x57415645) /* "WAVE" */
|
||||
{
|
||||
loop_flag = read_32bitBE(0x1048, streamFile);
|
||||
|
||||
/*Funky Channel Count Checking */
|
||||
if (read_32bitBE(0x10B0, streamFile) == 0x7374726D)
|
||||
channel_count = 6;
|
||||
else if (read_32bitBE(0x1080, streamFile) == 0x7374726D)
|
||||
channel_count = 4;
|
||||
else
|
||||
channel_count = read_8bit(0x1060, streamFile);
|
||||
|
||||
sampleRate = read_32bitBE(0x1024, streamFile);
|
||||
numSamples = read_32bitBE(0x102C, streamFile);
|
||||
startSample = read_32bitBE(0x1028, streamFile);
|
||||
dataSize = read_32bitBE(0x1020, streamFile);
|
||||
blockSize = read_32bitBE(0x1030, streamFile);
|
||||
blockCount = read_32bitBE(0x103C, streamFile);
|
||||
}
|
||||
else if (read_32bitBE(0x1000, streamFile) == 0x00000000) /* some like to be special */
|
||||
{
|
||||
loop_flag = read_32bitBE(0x6048, streamFile);
|
||||
|
||||
/*Funky Channel Count Checking */
|
||||
if (read_32bitBE(0x60B0, streamFile) == 0x7374726D)
|
||||
channel_count = 6;
|
||||
else if (read_32bitBE(0x6080, streamFile) == 0x7374726D)
|
||||
channel_count = 4;
|
||||
else
|
||||
channel_count = read_8bit(0x6060, streamFile);
|
||||
|
||||
sampleRate = read_32bitBE(0x6024, streamFile);
|
||||
numSamples = read_32bitBE(0x602C, streamFile);
|
||||
startSample = read_32bitBE(0x6028, streamFile);
|
||||
dataSize = read_32bitBE(0x6020, streamFile);
|
||||
blockSize = read_32bitBE(0x6030, streamFile);
|
||||
blockCount = read_32bitBE(0x603C, streamFile);
|
||||
}
|
||||
else
|
||||
goto fail; //cuz I don't know if there are other variants
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
if (read_32bitBE(0x1000, streamFile) == 0x00000000)
|
||||
start_offset = 0x7000;
|
||||
else
|
||||
start_offset = 0x2000;
|
||||
|
||||
vgmstream->sample_rate = sampleRate;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->num_samples = numSamples;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = startSample;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
vgmstream->meta_type = meta_TA_AAC_X360;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{
|
||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||
uint8_t buf[100];
|
||||
size_t bytes, datasize, block_size, block_count;
|
||||
|
||||
block_count = blockCount;
|
||||
block_size = blockSize;
|
||||
datasize = dataSize;
|
||||
|
||||
bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
||||
if ( !ffmpeg_data ) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
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;
|
||||
}
|
||||
|
||||
/* PlayStation 3 Variants (Star Ocean International, Resonance of Fate) */
|
||||
VGMSTREAM * init_vgmstream_ta_aac_ps3(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
uint32_t data_size, loop_start, loop_end, codec_id;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
/* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */
|
||||
if (!check_extensions(streamFile, "aac,laac,ace"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00, streamFile) != 0x41414320) /* "AAC " */
|
||||
goto fail;
|
||||
|
||||
/* Haven't Found a codec flag yet. Let's just use this for now */
|
||||
if (read_32bitBE(0x10000, streamFile) != 0x41534320) /* "ASC " */
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x10104, streamFile) != 0xFFFFFFFF)
|
||||
loop_flag = 1;
|
||||
else
|
||||
loop_flag = 0;
|
||||
|
||||
channel_count = read_32bitBE(0x100F4, streamFile);
|
||||
codec_id = read_32bitBE(0x100F0, streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* Useless header, let's play the guessing game */
|
||||
start_offset = 0x10110;
|
||||
vgmstream->sample_rate = read_32bitBE(0x100FC, streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->meta_type = meta_TA_AAC_PS3;
|
||||
data_size = read_32bitBE(0x100F8, streamFile);
|
||||
loop_start = read_32bitBE(0x10104, streamFile);
|
||||
loop_end = read_32bitBE(0x10108, streamFile);
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{
|
||||
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||
uint8_t buf[100];
|
||||
int32_t bytes, samples_size = 1024, block_size, encoder_delay, joint_stereo, max_samples;
|
||||
block_size = (codec_id == 4 ? 0x60 : (codec_id == 5 ? 0x98 : 0xC0)) * vgmstream->channels;
|
||||
max_samples = (data_size / block_size) * samples_size;
|
||||
encoder_delay = 0x0;
|
||||
joint_stereo = 0;
|
||||
|
||||
/* make a fake riff so FFmpeg can parse the ATRAC3 */
|
||||
bytes = ffmpeg_make_riff_atrac3(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay);
|
||||
if (bytes <= 0) goto fail;
|
||||
|
||||
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, data_size);
|
||||
if (!ffmpeg_data) goto fail;
|
||||
vgmstream->codec_data = ffmpeg_data;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->num_samples = max_samples;
|
||||
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = (loop_start / block_size) * samples_size;
|
||||
vgmstream->loop_end_sample = (loop_end / block_size) * samples_size;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/* open the file for reading */
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -355,6 +355,9 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_ogl,
|
||||
init_vgmstream_mc3,
|
||||
init_vgmstream_gtd,
|
||||
init_vgmstream_rsd6xma,
|
||||
init_vgmstream_ta_aac_x360,
|
||||
init_vgmstream_ta_aac_ps3,
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
init_vgmstream_mp4_aac_ffmpeg,
|
||||
|
@ -417,6 +417,7 @@ typedef enum {
|
||||
meta_RSD6XADP, /* RSD6XADP */
|
||||
meta_RSD6RADP, /* RSD6RADP */
|
||||
meta_RSD6OOGV, /* RSD6OOGV */
|
||||
meta_RSD6XMA, /* RSD6XMA */
|
||||
|
||||
meta_PS2_ASS, /* ASS */
|
||||
meta_PS2_SEG, /* Eragon */
|
||||
@ -610,6 +611,8 @@ typedef enum {
|
||||
meta_OGL, /* Shin'en Wii/WiiU (Jett Rocket (Wii), FAST Racing NEO (WiiU)) */
|
||||
meta_MC3, /* Paradigm games (T3 PS2, MX Rider PS2, MI: Operation Surma PS2) */
|
||||
meta_GTD, /* Knights Contract (X360/PS3), Valhalla Knights 3 (PSV) */
|
||||
meta_TA_AAC_X360, /* tri-ace AAC (Star Ocean 4, End of Eternity, Infinite Undiscovery) */
|
||||
meta_TA_AAC_PS3, /* tri-ace AAC (Star Ocean International, Resonance of Fate) */
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
meta_OGG_VORBIS, /* Ogg Vorbis */
|
||||
|
Loading…
x
Reference in New Issue
Block a user