14 #define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
16 #define DECL(x) { #x, (ALCvoid*)(x) }
18 const ALCchar
*funcName
;
21 DECL(alcCreateContext
),
22 DECL(alcMakeContextCurrent
),
23 DECL(alcProcessContext
),
24 DECL(alcSuspendContext
),
25 DECL(alcDestroyContext
),
26 DECL(alcGetCurrentContext
),
27 DECL(alcGetContextsDevice
),
31 DECL(alcIsExtensionPresent
),
32 DECL(alcGetProcAddress
),
33 DECL(alcGetEnumValue
),
36 DECL(alcCaptureOpenDevice
),
37 DECL(alcCaptureCloseDevice
),
38 DECL(alcCaptureStart
),
40 DECL(alcCaptureSamples
),
55 DECL(alIsExtensionPresent
),
56 DECL(alGetProcAddress
),
65 DECL(alGetListener3f
),
66 DECL(alGetListenerfv
),
68 DECL(alGetListener3i
),
69 DECL(alGetListeneriv
),
71 DECL(alDeleteSources
),
87 DECL(alSourceRewindv
),
93 DECL(alSourceQueueBuffers
),
94 DECL(alSourceUnqueueBuffers
),
96 DECL(alDeleteBuffers
),
111 DECL(alDopplerFactor
),
112 DECL(alDopplerVelocity
),
113 DECL(alSpeedOfSound
),
114 DECL(alDistanceModel
),
118 #define DECL(x) { #x, (x) }
119 static const struct {
120 const ALCchar
*enumName
;
122 } alcEnumerations
[] = {
127 DECL(ALC_MAJOR_VERSION
),
128 DECL(ALC_MINOR_VERSION
),
129 DECL(ALC_ATTRIBUTES_SIZE
),
130 DECL(ALC_ALL_ATTRIBUTES
),
131 DECL(ALC_DEFAULT_DEVICE_SPECIFIER
),
132 DECL(ALC_DEVICE_SPECIFIER
),
133 DECL(ALC_ALL_DEVICES_SPECIFIER
),
134 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER
),
135 DECL(ALC_EXTENSIONS
),
139 DECL(ALC_MONO_SOURCES
),
140 DECL(ALC_STEREO_SOURCES
),
141 DECL(ALC_CAPTURE_DEVICE_SPECIFIER
),
142 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
),
143 DECL(ALC_CAPTURE_SAMPLES
),
146 DECL(ALC_INVALID_DEVICE
),
147 DECL(ALC_INVALID_CONTEXT
),
148 DECL(ALC_INVALID_ENUM
),
149 DECL(ALC_INVALID_VALUE
),
150 DECL(ALC_OUT_OF_MEMORY
),
157 DECL(AL_SOURCE_RELATIVE
),
158 DECL(AL_CONE_INNER_ANGLE
),
159 DECL(AL_CONE_OUTER_ANGLE
),
169 DECL(AL_ORIENTATION
),
170 DECL(AL_REFERENCE_DISTANCE
),
171 DECL(AL_ROLLOFF_FACTOR
),
172 DECL(AL_CONE_OUTER_GAIN
),
173 DECL(AL_MAX_DISTANCE
),
175 DECL(AL_SAMPLE_OFFSET
),
176 DECL(AL_BYTE_OFFSET
),
177 DECL(AL_SOURCE_TYPE
),
180 DECL(AL_UNDETERMINED
),
182 DECL(AL_SOURCE_STATE
),
188 DECL(AL_BUFFERS_QUEUED
),
189 DECL(AL_BUFFERS_PROCESSED
),
191 DECL(AL_FORMAT_MONO8
),
192 DECL(AL_FORMAT_MONO16
),
193 DECL(AL_FORMAT_STEREO8
),
194 DECL(AL_FORMAT_STEREO16
),
206 DECL(AL_INVALID_NAME
),
207 DECL(AL_INVALID_ENUM
),
208 DECL(AL_INVALID_VALUE
),
209 DECL(AL_INVALID_OPERATION
),
210 DECL(AL_OUT_OF_MEMORY
),
217 DECL(AL_DOPPLER_FACTOR
),
218 DECL(AL_DOPPLER_VELOCITY
),
219 DECL(AL_DISTANCE_MODEL
),
220 DECL(AL_SPEED_OF_SOUND
),
222 DECL(AL_INVERSE_DISTANCE
),
223 DECL(AL_INVERSE_DISTANCE_CLAMPED
),
224 DECL(AL_LINEAR_DISTANCE
),
225 DECL(AL_LINEAR_DISTANCE_CLAMPED
),
226 DECL(AL_EXPONENT_DISTANCE
),
227 DECL(AL_EXPONENT_DISTANCE_CLAMPED
),
231 static const ALCchar alcNoError
[] = "No Error";
232 static const ALCchar alcErrInvalidDevice
[] = "Invalid Device";
233 static const ALCchar alcErrInvalidContext
[] = "Invalid Context";
234 static const ALCchar alcErrInvalidEnum
[] = "Invalid Enum";
235 static const ALCchar alcErrInvalidValue
[] = "Invalid Value";
236 static const ALCchar alcErrOutOfMemory
[] = "Out of Memory";
237 static const ALCchar alcExtensionList
[] =
238 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE";
240 static const ALCint alcMajorVersion
= 1;
241 static const ALCint alcMinorVersion
= 1;
244 static almtx_t EnumerationLock
;
245 static almtx_t ContextSwitchLock
;
247 static ATOMIC(ALCenum
) LastError
= ATOMIC_INIT_STATIC(ALC_NO_ERROR
);
248 static PtrIntMap DeviceIfaceMap
= PTRINTMAP_STATIC_INITIALIZE
;
249 static PtrIntMap ContextIfaceMap
= PTRINTMAP_STATIC_INITIALIZE
;
252 typedef struct EnumeratedList
{
258 static EnumeratedList DevicesList
= { NULL
, NULL
, NULL
, 0 };
259 static EnumeratedList AllDevicesList
= { NULL
, NULL
, NULL
, 0 };
260 static EnumeratedList CaptureDevicesList
= { NULL
, NULL
, NULL
, 0 };
262 static void ClearDeviceList(EnumeratedList
*list
)
264 al_free(list
->Names
);
266 list
->NamesEnd
= NULL
;
268 al_free(list
->Indicies
);
269 list
->Indicies
= NULL
;
273 static void AppendDeviceList(EnumeratedList
*list
, const ALCchar
*names
, ALint idx
)
275 const ALCchar
*name_end
= names
;
278 ALCint
*new_indicies
;
286 TRACE("Enumerated \"%s\", driver %d\n", name_end
, idx
);
288 name_end
+= strlen(name_end
)+1;
290 if(names
== name_end
)
293 len
= (list
->NamesEnd
- list
->Names
) + (name_end
- names
);
294 new_list
= al_calloc(DEF_ALIGN
, len
+ 1);
295 memcpy(new_list
, list
->Names
, list
->NamesEnd
- list
->Names
);
296 memcpy(new_list
+ (list
->NamesEnd
- list
->Names
), names
, name_end
- names
);
297 al_free(list
->Names
);
298 list
->Names
= new_list
;
299 list
->NamesEnd
= list
->Names
+ len
;
301 new_indicies
= al_calloc(16, sizeof(ALCint
)*(list
->IndexSize
+ count
));
302 for(i
= 0;i
< list
->IndexSize
;i
++)
303 new_indicies
[i
] = list
->Indicies
[i
];
304 for(i
= 0;i
< count
;i
++)
305 new_indicies
[list
->IndexSize
+i
] = idx
;
306 al_free(list
->Indicies
);
307 list
->Indicies
= new_indicies
;
308 list
->IndexSize
+= count
;
311 static ALint
GetDriverIndexForName(const EnumeratedList
*list
, const ALCchar
*name
)
313 const ALCchar
*devnames
= list
->Names
;
314 const ALCint
*index
= list
->Indicies
;
316 while(devnames
&& *devnames
)
318 if(strcmp(name
, devnames
) == 0)
320 devnames
+= strlen(devnames
)+1;
328 almtx_init(&EnumerationLock
, almtx_recursive
);
329 almtx_init(&ContextSwitchLock
, almtx_plain
);
332 void ReleaseALC(void)
334 ClearDeviceList(&DevicesList
);
335 ClearDeviceList(&AllDevicesList
);
336 ClearDeviceList(&CaptureDevicesList
);
338 ResetPtrIntMap(&ContextIfaceMap
);
339 ResetPtrIntMap(&DeviceIfaceMap
);
341 almtx_destroy(&ContextSwitchLock
);
342 almtx_destroy(&EnumerationLock
);
346 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*devicename
)
351 /* Prior to the enumeration extension, apps would hardcode these names as a
352 * quality hint for the wrapper driver. Ignore them since there's no sane
355 if(devicename
&& (devicename
[0] == '\0' ||
356 strcmp(devicename
, "DirectSound3D") == 0 ||
357 strcmp(devicename
, "DirectSound") == 0 ||
358 strcmp(devicename
, "MMSYSTEM") == 0))
362 almtx_lock(&EnumerationLock
);
363 if(!DevicesList
.Names
)
364 (void)alcGetString(NULL
, ALC_DEVICE_SPECIFIER
);
365 idx
= GetDriverIndexForName(&DevicesList
, devicename
);
368 if(!AllDevicesList
.Names
)
369 (void)alcGetString(NULL
, ALC_ALL_DEVICES_SPECIFIER
);
370 idx
= GetDriverIndexForName(&AllDevicesList
, devicename
);
373 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_VALUE
);
374 almtx_unlock(&EnumerationLock
);
378 almtx_unlock(&EnumerationLock
);
383 for(i
= 0;i
< DriverListSize
;i
++)
385 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
386 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATION_EXT"))
394 device
= DriverList
[idx
].alcOpenDevice(devicename
);
397 if(InsertPtrIntMapEntry(&DeviceIfaceMap
, device
, idx
) != ALC_NO_ERROR
)
399 DriverList
[idx
].alcCloseDevice(device
);
407 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
411 if(!device
|| (idx
=LookupPtrIntMapKey(&DeviceIfaceMap
, device
)) < 0)
413 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
416 if(!DriverList
[idx
].alcCloseDevice(device
))
418 RemovePtrIntMapKey(&DeviceIfaceMap
, device
);
423 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrlist
)
428 if(!device
|| (idx
=LookupPtrIntMapKey(&DeviceIfaceMap
, device
)) < 0)
430 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
433 context
= DriverList
[idx
].alcCreateContext(device
, attrlist
);
436 if(InsertPtrIntMapEntry(&ContextIfaceMap
, context
, idx
) != ALC_NO_ERROR
)
438 DriverList
[idx
].alcDestroyContext(context
);
446 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
450 almtx_lock(&ContextSwitchLock
);
453 idx
= LookupPtrIntMapKey(&ContextIfaceMap
, context
);
456 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
457 almtx_unlock(&ContextSwitchLock
);
460 if(!DriverList
[idx
].alcMakeContextCurrent(context
))
462 almtx_unlock(&ContextSwitchLock
);
467 /* Unset the context from the old driver if it's different from the new
472 DriverIface
*oldiface
= ATOMIC_EXCHANGE_PTR_SEQ(&CurrentCtxDriver
, NULL
);
473 if(oldiface
) oldiface
->alcMakeContextCurrent(NULL
);
477 DriverIface
*oldiface
= ATOMIC_EXCHANGE_PTR_SEQ(&CurrentCtxDriver
, &DriverList
[idx
]);
478 if(oldiface
&& oldiface
!= &DriverList
[idx
])
479 oldiface
->alcMakeContextCurrent(NULL
);
481 almtx_unlock(&ContextSwitchLock
);
486 ALC_API
void ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
490 ALint idx
= LookupPtrIntMapKey(&ContextIfaceMap
, context
);
492 return DriverList
[idx
].alcProcessContext(context
);
494 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
497 ALC_API
void ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
501 ALint idx
= LookupPtrIntMapKey(&ContextIfaceMap
, context
);
503 return DriverList
[idx
].alcSuspendContext(context
);
505 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
508 ALC_API
void ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
512 if(!context
|| (idx
=LookupPtrIntMapKey(&ContextIfaceMap
, context
)) < 0)
514 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
518 DriverList
[idx
].alcDestroyContext(context
);
519 RemovePtrIntMapKey(&ContextIfaceMap
, context
);
522 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
524 DriverIface
*iface
= ATOMIC_LOAD_SEQ(&CurrentCtxDriver
);
525 return iface
? iface
->alcGetCurrentContext() : NULL
;
528 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*context
)
532 ALint idx
= LookupPtrIntMapKey(&ContextIfaceMap
, context
);
534 return DriverList
[idx
].alcGetContextsDevice(context
);
536 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
541 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
545 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
546 if(idx
< 0) return ALC_INVALID_DEVICE
;
547 return DriverList
[idx
].alcGetError(device
);
549 return ATOMIC_EXCHANGE_SEQ(&LastError
, ALC_NO_ERROR
);
552 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extname
)
559 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
562 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
565 return DriverList
[idx
].alcIsExtensionPresent(device
, extname
);
568 len
= strlen(extname
);
569 ptr
= alcExtensionList
;
572 if(strncasecmp(ptr
, extname
, len
) == 0 && (ptr
[len
] == '\0' || isspace(ptr
[len
])))
574 if((ptr
=strchr(ptr
, ' ')) != NULL
)
578 } while(isspace(*ptr
));
584 ALC_API
void* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcname
)
590 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
593 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
596 return DriverList
[idx
].alcGetProcAddress(device
, funcname
);
599 for(i
= 0;i
< COUNTOF(alcFunctions
);i
++)
601 if(strcmp(funcname
, alcFunctions
[i
].funcName
) == 0)
602 return alcFunctions
[i
].address
;
607 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumname
)
613 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
616 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
619 return DriverList
[idx
].alcGetEnumValue(device
, enumname
);
622 for(i
= 0;i
< COUNTOF(alcEnumerations
);i
++)
624 if(strcmp(enumname
, alcEnumerations
[i
].enumName
) == 0)
625 return alcEnumerations
[i
].value
;
630 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*device
, ALCenum param
)
636 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
639 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
642 return DriverList
[idx
].alcGetString(device
, param
);
649 case ALC_INVALID_ENUM
:
650 return alcErrInvalidEnum
;
651 case ALC_INVALID_VALUE
:
652 return alcErrInvalidValue
;
653 case ALC_INVALID_DEVICE
:
654 return alcErrInvalidDevice
;
655 case ALC_INVALID_CONTEXT
:
656 return alcErrInvalidContext
;
657 case ALC_OUT_OF_MEMORY
:
658 return alcErrOutOfMemory
;
660 return alcExtensionList
;
662 case ALC_DEVICE_SPECIFIER
:
663 almtx_lock(&EnumerationLock
);
664 ClearDeviceList(&DevicesList
);
665 for(i
= 0;i
< DriverListSize
;i
++)
667 /* Only enumerate names from drivers that support it. */
668 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
669 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATION_EXT"))
670 AppendDeviceList(&DevicesList
,
671 DriverList
[i
].alcGetString(NULL
, ALC_DEVICE_SPECIFIER
), i
674 almtx_unlock(&EnumerationLock
);
675 return DevicesList
.Names
;
677 case ALC_ALL_DEVICES_SPECIFIER
:
678 almtx_lock(&EnumerationLock
);
679 ClearDeviceList(&AllDevicesList
);
680 for(i
= 0;i
< DriverListSize
;i
++)
682 /* If the driver doesn't support ALC_ENUMERATE_ALL_EXT, substitute
683 * standard enumeration.
685 if(DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATE_ALL_EXT"))
686 AppendDeviceList(&AllDevicesList
,
687 DriverList
[i
].alcGetString(NULL
, ALC_ALL_DEVICES_SPECIFIER
), i
689 else if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
690 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATION_EXT"))
691 AppendDeviceList(&AllDevicesList
,
692 DriverList
[i
].alcGetString(NULL
, ALC_DEVICE_SPECIFIER
), i
695 almtx_unlock(&EnumerationLock
);
696 return AllDevicesList
.Names
;
698 case ALC_CAPTURE_DEVICE_SPECIFIER
:
699 almtx_lock(&EnumerationLock
);
700 ClearDeviceList(&CaptureDevicesList
);
701 for(i
= 0;i
< DriverListSize
;i
++)
703 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
704 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_EXT_CAPTURE"))
705 AppendDeviceList(&CaptureDevicesList
,
706 DriverList
[i
].alcGetString(NULL
, ALC_CAPTURE_DEVICE_SPECIFIER
), i
709 almtx_unlock(&EnumerationLock
);
710 return CaptureDevicesList
.Names
;
712 case ALC_DEFAULT_DEVICE_SPECIFIER
:
713 for(i
= 0;i
< DriverListSize
;i
++)
715 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
716 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATION_EXT"))
717 return DriverList
[i
].alcGetString(NULL
, ALC_DEFAULT_DEVICE_SPECIFIER
);
721 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
722 for(i
= 0;i
< DriverListSize
;i
++)
724 if(DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATE_ALL_EXT"))
725 return DriverList
[i
].alcGetString(NULL
, ALC_DEFAULT_ALL_DEVICES_SPECIFIER
);
729 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
730 for(i
= 0;i
< DriverListSize
;i
++)
732 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
733 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_EXT_CAPTURE"))
734 return DriverList
[i
].alcGetString(NULL
, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
);
739 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_ENUM
);
745 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
749 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
752 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
755 return DriverList
[idx
].alcGetIntegerv(device
, param
, size
, values
);
758 if(size
<= 0 || values
== NULL
)
760 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_VALUE
);
766 case ALC_MAJOR_VERSION
:
769 values
[0] = alcMajorVersion
;
773 case ALC_MINOR_VERSION
:
776 values
[0] = alcMinorVersion
;
779 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_VALUE
);
782 case ALC_ATTRIBUTES_SIZE
:
783 case ALC_ALL_ATTRIBUTES
:
787 case ALC_MONO_SOURCES
:
788 case ALC_STEREO_SOURCES
:
789 case ALC_CAPTURE_SAMPLES
:
790 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
794 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_ENUM
);
800 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*devicename
, ALCuint frequency
, ALCenum format
, ALCsizei buffersize
)
805 if(devicename
&& devicename
[0] == '\0')
809 almtx_lock(&EnumerationLock
);
810 if(!CaptureDevicesList
.Names
)
811 (void)alcGetString(NULL
, ALC_CAPTURE_DEVICE_SPECIFIER
);
812 idx
= GetDriverIndexForName(&CaptureDevicesList
, devicename
);
815 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_VALUE
);
816 almtx_unlock(&EnumerationLock
);
819 almtx_unlock(&EnumerationLock
);
824 for(i
= 0;i
< DriverListSize
;i
++)
826 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
827 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_EXT_CAPTURE"))
835 device
= DriverList
[idx
].alcCaptureOpenDevice(devicename
, frequency
, format
, buffersize
);
838 if(InsertPtrIntMapEntry(&DeviceIfaceMap
, device
, idx
) != ALC_NO_ERROR
)
840 DriverList
[idx
].alcCaptureCloseDevice(device
);
848 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
852 if(!device
|| (idx
=LookupPtrIntMapKey(&DeviceIfaceMap
, device
)) < 0)
854 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
857 if(!DriverList
[idx
].alcCaptureCloseDevice(device
))
859 RemovePtrIntMapKey(&DeviceIfaceMap
, device
);
863 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
867 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
869 return DriverList
[idx
].alcCaptureStart(device
);
871 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
874 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
878 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
880 return DriverList
[idx
].alcCaptureStop(device
);
882 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
885 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
889 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
891 return DriverList
[idx
].alcCaptureSamples(device
, buffer
, samples
);
893 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);