From 775c6bc9a480a58abacef77018dda5391d4d363a Mon Sep 17 00:00:00 2001 From: Alexey Yakovenko Date: Sun, 27 Jun 2010 20:27:15 +0200 Subject: ao SPU reentrancy WIP --- plugins/ao/ao.h | 50 ++++-- plugins/ao/eng_psf/eng_psf.c | 6 +- plugins/ao/eng_psf/eng_spu.c | 4 +- plugins/ao/eng_psf/peops/adsr.c | 146 ++++++++-------- plugins/ao/eng_psf/peops/adsr.h | 4 +- plugins/ao/eng_psf/peops/dma.c | 12 +- plugins/ao/eng_psf/peops/externals.h | 22 --- plugins/ao/eng_psf/peops/registers.c | 232 ++++++++++++------------- plugins/ao/eng_psf/peops/reverb.c | 118 ++++++------- plugins/ao/eng_psf/peops/spu.c | 307 ++++++++++++++++------------------ plugins/ao/eng_psf/peops/spu.h | 33 ++++ plugins/ao/eng_psf/peops2/externals.h | 32 ++-- plugins/ao/eng_psf/psx.h | 7 +- 13 files changed, 488 insertions(+), 485 deletions(-) diff --git a/plugins/ao/ao.h b/plugins/ao/ao.h index 010317be..a9b0f01a 100755 --- a/plugins/ao/ao.h +++ b/plugins/ao/ao.h @@ -109,6 +109,42 @@ typedef signed long long int64; typedef unsigned long long uint64; #endif +typedef int8 s8; +typedef int16 s16; +typedef int32 s32; +typedef int64 s64; + +typedef uint8 u8; +typedef uint16 u16; +typedef uint32 u32; +typedef uint64 u64; + +#ifndef INLINE +#if defined(_MSC_VER) +#define INLINE __forceinline +#elif defined(__GNUC__) +#define INLINE __inline__ +#elif defined(_MWERKS_) +#define INLINE inline +#elif defined(__powerc) +#define INLINE inline +#else +#define INLINE +#endif +#endif + +#if LSB_FIRST +static INLINE u16 BFLIP16(u16 x) +{ + return x; +} +#else +static INLINE u16 BFLIP16(u16 x) +{ + return( ((x>>8)&0xFF)| ((x&0xFF)<<8) ); +} +#endif + #ifdef WIN32 #ifndef _BASETSD_H typedef signed int INT32; @@ -128,20 +164,6 @@ typedef unsigned long long UINT64; #endif #endif -#ifndef INLINE -#if defined(_MSC_VER) -#define INLINE __forceinline -#elif defined(__GNUC__) -#define INLINE __inline__ -#elif defined(_MWERKS_) -#define INLINE inline -#elif defined(__powerc) -#define INLINE inline -#else -#define INLINE -#endif -#endif - #if LSB_FIRST #define LE16(x) (x) #define LE32(x) (x) diff --git a/plugins/ao/eng_psf/eng_psf.c b/plugins/ao/eng_psf/eng_psf.c index d37a553f..4b90e61c 100644 --- a/plugins/ao/eng_psf/eng_psf.c +++ b/plugins/ao/eng_psf/eng_psf.c @@ -55,8 +55,6 @@ typedef struct { static uint32 initialPC, initialGP, initialSP; -extern void setlength(int32 stop, int32 fade); - static void spu_update (unsigned char* pSound,long lBytes,void *data) { psf_synth_t *s = data; @@ -331,7 +329,7 @@ void *psf_start(uint8 *buffer, uint32 length) lengthMS = ~0; } - setlength(lengthMS, fadeMS); + setlength(s->mips_cpu->spu, lengthMS, fadeMS); // patch illegal Chocobo Dungeon 2 code - CaitSith2 put a jump in the delay slot from a BNE // and rely on Highly Experimental's buggy-ass CPU to rescue them. Verified on real hardware @@ -419,7 +417,7 @@ int32 psf_command(void *handle, int32 command, int32 parameter) { lengthMS = ~0; } - setlength(lengthMS, fadeMS); + setlength(s->mips_cpu->spu, lengthMS, fadeMS); mipsinfo.i = initialPC; mips_set_info(s->mips_cpu, CPUINFO_INT_PC, &mipsinfo); diff --git a/plugins/ao/eng_psf/eng_spu.c b/plugins/ao/eng_psf/eng_spu.c index b27aa98d..b13e0c5f 100644 --- a/plugins/ao/eng_psf/eng_spu.c +++ b/plugins/ao/eng_psf/eng_spu.c @@ -43,8 +43,6 @@ #include "peops/spu.h" #include "peops/regs.h" -extern void setlength(int32 stop, int32 fade); - typedef struct { uint8 *start_of_file, *song_ptr; uint32 cur_tick, cur_event, num_events, next_tick, end_tick; @@ -81,7 +79,7 @@ void *spu_start(uint8 *buffer, uint32 length) s->mips_cpu = mips_alloc (); SPUinit(s->mips_cpu, spu_update, s); SPUopen(s->mips_cpu); - setlength(~0, 0); + setlength(s->mips_cpu->spu, ~0, 0); // upload the SPU RAM image SPUinjectRAMImage(s->mips_cpu, (unsigned short *)&buffer[0]); diff --git a/plugins/ao/eng_psf/peops/adsr.c b/plugins/ao/eng_psf/peops/adsr.c index 600ae841..980e97bd 100644 --- a/plugins/ao/eng_psf/peops/adsr.c +++ b/plugins/ao/eng_psf/peops/adsr.c @@ -61,116 +61,116 @@ static void InitADSR(void) // INIT ADSR //////////////////////////////////////////////////////////////////////// -static INLINE void StartADSR(int ch) // MIX ADSR +static INLINE void StartADSR(spu_state_t *spu, int ch) // MIX ADSR { - s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars - s_chan[ch].ADSRX.State=0; - s_chan[ch].ADSRX.EnvelopeVol=0; + spu->s_chan[ch].ADSRX.lVolume=1; // and init some adsr vars + spu->s_chan[ch].ADSRX.State=0; + spu->s_chan[ch].ADSRX.EnvelopeVol=0; } //////////////////////////////////////////////////////////////////////// -static INLINE int MixADSR(int ch) // MIX ADSR +static INLINE int MixADSR(spu_state_t *spu, int ch) // MIX ADSR { static const int sexytable[8]= {0,4,6,8,9,10,11,12}; - if(s_chan[ch].bStop) // should be stopped: + if(spu->s_chan[ch].bStop) // should be stopped: { // do release - if(s_chan[ch].ADSRX.ReleaseModeExp) + if(spu->s_chan[ch].ADSRX.ReleaseModeExp) { - s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]]; + spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x18+32+sexytable[(spu->s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]]; } else { - s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32]; + spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.ReleaseRate^0x1F))-0x0C + 32]; } - if(s_chan[ch].ADSRX.EnvelopeVol<0) + if(spu->s_chan[ch].ADSRX.EnvelopeVol<0) { - s_chan[ch].ADSRX.EnvelopeVol=0; - s_chan[ch].bOn=0; - s_chan[ch].bNoise=0; + spu->s_chan[ch].ADSRX.EnvelopeVol=0; + spu->s_chan[ch].bOn=0; + spu->s_chan[ch].bNoise=0; } - s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21; - return s_chan[ch].ADSRX.lVolume; + spu->s_chan[ch].ADSRX.lVolume=spu->s_chan[ch].ADSRX.EnvelopeVol>>21; + return spu->s_chan[ch].ADSRX.lVolume; } else // not stopped yet? { - if(s_chan[ch].ADSRX.State==0) // -> attack + if(spu->s_chan[ch].ADSRX.State==0) // -> attack { - if(s_chan[ch].ADSRX.AttackModeExp) + if(spu->s_chan[ch].ADSRX.AttackModeExp) { - if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000) - s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32]; + if(spu->s_chan[ch].ADSRX.EnvelopeVol<0x60000000) + spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32]; else - s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32]; + spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.AttackRate^0x7F)-0x18 + 32]; } else { - s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32]; + spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.AttackRate^0x7F)-0x10 + 32]; } - if(s_chan[ch].ADSRX.EnvelopeVol<0) + if(spu->s_chan[ch].ADSRX.EnvelopeVol<0) { - s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF; - s_chan[ch].ADSRX.State=1; + spu->s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF; + spu->s_chan[ch].ADSRX.State=1; } - s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21; - return s_chan[ch].ADSRX.lVolume; + spu->s_chan[ch].ADSRX.lVolume=spu->s_chan[ch].ADSRX.EnvelopeVol>>21; + return spu->s_chan[ch].ADSRX.lVolume; } //--------------------------------------------------// - if(s_chan[ch].ADSRX.State==1) // -> decay + if(spu->s_chan[ch].ADSRX.State==1) // -> decay { - s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]]; + spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[(4*(spu->s_chan[ch].ADSRX.DecayRate^0x1F))-0x18+32+sexytable[(spu->s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]]; - if(s_chan[ch].ADSRX.EnvelopeVol<0) s_chan[ch].ADSRX.EnvelopeVol=0; - if(((s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= s_chan[ch].ADSRX.SustainLevel) + if(spu->s_chan[ch].ADSRX.EnvelopeVol<0) spu->s_chan[ch].ADSRX.EnvelopeVol=0; + if(((spu->s_chan[ch].ADSRX.EnvelopeVol>>27)&0xF) <= spu->s_chan[ch].ADSRX.SustainLevel) { - s_chan[ch].ADSRX.State=2; + spu->s_chan[ch].ADSRX.State=2; } - s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21; - return s_chan[ch].ADSRX.lVolume; + spu->s_chan[ch].ADSRX.lVolume=spu->s_chan[ch].ADSRX.EnvelopeVol>>21; + return spu->s_chan[ch].ADSRX.lVolume; } //--------------------------------------------------// - if(s_chan[ch].ADSRX.State==2) // -> sustain + if(spu->s_chan[ch].ADSRX.State==2) // -> sustain { - if(s_chan[ch].ADSRX.SustainIncrease) + if(spu->s_chan[ch].ADSRX.SustainIncrease) { - if(s_chan[ch].ADSRX.SustainModeExp) + if(spu->s_chan[ch].ADSRX.SustainModeExp) { - if(s_chan[ch].ADSRX.EnvelopeVol<0x60000000) - s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32]; + if(spu->s_chan[ch].ADSRX.EnvelopeVol<0x60000000) + spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32]; else - s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32]; + spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.SustainRate^0x7F)-0x18 + 32]; } else { - s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32]; + spu->s_chan[ch].ADSRX.EnvelopeVol+=RateTable[(spu->s_chan[ch].ADSRX.SustainRate^0x7F)-0x10 + 32]; } - if(s_chan[ch].ADSRX.EnvelopeVol<0) + if(spu->s_chan[ch].ADSRX.EnvelopeVol<0) { - s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF; + spu->s_chan[ch].ADSRX.EnvelopeVol=0x7FFFFFFF; } } else { - if(s_chan[ch].ADSRX.SustainModeExp) - s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B+32+sexytable[(s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]]; + if(spu->s_chan[ch].ADSRX.SustainModeExp) + spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x1B+32+sexytable[(spu->s_chan[ch].ADSRX.EnvelopeVol>>28)&0x7]]; else - s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32]; + spu->s_chan[ch].ADSRX.EnvelopeVol-=RateTable[((spu->s_chan[ch].ADSRX.SustainRate^0x7F))-0x0F + 32]; - if(s_chan[ch].ADSRX.EnvelopeVol<0) + if(spu->s_chan[ch].ADSRX.EnvelopeVol<0) { - s_chan[ch].ADSRX.EnvelopeVol=0; + spu->s_chan[ch].ADSRX.EnvelopeVol=0; } } - s_chan[ch].ADSRX.lVolume=s_chan[ch].ADSRX.EnvelopeVol>>21; - return s_chan[ch].ADSRX.lVolume; + spu->s_chan[ch].ADSRX.lVolume=spu->s_chan[ch].ADSRX.EnvelopeVol>>21; + return spu->s_chan[ch].ADSRX.lVolume; } } return 0; @@ -398,45 +398,45 @@ every one millisecond i32 v,v2,lT,l1,l2,l3; - if(s_chan[ch].bStop) // psx wants to stop? -> release phase + if(spu->s_chan[ch].bStop) // psx wants to stop? -> release phase { - if(s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now) + if(spu->s_chan[ch].ADSR.ReleaseVal!=0) // -> release not 0: do release (if 0: stop right now) { - if(!s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff + if(!spu->s_chan[ch].ADSR.ReleaseVol) // --> release just started? set up the release stuff { - s_chan[ch].ADSR.ReleaseStartTime=s_chan[ch].ADSR.lTime; - s_chan[ch].ADSR.ReleaseVol=s_chan[ch].ADSR.lVolume; - s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level - (s_chan[ch].ADSR.ReleaseTime* - s_chan[ch].ADSR.ReleaseVol)/1024; + spu->s_chan[ch].ADSR.ReleaseStartTime=spu->s_chan[ch].ADSR.lTime; + spu->s_chan[ch].ADSR.ReleaseVol=spu->s_chan[ch].ADSR.lVolume; + spu->s_chan[ch].ADSR.ReleaseTime = // --> calc how long does it take to reach the wanted sus level + (spu->s_chan[ch].ADSR.ReleaseTime* + spu->s_chan[ch].ADSR.ReleaseVol)/1024; } // -> NO release exp mode used (yet) - v=s_chan[ch].ADSR.ReleaseVol; // -> get last volume - lT=s_chan[ch].ADSR.lTime- // -> how much time is past? - s_chan[ch].ADSR.ReleaseStartTime; - l1=s_chan[ch].ADSR.ReleaseTime; + v=spu->s_chan[ch].ADSR.ReleaseVol; // -> get last volume + lT=spu->s_chan[ch].ADSR.lTime- // -> how much time is past? + spu->s_chan[ch].ADSR.ReleaseStartTime; + l1=spu->s_chan[ch].ADSR.ReleaseTime; if(lT we still have to release { v=v-((v*lT)/l1); // --> calc new volume } else // -> release is over: now really stop that sample - {v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;} + {v=0;spu->s_chan[ch].bOn=0;spu->s_chan[ch].ADSR.ReleaseVol=0;spu->s_chan[ch].bNoise=0;} } else // -> release IS 0: release at once { - v=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0; + v=0;spu->s_chan[ch].bOn=0;spu->s_chan[ch].ADSR.ReleaseVol=0;spu->s_chan[ch].bNoise=0; } } else {//--------------------------------------------------// not in release phase: v=1024; - lT=s_chan[ch].ADSR.lTime; - l1=s_chan[ch].ADSR.AttackTime; + lT=spu->s_chan[ch].ADSR.lTime; + l1=spu->s_chan[ch].ADSR.AttackTime; if(lTs_chan[ch].ADSR.AttackModeExp) // { // v=(v*lT)/l1; // } @@ -448,8 +448,8 @@ every one millisecond } else // decay { // should be exp, but who cares? ;) - l2=s_chan[ch].ADSR.DecayTime; - v2=s_chan[ch].ADSR.SustainLevel; + l2=spu->s_chan[ch].ADSR.DecayTime; + v2=spu->s_chan[ch].ADSR.SustainLevel; lT-=l1; if(lTs_chan[ch].ADSR.SustainTime; lT-=l2; - if(s_chan[ch].ADSR.SustainModeDec>0) + if(spu->s_chan[ch].ADSR.SustainModeDec>0) { if(l3!=0) v2+=((v-v2)*lT)/l3; else v2=v; @@ -472,7 +472,7 @@ every one millisecond } if(v2>v) v2=v; - if(v2<=0) {v2=0;s_chan[ch].bOn=0;s_chan[ch].ADSR.ReleaseVol=0;s_chan[ch].bNoise=0;} + if(v2<=0) {v2=0;spu->s_chan[ch].bOn=0;spu->s_chan[ch].ADSR.ReleaseVol=0;spu->s_chan[ch].bNoise=0;} v=v2; } @@ -482,11 +482,11 @@ every one millisecond //----------------------------------------------------// // ok, done for this channel, so increase time - s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms; + spu->s_chan[ch].ADSR.lTime+=1; // 1 = 1.020408f ms; if(v>1024) v=1024; // adjust volume if(v<0) v=0; - s_chan[ch].ADSR.lVolume=v; // store act volume + spu->s_chan[ch].ADSR.lVolume=v; // store act volume return v; // return the volume factor */ diff --git a/plugins/ao/eng_psf/peops/adsr.h b/plugins/ao/eng_psf/peops/adsr.h index 868d57a9..5f27586b 100644 --- a/plugins/ao/eng_psf/peops/adsr.h +++ b/plugins/ao/eng_psf/peops/adsr.h @@ -24,5 +24,5 @@ // //*************************************************************************// -static INLINE void StartADSR(int ch); -static INLINE int MixADSR(int ch); +static INLINE void StartADSR(spu_state_t *spu, int ch); +static INLINE int MixADSR(spu_state_t *spu, int ch); diff --git a/plugins/ao/eng_psf/peops/dma.c b/plugins/ao/eng_psf/peops/dma.c index dfa0564c..15695c72 100644 --- a/plugins/ao/eng_psf/peops/dma.c +++ b/plugins/ao/eng_psf/peops/dma.c @@ -39,10 +39,10 @@ void SPUreadDMAMem(mips_cpu_context *cpu, u32 usPSXMem,int iSize) for(i=0;i>1]=spuMem[spuAddr>>1]; // spu addr got by writeregister + ram16[usPSXMem>>1]=cpu->spu->spuMem[cpu->spu->spuAddr>>1]; // spu addr got by writeregister usPSXMem+=2; - spuAddr+=2; // inc spu addr - if(spuAddr>0x7ffff) spuAddr=0; // wrap + cpu->spu->spuAddr+=2; // inc spu addr + if(cpu->spu->spuAddr>0x7ffff) cpu->spu->spuAddr=0; // wrap } } @@ -66,10 +66,10 @@ void SPUwriteDMAMem(mips_cpu_context *cpu, u32 usPSXMem,int iSize) for(i=0;i SPU %x\n", usPSXMem, spuAddr); - spuMem[spuAddr>>1] = ram16[usPSXMem>>1]; + cpu->spu->spuMem[cpu->spu->spuAddr>>1] = ram16[usPSXMem>>1]; usPSXMem+=2; // spu addr got by writeregister - spuAddr+=2; // inc spu addr - if(spuAddr>0x7ffff) spuAddr=0; // wrap + cpu->spu->spuAddr+=2; // inc spu addr + if(cpu->spu->spuAddr>0x7ffff) cpu->spu->spuAddr=0; // wrap } } diff --git a/plugins/ao/eng_psf/peops/externals.h b/plugins/ao/eng_psf/peops/externals.h index f27abc07..1c88552c 100644 --- a/plugins/ao/eng_psf/peops/externals.h +++ b/plugins/ao/eng_psf/peops/externals.h @@ -21,28 +21,6 @@ #ifndef PEOPS_EXTERNALS #define PEOPS_EXTERNALS -typedef int8 s8; -typedef int16 s16; -typedef int32 s32; -typedef int64 s64; - -typedef uint8 u8; -typedef uint16 u16; -typedef uint32 u32; -typedef uint64 u64; - -#if LSB_FIRST -static INLINE u16 BFLIP16(u16 x) -{ - return x; -} -#else -static INLINE u16 BFLIP16(u16 x) -{ - return( ((x>>8)&0xFF)| ((x&0xFF)<<8) ); -} -#endif - //*************************************************************************// // History of changes: // diff --git a/plugins/ao/eng_psf/peops/registers.c b/plugins/ao/eng_psf/peops/registers.c index 5393888f..abc13865 100644 --- a/plugins/ao/eng_psf/peops/registers.c +++ b/plugins/ao/eng_psf/peops/registers.c @@ -46,12 +46,12 @@ #include "../peops/registers.h" #include "../peops/regs.h" -static void SoundOn(int start,int end,u16 val); -static void SoundOff(int start,int end,u16 val); -static void FModOn(int start,int end,u16 val); -static void NoiseOn(int start,int end,u16 val); -static void SetVolumeLR(int right, u8 ch,s16 vol); -static void SetPitch(int ch,u16 val); +static void SoundOn(spu_state_t *spu, int start,int end,u16 val); +static void SoundOff(spu_state_t *spu, int start,int end,u16 val); +static void FModOn(spu_state_t *spu, int start,int end,u16 val); +static void NoiseOn(spu_state_t *spu, int start,int end,u16 val); +static void SetVolumeLR(spu_state_t *spu, int right, u8 ch,s16 vol); +static void SetPitch(spu_state_t *spu, int ch,u16 val); //////////////////////////////////////////////////////////////////////// // WRITE REGISTERS: called by main emu @@ -60,7 +60,7 @@ static void SetPitch(int ch,u16 val); void SPUwriteRegister(mips_cpu_context *cpu, u32 reg, u16 val) { const u32 r=reg&0xfff; - regArea[(r-0xc00)>>1] = val; + cpu->spu->regArea[(r-0xc00)>>1] = val; // printf("SPUwrite: r %x val %x\n", r, val); @@ -74,29 +74,29 @@ void SPUwriteRegister(mips_cpu_context *cpu, u32 reg, u16 val) { //------------------------------------------------// r volume case 0: - SetVolumeLR(0,(u8)ch,val); + SetVolumeLR(cpu->spu, 0,(u8)ch,val); break; //------------------------------------------------// l volume case 2: - SetVolumeLR(1,(u8)ch,val); + SetVolumeLR(cpu->spu, 1,(u8)ch,val); break; //------------------------------------------------// pitch case 4: - SetPitch(ch,val); + SetPitch(cpu->spu, ch,val); break; //------------------------------------------------// start case 6: - s_chan[ch].pStart=spuMemC+((u32) val<<3); + cpu->spu->s_chan[ch].pStart=cpu->spu->spuMemC+((u32) val<<3); break; //------------------------------------------------// level with pre-calcs case 8: { const u32 lval=val; // DEBUG CHECK //---------------------------------------------// - s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0; - s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f; - s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f; - s_chan[ch].ADSRX.SustainLevel=lval & 0x000f; + cpu->spu->s_chan[ch].ADSRX.AttackModeExp=(lval&0x8000)?1:0; + cpu->spu->s_chan[ch].ADSRX.AttackRate=(lval>>8) & 0x007f; + cpu->spu->s_chan[ch].ADSRX.DecayRate=(lval>>4) & 0x000f; + cpu->spu->s_chan[ch].ADSRX.SustainLevel=lval & 0x000f; //---------------------------------------------// } break; @@ -106,11 +106,11 @@ void SPUwriteRegister(mips_cpu_context *cpu, u32 reg, u16 val) const u32 lval=val; // DEBUG CHECK //----------------------------------------------// - s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0; - s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1; - s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f; - s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0; - s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f; + cpu->spu->s_chan[ch].ADSRX.SustainModeExp = (lval&0x8000)?1:0; + cpu->spu->s_chan[ch].ADSRX.SustainIncrease= (lval&0x4000)?0:1; + cpu->spu->s_chan[ch].ADSRX.SustainRate = (lval>>6) & 0x007f; + cpu->spu->s_chan[ch].ADSRX.ReleaseModeExp = (lval&0x0020)?1:0; + cpu->spu->s_chan[ch].ADSRX.ReleaseRate = lval & 0x001f; //----------------------------------------------// } break; @@ -119,8 +119,8 @@ void SPUwriteRegister(mips_cpu_context *cpu, u32 reg, u16 val) // break; //------------------------------------------------// case 0xE: // loop? - s_chan[ch].pLoop=spuMemC+((u32) val<<3); - s_chan[ch].bIgnoreLoop=1; + cpu->spu->s_chan[ch].pLoop=cpu->spu->spuMemC+((u32) val<<3); + cpu->spu->s_chan[ch].bIgnoreLoop=1; break; //------------------------------------------------// } @@ -131,40 +131,40 @@ void SPUwriteRegister(mips_cpu_context *cpu, u32 reg, u16 val) { //-------------------------------------------------// case H_SPUaddr: - spuAddr = (u32) val<<3; + cpu->spu->spuAddr = (u32) val<<3; break; //-------------------------------------------------// case H_SPUdata: - spuMem[spuAddr>>1] = BFLIP16(val); - spuAddr+=2; - if(spuAddr>0x7ffff) spuAddr=0; + cpu->spu->spuMem[cpu->spu->spuAddr>>1] = BFLIP16(val); + cpu->spu->spuAddr+=2; + if(cpu->spu->spuAddr>0x7ffff) cpu->spu->spuAddr=0; break; //-------------------------------------------------// case H_SPUctrl: - spuCtrl=val; + cpu->spu->spuCtrl=val; break; //-------------------------------------------------// case H_SPUstat: - spuStat=val & 0xf800; + cpu->spu->spuStat=val & 0xf800; break; //-------------------------------------------------// case H_SPUReverbAddr: if(val==0xFFFF || val<=0x200) - {rvb.StartAddr=rvb.CurrAddr=0;} + {cpu->spu->rvb.StartAddr=cpu->spu->rvb.CurrAddr=0;} else { const s32 iv=(u32)val<<2; - if(rvb.StartAddr!=iv) + if(cpu->spu->rvb.StartAddr!=iv) { - rvb.StartAddr=(u32)val<<2; - rvb.CurrAddr=rvb.StartAddr; + cpu->spu->rvb.StartAddr=(u32)val<<2; + cpu->spu->rvb.CurrAddr=cpu->spu->rvb.StartAddr; } } break; //-------------------------------------------------// case H_SPUirqAddr: - spuIrq = val; - pSpuIrq=spuMemC+((u32) val<<3); + cpu->spu->spuIrq = val; + cpu->spu->pSpuIrq=cpu->spu->spuMemC+((u32) val<<3); break; //-------------------------------------------------// /* Volume settings appear to be at least 15-bit unsigned in this case. @@ -172,12 +172,12 @@ void SPUwriteRegister(mips_cpu_context *cpu, u32 reg, u16 val) Check out "Chrono Cross: Shadow's End Forest" */ case H_SPUrvolL: - rvb.VolLeft=(s16)val; + cpu->spu->rvb.VolLeft=(s16)val; //printf("%d\n",val); break; //-------------------------------------------------// case H_SPUrvolR: - rvb.VolRight=(s16)val; + cpu->spu->rvb.VolRight=(s16)val; //printf("%d\n",val); break; //-------------------------------------------------// @@ -209,86 +209,86 @@ void SPUwriteRegister(mips_cpu_context *cpu, u32 reg, u16 val) */ //-------------------------------------------------// case H_SPUon1: - SoundOn(0,16,val); + SoundOn(cpu->spu, 0,16,val); break; //-------------------------------------------------// case H_SPUon2: // printf("Boop: %08x: %04x\n",reg,val); - SoundOn(16,24,val); + SoundOn(cpu->spu, 16,24,val); break; //-------------------------------------------------// case H_SPUoff1: - SoundOff(0,16,val); + SoundOff(cpu->spu, 0,16,val); break; //-------------------------------------------------// case H_SPUoff2: - SoundOff(16,24,val); + SoundOff(cpu->spu, 16,24,val); // printf("Boop: %08x: %04x\n",reg,val); break; //-------------------------------------------------// case H_FMod1: - FModOn(0,16,val); + FModOn(cpu->spu, 0,16,val); break; //-------------------------------------------------// case H_FMod2: - FModOn(16,24,val); + FModOn(cpu->spu, 16,24,val); break; //-------------------------------------------------// case H_Noise1: - NoiseOn(0,16,val); + NoiseOn(cpu->spu, 0,16,val); break; //-------------------------------------------------// case H_Noise2: - NoiseOn(16,24,val); + NoiseOn(cpu->spu, 16,24,val); break; //-------------------------------------------------// case H_RVBon1: - rvb.Enabled&=~0xFFFF; - rvb.Enabled|=val; + cpu->spu->rvb.Enabled&=~0xFFFF; + cpu->spu->rvb.Enabled|=val; break; //-------------------------------------------------// case H_RVBon2: - rvb.Enabled&=0xFFFF; - rvb.Enabled|=val<<16; + cpu->spu->rvb.Enabled&=0xFFFF; + cpu->spu->rvb.Enabled|=val<<16; break; //-------------------------------------------------// case H_Reverb+0: - rvb.FB_SRC_A=val; + cpu->spu->rvb.FB_SRC_A=val; break; - case H_Reverb+2 : rvb.FB_SRC_B=(s16)val; break; - case H_Reverb+4 : rvb.IIR_ALPHA=(s16)val; break; - case H_Reverb+6 : rvb.ACC_COEF_A=(s16)val; break; - case H_Reverb+8 : rvb.ACC_COEF_B=(s16)val; break; - case H_Reverb+10 : rvb.ACC_COEF_C=(s16)val; break; - case H_Reverb+12 : rvb.ACC_COEF_D=(s16)val; break; - case H_Reverb+14 : rvb.IIR_COEF=(s16)val; break; - case H_Reverb+16 : rvb.FB_ALPHA=(s16)val; break; - case H_Reverb+18 : rvb.FB_X=(s16)val; break; - case H_Reverb+20 : rvb.IIR_DEST_A0=(s16)val; break; - case H_Reverb+22 : rvb.IIR_DEST_A1=(s16)val; break; - case H_Reverb+24 : rvb.ACC_SRC_A0=(s16)val; break; - case H_Reverb+26 : rvb.ACC_SRC_A1=(s16)val; break; - case H_Reverb+28 : rvb.ACC_SRC_B0=(s16)val; break; - case H_Reverb+30 : rvb.ACC_SRC_B1=(s16)val; break; - case H_Reverb+32 : rvb.IIR_SRC_A0=(s16)val; break; - case H_Reverb+34 : rvb.IIR_SRC_A1=(s16)val; break; - case H_Reverb+36 : rvb.IIR_DEST_B0=(s16)val; break; - case H_Reverb+38 : rvb.IIR_DEST_B1=(s16)val; break; - case H_Reverb+40 : rvb.ACC_SRC_C0=(s16)val; break; - case H_Reverb+42 : rvb.ACC_SRC_C1=(s16)val; break; - case H_Reverb+44 : rvb.ACC_SRC_D0=(s16)val; break; - case H_Reverb+46 : rvb.ACC_SRC_D1=(s16)val; break; - case H_Reverb+48 : rvb.IIR_SRC_B1=(s16)val; break; - case H_Reverb+50 : rvb.IIR_SRC_B0=(s16)val; break; - case H_Reverb+52 : rvb.MIX_DEST_A0=(s16)val; break; - case H_Reverb+54 : rvb.MIX_DEST_A1=(s16)val; break; - case H_Reverb+56 : rvb.MIX_DEST_B0=(s16)val; break; - case H_Reverb+58 : rvb.MIX_DEST_B1=(s16)val; break; - case H_Reverb+60 : rvb.IN_COEF_L=(s16)val; break; - case H_Reverb+62 : rvb.IN_COEF_R=(s16)val; break; + case H_Reverb+2 : cpu->spu->rvb.FB_SRC_B=(s16)val; break; + case H_Reverb+4 : cpu->spu->rvb.IIR_ALPHA=(s16)val; break; + case H_Reverb+6 : cpu->spu->rvb.ACC_COEF_A=(s16)val; break; + case H_Reverb+8 : cpu->spu->rvb.ACC_COEF_B=(s16)val; break; + case H_Reverb+10 : cpu->spu->rvb.ACC_COEF_C=(s16)val; break; + case H_Reverb+12 : cpu->spu->rvb.ACC_COEF_D=(s16)val; break; + case H_Reverb+14 : cpu->spu->rvb.IIR_COEF=(s16)val; break; + case H_Reverb+16 : cpu->spu->rvb.FB_ALPHA=(s16)val; break; + case H_Reverb+18 : cpu->spu->rvb.FB_X=(s16)val; break; + case H_Reverb+20 : cpu->spu->rvb.IIR_DEST_A0=(s16)val; break; + case H_Reverb+22 : cpu->spu->rvb.IIR_DEST_A1=(s16)val; break; + case H_Reverb+24 : cpu->spu->rvb.ACC_SRC_A0=(s16)val; break; + case H_Reverb+26 : cpu->spu->rvb.ACC_SRC_A1=(s16)val; break; + case H_Reverb+28 : cpu->spu->rvb.ACC_SRC_B0=(s16)val; break; + case H_Reverb+30 : cpu->spu->rvb.ACC_SRC_B1=(s16)val; break; + case H_Reverb+32 : cpu->spu->rvb.IIR_SRC_A0=(s16)val; break; + case H_Reverb+34 : cpu->spu->rvb.IIR_SRC_A1=(s16)val; break; + case H_Reverb+36 : cpu->spu->rvb.IIR_DEST_B0=(s16)val; break; + case H_Reverb+38 : cpu->spu->rvb.IIR_DEST_B1=(s16)val; break; + case H_Reverb+40 : cpu->spu->rvb.ACC_SRC_C0=(s16)val; break; + case H_Reverb+42 : cpu->spu->rvb.ACC_SRC_C1=(s16)val; break; + case H_Reverb+44 : cpu->spu->rvb.ACC_SRC_D0=(s16)val; break; + case H_Reverb+46 : cpu->spu->rvb.ACC_SRC_D1=(s16)val; break; + case H_Reverb+48 : cpu->spu->rvb.IIR_SRC_B1=(s16)val; break; + case H_Reverb+50 : cpu->spu->rvb.IIR_SRC_B0=(s16)val; break; + case H_Reverb+52 : cpu->spu->rvb.MIX_DEST_A0=(s16)val; break; + case H_Reverb+54 : cpu->spu->rvb.MIX_DEST_A1=(s16)val; break; + case H_Reverb+56 : cpu->spu->rvb.MIX_DEST_B0=(s16)val; break; + case H_Reverb+58 : cpu->spu->rvb.MIX_DEST_B1=(s16)val; break; + case H_Reverb+60 : cpu->spu->rvb.IN_COEF_L=(s16)val; break; + case H_Reverb+62 : cpu->spu->rvb.IN_COEF_R=(s16)val; break; } } @@ -308,18 +308,18 @@ u16 SPUreadRegister(mips_cpu_context *cpu, u32 reg) case 0xC: // get adsr vol { const int ch=(r>>4)-0xc0; - if(s_chan[ch].bNew) return 1; // we are started, but not processed? return 1 - if(s_chan[ch].ADSRX.lVolume && // same here... we haven't decoded one sample yet, so no envelope yet. return 1 as well - !s_chan[ch].ADSRX.EnvelopeVol) + if(cpu->spu->s_chan[ch].bNew) return 1; // we are started, but not processed? return 1 + if(cpu->spu->s_chan[ch].ADSRX.lVolume && // same here... we haven't decoded one sample yet, so no envelope yet. return 1 as well + !cpu->spu->s_chan[ch].ADSRX.EnvelopeVol) return 1; - return (u16)(s_chan[ch].ADSRX.EnvelopeVol>>16); + return (u16)(cpu->spu->s_chan[ch].ADSRX.EnvelopeVol>>16); } case 0xE: // get loop address { const int ch=(r>>4)-0xc0; - if(s_chan[ch].pLoop==NULL) return 0; - return (u16)((s_chan[ch].pLoop-spuMemC)>>3); + if(cpu->spu->s_chan[ch].pLoop==NULL) return 0; + return (u16)((cpu->spu->s_chan[ch].pLoop-cpu->spu->spuMemC)>>3); } } } @@ -327,24 +327,24 @@ u16 SPUreadRegister(mips_cpu_context *cpu, u32 reg) switch(r) { case H_SPUctrl: - return spuCtrl; + return cpu->spu->spuCtrl; case H_SPUstat: - return spuStat; + return cpu->spu->spuStat; case H_SPUaddr: - return (u16)(spuAddr>>3); + return (u16)(cpu->spu->spuAddr>>3); case H_SPUdata: { - u16 s=BFLIP16(spuMem[spuAddr>>1]); - spuAddr+=2; - if(spuAddr>0x7ffff) spuAddr=0; + u16 s=BFLIP16(cpu->spu->spuMem[cpu->spu->spuAddr>>1]); + cpu->spu->spuAddr+=2; + if(cpu->spu->spuAddr>0x7ffff) cpu->spu->spuAddr=0; return s; } case H_SPUirqAddr: - return spuIrq; + return cpu->spu->spuIrq; //case H_SPUIsOn1: // return IsSoundOn(0,16); @@ -354,23 +354,23 @@ u16 SPUreadRegister(mips_cpu_context *cpu, u32 reg) } - return regArea[(r-0xc00)>>1]; + return cpu->spu->regArea[(r-0xc00)>>1]; } //////////////////////////////////////////////////////////////////////// // SOUND ON register write //////////////////////////////////////////////////////////////////////// -static void SoundOn(int start,int end,u16 val) // SOUND ON PSX COMAND +static void SoundOn(spu_state_t *spu, int start,int end,u16 val) // SOUND ON PSX COMAND { int ch; for(ch=start;ch>=1) // loop channels { - if((val&1) && s_chan[ch].pStart) // mmm... start has to be set before key on !?! + if((val&1) && spu->s_chan[ch].pStart) // mmm... start has to be set before key on !?! { - s_chan[ch].bIgnoreLoop=0; - s_chan[ch].bNew=1; + spu->s_chan[ch].bIgnoreLoop=0; + spu->s_chan[ch].bNew=1; } } } @@ -379,14 +379,14 @@ static void SoundOn(int start,int end,u16 val) // SOUND ON PSX COMAND // SOUND OFF register write //////////////////////////////////////////////////////////////////////// -static void SoundOff(int start,int end,u16 val) // SOUND OFF PSX COMMAND +static void SoundOff(spu_state_t *spu, int start,int end,u16 val) // SOUND OFF PSX COMMAND { int ch; for(ch=start;ch>=1) // loop channels { - if(val&1) // && s_chan[i].bOn) mmm... + if(val&1) // && cpu->spu->s_chan[i].bOn) mmm... { - s_chan[ch].bStop=1; + spu->s_chan[ch].bStop=1; } } } @@ -395,7 +395,7 @@ static void SoundOff(int start,int end,u16 val) // SOUND OFF PSX COMMAND // FMOD register write //////////////////////////////////////////////////////////////////////// -static void FModOn(int start,int end,u16 val) // FMOD ON PSX COMMAND +static void FModOn(spu_state_t *spu, int start,int end,u16 val) // FMOD ON PSX COMMAND { int ch; @@ -405,13 +405,13 @@ static void FModOn(int start,int end,u16 val) // FMOD ON PSX COMMAND { if(ch>0) { - s_chan[ch].bFMod=1; // --> sound channel - s_chan[ch-1].bFMod=2; // --> freq channel + spu->s_chan[ch].bFMod=1; // --> sound channel + spu->s_chan[ch-1].bFMod=2; // --> freq channel } } else { - s_chan[ch].bFMod=0; // --> turn off fmod + spu->s_chan[ch].bFMod=0; // --> turn off fmod } } } @@ -420,7 +420,7 @@ static void FModOn(int start,int end,u16 val) // FMOD ON PSX COMMAND // NOISE register write //////////////////////////////////////////////////////////////////////// -static void NoiseOn(int start,int end,u16 val) // NOISE ON PSX COMMAND +static void NoiseOn(spu_state_t *spu, int start,int end,u16 val) // NOISE ON PSX COMMAND { int ch; @@ -428,11 +428,11 @@ static void NoiseOn(int start,int end,u16 val) // NOISE ON PSX COMMAND { if(val&1) // -> noise on/off { - s_chan[ch].bNoise=1; + spu->s_chan[ch].bNoise=1; } else { - s_chan[ch].bNoise=0; + spu->s_chan[ch].bNoise=0; } } } @@ -443,14 +443,14 @@ static void NoiseOn(int start,int end,u16 val) // NOISE ON PSX COMMAND // please note: sweep is wrong. -static void SetVolumeLR(int right, u8 ch,s16 vol) // LEFT VOLUME +static void SetVolumeLR(spu_state_t *spu, int right, u8 ch,s16 vol) // LEFT VOLUME { //if(vol&0xc000) //printf("%d %08x\n",right,vol); if(right) - s_chan[ch].iRightVolRaw=vol; + spu->s_chan[ch].iRightVolRaw=vol; else - s_chan[ch].iLeftVolRaw=vol; + spu->s_chan[ch].iLeftVolRaw=vol; if(vol&0x8000) // sweep? { @@ -476,24 +476,24 @@ static void SetVolumeLR(int right, u8 ch,s16 vol) // LEFT VOLUME // vol&=0x3fff; } if(right) - s_chan[ch].iRightVolume=vol; + spu->s_chan[ch].iRightVolume=vol; else - s_chan[ch].iLeftVolume=vol; // store volume + spu->s_chan[ch].iLeftVolume=vol; // store volume } //////////////////////////////////////////////////////////////////////// // PITCH register write //////////////////////////////////////////////////////////////////////// -static void SetPitch(int ch,u16 val) // SET PITCH +static void SetPitch(spu_state_t *spu, int ch,u16 val) // SET PITCH { int NP; if(val>0x3fff) NP=0x3fff; // get pitch val else NP=val; - s_chan[ch].iRawPitch=NP; + spu->s_chan[ch].iRawPitch=NP; NP=(44100L*NP)/4096L; // calc frequency if(NP<1) NP=1; // some security - s_chan[ch].iActFreq=NP; // store frequency + spu->s_chan[ch].iActFreq=NP; // store frequency } diff --git a/plugins/ao/eng_psf/peops/reverb.c b/plugins/ao/eng_psf/peops/reverb.c index aa27f33c..0cc09243 100644 --- a/plugins/ao/eng_psf/peops/reverb.c +++ b/plugins/ao/eng_psf/peops/reverb.c @@ -51,23 +51,23 @@ //////////////////////////////////////////////////////////////////////// -static INLINE s64 g_buffer(int iOff) // get_buffer content helper: takes care about wraps +static INLINE s64 g_buffer(spu_state_t *spu, int iOff) // get_buffer content helper: takes care about wraps { - s16 * p=(s16 *)spuMem; - iOff=(iOff*4)+rvb.CurrAddr; - while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000); - while(iOffspuMem; + iOff=(iOff*4)+spu->rvb.CurrAddr; + while(iOff>0x3FFFF) iOff=spu->rvb.StartAddr+(iOff-0x40000); + while(iOffrvb.StartAddr) iOff=0x3ffff-(spu->rvb.StartAddr-iOff); return (int)(s16)BFLIP16(*(p+iOff)); } //////////////////////////////////////////////////////////////////////// -static INLINE void s_buffer(int iOff,int iVal) // set_buffer content helper: takes care about wraps and clipping +static INLINE void s_buffer(spu_state_t *spu, int iOff,int iVal) // set_buffer content helper: takes care about wraps and clipping { - s16 * p=(s16 *)spuMem; - iOff=(iOff*4)+rvb.CurrAddr; - while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000); - while(iOffspuMem; + iOff=(iOff*4)+spu->rvb.CurrAddr; + while(iOff>0x3FFFF) iOff=spu->rvb.StartAddr+(iOff-0x40000); + while(iOffrvb.StartAddr) iOff=0x3ffff-(spu->rvb.StartAddr-iOff); if(iVal<-32768L) iVal=-32768L; if(iVal>32767L) iVal=32767L; *(p+iOff)=(s16)BFLIP16((s16)iVal); @@ -75,17 +75,17 @@ static INLINE void s_buffer(int iOff,int iVal) // set_buffer cont //////////////////////////////////////////////////////////////////////// -static INLINE void s_buffer1(int iOff,int iVal) // set_buffer (+1 sample) content helper: takes care about wraps and clipping +static INLINE void s_buffer1(spu_state_t *spu, int iOff,int iVal) // set_buffer (+1 sample) content helper: takes care about wraps and clipping { - s16 * p=(s16 *)spuMem; - iOff=(iOff*4)+rvb.CurrAddr+1; - while(iOff>0x3FFFF) iOff=rvb.StartAddr+(iOff-0x40000); - while(iOffspuMem; + iOff=(iOff*4)+spu->rvb.CurrAddr+1; + while(iOff>0x3FFFF) iOff=spu->rvb.StartAddr+(iOff-0x40000); + while(iOffrvb.StartAddr) iOff=0x3ffff-(spu->rvb.StartAddr-iOff); if(iVal<-32768L) iVal=-32768L;if(iVal>32767L) iVal=32767L; *(p+iOff)=(s16)BFLIP16((s16)iVal); } -static INLINE void MixREVERBLeftRight(s32 *oleft, s32 *oright, s32 inleft, s32 inright) +static INLINE void MixREVERBLeftRight(spu_state_t *spu, s32 *oleft, s32 *oright, s32 inleft, s32 inright) { static s32 downbuf[2][8]; static s32 upbuf[2][8]; @@ -96,9 +96,9 @@ static INLINE void MixREVERBLeftRight(s32 *oleft, s32 *oright, s32 inleft, s32 i }; int x; - if(!rvb.StartAddr) // reverb is off + if(!spu->rvb.StartAddr) // reverb is off { - rvb.iRVBLeft=rvb.iRVBRight=0; + spu->rvb.iRVBLeft=spu->rvb.iRVBRight=0; return; } @@ -110,7 +110,7 @@ static INLINE void MixREVERBLeftRight(s32 *oleft, s32 *oright, s32 inleft, s32 i if(dbpos&1) // we work on every second left value: downsample to 22 khz { - if(spuCtrl&0x80) // -> reverb on? oki + if(spu->spuCtrl&0x80) // -> reverb on? oki { int ACC0,ACC1,FB_A0,FB_A1,FB_B0,FB_B1; s32 INPUT_SAMPLE_L=0; @@ -127,58 +127,58 @@ static INLINE void MixREVERBLeftRight(s32 *oleft, s32 *oright, s32 inleft, s32 i INPUT_SAMPLE_L>>=(16-8); INPUT_SAMPLE_R>>=(16-8); { - const s64 IIR_INPUT_A0 = ((g_buffer(rvb.IIR_SRC_A0) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_L * rvb.IN_COEF_L)>>15); - const s64 IIR_INPUT_A1 = ((g_buffer(rvb.IIR_SRC_A1) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_R * rvb.IN_COEF_R)>>15); - const s64 IIR_INPUT_B0 = ((g_buffer(rvb.IIR_SRC_B0) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_L * rvb.IN_COEF_L)>>15); - const s64 IIR_INPUT_B1 = ((g_buffer(rvb.IIR_SRC_B1) * rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_R * rvb.IN_COEF_R)>>15); - const s64 IIR_A0 = ((IIR_INPUT_A0 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_A0) * (32768L - rvb.IIR_ALPHA))>>15); - const s64 IIR_A1 = ((IIR_INPUT_A1 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_A1) * (32768L - rvb.IIR_ALPHA))>>15); - const s64 IIR_B0 = ((IIR_INPUT_B0 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_B0) * (32768L - rvb.IIR_ALPHA))>>15); - const s64 IIR_B1 = ((IIR_INPUT_B1 * rvb.IIR_ALPHA)>>15) + ((g_buffer(rvb.IIR_DEST_B1) * (32768L - rvb.IIR_ALPHA))>>15); - - s_buffer1(rvb.IIR_DEST_A0, IIR_A0); - s_buffer1(rvb.IIR_DEST_A1, IIR_A1); - s_buffer1(rvb.IIR_DEST_B0, IIR_B0); - s_buffer1(rvb.IIR_DEST_B1, IIR_B1); + const s64 IIR_INPUT_A0 = ((g_buffer(spu, spu->rvb.IIR_SRC_A0) * spu->rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_L * spu->rvb.IN_COEF_L)>>15); + const s64 IIR_INPUT_A1 = ((g_buffer(spu, spu->rvb.IIR_SRC_A1) * spu->rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_R * spu->rvb.IN_COEF_R)>>15); + const s64 IIR_INPUT_B0 = ((g_buffer(spu, spu->rvb.IIR_SRC_B0) * spu->rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_L * spu->rvb.IN_COEF_L)>>15); + const s64 IIR_INPUT_B1 = ((g_buffer(spu, spu->rvb.IIR_SRC_B1) * spu->rvb.IIR_COEF)>>15) + ((INPUT_SAMPLE_R * spu->rvb.IN_COEF_R)>>15); + const s64 IIR_A0 = ((IIR_INPUT_A0 * spu->rvb.IIR_ALPHA)>>15) + ((g_buffer(spu, spu->rvb.IIR_DEST_A0) * (32768L - spu->rvb.IIR_ALPHA))>>15); + const s64 IIR_A1 = ((IIR_INPUT_A1 * spu->rvb.IIR_ALPHA)>>15) + ((g_buffer(spu, spu->rvb.IIR_DEST_A1) * (32768L - spu->rvb.IIR_ALPHA))>>15); + const s64 IIR_B0 = ((IIR_INPUT_B0 * spu->rvb.IIR_ALPHA)>>15) + ((g_buffer(spu, spu->rvb.IIR_DEST_B0) * (32768L - spu->rvb.IIR_ALPHA))>>15); + const s64 IIR_B1 = ((IIR_INPUT_B1 * spu->rvb.IIR_ALPHA)>>15) + ((g_buffer(spu, spu->rvb.IIR_DEST_B1) * (32768L - spu->rvb.IIR_ALPHA))>>15); + + s_buffer1(spu, spu->rvb.IIR_DEST_A0, IIR_A0); + s_buffer1(spu, spu->rvb.IIR_DEST_A1, IIR_A1); + s_buffer1(spu, spu->rvb.IIR_DEST_B0, IIR_B0); + s_buffer1(spu, spu->rvb.IIR_DEST_B1, IIR_B1); - ACC0 = ((g_buffer(rvb.ACC_SRC_A0) * rvb.ACC_COEF_A)>>15) + - ((g_buffer(rvb.ACC_SRC_B0) * rvb.ACC_COEF_B)>>15) + - ((g_buffer(rvb.ACC_SRC_C0) * rvb.ACC_COEF_C)>>15) + - ((g_buffer(rvb.ACC_SRC_D0) * rvb.ACC_COEF_D)>>15); - ACC1 = ((g_buffer(rvb.ACC_SRC_A1) * rvb.ACC_COEF_A)>>15) + - ((g_buffer(rvb.ACC_SRC_B1) * rvb.ACC_COEF_B)>>15) + - ((g_buffer(rvb.ACC_SRC_C1) * rvb.ACC_COEF_C)>>15) + - ((g_buffer(rvb.ACC_SRC_D1) * rvb.ACC_COEF_D)>>15); - - FB_A0 = g_buffer(rvb.MIX_DEST_A0 - rvb.FB_SRC_A); - FB_A1 = g_buffer(rvb.MIX_DEST_A1 - rvb.FB_SRC_A); - FB_B0 = g_buffer(rvb.MIX_DEST_B0 - rvb.FB_SRC_B); - FB_B1 = g_buffer(rvb.MIX_DEST_B1 - rvb.FB_SRC_B); - - s_buffer(rvb.MIX_DEST_A0, ACC0 - ((FB_A0 * rvb.FB_ALPHA)>>15)); - s_buffer(rvb.MIX_DEST_A1, ACC1 - ((FB_A1 * rvb.FB_ALPHA)>>15)); + ACC0 = ((g_buffer(spu, spu->rvb.ACC_SRC_A0) * spu->rvb.ACC_COEF_A)>>15) + + ((g_buffer(spu, spu->rvb.ACC_SRC_B0) * spu->rvb.ACC_COEF_B)>>15) + + ((g_buffer(spu, spu->rvb.ACC_SRC_C0) * spu->rvb.ACC_COEF_C)>>15) + + ((g_buffer(spu, spu->rvb.ACC_SRC_D0) * spu->rvb.ACC_COEF_D)>>15); + ACC1 = ((g_buffer(spu, spu->rvb.ACC_SRC_A1) * spu->rvb.ACC_COEF_A)>>15) + + ((g_buffer(spu, spu->rvb.ACC_SRC_B1) * spu->rvb.ACC_COEF_B)>>15) + + ((g_buffer(spu, spu->rvb.ACC_SRC_C1) * spu->rvb.ACC_COEF_C)>>15) + + ((g_buffer(spu, spu->rvb.ACC_SRC_D1) * spu->rvb.ACC_COEF_D)>>15); + + FB_A0 = g_buffer(spu, spu->rvb.MIX_DEST_A0 - spu->rvb.FB_SRC_A); + FB_A1 = g_buffer(spu, spu->rvb.MIX_DEST_A1 - spu->rvb.FB_SRC_A); + FB_B0 = g_buffer(spu, spu->rvb.MIX_DEST_B0 - spu->rvb.FB_SRC_B); + FB_B1 = g_buffer(spu, spu->rvb.MIX_DEST_B1 - spu->rvb.FB_SRC_B); + + s_buffer(spu, spu->rvb.MIX_DEST_A0, ACC0 - ((FB_A0 * spu->rvb.FB_ALPHA)>>15)); + s_buffer(spu, spu->rvb.MIX_DEST_A1, ACC1 - ((FB_A1 * spu->rvb.FB_ALPHA)>>15)); - s_buffer(rvb.MIX_DEST_B0, ((rvb.FB_ALPHA * ACC0)>>15) - ((FB_A0 * (int)(rvb.FB_ALPHA^0xFFFF8000))>>15) - ((FB_B0 * rvb.FB_X)>>15)); - s_buffer(rvb.MIX_DEST_B1, ((rvb.FB_ALPHA * ACC1)>>15) - ((FB_A1 * (int)(rvb.FB_ALPHA^0xFFFF8000))>>15) - ((FB_B1 * rvb.FB_X)>>15)); + s_buffer(spu, spu->rvb.MIX_DEST_B0, ((spu->rvb.FB_ALPHA * ACC0)>>15) - ((FB_A0 * (int)(spu->rvb.FB_ALPHA^0xFFFF8000))>>15) - ((FB_B0 * spu->rvb.FB_X)>>15)); + s_buffer(spu, spu->rvb.MIX_DEST_B1, ((spu->rvb.FB_ALPHA * ACC1)>>15) - ((FB_A1 * (int)(spu->rvb.FB_ALPHA^0xFFFF8000))>>15) - ((FB_B1 * spu->rvb.FB_X)>>15)); - rvb.iRVBLeft = (g_buffer(rvb.MIX_DEST_A0)+g_buffer(rvb.MIX_DEST_B0))/3; - rvb.iRVBRight = (g_buffer(rvb.MIX_DEST_A1)+g_buffer(rvb.MIX_DEST_B1))/3; + spu->rvb.iRVBLeft = (g_buffer(spu, spu->rvb.MIX_DEST_A0)+g_buffer(spu, spu->rvb.MIX_DEST_B0))/3; + spu->rvb.iRVBRight = (g_buffer(spu, spu->rvb.MIX_DEST_A1)+g_buffer(spu, spu->rvb.MIX_DEST_B1))/3; - rvb.iRVBLeft = ((s64)rvb.iRVBLeft * rvb.VolLeft) >> 14; - rvb.iRVBRight = ((s64)rvb.iRVBRight * rvb.VolRight) >> 14; + spu->rvb.iRVBLeft = ((s64)spu->rvb.iRVBLeft * spu->rvb.VolLeft) >> 14; + spu->rvb.iRVBRight = ((s64)spu->rvb.iRVBRight * spu->rvb.VolRight) >> 14; - upbuf[0][ubpos]=rvb.iRVBLeft; - upbuf[1][ubpos]=rvb.iRVBRight; + upbuf[0][ubpos]=spu->rvb.iRVBLeft; + upbuf[1][ubpos]=spu->rvb.iRVBRight; ubpos=(ubpos+1)&7; } // Bracket hack(et). } else // -> reverb off { - rvb.iRVBLeft=rvb.iRVBRight=0; + spu->rvb.iRVBLeft=spu->rvb.iRVBRight=0; return; } - rvb.CurrAddr++; - if(rvb.CurrAddr>0x3ffff) rvb.CurrAddr=rvb.StartAddr; + spu->rvb.CurrAddr++; + if(spu->rvb.CurrAddr>0x3ffff) spu->rvb.CurrAddr=spu->rvb.StartAddr; } else { diff --git a/plugins/ao/eng_psf/peops/spu.c b/plugins/ao/eng_psf/peops/spu.c index 4dca0d79..75f3c845 100644 --- a/plugins/ao/eng_psf/peops/spu.c +++ b/plugins/ao/eng_psf/peops/spu.c @@ -93,39 +93,12 @@ void SPUirq(void) ; //////////////////////////////////////////////////////////////////////// // globals //////////////////////////////////////////////////////////////////////// - -// psx buffer / addresses - -static u16 regArea[0x200]; -static u16 spuMem[256*1024]; -static u8 * spuMemC; -static u8 * pSpuIrq=0; -static u8 * pSpuBuffer; - -// user settings -static int iVolume; - -// MAIN infos struct for each channel - -static SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling) -static REVERBInfo rvb; - -static u32 dwNoiseVal=1; // global noise generator - -static u16 spuCtrl=0; // some vars to store psx reg infos -static u16 spuStat=0; -static u16 spuIrq=0; -static u32 spuAddr=0xffffffff; // address into spu mem -static int bSPUIsOpen=0; - static const int f[5][2] = { - { 0, 0 }, - { 60, 0 }, - { 115, -52 }, - { 98, -55 }, - { 122, -60 } }; -static s16 * pS; -static s32 ttemp; + { 0, 0 }, + { 60, 0 }, + { 115, -52 }, + { 98, -55 }, + { 122, -60 } }; //////////////////////////////////////////////////////////////////////// // CODE AREA @@ -133,6 +106,8 @@ static s32 ttemp; // dirty inline func includes +#include "ao.h" + #include "../peops/reverb.c" #include "../peops/adsr.c" @@ -143,8 +118,8 @@ static s32 ttemp; //////////////////////////////////////////////////////////////////////// // helpers for so-called "gauss interpolation" -#define gval0 (((int *)(&s_chan[ch].SB[29]))[gpos]) -#define gval(x) (((int *)(&s_chan[ch].SB[29]))[(gpos+x)&3]) +#define gval0 (((int *)(&spu->s_chan[ch].SB[29]))[gpos]) +#define gval(x) (((int *)(&spu->s_chan[ch].SB[29]))[(gpos+x)&3]) #include "gauss_i.h" @@ -154,24 +129,24 @@ static s32 ttemp; // START SOUND... called by main thread to setup a new sound on a channel //////////////////////////////////////////////////////////////////////// -static INLINE void StartSound(int ch) +static INLINE void StartSound(spu_state_t *spu, int ch) { - StartADSR(ch); + StartADSR(spu, ch); - s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start + spu->s_chan[ch].pCurr=spu->s_chan[ch].pStart; // set sample start - s_chan[ch].s_1=0; // init mixing vars - s_chan[ch].s_2=0; - s_chan[ch].iSBPos=28; + spu->s_chan[ch].s_1=0; // init mixing vars + spu->s_chan[ch].s_2=0; + spu->s_chan[ch].iSBPos=28; - s_chan[ch].bNew=0; // init channel flags - s_chan[ch].bStop=0; - s_chan[ch].bOn=1; + spu->s_chan[ch].bNew=0; // init channel flags + spu->s_chan[ch].bStop=0; + spu->s_chan[ch].bOn=1; - s_chan[ch].SB[29]=0; // init our interpolation helpers - s_chan[ch].SB[30]=0; + spu->s_chan[ch].SB[29]=0; // init our interpolation helpers + spu->s_chan[ch].SB[30]=0; - s_chan[ch].spos=0x40000L;s_chan[ch].SB[28]=0; // -> start with more decoding + spu->s_chan[ch].spos=0x40000L;spu->s_chan[ch].SB[28]=0; // -> start with more decoding } //////////////////////////////////////////////////////////////////////// @@ -180,39 +155,35 @@ static INLINE void StartSound(int ch) // basically the whole sound processing is done in this fat func! //////////////////////////////////////////////////////////////////////// -static u32 sampcount; -static u32 decaybegin; -static u32 decayend; - // Counting to 65536 results in full volume offage. -void setlength(s32 stop, s32 fade) +void setlength(spu_state_t *spu, s32 stop, s32 fade) { if(stop==~0) { - decaybegin=~0; + spu->decaybegin=~0; } else { stop=(stop*441)/10; fade=(fade*441)/10; - decaybegin=stop; - decayend=stop+fade; + spu->decaybegin=stop; + spu->decayend=stop+fade; } } #define CLIP(_x) {if(_x>32767) _x=32767; if(_x<-32767) _x=-32767;} int SPUasync(mips_cpu_context *cpu, u32 cycles) { - int volmul=iVolume; - static s32 dosampies; + spu_state_t *spu = cpu->spu; + int volmul=spu->iVolume; s32 temp; - ttemp+=cycles; - dosampies=ttemp/384; - if(!dosampies) return(1); - ttemp-=dosampies*384; - temp=dosampies; + spu->ttemp+=cycles; + spu->dosampies=spu->ttemp/384; + if(!spu->dosampies) return(1); + spu->ttemp-=spu->dosampies*384; + temp=spu->dosampies; while(temp) { @@ -227,41 +198,41 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) { for(ch=0;chs_chan[ch].bNew) StartSound(spu, ch); // start new sound + if(!spu->s_chan[ch].bOn) continue; // channel not playing? next - if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency? + if(spu->s_chan[ch].iActFreq!=spu->s_chan[ch].iUsedFreq) // new psx frequency? { - s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps - s_chan[ch].sinc=s_chan[ch].iRawPitch<<4; - if(!s_chan[ch].sinc) s_chan[ch].sinc=1; + spu->s_chan[ch].iUsedFreq=spu->s_chan[ch].iActFreq; // -> take it and calc steps + spu->s_chan[ch].sinc=spu->s_chan[ch].iRawPitch<<4; + if(!spu->s_chan[ch].sinc) spu->s_chan[ch].sinc=1; } - while(s_chan[ch].spos>=0x10000L) + while(spu->s_chan[ch].spos>=0x10000L) { - if(s_chan[ch].iSBPos==28) // 28 reached? + if(spu->s_chan[ch].iSBPos==28) // 28 reached? { int predict_nr,shift_factor,flags,d,s; u8* start;unsigned int nSample; int s_1,s_2; - start=s_chan[ch].pCurr; // set up the current pos + start=spu->s_chan[ch].pCurr; // set up the current pos if (start == (u8*)-1) // special "stop" sign { - s_chan[ch].bOn=0; // -> turn everything off - s_chan[ch].ADSRX.lVolume=0; - s_chan[ch].ADSRX.EnvelopeVol=0; + spu->s_chan[ch].bOn=0; // -> turn everything off + spu->s_chan[ch].ADSRX.lVolume=0; + spu->s_chan[ch].ADSRX.EnvelopeVol=0; goto ENDX; // -> and done for this channel } - s_chan[ch].iSBPos=0; // Reset buffer play index. + spu->s_chan[ch].iSBPos=0; // Reset buffer play index. //////////////////////////////////////////// spu irq handler here? mmm... do it later - s_1=s_chan[ch].s_1; - s_2=s_chan[ch].s_2; + s_1=spu->s_chan[ch].s_1; + s_2=spu->s_chan[ch].s_2; predict_nr=(int)*start;start++; shift_factor=predict_nr&0xf; @@ -269,7 +240,7 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) flags=(int)*start;start++; // -------------------------------------- // - // Decode new samples into s_chan[ch].SB[0 through 27] + // Decode new samples into spu->s_chan[ch].SB[0 through 27] for (nSample=0;nSample<28;start++) { d=(int)*start; @@ -281,28 +252,28 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) s_2=s_1;s_1=fa; s=((d & 0xf0) << 8); - s_chan[ch].SB[nSample++]=fa; + spu->s_chan[ch].SB[nSample++]=fa; if(s&0x8000) s|=0xffff0000; fa=(s>>shift_factor); fa=fa + ((s_1 * f[predict_nr][0])>>6) + ((s_2 * f[predict_nr][1])>>6); s_2=s_1;s_1=fa; - s_chan[ch].SB[nSample++]=fa; + spu->s_chan[ch].SB[nSample++]=fa; } //////////////////////////////////////////// irq check - if(spuCtrl&0x40) // irq active? + if(spu->spuCtrl&0x40) // irq active? { - if((pSpuIrq > start-16 && // irq address reached? - pSpuIrq <= start) || + if((spu->pSpuIrq > start-16 && // irq address reached? + spu->pSpuIrq <= start) || ((flags&1) && // special: irq on looping addr, when stop/loop flag is set - (pSpuIrq > s_chan[ch].pLoop-16 && - pSpuIrq <= s_chan[ch].pLoop))) + (spu->pSpuIrq > spu->s_chan[ch].pLoop-16 && + spu->pSpuIrq <= spu->s_chan[ch].pLoop))) { //extern s32 spuirqvoodoo; - s_chan[ch].iIrqDone=1; // -> debug flag + spu->s_chan[ch].iIrqDone=1; // -> debug flag SPUirq(); //puts("IRQ"); //if(spuirqvoodoo!=-1) @@ -315,43 +286,43 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) //////////////////////////////////////////// flag handler - if((flags&4) && (!s_chan[ch].bIgnoreLoop)) - s_chan[ch].pLoop=start-16; // loop adress + if((flags&4) && (!spu->s_chan[ch].bIgnoreLoop)) + spu->s_chan[ch].pLoop=start-16; // loop adress if(flags&1) // 1: stop/loop { // We play this block out first... //if(!(flags&2)) // 1+2: do loop... otherwise: stop - if(flags!=3 || s_chan[ch].pLoop==NULL) // PETE: if we don't check exactly for 3, loop hang ups will happen (DQ4, for example) + if(flags!=3 || spu->s_chan[ch].pLoop==NULL) // PETE: if we don't check exactly for 3, loop hang ups will happen (DQ4, for example) { // and checking if pLoop is set avoids crashes, yeah start = (u8*)-1; } else { - start = s_chan[ch].pLoop; + start = spu->s_chan[ch].pLoop; } } - s_chan[ch].pCurr=start; // store values for next cycle - s_chan[ch].s_1=s_1; - s_chan[ch].s_2=s_2; + spu->s_chan[ch].pCurr=start; // store values for next cycle + spu->s_chan[ch].s_1=s_1; + spu->s_chan[ch].s_2=s_2; //////////////////////////////////////////// } - fa=s_chan[ch].SB[s_chan[ch].iSBPos++]; // get sample data + fa=spu->s_chan[ch].SB[spu->s_chan[ch].iSBPos++]; // get sample data - if((spuCtrl&0x4000)==0) fa=0; // muted? + if((spu->spuCtrl&0x4000)==0) fa=0; // muted? else CLIP(fa); { int gpos; - gpos = s_chan[ch].SB[28]; + gpos = spu->s_chan[ch].SB[28]; gval0 = fa; gpos = (gpos+1) & 3; - s_chan[ch].SB[28] = gpos; + spu->s_chan[ch].SB[28] = gpos; } - s_chan[ch].spos -= 0x10000L; + spu->s_chan[ch].spos -= 0x10000L; } //////////////////////////////////////////////// @@ -359,29 +330,29 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) // surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used... // and sometimes the noise will be used as fmod modulation... pfff - if(s_chan[ch].bNoise) + if(spu->s_chan[ch].bNoise) { //puts("Noise"); - if((dwNoiseVal<<=1)&0x80000000L) + if((spu->dwNoiseVal<<=1)&0x80000000L) { - dwNoiseVal^=0x0040001L; - fa=((dwNoiseVal>>2)&0x7fff); + spu->dwNoiseVal^=0x0040001L; + fa=((spu->dwNoiseVal>>2)&0x7fff); fa=-fa; } - else fa=(dwNoiseVal>>2)&0x7fff; + else fa=(spu->dwNoiseVal>>2)&0x7fff; // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val - fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl&0x3f00)>>9))+1)); + fa=spu->s_chan[ch].iOldNoise+((fa-spu->s_chan[ch].iOldNoise)/((0x001f-((spu->spuCtrl&0x3f00)>>9))+1)); if(fa>32767L) fa=32767L; if(fa<-32767L) fa=-32767L; - s_chan[ch].iOldNoise=fa; + spu->s_chan[ch].iOldNoise=fa; } //---------------------------------------- else // NO NOISE (NORMAL SAMPLE DATA) HERE { int vl, vr, gpos; - vl = (s_chan[ch].spos >> 6) & ~3; - gpos = s_chan[ch].SB[28]; + vl = (spu->s_chan[ch].spos >> 6) & ~3; + gpos = spu->s_chan[ch].SB[28]; vr=(gauss[vl]*gval0)>>9; vr+=(gauss[vl+1]*gval(1))>>9; vr+=(gauss[vl+2]*gval(2))>>9; @@ -389,28 +360,28 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) fa = vr>>2; } - s_chan[ch].sval = (MixADSR(ch) * fa)>>10; // / 1023; // add adsr - if(s_chan[ch].bFMod==2) // fmod freq channel + spu->s_chan[ch].sval = (MixADSR(spu, ch) * fa)>>10; // / 1023; // add adsr + if(spu->s_chan[ch].bFMod==2) // fmod freq channel { - int NP=s_chan[ch+1].iRawPitch; - NP=((32768L+s_chan[ch].sval)*NP)>>15; ///32768L; + int NP=spu->s_chan[ch+1].iRawPitch; + NP=((32768L+spu->s_chan[ch].sval)*NP)>>15; ///32768L; if(NP>0x3fff) NP=0x3fff; if(NP<0x1) NP=0x1; // mmmm... if I do this, all is screwed - // s_chan[ch+1].iRawPitch=NP; + // spu->s_chan[ch+1].iRawPitch=NP; NP=(44100L*NP)/(4096L); // calc frequency - s_chan[ch+1].iActFreq=NP; - s_chan[ch+1].iUsedFreq=NP; - s_chan[ch+1].sinc=(((NP/10)<<16)/4410); - if(!s_chan[ch+1].sinc) s_chan[ch+1].sinc=1; + spu->s_chan[ch+1].iActFreq=NP; + spu->s_chan[ch+1].iUsedFreq=NP; + spu->s_chan[ch+1].sinc=(((NP/10)<<16)/4410); + if(!spu->s_chan[ch+1].sinc) spu->s_chan[ch+1].sinc=1; // mmmm... set up freq decoding positions? - // s_chan[ch+1].iSBPos=28; - // s_chan[ch+1].spos=0x10000L; + // spu->s_chan[ch+1].iSBPos=28; + // spu->s_chan[ch+1].spos=0x10000L; } else { @@ -420,8 +391,8 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) if (1) //ao_channel_enable[ch+PSF_1]) { { - tmpl=(s_chan[ch].sval*s_chan[ch].iLeftVolume)>>14; - tmpr=(s_chan[ch].sval*s_chan[ch].iRightVolume)>>14; + tmpl=(spu->s_chan[ch].sval*spu->s_chan[ch].iLeftVolume)>>14; + tmpr=(spu->s_chan[ch].sval*spu->s_chan[ch].iRightVolume)>>14; } else { tmpl = 0; tmpr = 0; @@ -429,40 +400,40 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) sl+=tmpl; sr+=tmpr; - if(((rvb.Enabled>>ch)&1) && (spuCtrl&0x80)) + if(((spu->rvb.Enabled>>ch)&1) && (spu->spuCtrl&0x80)) { revLeft+=tmpl; revRight+=tmpr; } } - s_chan[ch].spos += s_chan[ch].sinc; + spu->s_chan[ch].spos += spu->s_chan[ch].sinc; ENDX: ; } } /////////////////////////////////////////////////////// // mix all channels (including reverb) into one buffer - MixREVERBLeftRight(&sl,&sr,revLeft,revRight); + MixREVERBLeftRight(spu, &sl,&sr,revLeft,revRight); // printf("sampcount %d decaybegin %d decayend %d\n", sampcount, decaybegin, decayend); - if(sampcount>=decaybegin) + if(spu->sampcount>=spu->decaybegin) { s32 dmul; - if(decaybegin!=~0) // Is anyone REALLY going to be playing a song + if(spu->decaybegin!=~0) // Is anyone REALLY going to be playing a song // for 13 hours? { - if(sampcount>=decayend) + if(spu->sampcount>=spu->decayend) { // ao_song_done = 1; return(0); } - dmul=256-(256*(sampcount-decaybegin)/(decayend-decaybegin)); + dmul=256-(256*(spu->sampcount-spu->decaybegin)/(spu->decayend-spu->decaybegin)); sl=(sl*dmul)>>8; sr=(sr*dmul)>>8; } } - sampcount++; + spu->sampcount++; sl=(sl*volmul)>>8; sr=(sr*volmul)>>8; @@ -483,8 +454,8 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) if(sl>32767) sl=32767; if(sl<-32767) sl=-32767; if(sr>32767) sr=32767; if(sr<-32767) sr=-32767; - *pS++=sl; - *pS++=sr; + *spu->pS++=sl; + *spu->pS++=sr; } return(1); @@ -492,11 +463,12 @@ int SPUasync(mips_cpu_context *cpu, u32 cycles) void SPU_flushboot(mips_cpu_context *cpu) { - if((u8*)pS>((u8*)pSpuBuffer+1024)) + spu_state_t *spu = cpu->spu; + if((u8*)spu->pS>((u8*)spu->pSpuBuffer+1024)) { //spu_update(cpu, (u8*)pSpuBuffer,(u8*)pS-(u8*)pSpuBuffer); - cpu->spu_callback ((u8*)pSpuBuffer,(u8*)pS-(u8*)pSpuBuffer, cpu->spu_callback_data); - pS=(s16 *)pSpuBuffer; + cpu->spu_callback ((u8*)spu->pSpuBuffer,(u8*)spu->pS-(u8*)spu->pSpuBuffer, cpu->spu_callback_data); + spu->pS=(s16 *)spu->pSpuBuffer; } } @@ -526,13 +498,17 @@ int SPUinit(mips_cpu_context *cpu, void (*update_cb)(unsigned char *pSound, long { cpu->spu_callback = update_cb; cpu->spu_callback_data = data; - spuMemC=(u8*)spuMem; // just small setup - memset((void *)s_chan,0,MAXCHAN*sizeof(SPUCHAN)); - memset((void *)&rvb,0,sizeof(REVERBInfo)); - memset(regArea,0,sizeof(regArea)); - memset(spuMem,0,sizeof(spuMem)); + cpu->spu = malloc (sizeof (spu_state_t)); + memset (cpu->spu, 0, sizeof (spu_state_t)); + cpu->spu->dwNoiseVal = 1; + cpu->spu->spuAddr = 0xffffffff; + cpu->spu->spuMemC=(u8*)cpu->spu->spuMem; // just small setup + memset((void *)cpu->spu->s_chan,0,MAXCHAN*sizeof(SPUCHAN)); + memset((void *)&cpu->spu->rvb,0,sizeof(REVERBInfo)); + memset(cpu->spu->regArea,0,sizeof(cpu->spu->regArea)); + memset(cpu->spu->spuMem,0,sizeof(cpu->spu->spuMem)); InitADSR(); - sampcount=ttemp=0; + cpu->spu->sampcount = cpu->spu->ttemp=0; #ifdef TIMEO begintime=gettime64(); #endif @@ -543,20 +519,20 @@ int SPUinit(mips_cpu_context *cpu, void (*update_cb)(unsigned char *pSound, long // SETUPSTREAMS: init most of the spu buffers //////////////////////////////////////////////////////////////////////// -void SetupStreams(void) +void SetupStreams(spu_state_t *spu) { int i; - pSpuBuffer=(u8*)malloc(32768); // alloc mixing buffer - pS=(s16 *)pSpuBuffer; + spu->pSpuBuffer=(u8*)malloc(32768); // alloc mixing buffer + spu->pS=(s16 *)spu->pSpuBuffer; for(i=0;i init sustain - s_chan[i].iIrqDone=0; - s_chan[i].pLoop=spuMemC; - s_chan[i].pStart=spuMemC; - s_chan[i].pCurr=spuMemC; + spu->s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain + spu->s_chan[i].iIrqDone=0; + spu->s_chan[i].pLoop=spu->spuMemC; + spu->s_chan[i].pStart=spu->spuMemC; + spu->s_chan[i].pCurr=spu->spuMemC; } } @@ -564,10 +540,10 @@ void SetupStreams(void) // REMOVESTREAMS: free most buffer //////////////////////////////////////////////////////////////////////// -void RemoveStreams(void) +void RemoveStreams(spu_state_t *spu) { - free(pSpuBuffer); // free mixing buffer - pSpuBuffer=NULL; + free(spu->pSpuBuffer); // free mixing buffer + spu->pSpuBuffer=NULL; #ifdef TIMEO { @@ -588,21 +564,22 @@ void RemoveStreams(void) int SPUopen(mips_cpu_context *cpu) { - if(bSPUIsOpen) return 0; // security for some stupid main emus - spuIrq=0; + spu_state_t *spu = cpu->spu; + if(spu->bSPUIsOpen) return 0; // security for some stupid main emus + spu->spuIrq=0; - spuStat=spuCtrl=0; - spuAddr=0xffffffff; - dwNoiseVal=1; + spu->spuStat=spu->spuCtrl=0; + spu->spuAddr=0xffffffff; + spu->dwNoiseVal=1; - spuMemC=(u8*)spuMem; - memset((void *)s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN)); - pSpuIrq=0; + spu->spuMemC=(u8*)spu->spuMem; + memset((void *)spu->s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN)); + spu->pSpuIrq=0; - iVolume=255; //85; - SetupStreams(); // prepare streaming + spu->iVolume=255; //85; + SetupStreams(spu); // prepare streaming - bSPUIsOpen=1; + spu->bSPUIsOpen=1; return 1; } @@ -615,11 +592,12 @@ int SPUopen(mips_cpu_context *cpu) int SPUclose(mips_cpu_context *cpu) { - if(!bSPUIsOpen) return 0; // some security + spu_state_t *spu = cpu->spu; + if(!spu->bSPUIsOpen) return 0; // some security - bSPUIsOpen=0; // no more open + spu->bSPUIsOpen=0; // no more open - RemoveStreams(); // no more streaming + RemoveStreams(spu); // no more streaming return 0; } @@ -635,10 +613,11 @@ int SPUshutdown(mips_cpu_context *cpu) void SPUinjectRAMImage(mips_cpu_context *cpu, u16 *pIncoming) { + spu_state_t *spu = cpu->spu; int i; for (i = 0; i < (256*1024); i++) { - spuMem[i] = pIncoming[i]; + spu->spuMem[i] = pIncoming[i]; } } diff --git a/plugins/ao/eng_psf/peops/spu.h b/plugins/ao/eng_psf/peops/spu.h index e438ce27..7e1ea9b7 100644 --- a/plugins/ao/eng_psf/peops/spu.h +++ b/plugins/ao/eng_psf/peops/spu.h @@ -28,6 +28,39 @@ #include "../psx.h" void sexyd_update(unsigned char* pSound,long lBytes); +typedef struct spu_state_s { + // psx buffer / addresses + u16 regArea[0x200]; + u16 spuMem[256*1024]; + u8 * spuMemC; + u8 * pSpuIrq; + u8 * pSpuBuffer; + + // user settings + int iVolume; + + // MAIN infos struct for each channel + + SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling) + REVERBInfo rvb; + + u32 dwNoiseVal;//=1; // global noise generator + + u16 spuCtrl; // some vars to store psx reg infos + u16 spuStat; + u16 spuIrq; + u32 spuAddr; //=0xffffffff; // address into spu mem + int bSPUIsOpen; + + s16 * pS; + s32 ttemp; + u32 sampcount; + u32 decaybegin; + u32 decayend; + + s32 dosampies; +} spu_state_t; + int SPUasync(mips_cpu_context *cpu, u32 cycles); void SPU_flushboot(mips_cpu_context *cpu); int SPUinit(mips_cpu_context *cpu, void (*update_cb)(unsigned char *pSound, long lBytes, void *data), void *data); diff --git a/plugins/ao/eng_psf/peops2/externals.h b/plugins/ao/eng_psf/peops2/externals.h index 83e74c08..c916af67 100644 --- a/plugins/ao/eng_psf/peops2/externals.h +++ b/plugins/ao/eng_psf/peops2/externals.h @@ -35,27 +35,17 @@ #include "ao.h" -typedef int8 s8; -typedef int16 s16; -typedef int32 s32; -typedef int64 s64; - -typedef uint8 u8; -typedef uint16 u16; -typedef uint32 u32; -typedef uint64 u64; - -#if LSB_FIRST -static INLINE u16 BFLIP16(u16 x) -{ - return x; -} -#else -static INLINE u16 BFLIP16(u16 x) -{ - return( ((x>>8)&0xFF)| ((x&0xFF)<<8) ); -} -#endif +//#if LSB_FIRST +//static INLINE u16 BFLIP16(u16 x) +//{ +// return x; +//} +//#else +//static INLINE u16 BFLIP16(u16 x) +//{ +// return( ((x>>8)&0xFF)| ((x&0xFF)<<8) ); +//} +//#endif ///////////////////////////////////////////////////////// // generic defines diff --git a/plugins/ao/eng_psf/psx.h b/plugins/ao/eng_psf/psx.h index 5674553a..12631f26 100644 --- a/plugins/ao/eng_psf/psx.h +++ b/plugins/ao/eng_psf/psx.h @@ -86,7 +86,9 @@ typedef struct mips_cpu_context_s uint32 initial_ram[(2*1024*1024)/4]; uint32 initial_scratch[0x400]; - // spu callback + // spu + struct spu_state_s *spu; + struct spu2_state_s *spu2; void (*spu_callback)(unsigned char *, long, void *); void *spu_callback_data; } mips_cpu_context; @@ -354,6 +356,9 @@ void program_write_byte_32le(mips_cpu_context *cpu, offs_t address, uint8 data); void program_write_word_32le(mips_cpu_context *cpu, offs_t address, uint16 data); void program_write_dword_32le(mips_cpu_context *cpu, offs_t address, uint32 data); +// SPU1 +void setlength(struct spu_state_s *spu, s32 stop, s32 fade); + // SPU2 void SPU2write(mips_cpu_context *cpu, unsigned long reg, unsigned short val); unsigned short SPU2read(mips_cpu_context *cpu, unsigned long reg); -- cgit v1.2.3