Don't pass the device to HRTF methods
[openal-soft.git] / Alc / ALc.c
blob1b3e3ba8a8a5815eafc724b207e3465cbbc79660
1 /**
2 * OpenAL cross platform audio library
3 * Copyright (C) 1999-2007 by authors.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 * Or go to http://www.gnu.org/copyleft/lgpl.html
21 #include "config.h"
23 #include <math.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <memory.h>
27 #include <ctype.h>
28 #include <signal.h>
30 #include "alMain.h"
31 #include "alSource.h"
32 #include "alListener.h"
33 #include "alThunk.h"
34 #include "alSource.h"
35 #include "alBuffer.h"
36 #include "alAuxEffectSlot.h"
37 #include "alError.h"
38 #include "alMidi.h"
39 #include "bs2b.h"
40 #include "alu.h"
42 #include "compat.h"
43 #include "threads.h"
44 #include "alstring.h"
46 #include "backends/base.h"
47 #include "midi/base.h"
50 /************************************************
51 * Backends
52 ************************************************/
53 struct BackendInfo {
54 const char *name;
55 ALCbackendFactory* (*getFactory)(void);
56 ALCboolean (*Init)(BackendFuncs*);
57 void (*Deinit)(void);
58 void (*Probe)(enum DevProbe);
59 BackendFuncs Funcs;
62 #define EmptyFuncs { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
63 static struct BackendInfo BackendList[] = {
64 #ifdef HAVE_PULSEAUDIO
65 { "pulse", ALCpulseBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
66 #endif
67 #ifdef HAVE_ALSA
68 { "alsa", ALCalsaBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
69 #endif
70 #ifdef HAVE_COREAUDIO
71 { "core", NULL, alc_ca_init, alc_ca_deinit, alc_ca_probe, EmptyFuncs },
72 #endif
73 #ifdef HAVE_OSS
74 { "oss", ALCossBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
75 #endif
76 #ifdef HAVE_SOLARIS
77 { "solaris", NULL, alc_solaris_init, alc_solaris_deinit, alc_solaris_probe, EmptyFuncs },
78 #endif
79 #ifdef HAVE_SNDIO
80 { "sndio", NULL, alc_sndio_init, alc_sndio_deinit, alc_sndio_probe, EmptyFuncs },
81 #endif
82 #ifdef HAVE_QSA
83 { "qsa", NULL, alc_qsa_init, alc_qsa_deinit, alc_qsa_probe, EmptyFuncs },
84 #endif
85 #ifdef HAVE_MMDEVAPI
86 { "mmdevapi", ALCmmdevBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
87 #endif
88 #ifdef HAVE_DSOUND
89 { "dsound", ALCdsoundBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
90 #endif
91 #ifdef HAVE_WINMM
92 { "winmm", NULL, alcWinMMInit, alcWinMMDeinit, alcWinMMProbe, EmptyFuncs },
93 #endif
94 #ifdef HAVE_PORTAUDIO
95 { "port", NULL, alc_pa_init, alc_pa_deinit, alc_pa_probe, EmptyFuncs },
96 #endif
97 #ifdef HAVE_OPENSL
98 { "opensl", NULL, alc_opensl_init, alc_opensl_deinit, alc_opensl_probe, EmptyFuncs },
99 #endif
101 { "null", ALCnullBackendFactory_getFactory, NULL, NULL, NULL, EmptyFuncs },
102 #ifdef HAVE_WAVE
103 { "wave", NULL, alc_wave_init, alc_wave_deinit, alc_wave_probe, EmptyFuncs },
104 #endif
106 { NULL, NULL, NULL, NULL, NULL, EmptyFuncs }
108 #undef EmptyFuncs
110 static struct BackendInfo PlaybackBackend;
111 static struct BackendInfo CaptureBackend;
114 /************************************************
115 * Functions, enums, and errors
116 ************************************************/
117 typedef struct ALCfunction {
118 const ALCchar *funcName;
119 ALCvoid *address;
120 } ALCfunction;
122 typedef struct ALCenums {
123 const ALCchar *enumName;
124 ALCenum value;
125 } ALCenums;
127 #define DECL(x) { #x, (ALCvoid*)(x) }
128 static const ALCfunction alcFunctions[] = {
129 DECL(alcCreateContext),
130 DECL(alcMakeContextCurrent),
131 DECL(alcProcessContext),
132 DECL(alcSuspendContext),
133 DECL(alcDestroyContext),
134 DECL(alcGetCurrentContext),
135 DECL(alcGetContextsDevice),
136 DECL(alcOpenDevice),
137 DECL(alcCloseDevice),
138 DECL(alcGetError),
139 DECL(alcIsExtensionPresent),
140 DECL(alcGetProcAddress),
141 DECL(alcGetEnumValue),
142 DECL(alcGetString),
143 DECL(alcGetIntegerv),
144 DECL(alcCaptureOpenDevice),
145 DECL(alcCaptureCloseDevice),
146 DECL(alcCaptureStart),
147 DECL(alcCaptureStop),
148 DECL(alcCaptureSamples),
150 DECL(alcSetThreadContext),
151 DECL(alcGetThreadContext),
153 DECL(alcLoopbackOpenDeviceSOFT),
154 DECL(alcIsRenderFormatSupportedSOFT),
155 DECL(alcRenderSamplesSOFT),
157 DECL(alcDevicePauseSOFT),
158 DECL(alcDeviceResumeSOFT),
160 DECL(alcGetInteger64vSOFT),
162 DECL(alEnable),
163 DECL(alDisable),
164 DECL(alIsEnabled),
165 DECL(alGetString),
166 DECL(alGetBooleanv),
167 DECL(alGetIntegerv),
168 DECL(alGetFloatv),
169 DECL(alGetDoublev),
170 DECL(alGetBoolean),
171 DECL(alGetInteger),
172 DECL(alGetFloat),
173 DECL(alGetDouble),
174 DECL(alGetError),
175 DECL(alIsExtensionPresent),
176 DECL(alGetProcAddress),
177 DECL(alGetEnumValue),
178 DECL(alListenerf),
179 DECL(alListener3f),
180 DECL(alListenerfv),
181 DECL(alListeneri),
182 DECL(alListener3i),
183 DECL(alListeneriv),
184 DECL(alGetListenerf),
185 DECL(alGetListener3f),
186 DECL(alGetListenerfv),
187 DECL(alGetListeneri),
188 DECL(alGetListener3i),
189 DECL(alGetListeneriv),
190 DECL(alGenSources),
191 DECL(alDeleteSources),
192 DECL(alIsSource),
193 DECL(alSourcef),
194 DECL(alSource3f),
195 DECL(alSourcefv),
196 DECL(alSourcei),
197 DECL(alSource3i),
198 DECL(alSourceiv),
199 DECL(alGetSourcef),
200 DECL(alGetSource3f),
201 DECL(alGetSourcefv),
202 DECL(alGetSourcei),
203 DECL(alGetSource3i),
204 DECL(alGetSourceiv),
205 DECL(alSourcePlayv),
206 DECL(alSourceStopv),
207 DECL(alSourceRewindv),
208 DECL(alSourcePausev),
209 DECL(alSourcePlay),
210 DECL(alSourceStop),
211 DECL(alSourceRewind),
212 DECL(alSourcePause),
213 DECL(alSourceQueueBuffers),
214 DECL(alSourceUnqueueBuffers),
215 DECL(alGenBuffers),
216 DECL(alDeleteBuffers),
217 DECL(alIsBuffer),
218 DECL(alBufferData),
219 DECL(alBufferf),
220 DECL(alBuffer3f),
221 DECL(alBufferfv),
222 DECL(alBufferi),
223 DECL(alBuffer3i),
224 DECL(alBufferiv),
225 DECL(alGetBufferf),
226 DECL(alGetBuffer3f),
227 DECL(alGetBufferfv),
228 DECL(alGetBufferi),
229 DECL(alGetBuffer3i),
230 DECL(alGetBufferiv),
231 DECL(alDopplerFactor),
232 DECL(alDopplerVelocity),
233 DECL(alSpeedOfSound),
234 DECL(alDistanceModel),
236 DECL(alGenFilters),
237 DECL(alDeleteFilters),
238 DECL(alIsFilter),
239 DECL(alFilteri),
240 DECL(alFilteriv),
241 DECL(alFilterf),
242 DECL(alFilterfv),
243 DECL(alGetFilteri),
244 DECL(alGetFilteriv),
245 DECL(alGetFilterf),
246 DECL(alGetFilterfv),
247 DECL(alGenEffects),
248 DECL(alDeleteEffects),
249 DECL(alIsEffect),
250 DECL(alEffecti),
251 DECL(alEffectiv),
252 DECL(alEffectf),
253 DECL(alEffectfv),
254 DECL(alGetEffecti),
255 DECL(alGetEffectiv),
256 DECL(alGetEffectf),
257 DECL(alGetEffectfv),
258 DECL(alGenAuxiliaryEffectSlots),
259 DECL(alDeleteAuxiliaryEffectSlots),
260 DECL(alIsAuxiliaryEffectSlot),
261 DECL(alAuxiliaryEffectSloti),
262 DECL(alAuxiliaryEffectSlotiv),
263 DECL(alAuxiliaryEffectSlotf),
264 DECL(alAuxiliaryEffectSlotfv),
265 DECL(alGetAuxiliaryEffectSloti),
266 DECL(alGetAuxiliaryEffectSlotiv),
267 DECL(alGetAuxiliaryEffectSlotf),
268 DECL(alGetAuxiliaryEffectSlotfv),
270 DECL(alBufferSubDataSOFT),
272 DECL(alBufferSamplesSOFT),
273 DECL(alBufferSubSamplesSOFT),
274 DECL(alGetBufferSamplesSOFT),
275 DECL(alIsBufferFormatSupportedSOFT),
277 DECL(alDeferUpdatesSOFT),
278 DECL(alProcessUpdatesSOFT),
280 DECL(alSourcedSOFT),
281 DECL(alSource3dSOFT),
282 DECL(alSourcedvSOFT),
283 DECL(alGetSourcedSOFT),
284 DECL(alGetSource3dSOFT),
285 DECL(alGetSourcedvSOFT),
286 DECL(alSourcei64SOFT),
287 DECL(alSource3i64SOFT),
288 DECL(alSourcei64vSOFT),
289 DECL(alGetSourcei64SOFT),
290 DECL(alGetSource3i64SOFT),
291 DECL(alGetSourcei64vSOFT),
293 DECL(alGenSoundfontsSOFT),
294 DECL(alDeleteSoundfontsSOFT),
295 DECL(alIsSoundfontSOFT),
296 DECL(alSoundfontSamplesSOFT),
297 DECL(alGetSoundfontSamplesSOFT),
298 DECL(alSoundfontMapSamplesSOFT),
299 DECL(alSoundfontUnmapSamplesSOFT),
300 DECL(alGetSoundfontivSOFT),
301 DECL(alSoundfontPresetsSOFT),
302 DECL(alGenPresetsSOFT),
303 DECL(alDeletePresetsSOFT),
304 DECL(alIsPresetSOFT),
305 DECL(alPresetiSOFT),
306 DECL(alPresetivSOFT),
307 DECL(alGetPresetivSOFT),
308 DECL(alPresetFontsoundsSOFT),
309 DECL(alGenFontsoundsSOFT),
310 DECL(alDeleteFontsoundsSOFT),
311 DECL(alIsFontsoundSOFT),
312 DECL(alFontsoundiSOFT),
313 DECL(alFontsound2iSOFT),
314 DECL(alFontsoundivSOFT),
315 DECL(alGetFontsoundivSOFT),
316 DECL(alFontsoundModulatoriSOFT),
317 DECL(alGetFontsoundModulatorivSOFT),
318 DECL(alMidiSoundfontSOFT),
319 DECL(alMidiSoundfontvSOFT),
320 DECL(alMidiEventSOFT),
321 DECL(alMidiSysExSOFT),
322 DECL(alMidiPlaySOFT),
323 DECL(alMidiPauseSOFT),
324 DECL(alMidiStopSOFT),
325 DECL(alMidiResetSOFT),
326 DECL(alMidiGainSOFT),
327 DECL(alGetInteger64SOFT),
328 DECL(alGetInteger64vSOFT),
329 DECL(alLoadSoundfontSOFT),
331 { NULL, NULL }
333 #undef DECL
335 #define DECL(x) { #x, (x) }
336 static const ALCenums enumeration[] = {
337 DECL(ALC_INVALID),
338 DECL(ALC_FALSE),
339 DECL(ALC_TRUE),
341 DECL(ALC_MAJOR_VERSION),
342 DECL(ALC_MINOR_VERSION),
343 DECL(ALC_ATTRIBUTES_SIZE),
344 DECL(ALC_ALL_ATTRIBUTES),
345 DECL(ALC_DEFAULT_DEVICE_SPECIFIER),
346 DECL(ALC_DEVICE_SPECIFIER),
347 DECL(ALC_ALL_DEVICES_SPECIFIER),
348 DECL(ALC_DEFAULT_ALL_DEVICES_SPECIFIER),
349 DECL(ALC_EXTENSIONS),
350 DECL(ALC_FREQUENCY),
351 DECL(ALC_REFRESH),
352 DECL(ALC_SYNC),
353 DECL(ALC_MONO_SOURCES),
354 DECL(ALC_STEREO_SOURCES),
355 DECL(ALC_CAPTURE_DEVICE_SPECIFIER),
356 DECL(ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER),
357 DECL(ALC_CAPTURE_SAMPLES),
358 DECL(ALC_CONNECTED),
360 DECL(ALC_EFX_MAJOR_VERSION),
361 DECL(ALC_EFX_MINOR_VERSION),
362 DECL(ALC_MAX_AUXILIARY_SENDS),
364 DECL(ALC_FORMAT_CHANNELS_SOFT),
365 DECL(ALC_FORMAT_TYPE_SOFT),
367 DECL(ALC_MONO_SOFT),
368 DECL(ALC_STEREO_SOFT),
369 DECL(ALC_QUAD_SOFT),
370 DECL(ALC_5POINT1_SOFT),
371 DECL(ALC_6POINT1_SOFT),
372 DECL(ALC_7POINT1_SOFT),
374 DECL(ALC_BYTE_SOFT),
375 DECL(ALC_UNSIGNED_BYTE_SOFT),
376 DECL(ALC_SHORT_SOFT),
377 DECL(ALC_UNSIGNED_SHORT_SOFT),
378 DECL(ALC_INT_SOFT),
379 DECL(ALC_UNSIGNED_INT_SOFT),
380 DECL(ALC_FLOAT_SOFT),
382 DECL(ALC_NO_ERROR),
383 DECL(ALC_INVALID_DEVICE),
384 DECL(ALC_INVALID_CONTEXT),
385 DECL(ALC_INVALID_ENUM),
386 DECL(ALC_INVALID_VALUE),
387 DECL(ALC_OUT_OF_MEMORY),
390 DECL(AL_INVALID),
391 DECL(AL_NONE),
392 DECL(AL_FALSE),
393 DECL(AL_TRUE),
395 DECL(AL_SOURCE_RELATIVE),
396 DECL(AL_CONE_INNER_ANGLE),
397 DECL(AL_CONE_OUTER_ANGLE),
398 DECL(AL_PITCH),
399 DECL(AL_POSITION),
400 DECL(AL_DIRECTION),
401 DECL(AL_VELOCITY),
402 DECL(AL_LOOPING),
403 DECL(AL_BUFFER),
404 DECL(AL_GAIN),
405 DECL(AL_MIN_GAIN),
406 DECL(AL_MAX_GAIN),
407 DECL(AL_ORIENTATION),
408 DECL(AL_REFERENCE_DISTANCE),
409 DECL(AL_ROLLOFF_FACTOR),
410 DECL(AL_CONE_OUTER_GAIN),
411 DECL(AL_MAX_DISTANCE),
412 DECL(AL_SEC_OFFSET),
413 DECL(AL_SAMPLE_OFFSET),
414 DECL(AL_SAMPLE_RW_OFFSETS_SOFT),
415 DECL(AL_BYTE_OFFSET),
416 DECL(AL_BYTE_RW_OFFSETS_SOFT),
417 DECL(AL_SOURCE_TYPE),
418 DECL(AL_STATIC),
419 DECL(AL_STREAMING),
420 DECL(AL_UNDETERMINED),
421 DECL(AL_METERS_PER_UNIT),
422 DECL(AL_DIRECT_CHANNELS_SOFT),
424 DECL(AL_DIRECT_FILTER),
425 DECL(AL_AUXILIARY_SEND_FILTER),
426 DECL(AL_AIR_ABSORPTION_FACTOR),
427 DECL(AL_ROOM_ROLLOFF_FACTOR),
428 DECL(AL_CONE_OUTER_GAINHF),
429 DECL(AL_DIRECT_FILTER_GAINHF_AUTO),
430 DECL(AL_AUXILIARY_SEND_FILTER_GAIN_AUTO),
431 DECL(AL_AUXILIARY_SEND_FILTER_GAINHF_AUTO),
433 DECL(AL_SOURCE_STATE),
434 DECL(AL_INITIAL),
435 DECL(AL_PLAYING),
436 DECL(AL_PAUSED),
437 DECL(AL_STOPPED),
439 DECL(AL_BUFFERS_QUEUED),
440 DECL(AL_BUFFERS_PROCESSED),
442 DECL(AL_FORMAT_MONO8),
443 DECL(AL_FORMAT_MONO16),
444 DECL(AL_FORMAT_MONO_FLOAT32),
445 DECL(AL_FORMAT_MONO_DOUBLE_EXT),
446 DECL(AL_FORMAT_STEREO8),
447 DECL(AL_FORMAT_STEREO16),
448 DECL(AL_FORMAT_STEREO_FLOAT32),
449 DECL(AL_FORMAT_STEREO_DOUBLE_EXT),
450 DECL(AL_FORMAT_MONO_IMA4),
451 DECL(AL_FORMAT_STEREO_IMA4),
452 DECL(AL_FORMAT_MONO_MSADPCM_SOFT),
453 DECL(AL_FORMAT_STEREO_MSADPCM_SOFT),
454 DECL(AL_FORMAT_QUAD8_LOKI),
455 DECL(AL_FORMAT_QUAD16_LOKI),
456 DECL(AL_FORMAT_QUAD8),
457 DECL(AL_FORMAT_QUAD16),
458 DECL(AL_FORMAT_QUAD32),
459 DECL(AL_FORMAT_51CHN8),
460 DECL(AL_FORMAT_51CHN16),
461 DECL(AL_FORMAT_51CHN32),
462 DECL(AL_FORMAT_61CHN8),
463 DECL(AL_FORMAT_61CHN16),
464 DECL(AL_FORMAT_61CHN32),
465 DECL(AL_FORMAT_71CHN8),
466 DECL(AL_FORMAT_71CHN16),
467 DECL(AL_FORMAT_71CHN32),
468 DECL(AL_FORMAT_REAR8),
469 DECL(AL_FORMAT_REAR16),
470 DECL(AL_FORMAT_REAR32),
471 DECL(AL_FORMAT_MONO_MULAW),
472 DECL(AL_FORMAT_MONO_MULAW_EXT),
473 DECL(AL_FORMAT_STEREO_MULAW),
474 DECL(AL_FORMAT_STEREO_MULAW_EXT),
475 DECL(AL_FORMAT_QUAD_MULAW),
476 DECL(AL_FORMAT_51CHN_MULAW),
477 DECL(AL_FORMAT_61CHN_MULAW),
478 DECL(AL_FORMAT_71CHN_MULAW),
479 DECL(AL_FORMAT_REAR_MULAW),
480 DECL(AL_FORMAT_MONO_ALAW_EXT),
481 DECL(AL_FORMAT_STEREO_ALAW_EXT),
483 DECL(AL_MONO8_SOFT),
484 DECL(AL_MONO16_SOFT),
485 DECL(AL_MONO32F_SOFT),
486 DECL(AL_STEREO8_SOFT),
487 DECL(AL_STEREO16_SOFT),
488 DECL(AL_STEREO32F_SOFT),
489 DECL(AL_QUAD8_SOFT),
490 DECL(AL_QUAD16_SOFT),
491 DECL(AL_QUAD32F_SOFT),
492 DECL(AL_REAR8_SOFT),
493 DECL(AL_REAR16_SOFT),
494 DECL(AL_REAR32F_SOFT),
495 DECL(AL_5POINT1_8_SOFT),
496 DECL(AL_5POINT1_16_SOFT),
497 DECL(AL_5POINT1_32F_SOFT),
498 DECL(AL_6POINT1_8_SOFT),
499 DECL(AL_6POINT1_16_SOFT),
500 DECL(AL_6POINT1_32F_SOFT),
501 DECL(AL_7POINT1_8_SOFT),
502 DECL(AL_7POINT1_16_SOFT),
503 DECL(AL_7POINT1_32F_SOFT),
505 DECL(AL_MONO_SOFT),
506 DECL(AL_STEREO_SOFT),
507 DECL(AL_QUAD_SOFT),
508 DECL(AL_REAR_SOFT),
509 DECL(AL_5POINT1_SOFT),
510 DECL(AL_6POINT1_SOFT),
511 DECL(AL_7POINT1_SOFT),
513 DECL(AL_BYTE_SOFT),
514 DECL(AL_UNSIGNED_BYTE_SOFT),
515 DECL(AL_SHORT_SOFT),
516 DECL(AL_UNSIGNED_SHORT_SOFT),
517 DECL(AL_INT_SOFT),
518 DECL(AL_UNSIGNED_INT_SOFT),
519 DECL(AL_FLOAT_SOFT),
520 DECL(AL_DOUBLE_SOFT),
521 DECL(AL_BYTE3_SOFT),
522 DECL(AL_UNSIGNED_BYTE3_SOFT),
524 DECL(AL_FREQUENCY),
525 DECL(AL_BITS),
526 DECL(AL_CHANNELS),
527 DECL(AL_SIZE),
528 DECL(AL_INTERNAL_FORMAT_SOFT),
529 DECL(AL_BYTE_LENGTH_SOFT),
530 DECL(AL_SAMPLE_LENGTH_SOFT),
531 DECL(AL_SEC_LENGTH_SOFT),
532 DECL(AL_UNPACK_BLOCK_ALIGNMENT_SOFT),
533 DECL(AL_PACK_BLOCK_ALIGNMENT_SOFT),
535 DECL(AL_UNUSED),
536 DECL(AL_PENDING),
537 DECL(AL_PROCESSED),
539 DECL(AL_NO_ERROR),
540 DECL(AL_INVALID_NAME),
541 DECL(AL_INVALID_ENUM),
542 DECL(AL_INVALID_VALUE),
543 DECL(AL_INVALID_OPERATION),
544 DECL(AL_OUT_OF_MEMORY),
546 DECL(AL_VENDOR),
547 DECL(AL_VERSION),
548 DECL(AL_RENDERER),
549 DECL(AL_EXTENSIONS),
551 DECL(AL_DOPPLER_FACTOR),
552 DECL(AL_DOPPLER_VELOCITY),
553 DECL(AL_DISTANCE_MODEL),
554 DECL(AL_SPEED_OF_SOUND),
555 DECL(AL_SOURCE_DISTANCE_MODEL),
556 DECL(AL_DEFERRED_UPDATES_SOFT),
558 DECL(AL_INVERSE_DISTANCE),
559 DECL(AL_INVERSE_DISTANCE_CLAMPED),
560 DECL(AL_LINEAR_DISTANCE),
561 DECL(AL_LINEAR_DISTANCE_CLAMPED),
562 DECL(AL_EXPONENT_DISTANCE),
563 DECL(AL_EXPONENT_DISTANCE_CLAMPED),
565 DECL(AL_FILTER_TYPE),
566 DECL(AL_FILTER_NULL),
567 DECL(AL_FILTER_LOWPASS),
568 DECL(AL_FILTER_HIGHPASS),
569 DECL(AL_FILTER_BANDPASS),
571 DECL(AL_LOWPASS_GAIN),
572 DECL(AL_LOWPASS_GAINHF),
574 DECL(AL_HIGHPASS_GAIN),
575 DECL(AL_HIGHPASS_GAINLF),
577 DECL(AL_BANDPASS_GAIN),
578 DECL(AL_BANDPASS_GAINHF),
579 DECL(AL_BANDPASS_GAINLF),
581 DECL(AL_EFFECT_TYPE),
582 DECL(AL_EFFECT_NULL),
583 DECL(AL_EFFECT_REVERB),
584 DECL(AL_EFFECT_EAXREVERB),
585 DECL(AL_EFFECT_CHORUS),
586 DECL(AL_EFFECT_DISTORTION),
587 DECL(AL_EFFECT_ECHO),
588 DECL(AL_EFFECT_FLANGER),
589 #if 0
590 DECL(AL_EFFECT_FREQUENCY_SHIFTER),
591 DECL(AL_EFFECT_VOCAL_MORPHER),
592 DECL(AL_EFFECT_PITCH_SHIFTER),
593 #endif
594 DECL(AL_EFFECT_RING_MODULATOR),
595 DECL(AL_EFFECT_AUTOWAH),
596 DECL(AL_EFFECT_COMPRESSOR),
597 DECL(AL_EFFECT_EQUALIZER),
598 DECL(AL_EFFECT_DEDICATED_LOW_FREQUENCY_EFFECT),
599 DECL(AL_EFFECT_DEDICATED_DIALOGUE),
601 DECL(AL_EAXREVERB_DENSITY),
602 DECL(AL_EAXREVERB_DIFFUSION),
603 DECL(AL_EAXREVERB_GAIN),
604 DECL(AL_EAXREVERB_GAINHF),
605 DECL(AL_EAXREVERB_GAINLF),
606 DECL(AL_EAXREVERB_DECAY_TIME),
607 DECL(AL_EAXREVERB_DECAY_HFRATIO),
608 DECL(AL_EAXREVERB_DECAY_LFRATIO),
609 DECL(AL_EAXREVERB_REFLECTIONS_GAIN),
610 DECL(AL_EAXREVERB_REFLECTIONS_DELAY),
611 DECL(AL_EAXREVERB_REFLECTIONS_PAN),
612 DECL(AL_EAXREVERB_LATE_REVERB_GAIN),
613 DECL(AL_EAXREVERB_LATE_REVERB_DELAY),
614 DECL(AL_EAXREVERB_LATE_REVERB_PAN),
615 DECL(AL_EAXREVERB_ECHO_TIME),
616 DECL(AL_EAXREVERB_ECHO_DEPTH),
617 DECL(AL_EAXREVERB_MODULATION_TIME),
618 DECL(AL_EAXREVERB_MODULATION_DEPTH),
619 DECL(AL_EAXREVERB_AIR_ABSORPTION_GAINHF),
620 DECL(AL_EAXREVERB_HFREFERENCE),
621 DECL(AL_EAXREVERB_LFREFERENCE),
622 DECL(AL_EAXREVERB_ROOM_ROLLOFF_FACTOR),
623 DECL(AL_EAXREVERB_DECAY_HFLIMIT),
625 DECL(AL_REVERB_DENSITY),
626 DECL(AL_REVERB_DIFFUSION),
627 DECL(AL_REVERB_GAIN),
628 DECL(AL_REVERB_GAINHF),
629 DECL(AL_REVERB_DECAY_TIME),
630 DECL(AL_REVERB_DECAY_HFRATIO),
631 DECL(AL_REVERB_REFLECTIONS_GAIN),
632 DECL(AL_REVERB_REFLECTIONS_DELAY),
633 DECL(AL_REVERB_LATE_REVERB_GAIN),
634 DECL(AL_REVERB_LATE_REVERB_DELAY),
635 DECL(AL_REVERB_AIR_ABSORPTION_GAINHF),
636 DECL(AL_REVERB_ROOM_ROLLOFF_FACTOR),
637 DECL(AL_REVERB_DECAY_HFLIMIT),
639 DECL(AL_CHORUS_WAVEFORM),
640 DECL(AL_CHORUS_PHASE),
641 DECL(AL_CHORUS_RATE),
642 DECL(AL_CHORUS_DEPTH),
643 DECL(AL_CHORUS_FEEDBACK),
644 DECL(AL_CHORUS_DELAY),
646 DECL(AL_DISTORTION_EDGE),
647 DECL(AL_DISTORTION_GAIN),
648 DECL(AL_DISTORTION_LOWPASS_CUTOFF),
649 DECL(AL_DISTORTION_EQCENTER),
650 DECL(AL_DISTORTION_EQBANDWIDTH),
652 DECL(AL_ECHO_DELAY),
653 DECL(AL_ECHO_LRDELAY),
654 DECL(AL_ECHO_DAMPING),
655 DECL(AL_ECHO_FEEDBACK),
656 DECL(AL_ECHO_SPREAD),
658 DECL(AL_FLANGER_WAVEFORM),
659 DECL(AL_FLANGER_PHASE),
660 DECL(AL_FLANGER_RATE),
661 DECL(AL_FLANGER_DEPTH),
662 DECL(AL_FLANGER_FEEDBACK),
663 DECL(AL_FLANGER_DELAY),
665 DECL(AL_RING_MODULATOR_FREQUENCY),
666 DECL(AL_RING_MODULATOR_HIGHPASS_CUTOFF),
667 DECL(AL_RING_MODULATOR_WAVEFORM),
669 DECL(AL_AUTOWAH_ATTACK_TIME),
670 DECL(AL_AUTOWAH_PEAK_GAIN),
671 DECL(AL_AUTOWAH_RELEASE_TIME),
672 DECL(AL_AUTOWAH_RESONANCE),
674 DECL(AL_COMPRESSOR_ONOFF),
676 DECL(AL_EQUALIZER_LOW_GAIN),
677 DECL(AL_EQUALIZER_LOW_CUTOFF),
678 DECL(AL_EQUALIZER_MID1_GAIN),
679 DECL(AL_EQUALIZER_MID1_CENTER),
680 DECL(AL_EQUALIZER_MID1_WIDTH),
681 DECL(AL_EQUALIZER_MID2_GAIN),
682 DECL(AL_EQUALIZER_MID2_CENTER),
683 DECL(AL_EQUALIZER_MID2_WIDTH),
684 DECL(AL_EQUALIZER_HIGH_GAIN),
685 DECL(AL_EQUALIZER_HIGH_CUTOFF),
687 DECL(AL_DEDICATED_GAIN),
689 { NULL, (ALCenum)0 }
691 #undef DECL
693 static const ALCchar alcNoError[] = "No Error";
694 static const ALCchar alcErrInvalidDevice[] = "Invalid Device";
695 static const ALCchar alcErrInvalidContext[] = "Invalid Context";
696 static const ALCchar alcErrInvalidEnum[] = "Invalid Enum";
697 static const ALCchar alcErrInvalidValue[] = "Invalid Value";
698 static const ALCchar alcErrOutOfMemory[] = "Out of Memory";
701 /************************************************
702 * Global variables
703 ************************************************/
705 /* Enumerated device names */
706 static const ALCchar alcDefaultName[] = "OpenAL Soft\0";
708 static al_string alcAllDevicesList;
709 static al_string alcCaptureDeviceList;
711 /* Default is always the first in the list */
712 static ALCchar *alcDefaultAllDevicesSpecifier;
713 static ALCchar *alcCaptureDefaultDeviceSpecifier;
715 /* Default context extensions */
716 static const ALchar alExtList[] =
717 "AL_EXT_ALAW AL_EXT_DOUBLE AL_EXT_EXPONENT_DISTANCE AL_EXT_FLOAT32 "
718 "AL_EXT_IMA4 AL_EXT_LINEAR_DISTANCE AL_EXT_MCFORMATS AL_EXT_MULAW "
719 "AL_EXT_MULAW_MCFORMATS AL_EXT_OFFSET AL_EXT_source_distance_model "
720 "AL_LOKI_quadriphonic AL_SOFT_block_alignment AL_SOFT_buffer_samples "
721 "AL_SOFT_buffer_sub_data AL_SOFT_deferred_updates AL_SOFT_direct_channels "
722 "AL_SOFT_loop_points AL_SOFTX_MSADPCM AL_SOFT_source_latency "
723 "AL_SOFTX_source_length";
725 static volatile ALCenum LastNullDeviceError = ALC_NO_ERROR;
727 /* Thread-local current context */
728 static altss_t LocalContext;
729 /* Process-wide current context */
730 static ALCcontext *volatile GlobalContext = NULL;
732 /* Mixing thread piority level */
733 ALint RTPrioLevel;
735 FILE *LogFile;
736 #ifdef _DEBUG
737 enum LogLevel LogLevel = LogWarning;
738 #else
739 enum LogLevel LogLevel = LogError;
740 #endif
742 /* Flag to trap ALC device errors */
743 static ALCboolean TrapALCError = ALC_FALSE;
745 /* One-time configuration init control */
746 static alonce_flag alc_config_once = AL_ONCE_FLAG_INIT;
748 /* Default effect that applies to sources that don't have an effect on send 0 */
749 static ALeffect DefaultEffect;
752 /************************************************
753 * ALC information
754 ************************************************/
755 static const ALCchar alcNoDeviceExtList[] =
756 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
757 "ALC_EXT_thread_local_context ALC_SOFT_loopback";
758 static const ALCchar alcExtensionList[] =
759 "ALC_ENUMERATE_ALL_EXT ALC_ENUMERATION_EXT ALC_EXT_CAPTURE "
760 "ALC_EXT_DEDICATED ALC_EXT_disconnect ALC_EXT_EFX "
761 "ALC_EXT_thread_local_context ALC_SOFTX_device_clock ALC_SOFTX_HRTF "
762 "ALC_SOFT_loopback ALC_SOFTX_midi_interface ALC_SOFTX_pause_device";
763 static const ALCint alcMajorVersion = 1;
764 static const ALCint alcMinorVersion = 1;
766 static const ALCint alcEFXMajorVersion = 1;
767 static const ALCint alcEFXMinorVersion = 0;
770 /************************************************
771 * Device lists
772 ************************************************/
773 static ALCdevice *volatile DeviceList = NULL;
775 static almtx_t ListLock;
776 static inline void LockLists(void)
778 int lockret = almtx_lock(&ListLock);
779 assert(lockret == althrd_success);
781 static inline void UnlockLists(void)
783 int unlockret = almtx_unlock(&ListLock);
784 assert(unlockret == althrd_success);
787 /************************************************
788 * Library initialization
789 ************************************************/
790 #if defined(_WIN32)
791 static void alc_init(void);
792 static void alc_deinit(void);
793 static void alc_deinit_safe(void);
795 #ifndef AL_LIBTYPE_STATIC
796 BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD reason, LPVOID lpReserved)
798 switch(reason)
800 case DLL_PROCESS_ATTACH:
801 /* Pin the DLL so we won't get unloaded until the process terminates */
802 GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
803 (WCHAR*)hModule, &hModule);
804 alc_init();
805 break;
807 case DLL_THREAD_DETACH:
808 break;
810 case DLL_PROCESS_DETACH:
811 if(!lpReserved)
812 alc_deinit();
813 else
814 alc_deinit_safe();
815 break;
817 return TRUE;
819 #elif defined(_MSC_VER)
820 #pragma section(".CRT$XCU",read)
821 static void alc_constructor(void);
822 static void alc_destructor(void);
823 __declspec(allocate(".CRT$XCU")) void (__cdecl* alc_constructor_)(void) = alc_constructor;
825 static void alc_constructor(void)
827 atexit(alc_destructor);
828 alc_init();
831 static void alc_destructor(void)
833 alc_deinit();
835 #elif defined(HAVE_GCC_DESTRUCTOR)
836 static void alc_init(void) __attribute__((constructor));
837 static void alc_deinit(void) __attribute__((destructor));
838 #else
839 #error "No static initialization available on this platform!"
840 #endif
842 #elif defined(HAVE_GCC_DESTRUCTOR)
844 static void alc_init(void) __attribute__((constructor));
845 static void alc_deinit(void) __attribute__((destructor));
847 #else
848 #error "No global initialization available on this platform!"
849 #endif
851 static void ReleaseThreadCtx(void *ptr);
852 static void alc_init(void)
854 const char *str;
855 int ret;
857 LogFile = stderr;
859 AL_STRING_INIT(alcAllDevicesList);
860 AL_STRING_INIT(alcCaptureDeviceList);
862 str = getenv("__ALSOFT_HALF_ANGLE_CONES");
863 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
864 ConeScale *= 0.5f;
866 str = getenv("__ALSOFT_REVERSE_Z");
867 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
868 ZScale *= -1.0f;
870 ret = altss_create(&LocalContext, ReleaseThreadCtx);
871 assert(ret == althrd_success);
873 ret = almtx_init(&ListLock, almtx_recursive);
874 assert(ret == althrd_success);
876 ThunkInit();
879 static void alc_initconfig(void)
881 const char *devs, *str;
882 ALuint capfilter;
883 float valf;
884 int i, n;
886 str = getenv("ALSOFT_LOGLEVEL");
887 if(str)
889 long lvl = strtol(str, NULL, 0);
890 if(lvl >= NoLog && lvl <= LogRef)
891 LogLevel = lvl;
894 str = getenv("ALSOFT_LOGFILE");
895 if(str && str[0])
897 FILE *logfile = al_fopen(str, "wt");
898 if(logfile) LogFile = logfile;
899 else ERR("Failed to open log file '%s'\n", str);
903 char buf[1024] = "";
904 int len = snprintf(buf, sizeof(buf), "%s", BackendList[0].name);
905 for(i = 1;BackendList[i].name;i++)
906 len += snprintf(buf+len, sizeof(buf)-len, ", %s", BackendList[i].name);
907 TRACE("Supported backends: %s\n", buf);
909 ReadALConfig();
911 capfilter = 0;
912 #if defined(HAVE_SSE4_1)
913 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2 | CPU_CAP_SSE4_1;
914 #elif defined(HAVE_SSE2)
915 capfilter |= CPU_CAP_SSE | CPU_CAP_SSE2;
916 #elif defined(HAVE_SSE)
917 capfilter |= CPU_CAP_SSE;
918 #endif
919 #ifdef HAVE_NEON
920 capfilter |= CPU_CAP_NEON;
921 #endif
922 if(ConfigValueStr(NULL, "disable-cpu-exts", &str))
924 if(strcasecmp(str, "all") == 0)
925 capfilter = 0;
926 else
928 size_t len;
929 const char *next = str;
931 do {
932 str = next;
933 while(isspace(str[0]))
934 str++;
935 next = strchr(str, ',');
937 if(!str[0] || str[0] == ',')
938 continue;
940 len = (next ? ((size_t)(next-str)) : strlen(str));
941 while(len > 0 && isspace(str[len-1]))
942 len--;
943 if(len == 3 && strncasecmp(str, "sse", len) == 0)
944 capfilter &= ~CPU_CAP_SSE;
945 else if(len == 4 && strncasecmp(str, "sse2", len) == 0)
946 capfilter &= ~CPU_CAP_SSE2;
947 else if(len == 6 && strncasecmp(str, "sse4.1", len) == 0)
948 capfilter &= ~CPU_CAP_SSE4_1;
949 else if(len == 4 && strncasecmp(str, "neon", len) == 0)
950 capfilter &= ~CPU_CAP_NEON;
951 else
952 WARN("Invalid CPU extension \"%s\"\n", str);
953 } while(next++);
956 FillCPUCaps(capfilter);
958 #ifdef _WIN32
959 RTPrioLevel = 1;
960 #else
961 RTPrioLevel = 0;
962 #endif
963 ConfigValueInt(NULL, "rt-prio", &RTPrioLevel);
965 if(ConfigValueStr(NULL, "resampler", &str))
967 if(strcasecmp(str, "point") == 0 || strcasecmp(str, "none") == 0)
968 DefaultResampler = PointResampler;
969 else if(strcasecmp(str, "linear") == 0)
970 DefaultResampler = LinearResampler;
971 else if(strcasecmp(str, "cubic") == 0)
972 DefaultResampler = CubicResampler;
973 else
975 char *end;
977 n = strtol(str, &end, 0);
978 if(*end == '\0' && (n == PointResampler || n == LinearResampler || n == CubicResampler))
979 DefaultResampler = n;
980 else
981 WARN("Invalid resampler: %s\n", str);
985 str = getenv("ALSOFT_TRAP_ERROR");
986 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
988 TrapALError = AL_TRUE;
989 TrapALCError = AL_TRUE;
991 else
993 str = getenv("ALSOFT_TRAP_AL_ERROR");
994 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
995 TrapALError = AL_TRUE;
996 TrapALError = GetConfigValueBool(NULL, "trap-al-error", TrapALError);
998 str = getenv("ALSOFT_TRAP_ALC_ERROR");
999 if(str && (strcasecmp(str, "true") == 0 || strtol(str, NULL, 0) == 1))
1000 TrapALCError = ALC_TRUE;
1001 TrapALCError = GetConfigValueBool(NULL, "trap-alc-error", TrapALCError);
1004 if(ConfigValueFloat("reverb", "boost", &valf))
1005 ReverbBoost *= powf(10.0f, valf / 20.0f);
1007 EmulateEAXReverb = GetConfigValueBool("reverb", "emulate-eax", AL_FALSE);
1009 if(((devs=getenv("ALSOFT_DRIVERS")) && devs[0]) ||
1010 ConfigValueStr(NULL, "drivers", &devs))
1012 int n;
1013 size_t len;
1014 const char *next = devs;
1015 int endlist, delitem;
1017 i = 0;
1018 do {
1019 devs = next;
1020 while(isspace(devs[0]))
1021 devs++;
1022 next = strchr(devs, ',');
1024 delitem = (devs[0] == '-');
1025 if(devs[0] == '-') devs++;
1027 if(!devs[0] || devs[0] == ',')
1029 endlist = 0;
1030 continue;
1032 endlist = 1;
1034 len = (next ? ((size_t)(next-devs)) : strlen(devs));
1035 while(len > 0 && isspace(devs[len-1]))
1036 len--;
1037 for(n = i;BackendList[n].name;n++)
1039 if(len == strlen(BackendList[n].name) &&
1040 strncmp(BackendList[n].name, devs, len) == 0)
1042 if(delitem)
1044 do {
1045 BackendList[n] = BackendList[n+1];
1046 ++n;
1047 } while(BackendList[n].name);
1049 else
1051 struct BackendInfo Bkp = BackendList[n];
1052 while(n > i)
1054 BackendList[n] = BackendList[n-1];
1055 --n;
1057 BackendList[n] = Bkp;
1059 i++;
1061 break;
1064 } while(next++);
1066 if(endlist)
1068 BackendList[i].name = NULL;
1069 BackendList[i].getFactory = NULL;
1070 BackendList[i].Init = NULL;
1071 BackendList[i].Deinit = NULL;
1072 BackendList[i].Probe = NULL;
1076 for(i = 0;(BackendList[i].Init || BackendList[i].getFactory) && (!PlaybackBackend.name || !CaptureBackend.name);i++)
1078 if(BackendList[i].getFactory)
1080 ALCbackendFactory *factory = BackendList[i].getFactory();
1081 if(!V0(factory,init)())
1083 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1084 continue;
1087 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1088 if(!PlaybackBackend.name && V(factory,querySupport)(ALCbackend_Playback))
1090 PlaybackBackend = BackendList[i];
1091 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1093 if(!CaptureBackend.name && V(factory,querySupport)(ALCbackend_Capture))
1095 CaptureBackend = BackendList[i];
1096 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1099 continue;
1102 if(!BackendList[i].Init(&BackendList[i].Funcs))
1104 WARN("Failed to initialize backend \"%s\"\n", BackendList[i].name);
1105 continue;
1108 TRACE("Initialized backend \"%s\"\n", BackendList[i].name);
1109 if(BackendList[i].Funcs.OpenPlayback && !PlaybackBackend.name)
1111 PlaybackBackend = BackendList[i];
1112 TRACE("Added \"%s\" for playback\n", PlaybackBackend.name);
1114 if(BackendList[i].Funcs.OpenCapture && !CaptureBackend.name)
1116 CaptureBackend = BackendList[i];
1117 TRACE("Added \"%s\" for capture\n", CaptureBackend.name);
1121 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1122 V0(factory,init)();
1125 if(ConfigValueStr(NULL, "excludefx", &str))
1127 size_t len;
1128 const char *next = str;
1130 do {
1131 str = next;
1132 next = strchr(str, ',');
1134 if(!str[0] || next == str)
1135 continue;
1137 len = (next ? ((size_t)(next-str)) : strlen(str));
1138 for(n = 0;EffectList[n].name;n++)
1140 if(len == strlen(EffectList[n].name) &&
1141 strncmp(EffectList[n].name, str, len) == 0)
1142 DisabledEffects[EffectList[n].type] = AL_TRUE;
1144 } while(next++);
1147 InitEffectFactoryMap();
1149 InitEffect(&DefaultEffect);
1150 str = getenv("ALSOFT_DEFAULT_REVERB");
1151 if((str && str[0]) || ConfigValueStr(NULL, "default-reverb", &str))
1152 LoadReverbPreset(str, &DefaultEffect);
1154 #define DO_INITCONFIG() alcall_once(&alc_config_once, alc_initconfig)
1157 /************************************************
1158 * Library deinitialization
1159 ************************************************/
1160 static void alc_cleanup(void)
1162 ALCdevice *dev;
1164 AL_STRING_DEINIT(alcAllDevicesList);
1165 AL_STRING_DEINIT(alcCaptureDeviceList);
1167 free(alcDefaultAllDevicesSpecifier);
1168 alcDefaultAllDevicesSpecifier = NULL;
1169 free(alcCaptureDefaultDeviceSpecifier);
1170 alcCaptureDefaultDeviceSpecifier = NULL;
1172 if((dev=ExchangePtr((XchgPtr*)&DeviceList, NULL)) != NULL)
1174 ALCuint num = 0;
1175 do {
1176 num++;
1177 } while((dev=dev->next) != NULL);
1178 ERR("%u device%s not closed\n", num, (num>1)?"s":"");
1181 DeinitEffectFactoryMap();
1184 static void alc_deinit_safe(void)
1186 alc_cleanup();
1188 FreeHrtfs();
1189 FreeALConfig();
1191 ThunkExit();
1192 almtx_destroy(&ListLock);
1193 altss_delete(LocalContext);
1195 if(LogFile != stderr)
1196 fclose(LogFile);
1197 LogFile = NULL;
1200 static void alc_deinit(void)
1202 int i;
1204 alc_cleanup();
1206 memset(&PlaybackBackend, 0, sizeof(PlaybackBackend));
1207 memset(&CaptureBackend, 0, sizeof(CaptureBackend));
1209 for(i = 0;BackendList[i].Deinit || BackendList[i].getFactory;i++)
1211 if(!BackendList[i].getFactory)
1212 BackendList[i].Deinit();
1213 else
1215 ALCbackendFactory *factory = BackendList[i].getFactory();
1216 V0(factory,deinit)();
1220 ALCbackendFactory *factory = ALCloopbackFactory_getFactory();
1221 V0(factory,deinit)();
1224 alc_deinit_safe();
1228 /************************************************
1229 * Device enumeration
1230 ************************************************/
1231 static void ProbeDevices(al_string *list, enum DevProbe type)
1233 DO_INITCONFIG();
1235 LockLists();
1236 al_string_clear(list);
1238 if(type == ALL_DEVICE_PROBE && (PlaybackBackend.Probe || PlaybackBackend.getFactory))
1240 if(!PlaybackBackend.getFactory)
1241 PlaybackBackend.Probe(type);
1242 else
1244 ALCbackendFactory *factory = PlaybackBackend.getFactory();
1245 V(factory,probe)(type);
1248 else if(type == CAPTURE_DEVICE_PROBE && (CaptureBackend.Probe || CaptureBackend.getFactory))
1250 if(!CaptureBackend.getFactory)
1251 CaptureBackend.Probe(type);
1252 else
1254 ALCbackendFactory *factory = CaptureBackend.getFactory();
1255 V(factory,probe)(type);
1258 UnlockLists();
1260 static void ProbeAllDevicesList(void)
1261 { ProbeDevices(&alcAllDevicesList, ALL_DEVICE_PROBE); }
1262 static void ProbeCaptureDeviceList(void)
1263 { ProbeDevices(&alcCaptureDeviceList, CAPTURE_DEVICE_PROBE); }
1265 static void AppendDevice(const ALCchar *name, al_string *devnames)
1267 size_t len = strlen(name);
1268 if(len > 0)
1270 al_string_append_range(devnames, name, name+len);
1271 al_string_append_char(devnames, '\0');
1274 void AppendAllDevicesList(const ALCchar *name)
1275 { AppendDevice(name, &alcAllDevicesList); }
1276 void AppendCaptureDeviceList(const ALCchar *name)
1277 { AppendDevice(name, &alcCaptureDeviceList); }
1280 /************************************************
1281 * Device format information
1282 ************************************************/
1283 const ALCchar *DevFmtTypeString(enum DevFmtType type)
1285 switch(type)
1287 case DevFmtByte: return "Signed Byte";
1288 case DevFmtUByte: return "Unsigned Byte";
1289 case DevFmtShort: return "Signed Short";
1290 case DevFmtUShort: return "Unsigned Short";
1291 case DevFmtInt: return "Signed Int";
1292 case DevFmtUInt: return "Unsigned Int";
1293 case DevFmtFloat: return "Float";
1295 return "(unknown type)";
1297 const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans)
1299 switch(chans)
1301 case DevFmtMono: return "Mono";
1302 case DevFmtStereo: return "Stereo";
1303 case DevFmtQuad: return "Quadraphonic";
1304 case DevFmtX51: return "5.1 Surround";
1305 case DevFmtX51Side: return "5.1 Side";
1306 case DevFmtX61: return "6.1 Surround";
1307 case DevFmtX71: return "7.1 Surround";
1309 return "(unknown channels)";
1312 extern inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type);
1313 ALuint BytesFromDevFmt(enum DevFmtType type)
1315 switch(type)
1317 case DevFmtByte: return sizeof(ALbyte);
1318 case DevFmtUByte: return sizeof(ALubyte);
1319 case DevFmtShort: return sizeof(ALshort);
1320 case DevFmtUShort: return sizeof(ALushort);
1321 case DevFmtInt: return sizeof(ALint);
1322 case DevFmtUInt: return sizeof(ALuint);
1323 case DevFmtFloat: return sizeof(ALfloat);
1325 return 0;
1327 ALuint ChannelsFromDevFmt(enum DevFmtChannels chans)
1329 switch(chans)
1331 case DevFmtMono: return 1;
1332 case DevFmtStereo: return 2;
1333 case DevFmtQuad: return 4;
1334 case DevFmtX51: return 6;
1335 case DevFmtX51Side: return 6;
1336 case DevFmtX61: return 7;
1337 case DevFmtX71: return 8;
1339 return 0;
1342 DECL_CONST static ALboolean DecomposeDevFormat(ALenum format,
1343 enum DevFmtChannels *chans, enum DevFmtType *type)
1345 static const struct {
1346 ALenum format;
1347 enum DevFmtChannels channels;
1348 enum DevFmtType type;
1349 } list[] = {
1350 { AL_FORMAT_MONO8, DevFmtMono, DevFmtUByte },
1351 { AL_FORMAT_MONO16, DevFmtMono, DevFmtShort },
1352 { AL_FORMAT_MONO_FLOAT32, DevFmtMono, DevFmtFloat },
1354 { AL_FORMAT_STEREO8, DevFmtStereo, DevFmtUByte },
1355 { AL_FORMAT_STEREO16, DevFmtStereo, DevFmtShort },
1356 { AL_FORMAT_STEREO_FLOAT32, DevFmtStereo, DevFmtFloat },
1358 { AL_FORMAT_QUAD8, DevFmtQuad, DevFmtUByte },
1359 { AL_FORMAT_QUAD16, DevFmtQuad, DevFmtShort },
1360 { AL_FORMAT_QUAD32, DevFmtQuad, DevFmtFloat },
1362 { AL_FORMAT_51CHN8, DevFmtX51, DevFmtUByte },
1363 { AL_FORMAT_51CHN16, DevFmtX51, DevFmtShort },
1364 { AL_FORMAT_51CHN32, DevFmtX51, DevFmtFloat },
1366 { AL_FORMAT_61CHN8, DevFmtX61, DevFmtUByte },
1367 { AL_FORMAT_61CHN16, DevFmtX61, DevFmtShort },
1368 { AL_FORMAT_61CHN32, DevFmtX61, DevFmtFloat },
1370 { AL_FORMAT_71CHN8, DevFmtX71, DevFmtUByte },
1371 { AL_FORMAT_71CHN16, DevFmtX71, DevFmtShort },
1372 { AL_FORMAT_71CHN32, DevFmtX71, DevFmtFloat },
1374 ALuint i;
1376 for(i = 0;i < COUNTOF(list);i++)
1378 if(list[i].format == format)
1380 *chans = list[i].channels;
1381 *type = list[i].type;
1382 return AL_TRUE;
1386 return AL_FALSE;
1389 DECL_CONST static ALCboolean IsValidALCType(ALCenum type)
1391 switch(type)
1393 case ALC_BYTE_SOFT:
1394 case ALC_UNSIGNED_BYTE_SOFT:
1395 case ALC_SHORT_SOFT:
1396 case ALC_UNSIGNED_SHORT_SOFT:
1397 case ALC_INT_SOFT:
1398 case ALC_UNSIGNED_INT_SOFT:
1399 case ALC_FLOAT_SOFT:
1400 return ALC_TRUE;
1402 return ALC_FALSE;
1405 DECL_CONST static ALCboolean IsValidALCChannels(ALCenum channels)
1407 switch(channels)
1409 case ALC_MONO_SOFT:
1410 case ALC_STEREO_SOFT:
1411 case ALC_QUAD_SOFT:
1412 case ALC_5POINT1_SOFT:
1413 case ALC_6POINT1_SOFT:
1414 case ALC_7POINT1_SOFT:
1415 return ALC_TRUE;
1417 return ALC_FALSE;
1421 /************************************************
1422 * Miscellaneous ALC helpers
1423 ************************************************/
1424 extern inline void LockContext(ALCcontext *context);
1425 extern inline void UnlockContext(ALCcontext *context);
1427 ALint64 ALCdevice_GetLatencyDefault(ALCdevice *UNUSED(device))
1429 return 0;
1432 ALint64 ALCdevice_GetLatency(ALCdevice *device)
1434 return V0(device->Backend,getLatency)();
1437 void ALCdevice_Lock(ALCdevice *device)
1439 V0(device->Backend,lock)();
1442 void ALCdevice_Unlock(ALCdevice *device)
1444 V0(device->Backend,unlock)();
1448 /* SetDefaultWFXChannelOrder
1450 * Sets the default channel order used by WaveFormatEx.
1452 void SetDefaultWFXChannelOrder(ALCdevice *device)
1454 ALuint i;
1456 for(i = 0;i < MaxChannels;i++)
1457 device->ChannelOffsets[i] = INVALID_OFFSET;
1459 switch(device->FmtChans)
1461 case DevFmtMono: device->ChannelOffsets[FrontCenter] = 0;
1462 break;
1463 case DevFmtStereo: device->ChannelOffsets[FrontLeft] = 0;
1464 device->ChannelOffsets[FrontRight] = 1;
1465 break;
1466 case DevFmtQuad: device->ChannelOffsets[FrontLeft] = 0;
1467 device->ChannelOffsets[FrontRight] = 1;
1468 device->ChannelOffsets[BackLeft] = 2;
1469 device->ChannelOffsets[BackRight] = 3;
1470 break;
1471 case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0;
1472 device->ChannelOffsets[FrontRight] = 1;
1473 device->ChannelOffsets[FrontCenter] = 2;
1474 device->ChannelOffsets[LFE] = 3;
1475 device->ChannelOffsets[BackLeft] = 4;
1476 device->ChannelOffsets[BackRight] = 5;
1477 break;
1478 case DevFmtX51Side: device->ChannelOffsets[FrontLeft] = 0;
1479 device->ChannelOffsets[FrontRight] = 1;
1480 device->ChannelOffsets[FrontCenter] = 2;
1481 device->ChannelOffsets[LFE] = 3;
1482 device->ChannelOffsets[SideLeft] = 4;
1483 device->ChannelOffsets[SideRight] = 5;
1484 break;
1485 case DevFmtX61: device->ChannelOffsets[FrontLeft] = 0;
1486 device->ChannelOffsets[FrontRight] = 1;
1487 device->ChannelOffsets[FrontCenter] = 2;
1488 device->ChannelOffsets[LFE] = 3;
1489 device->ChannelOffsets[BackCenter] = 4;
1490 device->ChannelOffsets[SideLeft] = 5;
1491 device->ChannelOffsets[SideRight] = 6;
1492 break;
1493 case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0;
1494 device->ChannelOffsets[FrontRight] = 1;
1495 device->ChannelOffsets[FrontCenter] = 2;
1496 device->ChannelOffsets[LFE] = 3;
1497 device->ChannelOffsets[BackLeft] = 4;
1498 device->ChannelOffsets[BackRight] = 5;
1499 device->ChannelOffsets[SideLeft] = 6;
1500 device->ChannelOffsets[SideRight] = 7;
1501 break;
1505 /* SetDefaultChannelOrder
1507 * Sets the default channel order used by most non-WaveFormatEx-based APIs.
1509 void SetDefaultChannelOrder(ALCdevice *device)
1511 ALuint i;
1513 for(i = 0;i < MaxChannels;i++)
1514 device->ChannelOffsets[i] = INVALID_OFFSET;
1516 switch(device->FmtChans)
1518 case DevFmtX51: device->ChannelOffsets[FrontLeft] = 0;
1519 device->ChannelOffsets[FrontRight] = 1;
1520 device->ChannelOffsets[BackLeft] = 2;
1521 device->ChannelOffsets[BackRight] = 3;
1522 device->ChannelOffsets[FrontCenter] = 4;
1523 device->ChannelOffsets[LFE] = 5;
1524 return;
1525 case DevFmtX71: device->ChannelOffsets[FrontLeft] = 0;
1526 device->ChannelOffsets[FrontRight] = 1;
1527 device->ChannelOffsets[BackLeft] = 2;
1528 device->ChannelOffsets[BackRight] = 3;
1529 device->ChannelOffsets[FrontCenter] = 4;
1530 device->ChannelOffsets[LFE] = 5;
1531 device->ChannelOffsets[SideLeft] = 6;
1532 device->ChannelOffsets[SideRight] = 7;
1533 return;
1535 /* Same as WFX order */
1536 case DevFmtMono:
1537 case DevFmtStereo:
1538 case DevFmtQuad:
1539 case DevFmtX51Side:
1540 case DevFmtX61:
1541 break;
1543 SetDefaultWFXChannelOrder(device);
1547 /* alcSetError
1549 * Stores the latest ALC device error
1551 static void alcSetError(ALCdevice *device, ALCenum errorCode)
1553 if(TrapALCError)
1555 #ifdef _WIN32
1556 /* DebugBreak() will cause an exception if there is no debugger */
1557 if(IsDebuggerPresent())
1558 DebugBreak();
1559 #elif defined(SIGTRAP)
1560 raise(SIGTRAP);
1561 #endif
1564 if(device)
1565 device->LastError = errorCode;
1566 else
1567 LastNullDeviceError = errorCode;
1571 /* UpdateClockBase
1573 * Updates the device's base clock time with however many samples have been
1574 * done. This is used so frequency changes on the device don't cause the time
1575 * to jump forward or back.
1577 static inline void UpdateClockBase(ALCdevice *device)
1579 device->ClockBase += device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency;
1580 device->SamplesDone = 0;
1583 /* UpdateDeviceParams
1585 * Updates device parameters according to the attribute list (caller is
1586 * responsible for holding the list lock).
1588 static ALCenum UpdateDeviceParams(ALCdevice *device, const ALCint *attrList)
1590 ALCcontext *context;
1591 enum DevFmtChannels oldChans;
1592 enum DevFmtType oldType;
1593 ALCuint oldFreq;
1594 FPUCtl oldMode;
1596 // Check for attributes
1597 if(device->Type == Loopback)
1599 enum {
1600 GotFreq = 1<<0,
1601 GotChans = 1<<1,
1602 GotType = 1<<2,
1603 GotAll = GotFreq|GotChans|GotType
1605 ALCuint freq, numMono, numStereo, numSends, flags;
1606 enum DevFmtChannels schans;
1607 enum DevFmtType stype;
1608 ALCuint attrIdx = 0;
1609 ALCint gotFmt = 0;
1611 if(!attrList)
1613 WARN("Missing attributes for loopback device\n");
1614 return ALC_INVALID_VALUE;
1617 numMono = device->NumMonoSources;
1618 numStereo = device->NumStereoSources;
1619 numSends = device->NumAuxSends;
1620 schans = device->FmtChans;
1621 stype = device->FmtType;
1622 freq = device->Frequency;
1623 flags = device->Flags;
1625 while(attrList[attrIdx])
1627 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1629 ALCint val = attrList[attrIdx + 1];
1630 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1631 return ALC_INVALID_VALUE;
1632 schans = val;
1633 gotFmt |= GotChans;
1636 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1638 ALCint val = attrList[attrIdx + 1];
1639 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1640 return ALC_INVALID_VALUE;
1641 stype = val;
1642 gotFmt |= GotType;
1645 if(attrList[attrIdx] == ALC_FREQUENCY)
1647 freq = attrList[attrIdx + 1];
1648 if(freq < MIN_OUTPUT_RATE)
1649 return ALC_INVALID_VALUE;
1650 gotFmt |= GotFreq;
1653 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1655 numStereo = attrList[attrIdx + 1];
1656 if(numStereo > device->MaxNoOfSources)
1657 numStereo = device->MaxNoOfSources;
1659 numMono = device->MaxNoOfSources - numStereo;
1662 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1663 numSends = attrList[attrIdx + 1];
1665 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1667 if(attrList[attrIdx + 1] != ALC_FALSE)
1668 flags |= DEVICE_HRTF_REQUEST;
1669 else
1670 flags &= ~DEVICE_HRTF_REQUEST;
1673 attrIdx += 2;
1676 if(gotFmt != GotAll)
1678 WARN("Missing format for loopback device\n");
1679 return ALC_INVALID_VALUE;
1682 ConfigValueUInt(NULL, "sends", &numSends);
1683 numSends = minu(MAX_SENDS, numSends);
1685 if((device->Flags&DEVICE_RUNNING))
1686 V0(device->Backend,stop)();
1687 device->Flags = (flags & ~DEVICE_RUNNING);
1689 if(freq != device->Frequency)
1690 UpdateClockBase(device);
1691 device->Frequency = freq;
1692 device->FmtChans = schans;
1693 device->FmtType = stype;
1694 device->NumMonoSources = numMono;
1695 device->NumStereoSources = numStereo;
1696 device->NumAuxSends = numSends;
1698 else if(attrList && attrList[0])
1700 ALCuint freq, numMono, numStereo, numSends;
1701 ALCuint attrIdx = 0;
1703 /* If a context is already running on the device, stop playback so the
1704 * device attributes can be updated. */
1705 if((device->Flags&DEVICE_RUNNING))
1706 V0(device->Backend,stop)();
1707 device->Flags &= ~DEVICE_RUNNING;
1709 freq = device->Frequency;
1710 numMono = device->NumMonoSources;
1711 numStereo = device->NumStereoSources;
1712 numSends = device->NumAuxSends;
1714 while(attrList[attrIdx])
1716 if(attrList[attrIdx] == ALC_FREQUENCY)
1718 freq = attrList[attrIdx + 1];
1719 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1722 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1724 numStereo = attrList[attrIdx + 1];
1725 if(numStereo > device->MaxNoOfSources)
1726 numStereo = device->MaxNoOfSources;
1728 numMono = device->MaxNoOfSources - numStereo;
1731 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1732 numSends = attrList[attrIdx + 1];
1734 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1736 if(attrList[attrIdx + 1] != ALC_FALSE)
1737 device->Flags |= DEVICE_HRTF_REQUEST;
1738 else
1739 device->Flags &= ~DEVICE_HRTF_REQUEST;
1742 attrIdx += 2;
1745 ConfigValueUInt(NULL, "frequency", &freq);
1746 freq = maxu(freq, MIN_OUTPUT_RATE);
1748 ConfigValueUInt(NULL, "sends", &numSends);
1749 numSends = minu(MAX_SENDS, numSends);
1751 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1752 device->Frequency;
1753 /* SSE and Neon do best with the update size being a multiple of 4 */
1754 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1755 device->UpdateSize = (device->UpdateSize+3)&~3;
1757 if(freq != device->Frequency)
1758 UpdateClockBase(device);
1759 device->Frequency = freq;
1760 device->NumMonoSources = numMono;
1761 device->NumStereoSources = numStereo;
1762 device->NumAuxSends = numSends;
1765 if((device->Flags&DEVICE_RUNNING))
1766 return ALC_NO_ERROR;
1768 UpdateClockBase(device);
1770 oldFreq = device->Frequency;
1771 oldChans = device->FmtChans;
1772 oldType = device->FmtType;
1774 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1775 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"",
1776 DevFmtChannelsString(device->FmtChans),
1777 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"",
1778 DevFmtTypeString(device->FmtType),
1779 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"",
1780 device->Frequency,
1781 device->UpdateSize, device->NumUpdates);
1783 if(device->Type != Loopback)
1785 int nohrtf = !(device->Flags&DEVICE_HRTF_REQUEST);
1786 if(GetConfigValueBool(NULL, "hrtf", !nohrtf))
1787 device->Flags |= DEVICE_HRTF_REQUEST;
1788 else
1789 device->Flags &= ~DEVICE_HRTF_REQUEST;
1791 if((device->Flags&DEVICE_HRTF_REQUEST))
1793 enum DevFmtChannels chans = device->FmtChans;
1794 ALCuint freq = device->Frequency;
1795 if(FindHrtfFormat(&chans, &freq))
1797 if(device->Type != Loopback)
1799 device->Frequency = freq;
1800 device->FmtChans = chans;
1801 device->Flags |= DEVICE_CHANNELS_REQUEST |
1802 DEVICE_FREQUENCY_REQUEST;
1804 else if(device->Frequency != freq || device->FmtChans != chans)
1806 ERR("Requested format not HRTF compatible: %s, %uhz\n",
1807 DevFmtChannelsString(device->FmtChans), device->Frequency);
1808 device->Flags &= ~DEVICE_HRTF_REQUEST;
1813 if(V0(device->Backend,reset)() == ALC_FALSE)
1814 return ALC_INVALID_DEVICE;
1816 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1818 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1819 DevFmtChannelsString(device->FmtChans));
1820 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1822 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1824 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1825 DevFmtTypeString(device->FmtType));
1826 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1828 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1830 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1831 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1834 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1835 DevFmtChannelsString(device->FmtChans),
1836 DevFmtTypeString(device->FmtType), device->Frequency,
1837 device->UpdateSize, device->NumUpdates);
1839 aluInitPanning(device);
1841 V(device->Synth,update)(device);
1843 device->Hrtf = NULL;
1844 if((device->Flags&DEVICE_HRTF_REQUEST))
1846 device->Hrtf = GetHrtf(device->FmtChans, device->Frequency);
1847 if(!device->Hrtf)
1848 device->Flags &= ~DEVICE_HRTF_REQUEST;
1850 TRACE("HRTF %s\n", device->Hrtf?"enabled":"disabled");
1852 if(!device->Hrtf && device->Bs2bLevel > 0 && device->Bs2bLevel <= 6)
1854 if(!device->Bs2b)
1856 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
1857 bs2b_clear(device->Bs2b);
1859 bs2b_set_srate(device->Bs2b, device->Frequency);
1860 bs2b_set_level(device->Bs2b, device->Bs2bLevel);
1861 TRACE("BS2B level %d\n", device->Bs2bLevel);
1863 else
1865 free(device->Bs2b);
1866 device->Bs2b = NULL;
1867 TRACE("BS2B disabled\n");
1870 device->Flags &= ~DEVICE_WIDE_STEREO;
1871 if(device->Type != Loopback && !device->Hrtf && GetConfigValueBool(NULL, "wide-stereo", AL_FALSE))
1872 device->Flags |= DEVICE_WIDE_STEREO;
1874 if(!device->Hrtf && (device->UpdateSize&3))
1876 if((CPUCapFlags&CPU_CAP_SSE))
1877 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1878 if((CPUCapFlags&CPU_CAP_NEON))
1879 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1882 SetMixerFPUMode(&oldMode);
1883 ALCdevice_Lock(device);
1884 context = device->ContextList;
1885 while(context)
1887 ALsizei pos;
1889 context->UpdateSources = AL_FALSE;
1890 LockUIntMapRead(&context->EffectSlotMap);
1891 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
1893 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
1895 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
1897 UnlockUIntMapRead(&context->EffectSlotMap);
1898 ALCdevice_Unlock(device);
1899 RestoreFPUMode(&oldMode);
1900 return ALC_INVALID_DEVICE;
1902 slot->NeedsUpdate = AL_FALSE;
1903 V(slot->EffectState,update)(device, slot);
1905 UnlockUIntMapRead(&context->EffectSlotMap);
1907 LockUIntMapRead(&context->SourceMap);
1908 for(pos = 0;pos < context->SourceMap.size;pos++)
1910 ALsource *source = context->SourceMap.array[pos].value;
1911 ALuint s = device->NumAuxSends;
1912 while(s < MAX_SENDS)
1914 if(source->Send[s].Slot)
1915 DecrementRef(&source->Send[s].Slot->ref);
1916 source->Send[s].Slot = NULL;
1917 source->Send[s].Gain = 1.0f;
1918 source->Send[s].GainHF = 1.0f;
1919 s++;
1921 source->NeedsUpdate = AL_TRUE;
1923 UnlockUIntMapRead(&context->SourceMap);
1925 for(pos = 0;pos < context->ActiveSourceCount;pos++)
1927 ALactivesource *src = context->ActiveSources[pos];
1928 ALsource *source = src->Source;
1929 ALuint s = device->NumAuxSends;
1930 while(s < MAX_SENDS)
1932 src->Send[s].Moving = AL_FALSE;
1933 src->Send[s].Counter = 0;
1934 s++;
1937 src->Update(src, context);
1938 source->NeedsUpdate = AL_FALSE;
1941 context = context->next;
1943 if(device->DefaultSlot)
1945 ALeffectslot *slot = device->DefaultSlot;
1947 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
1949 ALCdevice_Unlock(device);
1950 RestoreFPUMode(&oldMode);
1951 return ALC_INVALID_DEVICE;
1953 slot->NeedsUpdate = AL_FALSE;
1954 V(slot->EffectState,update)(device, slot);
1956 ALCdevice_Unlock(device);
1957 RestoreFPUMode(&oldMode);
1959 if(!(device->Flags&DEVICE_PAUSED))
1961 if(V0(device->Backend,start)() == ALC_FALSE)
1962 return ALC_INVALID_DEVICE;
1963 device->Flags |= DEVICE_RUNNING;
1966 return ALC_NO_ERROR;
1969 /* FreeDevice
1971 * Frees the device structure, and destroys any objects the app failed to
1972 * delete. Called once there's no more references on the device.
1974 static ALCvoid FreeDevice(ALCdevice *device)
1976 TRACE("%p\n", device);
1978 V0(device->Backend,close)();
1979 DELETE_OBJ(device->Backend);
1980 device->Backend = NULL;
1982 DELETE_OBJ(device->Synth);
1983 device->Synth = NULL;
1985 if(device->DefaultSlot)
1987 ALeffectState *state = device->DefaultSlot->EffectState;
1988 device->DefaultSlot = NULL;
1989 DELETE_OBJ(state);
1992 if(device->DefaultSfont)
1993 ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
1994 device->DefaultSfont = NULL;
1996 if(device->BufferMap.size > 0)
1998 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
1999 ReleaseALBuffers(device);
2001 ResetUIntMap(&device->BufferMap);
2003 if(device->EffectMap.size > 0)
2005 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
2006 ReleaseALEffects(device);
2008 ResetUIntMap(&device->EffectMap);
2010 if(device->FilterMap.size > 0)
2012 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2013 ReleaseALFilters(device);
2015 ResetUIntMap(&device->FilterMap);
2017 if(device->SfontMap.size > 0)
2019 WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size);
2020 ReleaseALSoundfonts(device);
2022 ResetUIntMap(&device->SfontMap);
2024 if(device->PresetMap.size > 0)
2026 WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size);
2027 ReleaseALPresets(device);
2029 ResetUIntMap(&device->PresetMap);
2031 if(device->FontsoundMap.size > 0)
2033 WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size);
2034 ReleaseALFontsounds(device);
2036 ResetUIntMap(&device->FontsoundMap);
2038 free(device->Bs2b);
2039 device->Bs2b = NULL;
2041 AL_STRING_DEINIT(device->DeviceName);
2043 al_free(device);
2047 void ALCdevice_IncRef(ALCdevice *device)
2049 uint ref;
2050 ref = IncrementRef(&device->ref);
2051 TRACEREF("%p increasing refcount to %u\n", device, ref);
2054 void ALCdevice_DecRef(ALCdevice *device)
2056 uint ref;
2057 ref = DecrementRef(&device->ref);
2058 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2059 if(ref == 0) FreeDevice(device);
2062 /* VerifyDevice
2064 * Checks if the device handle is valid, and increments its ref count if so.
2066 static ALCdevice *VerifyDevice(ALCdevice *device)
2068 ALCdevice *tmpDevice;
2070 if(!device)
2071 return NULL;
2073 LockLists();
2074 tmpDevice = DeviceList;
2075 while(tmpDevice && tmpDevice != device)
2076 tmpDevice = tmpDevice->next;
2078 if(tmpDevice)
2079 ALCdevice_IncRef(tmpDevice);
2080 UnlockLists();
2081 return tmpDevice;
2085 /* InitContext
2087 * Initializes context fields
2089 static ALvoid InitContext(ALCcontext *Context)
2091 ALint i, j;
2093 //Initialise listener
2094 Context->Listener->Gain = 1.0f;
2095 Context->Listener->MetersPerUnit = 1.0f;
2096 Context->Listener->Position[0] = 0.0f;
2097 Context->Listener->Position[1] = 0.0f;
2098 Context->Listener->Position[2] = 0.0f;
2099 Context->Listener->Velocity[0] = 0.0f;
2100 Context->Listener->Velocity[1] = 0.0f;
2101 Context->Listener->Velocity[2] = 0.0f;
2102 Context->Listener->Forward[0] = 0.0f;
2103 Context->Listener->Forward[1] = 0.0f;
2104 Context->Listener->Forward[2] = -1.0f;
2105 Context->Listener->Up[0] = 0.0f;
2106 Context->Listener->Up[1] = 1.0f;
2107 Context->Listener->Up[2] = 0.0f;
2108 for(i = 0;i < 4;i++)
2110 for(j = 0;j < 4;j++)
2111 Context->Listener->Params.Matrix[i][j] = ((i==j) ? 1.0f : 0.0f);
2113 for(i = 0;i < 3;i++)
2114 Context->Listener->Params.Velocity[i] = 0.0f;
2116 //Validate Context
2117 Context->LastError = AL_NO_ERROR;
2118 Context->UpdateSources = AL_FALSE;
2119 Context->ActiveSourceCount = 0;
2120 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2121 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2123 //Set globals
2124 Context->DistanceModel = DefaultDistanceModel;
2125 Context->SourceDistanceModel = AL_FALSE;
2126 Context->DopplerFactor = 1.0f;
2127 Context->DopplerVelocity = 1.0f;
2128 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2129 Context->DeferUpdates = AL_FALSE;
2131 Context->ExtensionList = alExtList;
2135 /* FreeContext
2137 * Cleans up the context, and destroys any remaining objects the app failed to
2138 * delete. Called once there's no more references on the context.
2140 static ALCvoid FreeContext(ALCcontext *context)
2142 ALsizei i;
2144 TRACE("%p\n", context);
2146 if(context->SourceMap.size > 0)
2148 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2149 ReleaseALSources(context);
2151 ResetUIntMap(&context->SourceMap);
2153 if(context->EffectSlotMap.size > 0)
2155 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2156 ReleaseALAuxiliaryEffectSlots(context);
2158 ResetUIntMap(&context->EffectSlotMap);
2160 for(i = 0;i < context->MaxActiveSources;i++)
2162 al_free(context->ActiveSources[i]);
2163 context->ActiveSources[i] = NULL;
2165 free(context->ActiveSources);
2166 context->ActiveSources = NULL;
2167 context->ActiveSourceCount = 0;
2168 context->MaxActiveSources = 0;
2170 VECTOR_DEINIT(context->ActiveAuxSlots);
2172 ALCdevice_DecRef(context->Device);
2173 context->Device = NULL;
2175 //Invalidate context
2176 memset(context, 0, sizeof(ALCcontext));
2177 free(context);
2180 /* ReleaseContext
2182 * Removes the context reference from the given device and removes it from
2183 * being current on the running thread or globally.
2185 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2187 ALCcontext *volatile*tmp_ctx;
2189 if(altss_get(LocalContext) == context)
2191 WARN("%p released while current on thread\n", context);
2192 altss_set(LocalContext, NULL);
2193 ALCcontext_DecRef(context);
2196 if(CompExchangePtr((XchgPtr*)&GlobalContext, context, NULL) == context)
2197 ALCcontext_DecRef(context);
2199 ALCdevice_Lock(device);
2200 tmp_ctx = &device->ContextList;
2201 while(*tmp_ctx)
2203 if(CompExchangePtr((XchgPtr*)tmp_ctx, context, context->next) == context)
2204 break;
2205 tmp_ctx = &(*tmp_ctx)->next;
2207 ALCdevice_Unlock(device);
2209 ALCcontext_DecRef(context);
2212 void ALCcontext_IncRef(ALCcontext *context)
2214 uint ref;
2215 ref = IncrementRef(&context->ref);
2216 TRACEREF("%p increasing refcount to %u\n", context, ref);
2219 void ALCcontext_DecRef(ALCcontext *context)
2221 uint ref;
2222 ref = DecrementRef(&context->ref);
2223 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2224 if(ref == 0) FreeContext(context);
2227 static void ReleaseThreadCtx(void *ptr)
2229 WARN("%p current for thread being destroyed\n", ptr);
2230 ALCcontext_DecRef(ptr);
2233 /* VerifyContext
2235 * Checks that the given context is valid, and increments its reference count.
2237 static ALCcontext *VerifyContext(ALCcontext *context)
2239 ALCdevice *dev;
2241 LockLists();
2242 dev = DeviceList;
2243 while(dev)
2245 ALCcontext *tmp_ctx = dev->ContextList;
2246 while(tmp_ctx)
2248 if(tmp_ctx == context)
2250 ALCcontext_IncRef(tmp_ctx);
2251 UnlockLists();
2252 return tmp_ctx;
2254 tmp_ctx = tmp_ctx->next;
2256 dev = dev->next;
2258 UnlockLists();
2260 return NULL;
2264 /* GetContextRef
2266 * Returns the currently active context for this thread, and adds a reference
2267 * without locking it.
2269 ALCcontext *GetContextRef(void)
2271 ALCcontext *context;
2273 context = altss_get(LocalContext);
2274 if(context)
2275 ALCcontext_IncRef(context);
2276 else
2278 LockLists();
2279 context = GlobalContext;
2280 if(context)
2281 ALCcontext_IncRef(context);
2282 UnlockLists();
2285 return context;
2289 /************************************************
2290 * Standard ALC functions
2291 ************************************************/
2293 /* alcGetError
2295 * Return last ALC generated error code for the given device
2297 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2299 ALCenum errorCode;
2301 if(VerifyDevice(device))
2303 errorCode = ExchangeInt(&device->LastError, ALC_NO_ERROR);
2304 ALCdevice_DecRef(device);
2306 else
2307 errorCode = ExchangeInt(&LastNullDeviceError, ALC_NO_ERROR);
2309 return errorCode;
2313 /* alcSuspendContext
2315 * Not functional
2317 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *UNUSED(context))
2321 /* alcProcessContext
2323 * Not functional
2325 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *UNUSED(context))
2330 /* alcGetString
2332 * Returns information about the device, and error strings
2334 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2336 const ALCchar *value = NULL;
2338 switch(param)
2340 case ALC_NO_ERROR:
2341 value = alcNoError;
2342 break;
2344 case ALC_INVALID_ENUM:
2345 value = alcErrInvalidEnum;
2346 break;
2348 case ALC_INVALID_VALUE:
2349 value = alcErrInvalidValue;
2350 break;
2352 case ALC_INVALID_DEVICE:
2353 value = alcErrInvalidDevice;
2354 break;
2356 case ALC_INVALID_CONTEXT:
2357 value = alcErrInvalidContext;
2358 break;
2360 case ALC_OUT_OF_MEMORY:
2361 value = alcErrOutOfMemory;
2362 break;
2364 case ALC_DEVICE_SPECIFIER:
2365 value = alcDefaultName;
2366 break;
2368 case ALC_ALL_DEVICES_SPECIFIER:
2369 if(VerifyDevice(Device))
2371 value = al_string_get_cstr(Device->DeviceName);
2372 ALCdevice_DecRef(Device);
2374 else
2376 ProbeAllDevicesList();
2377 value = al_string_get_cstr(alcAllDevicesList);
2379 break;
2381 case ALC_CAPTURE_DEVICE_SPECIFIER:
2382 if(VerifyDevice(Device))
2384 value = al_string_get_cstr(Device->DeviceName);
2385 ALCdevice_DecRef(Device);
2387 else
2389 ProbeCaptureDeviceList();
2390 value = al_string_get_cstr(alcCaptureDeviceList);
2392 break;
2394 /* Default devices are always first in the list */
2395 case ALC_DEFAULT_DEVICE_SPECIFIER:
2396 value = alcDefaultName;
2397 break;
2399 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2400 if(al_string_empty(alcAllDevicesList))
2401 ProbeAllDevicesList();
2403 Device = VerifyDevice(Device);
2405 free(alcDefaultAllDevicesSpecifier);
2406 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2407 if(!alcDefaultAllDevicesSpecifier)
2408 alcSetError(Device, ALC_OUT_OF_MEMORY);
2410 value = alcDefaultAllDevicesSpecifier;
2411 if(Device) ALCdevice_DecRef(Device);
2412 break;
2414 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2415 if(al_string_empty(alcCaptureDeviceList))
2416 ProbeCaptureDeviceList();
2418 Device = VerifyDevice(Device);
2420 free(alcCaptureDefaultDeviceSpecifier);
2421 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2422 if(!alcCaptureDefaultDeviceSpecifier)
2423 alcSetError(Device, ALC_OUT_OF_MEMORY);
2425 value = alcCaptureDefaultDeviceSpecifier;
2426 if(Device) ALCdevice_DecRef(Device);
2427 break;
2429 case ALC_EXTENSIONS:
2430 if(!VerifyDevice(Device))
2431 value = alcNoDeviceExtList;
2432 else
2434 value = alcExtensionList;
2435 ALCdevice_DecRef(Device);
2437 break;
2439 default:
2440 Device = VerifyDevice(Device);
2441 alcSetError(Device, ALC_INVALID_ENUM);
2442 if(Device) ALCdevice_DecRef(Device);
2443 break;
2446 return value;
2450 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2452 ALCsizei i;
2454 if(size <= 0 || values == NULL)
2456 alcSetError(device, ALC_INVALID_VALUE);
2457 return 0;
2460 if(!device)
2462 switch(param)
2464 case ALC_MAJOR_VERSION:
2465 values[0] = alcMajorVersion;
2466 return 1;
2467 case ALC_MINOR_VERSION:
2468 values[0] = alcMinorVersion;
2469 return 1;
2471 case ALC_ATTRIBUTES_SIZE:
2472 case ALC_ALL_ATTRIBUTES:
2473 case ALC_FREQUENCY:
2474 case ALC_REFRESH:
2475 case ALC_SYNC:
2476 case ALC_MONO_SOURCES:
2477 case ALC_STEREO_SOURCES:
2478 case ALC_CAPTURE_SAMPLES:
2479 case ALC_FORMAT_CHANNELS_SOFT:
2480 case ALC_FORMAT_TYPE_SOFT:
2481 alcSetError(NULL, ALC_INVALID_DEVICE);
2482 return 0;
2484 default:
2485 alcSetError(NULL, ALC_INVALID_ENUM);
2486 return 0;
2488 return 0;
2491 if(device->Type == Capture)
2493 switch(param)
2495 case ALC_CAPTURE_SAMPLES:
2496 ALCdevice_Lock(device);
2497 values[0] = V0(device->Backend,availableSamples)();
2498 ALCdevice_Unlock(device);
2499 return 1;
2501 case ALC_CONNECTED:
2502 values[0] = device->Connected;
2503 return 1;
2505 default:
2506 alcSetError(device, ALC_INVALID_ENUM);
2507 return 0;
2509 return 0;
2512 /* render device */
2513 switch(param)
2515 case ALC_MAJOR_VERSION:
2516 values[0] = alcMajorVersion;
2517 return 1;
2519 case ALC_MINOR_VERSION:
2520 values[0] = alcMinorVersion;
2521 return 1;
2523 case ALC_EFX_MAJOR_VERSION:
2524 values[0] = alcEFXMajorVersion;
2525 return 1;
2527 case ALC_EFX_MINOR_VERSION:
2528 values[0] = alcEFXMinorVersion;
2529 return 1;
2531 case ALC_ATTRIBUTES_SIZE:
2532 values[0] = 15;
2533 return 1;
2535 case ALC_ALL_ATTRIBUTES:
2536 if(size < 15)
2538 alcSetError(device, ALC_INVALID_VALUE);
2539 return 0;
2542 i = 0;
2543 values[i++] = ALC_FREQUENCY;
2544 values[i++] = device->Frequency;
2546 if(device->Type != Loopback)
2548 values[i++] = ALC_REFRESH;
2549 values[i++] = device->Frequency / device->UpdateSize;
2551 values[i++] = ALC_SYNC;
2552 values[i++] = ALC_FALSE;
2554 else
2556 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2557 values[i++] = device->FmtChans;
2559 values[i++] = ALC_FORMAT_TYPE_SOFT;
2560 values[i++] = device->FmtType;
2563 values[i++] = ALC_MONO_SOURCES;
2564 values[i++] = device->NumMonoSources;
2566 values[i++] = ALC_STEREO_SOURCES;
2567 values[i++] = device->NumStereoSources;
2569 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2570 values[i++] = device->NumAuxSends;
2572 values[i++] = ALC_HRTF_SOFT;
2573 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2575 values[i++] = 0;
2576 return i;
2578 case ALC_FREQUENCY:
2579 values[0] = device->Frequency;
2580 return 1;
2582 case ALC_REFRESH:
2583 if(device->Type == Loopback)
2585 alcSetError(device, ALC_INVALID_DEVICE);
2586 return 0;
2588 values[0] = device->Frequency / device->UpdateSize;
2589 return 1;
2591 case ALC_SYNC:
2592 if(device->Type == Loopback)
2594 alcSetError(device, ALC_INVALID_DEVICE);
2595 return 0;
2597 values[0] = ALC_FALSE;
2598 return 1;
2600 case ALC_FORMAT_CHANNELS_SOFT:
2601 if(device->Type != Loopback)
2603 alcSetError(device, ALC_INVALID_DEVICE);
2604 return 0;
2606 values[0] = device->FmtChans;
2607 return 1;
2609 case ALC_FORMAT_TYPE_SOFT:
2610 if(device->Type != Loopback)
2612 alcSetError(device, ALC_INVALID_DEVICE);
2613 return 0;
2615 values[0] = device->FmtType;
2616 return 1;
2618 case ALC_MONO_SOURCES:
2619 values[0] = device->NumMonoSources;
2620 return 1;
2622 case ALC_STEREO_SOURCES:
2623 values[0] = device->NumStereoSources;
2624 return 1;
2626 case ALC_MAX_AUXILIARY_SENDS:
2627 values[0] = device->NumAuxSends;
2628 return 1;
2630 case ALC_CONNECTED:
2631 values[0] = device->Connected;
2632 return 1;
2634 case ALC_HRTF_SOFT:
2635 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2636 return 1;
2638 default:
2639 alcSetError(device, ALC_INVALID_ENUM);
2640 return 0;
2642 return 0;
2645 /* alcGetIntegerv
2647 * Returns information about the device and the version of OpenAL
2649 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2651 device = VerifyDevice(device);
2652 if(size <= 0 || values == NULL)
2653 alcSetError(device, ALC_INVALID_VALUE);
2654 else
2655 GetIntegerv(device, param, size, values);
2656 if(device) ALCdevice_DecRef(device);
2659 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2661 ALCint *ivals;
2662 ALsizei i;
2664 device = VerifyDevice(device);
2665 if(size <= 0 || values == NULL)
2666 alcSetError(device, ALC_INVALID_VALUE);
2667 else if(!device || device->Type == Capture)
2669 ivals = malloc(size * sizeof(ALCint));
2670 size = GetIntegerv(device, pname, size, ivals);
2671 for(i = 0;i < size;i++)
2672 values[i] = ivals[i];
2673 free(ivals);
2675 else /* render device */
2677 switch(pname)
2679 case ALC_ATTRIBUTES_SIZE:
2680 *values = 17;
2681 break;
2683 case ALC_ALL_ATTRIBUTES:
2684 if(size < 17)
2685 alcSetError(device, ALC_INVALID_VALUE);
2686 else
2688 int i = 0;
2690 V0(device->Backend,lock)();
2691 values[i++] = ALC_FREQUENCY;
2692 values[i++] = device->Frequency;
2694 if(device->Type != Loopback)
2696 values[i++] = ALC_REFRESH;
2697 values[i++] = device->Frequency / device->UpdateSize;
2699 values[i++] = ALC_SYNC;
2700 values[i++] = ALC_FALSE;
2702 else
2704 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2705 values[i++] = device->FmtChans;
2707 values[i++] = ALC_FORMAT_TYPE_SOFT;
2708 values[i++] = device->FmtType;
2711 values[i++] = ALC_MONO_SOURCES;
2712 values[i++] = device->NumMonoSources;
2714 values[i++] = ALC_STEREO_SOURCES;
2715 values[i++] = device->NumStereoSources;
2717 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2718 values[i++] = device->NumAuxSends;
2720 values[i++] = ALC_HRTF_SOFT;
2721 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2723 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2724 values[i++] = device->ClockBase +
2725 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2727 values[i++] = 0;
2728 V0(device->Backend,unlock)();
2730 break;
2732 case ALC_DEVICE_CLOCK_SOFT:
2733 V0(device->Backend,lock)();
2734 *values = device->ClockBase +
2735 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2736 V0(device->Backend,unlock)();
2737 break;
2739 default:
2740 ivals = malloc(size * sizeof(ALCint));
2741 size = GetIntegerv(device, pname, size, ivals);
2742 for(i = 0;i < size;i++)
2743 values[i] = ivals[i];
2744 free(ivals);
2745 break;
2748 if(device)
2749 ALCdevice_DecRef(device);
2753 /* alcIsExtensionPresent
2755 * Determines if there is support for a particular extension
2757 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2759 ALCboolean bResult = ALC_FALSE;
2761 device = VerifyDevice(device);
2763 if(!extName)
2764 alcSetError(device, ALC_INVALID_VALUE);
2765 else
2767 size_t len = strlen(extName);
2768 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2769 while(ptr && *ptr)
2771 if(strncasecmp(ptr, extName, len) == 0 &&
2772 (ptr[len] == '\0' || isspace(ptr[len])))
2774 bResult = ALC_TRUE;
2775 break;
2777 if((ptr=strchr(ptr, ' ')) != NULL)
2779 do {
2780 ++ptr;
2781 } while(isspace(*ptr));
2785 if(device)
2786 ALCdevice_DecRef(device);
2787 return bResult;
2791 /* alcGetProcAddress
2793 * Retrieves the function address for a particular extension function
2795 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2797 ALCvoid *ptr = NULL;
2799 if(!funcName)
2801 device = VerifyDevice(device);
2802 alcSetError(device, ALC_INVALID_VALUE);
2803 if(device) ALCdevice_DecRef(device);
2805 else
2807 ALsizei i = 0;
2808 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
2809 i++;
2810 ptr = alcFunctions[i].address;
2813 return ptr;
2817 /* alcGetEnumValue
2819 * Get the value for a particular ALC enumeration name
2821 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
2823 ALCenum val = 0;
2825 if(!enumName)
2827 device = VerifyDevice(device);
2828 alcSetError(device, ALC_INVALID_VALUE);
2829 if(device) ALCdevice_DecRef(device);
2831 else
2833 ALsizei i = 0;
2834 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
2835 i++;
2836 val = enumeration[i].value;
2839 return val;
2843 /* alcCreateContext
2845 * Create and attach a context to the given device.
2847 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
2849 ALCcontext *ALContext;
2850 ALCenum err;
2852 LockLists();
2853 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
2855 UnlockLists();
2856 alcSetError(device, ALC_INVALID_DEVICE);
2857 if(device) ALCdevice_DecRef(device);
2858 return NULL;
2861 device->LastError = ALC_NO_ERROR;
2863 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
2865 UnlockLists();
2866 alcSetError(device, err);
2867 if(err == ALC_INVALID_DEVICE)
2869 ALCdevice_Lock(device);
2870 aluHandleDisconnect(device);
2871 ALCdevice_Unlock(device);
2873 ALCdevice_DecRef(device);
2874 return NULL;
2877 ALContext = calloc(1, sizeof(ALCcontext)+sizeof(ALlistener));
2878 if(ALContext)
2880 InitRef(&ALContext->ref, 1);
2881 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
2883 VECTOR_INIT(ALContext->ActiveAuxSlots);
2885 ALContext->MaxActiveSources = 256;
2886 ALContext->ActiveSources = calloc(ALContext->MaxActiveSources,
2887 sizeof(ALContext->ActiveSources[0]));
2889 if(!ALContext || !ALContext->ActiveSources)
2891 if(!device->ContextList)
2893 V0(device->Backend,stop)();
2894 device->Flags &= ~DEVICE_RUNNING;
2896 UnlockLists();
2898 if(ALContext)
2900 free(ALContext->ActiveSources);
2901 ALContext->ActiveSources = NULL;
2903 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
2905 free(ALContext);
2906 ALContext = NULL;
2909 alcSetError(device, ALC_OUT_OF_MEMORY);
2910 ALCdevice_DecRef(device);
2911 return NULL;
2914 ALContext->Device = device;
2915 ALCdevice_IncRef(device);
2916 InitContext(ALContext);
2918 do {
2919 ALContext->next = device->ContextList;
2920 } while(CompExchangePtr((XchgPtr*)&device->ContextList, ALContext->next, ALContext) != ALContext->next);
2921 UnlockLists();
2923 ALCdevice_DecRef(device);
2925 TRACE("Created context %p\n", ALContext);
2926 return ALContext;
2929 /* alcDestroyContext
2931 * Remove a context from its device
2933 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
2935 ALCdevice *Device;
2937 LockLists();
2938 /* alcGetContextsDevice sets an error for invalid contexts */
2939 Device = alcGetContextsDevice(context);
2940 if(Device)
2942 ReleaseContext(context, Device);
2943 if(!Device->ContextList)
2945 V0(Device->Backend,stop)();
2946 Device->Flags &= ~DEVICE_RUNNING;
2949 UnlockLists();
2953 /* alcGetCurrentContext
2955 * Returns the currently active context on the calling thread
2957 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
2959 ALCcontext *Context;
2961 Context = altss_get(LocalContext);
2962 if(!Context) Context = GlobalContext;
2964 return Context;
2967 /* alcGetThreadContext
2969 * Returns the currently active thread-local context
2971 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
2973 ALCcontext *Context;
2974 Context = altss_get(LocalContext);
2975 return Context;
2979 /* alcMakeContextCurrent
2981 * Makes the given context the active process-wide context, and removes the
2982 * thread-local context for the calling thread.
2984 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
2986 /* context must be valid or NULL */
2987 if(context && !(context=VerifyContext(context)))
2989 alcSetError(NULL, ALC_INVALID_CONTEXT);
2990 return ALC_FALSE;
2992 /* context's reference count is already incremented */
2993 context = ExchangePtr((XchgPtr*)&GlobalContext, context);
2994 if(context) ALCcontext_DecRef(context);
2996 if((context=altss_get(LocalContext)) != NULL)
2998 altss_set(LocalContext, NULL);
2999 ALCcontext_DecRef(context);
3002 return ALC_TRUE;
3005 /* alcSetThreadContext
3007 * Makes the given context the active context for the current thread
3009 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3011 ALCcontext *old;
3013 /* context must be valid or NULL */
3014 if(context && !(context=VerifyContext(context)))
3016 alcSetError(NULL, ALC_INVALID_CONTEXT);
3017 return ALC_FALSE;
3019 /* context's reference count is already incremented */
3020 old = altss_get(LocalContext);
3021 altss_set(LocalContext, context);
3022 if(old) ALCcontext_DecRef(old);
3024 return ALC_TRUE;
3028 /* alcGetContextsDevice
3030 * Returns the device that a particular context is attached to
3032 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3034 ALCdevice *Device;
3036 if(!(Context=VerifyContext(Context)))
3038 alcSetError(NULL, ALC_INVALID_CONTEXT);
3039 return NULL;
3041 Device = Context->Device;
3042 ALCcontext_DecRef(Context);
3044 return Device;
3048 /* alcOpenDevice
3050 * Opens the named device.
3052 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3054 const ALCchar *fmt;
3055 ALCdevice *device;
3056 ALCenum err;
3058 DO_INITCONFIG();
3060 if(!PlaybackBackend.name)
3062 alcSetError(NULL, ALC_INVALID_VALUE);
3063 return NULL;
3066 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3067 deviceName = NULL;
3069 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3070 if(!device)
3072 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3073 return NULL;
3076 //Validate device
3077 InitRef(&device->ref, 1);
3078 device->Connected = ALC_TRUE;
3079 device->Type = Playback;
3080 device->LastError = ALC_NO_ERROR;
3082 device->Flags = 0;
3083 device->Bs2b = NULL;
3084 device->Bs2bLevel = 0;
3085 AL_STRING_INIT(device->DeviceName);
3087 device->ContextList = NULL;
3089 device->ClockBase = 0;
3090 device->SamplesDone = 0;
3092 device->MaxNoOfSources = 256;
3093 device->AuxiliaryEffectSlotMax = 4;
3094 device->NumAuxSends = MAX_SENDS;
3096 InitUIntMap(&device->BufferMap, ~0);
3097 InitUIntMap(&device->EffectMap, ~0);
3098 InitUIntMap(&device->FilterMap, ~0);
3099 InitUIntMap(&device->SfontMap, ~0);
3100 InitUIntMap(&device->PresetMap, ~0);
3101 InitUIntMap(&device->FontsoundMap, ~0);
3103 //Set output format
3104 device->FmtChans = DevFmtChannelsDefault;
3105 device->FmtType = DevFmtTypeDefault;
3106 device->Frequency = DEFAULT_OUTPUT_RATE;
3107 device->NumUpdates = 4;
3108 device->UpdateSize = 1024;
3110 if(!PlaybackBackend.getFactory)
3111 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3112 ALCbackend_Playback);
3113 else
3115 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3116 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3118 if(!device->Backend)
3120 al_free(device);
3121 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3122 return NULL;
3126 if(ConfigValueStr(NULL, "channels", &fmt))
3128 static const struct {
3129 const char name[16];
3130 enum DevFmtChannels chans;
3131 } chanlist[] = {
3132 { "mono", DevFmtMono },
3133 { "stereo", DevFmtStereo },
3134 { "quad", DevFmtQuad },
3135 { "surround51", DevFmtX51 },
3136 { "surround61", DevFmtX61 },
3137 { "surround71", DevFmtX71 },
3139 size_t i;
3141 for(i = 0;i < COUNTOF(chanlist);i++)
3143 if(strcasecmp(chanlist[i].name, fmt) == 0)
3145 device->FmtChans = chanlist[i].chans;
3146 device->Flags |= DEVICE_CHANNELS_REQUEST;
3147 break;
3150 if(i == COUNTOF(chanlist))
3151 ERR("Unsupported channels: %s\n", fmt);
3153 if(ConfigValueStr(NULL, "sample-type", &fmt))
3155 static const struct {
3156 const char name[16];
3157 enum DevFmtType type;
3158 } typelist[] = {
3159 { "int8", DevFmtByte },
3160 { "uint8", DevFmtUByte },
3161 { "int16", DevFmtShort },
3162 { "uint16", DevFmtUShort },
3163 { "int32", DevFmtInt },
3164 { "uint32", DevFmtUInt },
3165 { "float32", DevFmtFloat },
3167 size_t i;
3169 for(i = 0;i < COUNTOF(typelist);i++)
3171 if(strcasecmp(typelist[i].name, fmt) == 0)
3173 device->FmtType = typelist[i].type;
3174 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3175 break;
3178 if(i == COUNTOF(typelist))
3179 ERR("Unsupported sample-type: %s\n", fmt);
3181 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3182 if((device->Flags&DEVICE_FORMAT_REQUEST) != DEVICE_FORMAT_REQUEST &&
3183 ConfigValueStr(NULL, "format", &fmt))
3185 static const struct {
3186 const char name[32];
3187 enum DevFmtChannels channels;
3188 enum DevFmtType type;
3189 } formats[] = {
3190 { "AL_FORMAT_MONO32", DevFmtMono, DevFmtFloat },
3191 { "AL_FORMAT_STEREO32", DevFmtStereo, DevFmtFloat },
3192 { "AL_FORMAT_QUAD32", DevFmtQuad, DevFmtFloat },
3193 { "AL_FORMAT_51CHN32", DevFmtX51, DevFmtFloat },
3194 { "AL_FORMAT_61CHN32", DevFmtX61, DevFmtFloat },
3195 { "AL_FORMAT_71CHN32", DevFmtX71, DevFmtFloat },
3197 { "AL_FORMAT_MONO16", DevFmtMono, DevFmtShort },
3198 { "AL_FORMAT_STEREO16", DevFmtStereo, DevFmtShort },
3199 { "AL_FORMAT_QUAD16", DevFmtQuad, DevFmtShort },
3200 { "AL_FORMAT_51CHN16", DevFmtX51, DevFmtShort },
3201 { "AL_FORMAT_61CHN16", DevFmtX61, DevFmtShort },
3202 { "AL_FORMAT_71CHN16", DevFmtX71, DevFmtShort },
3204 { "AL_FORMAT_MONO8", DevFmtMono, DevFmtByte },
3205 { "AL_FORMAT_STEREO8", DevFmtStereo, DevFmtByte },
3206 { "AL_FORMAT_QUAD8", DevFmtQuad, DevFmtByte },
3207 { "AL_FORMAT_51CHN8", DevFmtX51, DevFmtByte },
3208 { "AL_FORMAT_61CHN8", DevFmtX61, DevFmtByte },
3209 { "AL_FORMAT_71CHN8", DevFmtX71, DevFmtByte }
3211 size_t i;
3213 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3214 for(i = 0;i < COUNTOF(formats);i++)
3216 if(strcasecmp(fmt, formats[i].name) == 0)
3218 if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
3219 device->FmtChans = formats[i].channels;
3220 if(!(device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
3221 device->FmtType = formats[i].type;
3222 device->Flags |= DEVICE_FORMAT_REQUEST;
3223 break;
3226 if(i == COUNTOF(formats))
3227 ERR("Unsupported format: %s\n", fmt);
3229 #undef DEVICE_FORMAT_REQUEST
3231 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
3233 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3234 if(device->Frequency < MIN_OUTPUT_RATE)
3235 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3236 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3239 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
3240 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3242 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
3243 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3244 if((CPUCapFlags&CPU_CAP_SSE))
3245 device->UpdateSize = (device->UpdateSize+3)&~3;
3247 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3248 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3250 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3251 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3253 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3254 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3256 ConfigValueInt(NULL, "cf_level", &device->Bs2bLevel);
3258 device->NumStereoSources = 1;
3259 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3261 device->Synth = SynthCreate(device);
3262 if(!device->Synth)
3264 DELETE_OBJ(device->Backend);
3265 al_free(device);
3266 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3267 return NULL;
3270 // Find a playback device to open
3271 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3273 DELETE_OBJ(device->Synth);
3274 DELETE_OBJ(device->Backend);
3275 al_free(device);
3276 alcSetError(NULL, err);
3277 return NULL;
3280 if(DefaultEffect.type != AL_EFFECT_NULL)
3282 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3283 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3285 device->DefaultSlot = NULL;
3286 ERR("Failed to initialize the default effect slot\n");
3288 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3290 ALeffectState *state = device->DefaultSlot->EffectState;
3291 device->DefaultSlot = NULL;
3292 DELETE_OBJ(state);
3293 ERR("Failed to initialize the default effect\n");
3297 do {
3298 device->next = DeviceList;
3299 } while(CompExchangePtr((XchgPtr*)&DeviceList, device->next, device) != device->next);
3301 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3302 return device;
3305 /* alcCloseDevice
3307 * Closes the given device.
3309 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *Device)
3311 ALCdevice *volatile*list;
3312 ALCcontext *ctx;
3314 LockLists();
3315 list = &DeviceList;
3316 while(*list && *list != Device)
3317 list = &(*list)->next;
3319 if(!*list || (*list)->Type == Capture)
3321 alcSetError(*list, ALC_INVALID_DEVICE);
3322 UnlockLists();
3323 return ALC_FALSE;
3326 *list = (*list)->next;
3327 UnlockLists();
3329 while((ctx=Device->ContextList) != NULL)
3331 WARN("Releasing context %p\n", ctx);
3332 ReleaseContext(ctx, Device);
3334 if((Device->Flags&DEVICE_RUNNING))
3335 V0(Device->Backend,stop)();
3336 Device->Flags &= ~DEVICE_RUNNING;
3338 ALCdevice_DecRef(Device);
3340 return ALC_TRUE;
3344 /************************************************
3345 * ALC capture functions
3346 ************************************************/
3347 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3349 ALCdevice *device = NULL;
3350 ALCenum err;
3352 DO_INITCONFIG();
3354 if(!CaptureBackend.name)
3356 alcSetError(NULL, ALC_INVALID_VALUE);
3357 return NULL;
3360 if(samples <= 0)
3362 alcSetError(NULL, ALC_INVALID_VALUE);
3363 return NULL;
3366 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3367 deviceName = NULL;
3369 device = al_calloc(16, sizeof(ALCdevice));
3370 if(!device)
3372 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3373 return NULL;
3376 //Validate device
3377 InitRef(&device->ref, 1);
3378 device->Connected = ALC_TRUE;
3379 device->Type = Capture;
3381 AL_STRING_INIT(device->DeviceName);
3383 InitUIntMap(&device->BufferMap, ~0);
3384 InitUIntMap(&device->EffectMap, ~0);
3385 InitUIntMap(&device->FilterMap, ~0);
3386 InitUIntMap(&device->SfontMap, ~0);
3387 InitUIntMap(&device->PresetMap, ~0);
3388 InitUIntMap(&device->FontsoundMap, ~0);
3390 if(!CaptureBackend.getFactory)
3391 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3392 ALCbackend_Capture);
3393 else
3395 ALCbackendFactory *factory = CaptureBackend.getFactory();
3396 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3398 if(!device->Backend)
3400 al_free(device);
3401 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3402 return NULL;
3405 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3406 device->Frequency = frequency;
3408 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3409 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3411 al_free(device);
3412 alcSetError(NULL, ALC_INVALID_ENUM);
3413 return NULL;
3416 device->UpdateSize = samples;
3417 device->NumUpdates = 1;
3419 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3421 al_free(device);
3422 alcSetError(NULL, err);
3423 return NULL;
3426 do {
3427 device->next = DeviceList;
3428 } while(CompExchangePtr((XchgPtr*)&DeviceList, device->next, device) != device->next);
3430 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3431 return device;
3434 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *Device)
3436 ALCdevice *volatile*list;
3438 LockLists();
3439 list = &DeviceList;
3440 while(*list && *list != Device)
3441 list = &(*list)->next;
3443 if(!*list || (*list)->Type != Capture)
3445 alcSetError(*list, ALC_INVALID_DEVICE);
3446 UnlockLists();
3447 return ALC_FALSE;
3450 *list = (*list)->next;
3451 UnlockLists();
3453 ALCdevice_DecRef(Device);
3455 return ALC_TRUE;
3458 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3460 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3461 alcSetError(device, ALC_INVALID_DEVICE);
3462 else
3464 ALCdevice_Lock(device);
3465 if(device->Connected)
3467 if(!(device->Flags&DEVICE_RUNNING))
3468 V0(device->Backend,start)();
3469 device->Flags |= DEVICE_RUNNING;
3471 ALCdevice_Unlock(device);
3474 if(device) ALCdevice_DecRef(device);
3477 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3479 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3480 alcSetError(device, ALC_INVALID_DEVICE);
3481 else
3483 ALCdevice_Lock(device);
3484 if((device->Flags&DEVICE_RUNNING))
3485 V0(device->Backend,stop)();
3486 device->Flags &= ~DEVICE_RUNNING;
3487 ALCdevice_Unlock(device);
3490 if(device) ALCdevice_DecRef(device);
3493 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3495 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3496 alcSetError(device, ALC_INVALID_DEVICE);
3497 else
3499 ALCenum err = ALC_INVALID_VALUE;
3501 ALCdevice_Lock(device);
3502 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3503 err = V(device->Backend,captureSamples)(buffer, samples);
3504 ALCdevice_Unlock(device);
3506 if(err != ALC_NO_ERROR)
3507 alcSetError(device, err);
3509 if(device) ALCdevice_DecRef(device);
3513 /************************************************
3514 * ALC loopback functions
3515 ************************************************/
3517 /* alcLoopbackOpenDeviceSOFT
3519 * Open a loopback device, for manual rendering.
3521 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3523 ALCbackendFactory *factory;
3524 ALCdevice *device;
3526 DO_INITCONFIG();
3528 /* Make sure the device name, if specified, is us. */
3529 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3531 alcSetError(NULL, ALC_INVALID_VALUE);
3532 return NULL;
3535 device = al_calloc(16, sizeof(ALCdevice));
3536 if(!device)
3538 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3539 return NULL;
3542 //Validate device
3543 InitRef(&device->ref, 1);
3544 device->Connected = ALC_TRUE;
3545 device->Type = Loopback;
3546 device->LastError = ALC_NO_ERROR;
3548 device->Flags = 0;
3549 device->Bs2b = NULL;
3550 device->Bs2bLevel = 0;
3551 AL_STRING_INIT(device->DeviceName);
3553 device->ContextList = NULL;
3555 device->ClockBase = 0;
3556 device->SamplesDone = 0;
3558 device->MaxNoOfSources = 256;
3559 device->AuxiliaryEffectSlotMax = 4;
3560 device->NumAuxSends = MAX_SENDS;
3562 InitUIntMap(&device->BufferMap, ~0);
3563 InitUIntMap(&device->EffectMap, ~0);
3564 InitUIntMap(&device->FilterMap, ~0);
3565 InitUIntMap(&device->SfontMap, ~0);
3566 InitUIntMap(&device->PresetMap, ~0);
3567 InitUIntMap(&device->FontsoundMap, ~0);
3569 factory = ALCloopbackFactory_getFactory();
3570 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3571 if(!device->Backend)
3573 al_free(device);
3574 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3575 return NULL;
3578 //Set output format
3579 device->NumUpdates = 0;
3580 device->UpdateSize = 0;
3582 device->Frequency = DEFAULT_OUTPUT_RATE;
3583 device->FmtChans = DevFmtChannelsDefault;
3584 device->FmtType = DevFmtTypeDefault;
3586 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3587 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3589 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3590 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3592 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3593 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3595 device->NumStereoSources = 1;
3596 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3598 device->Synth = SynthCreate(device);
3599 if(!device->Synth)
3601 DELETE_OBJ(device->Backend);
3602 al_free(device);
3603 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3604 return NULL;
3607 // Open the "backend"
3608 V(device->Backend,open)("Loopback");
3609 do {
3610 device->next = DeviceList;
3611 } while(CompExchangePtr((XchgPtr*)&DeviceList, device->next, device) != device->next);
3613 TRACE("Created device %p\n", device);
3614 return device;
3617 /* alcIsRenderFormatSupportedSOFT
3619 * Determines if the loopback device supports the given format for rendering.
3621 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3623 ALCboolean ret = ALC_FALSE;
3625 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3626 alcSetError(device, ALC_INVALID_DEVICE);
3627 else if(freq <= 0)
3628 alcSetError(device, ALC_INVALID_VALUE);
3629 else
3631 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3632 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3633 freq >= MIN_OUTPUT_RATE)
3634 ret = ALC_TRUE;
3636 if(device) ALCdevice_DecRef(device);
3638 return ret;
3641 /* alcRenderSamplesSOFT
3643 * Renders some samples into a buffer, using the format last set by the
3644 * attributes given to alcCreateContext.
3646 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3648 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3649 alcSetError(device, ALC_INVALID_DEVICE);
3650 else if(samples < 0 || (samples > 0 && buffer == NULL))
3651 alcSetError(device, ALC_INVALID_VALUE);
3652 else
3653 aluMixData(device, buffer, samples);
3654 if(device) ALCdevice_DecRef(device);
3658 /************************************************
3659 * ALC DSP pause/resume functions
3660 ************************************************/
3662 /* alcDevicePauseSOFT
3664 * Pause the DSP to stop audio processing.
3666 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3668 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3669 alcSetError(device, ALC_INVALID_DEVICE);
3670 else
3672 LockLists();
3673 if((device->Flags&DEVICE_RUNNING))
3674 V0(device->Backend,stop)();
3675 device->Flags &= ~DEVICE_RUNNING;
3676 device->Flags |= DEVICE_PAUSED;
3677 UnlockLists();
3679 if(device) ALCdevice_DecRef(device);
3682 /* alcDeviceResumeSOFT
3684 * Resume the DSP to restart audio processing.
3686 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3688 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3689 alcSetError(device, ALC_INVALID_DEVICE);
3690 else
3692 LockLists();
3693 if((device->Flags&DEVICE_PAUSED))
3695 device->Flags &= ~DEVICE_PAUSED;
3696 if(device->ContextList != NULL)
3698 if(V0(device->Backend,start)() != ALC_FALSE)
3699 device->Flags |= DEVICE_RUNNING;
3700 else
3702 alcSetError(device, ALC_INVALID_DEVICE);
3703 ALCdevice_Lock(device);
3704 aluHandleDisconnect(device);
3705 ALCdevice_Unlock(device);
3709 UnlockLists();
3711 if(device) ALCdevice_DecRef(device);