diff --git a/src/coding/coding.h b/src/coding/coding.h index db8898d5..c6bb854d 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -59,7 +59,6 @@ void decode_ngc_afc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci /* pcm_decoder */ void decode_pcm16LE(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_pcm16_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int big_endian); void decode_pcm8(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); diff --git a/src/coding/pcm_decoder.c b/src/coding/pcm_decoder.c index c2f3732f..406f0dff 100644 --- a/src/coding/pcm_decoder.c +++ b/src/coding/pcm_decoder.c @@ -78,15 +78,6 @@ void decode_pcm16_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspa } } -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; ioffset+i*2*channelspacing,stream->streamfile)^stream->key_xor; - } -} - static int expand_ulaw(uint8_t ulawbyte) { int sign, segment, quantization, new_sample; const int bias = 0x84; diff --git a/src/formats.c b/src/formats.c index 7c2bd671..bf131d5f 100644 --- a/src/formats.c +++ b/src/formats.c @@ -436,7 +436,6 @@ typedef struct { static const coding_info coding_info_list[] = { {coding_PCM16LE, "Little Endian 16-bit PCM"}, - {coding_PCM16LE_XOR_int, "Little Endian 16-bit PCM with 2 byte interleave and XOR obfuscation"}, {coding_PCM16BE, "Big Endian 16-bit PCM"}, {coding_PCM16_int, "16-bit PCM with 2 byte interleave (block)"}, {coding_PCM8, "8-bit PCM"}, diff --git a/src/meta/ps2_jstm.c b/src/meta/ps2_jstm.c index bb739995..c9611fb3 100644 --- a/src/meta/ps2_jstm.c +++ b/src/meta/ps2_jstm.c @@ -1,63 +1,104 @@ #include "meta.h" -#include "../util.h" +#include "../coding/coding.h" -/* JSTM (.STM (renamed .JSTM) from Tantei Jinguji Saburo - Kind of Blue) */ +static STREAMFILE* setup_jstm_streamfile(STREAMFILE *streamFile, off_t start_offset); + +/* JSTM - from Tantei Jinguji Saburo - Kind of Blue (PS2) */ VGMSTREAM * init_vgmstream_ps2_jstm(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; - off_t start_offset = 0x20; - int loop_flag; - int channel_count; - char filename[PATH_LIMIT]; + STREAMFILE *temp_streamFile = NULL; + off_t start_offset; + int loop_flag, channel_count; - /* check extension */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("stm",filename_extension(filename)) && - strcasecmp("jstm",filename_extension(filename))) goto fail; - /* check header (JSTM) */ - if (read_32bitBE(0x0,streamFile) != 0x4A53544D) goto fail; + /* checks */ + /* .stm: original, .jstm: header id */ + if (!check_extensions(streamFile, "stm,jstm")) + goto fail; + if (read_32bitBE(0x00,streamFile) != 0x4A53544D) /* "JSTM" */ + 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; + start_offset = 0x20; + channel_count = read_16bitLE(0x04,streamFile); + if (channel_count != read_16bitLE(0x06,streamFile)) /* 0x02, interleave? */ + goto fail; + loop_flag = (read_32bitLE(0x14,streamFile) != -1); + /* build the VGMSTREAM */ 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->sample_rate = read_32bitLE(0x08,streamFile); + vgmstream->num_samples = pcm_bytes_to_samples(read_32bitLE(0x0C,streamFile),channel_count,16); + if (loop_flag) { + vgmstream->loop_start_sample = pcm_bytes_to_samples(read_32bitLE(0x14,streamFile),channel_count,16); + vgmstream->loop_end_sample = vgmstream->num_samples; + } vgmstream->meta_type = meta_PS2_JSTM; + vgmstream->coding_type = coding_PCM16LE; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x02; - 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; - } - } + temp_streamFile = setup_jstm_streamfile(streamFile, start_offset); + if (!temp_streamFile) goto fail; + if (!vgmstream_open_stream(vgmstream,temp_streamFile,start_offset)) + goto fail; + + close_streamfile(temp_streamFile); + return vgmstream; fail: - if (vgmstream) close_vgmstream(vgmstream); + close_streamfile(temp_streamFile); + close_vgmstream(vgmstream); + return NULL; +} + + +typedef struct { + off_t start_offset; +} jstm_decryption_data; + +static size_t jstm_decryption_read(STREAMFILE *streamfile, uint8_t *dest, off_t offset, size_t length, jstm_decryption_data* data) { + size_t bytes_read; + int i; + + bytes_read = streamfile->read(streamfile, dest, offset, length); + + /* decrypt data (xor) */ + for (i = 0; i < bytes_read; i++) { + if (offset+i >= data->start_offset) { + //VGM_LOG("xor %x to %x\n", dest[i], dest[i] ^ 0x5A);getchar(); + dest[i] = dest[i] ^ 0x5A; + } + } + + return bytes_read; +} + +static STREAMFILE* setup_jstm_streamfile(STREAMFILE *streamFile, off_t start_offset) { + STREAMFILE *temp_streamFile = NULL, *new_streamFile = NULL; + jstm_decryption_data io_data = {0}; + size_t io_data_size = sizeof(jstm_decryption_data); + + /* setup decryption */ + io_data.start_offset = start_offset; + + + /* setup custom streamfile */ + new_streamFile = open_wrap_streamfile(streamFile); + if (!new_streamFile) goto fail; + temp_streamFile = new_streamFile; + + new_streamFile = open_io_streamfile(temp_streamFile, &io_data,io_data_size, jstm_decryption_read); + if (!new_streamFile) goto fail; + temp_streamFile = new_streamFile; + + return temp_streamFile; + +fail: + close_streamfile(temp_streamFile); return NULL; } diff --git a/src/vgmstream.c b/src/vgmstream.c index 82138279..e55fca7a 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -963,7 +963,6 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) { return 1; case coding_PCM16LE: - case coding_PCM16LE_XOR_int: case coding_PCM16BE: case coding_PCM16_int: case coding_PCM8: @@ -1131,7 +1130,6 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) { return 0; case coding_PCM16LE: - case coding_PCM16LE_XOR_int: case coding_PCM16BE: case coding_PCM16_int: return 0x02; @@ -1338,13 +1336,6 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to samples_to_do); } break; - case coding_PCM16LE_XOR_int: - for (chan=0;chanchannels;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;chanchannels;chan++) { decode_pcm16BE(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan, diff --git a/src/vgmstream.h b/src/vgmstream.h index 3e0baa9a..db65bec8 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -78,7 +78,6 @@ enum { STREAM_NAME_SIZE = 255 }; /* reasonable max */ typedef enum { /* PCM */ coding_PCM16LE, /* little endian 16-bit PCM */ - coding_PCM16LE_XOR_int, /* little endian 16-bit PCM with sample-level xor (for blocks) */ coding_PCM16BE, /* big endian 16-bit PCM */ coding_PCM16_int, /* 16-bit PCM with sample-level interleave (for blocks) */ @@ -715,8 +714,6 @@ typedef struct { uint16_t adx_mult; uint16_t adx_add; - /* generic encryption */ - uint16_t key_xor; } VGMSTREAMCHANNEL; /* main vgmstream info */