1ccd605211520f8f136d3f7ab823dc36de04667c
[pcsx_rearmed.git] / plugins / dfsound / externals.h
1 /***************************************************************************\r
2                          externals.h  -  description\r
3                              -------------------\r
4     begin                : Wed May 15 2002\r
5     copyright            : (C) 2002 by Pete Bernert\r
6     email                : BlackDove@addcom.de\r
7  ***************************************************************************/\r
8 /***************************************************************************\r
9  *                                                                         *\r
10  *   This program is free software; you can redistribute it and/or modify  *\r
11  *   it under the terms of the GNU General Public License as published by  *\r
12  *   the Free Software Foundation; either version 2 of the License, or     *\r
13  *   (at your option) any later version. See also the license.txt file for *\r
14  *   additional informations.                                              *\r
15  *                                                                         *\r
16  ***************************************************************************/\r
17 \r
18 #ifndef __P_SOUND_EXTERNALS_H__\r
19 #define __P_SOUND_EXTERNALS_H__\r
20 \r
21 #include <stdint.h>\r
22 \r
23 /////////////////////////////////////////////////////////\r
24 // generic defines\r
25 /////////////////////////////////////////////////////////\r
26 \r
27 //#define log_unhandled printf\r
28 #define log_unhandled(...)\r
29 \r
30 #ifdef __GNUC__\r
31 #define noinline __attribute__((noinline))\r
32 #define unlikely(x) __builtin_expect((x), 0)\r
33 #else\r
34 #define noinline\r
35 #define unlikely(x) x\r
36 #endif\r
37 #if defined(__GNUC__) && !defined(_TMS320C6X)\r
38 #define preload __builtin_prefetch\r
39 #else\r
40 #define preload(...)\r
41 #endif\r
42 \r
43 #define PSE_LT_SPU                  4\r
44 #define PSE_SPU_ERR_SUCCESS         0\r
45 #define PSE_SPU_ERR                 -60\r
46 #define PSE_SPU_ERR_NOTCONFIGURED   PSE_SPU_ERR - 1\r
47 #define PSE_SPU_ERR_INIT            PSE_SPU_ERR - 2\r
48 #ifndef max\r
49 #define max(a,b)            (((a) > (b)) ? (a) : (b))\r
50 #define min(a,b)            (((a) < (b)) ? (a) : (b))\r
51 #endif\r
52 \r
53 ////////////////////////////////////////////////////////////////////////\r
54 // spu defines\r
55 ////////////////////////////////////////////////////////////////////////\r
56 \r
57 // num of channels\r
58 #define MAXCHAN     24\r
59 \r
60 // note: must be even due to the way reverb works now\r
61 #define NSSIZE ((44100 / 50 + 32) & ~1)\r
62 \r
63 ///////////////////////////////////////////////////////////\r
64 // struct defines\r
65 ///////////////////////////////////////////////////////////\r
66 \r
67 enum ADSR_State {\r
68  ADSR_ATTACK = 0,\r
69  ADSR_DECAY = 1,\r
70  ADSR_SUSTAIN = 2,\r
71  ADSR_RELEASE = 3,\r
72 };\r
73 \r
74 // ADSR INFOS PER CHANNEL\r
75 typedef struct\r
76 {\r
77  unsigned char  State:2;                               // ADSR_State\r
78  unsigned char  AttackModeExp:1;\r
79  unsigned char  SustainModeExp:1;\r
80  unsigned char  SustainIncrease:1;\r
81  unsigned char  ReleaseModeExp:1;\r
82  unsigned char  AttackRate;\r
83  unsigned char  DecayRate;\r
84  unsigned char  SustainLevel;\r
85  unsigned char  SustainRate;\r
86  unsigned char  ReleaseRate;\r
87  int            EnvelopeVol;\r
88 } ADSRInfoEx;\r
89               \r
90 ///////////////////////////////////////////////////////////\r
91 \r
92 // MAIN CHANNEL STRUCT\r
93 typedef struct\r
94 {\r
95  int               iSBPos;                             // mixing stuff\r
96  int               spos;\r
97  int               sinc;\r
98  int               sinc_inv;\r
99 \r
100  unsigned char *   pCurr;                              // current pos in sound mem\r
101  unsigned char *   pLoop;                              // loop ptr in sound mem\r
102 \r
103  unsigned int      bReverb:1;                          // can we do reverb on this channel? must have ctrl register bit, to get active\r
104  unsigned int      bRVBActive:1;                       // reverb active flag\r
105  unsigned int      bNoise:1;                           // noise active flag\r
106  unsigned int      bFMod:2;                            // freq mod (0=off, 1=sound channel, 2=freq channel)\r
107  unsigned int      prevflags:3;                        // flags from previous block\r
108  unsigned int      bIgnoreLoop:1;                      // Ignore loop\r
109  unsigned int      bStarting:1;                        // starting after keyon\r
110  union {\r
111   struct {\r
112    int             iLeftVolume;                        // left volume\r
113    int             iRightVolume;                       // right volume\r
114   };\r
115   int              iVolume[2];\r
116  };\r
117  ADSRInfoEx        ADSRX;\r
118  int               iRawPitch;                          // raw pitch (0...3fff)\r
119 } SPUCHAN;\r
120 \r
121 ///////////////////////////////////////////////////////////\r
122 \r
123 typedef struct\r
124 {\r
125  int StartAddr;      // reverb area start addr in samples\r
126  int CurrAddr;       // reverb area curr addr in samples\r
127 \r
128  int VolLeft;\r
129  int VolRight;\r
130 \r
131  // directly from nocash docs\r
132  //int dAPF1; // 1DC0 disp    Reverb APF Offset 1\r
133  //int dAPF2; // 1DC2 disp    Reverb APF Offset 2\r
134  int vIIR;    // 1DC4 volume  Reverb Reflection Volume 1\r
135  int vCOMB1;  // 1DC6 volume  Reverb Comb Volume 1\r
136  int vCOMB2;  // 1DC8 volume  Reverb Comb Volume 2\r
137  int vCOMB3;  // 1DCA volume  Reverb Comb Volume 3\r
138  int vCOMB4;  // 1DCC volume  Reverb Comb Volume 4\r
139  int vWALL;   // 1DCE volume  Reverb Reflection Volume 2\r
140  int vAPF1;   // 1DD0 volume  Reverb APF Volume 1\r
141  int vAPF2;   // 1DD2 volume  Reverb APF Volume 2\r
142  int mLSAME;  // 1DD4 src/dst Reverb Same Side Reflection Address 1 Left\r
143  int mRSAME;  // 1DD6 src/dst Reverb Same Side Reflection Address 1 Right\r
144  int mLCOMB1; // 1DD8 src     Reverb Comb Address 1 Left\r
145  int mRCOMB1; // 1DDA src     Reverb Comb Address 1 Right\r
146  int mLCOMB2; // 1DDC src     Reverb Comb Address 2 Left\r
147  int mRCOMB2; // 1DDE src     Reverb Comb Address 2 Right\r
148  int dLSAME;  // 1DE0 src     Reverb Same Side Reflection Address 2 Left\r
149  int dRSAME;  // 1DE2 src     Reverb Same Side Reflection Address 2 Right\r
150  int mLDIFF;  // 1DE4 src/dst Reverb Different Side Reflect Address 1 Left\r
151  int mRDIFF;  // 1DE6 src/dst Reverb Different Side Reflect Address 1 Right\r
152  int mLCOMB3; // 1DE8 src     Reverb Comb Address 3 Left\r
153  int mRCOMB3; // 1DEA src     Reverb Comb Address 3 Right\r
154  int mLCOMB4; // 1DEC src     Reverb Comb Address 4 Left\r
155  int mRCOMB4; // 1DEE src     Reverb Comb Address 4 Right\r
156  int dLDIFF;  // 1DF0 src     Reverb Different Side Reflect Address 2 Left\r
157  int dRDIFF;  // 1DF2 src     Reverb Different Side Reflect Address 2 Right\r
158  int mLAPF1;  // 1DF4 src/dst Reverb APF Address 1 Left\r
159  int mRAPF1;  // 1DF6 src/dst Reverb APF Address 1 Right\r
160  int mLAPF2;  // 1DF8 src/dst Reverb APF Address 2 Left\r
161  int mRAPF2;  // 1DFA src/dst Reverb APF Address 2 Right\r
162  int vLIN;    // 1DFC volume  Reverb Input Volume Left\r
163  int vRIN;    // 1DFE volume  Reverb Input Volume Right\r
164 \r
165  // subtracted offsets\r
166  int mLAPF1_dAPF1, mRAPF1_dAPF1, mLAPF2_dAPF2, mRAPF2_dAPF2;\r
167 \r
168  int dirty;   // registers changed\r
169 } REVERBInfo;\r
170 \r
171 ///////////////////////////////////////////////////////////\r
172 \r
173 // psx buffers / addresses\r
174 \r
175 typedef union\r
176 {\r
177  int SB[28 + 4 + 4];\r
178  int SB_rvb[2][4*2]; // for reverb filtering\r
179  struct {\r
180   int sample[28];\r
181   union {\r
182    struct {\r
183     int pos;\r
184     int val[4];\r
185    } gauss;\r
186    int simple[5]; // 28-32\r
187   } interp;\r
188   int sinc_old;\r
189  };\r
190 } sample_buf;\r
191 \r
192 typedef struct\r
193 {\r
194  unsigned short  spuCtrl;\r
195  unsigned short  spuStat;\r
196 \r
197  unsigned int    spuAddr;\r
198 \r
199  unsigned int    cycles_played;\r
200  unsigned int    cycles_dma_end;\r
201  int             decode_pos;\r
202  int             decode_dirty_ch;\r
203  unsigned int    bSpuInit:1;\r
204  unsigned int    bSPUIsOpen:1;\r
205  unsigned int    bMemDirty:1;          // had external write to SPU RAM\r
206 \r
207  unsigned int    dwNoiseVal;           // global noise generator\r
208  unsigned int    dwNoiseCount;\r
209  unsigned int    dwNewChannel;         // flags for faster testing, if new channel starts\r
210  unsigned int    dwChannelsAudible;    // not silent channels\r
211  unsigned int    dwChannelDead;        // silent+not useful channels\r
212 \r
213  unsigned int    XARepeat;\r
214  unsigned int    XALastVal;\r
215 \r
216  int             iLeftXAVol;\r
217  int             iRightXAVol;\r
218 \r
219  int             cdClearSamples;       // extra samples to clear the capture buffers\r
220  struct {                              // channel volume in the cd controller\r
221   unsigned char  ll, lr, rl, rr;       // see cdr.Attenuator* in cdrom.c\r
222  } cdv;                                // applied on spu side for easier emulation\r
223 \r
224  unsigned int    last_keyon_cycles;\r
225 \r
226  union {\r
227   unsigned char  *spuMemC;\r
228   unsigned short *spuMem;\r
229  };\r
230  unsigned char * pSpuIrq;\r
231 \r
232  unsigned char * pSpuBuffer;\r
233  short         * pS;\r
234 \r
235  SPUCHAN       * s_chan;\r
236  REVERBInfo    * rvb;\r
237 \r
238  int           * SSumLR;\r
239 \r
240  void (CALLBACK *irqCallback)(int);\r
241  //void (CALLBACK *cddavCallback)(short, short);\r
242  void (CALLBACK *scheduleCallback)(unsigned int);\r
243 \r
244  const xa_decode_t * xapGlobal;\r
245  unsigned int  * XAFeed;\r
246  unsigned int  * XAPlay;\r
247  unsigned int  * XAStart;\r
248  unsigned int  * XAEnd;\r
249 \r
250  unsigned int  * CDDAFeed;\r
251  unsigned int  * CDDAPlay;\r
252  unsigned int  * CDDAStart;\r
253  unsigned int  * CDDAEnd;\r
254 \r
255  unsigned short  regArea[0x400];\r
256 \r
257  sample_buf      sb[MAXCHAN+1]; // last entry is used for reverb filter\r
258  int             interpolation;\r
259 \r
260 #if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE)\r
261  sample_buf    * sb_thread;\r
262  sample_buf      sb_thread_[MAXCHAN+1];\r
263 #endif\r
264 } SPUInfo;\r
265 \r
266 #define regAreaRef(offset) \\r
267   spu.regArea[((offset) - 0xc00) >> 1]\r
268 #define regAreaGet(offset) \\r
269   regAreaRef(offset)\r
270 #define regAreaGetCh(ch, offset) \\r
271   spu.regArea[(((ch) << 4) | (offset)) >> 1]\r
272 \r
273 ///////////////////////////////////////////////////////////\r
274 // SPU.C globals\r
275 ///////////////////////////////////////////////////////////\r
276 \r
277 #ifndef _IN_SPU\r
278 \r
279 extern SPUInfo spu;\r
280 \r
281 void do_samples(unsigned int cycles_to, int force_no_thread);\r
282 void schedule_next_irq(void);\r
283 void check_irq_io(unsigned int addr);\r
284 void do_irq_io(int cycles_after);\r
285 \r
286 #define do_samples_if_needed(c, no_thread, samples) \\r
287  do { \\r
288   if ((no_thread) || (int)((c) - spu.cycles_played) >= (samples) * 768) \\r
289    do_samples(c, no_thread); \\r
290  } while (0)\r
291 \r
292 #endif\r
293 \r
294 void FeedXA(const xa_decode_t *xap);\r
295 void FeedCDDA(unsigned char *pcm, int nBytes);\r
296 \r
297 #endif /* __P_SOUND_EXTERNALS_H__ */\r