mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-18 07:44:43 +01:00
Encrypted ADX playback, currently assumed Clover Stuios key without any checking
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@533 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
4b578db302
commit
c70680a1e6
@ -33,3 +33,49 @@ void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
stream->adpcm_history2_32 = hist2;
|
||||
}
|
||||
|
||||
void adx_next_key(VGMSTREAMCHANNEL * stream)
|
||||
{
|
||||
stream->adx_xor = ( stream->adx_xor * stream->adx_mult + stream->adx_add ) & 0x7fff;
|
||||
}
|
||||
|
||||
void decode_adx_enc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i;
|
||||
int32_t sample_count;
|
||||
|
||||
int framesin = first_sample/32;
|
||||
|
||||
int32_t scale = (read_16bitBE(stream->offset+framesin*18,stream->streamfile) ^ stream->adx_xor) + 1;
|
||||
int32_t hist1 = stream->adpcm_history1_32;
|
||||
int32_t hist2 = stream->adpcm_history2_32;
|
||||
int coef1 = stream->adpcm_coef[0];
|
||||
int coef2 = stream->adpcm_coef[1];
|
||||
|
||||
first_sample = first_sample%32;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
int sample_byte = read_8bit(stream->offset+framesin*18+2+i/2,stream->streamfile);
|
||||
|
||||
outbuf[sample_count] = clamp16(
|
||||
(i&1?
|
||||
get_low_nibble_signed(sample_byte):
|
||||
get_high_nibble_signed(sample_byte)
|
||||
) * scale +
|
||||
((coef1 * hist1 + coef2 * hist2) >> 12)
|
||||
);
|
||||
|
||||
hist2 = hist1;
|
||||
hist1 = outbuf[sample_count];
|
||||
}
|
||||
|
||||
stream->adpcm_history1_32 = hist1;
|
||||
stream->adpcm_history2_32 = hist2;
|
||||
|
||||
if (!(i % 32)) {
|
||||
for (i=0;i<stream->adx_channels;i++)
|
||||
{
|
||||
adx_next_key(stream);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include "../vgmstream.h"
|
||||
|
||||
void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_adx_enc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
|
||||
void adx_next_key(VGMSTREAMCHANNEL * stream);
|
||||
|
||||
void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void g72x_init_state(struct g72x_state *state_ptr);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#endif
|
||||
#include <math.h>
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
||||
@ -20,6 +21,8 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
||||
int16_t coef1, coef2;
|
||||
uint16_t cutoff;
|
||||
char filename[260];
|
||||
int coding_type = coding_CRI_ADX;
|
||||
uint16_t xor_start=0,xor_mult=0,xor_add=0;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
@ -49,6 +52,16 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
||||
|
||||
/* check version signature, read loop info */
|
||||
version_signature = read_16bitBE(0x12,streamFile);
|
||||
/* encryption */
|
||||
if (version_signature == 0x0408) {
|
||||
/* TODO: check key */
|
||||
coding_type = coding_CRI_ADX_enc;
|
||||
/* Clover Studio (GOD HAND, Okami), 2nd result from guessadx */
|
||||
xor_start = 0x49e1;
|
||||
xor_mult = 0x4a57;
|
||||
xor_add = 0x553d;
|
||||
version_signature = 0x0400;
|
||||
}
|
||||
if (version_signature == 0x0300) { /* type 03 */
|
||||
header_type = meta_ADX_03;
|
||||
if (stream_offset-6 >= 0x2c) { /* enough space for loop info? */
|
||||
@ -94,7 +107,7 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
||||
vgmstream->loop_start_sample = loop_start_sample;
|
||||
vgmstream->loop_end_sample = loop_end_sample;
|
||||
|
||||
vgmstream->coding_type = coding_CRI_ADX;
|
||||
vgmstream->coding_type = coding_type;
|
||||
if (channel_count==1)
|
||||
vgmstream->layout_type = layout_none;
|
||||
else
|
||||
@ -136,6 +149,18 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
||||
|
||||
vgmstream->ch[i].adpcm_coef[0] = coef1;
|
||||
vgmstream->ch[i].adpcm_coef[1] = coef2;
|
||||
|
||||
if (coding_type == coding_CRI_ADX_enc)
|
||||
{
|
||||
int j;
|
||||
vgmstream->ch[i].adx_channels = channel_count;
|
||||
vgmstream->ch[i].adx_xor = xor_start;
|
||||
vgmstream->ch[i].adx_mult = xor_mult;
|
||||
vgmstream->ch[i].adx_add = xor_add;
|
||||
|
||||
for (j=0;j<i;j++)
|
||||
adx_next_key(&vgmstream->ch[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,6 +558,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||
switch (vgmstream->coding_type) {
|
||||
case coding_CRI_ADX:
|
||||
case coding_CRI_ADX_enc:
|
||||
return 32;
|
||||
case coding_NGC_DSP:
|
||||
return 14;
|
||||
@ -643,6 +644,7 @@ int get_vgmstream_samples_per_shortframe(VGMSTREAM * vgmstream) {
|
||||
int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||
switch (vgmstream->coding_type) {
|
||||
case coding_CRI_ADX:
|
||||
case coding_CRI_ADX_enc:
|
||||
return 18;
|
||||
case coding_NGC_DSP:
|
||||
return 8;
|
||||
@ -735,6 +737,14 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
||||
samples_to_do);
|
||||
}
|
||||
|
||||
break;
|
||||
case coding_CRI_ADX_enc:
|
||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||
decode_adx_enc(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
|
||||
vgmstream->channels,vgmstream->samples_into_block,
|
||||
samples_to_do);
|
||||
}
|
||||
|
||||
break;
|
||||
case coding_NGC_DSP:
|
||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||
@ -1172,6 +1182,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case coding_CRI_ADX:
|
||||
snprintf(temp,TEMPSIZE,"CRI ADX 4-bit ADPCM");
|
||||
break;
|
||||
case coding_CRI_ADX_enc:
|
||||
snprintf(temp,TEMPSIZE,"encrypted CRI ADX 4-bit ADPCM");
|
||||
break;
|
||||
case coding_NDS_IMA:
|
||||
snprintf(temp,TEMPSIZE,"NDS-style 4-bit IMA ADPCM");
|
||||
break;
|
||||
|
@ -43,6 +43,7 @@ typedef enum {
|
||||
/* 4-bit ADPCM */
|
||||
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
|
||||
coding_CRI_ADX, /* CRI ADX */
|
||||
coding_CRI_ADX_enc, /* encrypted CRI ADX */
|
||||
coding_NGC_DSP, /* NGC ADPCM, called DSP */
|
||||
coding_NGC_DTK, /* NGC hardware disc ADPCM, called DTK, TRK or ADP */
|
||||
coding_G721, /* CCITT G.721 ADPCM */
|
||||
@ -384,6 +385,12 @@ typedef struct {
|
||||
int samples_done;
|
||||
int16_t loop_history1,loop_history2;
|
||||
#endif
|
||||
|
||||
/* ADX encryption */
|
||||
int adx_channels;
|
||||
uint16_t adx_xor;
|
||||
uint16_t adx_mult;
|
||||
uint16_t adx_add;
|
||||
} VGMSTREAMCHANNEL;
|
||||
|
||||
typedef struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user