JSTM (.stm) from Tantei Jinguji Saburo - Kind of Blue. Includes a simple XOR obfuscation.

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@821 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
halleyscometsw 2010-08-28 01:43:40 +00:00
parent c802e2015b
commit 5df5090fdd
10 changed files with 103 additions and 2 deletions

View File

@ -1,4 +1,4 @@
Copyright (c) 2008-2009 Adam Gashlin, Fastelbja, Ronny Elfert
Copyright (c) 2008-2010 Adam Gashlin, Fastelbja, Ronny Elfert
Portions Copyright (c) 2004-2008, Marko Kreen
Portions Copyright 2001-2007 jagarl / Kazunori Ueno <jagarl@creator.club.ne.jp>

View File

@ -249,7 +249,8 @@ META_OBJS=meta/adx_header.o \
meta/ps2_vms.o \
meta/ps2_xau.o \
meta/gh3_bar.o \
meta/ffw.o
meta/ffw.o \
meta/ps2_jstm.o
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)

View File

@ -40,6 +40,7 @@ void decode_ngc_dtk(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
void decode_pcm16LE(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_pcm16LE_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_pcm16LE_XOR_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_pcm16BE(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_pcm8(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_pcm8_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);

View File

@ -76,3 +76,12 @@ void decode_pcm16LE_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channels
outbuf[sample_count]=read_16bitLE(stream->offset+i*2*channelspacing,stream->streamfile);
}
}
void decode_pcm16LE_XOR_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int i;
int32_t sample_count;
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
outbuf[sample_count]=read_16bitLE(stream->offset+i*2*channelspacing,stream->streamfile)^stream->key_xor;
}
}

View File

@ -634,6 +634,10 @@
RelativePath=".\meta\ps2_joe.c"
>
</File>
<File
RelativePath=".\meta\ps2_jstm.c"
>
</File>
<File
RelativePath=".\meta\ps2_kces.c"
>

View File

@ -202,5 +202,6 @@ libmeta_la_SOURCES += ps2_vms.c
libmeta_la_SOURCES += ps2_xau.c
libmeta_la_SOURCES += gh3_bar.c
libmeta_la_SOURCES += ffw.c
libmeta_la_SOURCES += ps2_jstm.c
EXTRA_DIST = meta.h

View File

@ -515,4 +515,6 @@ VGMSTREAM * init_vgmstream_ffw(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_dsp_dspw(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_ps2_jstm(STREAMFILE* streamFile);
#endif

62
src/meta/ps2_jstm.c Normal file
View File

@ -0,0 +1,62 @@
#include "meta.h"
#include "../util.h"
/* JSTM (.STM from Tantei Jinguji Saburo - Kind of Blue) */
VGMSTREAM * init_vgmstream_ps2_jstm(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset = 0x20;;
int loop_flag;
int channel_count;
char filename[260];
/* check extension */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("stm",filename_extension(filename))) goto fail;
/* check header (JSTM) */
if (read_32bitBE(0x0,streamFile) != 0x4A53544D) goto fail;
loop_flag = (read_32bitLE(0x14,streamFile) != 0);
channel_count = read_16bitLE(0x4,streamFile);
// hmm, don't know what 6 is, one is probably bytes per sample and the
// other is channels, but who can say?
if (channel_count != read_16bitLE(0x6,streamFile)) goto fail;
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the statistics vitale */
vgmstream->sample_rate = read_32bitLE(0x8,streamFile);
vgmstream->coding_type = coding_PCM16LE_XOR_int;
vgmstream->num_samples = read_32bitLE(0xC,streamFile)/2/channel_count;
vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_PS2_JSTM;
if (loop_flag) {
vgmstream->loop_start_sample=read_32bitLE(0x14,streamFile)/2/channel_count;
vgmstream->loop_end_sample=vgmstream->num_samples;
}
/* 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 + 2*i;
vgmstream->ch[i].key_xor = 0x5A5A;
}
}
return vgmstream;
fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -280,6 +280,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
init_vgmstream_gh3_bar,
init_vgmstream_ffw,
init_vgmstream_dsp_dspw,
init_vgmstream_ps2_jstm,
};
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
@ -747,6 +748,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
return 14;
case coding_PCM16LE:
case coding_PCM16LE_int:
case coding_PCM16LE_XOR_int:
case coding_PCM16BE:
case coding_PCM8:
case coding_PCM8_U:
@ -855,6 +857,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
return 8;
case coding_PCM16LE:
case coding_PCM16LE_int:
case coding_PCM16LE_XOR_int:
case coding_PCM16BE:
return 2;
case coding_PCM8:
@ -990,6 +993,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
samples_to_do);
}
break;
case coding_PCM16LE_XOR_int:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_pcm16LE_XOR_int(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
vgmstream->channels,vgmstream->samples_into_block,
samples_to_do);
}
break;
case coding_PCM16BE:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_pcm16BE(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
@ -1509,6 +1519,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
case coding_PCM16LE_int:
snprintf(temp,TEMPSIZE,"Little Endian 16-bit PCM with 2 byte interleave");
break;
case coding_PCM16LE_XOR_int:
snprintf(temp,TEMPSIZE,"Little Endian 16-bit PCM with 2 byte interleave and XOR obfuscation");
break;
case coding_PCM8:
snprintf(temp,TEMPSIZE,"8-bit PCM");
break;
@ -2640,6 +2653,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
break;
case meta_DSP_DSPW:
snprintf(temp,TEMPSIZE,"DSPW dsp header");
break;
case meta_PS2_JSTM:
snprintf(temp,TEMPSIZE,"JSTM Header");
break;
default:
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");

View File

@ -120,6 +120,7 @@ typedef enum {
coding_AICA, /* Yamaha AICA ADPCM */
coding_L5_555, /* Level-5 0x555 */
coding_SASSC, /* Activision EXAKT SASSC DPCM */
coding_PCM16LE_XOR_int, /* sample-level xor */
} coding_t;
/* The layout type specifies how the sound data is laid out in the file */
@ -480,6 +481,7 @@ typedef enum {
meta_GH3_BAR, /* Guitar Hero III Mobile .bar */
meta_FFW, /* Freedom Fighters [NGC] */
meta_DSP_DSPW, /* Sengoku Basara 3 [WII] */
meta_PS2_JSTM, /* Tantei Jinguji Saburo - Kind of Blue (PS2) */
} meta_t;
typedef struct {
@ -531,6 +533,9 @@ typedef struct {
/* BMDX encryption */
uint8_t bmdx_xor;
uint8_t bmdx_add;
/* generic encryption */
uint16_t key_xor;
} VGMSTREAMCHANNEL;
typedef struct {