2008-06-02 17:58:08 +00:00
|
|
|
#include <math.h>
|
2008-05-06 03:35:37 +00:00
|
|
|
#include "coding.h"
|
2008-05-05 22:45:21 +00:00
|
|
|
#include "../util.h"
|
|
|
|
|
|
|
|
double VAG_f[5][2] = { { 0.0 , 0.0 },
|
2009-03-05 20:10:24 +00:00
|
|
|
{ 60.0 / 64.0 , 0.0 },
|
2008-05-05 22:45:21 +00:00
|
|
|
{ 115.0 / 64.0 , -52.0 / 64.0 },
|
|
|
|
{ 98.0 / 64.0 , -55.0 / 64.0 } ,
|
|
|
|
{ 122.0 / 64.0 , -60.0 / 64.0 } } ;
|
2008-11-06 23:30:33 +00:00
|
|
|
long VAG_coefs[5][2] = { { 0 , 0 },
|
|
|
|
{ 60 , 0 },
|
|
|
|
{ 115 , -52 },
|
|
|
|
{ 98 , -55 } ,
|
|
|
|
{ 122 , -60 } } ;
|
2008-05-05 22:45:21 +00:00
|
|
|
|
|
|
|
void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
|
|
|
|
2009-03-05 20:10:24 +00:00
|
|
|
int predict_nr, shift_factor, sample;
|
|
|
|
int32_t hist1=stream->adpcm_history1_32;
|
|
|
|
int32_t hist2=stream->adpcm_history2_32;
|
2008-05-05 22:45:21 +00:00
|
|
|
|
2008-05-09 17:59:05 +00:00
|
|
|
short scale;
|
2008-05-05 22:45:21 +00:00
|
|
|
int i;
|
|
|
|
int32_t sample_count;
|
2008-05-13 19:53:31 +00:00
|
|
|
uint8_t flag;
|
2008-05-05 22:45:21 +00:00
|
|
|
|
|
|
|
int framesin = first_sample/28;
|
|
|
|
|
|
|
|
predict_nr = read_8bit(stream->offset+framesin*16,stream->streamfile) >> 4;
|
|
|
|
shift_factor = read_8bit(stream->offset+framesin*16,stream->streamfile) & 0xf;
|
2008-05-13 19:53:31 +00:00
|
|
|
flag = read_8bit(stream->offset+framesin*16+1,stream->streamfile);
|
2008-05-05 22:45:21 +00:00
|
|
|
|
2008-05-13 19:53:31 +00:00
|
|
|
first_sample = first_sample % 28;
|
|
|
|
|
2008-05-05 22:45:21 +00:00
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
|
|
|
2008-05-13 19:53:31 +00:00
|
|
|
sample=0;
|
|
|
|
|
2008-05-17 21:52:40 +00:00
|
|
|
if(flag<0x07) {
|
2008-05-13 19:53:31 +00:00
|
|
|
|
|
|
|
short sample_byte = (short)read_8bit(stream->offset+(framesin*16)+2+i/2,stream->streamfile);
|
|
|
|
|
|
|
|
scale = ((i&1 ?
|
|
|
|
sample_byte >> 4 :
|
|
|
|
sample_byte & 0x0f)<<12);
|
2008-05-05 22:45:21 +00:00
|
|
|
|
2009-03-05 20:10:24 +00:00
|
|
|
sample=(int)((scale >> shift_factor)+hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]);
|
2008-05-13 19:53:31 +00:00
|
|
|
}
|
2008-05-05 22:45:21 +00:00
|
|
|
|
2008-05-13 19:53:31 +00:00
|
|
|
outbuf[sample_count] = clamp16(sample);
|
2008-05-05 22:45:21 +00:00
|
|
|
hist2=hist1;
|
2008-05-10 19:58:03 +00:00
|
|
|
hist1=sample;
|
2008-05-05 22:45:21 +00:00
|
|
|
}
|
2009-03-05 20:10:24 +00:00
|
|
|
stream->adpcm_history1_32=hist1;
|
|
|
|
stream->adpcm_history2_32=hist2;
|
2008-05-06 03:35:37 +00:00
|
|
|
}
|
2008-06-25 20:39:15 +00:00
|
|
|
|
|
|
|
void decode_invert_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
|
|
|
|
|
|
|
int predict_nr, shift_factor, sample;
|
|
|
|
int32_t hist1=stream->adpcm_history1_32;
|
|
|
|
int32_t hist2=stream->adpcm_history2_32;
|
|
|
|
|
|
|
|
short scale;
|
|
|
|
int i;
|
|
|
|
int32_t sample_count;
|
|
|
|
uint8_t flag;
|
|
|
|
|
|
|
|
int framesin = first_sample/28;
|
2009-01-10 00:07:12 +00:00
|
|
|
int head = read_8bit(stream->offset+framesin*16,stream->streamfile) ^ stream->bmdx_xor;
|
2008-06-25 20:39:15 +00:00
|
|
|
|
2008-06-26 02:12:40 +00:00
|
|
|
predict_nr = ((head >> 4) & 0xf);
|
|
|
|
shift_factor = (head & 0xf);
|
2008-06-25 20:39:15 +00:00
|
|
|
flag = read_8bit(stream->offset+framesin*16+1,stream->streamfile);
|
|
|
|
|
|
|
|
first_sample = first_sample % 28;
|
|
|
|
|
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
|
|
|
|
|
|
sample=0;
|
|
|
|
|
|
|
|
if(flag<0x07) {
|
|
|
|
|
|
|
|
short sample_byte = (short)read_8bit(stream->offset+(framesin*16)+2+i/2,stream->streamfile);
|
2009-01-07 12:38:46 +00:00
|
|
|
if (i/2 == 0)
|
2009-01-10 00:07:12 +00:00
|
|
|
sample_byte = (short)(int8_t)(sample_byte+stream->bmdx_add);
|
2008-06-25 20:39:15 +00:00
|
|
|
|
|
|
|
scale = ((i&1 ?
|
|
|
|
sample_byte >> 4 :
|
|
|
|
sample_byte & 0x0f)<<12);
|
|
|
|
|
|
|
|
sample=(int)((scale >> shift_factor)+hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]);
|
|
|
|
}
|
|
|
|
|
|
|
|
outbuf[sample_count] = clamp16(sample);
|
|
|
|
hist2=hist1;
|
|
|
|
hist1=sample;
|
|
|
|
}
|
|
|
|
stream->adpcm_history1_32=hist1;
|
|
|
|
stream->adpcm_history2_32=hist2;
|
|
|
|
}
|
2008-07-25 19:02:29 +00:00
|
|
|
|
|
|
|
/* some TAITO games have garbage (?) in their flags, this decoder
|
|
|
|
* just ignores that byte */
|
|
|
|
void decode_psx_badflags(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
|
|
|
|
|
|
|
int predict_nr, shift_factor, sample;
|
|
|
|
int32_t hist1=stream->adpcm_history1_32;
|
|
|
|
int32_t hist2=stream->adpcm_history2_32;
|
|
|
|
|
|
|
|
short scale;
|
|
|
|
int i;
|
|
|
|
int32_t sample_count;
|
|
|
|
|
|
|
|
int framesin = first_sample/28;
|
|
|
|
|
|
|
|
predict_nr = read_8bit(stream->offset+framesin*16,stream->streamfile) >> 4;
|
|
|
|
shift_factor = read_8bit(stream->offset+framesin*16,stream->streamfile) & 0xf;
|
|
|
|
first_sample = first_sample % 28;
|
|
|
|
|
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
|
|
short sample_byte = (short)read_8bit(stream->offset+(framesin*16)+2+i/2,stream->streamfile);
|
|
|
|
|
|
|
|
scale = ((i&1 ?
|
|
|
|
sample_byte >> 4 :
|
|
|
|
sample_byte & 0x0f)<<12);
|
|
|
|
|
|
|
|
sample=(int)((scale >> shift_factor)+hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]);
|
|
|
|
|
|
|
|
outbuf[sample_count] = clamp16(sample);
|
|
|
|
hist2=hist1;
|
|
|
|
hist1=sample;
|
|
|
|
}
|
|
|
|
stream->adpcm_history1_32=hist1;
|
|
|
|
stream->adpcm_history2_32=hist2;
|
|
|
|
}
|
|
|
|
|
2008-11-06 23:30:33 +00:00
|
|
|
/* FF XI's Vag-ish format */
|
|
|
|
void decode_ffxi_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
|
|
|
|
|
|
|
int predict_nr, shift_factor, sample;
|
|
|
|
int32_t hist1=stream->adpcm_history1_32;
|
|
|
|
int32_t hist2=stream->adpcm_history2_32;
|
|
|
|
|
|
|
|
short scale;
|
|
|
|
int i;
|
|
|
|
int32_t sample_count;
|
|
|
|
long predictor;
|
|
|
|
|
|
|
|
int framesin = first_sample/16;
|
|
|
|
|
|
|
|
predict_nr = read_8bit(stream->offset+framesin*9,stream->streamfile) >> 4;
|
|
|
|
shift_factor = read_8bit(stream->offset+framesin*9,stream->streamfile) & 0xf;
|
|
|
|
first_sample = first_sample % 16;
|
|
|
|
|
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
|
|
short sample_byte = (short)read_8bit(stream->offset+(framesin*9)+1+i/2,stream->streamfile);
|
|
|
|
|
|
|
|
sample=0;
|
|
|
|
|
|
|
|
scale = ((i&1 ?
|
|
|
|
sample_byte >> 4 :
|
|
|
|
sample_byte & 0x0f)<<12);
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
predictor =
|
|
|
|
(int)((hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]));
|
|
|
|
#else
|
|
|
|
predictor =
|
|
|
|
(hist1*VAG_coefs[predict_nr][0]+hist2*VAG_coefs[predict_nr][1])/64;
|
|
|
|
#endif
|
|
|
|
sample=(scale >> shift_factor) + predictor;
|
|
|
|
|
|
|
|
outbuf[sample_count] = clamp16(sample);
|
|
|
|
hist2=hist1;
|
|
|
|
hist1=sample;
|
|
|
|
}
|
|
|
|
stream->adpcm_history1_32=hist1;
|
|
|
|
stream->adpcm_history2_32=hist2;
|
|
|
|
}
|
|
|
|
|
2010-09-11 20:57:39 +00:00
|
|
|
void decode_blur_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
|
|
|
|
|
|
|
int predict_nr, shift_factor, sample;
|
|
|
|
int32_t hist1=stream->adpcm_history1_32;
|
|
|
|
int32_t hist2=stream->adpcm_history2_32;
|
|
|
|
|
|
|
|
short scale;
|
|
|
|
int i;
|
|
|
|
int32_t sample_count;
|
|
|
|
|
|
|
|
int framesin = first_sample/64;
|
|
|
|
|
|
|
|
predict_nr = read_8bit(stream->offset+framesin*33,stream->streamfile) >> 4;
|
|
|
|
shift_factor = read_8bit(stream->offset+framesin*33,stream->streamfile) & 0xf;
|
|
|
|
|
|
|
|
first_sample = first_sample % 64;
|
|
|
|
|
|
|
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
|
|
short sample_byte = (short)read_8bit(stream->offset+(framesin*33)+1+i/2,stream->streamfile);
|
|
|
|
|
|
|
|
scale = ((i&1 ?
|
|
|
|
sample_byte >> 4 :
|
|
|
|
sample_byte & 0x0f)<<12);
|
|
|
|
|
|
|
|
sample=(int)((scale >> shift_factor)+hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]);
|
|
|
|
|
|
|
|
outbuf[sample_count] = clamp16(sample);
|
|
|
|
hist2=hist1;
|
|
|
|
hist1=sample;
|
|
|
|
}
|
|
|
|
stream->adpcm_history1_32=hist1;
|
|
|
|
stream->adpcm_history2_32=hist2;
|
|
|
|
}
|