mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 01:30:49 +01:00
.scd (FFXIII and FFXIV, MPEG, MS ADPCM, and PCM)
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@834 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
83f3ad9604
commit
e98bb44bb5
@ -408,6 +408,7 @@ bool input_vgmstream::g_is_our_path(const char * p_path,const char * p_extension
|
|||||||
if(!stricmp_utf8(p_extension,"sad")) return 1;
|
if(!stricmp_utf8(p_extension,"sad")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"sap")) return 1;
|
if(!stricmp_utf8(p_extension,"sap")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"sc")) return 1;
|
if(!stricmp_utf8(p_extension,"sc")) return 1;
|
||||||
|
if(!stricmp_utf8(p_extension,"scd")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"sck")) return 1;
|
if(!stricmp_utf8(p_extension,"sck")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"sd9")) return 1;
|
if(!stricmp_utf8(p_extension,"sd9")) return 1;
|
||||||
if(!stricmp_utf8(p_extension,"sdt")) return 1;
|
if(!stricmp_utf8(p_extension,"sdt")) return 1;
|
||||||
@ -689,6 +690,7 @@ DECLARE_MULTIPLE_FILE_TYPE("SAB Audio File (*.SAB)", sab);
|
|||||||
DECLARE_MULTIPLE_FILE_TYPE("SAD Audio File (*.SAD)", sad);
|
DECLARE_MULTIPLE_FILE_TYPE("SAD Audio File (*.SAD)", sad);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("SAP Audio File (*.SAP)", sap);
|
DECLARE_MULTIPLE_FILE_TYPE("SAP Audio File (*.SAP)", sap);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("SC Audio File (*.SC)", sc);
|
DECLARE_MULTIPLE_FILE_TYPE("SC Audio File (*.SC)", sc);
|
||||||
|
DECLARE_MULTIPLE_FILE_TYPE("SCD Audio File (*.SCD)", scd);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("SCK Audio File (*.SCK)", sck);
|
DECLARE_MULTIPLE_FILE_TYPE("SCK Audio File (*.SCK)", sck);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("SD9 Audio File (*.SD9)", sd9);
|
DECLARE_MULTIPLE_FILE_TYPE("SD9 Audio File (*.SD9)", sd9);
|
||||||
DECLARE_MULTIPLE_FILE_TYPE("SDT Audio File (*.SDT)", sdt);
|
DECLARE_MULTIPLE_FILE_TYPE("SDT Audio File (*.SDT)", sdt);
|
||||||
|
@ -251,6 +251,7 @@ etc:
|
|||||||
- .sab (Worms 4 soundpacks)
|
- .sab (Worms 4 soundpacks)
|
||||||
- .s14/.sss (G.722.1)
|
- .s14/.sss (G.722.1)
|
||||||
- .sc (Activision EXAKT SASSC DPCM)
|
- .sc (Activision EXAKT SASSC DPCM)
|
||||||
|
- .scd (MS ADPCM, MPEG Audio, 16 bit PCM)
|
||||||
- .sd9 (MS ADPCM)
|
- .sd9 (MS ADPCM)
|
||||||
- .smp (MS ADPCM)
|
- .smp (MS ADPCM)
|
||||||
- .spw (FFXI PS-like ADPCM)
|
- .spw (FFXI PS-like ADPCM)
|
||||||
|
@ -252,7 +252,8 @@ META_OBJS=meta/adx_header.o \
|
|||||||
meta/ffw.o \
|
meta/ffw.o \
|
||||||
meta/ps2_jstm.o \
|
meta/ps2_jstm.o \
|
||||||
meta/ps3_xvag.o \
|
meta/ps3_xvag.o \
|
||||||
meta/ps3_cps.o
|
meta/ps3_cps.o \
|
||||||
|
meta/se_scd.o
|
||||||
|
|
||||||
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)
|
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ void decode_fake_mpeg2_l2(VGMSTREAMCHANNEL * stream,
|
|||||||
mpeg_codec_data * data,
|
mpeg_codec_data * data,
|
||||||
sample * outbuf, int32_t samples_to_do);
|
sample * outbuf, int32_t samples_to_do);
|
||||||
mpeg_codec_data *init_mpeg_codec_data(STREAMFILE *streamfile, off_t start_offset, long given_sample_rate, int given_channels, coding_t *coding_type);
|
mpeg_codec_data *init_mpeg_codec_data(STREAMFILE *streamfile, off_t start_offset, long given_sample_rate, int given_channels, coding_t *coding_type);
|
||||||
|
long mpeg_bytes_to_samples(long bytes, const struct mpg123_frameinfo *mi);
|
||||||
void decode_mpeg(VGMSTREAMCHANNEL * stream,
|
void decode_mpeg(VGMSTREAMCHANNEL * stream,
|
||||||
mpeg_codec_data * data,
|
mpeg_codec_data * data,
|
||||||
sample * outbuf, int32_t samples_to_do, int channels);
|
sample * outbuf, int32_t samples_to_do, int channels);
|
||||||
@ -94,6 +95,7 @@ void decode_acm(ACMStream * acm, sample * outbuf,
|
|||||||
|
|
||||||
void decode_nwa(NWAData *nwa, sample *outbuf, int32_t samples_to_do);
|
void decode_nwa(NWAData *nwa, sample *outbuf, int32_t samples_to_do);
|
||||||
|
|
||||||
|
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels);
|
||||||
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
@ -214,4 +214,8 @@ void decode_mpeg(VGMSTREAMCHANNEL *stream,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long mpeg_bytes_to_samples(long bytes, const struct mpg123_frameinfo *mi) {
|
||||||
|
return bytes * mi->rate * 8 / (mi->bitrate * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -21,6 +21,10 @@ static const int ADPCMCoeffs[7][2] =
|
|||||||
{ 392, -232 }
|
{ 392, -232 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels) {
|
||||||
|
return bytes/block_size*((block_size-(7-1)*channels)*2/channels);
|
||||||
|
}
|
||||||
|
|
||||||
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do) {
|
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do) {
|
||||||
VGMSTREAMCHANNEL *ch1,*ch2;
|
VGMSTREAMCHANNEL *ch1,*ch2;
|
||||||
int i;
|
int i;
|
||||||
|
@ -890,6 +890,10 @@
|
|||||||
RelativePath=".\meta\sdt.c"
|
RelativePath=".\meta\sdt.c"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\meta\se_scd.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\meta\sfl.c"
|
RelativePath=".\meta\sfl.c"
|
||||||
>
|
>
|
||||||
|
@ -205,5 +205,6 @@ libmeta_la_SOURCES += ffw.c
|
|||||||
libmeta_la_SOURCES += ps2_jstm.c
|
libmeta_la_SOURCES += ps2_jstm.c
|
||||||
libmeta_la_SOURCES += ps3_xvag.c
|
libmeta_la_SOURCES += ps3_xvag.c
|
||||||
libmeta_la_SOURCES += ps3_cps.c
|
libmeta_la_SOURCES += ps3_cps.c
|
||||||
|
libmeta_la_SOURCES += se_scd.c
|
||||||
|
|
||||||
EXTRA_DIST = meta.h
|
EXTRA_DIST = meta.h
|
||||||
|
@ -521,5 +521,6 @@ VGMSTREAM * init_vgmstream_ps3_xvag(STREAMFILE* streamFile);
|
|||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ps3_cps(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_ps3_cps(STREAMFILE* streamFile);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_se_scd(STREAMFILE* streamFile);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
143
src/meta/se_scd.c
Normal file
143
src/meta/se_scd.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
/* Square-Enix SCD (FF XIII, XIV) */
|
||||||
|
VGMSTREAM * init_vgmstream_se_scd(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
char filename[260];
|
||||||
|
off_t start_offset, meta_offset_offset, meta_offset, size_offset;
|
||||||
|
int32_t loop_start, loop_end;
|
||||||
|
|
||||||
|
int loop_flag = 0;
|
||||||
|
int channel_count;
|
||||||
|
int codec_id;
|
||||||
|
|
||||||
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||||
|
int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL;
|
||||||
|
|
||||||
|
/* check extension, case insensitive */
|
||||||
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
|
if (strcasecmp("scd",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
|
/* SEDB */
|
||||||
|
if (read_32bitBE(0,streamFile) != 0x53454442) goto fail;
|
||||||
|
/* SSCF */
|
||||||
|
if (read_32bitBE(4,streamFile) != 0x53534346) goto fail;
|
||||||
|
if (read_32bitBE(8,streamFile) == 2) {
|
||||||
|
/* version 2 BE, as seen in FFXIII for PS3 */
|
||||||
|
read_32bit = read_32bitBE;
|
||||||
|
read_16bit = read_16bitBE;
|
||||||
|
size_offset = 0x14;
|
||||||
|
meta_offset_offset = 0x70;
|
||||||
|
} else if (read_32bitLE(8,streamFile) == 3 ||
|
||||||
|
read_32bitLE(8,streamFile) == 2) {
|
||||||
|
/* version 2/3 LE, as seen in FFXIV for ?? */
|
||||||
|
read_32bit = read_32bitLE;
|
||||||
|
read_16bit = read_16bitLE;
|
||||||
|
size_offset = 0x10;
|
||||||
|
meta_offset_offset = 0x70;
|
||||||
|
} else goto fail;
|
||||||
|
|
||||||
|
/* check file size with header value */
|
||||||
|
if (read_32bit(size_offset,streamFile) != get_streamfile_size(streamFile))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* this is probably some kind of chunk offset (?) */
|
||||||
|
meta_offset = read_32bit(0x70,streamFile);
|
||||||
|
|
||||||
|
/* check that chunk size equals stream size (?) */
|
||||||
|
loop_start = read_32bit(meta_offset+0x10,streamFile);
|
||||||
|
loop_end = read_32bit(meta_offset+0x14,streamFile);
|
||||||
|
loop_flag = (loop_end > 0);
|
||||||
|
|
||||||
|
channel_count = read_32bit(meta_offset+4,streamFile);
|
||||||
|
codec_id = read_32bit(meta_offset+0xc,streamFile);
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
/* fill in the vital statistics */
|
||||||
|
vgmstream->channels = channel_count;
|
||||||
|
vgmstream->sample_rate = read_32bit(meta_offset+8,streamFile);
|
||||||
|
start_offset = meta_offset + 0x20 + read_32bit(meta_offset+0x18,streamFile);
|
||||||
|
|
||||||
|
switch (codec_id) {
|
||||||
|
case 0x1:
|
||||||
|
/* PCM */
|
||||||
|
vgmstream->coding_type = coding_PCM16LE_int;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
vgmstream->num_samples = read_32bit(meta_offset+0,streamFile) / 2 / channel_count;
|
||||||
|
|
||||||
|
if (loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = loop_start / 2 / channel_count;
|
||||||
|
vgmstream->loop_end_sample = loop_end / 2 / channel_count;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
case 0x7:
|
||||||
|
/* MPEG */
|
||||||
|
{
|
||||||
|
mpeg_codec_data *mpeg_data = NULL;
|
||||||
|
struct mpg123_frameinfo mi;
|
||||||
|
coding_t ct;
|
||||||
|
|
||||||
|
mpeg_data = init_mpeg_codec_data(streamFile, start_offset, vgmstream->sample_rate, vgmstream->channels, &ct);
|
||||||
|
if (!mpeg_data) goto fail;
|
||||||
|
vgmstream->codec_data = mpeg_data;
|
||||||
|
|
||||||
|
if (MPG123_OK != mpg123_info(mpeg_data->m, &mi)) goto fail;
|
||||||
|
|
||||||
|
vgmstream->coding_type = ct;
|
||||||
|
vgmstream->layout_type = layout_mpeg;
|
||||||
|
if (mi.vbr != MPG123_CBR) goto fail;
|
||||||
|
vgmstream->num_samples = mpeg_bytes_to_samples(read_32bit(meta_offset+0,streamFile), &mi);
|
||||||
|
if (loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = mpeg_bytes_to_samples(loop_start, &mi);
|
||||||
|
vgmstream->loop_end_sample = mpeg_bytes_to_samples(loop_end, &mi);
|
||||||
|
}
|
||||||
|
vgmstream->interleave_block_size = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 0xC:
|
||||||
|
/* MS ADPCM */
|
||||||
|
vgmstream->coding_type = coding_MSADPCM;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
vgmstream->interleave_block_size = read_16bit(meta_offset+0x2c,streamFile);
|
||||||
|
vgmstream->num_samples = msadpcm_bytes_to_samples(read_32bit(meta_offset+0,streamFile), vgmstream->interleave_block_size, vgmstream->channels);
|
||||||
|
|
||||||
|
if (loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = msadpcm_bytes_to_samples(loop_start, vgmstream->interleave_block_size, vgmstream->channels);
|
||||||
|
vgmstream->loop_end_sample = msadpcm_bytes_to_samples(loop_end, vgmstream->interleave_block_size, vgmstream->channels);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
vgmstream->meta_type = meta_SE_SCD;
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
|
||||||
|
vgmstream->ch[i].channel_start_offset=
|
||||||
|
vgmstream->ch[i].offset=start_offset;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
/* clean up anything we may have opened */
|
||||||
|
fail:
|
||||||
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -283,6 +283,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
|||||||
init_vgmstream_ps2_jstm,
|
init_vgmstream_ps2_jstm,
|
||||||
init_vgmstream_ps3_xvag,
|
init_vgmstream_ps3_xvag,
|
||||||
init_vgmstream_ps3_cps,
|
init_vgmstream_ps3_cps,
|
||||||
|
init_vgmstream_se_scd,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
|
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
|
||||||
@ -2664,6 +2665,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
|||||||
break;
|
break;
|
||||||
case meta_PS3_CPS:
|
case meta_PS3_CPS:
|
||||||
snprintf(temp,TEMPSIZE,"CPS Header");
|
snprintf(temp,TEMPSIZE,"CPS Header");
|
||||||
|
break;
|
||||||
|
case meta_SE_SCD:
|
||||||
|
snprintf(temp,TEMPSIZE,"Square-Enix SCD");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");
|
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");
|
||||||
|
@ -484,6 +484,7 @@ typedef enum {
|
|||||||
meta_PS2_JSTM, /* Tantei Jinguji Saburo - Kind of Blue (PS2) */
|
meta_PS2_JSTM, /* Tantei Jinguji Saburo - Kind of Blue (PS2) */
|
||||||
meta_PS3_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */
|
meta_PS3_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */
|
||||||
meta_PS3_CPS, /* Eternal Sonata (PS3) */
|
meta_PS3_CPS, /* Eternal Sonata (PS3) */
|
||||||
|
meta_SE_SCD, /* Square-Enix SCD */
|
||||||
} meta_t;
|
} meta_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -169,6 +169,7 @@ gchar *vgmstream_exts [] = {
|
|||||||
"sad",
|
"sad",
|
||||||
"sap",
|
"sap",
|
||||||
"sc",
|
"sc",
|
||||||
|
"scd",
|
||||||
"sck",
|
"sck",
|
||||||
"sd9",
|
"sd9",
|
||||||
"sdt",
|
"sdt",
|
||||||
|
@ -235,6 +235,7 @@ char * extension_list[] = {
|
|||||||
"sad\0SAD Audio File (*.SAD)\0",
|
"sad\0SAD Audio File (*.SAD)\0",
|
||||||
"sap\0SAP Audio File (*.SAP)\0",
|
"sap\0SAP Audio File (*.SAP)\0",
|
||||||
"sc\0SC Audio File (*.SC)\0",
|
"sc\0SC Audio File (*.SC)\0",
|
||||||
|
"scd\0SCD Audio File (*.SCD)\0",
|
||||||
"sck\0SCK Audio File (*.SCK)\0",
|
"sck\0SCK Audio File (*.SCK)\0",
|
||||||
"sd9\0SD9 Audio File (*.SD9)\0",
|
"sd9\0SD9 Audio File (*.SD9)\0",
|
||||||
"sdt\0SDT Audio File (*.SDT)\0",
|
"sdt\0SDT Audio File (*.SDT)\0",
|
||||||
|
Loading…
Reference in New Issue
Block a user