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 TRACE("Found driver %d for name \"%s\"\n", *index
, name
);
323 devnames
+= strlen(devnames
)+1;
326 TRACE("Failed to find driver for name \"%s\"\n", name
);
332 almtx_init(&EnumerationLock
, almtx_recursive
);
333 almtx_init(&ContextSwitchLock
, almtx_plain
);
336 void ReleaseALC(void)
338 ClearDeviceList(&DevicesList
);
339 ClearDeviceList(&AllDevicesList
);
340 ClearDeviceList(&CaptureDevicesList
);
342 ResetPtrIntMap(&ContextIfaceMap
);
343 ResetPtrIntMap(&DeviceIfaceMap
);
345 almtx_destroy(&ContextSwitchLock
);
346 almtx_destroy(&EnumerationLock
);
350 ALC_API ALCdevice
* ALC_APIENTRY
alcOpenDevice(const ALCchar
*devicename
)
352 ALCdevice
*device
= NULL
;
355 /* Prior to the enumeration extension, apps would hardcode these names as a
356 * quality hint for the wrapper driver. Ignore them since there's no sane
359 if(devicename
&& (devicename
[0] == '\0' ||
360 strcmp(devicename
, "DirectSound3D") == 0 ||
361 strcmp(devicename
, "DirectSound") == 0 ||
362 strcmp(devicename
, "MMSYSTEM") == 0))
366 almtx_lock(&EnumerationLock
);
367 if(!DevicesList
.Names
)
368 (void)alcGetString(NULL
, ALC_DEVICE_SPECIFIER
);
369 idx
= GetDriverIndexForName(&DevicesList
, devicename
);
372 if(!AllDevicesList
.Names
)
373 (void)alcGetString(NULL
, ALC_ALL_DEVICES_SPECIFIER
);
374 idx
= GetDriverIndexForName(&AllDevicesList
, devicename
);
376 almtx_unlock(&EnumerationLock
);
378 device
= DriverList
[idx
].alcOpenDevice(devicename
);
379 else for(idx
= 0;idx
< DriverListSize
;idx
++)
381 device
= DriverList
[idx
].alcOpenDevice(devicename
);
388 for(i
= 0;i
< DriverListSize
;i
++)
390 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
391 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATION_EXT"))
394 device
= DriverList
[idx
].alcOpenDevice(NULL
);
402 if(InsertPtrIntMapEntry(&DeviceIfaceMap
, device
, idx
) != ALC_NO_ERROR
)
404 DriverList
[idx
].alcCloseDevice(device
);
412 ALC_API ALCboolean ALC_APIENTRY
alcCloseDevice(ALCdevice
*device
)
416 if(!device
|| (idx
=LookupPtrIntMapKey(&DeviceIfaceMap
, device
)) < 0)
418 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
421 if(!DriverList
[idx
].alcCloseDevice(device
))
423 RemovePtrIntMapKey(&DeviceIfaceMap
, device
);
428 ALC_API ALCcontext
* ALC_APIENTRY
alcCreateContext(ALCdevice
*device
, const ALCint
*attrlist
)
433 if(!device
|| (idx
=LookupPtrIntMapKey(&DeviceIfaceMap
, device
)) < 0)
435 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
438 context
= DriverList
[idx
].alcCreateContext(device
, attrlist
);
441 if(InsertPtrIntMapEntry(&ContextIfaceMap
, context
, idx
) != ALC_NO_ERROR
)
443 DriverList
[idx
].alcDestroyContext(context
);
451 ALC_API ALCboolean ALC_APIENTRY
alcMakeContextCurrent(ALCcontext
*context
)
455 almtx_lock(&ContextSwitchLock
);
458 idx
= LookupPtrIntMapKey(&ContextIfaceMap
, context
);
461 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
462 almtx_unlock(&ContextSwitchLock
);
465 if(!DriverList
[idx
].alcMakeContextCurrent(context
))
467 almtx_unlock(&ContextSwitchLock
);
472 /* Unset the context from the old driver if it's different from the new
477 DriverIface
*oldiface
= ATOMIC_EXCHANGE_PTR_SEQ(&CurrentCtxDriver
, NULL
);
478 if(oldiface
) oldiface
->alcMakeContextCurrent(NULL
);
482 DriverIface
*oldiface
= ATOMIC_EXCHANGE_PTR_SEQ(&CurrentCtxDriver
, &DriverList
[idx
]);
483 if(oldiface
&& oldiface
!= &DriverList
[idx
])
484 oldiface
->alcMakeContextCurrent(NULL
);
486 almtx_unlock(&ContextSwitchLock
);
491 ALC_API
void ALC_APIENTRY
alcProcessContext(ALCcontext
*context
)
495 ALint idx
= LookupPtrIntMapKey(&ContextIfaceMap
, context
);
497 return DriverList
[idx
].alcProcessContext(context
);
499 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
502 ALC_API
void ALC_APIENTRY
alcSuspendContext(ALCcontext
*context
)
506 ALint idx
= LookupPtrIntMapKey(&ContextIfaceMap
, context
);
508 return DriverList
[idx
].alcSuspendContext(context
);
510 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
513 ALC_API
void ALC_APIENTRY
alcDestroyContext(ALCcontext
*context
)
517 if(!context
|| (idx
=LookupPtrIntMapKey(&ContextIfaceMap
, context
)) < 0)
519 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
523 DriverList
[idx
].alcDestroyContext(context
);
524 RemovePtrIntMapKey(&ContextIfaceMap
, context
);
527 ALC_API ALCcontext
* ALC_APIENTRY
alcGetCurrentContext(void)
529 DriverIface
*iface
= ATOMIC_LOAD_SEQ(&CurrentCtxDriver
);
530 return iface
? iface
->alcGetCurrentContext() : NULL
;
533 ALC_API ALCdevice
* ALC_APIENTRY
alcGetContextsDevice(ALCcontext
*context
)
537 ALint idx
= LookupPtrIntMapKey(&ContextIfaceMap
, context
);
539 return DriverList
[idx
].alcGetContextsDevice(context
);
541 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_CONTEXT
);
546 ALC_API ALCenum ALC_APIENTRY
alcGetError(ALCdevice
*device
)
550 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
551 if(idx
< 0) return ALC_INVALID_DEVICE
;
552 return DriverList
[idx
].alcGetError(device
);
554 return ATOMIC_EXCHANGE_SEQ(&LastError
, ALC_NO_ERROR
);
557 ALC_API ALCboolean ALC_APIENTRY
alcIsExtensionPresent(ALCdevice
*device
, const ALCchar
*extname
)
564 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
567 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
570 return DriverList
[idx
].alcIsExtensionPresent(device
, extname
);
573 len
= strlen(extname
);
574 ptr
= alcExtensionList
;
577 if(strncasecmp(ptr
, extname
, len
) == 0 && (ptr
[len
] == '\0' || isspace(ptr
[len
])))
579 if((ptr
=strchr(ptr
, ' ')) != NULL
)
583 } while(isspace(*ptr
));
589 ALC_API
void* ALC_APIENTRY
alcGetProcAddress(ALCdevice
*device
, const ALCchar
*funcname
)
595 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
598 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
601 return DriverList
[idx
].alcGetProcAddress(device
, funcname
);
604 for(i
= 0;i
< COUNTOF(alcFunctions
);i
++)
606 if(strcmp(funcname
, alcFunctions
[i
].funcName
) == 0)
607 return alcFunctions
[i
].address
;
612 ALC_API ALCenum ALC_APIENTRY
alcGetEnumValue(ALCdevice
*device
, const ALCchar
*enumname
)
618 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
621 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
624 return DriverList
[idx
].alcGetEnumValue(device
, enumname
);
627 for(i
= 0;i
< COUNTOF(alcEnumerations
);i
++)
629 if(strcmp(enumname
, alcEnumerations
[i
].enumName
) == 0)
630 return alcEnumerations
[i
].value
;
635 ALC_API
const ALCchar
* ALC_APIENTRY
alcGetString(ALCdevice
*device
, ALCenum param
)
641 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
644 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
647 return DriverList
[idx
].alcGetString(device
, param
);
654 case ALC_INVALID_ENUM
:
655 return alcErrInvalidEnum
;
656 case ALC_INVALID_VALUE
:
657 return alcErrInvalidValue
;
658 case ALC_INVALID_DEVICE
:
659 return alcErrInvalidDevice
;
660 case ALC_INVALID_CONTEXT
:
661 return alcErrInvalidContext
;
662 case ALC_OUT_OF_MEMORY
:
663 return alcErrOutOfMemory
;
665 return alcExtensionList
;
667 case ALC_DEVICE_SPECIFIER
:
668 almtx_lock(&EnumerationLock
);
669 ClearDeviceList(&DevicesList
);
670 for(i
= 0;i
< DriverListSize
;i
++)
672 /* Only enumerate names from drivers that support it. */
673 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
674 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATION_EXT"))
675 AppendDeviceList(&DevicesList
,
676 DriverList
[i
].alcGetString(NULL
, ALC_DEVICE_SPECIFIER
), i
679 almtx_unlock(&EnumerationLock
);
680 return DevicesList
.Names
;
682 case ALC_ALL_DEVICES_SPECIFIER
:
683 almtx_lock(&EnumerationLock
);
684 ClearDeviceList(&AllDevicesList
);
685 for(i
= 0;i
< DriverListSize
;i
++)
687 /* If the driver doesn't support ALC_ENUMERATE_ALL_EXT, substitute
688 * standard enumeration.
690 if(DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATE_ALL_EXT"))
691 AppendDeviceList(&AllDevicesList
,
692 DriverList
[i
].alcGetString(NULL
, ALC_ALL_DEVICES_SPECIFIER
), i
694 else if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
695 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATION_EXT"))
696 AppendDeviceList(&AllDevicesList
,
697 DriverList
[i
].alcGetString(NULL
, ALC_DEVICE_SPECIFIER
), i
700 almtx_unlock(&EnumerationLock
);
701 return AllDevicesList
.Names
;
703 case ALC_CAPTURE_DEVICE_SPECIFIER
:
704 almtx_lock(&EnumerationLock
);
705 ClearDeviceList(&CaptureDevicesList
);
706 for(i
= 0;i
< DriverListSize
;i
++)
708 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
709 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_EXT_CAPTURE"))
710 AppendDeviceList(&CaptureDevicesList
,
711 DriverList
[i
].alcGetString(NULL
, ALC_CAPTURE_DEVICE_SPECIFIER
), i
714 almtx_unlock(&EnumerationLock
);
715 return CaptureDevicesList
.Names
;
717 case ALC_DEFAULT_DEVICE_SPECIFIER
:
718 for(i
= 0;i
< DriverListSize
;i
++)
720 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
721 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATION_EXT"))
722 return DriverList
[i
].alcGetString(NULL
, ALC_DEFAULT_DEVICE_SPECIFIER
);
726 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER
:
727 for(i
= 0;i
< DriverListSize
;i
++)
729 if(DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_ENUMERATE_ALL_EXT"))
730 return DriverList
[i
].alcGetString(NULL
, ALC_DEFAULT_ALL_DEVICES_SPECIFIER
);
734 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
:
735 for(i
= 0;i
< DriverListSize
;i
++)
737 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
738 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_EXT_CAPTURE"))
739 return DriverList
[i
].alcGetString(NULL
, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER
);
744 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_ENUM
);
750 ALC_API
void ALC_APIENTRY
alcGetIntegerv(ALCdevice
*device
, ALCenum param
, ALCsizei size
, ALCint
*values
)
754 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
757 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
760 return DriverList
[idx
].alcGetIntegerv(device
, param
, size
, values
);
763 if(size
<= 0 || values
== NULL
)
765 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_VALUE
);
771 case ALC_MAJOR_VERSION
:
774 values
[0] = alcMajorVersion
;
778 case ALC_MINOR_VERSION
:
781 values
[0] = alcMinorVersion
;
784 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_VALUE
);
787 case ALC_ATTRIBUTES_SIZE
:
788 case ALC_ALL_ATTRIBUTES
:
792 case ALC_MONO_SOURCES
:
793 case ALC_STEREO_SOURCES
:
794 case ALC_CAPTURE_SAMPLES
:
795 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
799 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_ENUM
);
805 ALC_API ALCdevice
* ALC_APIENTRY
alcCaptureOpenDevice(const ALCchar
*devicename
, ALCuint frequency
, ALCenum format
, ALCsizei buffersize
)
807 ALCdevice
*device
= NULL
;
810 if(devicename
&& devicename
[0] == '\0')
814 almtx_lock(&EnumerationLock
);
815 if(!CaptureDevicesList
.Names
)
816 (void)alcGetString(NULL
, ALC_CAPTURE_DEVICE_SPECIFIER
);
817 idx
= GetDriverIndexForName(&CaptureDevicesList
, devicename
);
818 almtx_unlock(&EnumerationLock
);
820 device
= DriverList
[idx
].alcCaptureOpenDevice(
821 devicename
, frequency
, format
, buffersize
823 else for(idx
= 0;idx
< DriverListSize
;idx
++)
825 device
= DriverList
[idx
].alcCaptureOpenDevice(
826 devicename
, frequency
, format
, buffersize
834 for(i
= 0;i
< DriverListSize
;i
++)
836 if(DriverList
[i
].ALCVer
>= MAKE_ALC_VER(1, 1) ||
837 DriverList
[i
].alcIsExtensionPresent(NULL
, "ALC_EXT_CAPTURE"))
840 device
= DriverList
[idx
].alcCaptureOpenDevice(
841 NULL
, frequency
, format
, buffersize
850 if(InsertPtrIntMapEntry(&DeviceIfaceMap
, device
, idx
) != ALC_NO_ERROR
)
852 DriverList
[idx
].alcCaptureCloseDevice(device
);
860 ALC_API ALCboolean ALC_APIENTRY
alcCaptureCloseDevice(ALCdevice
*device
)
864 if(!device
|| (idx
=LookupPtrIntMapKey(&DeviceIfaceMap
, device
)) < 0)
866 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
869 if(!DriverList
[idx
].alcCaptureCloseDevice(device
))
871 RemovePtrIntMapKey(&DeviceIfaceMap
, device
);
875 ALC_API
void ALC_APIENTRY
alcCaptureStart(ALCdevice
*device
)
879 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
881 return DriverList
[idx
].alcCaptureStart(device
);
883 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
886 ALC_API
void ALC_APIENTRY
alcCaptureStop(ALCdevice
*device
)
890 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
892 return DriverList
[idx
].alcCaptureStop(device
);
894 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);
897 ALC_API
void ALC_APIENTRY
alcCaptureSamples(ALCdevice
*device
, ALCvoid
*buffer
, ALCsizei samples
)
901 ALint idx
= LookupPtrIntMapKey(&DeviceIfaceMap
, device
);
903 return DriverList
[idx
].alcCaptureSamples(device
, buffer
, samples
);
905 ATOMIC_STORE_SEQ(&LastError
, ALC_INVALID_DEVICE
);