/*************************************************************************** externals.h - description ------------------- begin : Wed May 15 2002 copyright : (C) 2002 by Pete Bernert email : BlackDove@addcom.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. See also the license.txt file for * * additional informations. * * * ***************************************************************************/ #ifndef __P_SOUND_EXTERNALS_H__ #define __P_SOUND_EXTERNALS_H__ #include ///////////////////////////////////////////////////////// // generic defines ///////////////////////////////////////////////////////// #ifdef __GNUC__ #define noinline __attribute__((noinline)) #define unlikely(x) __builtin_expect((x), 0) #else #define noinline #define unlikely(x) x #endif #if defined(__GNUC__) && !defined(_TMS320C6X) #define preload __builtin_prefetch #else #define preload(...) #endif #define PSE_LT_SPU 4 #define PSE_SPU_ERR_SUCCESS 0 #define PSE_SPU_ERR -60 #define PSE_SPU_ERR_NOTCONFIGURED PSE_SPU_ERR - 1 #define PSE_SPU_ERR_INIT PSE_SPU_ERR - 2 #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif //////////////////////////////////////////////////////////////////////// // spu defines //////////////////////////////////////////////////////////////////////// // num of channels #define MAXCHAN 24 // note: must be even due to the way reverb works now #define NSSIZE ((44100 / 50 + 16) & ~1) /////////////////////////////////////////////////////////// // struct defines /////////////////////////////////////////////////////////// enum ADSR_State { ADSR_ATTACK = 0, ADSR_DECAY = 1, ADSR_SUSTAIN = 2, ADSR_RELEASE = 3, }; // ADSR INFOS PER CHANNEL typedef struct { unsigned char State:2; // ADSR_State unsigned char AttackModeExp:1; unsigned char SustainModeExp:1; unsigned char SustainIncrease:1; unsigned char ReleaseModeExp:1; unsigned char AttackRate; unsigned char DecayRate; unsigned char SustainLevel; unsigned char SustainRate; unsigned char ReleaseRate; int EnvelopeVol; } ADSRInfoEx; /////////////////////////////////////////////////////////// // Tmp Flags // used for debug channel muting #define FLAG_MUTE 1 // used for simple interpolation #define FLAG_IPOL0 2 #define FLAG_IPOL1 4 /////////////////////////////////////////////////////////// // MAIN CHANNEL STRUCT typedef struct { int iSBPos; // mixing stuff int spos; int sinc; int sinc_inv; unsigned char * pCurr; // current pos in sound mem unsigned char * pLoop; // loop ptr in sound mem unsigned int bReverb:1; // can we do reverb on this channel? must have ctrl register bit, to get active unsigned int bRVBActive:1; // reverb active flag unsigned int bNoise:1; // noise active flag unsigned int bFMod:2; // freq mod (0=off, 1=sound channel, 2=freq channel) unsigned int prevflags:3; // flags from previous block int iLeftVolume; // left volume int iRightVolume; // right volume ADSRInfoEx ADSRX; int iRawPitch; // raw pitch (0...3fff) } SPUCHAN; /////////////////////////////////////////////////////////// typedef struct { int StartAddr; // reverb area start addr in samples int CurrAddr; // reverb area curr addr in samples int VolLeft; int VolRight; int FB_SRC_A; // (offset) int FB_SRC_B; // (offset) int IIR_ALPHA; // (coef.) int ACC_COEF_A; // (coef.) int ACC_COEF_B; // (coef.) int ACC_COEF_C; // (coef.) int ACC_COEF_D; // (coef.) int IIR_COEF; // (coef.) int FB_ALPHA; // (coef.) int FB_X; // (coef.) int IIR_DEST_A0; // (offset) int IIR_DEST_A1; // (offset) int ACC_SRC_A0; // (offset) int ACC_SRC_A1; // (offset) int ACC_SRC_B0; // (offset) int ACC_SRC_B1; // (offset) int IIR_SRC_A0; // (offset) int IIR_SRC_A1; // (offset) int IIR_DEST_B0; // (offset) int IIR_DEST_B1; // (offset) int ACC_SRC_C0; // (offset) int ACC_SRC_C1; // (offset) int ACC_SRC_D0; // (offset) int ACC_SRC_D1; // (offset) int IIR_SRC_B1; // (offset) int IIR_SRC_B0; // (offset) int MIX_DEST_A0; // (offset) int MIX_DEST_A1; // (offset) int MIX_DEST_B0; // (offset) int MIX_DEST_B1; // (offset) int IN_COEF_L; // (coef.) int IN_COEF_R; // (coef.) int dirty; // registers changed // MIX_DEST_xx - FB_SRC_x int FB_SRC_A0, FB_SRC_A1, FB_SRC_B0, FB_SRC_B1; } REVERBInfo; /////////////////////////////////////////////////////////// // psx buffers / addresses #define SB_SIZE (32 + 4) typedef struct { unsigned short spuCtrl; unsigned short spuStat; unsigned int spuAddr; union { unsigned char *spuMemC; unsigned short *spuMem; }; unsigned char * pSpuIrq; unsigned int cycles_played; int decode_pos; int decode_dirty_ch; unsigned int bSpuInit:1; unsigned int bSPUIsOpen:1; unsigned int bMemDirty:1; // had external write to SPU RAM unsigned int dwNoiseVal; // global noise generator unsigned int dwNoiseCount; unsigned int dwNewChannel; // flags for faster testing, if new channel starts unsigned int dwChannelOn; // not silent channels unsigned int dwChannelDead; // silent+not useful channels unsigned char * pSpuBuffer; short * pS; void (CALLBACK *irqCallback)(void); // func of main emu, called on spu irq void (CALLBACK *cddavCallback)(unsigned short,unsigned short); void (CALLBACK *scheduleCallback)(unsigned int); xa_decode_t * xapGlobal; unsigned int * XAFeed; unsigned int * XAPlay; unsigned int * XAStart; unsigned int * XAEnd; unsigned int * CDDAFeed; unsigned int * CDDAPlay; unsigned int * CDDAStart; unsigned int * CDDAEnd; unsigned int XARepeat; unsigned int XALastVal; int iLeftXAVol; int iRightXAVol; SPUCHAN * s_chan; REVERBInfo * rvb; // buffers int * SB; int * SSumLR; int pad[29]; unsigned short regArea[0x400]; } SPUInfo; /////////////////////////////////////////////////////////// // SPU.C globals /////////////////////////////////////////////////////////// #ifndef _IN_SPU extern SPUInfo spu; void do_samples(unsigned int cycles_to, int do_sync); void schedule_next_irq(void); #define regAreaGet(ch,offset) \ spu.regArea[((ch<<4)|(offset))>>1] #define do_samples_if_needed(c, sync) \ do { \ if (sync || (int)((c) - spu.cycles_played) >= 16 * 768) \ do_samples(c, sync); \ } while (0) #endif #endif /* __P_SOUND_EXTERNALS_H__ */