From 67faaeb473f9a579796e2a1f23acdfb515b22f81 Mon Sep 17 00:00:00 2001 From: "R. Belmont" Date: Mon, 28 Jul 2008 05:46:29 +0000 Subject: [PATCH] AICA updates [Deunan Knute, ajax16384, R. Belmont] - Fixed ADPCM decoder to remove bad optimization and match YMZ280B. DC offset is fixed and output quality is higher - Improved handling of slot monitor and timers B and C - Simplified interpolation code --- src/emu/sound/aica.c | 66 ++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/src/emu/sound/aica.c b/src/emu/sound/aica.c index cf969ed0b1f..ebdf29c752c 100644 --- a/src/emu/sound/aica.c +++ b/src/emu/sound/aica.c @@ -123,12 +123,10 @@ struct _SLOT struct _LFO ALFO; //Amplitude LFO int slot; int cur_sample; //current ADPCM sample - int nxt_sample; //next ADPCM sample int cur_quant; //current ADPCM step - int nxt_quant; //next ADPCM step - int curstep, nxtstep; + int curstep; int cur_lpquant, cur_lpsample, cur_lpstep; - UINT8 *adbase, *nxtbase, *adlpbase; + UINT8 *adbase, *adlpbase; UINT8 mslc; // monitored? }; @@ -442,10 +440,11 @@ static void InitADPCM(int *PrevSignal, int *PrevQuant) *PrevQuant=0x7f; } -INLINE signed short DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQuant) +INLINE signed short inline DecodeADPCM(int *PrevSignal, unsigned char Delta, int *PrevQuant) { - *PrevSignal+=(*PrevQuant*quant_mul[Delta&15])>>(3); - *PrevSignal=ICLIP16(*PrevSignal); + int x = *PrevQuant * quant_mul [Delta & 15]; + x = *PrevSignal + ((int)(x + ((UINT32)x >> 29)) >> 3); + *PrevSignal=ICLIP16(x); *PrevQuant=(*PrevQuant*TableQuant[Delta&7])>>ADPCMSHIFT; *PrevQuant=(*PrevQuant<0x7f)?0x7f:((*PrevQuant>0x6000)?0x6000:*PrevQuant); return *PrevSignal; @@ -471,10 +470,9 @@ static void AICA_StartSlot(struct _AICA *AICA, struct _SLOT *slot) UINT8 *base; UINT32 curstep, steps_to_go; - slot->curstep = slot->nxtstep = 0; - slot->adbase = slot->nxtbase = (unsigned char *) (AICA->AICARAM+((SA(slot))&0x7fffff)); + slot->curstep = 0; + slot->adbase = (unsigned char *) (AICA->AICARAM+((SA(slot))&0x7fffff)); InitADPCM(&(slot->cur_sample), &(slot->cur_quant)); - InitADPCM(&(slot->nxt_sample), &(slot->nxt_quant)); InitADPCM(&(slot->cur_lpsample), &(slot->cur_lpquant)); // walk to the ADPCM state at LSA @@ -1085,12 +1083,16 @@ INLINE INT32 AICA_UpdateSlot(struct _AICA *AICA, struct _SLOT *slot) { UINT8 *base= slot->adbase; INT32 s; + int cur_sample; //current ADPCM sample + int nxt_sample; //next ADPCM sample INT32 fpart=slot->cur_addr&((1<curstep; + UINT32 steps_to_go = addr2, curstep = slot->curstep; if (slot->adbase) { - // seek to the current sample + cur_sample = slot->cur_sample; // may already contains current decoded sample + + // seek to the interpolation sample while (curstep < steps_to_go) { int shift1, delta1; @@ -1102,33 +1104,15 @@ INLINE INT32 AICA_UpdateSlot(struct _AICA *AICA, struct _SLOT *slot) { base++; } + if (curstep == addr1) + cur_sample = slot->cur_sample; } + nxt_sample = slot->cur_sample; slot->adbase = base; slot->curstep = curstep; - base = slot->nxtbase; - curstep = slot->nxtstep; - steps_to_go = addr2; - - // seek to the interpolation sample - while (curstep < steps_to_go) - { - int shift1, delta1; - shift1 = 4*((curstep&1)); - delta1 = (*base>>shift1)&0xf; - DecodeADPCM(&(slot->nxt_sample),delta1,&(slot->nxt_quant)); - curstep++; - if (!(curstep & 1)) - { - base++; - } - } - - slot->nxtbase = base; - slot->nxtstep = curstep; - - s=(int) slot->cur_sample*((1<nxt_sample*fpart; + s=(int)cur_sample*((1<=2 && addr_select==0) + if(PCMS(slot)>=2) { // restore the state @ LSA - the sampler will naturally walk to (LSA + remainder) slot->adbase = &AICA->AICARAM[SA(slot)+(LSA(slot)/2)]; @@ -1184,16 +1168,6 @@ INLINE INT32 AICA_UpdateSlot(struct _AICA *AICA, struct _SLOT *slot) // printf("Looping: slot_addr %x LSA %x LEA %x step %x base %x\n", *slot_addr[addr_select]>>SHIFT, LSA(slot), LEA(slot), slot->curstep, slot->adbase); } - else if(PCMS(slot)>=2 && addr_select==1) - { - slot->nxtbase = &AICA->AICARAM[SA(slot)+(LSA(slot)/2)]; - slot->nxtstep = LSA(slot); - if (PCMS(slot) == 2) - { - slot->nxt_sample = slot->cur_lpsample; - slot->nxt_quant = slot->cur_lpquant; - } - } } break; } @@ -1212,7 +1186,7 @@ INLINE INT32 AICA_UpdateSlot(struct _AICA *AICA, struct _SLOT *slot) if(slot->mslc) { - AICA->udata.data[0x12/2] = addr1; + AICA->udata.data[0x14/2] = addr1; if (!(AFSEL(AICA))) { AICA->udata.data[0x10/2] |= slot->EG.state<<13;