add SC meta and Activision / EXAKT SASSC 8-bit DPCM for Supercar Street Challenge (PS2)

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@687 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
halleyscometsw 2009-09-04 04:19:39 +00:00
parent 24a05a711d
commit 3f318927da
13 changed files with 172 additions and 4 deletions

View File

@ -224,6 +224,7 @@ etc:
- .mwv (Level-5 0x555 ADPCM)
- .ogg, .logg (Ogg Vorbis)
- .rsf (CCITT G.721 ADPCM)
- .sc (Activision EXAKT SASSC DPCM)
- .sd9 (MS ADPCM)
- .spw (FFXI PS-like ADPCM)
- .str (SDX2 DPCM)

View File

@ -17,7 +17,8 @@ CODING_OBJS=coding/adx_decoder.o \
coding/msadpcm_decoder.o \
coding/aica_decoder.o \
coding/nds_procyon_decoder.o \
coding/l5_555_decoder.o
coding/l5_555_decoder.o \
coding/SASSC_decoder.o
LAYOUT_OBJS=layout/ast_blocked.o \
layout/blocked.o \
@ -207,7 +208,8 @@ META_OBJS=meta/adx_header.o \
meta/ngc_sck_dsp.o \
meta/apple_caff.o \
meta/pc_mxst.o \
meta/pc_sob.o
meta/pc_sob.o \
meta/exakt_sc.o
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)

View File

@ -25,5 +25,6 @@ libcoding_la_SOURCES += aica_decoder.c
libcoding_la_SOURCES += msadpcm_decoder.c
libcoding_la_SOURCES += nds_procyon_decoder.c
libcoding_la_SOURCES += l5_555_decoder.c
libcoding_la_SOURCES += SASSC_decoder.c
EXTRA_DIST = coding.h g72x_state.h

View File

@ -0,0 +1,77 @@
#include "coding.h"
#include "../util.h"
/* Activision / EXAKT Entertainment's DPCM for Supercar Street Challenge */
#if 0
To build table:
int32_t bring_round(int32_t v)
{
return v | (v >> 12);
}
for (i=0x00;i<0x20;i++)
SASSC_steps[i] = bring_round(i<<4);
for (i=0x20;i<0x40;i++)
SASSC_steps[i] = bring_round(((i-0x20)*7+0x20)<<4);
for (i=0x40;i<0x60;i++)
SASSC_steps[i] = bring_round(((i-0x40)*24+0x100)<<4);
for (i=0x60;i<0x80;i++)
SASSC_steps[i] = bring_round(((i-0x60)*96+0x400)<<4);
for (i=0x80;i<0xFF;i++)
SASSC_steps[i] = -SASSC_steps[i-0x80];
SASSC_steps[0xFF] = SASSC_steps[0x7F];
#endif
int32_t SASSC_steps[256] =
{
0, 16, 32, 48, 64, 80, 96, 112,
128, 144, 160, 176, 192, 208, 224, 240,
256, 272, 288, 304, 320, 336, 352, 368,
384, 400, 416, 432, 448, 464, 480, 496,
512, 624, 736, 848, 960, 1072, 1184, 1296,
1408, 1520, 1632, 1744, 1856, 1968, 2080, 2192,
2304, 2416, 2528, 2640, 2752, 2864, 2976, 3088,
3200, 3312, 3424, 3536, 3648, 3760, 3872, 3984,
4097, 4481, 4865, 5249, 5633, 6017, 6401, 6785,
7169, 7553, 7937, 8322, 8706, 9090, 9474, 9858,
10242, 10626, 11010, 11394, 11778, 12162, 12547, 12931,
13315, 13699, 14083, 14467, 14851, 15235, 15619, 16003,
16388, 17924, 19460, 20997, 22533, 24069, 25606, 27142,
28679, 30215, 31751, 33288, 34824, 36360, 37897, 39433,
40970, 42506, 44042, 45579, 47115, 48651, 50188, 51724,
53261, 54797, 56333, 57870, 59406, 60942, 62479, 64015,
0, -16, -32, -48, -64, -80, -96, -112,
-128, -144, -160, -176, -192, -208, -224, -240,
-256, -272, -288, -304, -320, -336, -352, -368,
-384, -400, -416, -432, -448, -464, -480, -496,
-512, -624, -736, -848, -960, -1072, -1184, -1296,
-1408, -1520, -1632, -1744, -1856, -1968, -2080, -2192,
-2304, -2416, -2528, -2640, -2752, -2864, -2976, -3088,
-3200, -3312, -3424, -3536, -3648, -3760, -3872, -3984,
-4097, -4481, -4865, -5249, -5633, -6017, -6401, -6785,
-7169, -7553, -7937, -8322, -8706, -9090, -9474, -9858,
-10242, -10626, -11010, -11394, -11778, -12162, -12547, -12931,
-13315, -13699, -14083, -14467, -14851, -15235, -15619, -16003,
-16388, -17924, -19460, -20997, -22533, -24069, -25606, -27142,
-28679, -30215, -31751, -33288, -34824, -36360, -37897, -39433,
-40970, -42506, -44042, -45579, -47115, -48651, -50188, -51724,
-53261, -54797, -56333, -57870, -59406, -60942, -62479, 64015,
};
void decode_SASSC(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int i;
int32_t sample_count;
int32_t hist = stream->adpcm_history1_32;
for(i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
hist = hist + SASSC_steps[(uint8_t)read_8bit(stream->offset+i,stream->streamfile)];
outbuf[sample_count] = clamp16(hist);
}
stream->adpcm_history1_32 = hist;
}

View File

@ -88,4 +88,6 @@ void decode_nds_procyon(VGMSTREAMCHANNEL * stream, sample * outbuf, int channels
void decode_l5_555(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_SASSC(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
#endif

View File

@ -296,6 +296,10 @@
RelativePath=".\meta\emff.c"
>
</File>
<File
RelativePath=".\meta\exakt_sc.c"
>
</File>
<File
RelativePath=".\meta\fsb.c"
>
@ -970,6 +974,10 @@
RelativePath=".\coding\xa_decoder.c"
>
</File>
<File
RelativePath=".\coding\SASSC_decoder.c"
>
</File>
</Filter>
</Filter>
<Filter

View File

@ -166,5 +166,6 @@ libmeta_la_SOURCES += ngc_sck_dsp.c
libmeta_la_SOURCES += apple_caff.c
libmeta_la_SOURCES += pc_mxst.c
libmeta_la_SOURCES += pc_sob.c
libmeta_la_SOURCES += exakt_sc.c
EXTRA_DIST = meta.h

54
src/meta/exakt_sc.c Normal file
View File

@ -0,0 +1,54 @@
#include "meta.h"
#include "../util.h"
/* .SC - from Activision's EXAKT system, seen in Supercar Street Challenge */
VGMSTREAM * init_vgmstream_exakt_sc(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[260];
size_t file_size;
/* check extension, case insensitive */
/* this is all we have to go on, SC is completely headerless */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("sc",filename_extension(filename))) goto fail;
file_size = get_streamfile_size(streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(2,0);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = file_size / 2;
vgmstream->sample_rate = 44100;
vgmstream->coding_type = coding_SASSC;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x100;
vgmstream->meta_type = meta_EXAKT_SC;
/* open the file for reading by each channel */
{
int i;
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[i].streamfile) goto fail;
vgmstream->ch[i].channel_start_offset=
vgmstream->ch[i].offset=vgmstream->interleave_block_size*i;
}
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -411,4 +411,6 @@ VGMSTREAM * init_vgmstream_pc_mxst(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_sab(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_exakt_sc(STREAMFILE* streamFile);
#endif

View File

@ -225,7 +225,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
init_vgmstream_apple_caff,
init_vgmstream_pc_mxst,
init_vgmstream_sab,
init_vgmstream_exakt_sc,
};
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
@ -685,6 +685,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
case coding_NWA3:
case coding_NWA4:
case coding_NWA5:
case coding_SASSC:
return 1;
case coding_NDS_IMA:
return (vgmstream->interleave_block_size-4)*2;
@ -766,6 +767,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
case coding_NWA3:
case coding_NWA4:
case coding_NWA5:
case coding_SASSC:
return 1;
case coding_MS_IMA:
case coding_NDS_IMA:
@ -1157,6 +1159,14 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
samples_to_do);
}
break;
case coding_SASSC:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_SASSC(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
vgmstream->channels,vgmstream->samples_into_block,
samples_to_do);
}
break;
}
}
@ -1499,6 +1509,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
case coding_L5_555:
snprintf(temp,TEMPSIZE,"Level-5 0x555 ADPCM");
break;
case coding_SASSC:
snprintf(temp,TEMPSIZE,"Activision / EXAKT SASSC 8-bit DPCM");
break;
default:
snprintf(temp,TEMPSIZE,"CANNOT DECODE");
}
@ -2291,6 +2304,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
case meta_MAXIS_XA:
snprintf(temp,TEMPSIZE,"Maxis XAI/XAJ Header");
break;
case meta_EXAKT_SC:
snprintf(temp,TEMPSIZE,"assumed Activision / EXAKT SC by extension");
break;
default:
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");
}

View File

@ -102,6 +102,7 @@ typedef enum {
coding_MSADPCM, /* Microsoft ADPCM */
coding_AICA, /* Yamaha AICA ADPCM */
coding_L5_555, /* Level-5 0x555 */
coding_SASSC, /* Activision EXAKT SASSC DPCM */
} coding_t;
/* The layout type specifies how the sound data is laid out in the file */
@ -411,6 +412,7 @@ typedef enum {
meta_MAXIS_XA, /* Sim City 3000 (PC) */
meta_NGC_SCK_DSP, /* Scorpion King (NGC) */
meta_CAFF, /* iPhone .caf */
meta_EXAKT_SC, /* Activision EXAKT .SC (PS2) */
} meta_t;
typedef struct {

View File

@ -184,7 +184,8 @@ gchar *vgmstream_exts [] = {
"hwas",
"caf",
"mxst",
"sab"
"sab",
"sc",
/* terminator */
NULL
};

View File

@ -209,6 +209,7 @@ char * extension_list[] = {
"sab\0SAB Audio File (*.SAB)\0",
"sad\0SAD Audio File (*.SAD)\0",
"sap\0SAP Audio File (*.SAP)\0",
"sc\0SC Audio File (*.SC)\0",
"sck\0SCK Audio File (*.SCK)\0",
"sd9\0SD9 Audio File (*.SD9)\0",
"sdt\0SDT Audio File (*.SDT)\0",