1 /***************************************************************************
\r
2 externals.h - description
\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
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
16 ***************************************************************************/
\r
18 #ifndef __P_SOUND_EXTERNALS_H__
\r
19 #define __P_SOUND_EXTERNALS_H__
\r
23 /////////////////////////////////////////////////////////
\r
25 /////////////////////////////////////////////////////////
\r
27 //#define log_unhandled printf
\r
28 #define log_unhandled(...)
\r
31 #define noinline __attribute__((noinline))
\r
32 #define unlikely(x) __builtin_expect((x), 0)
\r
35 #define unlikely(x) x
\r
37 #if defined(__GNUC__) && !defined(_TMS320C6X)
\r
38 #define preload __builtin_prefetch
\r
40 #define preload(...)
\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
49 #define max(a,b) (((a) > (b)) ? (a) : (b))
\r
50 #define min(a,b) (((a) < (b)) ? (a) : (b))
\r
53 ////////////////////////////////////////////////////////////////////////
\r
55 ////////////////////////////////////////////////////////////////////////
\r
60 // note: must be even due to the way reverb works now
\r
61 #define NSSIZE ((44100 / 50 + 16) & ~1)
\r
63 ///////////////////////////////////////////////////////////
\r
65 ///////////////////////////////////////////////////////////
\r
74 // ADSR INFOS PER CHANNEL
\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
90 ///////////////////////////////////////////////////////////
\r
92 // MAIN CHANNEL STRUCT
\r
95 int iSBPos; // mixing stuff
\r
100 unsigned char * pCurr; // current pos in sound mem
\r
101 unsigned char * pLoop; // loop ptr in sound mem
\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
112 int iLeftVolume; // left volume
\r
113 int iRightVolume; // right volume
\r
118 int iRawPitch; // raw pitch (0...3fff)
\r
121 ///////////////////////////////////////////////////////////
\r
125 int StartAddr; // reverb area start addr in samples
\r
126 int CurrAddr; // reverb area curr addr in samples
\r
131 int FB_SRC_A; // (offset)
\r
132 int FB_SRC_B; // (offset)
\r
133 int IIR_ALPHA; // (coef.)
\r
134 int ACC_COEF_A; // (coef.)
\r
135 int ACC_COEF_B; // (coef.)
\r
136 int ACC_COEF_C; // (coef.)
\r
137 int ACC_COEF_D; // (coef.)
\r
138 int IIR_COEF; // (coef.)
\r
139 int FB_ALPHA; // (coef.)
\r
140 int FB_X; // (coef.)
\r
141 int IIR_DEST_A0; // (offset)
\r
142 int IIR_DEST_A1; // (offset)
\r
143 int ACC_SRC_A0; // (offset)
\r
144 int ACC_SRC_A1; // (offset)
\r
145 int ACC_SRC_B0; // (offset)
\r
146 int ACC_SRC_B1; // (offset)
\r
147 int IIR_SRC_A0; // (offset)
\r
148 int IIR_SRC_A1; // (offset)
\r
149 int IIR_DEST_B0; // (offset)
\r
150 int IIR_DEST_B1; // (offset)
\r
151 int ACC_SRC_C0; // (offset)
\r
152 int ACC_SRC_C1; // (offset)
\r
153 int ACC_SRC_D0; // (offset)
\r
154 int ACC_SRC_D1; // (offset)
\r
155 int IIR_SRC_B1; // (offset)
\r
156 int IIR_SRC_B0; // (offset)
\r
157 int MIX_DEST_A0; // (offset)
\r
158 int MIX_DEST_A1; // (offset)
\r
159 int MIX_DEST_B0; // (offset)
\r
160 int MIX_DEST_B1; // (offset)
\r
161 int IN_COEF_L; // (coef.)
\r
162 int IN_COEF_R; // (coef.)
\r
164 int dirty; // registers changed
\r
166 // MIX_DEST_xx - FB_SRC_x
\r
167 int FB_SRC_A0, FB_SRC_A1, FB_SRC_B0, FB_SRC_B1;
\r
170 ///////////////////////////////////////////////////////////
\r
172 // psx buffers / addresses
\r
176 int SB[28 + 4 + 4];
\r
184 int simple[5]; // 28-32
\r
192 unsigned short spuCtrl;
\r
193 unsigned short spuStat;
\r
195 unsigned int spuAddr;
\r
197 unsigned int cycles_played;
\r
198 unsigned int cycles_dma_end;
\r
200 int decode_dirty_ch;
\r
201 unsigned int bSpuInit:1;
\r
202 unsigned int bSPUIsOpen:1;
\r
203 unsigned int bMemDirty:1; // had external write to SPU RAM
\r
205 unsigned int dwNoiseVal; // global noise generator
\r
206 unsigned int dwNoiseCount;
\r
207 unsigned int dwNewChannel; // flags for faster testing, if new channel starts
\r
208 unsigned int dwChannelsAudible; // not silent channels
\r
209 unsigned int dwChannelDead; // silent+not useful channels
\r
211 unsigned int XARepeat;
\r
212 unsigned int XALastVal;
\r
217 int cdClearSamples; // extra samples to clear the capture buffers
\r
218 struct { // channel volume in the cd controller
\r
219 unsigned char ll, lr, rl, rr; // see cdr.Attenuator* in cdrom.c
\r
220 } cdv; // applied on spu side for easier emulation
\r
222 unsigned int last_keyon_cycles;
\r
225 unsigned char *spuMemC;
\r
226 unsigned short *spuMem;
\r
228 unsigned char * pSpuIrq;
\r
230 unsigned char * pSpuBuffer;
\r
238 void (CALLBACK *irqCallback)(int);
\r
239 //void (CALLBACK *cddavCallback)(short, short);
\r
240 void (CALLBACK *scheduleCallback)(unsigned int);
\r
242 const xa_decode_t * xapGlobal;
\r
243 unsigned int * XAFeed;
\r
244 unsigned int * XAPlay;
\r
245 unsigned int * XAStart;
\r
246 unsigned int * XAEnd;
\r
248 unsigned int * CDDAFeed;
\r
249 unsigned int * CDDAPlay;
\r
250 unsigned int * CDDAStart;
\r
251 unsigned int * CDDAEnd;
\r
253 unsigned short regArea[0x400];
\r
255 sample_buf sb[MAXCHAN];
\r
258 #if P_HAVE_PTHREAD || defined(WANT_THREAD_CODE)
\r
259 sample_buf * sb_thread;
\r
260 sample_buf sb_thread_[MAXCHAN];
\r
264 #define regAreaGet(offset) \
\r
265 spu.regArea[((offset) - 0xc00) >> 1]
\r
266 #define regAreaGetCh(ch, offset) \
\r
267 spu.regArea[(((ch) << 4) | (offset)) >> 1]
\r
269 ///////////////////////////////////////////////////////////
\r
271 ///////////////////////////////////////////////////////////
\r
275 extern SPUInfo spu;
\r
277 void do_samples(unsigned int cycles_to, int force_no_thread);
\r
278 void schedule_next_irq(void);
\r
279 void check_irq_io(unsigned int addr);
\r
280 void do_irq_io(int cycles_after);
\r
282 #define do_samples_if_needed(c, no_thread, samples) \
\r
284 if ((no_thread) || (int)((c) - spu.cycles_played) >= (samples) * 768) \
\r
285 do_samples(c, no_thread); \
\r
290 void FeedXA(const xa_decode_t *xap);
\r
291 void FeedCDDA(unsigned char *pcm, int nBytes);
\r
293 #endif /* __P_SOUND_EXTERNALS_H__ */
\r