5 #pragma warning (disable:4201)
\r
6 #include <mmsystem.h>
\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
14 short *DSoundNext=NULL; // Buffer for next sound data to put in loop
\r
16 static int LoopBlank()
\r
18 void *mema=NULL,*memb=NULL;
\r
19 DWORD sizea=0,sizeb=0;
\r
21 LoopBuffer->Lock(0,LoopLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
\r
23 if (mema) memset(mema,0,sizea);
\r
25 LoopBuffer->Unlock(mema,sizea, memb,sizeb);
\r
35 memset(&dsbd,0,sizeof(dsbd));
\r
36 memset(&wfx,0,sizeof(wfx));
\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
44 wfx.nBlockAlign=(WORD)((wfx.nChannels*wfx.wBitsPerSample)>>3);
\r
45 wfx.nAvgBytesPerSec=wfx.nBlockAlign*wfx.nSamplesPerSec;
\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 // lprintf("p %p\n", DSoundNext);
\r
52 // Create the DirectSound interface:
\r
53 DirectSoundCreate(NULL,&DSound,NULL);
\r
54 if (DSound==NULL) return 1;
\r
56 LoopLen=PsndLen<<1; // 2 segs
\r
59 LoopLen<<=1; // 4 segs
\r
60 DSound->SetCooperativeLevel(FrameWnd,DSSCL_PRIORITY);
\r
61 dsbd.dwFlags=DSBCAPS_GLOBALFOCUS; // Play in background
\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
69 DSound->CreateSoundBuffer(&dsbd,&LoopBuffer,NULL);
\r
70 if (LoopBuffer==NULL) return 1;
\r
73 LoopBuffer->Play(0,0,DSBPLAY_LOOPING);
\r
79 if (LoopBuffer) LoopBuffer->Stop();
\r
83 if (DSoundNext) free(DSoundNext); DSoundNext=NULL;
\r
86 static int WriteSeg()
\r
88 void *mema=NULL,*memb=NULL;
\r
89 DWORD sizea=0,sizeb=0;
\r
92 // Lock the segment at 'LoopWrite' and copy the next segment in
\r
93 ret = LoopBuffer->Lock(LoopWrite<<((PicoOpt&8) ? 2 : 1),PsndLen<<((PicoOpt&8) ? 2 : 1), &mema,&sizea, &memb,&sizeb, 0);
\r
94 if (ret) lprintf("LoopBuffer->Lock() failed: %i\n", ret);
\r
96 if (mema) memcpy(mema,DSoundNext,sizea);
\r
97 // if (memb) memcpy(memb,DSoundNext+sizea,sizeb);
\r
98 if (sizeb != 0) lprintf("sizeb is not 0! (%i)\n", sizeb);
\r
100 ret = LoopBuffer->Unlock(mema,sizea, memb,0);
\r
101 if (ret) lprintf("LoopBuffer->Unlock() failed: %i\n", ret);
\r
106 static int DSoundFake()
\r
108 static int ticks_old = 0;
\r
109 int ticks = GetTickCount() * 1000;
\r
112 diff = ticks - ticks_old;
\r
113 if (diff >= 0 && diff < 1000000/60*4)
\r
115 while (diff >= 0 && diff < 1000000/60)
\r
118 diff = GetTickCount()*1000 - ticks_old;
\r
120 ticks_old += 1000000/60;
\r
132 if (LoopBuffer==NULL) return DSoundFake();
\r
134 LoopBuffer->GetCurrentPosition(&play,NULL);
\r
135 pos=play>>((PicoOpt&8) ? 2 : 1);
\r
137 // 'LoopWrite' is the next seg in the loop that we want to write
\r
138 // First check that the sound 'play' pointer has moved out of it:
\r
139 if (pos>=LoopWrite && pos<LoopWrite+PsndLen) return 1; // No, it hasn't
\r
143 // Advance LoopWrite to next seg:
\r
144 LoopWrite+=PsndLen; if (LoopWrite+PsndLen>LoopLen) LoopWrite=0;
\r