Adjust ASF shift modes after debugging info

This commit is contained in:
bnnm 2018-07-27 17:13:10 +02:00
parent 4337f00d5d
commit 87bd10073d

View File

@ -1,9 +1,8 @@
#include "coding.h"
/* Decodes Argonaut's ASF ADPCM codec. Algorithm follows Croc2_asf2raw.exe, and the waveform
* looks almost correct, but should reverse engineer asfcodec.adl (DLL) for accuracy. */
#define carry(a, b) (((uint32_t)(a) > (uint32_t)((a) + (b))))
/* Decodes Argonaut's ASF ADPCM codec, used in some of their PC games.
* Algorithm should be accurate (reverse engineered from asfcodec.adl DLL). */
void decode_asf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
off_t frame_offset;
int i, frames_in, sample_count = 0;
@ -31,25 +30,19 @@ void decode_asf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
new_sample = i&1 ? /* high nibble first */
get_low_nibble_signed(nibbles):
get_high_nibble_signed(nibbles);
new_sample = new_sample << (shift + 6);
/* move sample to upper nibble, then shift + 2 (IOW: shift + 6) */
new_sample = (new_sample << 4) << (shift + 2);
switch(mode) {
case 0x00:
new_sample = (new_sample + (hist1 << 6)) >> 6;
break;
case 0x04:
new_sample = (new_sample + (hist1 << 7) - (hist2 << 6)) >> 6;
break;
default: /* other modes (ex 0x02/09) seem only at last frame as 0 */
//VGM_LOG("ASF: unknown mode %x at %lx\n", mode,frame_offset);
//new_sample = 0; /* maybe? */
break;
/* mode is checked as a flag, so there are 2 modes only, but lower nibble
* may have other values at last frame (ex 0x02/09), could be control flags (loop related?) */
if (mode & 0x4) { /* ~filters: 2, -1 */
new_sample = (new_sample + (hist1 << 7) - (hist2 << 6)) >> 6;
}
else { /* ~filters: 1, 0 */
new_sample = (new_sample + (hist1 << 6)) >> 6;
}
//new_sample = clamp16(new_sample); /* must not */
outbuf[sample_count] = (int16_t)new_sample;
sample_count += channelspacing;