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