#include "coding.h" #include "../util.h" const int SH = 4; const int SHC = 10; double K0[4] = { 0.0, 0.9375, 1.796875, 1.53125}; double K1[4] = { 0.0, 0.0, -0.8125,-0.859375}; int IK0(int fid) { return ((int)((-K0[fid]) * (1 << SHC))); } int IK1(int fid) { return ((int)((-K1[fid]) * (1 << SHC))); } int CLAMP(int value, int Minim, int Maxim) { if (value < Minim) value = Minim; if (value > Maxim) value = Maxim; return value; } static int get_high_nibble = 1; void init_get_high_nibble() { get_high_nibble=1; } void decode_xa(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; int HeadTable[8]={0,2,8,10}; short scale; int i; int32_t sample_count; int framesin = first_sample / (56 / channelspacing); first_sample = first_sample % 28; get_high_nibble=!get_high_nibble; if((first_sample) && (channelspacing==1)) get_high_nibble=!get_high_nibble; predict_nr = read_8bit(stream->offset+HeadTable[framesin]+get_high_nibble,stream->streamfile) >> 4; shift_factor = read_8bit(stream->offset+HeadTable[framesin]+get_high_nibble,stream->streamfile) & 0xf; for (i=first_sample,sample_count=0; ioffset+16+framesin+(i*4),stream->streamfile); scale = ((get_high_nibble ? sample_byte >> 4 : sample_byte & 0x0f)<<12); sample = (short)(scale & 0xf000) >> shift_factor; sample <<= SH; sample -= (IK0(predict_nr) * hist1 + (IK1(predict_nr) * hist2)) >> SHC; hist2=hist1; hist1=sample; sample = CLAMP(sample, -32768 << SH, 32767 << SH); outbuf[sample_count] = (short)(sample >> SH); } stream->adpcm_history1_32=hist1; stream->adpcm_history2_32=hist2; }