+++ /dev/null
-//#pragma warning (disable:4201)\r
-#include <stdlib.h>\r
-#define WIN32_LEAN_AND_MEAN\r
-#include <windows.h>\r
-#include <mmsystem.h>\r
-#include <dsound.h>\r
-\r
-#include "dsnd.h"\r
-#include "../common/lprintf.h"\r
-\r
-#define NSEGS 4\r
-#define RELEASE(x) if (x) x->Release(); x=NULL;\r
-\r
-static LPDIRECTSOUND DSound;\r
-static LPDIRECTSOUNDBUFFER LoopBuffer;\r
-static LPDIRECTSOUNDNOTIFY DSoundNotify;\r
-static HANDLE seg_played_event;\r
-static int LoopLen, LoopWrite, LoopSeg; // bytes\r
-\r
-static int LoopBlank(void)\r
-{\r
- void *mema=NULL,*memb=NULL;\r
- DWORD sizea=0,sizeb=0;\r
-\r
- LoopBuffer->Lock(0, LoopLen, &mema,&sizea, &memb,&sizeb, 0);\r
- \r
- if (mema) memset(mema,0,sizea);\r
-\r
- LoopBuffer->Unlock(mema,sizea, memb,sizeb);\r
-\r
- return 0;\r
-}\r
-\r
-int DSoundInit(HWND wnd_coop, int rate, int stereo, int seg_samples)\r
-{\r
- DSBUFFERDESC dsbd;\r
- WAVEFORMATEX wfx;\r
- DSBPOSITIONNOTIFY notifies[NSEGS];\r
- int i;\r
-\r
- memset(&dsbd,0,sizeof(dsbd));\r
- memset(&wfx,0,sizeof(wfx));\r
-\r
- // Make wave format:\r
- wfx.wFormatTag=WAVE_FORMAT_PCM;\r
- wfx.nChannels=stereo ? 2 : 1;\r
- wfx.nSamplesPerSec=rate;\r
- wfx.wBitsPerSample=16;\r
-\r
- wfx.nBlockAlign=(WORD)((wfx.nChannels*wfx.wBitsPerSample)>>3);\r
- wfx.nAvgBytesPerSec=wfx.nBlockAlign*wfx.nSamplesPerSec;\r
-\r
- // Create the DirectSound interface:\r
- DirectSoundCreate(NULL,&DSound,NULL);\r
- if (DSound==NULL) return 1;\r
-\r
- LoopSeg = seg_samples * 2;\r
- if (stereo)\r
- LoopSeg *= 2;\r
-\r
- LoopLen = LoopSeg * NSEGS;\r
-\r
- DSound->SetCooperativeLevel(wnd_coop, DSSCL_PRIORITY);\r
- dsbd.dwFlags=DSBCAPS_GLOBALFOCUS; // Play in background\r
- dsbd.dwFlags|=DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_CTRLPOSITIONNOTIFY;\r
-\r
- // Create the looping buffer:\r
- dsbd.dwSize=sizeof(dsbd);\r
- dsbd.dwBufferBytes=LoopLen;\r
- dsbd.lpwfxFormat=&wfx;\r
-\r
- DSound->CreateSoundBuffer(&dsbd,&LoopBuffer,NULL);\r
- if (LoopBuffer==NULL) return 1;\r
-\r
- LoopBuffer->QueryInterface(IID_IDirectSoundNotify, (LPVOID*)&DSoundNotify);\r
- if (DSoundNotify == NULL) {\r
- lprintf("QueryInterface(IID_IDirectSoundNotify) failed\n");\r
- goto out;\r
- }\r
-\r
- seg_played_event = CreateEvent(NULL, 0, 0, NULL);\r
- if (seg_played_event == NULL)\r
- goto out;\r
-\r
- for (i = 0; i < NSEGS; i++) {\r
- notifies[i].dwOffset = i * LoopSeg;\r
- notifies[i].hEventNotify = seg_played_event;\r
- }\r
- i = DSoundNotify->SetNotificationPositions(NSEGS, notifies);\r
- if (i != DS_OK) {\r
- lprintf("SetNotificationPositions failed\n");\r
- goto out;\r
- }\r
-\r
-out:\r
- LoopBlank();\r
- LoopBuffer->Play(0, 0, DSBPLAY_LOOPING);\r
- return 0;\r
-}\r
-\r
-void DSoundExit(void)\r
-{\r
- if (LoopBuffer)\r
- LoopBuffer->Stop();\r
- RELEASE(DSoundNotify);\r
- RELEASE(LoopBuffer)\r
- RELEASE(DSound)\r
- CloseHandle(seg_played_event);\r
- seg_played_event = NULL;\r
-}\r
-\r
-static int WriteSeg(const void *buff)\r
-{\r
- void *mema=NULL,*memb=NULL;\r
- DWORD sizea=0,sizeb=0;\r
- int ret;\r
-\r
- // Lock the segment at 'LoopWrite' and copy the next segment in\r
- ret = LoopBuffer->Lock(LoopWrite, LoopSeg, &mema, &sizea, &memb, &sizeb, 0);\r
- if (ret != DS_OK)\r
- lprintf("LoopBuffer->Lock() failed: %i\n", ret);\r
-\r
- if (mema) memcpy(mema,buff,sizea);\r
-// if (memb) memcpy(memb,DSoundNext+sizea,sizeb);\r
- if (sizeb != 0) lprintf("sizeb is not 0! (%i)\n", sizeb);\r
-\r
- ret = LoopBuffer->Unlock(mema,sizea, memb, sizeb);\r
- if (ret != DS_OK)\r
- lprintf("LoopBuffer->Unlock() failed: %i\n", ret);\r
-\r
- return 0;\r
-}\r
-\r
-int DSoundUpdate(const void *buff, int blocking)\r
-{\r
- DWORD play = 0;\r
- int pos;\r
-\r
- LoopBuffer->GetCurrentPosition(&play, NULL);\r
- pos = play;\r
-\r
- // 'LoopWrite' is the next seg in the loop that we want to write\r
- // First check that the sound 'play' pointer has moved out of it:\r
- if (blocking) {\r
- while (LoopWrite <= pos && pos < LoopWrite + LoopSeg) {\r
- WaitForSingleObject(seg_played_event, 5000);\r
- LoopBuffer->GetCurrentPosition(&play, NULL);\r
- pos = play;\r
- }\r
- }\r
- else {\r
- if (LoopWrite <= pos && pos < LoopWrite + LoopSeg)\r
- return 1;\r
- }\r
-\r
- WriteSeg(buff);\r
-\r
- // Advance LoopWrite to next seg:\r
- LoopWrite += LoopSeg;\r
- if (LoopWrite + LoopSeg > LoopLen)\r
- LoopWrite = 0;\r
-\r
- return 0;\r
-}\r
-\r