initial import
[picodrive.git] / platform / win32 / GenaDrive / DSound.cpp
CommitLineData
cc68a136 1\r
2#include "app.h"\r
3\r
4#ifndef _XBOX\r
5#pragma warning (disable:4201)\r
6#include <mmsystem.h>\r
7#include <dsound.h>\r
8#endif\r
9\r
10static IDirectSound *DSound=NULL;\r
11static IDirectSoundBuffer *LoopBuffer=NULL;\r
12static int LoopLen=0,LoopWrite=0; // Next position in loop to write\r
13\r
14short *DSoundNext=NULL; // Buffer for next sound data to put in loop\r
15//int DSoundSeg=0; // Seg length in samples\r
16\r
17static int LoopBlank()\r
18{\r
19 void *mema=NULL,*memb=NULL;\r
20 DWORD sizea=0,sizeb=0;\r
21\r
22 LoopBuffer->Lock(0,LoopLen<<2, &mema,&sizea, &memb,&sizeb, 0);\r
23 \r
24 if (mema) memset(mema,0,sizea);\r
25\r
26 LoopBuffer->Unlock(mema,sizea, memb,sizeb);\r
27\r
28 return 0;\r
29}\r
30\r
31int DSoundInit()\r
32{\r
33 DSBUFFERDESC dsbd;\r
34 WAVEFORMATEX wfx;\r
35\r
36 memset(&dsbd,0,sizeof(dsbd));\r
37 memset(&wfx,0,sizeof(wfx));\r
38\r
39 // Make wave format:\r
40 wfx.wFormatTag=WAVE_FORMAT_PCM;\r
41 wfx.nChannels=(unsigned short)((PicoOpt&8) ? 2 : 1); // Stereo/mono\r
42 wfx.nSamplesPerSec=PsndRate;\r
43 wfx.wBitsPerSample=16;\r
44\r
45 wfx.nBlockAlign=(WORD)((wfx.nChannels*wfx.wBitsPerSample)>>3);\r
46 wfx.nAvgBytesPerSec=wfx.nBlockAlign*wfx.nSamplesPerSec;\r
47\r
48 // Make buffer for the next seg to put into the loop:\r
49 DSoundNext=(short *)malloc(PsndLen<<2); if (DSoundNext==NULL) return 1;\r
50 memset(DSoundNext,0,PsndLen<<2);\r
51\r
52 // Create the DirectSound interface:\r
53 DirectSoundCreate(NULL,&DSound,NULL);\r
54 if (DSound==NULL) return 1;\r
55\r
56 LoopLen=PsndLen<<1; // 2 segs\r
57\r
58#ifndef _XBOX\r
59 LoopLen<<=1; // 4 segs\r
60 DSound->SetCooperativeLevel(FrameWnd,DSSCL_PRIORITY);\r
61 dsbd.dwFlags=DSBCAPS_GLOBALFOCUS; // Play in background\r
62#endif\r
63\r
64 // Create the looping buffer:\r
65 dsbd.dwSize=sizeof(dsbd);\r
66 dsbd.dwBufferBytes=LoopLen<<wfx.nChannels; // 16bit stereo?\r
67 dsbd.lpwfxFormat=&wfx;\r
68\r
69 DSound->CreateSoundBuffer(&dsbd,&LoopBuffer,NULL);\r
70 if (LoopBuffer==NULL) return 1;\r
71\r
72 LoopBlank();\r
73 LoopBuffer->Play(0,0,DSBPLAY_LOOPING);\r
74 return 0;\r
75}\r
76\r
77void DSoundExit()\r
78{\r
79 if (LoopBuffer) LoopBuffer->Stop();\r
80 RELEASE(LoopBuffer)\r
81 RELEASE(DSound)\r
82 free(DSoundNext); DSoundNext=NULL;\r
83}\r
84\r
85static int WriteSeg()\r
86{\r
87 void *mema=NULL,*memb=NULL;\r
88 DWORD sizea=0,sizeb=0;\r
89\r
90 // Lock the segment at 'LoopWrite' and copy the next segment in\r
91 LoopBuffer->Lock(LoopWrite<<((PicoOpt&8) ? 2 : 1),PsndLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);\r
92 \r
93 if (mema) memcpy(mema,DSoundNext,sizea);\r
94\r
95 LoopBuffer->Unlock(mema,sizea, memb,0);\r
96\r
97 return 0;\r
98}\r
99\r
100int DSoundUpdate()\r
101{\r
102 DWORD play=0;\r
103 int pos=0;\r
104\r
105 if (LoopBuffer==NULL) return 1;\r
106\r
107 LoopBuffer->GetCurrentPosition(&play,NULL);\r
108 pos=play>>((PicoOpt&8) ? 2 : 1);\r
109\r
110 // 'LoopWrite' is the next seg in the loop that we want to write\r
111 // First check that the sound 'play' pointer has moved out of it:\r
112 if (pos>=LoopWrite && pos<LoopWrite+PsndLen) return 1; // No, it hasn't\r
113\r
114 WriteSeg();\r
115\r
116 // Advance LoopWrite to next seg:\r
117 LoopWrite+=PsndLen; if (LoopWrite+PsndLen>LoopLen) LoopWrite=0;\r
118\r
119 return 0;\r
120}\r
121\r
122void DSoundMute()\r
123{\r
124 LoopBuffer->Stop();\r
125}\r
126\r
127void DSoundUnMute()\r
128{\r
129 LoopBuffer->Play(0,0,DSBPLAY_LOOPING);\r
130}\r