aica: don't reset the adpcm decoder when looping

also don't decode past LEA, use LSA instead
This commit is contained in:
Flyinghead 2019-09-05 18:17:53 +02:00
parent a50ed2cc7d
commit 7287b3816b
1 changed files with 32 additions and 43 deletions

View File

@ -84,13 +84,13 @@ void AICA_Sample();
SampleType Sc=FPMul(temp,volume_lut[0xF-(t_pan&0xF)],15);\
if (t_pan& 0x10)\
{\
outl+=temp;\
outr+=Sc ;\
(outl)+=temp;\
(outr)+=Sc ;\
}\
else\
{\
outl+=Sc;\
outr+=temp;\
(outl)+=Sc;\
(outr)+=temp;\
}\
}
s16 pl=0,pr=0;
@ -358,12 +358,12 @@ struct ChannelEx
} lfo;
bool enabled; //set to false to 'freeze' the channel
int ChanelNumber;
int ChannelNumber;
void Init(int cn,u8* ccd_raw)
{
ccd=(ChannelCommonData*)&ccd_raw[cn*0x80];
ChanelNumber=cn;
ChannelNumber = cn;
for (u32 i=0;i<0x80;i++)
RegWrite(i);
disable();
@ -490,7 +490,8 @@ struct ChannelEx
StepStreamInitial(this);
key_printf("[%p] KEY_ON %s @ %f Hz, loop : %d", this, stream_names[ccd->PCMS], (44100.0 * update_rate) / 1024, ccd->LPCTL);
key_printf("[%d] KEY_ON %s @ %f Hz, loop %d, AEG AR %d DC1R %d DC2V %d DC2R %d RR %d", ChannelNumber, stream_names[ccd->PCMS], (44100.0 * update_rate) / 1024, ccd->LPCTL,
AEG.AttackRate, AEG.Decay1Rate, AEG.Decay2Value, AEG.Decay2Rate, AEG.ReleaseRate);
}
else
{
@ -501,7 +502,7 @@ struct ChannelEx
{
if (AEG.state!=EG_Release)
{
key_printf("[%p] KEY_OFF -> Release", this);
key_printf("[%d] KEY_OFF -> Release", ChannelNumber);
SetAegState(EG_Release);
//switch to release state
}
@ -772,6 +773,7 @@ __forceinline void StepDecodeSample(ChannelEx* ch,u32 CA)
s16* sptr16=(s16*)ch->SA;
s8* sptr8=(s8*)sptr16;
u8* uptr8=(u8*)sptr16;
u32 next_addr = CA + 1 >= ch->loop.LEA ? ch->loop.LSA : CA + 1;
SampleType s0,s1;
switch(PCMS)
@ -789,18 +791,16 @@ __forceinline void StepDecodeSample(ChannelEx* ch,u32 CA)
case 0:
{
//s16* ptr=(s16*)&aica_ram[(addr&~1)+(CA<<1)];
sptr16+=CA;
s0=sptr16[0];
s1=sptr16[1];
s0 = sptr16[CA];
s1 = sptr16[next_addr];
}
break;
case 1:
{
//s8* ptr=(s8*)&aica_ram[addr+(CA)];
sptr8+=CA;
s0=sptr8[0]<<8;
s1=sptr8[1]<<8;
s0 = sptr8[CA] << 8;
s1 = sptr8[next_addr] << 8;
}
break;
@ -808,8 +808,8 @@ __forceinline void StepDecodeSample(ChannelEx* ch,u32 CA)
case 3:
{
//u32 offs=CA;
u8 ad1=uptr8[CA>>1];
u8 ad2=uptr8[(CA+1)>>1];
u8 ad1 = uptr8[CA >> 1];
u8 ad2 = uptr8[next_addr >> 1];
u8 sf=(CA&1)*4;
ad1>>=sf;
@ -862,26 +862,17 @@ void StreamStep(ChannelEx* ch)
if ((ch->AEG.state==EG_Attack) && (CA>=ch->loop.LSA))
{
step_printf("[%p]LPSLNK : Switching to EG_Decay1 %X", ch, ch->AEG.GetValue());
step_printf("[%d]LPSLNK : Switching to EG_Decay1 %X", ch->ChannelNumber, ch->AEG.GetValue());
ch->SetAegState(EG_Decay1);
}
}
if (ca_t>=ch->loop.LEA)
if (ca_t >= ch->loop.LEA)
{
ch->loop.looped=1;
CA=ch->loop.LSA;
if (LPCTL)
{
if (PCMS==2) //if in adpcm non-stream mode, reset the decoder
{
ch->adpcm.Reset(ch);
}
}
else
{
ch->loop.looped = 1;
CA = ch->loop.LSA;
if (LPCTL == 0)
ch->disable();
}
}
ch->CA=CA;
@ -960,12 +951,12 @@ void AegStep(ChannelEx* ch)
ch->AEG.val-=ch->AEG.AttackRate;
if (ch->AEG.GetValue()<=0)
{
ch->AEG.SetValue(0);
if (!ch->ccd->LPSLNK)
{
aeg_printf("[%p]AEG_step : Switching to EG_Decay1 %d", ch, ch->AEG.GetValue());
aeg_printf("[%d]AEG_step : Switching to EG_Decay1 %d", ch->ChannelNumber, ch->AEG.GetValue());
ch->SetAegState(EG_Decay1);
}
ch->AEG.SetValue(0);
}
}
break;
@ -975,7 +966,7 @@ void AegStep(ChannelEx* ch)
ch->AEG.val+=ch->AEG.Decay1Rate;
if (((u32)ch->AEG.GetValue())>=ch->AEG.Decay2Value)
{
aeg_printf("[%p]AEG_step : Switching to EG_Decay2 @ %x", ch, ch->AEG.GetValue());
aeg_printf("[%d]AEG_step : Switching to EG_Decay2 @ %x", ch->ChannelNumber, ch->AEG.GetValue());
ch->SetAegState(EG_Decay2);
}
}
@ -986,7 +977,7 @@ void AegStep(ChannelEx* ch)
ch->AEG.val+=ch->AEG.Decay2Rate;
if (ch->AEG.GetValue()>=0x3FF)
{
aeg_printf("[%p]AEG_step : Switching to EG_Release @ %x", ch, ch->AEG.GetValue());
aeg_printf("[%d]AEG_step : Switching to EG_Release @ %x", ch->ChannelNumber, ch->AEG.GetValue());
ch->AEG.SetValue(0x3FF);
ch->SetAegState(EG_Release);
}
@ -998,7 +989,7 @@ void AegStep(ChannelEx* ch)
if (ch->AEG.GetValue()>=0x3FF)
{
aeg_printf("[%p]AEG_step : EG_Release End @ %x", ch, ch->AEG.GetValue());
aeg_printf("[%d]AEG_step : EG_Release End @ %x", ch->ChannelNumber, ch->AEG.GetValue());
ch->AEG.SetValue(0x3FF); // TODO: mnn, should we do anything about it running wild ?
ch->disable(); // TODO: Is this ok here? It's a speed optimisation (since the channel is muted)
}
@ -1085,20 +1076,20 @@ u32 CalcAegSteps(float t)
//44.1*ms = samples
double scnt=44.1*t;
double steps=aeg_allsteps/scnt;
return (u32)lroundf(steps);
return (u32)lround(steps);
}
void sgc_Init()
{
staticinitialise();
for (int i=0;i<16;i++)
for (int i = 0; i < 16; i++)
{
volume_lut[i]=(s32)((1<<15)/pow(2.0,(15-i)/2.0));
if (i==0)
volume_lut[i]=0;
}
for (int i=0;i<256;i++)
for (int i = 0; i < 256; i++)
{
tl_lut[i]=(s32)((1<<15)/pow(2.0,i/16.0));
}
@ -1323,8 +1314,6 @@ void AICA_Sample()
s32 EXTS0R=cdda_sector[cdda_index+1];
cdda_index+=2;
//No dsp tho ;p
//Final MIX ..
//Add CDDA / DSP effect(s)
@ -1348,7 +1337,7 @@ void AICA_Sample()
for (int i=0;i<16;i++)
{
VOLPAN( (*(s16*)&DSPData->EFREG[i]) ,dsp_out_vol[i].EFSDL,dsp_out_vol[i].EFPAN,mixl,mixr);
VOLPAN(*(s16*)&DSPData->EFREG[i], dsp_out_vol[i].EFSDL, dsp_out_vol[i].EFPAN, mixl, mixr);
}
}
@ -1445,7 +1434,7 @@ bool channel_serialize(void **data, unsigned int *total_size)
REICAST_S(Chans[i].lfo.alfo_calc_lut) ;
REICAST_S(Chans[i].lfo.plfo_calc_lut) ;
REICAST_S(Chans[i].enabled) ;
REICAST_S(Chans[i].ChanelNumber) ;
REICAST_S(Chans[i].ChannelNumber) ;
}
/* TODO/FIXME - no possibility for this to return false? */
@ -1505,7 +1494,7 @@ bool channel_unserialize(void **data, unsigned int *total_size)
Chans[i].lfo.alfo_calc = ALFOWS_CALC[Chans[i].lfo.alfo_calc_lut];
Chans[i].lfo.plfo_calc = PLFOWS_CALC[Chans[i].lfo.plfo_calc_lut];
REICAST_US(Chans[i].enabled) ;
REICAST_US(Chans[i].ChanelNumber) ;
REICAST_US(Chans[i].ChannelNumber) ;
}