comparison Plugins/Input/sexypsf/spu/spu.c @ 854:61e7332e0652 trunk

[svn] - PSF2 support (everything is BORKED right now)
author nenolod
date Sun, 19 Mar 2006 12:51:03 -0800
parents d539e5c5f730
children
comparison
equal deleted inserted replaced
853:74576869a506 854:61e7332e0652
17 ***************************************************************************/ 17 ***************************************************************************/
18 18
19 //*************************************************************************// 19 //*************************************************************************//
20 // History of changes: 20 // History of changes:
21 // 21 //
22 // 2005/08/29 - Pete
23 // - changed to 48Khz output
24 //
25 // 2004/12/25 - Pete
26 // - inc'd version for pcsx2-0.7
27 //
28 // 2004/04/18 - Pete
29 // - changed all kind of things in the plugin
30 //
31 // 2004/04/04 - Pete
32 // - changed plugin to emulate PS2 spu
33 //
34 // 2003/04/07 - Eric
35 // - adjusted cubic interpolation algorithm
36 //
37 // 2003/03/16 - Eric
38 // - added cubic interpolation
39 //
22 // 2003/03/01 - linuzappz 40 // 2003/03/01 - linuzappz
23 // - libraryName changes using ALSA 41 // - libraryName changes using ALSA
24 // 42 //
25 // 2003/02/28 - Pete 43 // 2003/02/28 - Pete
26 // - added option for type of interpolation 44 // - added option for type of interpolation
75 // 2002/05/15 - Pete 93 // 2002/05/15 - Pete
76 // - generic cleanup for the Peops release 94 // - generic cleanup for the Peops release
77 // 95 //
78 //*************************************************************************// 96 //*************************************************************************//
79 97
98 #include "stdafx.h"
99
80 #define _IN_SPU 100 #define _IN_SPU
81 101
82 #include "stdafx.h"
83 #include "externals.h" 102 #include "externals.h"
84 #include "spu.h" 103 #include "cfg.h"
104 #include "dsoundoss.h"
85 #include "regs.h" 105 #include "regs.h"
86 #include "registers.h" 106 #include "debug.h"
87 107 #include "record.h"
88 #include "PsxMem.h" 108 #include "resource.h"
89 #include "driver.h" 109 #include "dma.h"
110
111 ////////////////////////////////////////////////////////////////////////
112 // spu version infos/name
113 ////////////////////////////////////////////////////////////////////////
114
115 const unsigned char version = 4;
116 const unsigned char revision = 1;
117 const unsigned char build = 3;
118 #ifdef _WINDOWS
119 static char * libraryName = "P.E.Op.S. SPU2 DSound Driver";
120 #else
121 #ifndef USEALSA
122 static char * libraryName = "P.E.Op.S. SPU2 OSS Driver";
123 #else
124 static char * libraryName = "P.E.Op.S. SPU2 ALSA Driver";
125 #endif
126 #endif
127 static char * libraryInfo = "P.E.Op.S. SPU2 Driver V1.3\nCoded by Pete Bernert and the P.E.Op.S. team\n";
90 128
91 //////////////////////////////////////////////////////////////////////// 129 ////////////////////////////////////////////////////////////////////////
92 // globals 130 // globals
93 //////////////////////////////////////////////////////////////////////// 131 ////////////////////////////////////////////////////////////////////////
94 132
95 // psx buffer / addresses 133 // psx buffer / addresses
96 134
97 static u16 regArea[0x200]; 135 unsigned short regArea[32*1024];
98 static u16 spuMem[256*1024]; 136 unsigned short spuMem[1*1024*1024];
99 static u8 * spuMemC; 137 unsigned char * spuMemC;
100 static u8 * pSpuIrq=0; 138 unsigned char * pSpuIrq[2];
101 static u8 * pSpuBuffer; 139 unsigned char * pSpuBuffer;
102 140
103 // user settings 141 // sexypsf tracking stuff
104 static int iVolume; 142
105 143 static unsigned long seektime;
106 // MAIN infos struct for each channel 144 static unsigned long sampcount;
107 145 static unsigned long decaybegin;
108 static SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling) 146 static unsigned long decayend;
109 static REVERBInfo rvb; 147
110 148 void SPUsetlength(long stop, long fade)
111 static u32 dwNoiseVal=1; // global noise generator
112
113 static u16 spuCtrl=0; // some vars to store psx reg infos
114 static u16 spuStat=0;
115 static u16 spuIrq=0;
116 static u32 spuAddr=0xffffffff; // address into spu mem
117 static int bSPUIsOpen=0;
118
119 static const int f[5][2] = {
120 { 0, 0 },
121 { 60, 0 },
122 { 115, -52 },
123 { 98, -55 },
124 { 122, -60 } };
125 s16 * pS;
126
127 ////////////////////////////////////////////////////////////////////////
128 // CODE AREA
129 ////////////////////////////////////////////////////////////////////////
130
131 // dirty inline func includes
132
133 #include "reverb.c"
134 #include "adsr.c"
135
136 // Try this to increase speed.
137 #include "registers.c"
138 #include "dma.c"
139
140 ////////////////////////////////////////////////////////////////////////
141 // helpers for so-called "gauss interpolation"
142
143 #define gval0 (((int *)(&s_chan[ch].SB[29]))[gpos])
144 #define gval(x) (((int *)(&s_chan[ch].SB[29]))[(gpos+x)&3])
145
146 #include "gauss_i.h"
147
148 ////////////////////////////////////////////////////////////////////////
149
150 ////////////////////////////////////////////////////////////////////////
151 // START SOUND... called by main thread to setup a new sound on a channel
152 ////////////////////////////////////////////////////////////////////////
153
154 static INLINE void StartSound(int ch)
155 {
156 StartADSR(ch);
157
158 s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start
159
160 s_chan[ch].s_1=0; // init mixing vars
161 s_chan[ch].s_2=0;
162 s_chan[ch].iSBPos=28;
163
164 s_chan[ch].bNew=0; // init channel flags
165 s_chan[ch].bStop=0;
166 s_chan[ch].bOn=1;
167
168 s_chan[ch].SB[29]=0; // init our interpolation helpers
169 s_chan[ch].SB[30]=0;
170
171 s_chan[ch].spos=0x40000L;s_chan[ch].SB[28]=0; // -> start with more decoding
172 }
173
174 ////////////////////////////////////////////////////////////////////////
175 // MAIN SPU FUNCTION
176 // here is the main job handler... thread, timer or direct func call
177 // basically the whole sound processing is done in this fat func!
178 ////////////////////////////////////////////////////////////////////////
179
180 static u32 sampcount;
181 static u32 decaybegin;
182 static u32 decayend;
183
184 // Counting to 65536 results in full volume offage.
185 void SPUsetlength(s32 stop, s32 fade)
186 { 149 {
187 if(stop==~0) 150 if(stop==~0)
188 { 151 {
189 decaybegin=~0; 152 decaybegin=~0;
190 } 153 }
196 decaybegin=stop; 159 decaybegin=stop;
197 decayend=stop+fade; 160 decayend=stop+fade;
198 } 161 }
199 } 162 }
200 163
201 static u32 seektime; 164 // user settings
202 static s32 poo; 165
203 int sexypsf_seek(u32 t) 166 int iUseXA=1;
204 { 167 int iVolume=3;
205 seektime=t*441/10; 168 int iXAPitch=1;
206 if(seektime>sampcount) return(1); 169 int iUseTimer=2;
207 return(0); 170 int iSPUIRQWait=1;
208 } 171 int iDebugMode=0;
209 172 int iRecordMode=0;
210 #define CLIP(_x) {if(_x>32767) _x=32767; if(_x<-32767) _x=-32767;} 173 int iUseReverb=0;
211 int SPUasync(u32 cycles) 174 int iUseInterpolation=2;
212 { 175 int iDisStereo=0;
213 int volmul=iVolume; 176
214 static s32 dosampies; 177 // MAIN infos struct for each channel
215 s32 temp; 178
216 179 SPUCHAN s_chan[MAXCHAN+1]; // channel + 1 infos (1 is security for fmod handling)
217 poo+=cycles; 180 REVERBInfo rvb[2];
218 dosampies=poo/384; 181
219 if(!dosampies) return(1); 182 unsigned long dwNoiseVal=1; // global noise generator
220 poo-=dosampies*384; 183
221 temp=dosampies; 184 unsigned short spuCtrl2[2]; // some vars to store psx reg infos
222 185 unsigned short spuStat2[2];
223 while(temp) 186 unsigned long spuIrq2[2];
224 { 187 unsigned long spuAddr2[2]; // address into spu mem
225 s32 revLeft=0, revRight=0; 188 unsigned long spuRvbAddr2[2];
226 s32 sl=0, sr=0; 189 unsigned long spuRvbAEnd2[2];
227 int ch,fa; 190 int bEndThread=0; // thread handlers
228 191 int bThreadEnded=0;
229 temp--; 192 int bSpuInit=0;
193 int bSPUIsOpen=0;
194
195 #ifdef _WINDOWS
196 HWND hWMain=0; // window handle
197 HWND hWDebug=0;
198 HWND hWRecord=0;
199 static HANDLE hMainThread;
200 #else
201 // 2003/06/07 - Pete
202 #ifndef NOTHREADLIB
203 static pthread_t thread = -1; // thread id (linux)
204 #endif
205 #endif
206
207 unsigned long dwNewChannel2[2]; // flags for faster testing, if new channel starts
208 unsigned long dwEndChannel2[2];
209
210 // UNUSED IN PS2 YET
211 void (CALLBACK *irqCallback)(void)=0; // func of main emu, called on spu irq
212 void (CALLBACK *cddavCallback)(unsigned short,unsigned short)=0;
213
214 // certain globals (were local before, but with the new timeproc I need em global)
215
216 const int f[5][2] = { { 0, 0 },
217 { 60, 0 },
218 { 115, -52 },
219 { 98, -55 },
220 { 122, -60 } };
221 int SSumR[NSSIZE];
222 int SSumL[NSSIZE];
223 int iCycle=0;
224 short * pS;
225
226 static int lastch=-1; // last channel processed on spu irq in timer mode
227 static int lastns=0; // last ns pos
228 static int iSecureStart=0; // secure start counter
229
230 ////////////////////////////////////////////////////////////////////////
231 // CODE AREA
232 ////////////////////////////////////////////////////////////////////////
233
234 // dirty inline func includes
235
236 #include "reverb.c"
237 #include "adsr.c"
238
239 ////////////////////////////////////////////////////////////////////////
240 // helpers for simple interpolation
241
242 //
243 // easy interpolation on upsampling, no special filter, just "Pete's common sense" tm
244 //
245 // instead of having n equal sample values in a row like:
246 // ____
247 // |____
248 //
249 // we compare the current delta change with the next delta change.
250 //
251 // if curr_delta is positive,
252 //
253 // - and next delta is smaller (or changing direction):
254 // \.
255 // -__
256 //
257 // - and next delta significant (at least twice) bigger:
258 // --_
259 // \.
260 //
261 // - and next delta is nearly same:
262 // \.
263 // \.
264 //
265 //
266 // if curr_delta is negative,
267 //
268 // - and next delta is smaller (or changing direction):
269 // _--
270 // /
271 //
272 // - and next delta significant (at least twice) bigger:
273 // /
274 // __-
275 //
276 // - and next delta is nearly same:
277 // /
278 // /
279 //
280
281 static unsigned long long SexyTime64(void)
282 {
283 struct timeval tv;
284 unsigned long long ret;
285
286 gettimeofday(&tv,0);
287 ret=tv.tv_sec;
288 ret*=1000000;
289 ret+=tv.tv_usec;
290 return(ret);
291 }
292
293 INLINE void InterpolateUp(int ch)
294 {
295 if(s_chan[ch].SB[32]==1) // flag == 1? calc step and set flag... and don't change the value in this pass
296 {
297 const int id1=s_chan[ch].SB[30]-s_chan[ch].SB[29]; // curr delta to next val
298 const int id2=s_chan[ch].SB[31]-s_chan[ch].SB[30]; // and next delta to next-next val :)
299
300 s_chan[ch].SB[32]=0;
301
302 if(id1>0) // curr delta positive
303 {
304 if(id2<id1)
305 {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;}
306 else
307 if(id2<(id1<<1))
308 s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L;
309 else
310 s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L;
311 }
312 else // curr delta negative
313 {
314 if(id2>id1)
315 {s_chan[ch].SB[28]=id1;s_chan[ch].SB[32]=2;}
316 else
317 if(id2>(id1<<1))
318 s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x10000L;
319 else
320 s_chan[ch].SB[28]=(id1*s_chan[ch].sinc)/0x20000L;
321 }
322 }
323 else
324 if(s_chan[ch].SB[32]==2) // flag 1: calc step and set flag... and don't change the value in this pass
325 {
326 s_chan[ch].SB[32]=0;
327
328 s_chan[ch].SB[28]=(s_chan[ch].SB[28]*s_chan[ch].sinc)/0x20000L;
329 if(s_chan[ch].sinc<=0x8000)
330 s_chan[ch].SB[29]=s_chan[ch].SB[30]-(s_chan[ch].SB[28]*((0x10000/s_chan[ch].sinc)-1));
331 else s_chan[ch].SB[29]+=s_chan[ch].SB[28];
332 }
333 else // no flags? add bigger val (if possible), calc smaller step, set flag1
334 s_chan[ch].SB[29]+=s_chan[ch].SB[28];
335 }
336
337 //
338 // even easier interpolation on downsampling, also no special filter, again just "Pete's common sense" tm
339 //
340
341 INLINE void InterpolateDown(int ch)
342 {
343 if(s_chan[ch].sinc>=0x20000L) // we would skip at least one val?
344 {
345 s_chan[ch].SB[29]+=(s_chan[ch].SB[30]-s_chan[ch].SB[29])/2; // add easy weight
346 if(s_chan[ch].sinc>=0x30000L) // we would skip even more vals?
347 s_chan[ch].SB[29]+=(s_chan[ch].SB[31]-s_chan[ch].SB[30])/2;// add additional next weight
348 }
349 }
350
351 ////////////////////////////////////////////////////////////////////////
352 // helpers for gauss interpolation
353
354 #define gval0 (((short*)(&s_chan[ch].SB[29]))[gpos])
355 #define gval(x) (((short*)(&s_chan[ch].SB[29]))[(gpos+x)&3])
356
357 #include "gauss_i.h"
358
359 ////////////////////////////////////////////////////////////////////////
360
361 #include "xa.c"
362
363 ////////////////////////////////////////////////////////////////////////
364 // START SOUND... called by main thread to setup a new sound on a channel
365 ////////////////////////////////////////////////////////////////////////
366
367 INLINE void StartSound(int ch)
368 {
369 dwNewChannel2[ch/24]&=~(1<<(ch%24)); // clear new channel bit
370 dwEndChannel2[ch/24]&=~(1<<(ch%24)); // clear end channel bit
371
372 StartADSR(ch);
373 StartREVERB(ch);
374
375 s_chan[ch].pCurr=s_chan[ch].pStart; // set sample start
376
377 s_chan[ch].s_1=0; // init mixing vars
378 s_chan[ch].s_2=0;
379 s_chan[ch].iSBPos=28;
380
381 s_chan[ch].bNew=0; // init channel flags
382 s_chan[ch].bStop=0;
383 s_chan[ch].bOn=1;
384
385 s_chan[ch].SB[29]=0; // init our interpolation helpers
386 s_chan[ch].SB[30]=0;
387
388 if(iUseInterpolation>=2) // gauss interpolation?
389 {s_chan[ch].spos=0x30000L;s_chan[ch].SB[28]=0;} // -> start with more decoding
390 else {s_chan[ch].spos=0x10000L;s_chan[ch].SB[31]=0;} // -> no/simple interpolation starts with one 44100 decoding
391 }
392
393 ////////////////////////////////////////////////////////////////////////
394 // MAIN SPU FUNCTION
395 // here is the main job handler... thread, timer or direct func call
396 // basically the whole sound processing is done in this fat func!
397 ////////////////////////////////////////////////////////////////////////
398
399 // 5 ms waiting phase, if buffer is full and no new sound has to get started
400 // .. can be made smaller (smallest val: 1 ms), but bigger waits give
401 // better performance
402
403 #define PAUSE_W 5
404 #define PAUSE_L 5000
405
406 ////////////////////////////////////////////////////////////////////////
407
408 int iSpuAsyncWait=0;
409
410 #ifdef _WINDOWS
411 static VOID CALLBACK MAINProc(UINT nTimerId,UINT msg,DWORD dwUser,DWORD dwParam1, DWORD dwParam2)
412 #else
413 static void *MAINThread(void *arg)
414 #endif
415 {
416 int s_1,s_2,fa,ns,voldiv=iVolume;
417 unsigned char * start;unsigned int nSample;
418 int ch,predict_nr,shift_factor,flags,d,s;
419 int gpos,bIRQReturn=0;
420
421 while(!bEndThread) // until we are shutting down
422 {
423 //--------------------------------------------------//
424 // ok, at the beginning we are looking if there is
425 // enuff free place in the dsound/oss buffer to
426 // fill in new data, or if there is a new channel to start.
427 // if not, we wait (thread) or return (timer/spuasync)
428 // until enuff free place is available/a new channel gets
429 // started
430
431 if(dwNewChannel2[0] || dwNewChannel2[1]) // new channel should start immedately?
432 { // (at least one bit 0 ... MAXCHANNEL is set?)
433 iSecureStart++; // -> set iSecure
434 if(iSecureStart>5) iSecureStart=0; // (if it is set 5 times - that means on 5 tries a new samples has been started - in a row, we will reset it, to give the sound update a chance)
435 }
436 else iSecureStart=0; // 0: no new channel should start
437
438 while(!iSecureStart && !bEndThread // no new start? no thread end?
439 #if 0
440 && (SoundGetBytesBuffered()>TESTSIZE)
441 #endif
442 ) // and still enuff data in sound buffer?
443 {
444 iSecureStart=0; // reset secure
445
446 #ifdef _WINDOWS
447 if(iUseTimer) // no-thread mode?
448 {
449 if(iUseTimer==1) // -> ok, timer mode 1: setup a oneshot timer of x ms to wait
450 timeSetEvent(PAUSE_W,1,MAINProc,0,TIME_ONESHOT);
451 return; // -> and done this time (timer mode 1 or 2)
452 }
453 // win thread mode:
454 Sleep(PAUSE_W); // sleep for x ms (win)
455 #else
456 if(iUseTimer) return 0; // linux no-thread mode? bye
457 usleep(PAUSE_L); // else sleep for x ms (linux)
458 #endif
459
460 if(dwNewChannel2[0] || dwNewChannel2[1])
461 iSecureStart=1; // if a new channel kicks in (or, of course, sound buffer runs low), we will leave the loop
462 }
463
464 //--------------------------------------------------// continue from irq handling in timer mode?
465
466 if(lastch>=0) // will be -1 if no continue is pending
467 {
468 ch=lastch; ns=lastns; lastch=-1; // -> setup all kind of vars to continue
469 goto GOON; // -> directly jump to the continue point
470 }
471
230 //--------------------------------------------------// 472 //--------------------------------------------------//
231 //- main channel loop -// 473 //- main channel loop -//
232 //--------------------------------------------------// 474 //--------------------------------------------------//
233 { 475 {
234 for(ch=0;ch<MAXCHAN;ch++) // loop em all. 476 for(ch=0;ch<MAXCHAN;ch++) // loop em all... we will collect 1 ms of sound of each playing channel
235 { 477 {
236 if(s_chan[ch].bNew) StartSound(ch); // start new sound 478 if(s_chan[ch].bNew) StartSound(ch); // start new sound
237 if(!s_chan[ch].bOn) continue; // channel not playing? next 479 if(!s_chan[ch].bOn) continue; // channel not playing? next
238
239 480
240 if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency? 481 if(s_chan[ch].iActFreq!=s_chan[ch].iUsedFreq) // new psx frequency?
241 { 482 {
242 s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps 483 s_chan[ch].iUsedFreq=s_chan[ch].iActFreq; // -> take it and calc steps
243 s_chan[ch].sinc=s_chan[ch].iRawPitch<<4; 484 s_chan[ch].sinc=s_chan[ch].iRawPitch<<4;
244 if(!s_chan[ch].sinc) s_chan[ch].sinc=1; 485 if(!s_chan[ch].sinc) s_chan[ch].sinc=1;
486 if(iUseInterpolation==1) s_chan[ch].SB[32]=1; // -> freq change in simle imterpolation mode: set flag
245 } 487 }
246 488
489 ns=0;
490 while(ns<NSSIZE) // loop until 1 ms of data is reached
491 {
247 while(s_chan[ch].spos>=0x10000L) 492 while(s_chan[ch].spos>=0x10000L)
248 { 493 {
249 if(s_chan[ch].iSBPos==28) // 28 reached? 494 if(s_chan[ch].iSBPos==28) // 28 reached?
250 { 495 {
251 int predict_nr,shift_factor,flags,d,s;
252 u8* start;unsigned int nSample;
253 int s_1,s_2;
254
255 start=s_chan[ch].pCurr; // set up the current pos 496 start=s_chan[ch].pCurr; // set up the current pos
256 497
257 if (start == (u8*)-1) // special "stop" sign 498 if (start == (unsigned char*)-1) // special "stop" sign
258 { 499 {
259 s_chan[ch].bOn=0; // -> turn everything off 500 s_chan[ch].bOn=0; // -> turn everything off
260 s_chan[ch].ADSRX.lVolume=0; 501 s_chan[ch].ADSRX.lVolume=0;
261 s_chan[ch].ADSRX.EnvelopeVol=0; 502 s_chan[ch].ADSRX.EnvelopeVol=0;
262 goto ENDX; // -> and done for this channel 503 goto ENDX; // -> and done for this channel
263 } 504 }
264 505
265 s_chan[ch].iSBPos=0; // Reset buffer play index. 506 s_chan[ch].iSBPos=0;
266 507
267 //////////////////////////////////////////// spu irq handler here? mmm... do it later 508 //////////////////////////////////////////// spu irq handler here? mmm... do it later
268 509
269 s_1=s_chan[ch].s_1; 510 s_1=s_chan[ch].s_1;
270 s_2=s_chan[ch].s_2; 511 s_2=s_chan[ch].s_2;
271 512
272 predict_nr=(int)*start;start++; 513 predict_nr=(int)*start;start++;
273 shift_factor=predict_nr&0xf; 514 shift_factor=predict_nr&0xf;
274 predict_nr >>= 4; 515 predict_nr >>= 4;
275 flags=(int)*start;start++; 516 flags=(int)*start;start++;
276 517
277 // -------------------------------------- // 518 // -------------------------------------- //
278 // Decode new samples into s_chan[ch].SB[0 through 27] 519
279 for (nSample=0;nSample<28;start++) 520 for (nSample=0;nSample<28;start++)
280 { 521 {
281 d=(int)*start; 522 d=(int)*start;
282 s=((d&0xf)<<12); 523 s=((d&0xf)<<12);
283 if(s&0x8000) s|=0xffff0000; 524 if(s&0x8000) s|=0xffff0000;
297 s_chan[ch].SB[nSample++]=fa; 538 s_chan[ch].SB[nSample++]=fa;
298 } 539 }
299 540
300 //////////////////////////////////////////// irq check 541 //////////////////////////////////////////// irq check
301 542
302 if(spuCtrl&0x40) // irq active? 543 if(spuCtrl2[ch/24]&0x40) // some irq active?
303 { 544 {
304 if((pSpuIrq > start-16 && // irq address reached? 545 if((pSpuIrq[ch/24] > start-16 && // irq address reached?
305 pSpuIrq <= start) || 546 pSpuIrq[ch/24] <= start) ||
306 ((flags&1) && // special: irq on looping addr, when stop/loop flag is set 547 ((flags&1) && // special: irq on looping addr, when stop/loop flag is set
307 (pSpuIrq > s_chan[ch].pLoop-16 && 548 (pSpuIrq[ch/24] > s_chan[ch].pLoop-16 &&
308 pSpuIrq <= s_chan[ch].pLoop))) 549 pSpuIrq[ch/24] <= s_chan[ch].pLoop)))
309 { 550 {
310 //extern s32 spuirqvoodoo;
311 s_chan[ch].iIrqDone=1; // -> debug flag 551 s_chan[ch].iIrqDone=1; // -> debug flag
312 SPUirq(); 552
313 //puts("IRQ"); 553 if(irqCallback) irqCallback(); // -> call main emu (not supported in SPU2 right now)
314 //if(spuirqvoodoo!=-1) 554 else
315 //{ 555 {
316 // spuirqvoodoo=temp*384; 556 if(ch<24) InterruptDMA4(); // -> let's see what is happening if we call our irqs instead ;)
317 // temp=0; 557 else InterruptDMA7();
318 //} 558 }
559
560 if(iSPUIRQWait) // -> option: wait after irq for main emu
561 {
562 iSpuAsyncWait=1;
563 bIRQReturn=1;
564 }
319 } 565 }
320 } 566 }
321 567
322 //////////////////////////////////////////// flag handler 568 //////////////////////////////////////////// flag handler
323 569
324 if((flags&4) && (!s_chan[ch].bIgnoreLoop)) 570 if((flags&4) && (!s_chan[ch].bIgnoreLoop))
325 s_chan[ch].pLoop=start-16; // loop adress 571 s_chan[ch].pLoop=start-16; // loop adress
326 572
327 if(flags&1) // 1: stop/loop 573 if(flags&1) // 1: stop/loop
328 { 574 {
575 dwEndChannel2[ch/24]|=(1<<(ch%24));
576
329 // We play this block out first... 577 // We play this block out first...
330 //if(!(flags&2)) // 1+2: do loop... otherwise: stop 578 //if(!(flags&2)|| s_chan[ch].pLoop==NULL)
579 // 1+2: do loop... otherwise: stop
331 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) 580 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)
332 { // and checking if pLoop is set avoids crashes, yeah 581 { // and checking if pLoop is set avoids crashes, yeah
333 start = (u8*)-1; 582 start = (unsigned char*)-1;
334 } 583 }
335 else 584 else
336 { 585 {
337 start = s_chan[ch].pLoop; 586 start = s_chan[ch].pLoop;
338 } 587 }
341 s_chan[ch].pCurr=start; // store values for next cycle 590 s_chan[ch].pCurr=start; // store values for next cycle
342 s_chan[ch].s_1=s_1; 591 s_chan[ch].s_1=s_1;
343 s_chan[ch].s_2=s_2; 592 s_chan[ch].s_2=s_2;
344 593
345 //////////////////////////////////////////// 594 ////////////////////////////////////////////
595
596 if(bIRQReturn) // special return for "spu irq - wait for cpu action"
597 {
598 bIRQReturn=0;
599 if(iUseTimer!=2)
600 {
601 DWORD dwWatchTime=SexyTime64()+2500;
602
603 while(iSpuAsyncWait && !bEndThread &&
604 SexyTime64()<dwWatchTime)
605 #ifdef _WINDOWS
606 Sleep(1);
607 #else
608 usleep(1000L);
609 #endif
610
611 }
612 else
613 {
614 lastch=ch;
615 lastns=ns;
616
617 #ifdef _WINDOWS
618 return;
619 #else
620 return 0;
621 #endif
622 }
623 }
624
625 ////////////////////////////////////////////
626
627 GOON: ;
628
346 } 629 }
347 630
348 fa=s_chan[ch].SB[s_chan[ch].iSBPos++]; // get sample data 631 fa=s_chan[ch].SB[s_chan[ch].iSBPos++]; // get sample data
349 632
350 if((spuCtrl&0x4000)==0) fa=0; // muted? 633 if((spuCtrl2[ch/24]&0x4000)==0) fa=0; // muted?
351 else CLIP(fa); 634 else // else adjust
352 635 {
353 { 636 if(fa>32767L) fa=32767L;
354 int gpos; 637 if(fa<-32767L) fa=-32767L;
638 }
639
640 if(iUseInterpolation>=2) // gauss/cubic interpolation
641 {
355 gpos = s_chan[ch].SB[28]; 642 gpos = s_chan[ch].SB[28];
356 gval0 = fa; 643 gval0 = fa;
357 gpos = (gpos+1) & 3; 644 gpos = (gpos+1) & 3;
358 s_chan[ch].SB[28] = gpos; 645 s_chan[ch].SB[28] = gpos;
359 } 646 }
647 else
648 if(iUseInterpolation==1) // simple interpolation
649 {
650 s_chan[ch].SB[28] = 0;
651 s_chan[ch].SB[29] = s_chan[ch].SB[30]; // -> helpers for simple linear interpolation: delay real val for two slots, and calc the two deltas, for a 'look at the future behaviour'
652 s_chan[ch].SB[30] = s_chan[ch].SB[31];
653 s_chan[ch].SB[31] = fa;
654 s_chan[ch].SB[32] = 1; // -> flag: calc new interolation
655 }
656 else s_chan[ch].SB[29]=fa; // no interpolation
657
360 s_chan[ch].spos -= 0x10000L; 658 s_chan[ch].spos -= 0x10000L;
361 } 659 }
362 660
363 //////////////////////////////////////////////// 661 ////////////////////////////////////////////////
364 // noise handler... just produces some noise data 662 // noise handler... just produces some noise data
365 // surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used... 663 // surely wrong... and no noise frequency (spuCtrl&0x3f00) will be used...
366 // and sometimes the noise will be used as fmod modulation... pfff 664 // and sometimes the noise will be used as fmod modulation... pfff
367 665
368 if(s_chan[ch].bNoise) 666 if(s_chan[ch].bNoise)
369 { 667 {
370 //puts("Noise");
371 if((dwNoiseVal<<=1)&0x80000000L) 668 if((dwNoiseVal<<=1)&0x80000000L)
372 { 669 {
373 dwNoiseVal^=0x0040001L; 670 dwNoiseVal^=0x0040001L;
374 fa=((dwNoiseVal>>2)&0x7fff); 671 fa=((dwNoiseVal>>2)&0x7fff);
375 fa=-fa; 672 fa=-fa;
376 } 673 }
377 else fa=(dwNoiseVal>>2)&0x7fff; 674 else fa=(dwNoiseVal>>2)&0x7fff;
378 675
379 // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val 676 // mmm... depending on the noise freq we allow bigger/smaller changes to the previous val
380 fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl&0x3f00)>>9))+1)); 677 fa=s_chan[ch].iOldNoise+((fa-s_chan[ch].iOldNoise)/((0x001f-((spuCtrl2[ch/24]&0x3f00)>>9))+1));
381 if(fa>32767L) fa=32767L; 678 if(fa>32767L) fa=32767L;
382 if(fa<-32767L) fa=-32767L; 679 if(fa<-32767L) fa=-32767L;
383 s_chan[ch].iOldNoise=fa; 680 s_chan[ch].iOldNoise=fa;
384 681
682 if(iUseInterpolation<2) // no gauss/cubic interpolation?
683 s_chan[ch].SB[29] = fa; // -> store noise val in "current sample" slot
385 } //---------------------------------------- 684 } //----------------------------------------
386 else // NO NOISE (NORMAL SAMPLE DATA) HERE 685 else // NO NOISE (NORMAL SAMPLE DATA) HERE
387 { 686 {//------------------------------------------//
388 int vl, vr, gpos; 687 if(iUseInterpolation==3) // cubic interpolation
688 {
689 long xd;
690 xd = ((s_chan[ch].spos) >> 1)+1;
691 gpos = s_chan[ch].SB[28];
692
693 fa = gval(3) - 3*gval(2) + 3*gval(1) - gval0;
694 fa *= (xd - (2<<15)) / 6;
695 fa >>= 15;
696 fa += gval(2) - gval(1) - gval(1) + gval0;
697 fa *= (xd - (1<<15)) >> 1;
698 fa >>= 15;
699 fa += gval(1) - gval0;
700 fa *= xd;
701 fa >>= 15;
702 fa = fa + gval0;
703 }
704 //------------------------------------------//
705 else
706 if(iUseInterpolation==2) // gauss interpolation
707 {
708 int vl, vr;
389 vl = (s_chan[ch].spos >> 6) & ~3; 709 vl = (s_chan[ch].spos >> 6) & ~3;
390 gpos = s_chan[ch].SB[28]; 710 gpos = s_chan[ch].SB[28];
711 vr=(gauss[vl]*gval0)&~2047;
712 vr+=(gauss[vl+1]*gval(1))&~2047;
713 vr+=(gauss[vl+2]*gval(2))&~2047;
714 vr+=(gauss[vl+3]*gval(3))&~2047;
715 fa = vr>>11;
716 /*
391 vr=(gauss[vl]*gval0)>>9; 717 vr=(gauss[vl]*gval0)>>9;
392 vr+=(gauss[vl+1]*gval(1))>>9; 718 vr+=(gauss[vl+1]*gval(1))>>9;
393 vr+=(gauss[vl+2]*gval(2))>>9; 719 vr+=(gauss[vl+2]*gval(2))>>9;
394 vr+=(gauss[vl+3]*gval(3))>>9; 720 vr+=(gauss[vl+3]*gval(3))>>9;
395 fa = vr>>2; 721 fa = vr>>2;
722 */
723 }
724 //------------------------------------------//
725 else
726 if(iUseInterpolation==1) // simple interpolation
727 {
728 if(s_chan[ch].sinc<0x10000L) // -> upsampling?
729 InterpolateUp(ch); // --> interpolate up
730 else InterpolateDown(ch); // --> else down
731 fa=s_chan[ch].SB[29];
732 }
733 //------------------------------------------//
734 else fa=s_chan[ch].SB[29]; // no interpolation
396 } 735 }
397 736
398 s_chan[ch].sval = (MixADSR(ch) * fa)>>10; // / 1023; // add adsr 737 s_chan[ch].sval = (MixADSR(ch) * fa) / 1023; // add adsr
738
399 if(s_chan[ch].bFMod==2) // fmod freq channel 739 if(s_chan[ch].bFMod==2) // fmod freq channel
400 { 740 {
401 int NP=s_chan[ch+1].iRawPitch; 741 int NP=s_chan[ch+1].iRawPitch;
402 NP=((32768L+s_chan[ch].sval)*NP)>>15; ///32768L; 742
743 NP=((32768L+s_chan[ch].sval)*NP)/32768L; // mmm... I still need to adjust that to 1/48 khz... we will wait for the first game/demo using it to decide how to do it :)
403 744
404 if(NP>0x3fff) NP=0x3fff; 745 if(NP>0x3fff) NP=0x3fff;
405 if(NP<0x1) NP=0x1; 746 if(NP<0x1) NP=0x1;
406 747
407 // mmmm... if I do this, all is screwed
408 // s_chan[ch+1].iRawPitch=NP;
409
410 NP=(44100L*NP)/(4096L); // calc frequency 748 NP=(44100L*NP)/(4096L); // calc frequency
411 749
412 s_chan[ch+1].iActFreq=NP; 750 s_chan[ch+1].iActFreq=NP;
413 s_chan[ch+1].iUsedFreq=NP; 751 s_chan[ch+1].iUsedFreq=NP;
414 s_chan[ch+1].sinc=(((NP/10)<<16)/4410); 752 s_chan[ch+1].sinc=(((NP/10)<<16)/4410);
415 if(!s_chan[ch+1].sinc) s_chan[ch+1].sinc=1; 753 if(!s_chan[ch+1].sinc) s_chan[ch+1].sinc=1;
416 754 if(iUseInterpolation==1) // freq change in sipmle interpolation mode
417 // mmmm... set up freq decoding positions? 755 s_chan[ch+1].SB[32]=1;
418 // s_chan[ch+1].iSBPos=28; 756
419 // s_chan[ch+1].spos=0x10000L; 757 // mmmm... set up freq decoding positions?
758 // s_chan[ch+1].iSBPos=28;
759 // s_chan[ch+1].spos=0x10000L;
420 } 760 }
421 else 761 else
422 { 762 {
423 ////////////////////////////////////////////// 763 //////////////////////////////////////////////
424 // ok, left/right sound volume (psx volume goes from 0 ... 0x3fff) 764 // ok, left/right sound volume (psx volume goes from 0 ... 0x3fff)
425 int tmpl,tmpr; 765
426 766 if(s_chan[ch].iMute)
427 tmpl=(s_chan[ch].sval*s_chan[ch].iLeftVolume)>>14; 767 s_chan[ch].sval=0; // debug mute
428 tmpr=(s_chan[ch].sval*s_chan[ch].iRightVolume)>>14; 768 else
429 769 {
430 sl+=tmpl; 770 if(s_chan[ch].bVolumeL)
431 sr+=tmpr; 771 SSumL[ns]+=(s_chan[ch].sval*s_chan[ch].iLeftVolume)/0x4000L;
432 772 if(s_chan[ch].bVolumeR)
433 if(((rvb.Enabled>>ch)&1) && (spuCtrl&0x80)) 773 SSumR[ns]+=(s_chan[ch].sval*s_chan[ch].iRightVolume)/0x4000L;
434 { 774 }
435 revLeft+=tmpl; 775
436 revRight+=tmpr; 776 //////////////////////////////////////////////
437 } 777 // now let us store sound data for reverb
778
779 if(s_chan[ch].bRVBActive) StoreREVERB(ch,ns);
438 } 780 }
439 781
782 ////////////////////////////////////////////////
783 // ok, go on until 1 ms data of this channel is collected
784
785 ns++;
440 s_chan[ch].spos += s_chan[ch].sinc; 786 s_chan[ch].spos += s_chan[ch].sinc;
441 ENDX: ; 787
788 }
789 ENDX: ;
442 } 790 }
443 } 791 }
444 792
793 //---------------------------------------------------//
794 //- here we have another 1 ms of sound data
795 //---------------------------------------------------//
796 // mix XA infos (if any)
797 sampcount++;
798
799
800 if(XAPlay!=XAFeed || XARepeat) MixXA();
801
445 /////////////////////////////////////////////////////// 802 ///////////////////////////////////////////////////////
446 // mix all channels (including reverb) into one buffer 803 // mix all channels (including reverb) into one buffer
447 MixREVERBLeftRight(&sl,&sr,revLeft,revRight); 804
448 if(sampcount>=decaybegin) 805 if(iDisStereo) // no stereo?
449 {
450 s32 dmul;
451 if(decaybegin!=(u32)~0) // Is anyone REALLY going to be playing a song
452 // for 13 hours?
453 { 806 {
454 if(sampcount>=decayend) return(0); 807 int dl,dr;
455 dmul=256-(256*(sampcount-decaybegin)/(decayend-decaybegin)); 808 for(ns=0;ns<NSSIZE;ns++)
456 sl=(sl*dmul)>>8; 809 {
457 sr=(sr*dmul)>>8; 810 SSumL[ns]+=MixREVERBLeft(ns,0);
811 SSumL[ns]+=MixREVERBLeft(ns,1);
812
813 dl=SSumL[ns]/voldiv;SSumL[ns]=0;
814 if(dl<-32767) dl=-32767;if(dl>32767) dl=32767;
815
816 SSumR[ns]+=MixREVERBRight(0);
817 SSumR[ns]+=MixREVERBRight(1);
818
819 dr=SSumR[ns]/voldiv;SSumR[ns]=0;
820 if(dr<-32767) dr=-32767;if(dr>32767) dr=32767;
821 *pS++=(dl+dr)/2;
822 }
458 } 823 }
459 } 824 else // stereo:
460 sampcount++; 825 for(ns=0;ns<NSSIZE;ns++)
461 sl=(sl*volmul)>>8; 826 {
462 sr=(sr*volmul)>>8; 827 SSumL[ns]+=MixREVERBLeft(ns,0);
463 828 SSumL[ns]+=MixREVERBLeft(ns,1);
464 //{ 829
465 // static double asl=0; 830 d=SSumL[ns]/voldiv;SSumL[ns]=0;
466 // static double asr=0; 831 if(d<-32767) d=-32767;if(d>32767) d=32767;
467 832 *pS++=d;
468 // asl+=(sl-asl)/5; 833
469 // asr+=(sl-asr)/5; 834 SSumR[ns]+=MixREVERBRight(0);
470 835 SSumR[ns]+=MixREVERBRight(1);
471 //sl-=asl; 836
472 //sr-=asr; 837 d=SSumR[ns]/voldiv;SSumR[ns]=0;
473 838 if(d<-32767) d=-32767;if(d>32767) d=32767;
474 // if(sl>32767 || sl < -32767) printf("Left: %d, %f\n",sl,asl); 839 *pS++=d;
475 // if(sr>32767 || sr < -32767) printf("Right: %d, %f\n",sl,asl); 840 }
476 //} 841
477 842 InitREVERB();
478 if(sl>32767) sl=32767; if(sl<-32767) sl=-32767; 843
479 if(sr>32767) sr=32767; if(sr<-32767) sr=-32767;
480 *pS++=sl;
481 *pS++=sr;
482 } 844 }
483 845
484 return(1); 846 // end of big main loop...
847
848 bThreadEnded=1;
849
850 #ifndef _WINDOWS
851 return 0;
852 #endif
485 } 853 }
486 854
487 void sexypsf_stop(void) 855 void sexypsf_stop(void)
488 { 856 {
489 decaybegin=decayend=0; 857 decaybegin=decayend=0;
490 } 858 }
491 859
492 void SPUendflush(void) 860 void SPUendflush(void)
493 { 861 {
494 if((seektime!=(u32)~0) && seektime>sampcount) 862 if((seektime!=~0) && seektime>sampcount)
495 { 863 {
496 pS=(s16 *)pSpuBuffer; 864 pS=(short *)pSpuBuffer;
497 sexypsf_update(0,0); 865 sexypsf_update(0,0);
498 } 866 }
499 else if((u8*)pS>((u8*)pSpuBuffer+1024)) 867 else if((unsigned short *)pS>((unsigned short *)pSpuBuffer+1024))
500 { 868 {
501 sexypsf_update((u8*)pSpuBuffer,(u8*)pS-(u8*)pSpuBuffer); 869 sexypsf_update((unsigned short *)pSpuBuffer,(unsigned short *)pS-(unsigned short*)pSpuBuffer);
502 pS=(s16 *)pSpuBuffer; 870 pS=(short *)pSpuBuffer;
503 } 871 }
504 } 872 }
505 873
506 #ifdef TIMEO 874 ////////////////////////////////////////////////////////////////////////
507 static u64 begintime; 875 // WINDOWS THREAD... simply calls the timer func and stays forever :)
508 static u64 SexyTime64(void) 876 ////////////////////////////////////////////////////////////////////////
509 { 877
510 struct timeval tv; 878 #ifdef _WINDOWS
511 u64 ret; 879
512 880 DWORD WINAPI MAINThreadEx(LPVOID lpParameter)
513 gettimeofday(&tv,0); 881 {
514 ret=tv.tv_sec; 882 MAINProc(0,0,0,0,0);
515 ret*=1000000; 883 return 0;
516 ret+=tv.tv_usec; 884 }
517 return(ret); 885
518 } 886 #endif
519 #endif 887
888 ////////////////////////////////////////////////////////////////////////
889 ////////////////////////////////////////////////////////////////////////
890 ////////////////////////////////////////////////////////////////////////
891
892 ////////////////////////////////////////////////////////////////////////
893 // SPU ASYNC... even newer epsxe func
894 // 1 time every 'cycle' cycles... harhar
895 ////////////////////////////////////////////////////////////////////////
896
897 int sexypsf_seek(unsigned long t)
898 {
899 seektime=t*441/10;
900 if(seektime>sampcount) return(1);
901 return(0);
902 }
903
904 EXPORT_GCC void CALLBACK SPU2async(unsigned long cycle)
905 {
906 if(iSpuAsyncWait)
907 {
908 iSpuAsyncWait++;
909 if(iSpuAsyncWait<=64) return;
910 iSpuAsyncWait=0;
911 }
912
913 #ifdef _WINDOWS
914 if(iDebugMode==2)
915 {
916 if(IsWindow(hWDebug)) DestroyWindow(hWDebug);
917 hWDebug=0;iDebugMode=0;
918 }
919 if(iRecordMode==2)
920 {
921 if(IsWindow(hWRecord)) DestroyWindow(hWRecord);
922 hWRecord=0;iRecordMode=0;
923 }
924 #endif
925
926 if(iUseTimer==2) // special mode, only used in Linux by this spu (or if you enable the experimental Windows mode)
927 {
928 if(!bSpuInit) return; // -> no init, no call
929
930 #ifdef _WINDOWS
931 MAINProc(0,0,0,0,0); // -> experimental win mode... not really tested... don't like the drawbacks
932 #else
933 MAINThread(0); // -> linux high-compat mode
934 #endif
935 }
936 }
937
938 ////////////////////////////////////////////////////////////////////////
939 // XA AUDIO
940 ////////////////////////////////////////////////////////////////////////
941
942 // dummy func... not used yet
943 EXPORT_GCC void CALLBACK SPU2playADPCMchannel(xa_decode_t *xap)
944 {
945 if(!iUseXA) return; // no XA? bye
946 if(!xap) return;
947 if(!xap->freq) return; // no xa freq ? bye
948
949 FeedXA(xap); // call main XA feeder
950 }
951
520 //////////////////////////////////////////////////////////////////////// 952 ////////////////////////////////////////////////////////////////////////
521 // INIT/EXIT STUFF 953 // INIT/EXIT STUFF
522 //////////////////////////////////////////////////////////////////////// 954 ////////////////////////////////////////////////////////////////////////
523 955
524 //////////////////////////////////////////////////////////////////////// 956 ////////////////////////////////////////////////////////////////////////
525 // SPUINIT: this func will be called first by the main emu 957 // SPUINIT: this func will be called first by the main emu
526 //////////////////////////////////////////////////////////////////////// 958 ////////////////////////////////////////////////////////////////////////
959
960 #ifdef _WINDOWS
961 static HINSTANCE hIRE = NULL;
962 #endif
527 963
528 int SPUinit(void) 964 EXPORT_GCC long CALLBACK SPU2init(void)
529 { 965 {
530 spuMemC=(u8*)spuMem; // just small setup 966 spuMemC=(unsigned char *)spuMem; // just small setup
531 memset((void *)s_chan,0,MAXCHAN*sizeof(SPUCHAN)); 967 memset((void *)s_chan,0,MAXCHAN*sizeof(SPUCHAN));
532 memset((void *)&rvb,0,sizeof(REVERBInfo)); 968 memset(rvb,0,2*sizeof(REVERBInfo));
533 memset(regArea,0,sizeof(regArea)); 969
534 memset(spuMem,0,sizeof(spuMem));
535 InitADSR(); 970 InitADSR();
536 sampcount=poo=0; 971
537 seektime=(u32)~0; 972 #ifdef _WINDOWS
538 #ifdef TIMEO 973 if(hIRE==NULL) hIRE=LoadLibrary("Riched32.dll "); // needed for debug output
539 begintime=SexyTime64(); 974 #endif
540 #endif 975
541 return 0; 976 return 0;
977 }
978
979 ////////////////////////////////////////////////////////////////////////
980 // SETUPTIMER: init of certain buffers and threads/timers
981 ////////////////////////////////////////////////////////////////////////
982
983 void SetupTimer(void)
984 {
985 memset(SSumR,0,NSSIZE*sizeof(int)); // init some mixing buffers
986 memset(SSumL,0,NSSIZE*sizeof(int));
987 pS=(short *)pSpuBuffer; // setup soundbuffer pointer
988
989 bEndThread=0; // init thread vars
990 bThreadEnded=0;
991 bSpuInit=1; // flag: we are inited
992
993 #ifdef _WINDOWS
994
995 if(iUseTimer==1) // windows: use timer
996 {
997 timeBeginPeriod(1);
998 timeSetEvent(1,1,MAINProc,0,TIME_ONESHOT);
999 }
1000 else
1001 if(iUseTimer==0) // windows: use thread
1002 {
1003 //_beginthread(MAINThread,0,NULL);
1004 DWORD dw;
1005 hMainThread=CreateThread(NULL,0,MAINThreadEx,0,0,&dw);
1006 SetThreadPriority(hMainThread,
1007 //THREAD_PRIORITY_TIME_CRITICAL);
1008 THREAD_PRIORITY_HIGHEST);
1009 }
1010
1011 #else
1012
1013 #ifndef NOTHREADLIB
1014 if(!iUseTimer) // linux: use thread
1015 {
1016 pthread_create(&thread, NULL, MAINThread, NULL);
1017 }
1018 #endif
1019
1020 #endif
1021 }
1022
1023 ////////////////////////////////////////////////////////////////////////
1024 // REMOVETIMER: kill threads/timers
1025 ////////////////////////////////////////////////////////////////////////
1026
1027 void RemoveTimer(void)
1028 {
1029 bEndThread=1; // raise flag to end thread
1030
1031 #ifdef _WINDOWS
1032
1033 if(iUseTimer!=2) // windows thread?
1034 {
1035 while(!bThreadEnded) {Sleep(5L);} // -> wait till thread has ended
1036 Sleep(5L);
1037 }
1038 if(iUseTimer==1) timeEndPeriod(1); // windows timer? stop it
1039
1040 #else
1041
1042 #ifndef NOTHREADLIB
1043 if(!iUseTimer) // linux tread?
1044 {
1045 int i=0;
1046 while(!bThreadEnded && i<2000) {usleep(1000L);i++;} // -> wait until thread has ended
1047 if(thread!=-1) {pthread_cancel(thread);thread=-1;} // -> cancel thread anyway
1048 }
1049 #endif
1050
1051 #endif
1052
1053 bThreadEnded=0; // no more spu is running
1054 bSpuInit=0;
542 } 1055 }
543 1056
544 //////////////////////////////////////////////////////////////////////// 1057 ////////////////////////////////////////////////////////////////////////
545 // SETUPSTREAMS: init most of the spu buffers 1058 // SETUPSTREAMS: init most of the spu buffers
546 //////////////////////////////////////////////////////////////////////// 1059 ////////////////////////////////////////////////////////////////////////
547 1060
548 void SetupStreams(void) 1061 void SetupStreams(void)
549 { 1062 {
550 int i; 1063 int i;
551 1064
552 pSpuBuffer=(u8*)malloc(32768); // alloc mixing buffer 1065 pSpuBuffer=(unsigned char *)malloc(32768); // alloc mixing buffer
553 pS=(s16 *)pSpuBuffer; 1066
1067 i=NSSIZE*2;
1068
1069 sRVBStart[0] = (int *)malloc(i*4); // alloc reverb buffer
1070 memset(sRVBStart[0],0,i*4);
1071 sRVBEnd[0] = sRVBStart[0] + i;
1072 sRVBPlay[0] = sRVBStart[0];
1073 sRVBStart[1] = (int *)malloc(i*4); // alloc reverb buffer
1074 memset(sRVBStart[1],0,i*4);
1075 sRVBEnd[1] = sRVBStart[1] + i;
1076 sRVBPlay[1] = sRVBStart[1];
1077
1078 XAStart = // alloc xa buffer (not used here anyway)
1079 (unsigned long *)malloc(48000*4);
1080 XAPlay = XAStart;
1081 XAFeed = XAStart;
1082 XAEnd = XAStart + 48000;
554 1083
555 for(i=0;i<MAXCHAN;i++) // loop sound channels 1084 for(i=0;i<MAXCHAN;i++) // loop sound channels
556 { 1085 {
1086 // we don't use mutex sync... not needed, would only
1087 // slow us down:
1088 // s_chan[i].hMutex=CreateMutex(NULL,FALSE,NULL);
557 s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain 1089 s_chan[i].ADSRX.SustainLevel = 1024; // -> init sustain
1090 s_chan[i].iMute=0;
558 s_chan[i].iIrqDone=0; 1091 s_chan[i].iIrqDone=0;
559 s_chan[i].pLoop=spuMemC; 1092 s_chan[i].pLoop=spuMemC;
560 s_chan[i].pStart=spuMemC; 1093 s_chan[i].pStart=spuMemC;
561 s_chan[i].pCurr=spuMemC; 1094 s_chan[i].pCurr=spuMemC;
562 } 1095 }
568 1101
569 void RemoveStreams(void) 1102 void RemoveStreams(void)
570 { 1103 {
571 free(pSpuBuffer); // free mixing buffer 1104 free(pSpuBuffer); // free mixing buffer
572 pSpuBuffer=NULL; 1105 pSpuBuffer=NULL;
573 1106 free(sRVBStart[0]); // free reverb buffer
574 #ifdef TIMEO 1107 sRVBStart[0]=0;
575 { 1108 free(sRVBStart[1]); // free reverb buffer
576 u64 tmp; 1109 sRVBStart[1]=0;
577 tmp=SexyTime64(); 1110 free(XAStart); // free XA buffer
578 tmp-=begintime; 1111 XAStart=0;
579 if(tmp) 1112
580 tmp=(u64)sampcount*1000000/tmp; 1113 /*
581 printf("%lld samples per second\n",tmp); 1114 int i;
582 } 1115 for(i=0;i<MAXCHAN;i++)
583 #endif 1116 {
1117 WaitForSingleObject(s_chan[i].hMutex,2000);
1118 ReleaseMutex(s_chan[i].hMutex);
1119 if(s_chan[i].hMutex)
1120 {CloseHandle(s_chan[i].hMutex);s_chan[i].hMutex=0;}
1121 }
1122 */
584 } 1123 }
585 1124
586 1125
587 //////////////////////////////////////////////////////////////////////// 1126 ////////////////////////////////////////////////////////////////////////
588 // SPUOPEN: called by main emu after init 1127 // SPUOPEN: called by main emu after init
589 //////////////////////////////////////////////////////////////////////// 1128 ////////////////////////////////////////////////////////////////////////
590 1129
591 int SPUopen(void) 1130 EXPORT_GCC long CALLBACK SPU2open(void *pDsp)
592 { 1131 {
1132 #ifdef _WINDOWS
1133 HWND hW=0;
1134 #endif
1135
593 if(bSPUIsOpen) return 0; // security for some stupid main emus 1136 if(bSPUIsOpen) return 0; // security for some stupid main emus
594 spuIrq=0; 1137
595 1138 iUseXA=1; // just small setup
596 spuStat=spuCtrl=0; 1139 iVolume=3;
597 spuAddr=0xffffffff; 1140 bEndThread=0;
598 dwNoiseVal=1; 1141 bThreadEnded=0;
599 1142 spuMemC=(unsigned char *)spuMem;
600 spuMemC=(u8*)spuMem;
601 memset((void *)s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN)); 1143 memset((void *)s_chan,0,(MAXCHAN+1)*sizeof(SPUCHAN));
602 pSpuIrq=0; 1144 pSpuIrq[0]=0;
603 1145 pSpuIrq[1]=0;
604 iVolume=128; //85; 1146 iSPUIRQWait=1;
1147 dwNewChannel2[0]=0;
1148 dwNewChannel2[1]=0;
1149 dwEndChannel2[0]=0;
1150 dwEndChannel2[1]=0;
1151 spuCtrl2[0]=0;
1152 spuCtrl2[1]=0;
1153 spuStat2[0]=0;
1154 spuStat2[1]=0;
1155 spuIrq2[0]=0;
1156 spuIrq2[1]=0;
1157 spuAddr2[0]=0xffffffff;
1158 spuAddr2[1]=0xffffffff;
1159 spuRvbAddr2[0]=0;
1160 spuRvbAddr2[1]=0;
1161 spuRvbAEnd2[0]=0;
1162 spuRvbAEnd2[1]=0;
1163
1164 #ifdef _WINDOWS
1165 LastWrite=0xffffffff;LastPlay=0; // init some play vars
1166 if(!IsWindow(hW)) hW=GetActiveWindow();
1167 hWMain = hW; // store hwnd
1168 #endif
1169
605 SetupStreams(); // prepare streaming 1170 SetupStreams(); // prepare streaming
606 1171
1172 SetupTimer(); // timer for feeding data
1173
607 bSPUIsOpen=1; 1174 bSPUIsOpen=1;
608 1175
609 return 1; 1176 #ifdef _WINDOWS
610 } 1177 if(iDebugMode) // windows debug dialog
611 1178 {
612 //////////////////////////////////////////////////////////////////////// 1179 hWDebug=CreateDialog(hInst,MAKEINTRESOURCE(IDD_DEBUG),
1180 NULL,(DLGPROC)DebugDlgProc);
1181 SetWindowPos(hWDebug,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW|SWP_NOACTIVATE);
1182 UpdateWindow(hWDebug);
1183 SetFocus(hWMain);
1184 }
1185
1186 if(iRecordMode) // windows recording dialog
1187 {
1188 hWRecord=CreateDialog(hInst,MAKEINTRESOURCE(IDD_RECORD),
1189 NULL,(DLGPROC)RecordDlgProc);
1190 SetWindowPos(hWRecord,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW|SWP_NOACTIVATE);
1191 UpdateWindow(hWRecord);
1192 SetFocus(hWMain);
1193 }
1194 #endif
1195
1196 return 0;
1197 }
1198
1199 ////////////////////////////////////////////////////////////////////////
1200
1201 // not used yet
1202 #ifndef _WINDOWS
1203 void SPU2setConfigFile(char * pCfg)
1204 {
1205
1206 }
1207 #endif
613 1208
614 //////////////////////////////////////////////////////////////////////// 1209 ////////////////////////////////////////////////////////////////////////
615 // SPUCLOSE: called before shutdown 1210 // SPUCLOSE: called before shutdown
616 //////////////////////////////////////////////////////////////////////// 1211 ////////////////////////////////////////////////////////////////////////
617 1212
618 int SPUclose(void) 1213 EXPORT_GCC void CALLBACK SPU2close(void)
619 { 1214 {
620 if(!bSPUIsOpen) return 0; // some security 1215 if(!bSPUIsOpen) return; // some security
621 1216
622 bSPUIsOpen=0; // no more open 1217 bSPUIsOpen=0; // no more open
623 1218
1219 #ifdef _WINDOWS
1220 if(IsWindow(hWDebug)) DestroyWindow(hWDebug);
1221 hWDebug=0;
1222 if(IsWindow(hWRecord)) DestroyWindow(hWRecord);
1223 hWRecord=0;
1224 #endif
1225
1226 RemoveTimer(); // no more feeding
1227
624 RemoveStreams(); // no more streaming 1228 RemoveStreams(); // no more streaming
625 1229 }
1230
1231 ////////////////////////////////////////////////////////////////////////
1232 // SPUSHUTDOWN: called by main emu on final exit
1233 ////////////////////////////////////////////////////////////////////////
1234
1235 EXPORT_GCC void CALLBACK SPU2shutdown(void)
1236 {
1237 #ifdef _WINDOWS
1238 if(hIRE!=NULL) {FreeLibrary(hIRE);hIRE=NULL;}
1239 #endif
1240
1241 return;
1242 }
1243
1244 ////////////////////////////////////////////////////////////////////////
1245 // SPUTEST: we don't test, we are always fine ;)
1246 ////////////////////////////////////////////////////////////////////////
1247
1248 EXPORT_GCC long CALLBACK SPU2test(void)
1249 {
626 return 0; 1250 return 0;
627 } 1251 }
628 1252
629 //////////////////////////////////////////////////////////////////////// 1253 ////////////////////////////////////////////////////////////////////////
630 // SPUSHUTDOWN: called by main emu on final exit 1254 // SPUCONFIGURE: call config dialog
631 //////////////////////////////////////////////////////////////////////// 1255 ////////////////////////////////////////////////////////////////////////
632 1256
633 int SPUshutdown(void) 1257 EXPORT_GCC void CALLBACK SPU2configure(void)
634 { 1258 {
635 return 0; 1259
636 } 1260 }
637 1261
1262 ////////////////////////////////////////////////////////////////////////
1263 // SPUABOUT: show about window
1264 ////////////////////////////////////////////////////////////////////////
1265
1266 EXPORT_GCC void CALLBACK SPU2about(void)
1267 {
1268
1269 }
1270
1271 ////////////////////////////////////////////////////////////////////////
1272 // SETUP CALLBACKS
1273 // this functions will be called once,
1274 // passes a callback that should be called on SPU-IRQ/cdda volume change
1275 ////////////////////////////////////////////////////////////////////////
1276
1277 // not used yet
1278 EXPORT_GCC void CALLBACK SPU2irqCallback(void (CALLBACK *callback)(void))
1279 {
1280 irqCallback = callback;
1281 }
1282
1283 // not used yet
1284 EXPORT_GCC void CALLBACK SPU2registerCallback(void (CALLBACK *callback)(void))
1285 {
1286 irqCallback = callback;
1287 }
1288
1289 // not used yet
1290 EXPORT_GCC void CALLBACK SPU2registerCDDAVolume(void (CALLBACK *CDDAVcallback)(unsigned short,unsigned short))
1291 {
1292 cddavCallback = CDDAVcallback;
1293 }
1294
1295 ////////////////////////////////////////////////////////////////////////
1296 // COMMON PLUGIN INFO FUNCS
1297 ////////////////////////////////////////////////////////////////////////
1298
1299 EXPORT_GCC char * CALLBACK PS2EgetLibName(void)
1300 {
1301 return libraryName;
1302 }
1303
1304 #define PS2E_LT_SPU2 0x4
1305
1306 EXPORT_GCC unsigned long CALLBACK PS2EgetLibType(void)
1307 {
1308 return PS2E_LT_SPU2;
1309 }
1310
1311 EXPORT_GCC unsigned long CALLBACK PS2EgetLibVersion2(unsigned long type)
1312 {
1313 unsigned char v=version;
1314
1315 // key hack to fake a lower version:
1316 //if(GetAsyncKeyState(VK_SHIFT)&0x8000) v--;
1317
1318 // compile hack to set lib version to PCSX2 0.6 standards
1319 //v=2;
1320
1321 return v<<16|revision<<8|build;
1322 }
1323
1324 // not used yet
1325 char * SPU2getLibInfos(void)
1326 {
1327 return libraryInfo;
1328 }
1329
1330 ////////////////////////////////////////////////////////////////////////
1331