30 #ifndef _WAVEFORMATEXTENSIBLE_
38 #ifndef DSSPEAKER_5POINT1
39 #define DSSPEAKER_5POINT1 6
41 #ifndef DSSPEAKER_7POINT1
42 #define DSSPEAKER_7POINT1 7
45 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
46 DEFINE_GUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, 0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
50 static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice, IDirectSound **
ppDS, IUnknown *
pUnkOuter);
51 static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback,
void *
pContext);
52 static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID pcGuidDevice, IDirectSoundCapture **
ppDSC, IUnknown *
pUnkOuter);
53 static HRESULT (WINAPI *pDirectSoundCaptureEnumerateA)(LPDSENUMCALLBACKA pDSEnumCallback,
void *
pContext);
55 #define DirectSoundCreate pDirectSoundCreate
56 #define DirectSoundEnumerateA pDirectSoundEnumerateA
57 #define DirectSoundCaptureCreate pDirectSoundCaptureCreate
58 #define DirectSoundCaptureEnumerateA pDirectSoundCaptureEnumerateA
64 IDirectSoundBuffer *PrimaryBuffer;
65 IDirectSoundBuffer *Buffer;
66 IDirectSoundNotify *Notifies;
75 IDirectSoundCapture *DSC;
76 IDirectSoundCaptureBuffer *DSCbuffer;
93 #define MAX_UPDATES 128
102 ERR(
"Failed to load dsound.dll\n");
106 #define LOAD_FUNC(f) do { \
107 p##f = GetSymbol(ds_handle, #f); \
109 CloseLib(ds_handle); \
126 LPOLESTR guidstr =
NULL;
142 snprintf(str,
sizeof(str),
"%s", desc);
144 snprintf(str,
sizeof(str),
"%s #%d", desc, count+1);
154 hr = StringFromCLSID(guid, &guidstr);
157 TRACE(
"Got device \"%s\", GUID \"%ls\"\n", str, guidstr);
158 CoTaskMemFree(guidstr);
176 LPOLESTR guidstr =
NULL;
192 snprintf(str,
sizeof(str),
"%s", desc);
194 snprintf(str,
sizeof(str),
"%s #%d", desc, count+1);
204 hr = StringFromCLSID(guid, &guidstr);
207 TRACE(
"Got device \"%s\", GUID \"%ls\"\n", str, guidstr);
208 CoTaskMemFree(guidstr);
227 DSoundPlaybackData *
data = (DSoundPlaybackData*)Device->
ExtraData;
229 DWORD LastCursor = 0;
231 VOID *WritePtr1, *WritePtr2;
232 DWORD WriteCnt1, WriteCnt2;
241 memset(&DSBCaps, 0,
sizeof(DSBCaps));
242 DSBCaps.dwSize =
sizeof(DSBCaps);
243 err = IDirectSoundBuffer_GetCaps(data->Buffer, &DSBCaps);
246 ERR(
"Failed to get buffer caps: 0x%lx\n", err);
256 IDirectSoundBuffer_GetCurrentPosition(data->Buffer, &LastCursor,
NULL);
257 while(!data->killNow)
260 IDirectSoundBuffer_GetCurrentPosition(data->Buffer, &PlayCursor,
NULL);
261 avail = (PlayCursor-LastCursor+DSBCaps.dwBufferBytes) % DSBCaps.dwBufferBytes;
267 err = IDirectSoundBuffer_Play(data->Buffer, 0, 0, DSBPLAY_LOOPING);
270 ERR(
"Failed to play buffer: 0x%lx\n", err);
279 avail = WaitForSingleObjectEx(data->NotifyEvent, 2000,
FALSE);
280 if(avail != WAIT_OBJECT_0)
281 ERR(
"WaitForSingleObjectEx error: 0x%lx\n", avail);
284 avail -= avail%FragSize;
289 err = IDirectSoundBuffer_Lock(data->Buffer, LastCursor, avail, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
292 if(err == DSERR_BUFFERLOST)
294 WARN(
"Buffer lost, restoring...\n");
295 err = IDirectSoundBuffer_Restore(data->Buffer);
300 err = IDirectSoundBuffer_Lock(data->Buffer, 0, DSBCaps.dwBufferBytes, &WritePtr1, &WriteCnt1, &WritePtr2, &WriteCnt2, 0);
308 aluMixData(Device, WritePtr1, WriteCnt1/FrameSize);
309 aluMixData(Device, WritePtr2, WriteCnt2/FrameSize);
312 IDirectSoundBuffer_Unlock(data->Buffer, WritePtr1, WriteCnt1, WritePtr2, WriteCnt2);
316 ERR(
"Buffer lock error: %#lx\n", err);
324 LastCursor += WriteCnt1+WriteCnt2;
325 LastCursor %= DSBCaps.dwBufferBytes;
341 ERR(
"Error enumerating DirectSound devices (%#x)!\n", (
unsigned int)hr);
361 if(i == NumPlaybackDevices)
366 data =
calloc(1,
sizeof(DSoundPlaybackData));
372 if(data->NotifyEvent ==
NULL)
379 hr = IDirectSound_SetCooperativeLevel(data->DS, GetForegroundWindow(), DSSCL_PRIORITY);
383 IDirectSound_Release(data->DS);
384 if(data->NotifyEvent)
385 CloseHandle(data->NotifyEvent);
387 ERR(
"Device init failed: 0x%08lx\n", hr);
401 IDirectSoundNotify_Release(data->Notifies);
402 data->Notifies =
NULL;
404 IDirectSoundBuffer_Release(data->Buffer);
406 if(data->PrimaryBuffer !=
NULL)
407 IDirectSoundBuffer_Release(data->PrimaryBuffer);
408 data->PrimaryBuffer =
NULL;
410 IDirectSound_Release(data->DS);
411 CloseHandle(data->NotifyEvent);
418 DSoundPlaybackData *
data = (DSoundPlaybackData*)device->
ExtraData;
419 DSBUFFERDESC DSBDescription;
424 memset(&OutputType, 0,
sizeof(OutputType));
427 IDirectSoundNotify_Release(data->Notifies);
428 data->Notifies =
NULL;
430 IDirectSoundBuffer_Release(data->Buffer);
432 if(data->PrimaryBuffer !=
NULL)
433 IDirectSoundBuffer_Release(data->PrimaryBuffer);
434 data->PrimaryBuffer =
NULL;
457 hr = IDirectSound_GetSpeakerConfig(data->DS, &speakers);
462 speakers = DSSPEAKER_CONFIG(speakers);
463 if(speakers == DSSPEAKER_MONO)
465 else if(speakers == DSSPEAKER_STEREO || speakers == DSSPEAKER_HEADPHONE)
467 else if(speakers == DSSPEAKER_QUAD)
469 else if(speakers == DSSPEAKER_5POINT1)
471 else if(speakers == DSSPEAKER_7POINT1)
474 ERR(
"Unknown system speaker config: 0x%lx\n", speakers);
534 OutputType.Format.nBlockAlign = OutputType.Format.nChannels*OutputType.Format.wBitsPerSample/8;
535 OutputType.Format.nSamplesPerSec = device->
Frequency;
536 OutputType.Format.nAvgBytesPerSec = OutputType.Format.nSamplesPerSec*OutputType.Format.nBlockAlign;
537 OutputType.Format.cbSize = 0;
543 OutputType.Samples.wValidBitsPerSample = OutputType.Format.wBitsPerSample;
546 OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
548 OutputType.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
550 if(data->PrimaryBuffer)
551 IDirectSoundBuffer_Release(data->PrimaryBuffer);
552 data->PrimaryBuffer =
NULL;
556 if(SUCCEEDED(hr) && !data->PrimaryBuffer)
558 memset(&DSBDescription,0,
sizeof(DSBUFFERDESC));
559 DSBDescription.dwSize=
sizeof(DSBUFFERDESC);
560 DSBDescription.dwFlags=DSBCAPS_PRIMARYBUFFER;
561 hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->PrimaryBuffer,
NULL);
564 hr = IDirectSoundBuffer_SetFormat(data->PrimaryBuffer,&OutputType.Format);
576 memset(&DSBDescription,0,
sizeof(DSBUFFERDESC));
577 DSBDescription.dwSize=
sizeof(DSBUFFERDESC);
578 DSBDescription.dwFlags=DSBCAPS_CTRLPOSITIONNOTIFY|DSBCAPS_GETCURRENTPOSITION2|DSBCAPS_GLOBALFOCUS;
580 OutputType.Format.nBlockAlign;
581 DSBDescription.lpwfxFormat=&OutputType.Format;
582 hr = IDirectSound_CreateSoundBuffer(data->DS, &DSBDescription, &data->Buffer,
NULL);
592 hr = IDirectSoundBuffer_QueryInterface(data->Buffer, &IID_IDirectSoundNotify, (
LPVOID *)&data->Notifies);
601 OutputType.Format.nBlockAlign;
602 notifies[
i].hEventNotify = data->NotifyEvent;
604 if(IDirectSoundNotify_SetNotificationPositions(data->Notifies, device->
NumUpdates, notifies) != DS_OK)
611 if(data->Notifies !=
NULL)
612 IDirectSoundNotify_Release(data->Notifies);
613 data->Notifies =
NULL;
614 if(data->Buffer !=
NULL)
615 IDirectSoundBuffer_Release(data->Buffer);
617 if(data->PrimaryBuffer !=
NULL)
618 IDirectSoundBuffer_Release(data->PrimaryBuffer);
619 data->PrimaryBuffer =
NULL;
623 ResetEvent(data->NotifyEvent);
631 DSoundPlaybackData *
data = (DSoundPlaybackData*)device->
ExtraData;
634 if(data->thread ==
NULL)
652 IDirectSoundBuffer_Stop(data->Buffer);
660 DSCBUFFERDESC DSCBDescription;
668 hrcom = CoInitialize(
NULL);
671 ERR(
"Error enumerating DirectSound devices (%#x)!\n", (
unsigned int)hr);
693 if(i == NumCaptureDevices)
713 data =
calloc(1,
sizeof(DSoundCaptureData));
724 memset(&InputType, 0,
sizeof(InputType));
792 InputType.
SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
794 InputType.
SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
800 memset(&DSCBDescription, 0,
sizeof(DSCBUFFERDESC));
801 DSCBDescription.dwSize =
sizeof(DSCBUFFERDESC);
802 DSCBDescription.dwFlags = 0;
804 DSCBDescription.lpwfxFormat = &InputType.
Format;
806 hr = IDirectSoundCapture_CreateCaptureBuffer(data->DSC, &DSCBDescription, &data->DSCbuffer,
NULL);
811 if(data->Ring ==
NULL)
812 hr = DSERR_OUTOFMEMORY;
817 ERR(
"Device init failed: 0x%08lx\n", hr);
821 if(data->DSCbuffer !=
NULL)
822 IDirectSoundCaptureBuffer_Release(data->DSCbuffer);
823 data->DSCbuffer =
NULL;
825 IDirectSoundCapture_Release(data->DSC);
832 data->BufferBytes = DSCBDescription.dwBufferBytes;
848 if(data->DSCbuffer !=
NULL)
850 IDirectSoundCaptureBuffer_Stop(data->DSCbuffer);
851 IDirectSoundCaptureBuffer_Release(data->DSCbuffer);
852 data->DSCbuffer =
NULL;
855 IDirectSoundCapture_Release(data->DSC);
867 hr = IDirectSoundCaptureBuffer_Start(data->DSCbuffer, DSCBSTART_LOOPING);
870 ERR(
"start failed: 0x%08lx\n", hr);
880 hr = IDirectSoundCaptureBuffer_Stop(data->DSCbuffer);
883 ERR(
"stop failed: 0x%08lx\n", hr);
898 DWORD ReadCursor, LastCursor, BufferBytes, NumBytes;
899 VOID *ReadPtr1, *ReadPtr2;
900 DWORD ReadCnt1, ReadCnt2;
908 BufferBytes = data->BufferBytes;
909 LastCursor = data->Cursor;
911 hr = IDirectSoundCaptureBuffer_GetCurrentPosition(data->DSCbuffer,
NULL, &ReadCursor);
914 NumBytes = (ReadCursor-LastCursor + BufferBytes) % BufferBytes;
917 hr = IDirectSoundCaptureBuffer_Lock(data->DSCbuffer, LastCursor, NumBytes,
918 &ReadPtr1, &ReadCnt1,
919 &ReadPtr2, &ReadCnt2, 0);
926 hr = IDirectSoundCaptureBuffer_Unlock(data->DSCbuffer,
929 data->Cursor = (LastCursor+ReadCnt1+ReadCnt2) % BufferBytes;
934 ERR(
"update failed: 0x%08lx\n", hr);
977 NumPlaybackDevices = 0;
983 NumCaptureDevices = 0;
1002 NumPlaybackDevices = 0;
1006 ERR(
"Error enumerating DirectSound playback devices (%#x)!\n", (
unsigned int)hr);
1019 NumCaptureDevices = 0;
1022 hrcom = CoInitialize(
NULL);
1025 ERR(
"Error enumerating DirectSound capture devices (%#x)!\n", (
unsigned int)hr);
1031 if(SUCCEEDED(hrcom))
static ALuint NumCaptureDevices
static void DSoundCloseCapture(ALCdevice *device)
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
GLvoid **typedef void(GLAPIENTRY *PFNGLGETVERTEXATTRIBDVPROC)(GLuint
char * strdup(const char *inStr)
static BOOL CALLBACK DSoundEnumCaptureDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data)
static void DSoundStopPlayback(ALCdevice *device)
#define DirectSoundCaptureCreate
static ALCenum DSoundOpenPlayback(ALCdevice *device, const ALCchar *deviceName)
#define SPEAKER_FRONT_CENTER
#define SPEAKER_BACK_LEFT
#define SPEAKER_BACK_RIGHT
ALvoid aluMixData(ALCdevice *device, ALvoid *buffer, ALsizei size)
static ALCenum DSoundOpenCapture(ALCdevice *device, const ALCchar *deviceName)
ALint64 ALCdevice_GetLatencyDefault(ALCdevice *device)
EGLImageKHR EGLint * name
static const BackendFuncs DSoundFuncs
#define SPEAKER_FRONT_RIGHT
static DevMap * PlaybackDeviceList
#define DEVICE_SAMPLE_TYPE_REQUEST
ALsizei RingBufferSize(RingBuffer *ring)
static ALCboolean DSoundResetPlayback(ALCdevice *device)
void AppendCaptureDeviceList(const ALCchar *name)
ALvoid aluHandleDisconnect(ALCdevice *device)
#define SPEAKER_BACK_CENTER
#define DirectSoundCaptureEnumerateA
#define ALCdevice_Unlock(a)
struct RingBuffer RingBuffer
#define WAVE_FORMAT_EXTENSIBLE
#define SPEAKER_SIDE_LEFT
static IDirectSoundCapture ** ppDSC
static IDirectSound ** ppDS
typedef HANDLE(WINAPI *PFNWGLCREATEBUFFERREGIONARBPROC)(HDC hDC
ALuint StopThread(ALvoid *thread)
static ALCboolean DSoundLoad(void)
void SetDefaultWFXChannelOrder(ALCdevice *device)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
static ALCboolean DSoundStartPlayback(ALCdevice *device)
static HRESULT(WINAPI *pDirectSoundCreate)(LPCGUID pcGuidDevice
RingBuffer * CreateRingBuffer(ALsizei frame_size, ALsizei length)
static ALuint DSoundPlaybackProc(ALvoid *ptr)
#define DirectSoundEnumerateA
static BOOL CALLBACK DSoundEnumPlaybackDevices(LPGUID guid, LPCSTR desc, LPCSTR drvname, LPVOID data)
static void DSoundStartCapture(ALCdevice *device)
DEFINE_GUID(KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71)
static DevMap * CaptureDeviceList
union WAVEFORMATEXTENSIBLE::@63 Samples
enum DevFmtChannels FmtChans
typedef LPVOID(WINAPI *PFNWGLCREATEIMAGEBUFFERI3DPROC)(HDC hDC
#define DEVICE_CHANNELS_REQUEST
#define SPEAKER_LOW_FREQUENCY
static SDL_Thread * thread
static ALCuint DSoundAvailableSamples(ALCdevice *Device)
void ALCdevice_LockDefault(ALCdevice *device)
typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex
static ALuint NumPlaybackDevices
#define SPEAKER_SIDE_RIGHT
void alcDSoundProbe(enum DevProbe type)
static void DSoundClosePlayback(ALCdevice *device)
#define ALC_INVALID_VALUE
#define ALC_OUT_OF_MEMORY
static IDirectSound IUnknown * pUnkOuter
void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len)
#define DirectSoundCreate
ALCboolean alcDSoundInit(BackendFuncs *FuncList)
#define SPEAKER_FRONT_LEFT
static ALCenum DSoundCaptureSamples(ALCdevice *Device, ALCvoid *pBuffer, ALCuint lSamples)
static void DSoundStopCapture(ALCdevice *device)
const ALCchar * DevFmtTypeString(enum DevFmtType type)
void alcDSoundDeinit(void)
ALuint BytesFromDevFmt(enum DevFmtType type)
void DestroyRingBuffer(RingBuffer *ring)
typedef VOID(WINAPI *PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC)(HGLRC dstCtx
void ALCdevice_UnlockDefault(ALCdevice *device)
static __inline ALuint maxu(ALuint a, ALuint b)
void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len)
ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
#define ALCdevice_Lock(a)
void AppendAllDevicesList(const ALCchar *name)
ALvoid * StartThread(ALuint(*func)(ALvoid *), ALvoid *ptr)
static __inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
typedef BOOL(WINAPI *PFNWGLSETSTEREOEMITTERSTATE3DLPROC)(HDC hDC