This commit is contained in:
bnnm 2022-07-31 15:14:25 +02:00
parent bd5af18732
commit 4e390bd61a
10 changed files with 71 additions and 69 deletions

View File

@ -167,7 +167,7 @@ void decode_msadpcm_stereo(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t first
void decode_msadpcm_mono(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int config);
void decode_msadpcm_ck(VGMSTREAM* vgmstream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels);
int msadpcm_check_coefs(STREAMFILE* sf, off_t offset);
int msadpcm_check_coefs(STREAMFILE* sf, uint32_t offset);
/* yamaha_decoder */

View File

@ -34,7 +34,7 @@ struct ffmpeg_codec_data {
int bad_init;
// FFmpeg context used for metadata
AVCodec* codec;
const AVCodec* codec;
/* FFmpeg decoder state */
unsigned char* buffer;

View File

@ -248,11 +248,11 @@ long msadpcm_bytes_to_samples(long bytes, int block_size, int channels) {
}
/* test if MSADPCM coefs were re-defined (possible in theory but not used in practice) */
int msadpcm_check_coefs(STREAMFILE* sf, off_t offset) {
int msadpcm_check_coefs(STREAMFILE* sf, uint32_t offset) {
int i;
int count = read_u16le(offset, sf);
if (count != 7) {
vgm_logi("MSADPCM: bad count %i at %lx (report)\n", count, offset);
vgm_logi("MSADPCM: bad count %i at %x (report)\n", count, offset);
goto fail;
}

View File

@ -25,16 +25,16 @@ VGMSTREAM* init_vgmstream_adx(STREAMFILE* sf) {
VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
VGMSTREAM* vgmstream = NULL;
off_t start_offset, hist_offset = 0;
int loop_flag = 0, channel_count;
int32_t loop_start_sample = 0, loop_end_sample = 0;
int loop_flag = 0, channels, sample_rate;
int32_t num_samples, loop_start_sample = 0, loop_end_sample = 0;
uint16_t cutoff;
uint16_t version;
uint8_t encoding_type;
uint8_t frame_size;
uint8_t encoding_type, frame_size;
int16_t coef1, coef2;
uint16_t xor_start = 0, xor_mult = 0, xor_add = 0;
meta_t header_type;
coding_t coding_type;
int16_t coef1, coef2;
uint16_t xor_start=0,xor_mult=0,xor_add=0;
/* checks*/
@ -46,11 +46,13 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
if (!check_extensions(sf,"adx,adp"))
goto fail;
/* CRI checks both 0x8000 and memcmps this */
start_offset = read_u16be(0x02,sf) + 0x04;
if (read_u16be(start_offset - 0x06,sf) != 0x2863 || /* "(c" */
read_u32be(start_offset - 0x04,sf) != 0x29435249) /* ")CRI" */
goto fail;
encoding_type = read_u8(0x04, sf);
switch (encoding_type) {
case 0x02:
@ -67,19 +69,19 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
}
/* ADX encoders can't set this value, but is honored by ADXPlay if changed and multiple of 0x12,
* though output is unusual and may not be fully supported (works in mono so not an interleave) */
frame_size = read_8bit(0x05, sf);
* though output is unusual and may not be fully supported (works in mono so not an interleave)
* Later versions of the decode just use constant 0x12 ignoring it, though. */
frame_size = read_u8(0x05, sf);
if (read_u8(0x06,sf) != 4) /* bits per sample */
goto fail;
/* older ADX (adxencd) up to 2ch, newer ADX (criatomencd) up to 8 */
channel_count = read_u8(0x07,sf);
/* 0x08: sample rate */
/* 0x0c: samples */
/* 0x10: high-pass frequency */
version = read_u16be(0x12,sf);
channels = read_u8(0x07,sf);
sample_rate = read_s32be(0x08,sf);
num_samples = read_s32be(0x0c,sf);
cutoff = read_u16be(0x10,sf); /* high-pass cutoff frequency, always 500 */
version = read_u16be(0x12,sf); /* version + revision, originally read as separate */
/* encryption */
if (version == 0x0408) {
@ -111,12 +113,12 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
/* 0x00 (2): initial loop padding (the encoder adds a few blank samples so loop start is block-aligned; max 31)
* ex. loop_start=12: enc_start=32, padding=20 (32-20=12); loop_start=35: enc_start=64, padding=29 (64-29=35)
* 0x02 (2): loop sample(?) flag (always 1) */
loop_flag = read_32bitBE(loops_offset+0x04,sf) != 0; /* loop offset(?) flag (always 1) */
loop_start_sample = read_32bitBE(loops_offset+0x08,sf);
//loop_start_offset = read_32bitBE(loops_offset+0x0c,sf);
loop_end_sample = read_32bitBE(loops_offset+0x10,sf);
//loop_end_offset = read_32bitBE(loops_offset+0x14,sf);
* 0x02 (2): loop flag? (always 1) */
loop_flag = read_s32be(loops_offset+0x04,sf) != 0; /* loop count + loop type? (always 1) */
loop_start_sample = read_s32be(loops_offset+0x08,sf);
//loop_start_offset = read_u32be(loops_offset+0x0c,sf);
loop_end_sample = read_s32be(loops_offset+0x10,sf);
//loop_end_offset = read_u32be(loops_offset+0x14,sf);
}
}
else if (version == 0x0400) { /* common */
@ -126,23 +128,23 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
header_type = meta_ADX_04;
hist_offset = base_size; /* always present but often blank */
hist_size = (channel_count > 1 ? 0x04 * channel_count : 0x04 + 0x04); /* min is 8, even in 1ch files */
hist_size = (channels > 1 ? 0x04 * channels : 0x04 + 0x04); /* min is 0x8, even in 1ch files */
ainf_offset = base_size + hist_size + 0x04; /* not seen with >2ch though */
if (read_u32be(ainf_offset+0x00,sf) == 0x41494E46) /* "AINF" */
ainf_size = read_32bitBE(ainf_offset+0x04,sf);
if (is_id32be(ainf_offset+0x00,sf, "AINF"))
ainf_size = read_u32be(ainf_offset+0x04,sf);
if (start_offset - ainf_size - 0x06 >= hist_offset + hist_size + loops_size) { /* enough space for loop info? */
off_t loops_offset = base_size + hist_size;
/* 0x00 (2): initial loop padding (the encoder adds a few blank samples so loop start is block-aligned; max 31)
* ex. loop_start=12: enc_start=32, padding=20 (32-20=12); loop_start=35: enc_start=64, padding=29 (64-29=35)
* 0x02 (2): loop sample(?) flag (always 1) */
loop_flag = read_32bitBE(loops_offset+0x04,sf) != 0; /* loop offset(?) flag (always 1) */
loop_start_sample = read_32bitBE(loops_offset+0x08,sf);
//loop_start_offset = read_32bitBE(loops_offset+0x0c,sf);
loop_end_sample = read_32bitBE(loops_offset+0x10,sf);
//loop_end_offset = read_32bitBE(loops_offset+0x14,sf);
* 0x02 (2): loop flag? (always 1) */
loop_flag = read_s32be(loops_offset+0x04,sf) != 0; /* loop count + loop type? (always 1) */
loop_start_sample = read_s32be(loops_offset+0x08,sf);
//loop_start_offset = read_u32be(loops_offset+0x0c,sf);
loop_end_sample = read_s32be(loops_offset+0x10,sf);
//loop_end_offset = read_u32be(loops_offset+0x14,sf);
}
/* AINF header info (may be inserted by CRI's tools but is rarely used)
@ -171,11 +173,11 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
vgmstream = allocate_vgmstream(channels, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = read_32bitBE(0x08,sf);
vgmstream->num_samples = read_32bitBE(0x0c,sf);
vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = num_samples;
vgmstream->loop_start_sample = loop_start_sample;
vgmstream->loop_end_sample = loop_end_sample;
@ -189,7 +191,7 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
if (coding_type == coding_CRI_ADX_fixed) {
int i;
/* standard XA coefs * (2<<11) */
for (i = 0; i < channel_count; i++) {
for (i = 0; i < channels; i++) {
vgmstream->ch[i].adpcm_coef[0] = 0x0000;
vgmstream->ch[i].adpcm_coef[1] = 0x0000;
vgmstream->ch[i].adpcm_coef[2] = 0x0F00;
@ -201,23 +203,22 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
}
}
else {
double x,y,z,a,b,c;
/* coefs from cutoff frequency (some info from decomps, uses floats but no diffs if using doubles due to rounding) */
int i;
/* high-pass cutoff frequency, always 500 that I've seen */
uint16_t cutoff = read_u16be(0x10,sf);
float x, y, z, a, b, c;
x = cutoff;
y = vgmstream->sample_rate;
z = cos(2.0 * M_PI * x / y);
y = sample_rate;
z = cosf(2.0 * M_PI * x / y); /* 2.0 * M_PI: 6.28318548202515f (decomp) */
a = M_SQRT2 - z;
b = M_SQRT2 - 1.0;
c = (a - sqrt((a + b) * (a - b))) / b;
a = M_SQRT2 - z; /* M_SQRT2: 1.41421353816986f (decomp) */
b = M_SQRT2 - 1.0; /* M_SQRT2 - 1: 0.414213538169861f (decomp) */
c = (a - sqrtf((a + b) * (a - b))) / b; /* this seems calculated with a custom algorithm */
coef1 = (short)(c * 8192);
coef2 = (short)(c * c * -4096);
for (i = 0; i < channel_count; i++) {
for (i = 0; i < channels; i++) {
vgmstream->ch[i].adpcm_coef[0] = coef1;
vgmstream->ch[i].adpcm_coef[1] = coef2;
}
@ -227,17 +228,17 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
{
int i;
for (i = 0; i < channel_count; i++) {
for (i = 0; i < channels; i++) {
/* 2 hist shorts per ch, corresponding to the very first original sample repeated (verified with CRI's encoders).
* Not vital as their effect is small, after a few samples they don't matter, and most songs start in silence. */
if (hist_offset) {
vgmstream->ch[i].adpcm_history1_32 = read_16bitBE(hist_offset + i*4 + 0x00,sf);
vgmstream->ch[i].adpcm_history2_32 = read_16bitBE(hist_offset + i*4 + 0x02,sf);
vgmstream->ch[i].adpcm_history1_32 = read_s16be(hist_offset + i*4 + 0x00,sf);
vgmstream->ch[i].adpcm_history2_32 = read_s16be(hist_offset + i*4 + 0x02,sf);
}
if (coding_type == coding_CRI_ADX_enc_8 || coding_type == coding_CRI_ADX_enc_9) {
int j;
vgmstream->ch[i].adx_channels = channel_count;
vgmstream->ch[i].adx_channels = channels;
vgmstream->ch[i].adx_xor = xor_start;
vgmstream->ch[i].adx_mult = xor_mult;
vgmstream->ch[i].adx_add = xor_add;
@ -249,7 +250,7 @@ VGMSTREAM* init_vgmstream_adx_subkey(STREAMFILE* sf, uint16_t subkey) {
}
if ( !vgmstream_open_stream(vgmstream, sf, start_offset) )
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
goto fail;
return vgmstream;
@ -293,9 +294,9 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1
}
if (key_size == 0x06 && !is_ascii) {
*xor_start = get_16bitBE(keybuf + 0x00);
*xor_mult = get_16bitBE(keybuf + 0x02);
*xor_add = get_16bitBE(keybuf + 0x04);
*xor_start = get_u16be(keybuf + 0x00);
*xor_mult = get_u16be(keybuf + 0x02);
*xor_add = get_u16be(keybuf + 0x04);
return 1;
}
else if (type == 8 && is_ascii) {
@ -321,11 +322,11 @@ static int find_adx_key(STREAMFILE* sf, uint8_t type, uint16_t *xor_start, uint1
/* setup totals */
{
int frame_count;
int channels = read_8bit(0x07, sf);
int num_samples = read_32bitBE(0x0c, sf);
int channels = read_u8(0x07, sf);
int num_samples = read_s32be(0x0c, sf);
off_t end_offset;
start_offset = read_16bitBE(0x02, sf) + 0x4;
start_offset = read_u16be(0x02, sf) + 0x4;
end_offset = (num_samples + 31) / 32 * frame_size * channels + start_offset; /* samples-to-bytes */
frame_count = (end_offset - start_offset) / frame_size;

View File

@ -293,7 +293,7 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) {
/* sometimes there is garbage at the end or missing bytes due to improper ripping */
vgm_asserti(fsb.base_header_size + fsb.sample_headers_size + fsb.sample_data_size != get_streamfile_size(sf),
"FSB wrong head/data_size found (expected 0x%x vs 0x%x)\n",
fsb.base_header_size + fsb.sample_headers_size + fsb.sample_data_size, get_streamfile_size(sf));
fsb.base_header_size + fsb.sample_headers_size + fsb.sample_data_size, (uint32_t)get_streamfile_size(sf));
/* autodetect unwanted loops */
{

View File

@ -7,16 +7,16 @@
VGMSTREAM* init_vgmstream_fsb_encrypted(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
/* ignore non-encrypted FSB */
if ((read_u32be(0x00,sf) & 0xFFFFFF00) == get_id32be("FSB\0"))
goto fail;
/* checks */
/* .fsb: standard
* .fsb.xen: various Guitar Hero (X360/PC) */
if (!check_extensions(sf, "fsb,xen"))
goto fail;
/* ignore non-encrypted FSB */
if ((read_u32be(0x00,sf) & 0xFFFFFF00) == 0x46534200) /* "FSB\0" */
goto fail;
/* try fsbkey + all combinations of FSB4/5 and decryption algorithms */
{

View File

@ -91,7 +91,7 @@ static int read_dsp_header_endian(struct dsp_header *header, off_t offset, STREA
if (header->channels > 64) /* arbitrary max */
header->channels = 0;
if (header->block_size > 0x100000)
if (header->block_size >= 0xF000) /* same, 16b (usually 0) */
header->block_size = 0;
return 1;

View File

@ -97,7 +97,7 @@ VGMSTREAM* init_vgmstream_sgxd(STREAMFILE* sf) {
* - WSUR: ?
* - WMKR: ?
* - CONF: ? (name offset + config offset)
* - BUSS: bus config?
* - BUSS: bus config? */
/* WAVE chunk (size 0x10 + files * 0x38 + optional padding) */
if (is_sgx) { /* position after chunk+size */

View File

@ -15,17 +15,17 @@ VGMSTREAM* init_vgmstream_vag(STREAMFILE* sf) {
/* checks */
if (((read_u32be(0x00,sf) & 0xFFFFFF00) != get_id32be("VAG\0")) &&
((read_u32le(0x00,sf) & 0xFFFFFF00) != get_id32be("VAG\0")))
goto fail;
/* .vag: standard
* .swag: Frantix (PSP)
* .str: Ben10 Galactic Racing
* .vig: MX vs. ATV Untamed (PS2)
* .l/r: Crash Nitro Kart (PS2), Gradius V (PS2)
* .vas: Kingdom Hearts II (PS2) */
if ( !check_extensions(sf,"vag,swag,str,vig,l,r,vas") )
goto fail;
if (((read_u32be(0x00,sf) & 0xFFFFFF00) != 0x56414700) && /* "VAG" */
((read_u32le(0x00,sf) & 0xFFFFFF00) != 0x56414700))
if (!check_extensions(sf,"vag,swag,str,vig,l,r,vas"))
goto fail;
file_size = get_streamfile_size(sf);

View File

@ -16,6 +16,7 @@ typedef struct {
int alignment; /* chunks with odd size need to be aligned to even, per RIFF spec */
} chunk_t;
/* reads from current offset and updates chunk_t */
int next_chunk(chunk_t* chunk, STREAMFILE* sf);
#if 0