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_history1_32 = hist1;
|
||||||
stream->adpcm_history2_32 = hist2;
|
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"
|
#include "../vgmstream.h"
|
||||||
|
|
||||||
void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
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 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);
|
void g72x_init_state(struct g72x_state *state_ptr);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
||||||
@ -20,6 +21,8 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
|||||||
int16_t coef1, coef2;
|
int16_t coef1, coef2;
|
||||||
uint16_t cutoff;
|
uint16_t cutoff;
|
||||||
char filename[260];
|
char filename[260];
|
||||||
|
int coding_type = coding_CRI_ADX;
|
||||||
|
uint16_t xor_start=0,xor_mult=0,xor_add=0;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
@ -49,6 +52,16 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
/* check version signature, read loop info */
|
/* check version signature, read loop info */
|
||||||
version_signature = read_16bitBE(0x12,streamFile);
|
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 */
|
if (version_signature == 0x0300) { /* type 03 */
|
||||||
header_type = meta_ADX_03;
|
header_type = meta_ADX_03;
|
||||||
if (stream_offset-6 >= 0x2c) { /* enough space for loop info? */
|
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_start_sample = loop_start_sample;
|
||||||
vgmstream->loop_end_sample = loop_end_sample;
|
vgmstream->loop_end_sample = loop_end_sample;
|
||||||
|
|
||||||
vgmstream->coding_type = coding_CRI_ADX;
|
vgmstream->coding_type = coding_type;
|
||||||
if (channel_count==1)
|
if (channel_count==1)
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
else
|
else
|
||||||
@ -136,6 +149,18 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
|
|||||||
|
|
||||||
vgmstream->ch[i].adpcm_coef[0] = coef1;
|
vgmstream->ch[i].adpcm_coef[0] = coef1;
|
||||||
vgmstream->ch[i].adpcm_coef[1] = coef2;
|
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) {
|
int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
|
||||||
switch (vgmstream->coding_type) {
|
switch (vgmstream->coding_type) {
|
||||||
case coding_CRI_ADX:
|
case coding_CRI_ADX:
|
||||||
|
case coding_CRI_ADX_enc:
|
||||||
return 32;
|
return 32;
|
||||||
case coding_NGC_DSP:
|
case coding_NGC_DSP:
|
||||||
return 14;
|
return 14;
|
||||||
@ -643,6 +644,7 @@ int get_vgmstream_samples_per_shortframe(VGMSTREAM * vgmstream) {
|
|||||||
int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
|
||||||
switch (vgmstream->coding_type) {
|
switch (vgmstream->coding_type) {
|
||||||
case coding_CRI_ADX:
|
case coding_CRI_ADX:
|
||||||
|
case coding_CRI_ADX_enc:
|
||||||
return 18;
|
return 18;
|
||||||
case coding_NGC_DSP:
|
case coding_NGC_DSP:
|
||||||
return 8;
|
return 8;
|
||||||
@ -735,6 +737,14 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
|
|||||||
samples_to_do);
|
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;
|
break;
|
||||||
case coding_NGC_DSP:
|
case coding_NGC_DSP:
|
||||||
for (chan=0;chan<vgmstream->channels;chan++) {
|
for (chan=0;chan<vgmstream->channels;chan++) {
|
||||||
@ -1172,6 +1182,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
|||||||
case coding_CRI_ADX:
|
case coding_CRI_ADX:
|
||||||
snprintf(temp,TEMPSIZE,"CRI ADX 4-bit ADPCM");
|
snprintf(temp,TEMPSIZE,"CRI ADX 4-bit ADPCM");
|
||||||
break;
|
break;
|
||||||
|
case coding_CRI_ADX_enc:
|
||||||
|
snprintf(temp,TEMPSIZE,"encrypted CRI ADX 4-bit ADPCM");
|
||||||
|
break;
|
||||||
case coding_NDS_IMA:
|
case coding_NDS_IMA:
|
||||||
snprintf(temp,TEMPSIZE,"NDS-style 4-bit IMA ADPCM");
|
snprintf(temp,TEMPSIZE,"NDS-style 4-bit IMA ADPCM");
|
||||||
break;
|
break;
|
||||||
|
@ -43,6 +43,7 @@ typedef enum {
|
|||||||
/* 4-bit ADPCM */
|
/* 4-bit ADPCM */
|
||||||
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
|
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
|
||||||
coding_CRI_ADX, /* CRI ADX */
|
coding_CRI_ADX, /* CRI ADX */
|
||||||
|
coding_CRI_ADX_enc, /* encrypted CRI ADX */
|
||||||
coding_NGC_DSP, /* NGC ADPCM, called DSP */
|
coding_NGC_DSP, /* NGC ADPCM, called DSP */
|
||||||
coding_NGC_DTK, /* NGC hardware disc ADPCM, called DTK, TRK or ADP */
|
coding_NGC_DTK, /* NGC hardware disc ADPCM, called DTK, TRK or ADP */
|
||||||
coding_G721, /* CCITT G.721 ADPCM */
|
coding_G721, /* CCITT G.721 ADPCM */
|
||||||
@ -384,6 +385,12 @@ typedef struct {
|
|||||||
int samples_done;
|
int samples_done;
|
||||||
int16_t loop_history1,loop_history2;
|
int16_t loop_history1,loop_history2;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ADX encryption */
|
||||||
|
int adx_channels;
|
||||||
|
uint16_t adx_xor;
|
||||||
|
uint16_t adx_mult;
|
||||||
|
uint16_t adx_add;
|
||||||
} VGMSTREAMCHANNEL;
|
} VGMSTREAMCHANNEL;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user