Add SSE2 and SSE4.1 linear resamplers
[openal-soft.git] / Alc / ALc.c
blob7c8c2322ebd3a1bd4c135fae958a17a9fa095cd9
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;
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;
1624 while(attrList[attrIdx])
1626 if(attrList[attrIdx] == ALC_FORMAT_CHANNELS_SOFT)
1628 ALCint val = attrList[attrIdx + 1];
1629 if(!IsValidALCChannels(val) || !ChannelsFromDevFmt(val))
1630 return ALC_INVALID_VALUE;
1631 schans = val;
1632 gotFmt |= GotChans;
1635 if(attrList[attrIdx] == ALC_FORMAT_TYPE_SOFT)
1637 ALCint val = attrList[attrIdx + 1];
1638 if(!IsValidALCType(val) || !BytesFromDevFmt(val))
1639 return ALC_INVALID_VALUE;
1640 stype = val;
1641 gotFmt |= GotType;
1644 if(attrList[attrIdx] == ALC_FREQUENCY)
1646 freq = attrList[attrIdx + 1];
1647 if(freq < MIN_OUTPUT_RATE)
1648 return ALC_INVALID_VALUE;
1649 gotFmt |= GotFreq;
1652 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1654 numStereo = attrList[attrIdx + 1];
1655 if(numStereo > device->MaxNoOfSources)
1656 numStereo = device->MaxNoOfSources;
1658 numMono = device->MaxNoOfSources - numStereo;
1661 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1662 numSends = attrList[attrIdx + 1];
1664 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1666 if(attrList[attrIdx + 1] != ALC_FALSE)
1667 device->Flags |= DEVICE_HRTF_REQUEST;
1668 else
1669 device->Flags &= ~DEVICE_HRTF_REQUEST;
1672 attrIdx += 2;
1675 if(gotFmt != GotAll)
1677 WARN("Missing format for loopback device\n");
1678 return ALC_INVALID_VALUE;
1681 ConfigValueUInt(NULL, "sends", &numSends);
1682 numSends = minu(MAX_SENDS, numSends);
1684 if((device->Flags&DEVICE_RUNNING))
1685 V0(device->Backend,stop)();
1686 device->Flags &= ~DEVICE_RUNNING;
1688 if(freq != device->Frequency)
1689 UpdateClockBase(device);
1690 device->Frequency = freq;
1691 device->FmtChans = schans;
1692 device->FmtType = stype;
1693 device->NumMonoSources = numMono;
1694 device->NumStereoSources = numStereo;
1695 device->NumAuxSends = numSends;
1697 else if(attrList && attrList[0])
1699 ALCuint freq, numMono, numStereo, numSends;
1700 ALCuint attrIdx = 0;
1702 /* If a context is already running on the device, stop playback so the
1703 * device attributes can be updated. */
1704 if((device->Flags&DEVICE_RUNNING))
1705 V0(device->Backend,stop)();
1706 device->Flags &= ~DEVICE_RUNNING;
1708 freq = device->Frequency;
1709 numMono = device->NumMonoSources;
1710 numStereo = device->NumStereoSources;
1711 numSends = device->NumAuxSends;
1713 while(attrList[attrIdx])
1715 if(attrList[attrIdx] == ALC_FREQUENCY)
1717 freq = attrList[attrIdx + 1];
1718 device->Flags |= DEVICE_FREQUENCY_REQUEST;
1721 if(attrList[attrIdx] == ALC_STEREO_SOURCES)
1723 numStereo = attrList[attrIdx + 1];
1724 if(numStereo > device->MaxNoOfSources)
1725 numStereo = device->MaxNoOfSources;
1727 numMono = device->MaxNoOfSources - numStereo;
1730 if(attrList[attrIdx] == ALC_MAX_AUXILIARY_SENDS)
1731 numSends = attrList[attrIdx + 1];
1733 if(attrList[attrIdx] == ALC_HRTF_SOFT)
1735 if(attrList[attrIdx + 1] != ALC_FALSE)
1736 device->Flags |= DEVICE_HRTF_REQUEST;
1737 else
1738 device->Flags &= ~DEVICE_HRTF_REQUEST;
1741 attrIdx += 2;
1744 ConfigValueUInt(NULL, "frequency", &freq);
1745 freq = maxu(freq, MIN_OUTPUT_RATE);
1747 ConfigValueUInt(NULL, "sends", &numSends);
1748 numSends = minu(MAX_SENDS, numSends);
1750 device->UpdateSize = (ALuint64)device->UpdateSize * freq /
1751 device->Frequency;
1752 /* SSE and Neon do best with the update size being a multiple of 4 */
1753 if((CPUCapFlags&(CPU_CAP_SSE|CPU_CAP_NEON)) != 0)
1754 device->UpdateSize = (device->UpdateSize+3)&~3;
1756 if(freq != device->Frequency)
1757 UpdateClockBase(device);
1758 device->Frequency = freq;
1759 device->NumMonoSources = numMono;
1760 device->NumStereoSources = numStereo;
1761 device->NumAuxSends = numSends;
1764 if((device->Flags&DEVICE_RUNNING))
1765 return ALC_NO_ERROR;
1767 UpdateClockBase(device);
1769 oldFreq = device->Frequency;
1770 oldChans = device->FmtChans;
1771 oldType = device->FmtType;
1773 TRACE("Pre-reset: %s%s, %s%s, %s%uhz, %u update size x%d\n",
1774 (device->Flags&DEVICE_CHANNELS_REQUEST)?"*":"",
1775 DevFmtChannelsString(device->FmtChans),
1776 (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST)?"*":"",
1777 DevFmtTypeString(device->FmtType),
1778 (device->Flags&DEVICE_FREQUENCY_REQUEST)?"*":"",
1779 device->Frequency,
1780 device->UpdateSize, device->NumUpdates);
1782 if(device->Type != Loopback)
1784 int nohrtf = !(device->Flags&DEVICE_HRTF_REQUEST);
1785 if(GetConfigValueBool(NULL, "hrtf", !nohrtf))
1786 device->Flags |= DEVICE_HRTF_REQUEST;
1787 else
1788 device->Flags &= ~DEVICE_HRTF_REQUEST;
1790 if((device->Flags&DEVICE_HRTF_REQUEST))
1792 enum DevFmtChannels chans;
1793 ALCuint freq;
1794 if(FindHrtfFormat(device, &chans, &freq))
1796 device->Frequency = freq;
1797 device->FmtChans = chans;
1798 device->Flags |= DEVICE_CHANNELS_REQUEST |
1799 DEVICE_FREQUENCY_REQUEST;
1803 if(V0(device->Backend,reset)() == ALC_FALSE)
1804 return ALC_INVALID_DEVICE;
1806 if(device->FmtChans != oldChans && (device->Flags&DEVICE_CHANNELS_REQUEST))
1808 ERR("Failed to set %s, got %s instead\n", DevFmtChannelsString(oldChans),
1809 DevFmtChannelsString(device->FmtChans));
1810 device->Flags &= ~DEVICE_CHANNELS_REQUEST;
1812 if(device->FmtType != oldType && (device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
1814 ERR("Failed to set %s, got %s instead\n", DevFmtTypeString(oldType),
1815 DevFmtTypeString(device->FmtType));
1816 device->Flags &= ~DEVICE_SAMPLE_TYPE_REQUEST;
1818 if(device->Frequency != oldFreq && (device->Flags&DEVICE_FREQUENCY_REQUEST))
1820 ERR("Failed to set %uhz, got %uhz instead\n", oldFreq, device->Frequency);
1821 device->Flags &= ~DEVICE_FREQUENCY_REQUEST;
1824 TRACE("Post-reset: %s, %s, %uhz, %u update size x%d\n",
1825 DevFmtChannelsString(device->FmtChans),
1826 DevFmtTypeString(device->FmtType), device->Frequency,
1827 device->UpdateSize, device->NumUpdates);
1829 aluInitPanning(device);
1831 V(device->Synth,update)(device);
1833 device->Hrtf = NULL;
1834 if((device->Flags&DEVICE_HRTF_REQUEST))
1836 device->Hrtf = GetHrtf(device);
1837 if(!device->Hrtf)
1838 device->Flags &= ~DEVICE_HRTF_REQUEST;
1840 TRACE("HRTF %s\n", device->Hrtf?"enabled":"disabled");
1842 if(!device->Hrtf && device->Bs2bLevel > 0 && device->Bs2bLevel <= 6)
1844 if(!device->Bs2b)
1846 device->Bs2b = calloc(1, sizeof(*device->Bs2b));
1847 bs2b_clear(device->Bs2b);
1849 bs2b_set_srate(device->Bs2b, device->Frequency);
1850 bs2b_set_level(device->Bs2b, device->Bs2bLevel);
1851 TRACE("BS2B level %d\n", device->Bs2bLevel);
1853 else
1855 free(device->Bs2b);
1856 device->Bs2b = NULL;
1857 TRACE("BS2B disabled\n");
1860 device->Flags &= ~DEVICE_WIDE_STEREO;
1861 if(device->Type != Loopback && !device->Hrtf && GetConfigValueBool(NULL, "wide-stereo", AL_FALSE))
1862 device->Flags |= DEVICE_WIDE_STEREO;
1864 if(!device->Hrtf && (device->UpdateSize&3))
1866 if((CPUCapFlags&CPU_CAP_SSE))
1867 WARN("SSE performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1868 if((CPUCapFlags&CPU_CAP_NEON))
1869 WARN("NEON performs best with multiple of 4 update sizes (%u)\n", device->UpdateSize);
1872 SetMixerFPUMode(&oldMode);
1873 ALCdevice_Lock(device);
1874 context = device->ContextList;
1875 while(context)
1877 ALsizei pos;
1879 context->UpdateSources = AL_FALSE;
1880 LockUIntMapRead(&context->EffectSlotMap);
1881 for(pos = 0;pos < context->EffectSlotMap.size;pos++)
1883 ALeffectslot *slot = context->EffectSlotMap.array[pos].value;
1885 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
1887 UnlockUIntMapRead(&context->EffectSlotMap);
1888 ALCdevice_Unlock(device);
1889 RestoreFPUMode(&oldMode);
1890 return ALC_INVALID_DEVICE;
1892 slot->NeedsUpdate = AL_FALSE;
1893 V(slot->EffectState,update)(device, slot);
1895 UnlockUIntMapRead(&context->EffectSlotMap);
1897 LockUIntMapRead(&context->SourceMap);
1898 for(pos = 0;pos < context->SourceMap.size;pos++)
1900 ALsource *source = context->SourceMap.array[pos].value;
1901 ALuint s = device->NumAuxSends;
1902 while(s < MAX_SENDS)
1904 if(source->Send[s].Slot)
1905 DecrementRef(&source->Send[s].Slot->ref);
1906 source->Send[s].Slot = NULL;
1907 source->Send[s].Gain = 1.0f;
1908 source->Send[s].GainHF = 1.0f;
1909 s++;
1911 source->NeedsUpdate = AL_TRUE;
1913 UnlockUIntMapRead(&context->SourceMap);
1915 for(pos = 0;pos < context->ActiveSourceCount;pos++)
1917 ALactivesource *src = context->ActiveSources[pos];
1918 ALsource *source = src->Source;
1919 ALuint s = device->NumAuxSends;
1920 while(s < MAX_SENDS)
1922 src->Send[s].Moving = AL_FALSE;
1923 src->Send[s].Counter = 0;
1924 s++;
1927 src->Update(src, context);
1928 source->NeedsUpdate = AL_FALSE;
1931 context = context->next;
1933 if(device->DefaultSlot)
1935 ALeffectslot *slot = device->DefaultSlot;
1937 if(V(slot->EffectState,deviceUpdate)(device) == AL_FALSE)
1939 ALCdevice_Unlock(device);
1940 RestoreFPUMode(&oldMode);
1941 return ALC_INVALID_DEVICE;
1943 slot->NeedsUpdate = AL_FALSE;
1944 V(slot->EffectState,update)(device, slot);
1946 ALCdevice_Unlock(device);
1947 RestoreFPUMode(&oldMode);
1949 if(!(device->Flags&DEVICE_PAUSED))
1951 if(V0(device->Backend,start)() == ALC_FALSE)
1952 return ALC_INVALID_DEVICE;
1953 device->Flags |= DEVICE_RUNNING;
1956 return ALC_NO_ERROR;
1959 /* FreeDevice
1961 * Frees the device structure, and destroys any objects the app failed to
1962 * delete. Called once there's no more references on the device.
1964 static ALCvoid FreeDevice(ALCdevice *device)
1966 TRACE("%p\n", device);
1968 V0(device->Backend,close)();
1969 DELETE_OBJ(device->Backend);
1970 device->Backend = NULL;
1972 DELETE_OBJ(device->Synth);
1973 device->Synth = NULL;
1975 if(device->DefaultSlot)
1977 ALeffectState *state = device->DefaultSlot->EffectState;
1978 device->DefaultSlot = NULL;
1979 DELETE_OBJ(state);
1982 if(device->DefaultSfont)
1983 ALsoundfont_deleteSoundfont(device->DefaultSfont, device);
1984 device->DefaultSfont = NULL;
1986 if(device->BufferMap.size > 0)
1988 WARN("(%p) Deleting %d Buffer(s)\n", device, device->BufferMap.size);
1989 ReleaseALBuffers(device);
1991 ResetUIntMap(&device->BufferMap);
1993 if(device->EffectMap.size > 0)
1995 WARN("(%p) Deleting %d Effect(s)\n", device, device->EffectMap.size);
1996 ReleaseALEffects(device);
1998 ResetUIntMap(&device->EffectMap);
2000 if(device->FilterMap.size > 0)
2002 WARN("(%p) Deleting %d Filter(s)\n", device, device->FilterMap.size);
2003 ReleaseALFilters(device);
2005 ResetUIntMap(&device->FilterMap);
2007 if(device->SfontMap.size > 0)
2009 WARN("(%p) Deleting %d Soundfont(s)\n", device, device->SfontMap.size);
2010 ReleaseALSoundfonts(device);
2012 ResetUIntMap(&device->SfontMap);
2014 if(device->PresetMap.size > 0)
2016 WARN("(%p) Deleting %d Preset(s)\n", device, device->PresetMap.size);
2017 ReleaseALPresets(device);
2019 ResetUIntMap(&device->PresetMap);
2021 if(device->FontsoundMap.size > 0)
2023 WARN("(%p) Deleting %d Fontsound(s)\n", device, device->FontsoundMap.size);
2024 ReleaseALFontsounds(device);
2026 ResetUIntMap(&device->FontsoundMap);
2028 free(device->Bs2b);
2029 device->Bs2b = NULL;
2031 AL_STRING_DEINIT(device->DeviceName);
2033 al_free(device);
2037 void ALCdevice_IncRef(ALCdevice *device)
2039 uint ref;
2040 ref = IncrementRef(&device->ref);
2041 TRACEREF("%p increasing refcount to %u\n", device, ref);
2044 void ALCdevice_DecRef(ALCdevice *device)
2046 uint ref;
2047 ref = DecrementRef(&device->ref);
2048 TRACEREF("%p decreasing refcount to %u\n", device, ref);
2049 if(ref == 0) FreeDevice(device);
2052 /* VerifyDevice
2054 * Checks if the device handle is valid, and increments its ref count if so.
2056 static ALCdevice *VerifyDevice(ALCdevice *device)
2058 ALCdevice *tmpDevice;
2060 if(!device)
2061 return NULL;
2063 LockLists();
2064 tmpDevice = DeviceList;
2065 while(tmpDevice && tmpDevice != device)
2066 tmpDevice = tmpDevice->next;
2068 if(tmpDevice)
2069 ALCdevice_IncRef(tmpDevice);
2070 UnlockLists();
2071 return tmpDevice;
2075 /* InitContext
2077 * Initializes context fields
2079 static ALvoid InitContext(ALCcontext *Context)
2081 ALint i, j;
2083 //Initialise listener
2084 Context->Listener->Gain = 1.0f;
2085 Context->Listener->MetersPerUnit = 1.0f;
2086 Context->Listener->Position[0] = 0.0f;
2087 Context->Listener->Position[1] = 0.0f;
2088 Context->Listener->Position[2] = 0.0f;
2089 Context->Listener->Velocity[0] = 0.0f;
2090 Context->Listener->Velocity[1] = 0.0f;
2091 Context->Listener->Velocity[2] = 0.0f;
2092 Context->Listener->Forward[0] = 0.0f;
2093 Context->Listener->Forward[1] = 0.0f;
2094 Context->Listener->Forward[2] = -1.0f;
2095 Context->Listener->Up[0] = 0.0f;
2096 Context->Listener->Up[1] = 1.0f;
2097 Context->Listener->Up[2] = 0.0f;
2098 for(i = 0;i < 4;i++)
2100 for(j = 0;j < 4;j++)
2101 Context->Listener->Params.Matrix[i][j] = ((i==j) ? 1.0f : 0.0f);
2103 for(i = 0;i < 3;i++)
2104 Context->Listener->Params.Velocity[i] = 0.0f;
2106 //Validate Context
2107 Context->LastError = AL_NO_ERROR;
2108 Context->UpdateSources = AL_FALSE;
2109 Context->ActiveSourceCount = 0;
2110 InitUIntMap(&Context->SourceMap, Context->Device->MaxNoOfSources);
2111 InitUIntMap(&Context->EffectSlotMap, Context->Device->AuxiliaryEffectSlotMax);
2113 //Set globals
2114 Context->DistanceModel = DefaultDistanceModel;
2115 Context->SourceDistanceModel = AL_FALSE;
2116 Context->DopplerFactor = 1.0f;
2117 Context->DopplerVelocity = 1.0f;
2118 Context->SpeedOfSound = SPEEDOFSOUNDMETRESPERSEC;
2119 Context->DeferUpdates = AL_FALSE;
2121 Context->ExtensionList = alExtList;
2125 /* FreeContext
2127 * Cleans up the context, and destroys any remaining objects the app failed to
2128 * delete. Called once there's no more references on the context.
2130 static ALCvoid FreeContext(ALCcontext *context)
2132 ALsizei i;
2134 TRACE("%p\n", context);
2136 if(context->SourceMap.size > 0)
2138 WARN("(%p) Deleting %d Source(s)\n", context, context->SourceMap.size);
2139 ReleaseALSources(context);
2141 ResetUIntMap(&context->SourceMap);
2143 if(context->EffectSlotMap.size > 0)
2145 WARN("(%p) Deleting %d AuxiliaryEffectSlot(s)\n", context, context->EffectSlotMap.size);
2146 ReleaseALAuxiliaryEffectSlots(context);
2148 ResetUIntMap(&context->EffectSlotMap);
2150 for(i = 0;i < context->MaxActiveSources;i++)
2152 al_free(context->ActiveSources[i]);
2153 context->ActiveSources[i] = NULL;
2155 free(context->ActiveSources);
2156 context->ActiveSources = NULL;
2157 context->ActiveSourceCount = 0;
2158 context->MaxActiveSources = 0;
2160 VECTOR_DEINIT(context->ActiveAuxSlots);
2162 ALCdevice_DecRef(context->Device);
2163 context->Device = NULL;
2165 //Invalidate context
2166 memset(context, 0, sizeof(ALCcontext));
2167 free(context);
2170 /* ReleaseContext
2172 * Removes the context reference from the given device and removes it from
2173 * being current on the running thread or globally.
2175 static void ReleaseContext(ALCcontext *context, ALCdevice *device)
2177 ALCcontext *volatile*tmp_ctx;
2179 if(altss_get(LocalContext) == context)
2181 WARN("%p released while current on thread\n", context);
2182 altss_set(LocalContext, NULL);
2183 ALCcontext_DecRef(context);
2186 if(CompExchangePtr((XchgPtr*)&GlobalContext, context, NULL) == context)
2187 ALCcontext_DecRef(context);
2189 ALCdevice_Lock(device);
2190 tmp_ctx = &device->ContextList;
2191 while(*tmp_ctx)
2193 if(CompExchangePtr((XchgPtr*)tmp_ctx, context, context->next) == context)
2194 break;
2195 tmp_ctx = &(*tmp_ctx)->next;
2197 ALCdevice_Unlock(device);
2199 ALCcontext_DecRef(context);
2202 void ALCcontext_IncRef(ALCcontext *context)
2204 uint ref;
2205 ref = IncrementRef(&context->ref);
2206 TRACEREF("%p increasing refcount to %u\n", context, ref);
2209 void ALCcontext_DecRef(ALCcontext *context)
2211 uint ref;
2212 ref = DecrementRef(&context->ref);
2213 TRACEREF("%p decreasing refcount to %u\n", context, ref);
2214 if(ref == 0) FreeContext(context);
2217 static void ReleaseThreadCtx(void *ptr)
2219 WARN("%p current for thread being destroyed\n", ptr);
2220 ALCcontext_DecRef(ptr);
2223 /* VerifyContext
2225 * Checks that the given context is valid, and increments its reference count.
2227 static ALCcontext *VerifyContext(ALCcontext *context)
2229 ALCdevice *dev;
2231 LockLists();
2232 dev = DeviceList;
2233 while(dev)
2235 ALCcontext *tmp_ctx = dev->ContextList;
2236 while(tmp_ctx)
2238 if(tmp_ctx == context)
2240 ALCcontext_IncRef(tmp_ctx);
2241 UnlockLists();
2242 return tmp_ctx;
2244 tmp_ctx = tmp_ctx->next;
2246 dev = dev->next;
2248 UnlockLists();
2250 return NULL;
2254 /* GetContextRef
2256 * Returns the currently active context for this thread, and adds a reference
2257 * without locking it.
2259 ALCcontext *GetContextRef(void)
2261 ALCcontext *context;
2263 context = altss_get(LocalContext);
2264 if(context)
2265 ALCcontext_IncRef(context);
2266 else
2268 LockLists();
2269 context = GlobalContext;
2270 if(context)
2271 ALCcontext_IncRef(context);
2272 UnlockLists();
2275 return context;
2279 /************************************************
2280 * Standard ALC functions
2281 ************************************************/
2283 /* alcGetError
2285 * Return last ALC generated error code for the given device
2287 ALC_API ALCenum ALC_APIENTRY alcGetError(ALCdevice *device)
2289 ALCenum errorCode;
2291 if(VerifyDevice(device))
2293 errorCode = ExchangeInt(&device->LastError, ALC_NO_ERROR);
2294 ALCdevice_DecRef(device);
2296 else
2297 errorCode = ExchangeInt(&LastNullDeviceError, ALC_NO_ERROR);
2299 return errorCode;
2303 /* alcSuspendContext
2305 * Not functional
2307 ALC_API ALCvoid ALC_APIENTRY alcSuspendContext(ALCcontext *UNUSED(context))
2311 /* alcProcessContext
2313 * Not functional
2315 ALC_API ALCvoid ALC_APIENTRY alcProcessContext(ALCcontext *UNUSED(context))
2320 /* alcGetString
2322 * Returns information about the device, and error strings
2324 ALC_API const ALCchar* ALC_APIENTRY alcGetString(ALCdevice *Device, ALCenum param)
2326 const ALCchar *value = NULL;
2328 switch(param)
2330 case ALC_NO_ERROR:
2331 value = alcNoError;
2332 break;
2334 case ALC_INVALID_ENUM:
2335 value = alcErrInvalidEnum;
2336 break;
2338 case ALC_INVALID_VALUE:
2339 value = alcErrInvalidValue;
2340 break;
2342 case ALC_INVALID_DEVICE:
2343 value = alcErrInvalidDevice;
2344 break;
2346 case ALC_INVALID_CONTEXT:
2347 value = alcErrInvalidContext;
2348 break;
2350 case ALC_OUT_OF_MEMORY:
2351 value = alcErrOutOfMemory;
2352 break;
2354 case ALC_DEVICE_SPECIFIER:
2355 value = alcDefaultName;
2356 break;
2358 case ALC_ALL_DEVICES_SPECIFIER:
2359 if(VerifyDevice(Device))
2361 value = al_string_get_cstr(Device->DeviceName);
2362 ALCdevice_DecRef(Device);
2364 else
2366 ProbeAllDevicesList();
2367 value = al_string_get_cstr(alcAllDevicesList);
2369 break;
2371 case ALC_CAPTURE_DEVICE_SPECIFIER:
2372 if(VerifyDevice(Device))
2374 value = al_string_get_cstr(Device->DeviceName);
2375 ALCdevice_DecRef(Device);
2377 else
2379 ProbeCaptureDeviceList();
2380 value = al_string_get_cstr(alcCaptureDeviceList);
2382 break;
2384 /* Default devices are always first in the list */
2385 case ALC_DEFAULT_DEVICE_SPECIFIER:
2386 value = alcDefaultName;
2387 break;
2389 case ALC_DEFAULT_ALL_DEVICES_SPECIFIER:
2390 if(al_string_empty(alcAllDevicesList))
2391 ProbeAllDevicesList();
2393 Device = VerifyDevice(Device);
2395 free(alcDefaultAllDevicesSpecifier);
2396 alcDefaultAllDevicesSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2397 if(!alcDefaultAllDevicesSpecifier)
2398 alcSetError(Device, ALC_OUT_OF_MEMORY);
2400 value = alcDefaultAllDevicesSpecifier;
2401 if(Device) ALCdevice_DecRef(Device);
2402 break;
2404 case ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER:
2405 if(al_string_empty(alcCaptureDeviceList))
2406 ProbeCaptureDeviceList();
2408 Device = VerifyDevice(Device);
2410 free(alcCaptureDefaultDeviceSpecifier);
2411 alcCaptureDefaultDeviceSpecifier = strdup(al_string_get_cstr(alcAllDevicesList));
2412 if(!alcCaptureDefaultDeviceSpecifier)
2413 alcSetError(Device, ALC_OUT_OF_MEMORY);
2415 value = alcCaptureDefaultDeviceSpecifier;
2416 if(Device) ALCdevice_DecRef(Device);
2417 break;
2419 case ALC_EXTENSIONS:
2420 if(!VerifyDevice(Device))
2421 value = alcNoDeviceExtList;
2422 else
2424 value = alcExtensionList;
2425 ALCdevice_DecRef(Device);
2427 break;
2429 default:
2430 Device = VerifyDevice(Device);
2431 alcSetError(Device, ALC_INVALID_ENUM);
2432 if(Device) ALCdevice_DecRef(Device);
2433 break;
2436 return value;
2440 static ALCsizei GetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2442 ALCsizei i;
2444 if(size <= 0 || values == NULL)
2446 alcSetError(device, ALC_INVALID_VALUE);
2447 return 0;
2450 if(!device)
2452 switch(param)
2454 case ALC_MAJOR_VERSION:
2455 values[0] = alcMajorVersion;
2456 return 1;
2457 case ALC_MINOR_VERSION:
2458 values[0] = alcMinorVersion;
2459 return 1;
2461 case ALC_ATTRIBUTES_SIZE:
2462 case ALC_ALL_ATTRIBUTES:
2463 case ALC_FREQUENCY:
2464 case ALC_REFRESH:
2465 case ALC_SYNC:
2466 case ALC_MONO_SOURCES:
2467 case ALC_STEREO_SOURCES:
2468 case ALC_CAPTURE_SAMPLES:
2469 case ALC_FORMAT_CHANNELS_SOFT:
2470 case ALC_FORMAT_TYPE_SOFT:
2471 alcSetError(NULL, ALC_INVALID_DEVICE);
2472 return 0;
2474 default:
2475 alcSetError(NULL, ALC_INVALID_ENUM);
2476 return 0;
2478 return 0;
2481 if(device->Type == Capture)
2483 switch(param)
2485 case ALC_CAPTURE_SAMPLES:
2486 ALCdevice_Lock(device);
2487 values[0] = V0(device->Backend,availableSamples)();
2488 ALCdevice_Unlock(device);
2489 return 1;
2491 case ALC_CONNECTED:
2492 values[0] = device->Connected;
2493 return 1;
2495 default:
2496 alcSetError(device, ALC_INVALID_ENUM);
2497 return 0;
2499 return 0;
2502 /* render device */
2503 switch(param)
2505 case ALC_MAJOR_VERSION:
2506 values[0] = alcMajorVersion;
2507 return 1;
2509 case ALC_MINOR_VERSION:
2510 values[0] = alcMinorVersion;
2511 return 1;
2513 case ALC_EFX_MAJOR_VERSION:
2514 values[0] = alcEFXMajorVersion;
2515 return 1;
2517 case ALC_EFX_MINOR_VERSION:
2518 values[0] = alcEFXMinorVersion;
2519 return 1;
2521 case ALC_ATTRIBUTES_SIZE:
2522 values[0] = 15;
2523 return 1;
2525 case ALC_ALL_ATTRIBUTES:
2526 if(size < 15)
2528 alcSetError(device, ALC_INVALID_VALUE);
2529 return 0;
2532 i = 0;
2533 values[i++] = ALC_FREQUENCY;
2534 values[i++] = device->Frequency;
2536 if(device->Type != Loopback)
2538 values[i++] = ALC_REFRESH;
2539 values[i++] = device->Frequency / device->UpdateSize;
2541 values[i++] = ALC_SYNC;
2542 values[i++] = ALC_FALSE;
2544 else
2546 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2547 values[i++] = device->FmtChans;
2549 values[i++] = ALC_FORMAT_TYPE_SOFT;
2550 values[i++] = device->FmtType;
2553 values[i++] = ALC_MONO_SOURCES;
2554 values[i++] = device->NumMonoSources;
2556 values[i++] = ALC_STEREO_SOURCES;
2557 values[i++] = device->NumStereoSources;
2559 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2560 values[i++] = device->NumAuxSends;
2562 values[i++] = ALC_HRTF_SOFT;
2563 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2565 values[i++] = 0;
2566 return i;
2568 case ALC_FREQUENCY:
2569 values[0] = device->Frequency;
2570 return 1;
2572 case ALC_REFRESH:
2573 if(device->Type == Loopback)
2575 alcSetError(device, ALC_INVALID_DEVICE);
2576 return 0;
2578 values[0] = device->Frequency / device->UpdateSize;
2579 return 1;
2581 case ALC_SYNC:
2582 if(device->Type == Loopback)
2584 alcSetError(device, ALC_INVALID_DEVICE);
2585 return 0;
2587 values[0] = ALC_FALSE;
2588 return 1;
2590 case ALC_FORMAT_CHANNELS_SOFT:
2591 if(device->Type != Loopback)
2593 alcSetError(device, ALC_INVALID_DEVICE);
2594 return 0;
2596 values[0] = device->FmtChans;
2597 return 1;
2599 case ALC_FORMAT_TYPE_SOFT:
2600 if(device->Type != Loopback)
2602 alcSetError(device, ALC_INVALID_DEVICE);
2603 return 0;
2605 values[0] = device->FmtType;
2606 return 1;
2608 case ALC_MONO_SOURCES:
2609 values[0] = device->NumMonoSources;
2610 return 1;
2612 case ALC_STEREO_SOURCES:
2613 values[0] = device->NumStereoSources;
2614 return 1;
2616 case ALC_MAX_AUXILIARY_SENDS:
2617 values[0] = device->NumAuxSends;
2618 return 1;
2620 case ALC_CONNECTED:
2621 values[0] = device->Connected;
2622 return 1;
2624 case ALC_HRTF_SOFT:
2625 values[0] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2626 return 1;
2628 default:
2629 alcSetError(device, ALC_INVALID_ENUM);
2630 return 0;
2632 return 0;
2635 /* alcGetIntegerv
2637 * Returns information about the device and the version of OpenAL
2639 ALC_API void ALC_APIENTRY alcGetIntegerv(ALCdevice *device, ALCenum param, ALCsizei size, ALCint *values)
2641 device = VerifyDevice(device);
2642 if(size <= 0 || values == NULL)
2643 alcSetError(device, ALC_INVALID_VALUE);
2644 else
2645 GetIntegerv(device, param, size, values);
2646 if(device) ALCdevice_DecRef(device);
2649 ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALCsizei size, ALCint64SOFT *values)
2651 ALCint *ivals;
2652 ALsizei i;
2654 device = VerifyDevice(device);
2655 if(size <= 0 || values == NULL)
2656 alcSetError(device, ALC_INVALID_VALUE);
2657 else if(!device || device->Type == Capture)
2659 ivals = malloc(size * sizeof(ALCint));
2660 size = GetIntegerv(device, pname, size, ivals);
2661 for(i = 0;i < size;i++)
2662 values[i] = ivals[i];
2663 free(ivals);
2665 else /* render device */
2667 switch(pname)
2669 case ALC_ATTRIBUTES_SIZE:
2670 *values = 17;
2671 break;
2673 case ALC_ALL_ATTRIBUTES:
2674 if(size < 17)
2675 alcSetError(device, ALC_INVALID_VALUE);
2676 else
2678 int i = 0;
2680 V0(device->Backend,lock)();
2681 values[i++] = ALC_FREQUENCY;
2682 values[i++] = device->Frequency;
2684 if(device->Type != Loopback)
2686 values[i++] = ALC_REFRESH;
2687 values[i++] = device->Frequency / device->UpdateSize;
2689 values[i++] = ALC_SYNC;
2690 values[i++] = ALC_FALSE;
2692 else
2694 values[i++] = ALC_FORMAT_CHANNELS_SOFT;
2695 values[i++] = device->FmtChans;
2697 values[i++] = ALC_FORMAT_TYPE_SOFT;
2698 values[i++] = device->FmtType;
2701 values[i++] = ALC_MONO_SOURCES;
2702 values[i++] = device->NumMonoSources;
2704 values[i++] = ALC_STEREO_SOURCES;
2705 values[i++] = device->NumStereoSources;
2707 values[i++] = ALC_MAX_AUXILIARY_SENDS;
2708 values[i++] = device->NumAuxSends;
2710 values[i++] = ALC_HRTF_SOFT;
2711 values[i++] = (device->Hrtf ? ALC_TRUE : ALC_FALSE);
2713 values[i++] = ALC_DEVICE_CLOCK_SOFT;
2714 values[i++] = device->ClockBase +
2715 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2717 values[i++] = 0;
2718 V0(device->Backend,unlock)();
2720 break;
2722 case ALC_DEVICE_CLOCK_SOFT:
2723 V0(device->Backend,lock)();
2724 *values = device->ClockBase +
2725 (device->SamplesDone * DEVICE_CLOCK_RES / device->Frequency);
2726 V0(device->Backend,unlock)();
2727 break;
2729 default:
2730 ivals = malloc(size * sizeof(ALCint));
2731 size = GetIntegerv(device, pname, size, ivals);
2732 for(i = 0;i < size;i++)
2733 values[i] = ivals[i];
2734 free(ivals);
2735 break;
2738 if(device)
2739 ALCdevice_DecRef(device);
2743 /* alcIsExtensionPresent
2745 * Determines if there is support for a particular extension
2747 ALC_API ALCboolean ALC_APIENTRY alcIsExtensionPresent(ALCdevice *device, const ALCchar *extName)
2749 ALCboolean bResult = ALC_FALSE;
2751 device = VerifyDevice(device);
2753 if(!extName)
2754 alcSetError(device, ALC_INVALID_VALUE);
2755 else
2757 size_t len = strlen(extName);
2758 const char *ptr = (device ? alcExtensionList : alcNoDeviceExtList);
2759 while(ptr && *ptr)
2761 if(strncasecmp(ptr, extName, len) == 0 &&
2762 (ptr[len] == '\0' || isspace(ptr[len])))
2764 bResult = ALC_TRUE;
2765 break;
2767 if((ptr=strchr(ptr, ' ')) != NULL)
2769 do {
2770 ++ptr;
2771 } while(isspace(*ptr));
2775 if(device)
2776 ALCdevice_DecRef(device);
2777 return bResult;
2781 /* alcGetProcAddress
2783 * Retrieves the function address for a particular extension function
2785 ALC_API ALCvoid* ALC_APIENTRY alcGetProcAddress(ALCdevice *device, const ALCchar *funcName)
2787 ALCvoid *ptr = NULL;
2789 if(!funcName)
2791 device = VerifyDevice(device);
2792 alcSetError(device, ALC_INVALID_VALUE);
2793 if(device) ALCdevice_DecRef(device);
2795 else
2797 ALsizei i = 0;
2798 while(alcFunctions[i].funcName && strcmp(alcFunctions[i].funcName, funcName) != 0)
2799 i++;
2800 ptr = alcFunctions[i].address;
2803 return ptr;
2807 /* alcGetEnumValue
2809 * Get the value for a particular ALC enumeration name
2811 ALC_API ALCenum ALC_APIENTRY alcGetEnumValue(ALCdevice *device, const ALCchar *enumName)
2813 ALCenum val = 0;
2815 if(!enumName)
2817 device = VerifyDevice(device);
2818 alcSetError(device, ALC_INVALID_VALUE);
2819 if(device) ALCdevice_DecRef(device);
2821 else
2823 ALsizei i = 0;
2824 while(enumeration[i].enumName && strcmp(enumeration[i].enumName, enumName) != 0)
2825 i++;
2826 val = enumeration[i].value;
2829 return val;
2833 /* alcCreateContext
2835 * Create and attach a context to the given device.
2837 ALC_API ALCcontext* ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrList)
2839 ALCcontext *ALContext;
2840 ALCenum err;
2842 LockLists();
2843 if(!(device=VerifyDevice(device)) || device->Type == Capture || !device->Connected)
2845 UnlockLists();
2846 alcSetError(device, ALC_INVALID_DEVICE);
2847 if(device) ALCdevice_DecRef(device);
2848 return NULL;
2851 device->LastError = ALC_NO_ERROR;
2853 if((err=UpdateDeviceParams(device, attrList)) != ALC_NO_ERROR)
2855 UnlockLists();
2856 alcSetError(device, err);
2857 if(err == ALC_INVALID_DEVICE)
2859 ALCdevice_Lock(device);
2860 aluHandleDisconnect(device);
2861 ALCdevice_Unlock(device);
2863 ALCdevice_DecRef(device);
2864 return NULL;
2867 ALContext = calloc(1, sizeof(ALCcontext)+sizeof(ALlistener));
2868 if(ALContext)
2870 InitRef(&ALContext->ref, 1);
2871 ALContext->Listener = (ALlistener*)ALContext->_listener_mem;
2873 VECTOR_INIT(ALContext->ActiveAuxSlots);
2875 ALContext->MaxActiveSources = 256;
2876 ALContext->ActiveSources = calloc(ALContext->MaxActiveSources,
2877 sizeof(ALContext->ActiveSources[0]));
2879 if(!ALContext || !ALContext->ActiveSources)
2881 if(!device->ContextList)
2883 V0(device->Backend,stop)();
2884 device->Flags &= ~DEVICE_RUNNING;
2886 UnlockLists();
2888 if(ALContext)
2890 free(ALContext->ActiveSources);
2891 ALContext->ActiveSources = NULL;
2893 VECTOR_DEINIT(ALContext->ActiveAuxSlots);
2895 free(ALContext);
2896 ALContext = NULL;
2899 alcSetError(device, ALC_OUT_OF_MEMORY);
2900 ALCdevice_DecRef(device);
2901 return NULL;
2904 ALContext->Device = device;
2905 ALCdevice_IncRef(device);
2906 InitContext(ALContext);
2908 do {
2909 ALContext->next = device->ContextList;
2910 } while(CompExchangePtr((XchgPtr*)&device->ContextList, ALContext->next, ALContext) != ALContext->next);
2911 UnlockLists();
2913 ALCdevice_DecRef(device);
2915 TRACE("Created context %p\n", ALContext);
2916 return ALContext;
2919 /* alcDestroyContext
2921 * Remove a context from its device
2923 ALC_API ALCvoid ALC_APIENTRY alcDestroyContext(ALCcontext *context)
2925 ALCdevice *Device;
2927 LockLists();
2928 /* alcGetContextsDevice sets an error for invalid contexts */
2929 Device = alcGetContextsDevice(context);
2930 if(Device)
2932 ReleaseContext(context, Device);
2933 if(!Device->ContextList)
2935 V0(Device->Backend,stop)();
2936 Device->Flags &= ~DEVICE_RUNNING;
2939 UnlockLists();
2943 /* alcGetCurrentContext
2945 * Returns the currently active context on the calling thread
2947 ALC_API ALCcontext* ALC_APIENTRY alcGetCurrentContext(void)
2949 ALCcontext *Context;
2951 Context = altss_get(LocalContext);
2952 if(!Context) Context = GlobalContext;
2954 return Context;
2957 /* alcGetThreadContext
2959 * Returns the currently active thread-local context
2961 ALC_API ALCcontext* ALC_APIENTRY alcGetThreadContext(void)
2963 ALCcontext *Context;
2964 Context = altss_get(LocalContext);
2965 return Context;
2969 /* alcMakeContextCurrent
2971 * Makes the given context the active process-wide context, and removes the
2972 * thread-local context for the calling thread.
2974 ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
2976 /* context must be valid or NULL */
2977 if(context && !(context=VerifyContext(context)))
2979 alcSetError(NULL, ALC_INVALID_CONTEXT);
2980 return ALC_FALSE;
2982 /* context's reference count is already incremented */
2983 context = ExchangePtr((XchgPtr*)&GlobalContext, context);
2984 if(context) ALCcontext_DecRef(context);
2986 if((context=altss_get(LocalContext)) != NULL)
2988 altss_set(LocalContext, NULL);
2989 ALCcontext_DecRef(context);
2992 return ALC_TRUE;
2995 /* alcSetThreadContext
2997 * Makes the given context the active context for the current thread
2999 ALC_API ALCboolean ALC_APIENTRY alcSetThreadContext(ALCcontext *context)
3001 ALCcontext *old;
3003 /* context must be valid or NULL */
3004 if(context && !(context=VerifyContext(context)))
3006 alcSetError(NULL, ALC_INVALID_CONTEXT);
3007 return ALC_FALSE;
3009 /* context's reference count is already incremented */
3010 old = altss_get(LocalContext);
3011 altss_set(LocalContext, context);
3012 if(old) ALCcontext_DecRef(old);
3014 return ALC_TRUE;
3018 /* alcGetContextsDevice
3020 * Returns the device that a particular context is attached to
3022 ALC_API ALCdevice* ALC_APIENTRY alcGetContextsDevice(ALCcontext *Context)
3024 ALCdevice *Device;
3026 if(!(Context=VerifyContext(Context)))
3028 alcSetError(NULL, ALC_INVALID_CONTEXT);
3029 return NULL;
3031 Device = Context->Device;
3032 ALCcontext_DecRef(Context);
3034 return Device;
3038 /* alcOpenDevice
3040 * Opens the named device.
3042 ALC_API ALCdevice* ALC_APIENTRY alcOpenDevice(const ALCchar *deviceName)
3044 const ALCchar *fmt;
3045 ALCdevice *device;
3046 ALCenum err;
3048 DO_INITCONFIG();
3050 if(!PlaybackBackend.name)
3052 alcSetError(NULL, ALC_INVALID_VALUE);
3053 return NULL;
3056 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3057 deviceName = NULL;
3059 device = al_calloc(16, sizeof(ALCdevice)+sizeof(ALeffectslot));
3060 if(!device)
3062 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3063 return NULL;
3066 //Validate device
3067 InitRef(&device->ref, 1);
3068 device->Connected = ALC_TRUE;
3069 device->Type = Playback;
3070 device->LastError = ALC_NO_ERROR;
3072 device->Flags = 0;
3073 device->Bs2b = NULL;
3074 device->Bs2bLevel = 0;
3075 AL_STRING_INIT(device->DeviceName);
3077 device->ContextList = NULL;
3079 device->ClockBase = 0;
3080 device->SamplesDone = 0;
3082 device->MaxNoOfSources = 256;
3083 device->AuxiliaryEffectSlotMax = 4;
3084 device->NumAuxSends = MAX_SENDS;
3086 InitUIntMap(&device->BufferMap, ~0);
3087 InitUIntMap(&device->EffectMap, ~0);
3088 InitUIntMap(&device->FilterMap, ~0);
3089 InitUIntMap(&device->SfontMap, ~0);
3090 InitUIntMap(&device->PresetMap, ~0);
3091 InitUIntMap(&device->FontsoundMap, ~0);
3093 //Set output format
3094 device->FmtChans = DevFmtChannelsDefault;
3095 device->FmtType = DevFmtTypeDefault;
3096 device->Frequency = DEFAULT_OUTPUT_RATE;
3097 device->NumUpdates = 4;
3098 device->UpdateSize = 1024;
3100 if(!PlaybackBackend.getFactory)
3101 device->Backend = create_backend_wrapper(device, &PlaybackBackend.Funcs,
3102 ALCbackend_Playback);
3103 else
3105 ALCbackendFactory *factory = PlaybackBackend.getFactory();
3106 device->Backend = V(factory,createBackend)(device, ALCbackend_Playback);
3108 if(!device->Backend)
3110 al_free(device);
3111 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3112 return NULL;
3116 if(ConfigValueStr(NULL, "channels", &fmt))
3118 static const struct {
3119 const char name[16];
3120 enum DevFmtChannels chans;
3121 } chanlist[] = {
3122 { "mono", DevFmtMono },
3123 { "stereo", DevFmtStereo },
3124 { "quad", DevFmtQuad },
3125 { "surround51", DevFmtX51 },
3126 { "surround61", DevFmtX61 },
3127 { "surround71", DevFmtX71 },
3129 size_t i;
3131 for(i = 0;i < COUNTOF(chanlist);i++)
3133 if(strcasecmp(chanlist[i].name, fmt) == 0)
3135 device->FmtChans = chanlist[i].chans;
3136 device->Flags |= DEVICE_CHANNELS_REQUEST;
3137 break;
3140 if(i == COUNTOF(chanlist))
3141 ERR("Unsupported channels: %s\n", fmt);
3143 if(ConfigValueStr(NULL, "sample-type", &fmt))
3145 static const struct {
3146 const char name[16];
3147 enum DevFmtType type;
3148 } typelist[] = {
3149 { "int8", DevFmtByte },
3150 { "uint8", DevFmtUByte },
3151 { "int16", DevFmtShort },
3152 { "uint16", DevFmtUShort },
3153 { "int32", DevFmtInt },
3154 { "uint32", DevFmtUInt },
3155 { "float32", DevFmtFloat },
3157 size_t i;
3159 for(i = 0;i < COUNTOF(typelist);i++)
3161 if(strcasecmp(typelist[i].name, fmt) == 0)
3163 device->FmtType = typelist[i].type;
3164 device->Flags |= DEVICE_SAMPLE_TYPE_REQUEST;
3165 break;
3168 if(i == COUNTOF(typelist))
3169 ERR("Unsupported sample-type: %s\n", fmt);
3171 #define DEVICE_FORMAT_REQUEST (DEVICE_CHANNELS_REQUEST|DEVICE_SAMPLE_TYPE_REQUEST)
3172 if((device->Flags&DEVICE_FORMAT_REQUEST) != DEVICE_FORMAT_REQUEST &&
3173 ConfigValueStr(NULL, "format", &fmt))
3175 static const struct {
3176 const char name[32];
3177 enum DevFmtChannels channels;
3178 enum DevFmtType type;
3179 } formats[] = {
3180 { "AL_FORMAT_MONO32", DevFmtMono, DevFmtFloat },
3181 { "AL_FORMAT_STEREO32", DevFmtStereo, DevFmtFloat },
3182 { "AL_FORMAT_QUAD32", DevFmtQuad, DevFmtFloat },
3183 { "AL_FORMAT_51CHN32", DevFmtX51, DevFmtFloat },
3184 { "AL_FORMAT_61CHN32", DevFmtX61, DevFmtFloat },
3185 { "AL_FORMAT_71CHN32", DevFmtX71, DevFmtFloat },
3187 { "AL_FORMAT_MONO16", DevFmtMono, DevFmtShort },
3188 { "AL_FORMAT_STEREO16", DevFmtStereo, DevFmtShort },
3189 { "AL_FORMAT_QUAD16", DevFmtQuad, DevFmtShort },
3190 { "AL_FORMAT_51CHN16", DevFmtX51, DevFmtShort },
3191 { "AL_FORMAT_61CHN16", DevFmtX61, DevFmtShort },
3192 { "AL_FORMAT_71CHN16", DevFmtX71, DevFmtShort },
3194 { "AL_FORMAT_MONO8", DevFmtMono, DevFmtByte },
3195 { "AL_FORMAT_STEREO8", DevFmtStereo, DevFmtByte },
3196 { "AL_FORMAT_QUAD8", DevFmtQuad, DevFmtByte },
3197 { "AL_FORMAT_51CHN8", DevFmtX51, DevFmtByte },
3198 { "AL_FORMAT_61CHN8", DevFmtX61, DevFmtByte },
3199 { "AL_FORMAT_71CHN8", DevFmtX71, DevFmtByte }
3201 size_t i;
3203 ERR("Option 'format' is deprecated, please use 'channels' and 'sample-type'\n");
3204 for(i = 0;i < COUNTOF(formats);i++)
3206 if(strcasecmp(fmt, formats[i].name) == 0)
3208 if(!(device->Flags&DEVICE_CHANNELS_REQUEST))
3209 device->FmtChans = formats[i].channels;
3210 if(!(device->Flags&DEVICE_SAMPLE_TYPE_REQUEST))
3211 device->FmtType = formats[i].type;
3212 device->Flags |= DEVICE_FORMAT_REQUEST;
3213 break;
3216 if(i == COUNTOF(formats))
3217 ERR("Unsupported format: %s\n", fmt);
3219 #undef DEVICE_FORMAT_REQUEST
3221 if(ConfigValueUInt(NULL, "frequency", &device->Frequency))
3223 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3224 if(device->Frequency < MIN_OUTPUT_RATE)
3225 ERR("%uhz request clamped to %uhz minimum\n", device->Frequency, MIN_OUTPUT_RATE);
3226 device->Frequency = maxu(device->Frequency, MIN_OUTPUT_RATE);
3229 ConfigValueUInt(NULL, "periods", &device->NumUpdates);
3230 device->NumUpdates = clampu(device->NumUpdates, 2, 16);
3232 ConfigValueUInt(NULL, "period_size", &device->UpdateSize);
3233 device->UpdateSize = clampu(device->UpdateSize, 64, 8192);
3234 if((CPUCapFlags&CPU_CAP_SSE))
3235 device->UpdateSize = (device->UpdateSize+3)&~3;
3237 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3238 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3240 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3241 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3243 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3244 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3246 ConfigValueInt(NULL, "cf_level", &device->Bs2bLevel);
3248 device->NumStereoSources = 1;
3249 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3251 device->Synth = SynthCreate(device);
3252 if(!device->Synth)
3254 DELETE_OBJ(device->Backend);
3255 al_free(device);
3256 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3257 return NULL;
3260 // Find a playback device to open
3261 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3263 DELETE_OBJ(device->Synth);
3264 DELETE_OBJ(device->Backend);
3265 al_free(device);
3266 alcSetError(NULL, err);
3267 return NULL;
3270 if(DefaultEffect.type != AL_EFFECT_NULL)
3272 device->DefaultSlot = (ALeffectslot*)device->_slot_mem;
3273 if(InitEffectSlot(device->DefaultSlot) != AL_NO_ERROR)
3275 device->DefaultSlot = NULL;
3276 ERR("Failed to initialize the default effect slot\n");
3278 else if(InitializeEffect(device, device->DefaultSlot, &DefaultEffect) != AL_NO_ERROR)
3280 ALeffectState *state = device->DefaultSlot->EffectState;
3281 device->DefaultSlot = NULL;
3282 DELETE_OBJ(state);
3283 ERR("Failed to initialize the default effect\n");
3287 do {
3288 device->next = DeviceList;
3289 } while(CompExchangePtr((XchgPtr*)&DeviceList, device->next, device) != device->next);
3291 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3292 return device;
3295 /* alcCloseDevice
3297 * Closes the given device.
3299 ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *Device)
3301 ALCdevice *volatile*list;
3302 ALCcontext *ctx;
3304 LockLists();
3305 list = &DeviceList;
3306 while(*list && *list != Device)
3307 list = &(*list)->next;
3309 if(!*list || (*list)->Type == Capture)
3311 alcSetError(*list, ALC_INVALID_DEVICE);
3312 UnlockLists();
3313 return ALC_FALSE;
3316 *list = (*list)->next;
3317 UnlockLists();
3319 while((ctx=Device->ContextList) != NULL)
3321 WARN("Releasing context %p\n", ctx);
3322 ReleaseContext(ctx, Device);
3324 if((Device->Flags&DEVICE_RUNNING))
3325 V0(Device->Backend,stop)();
3326 Device->Flags &= ~DEVICE_RUNNING;
3328 ALCdevice_DecRef(Device);
3330 return ALC_TRUE;
3334 /************************************************
3335 * ALC capture functions
3336 ************************************************/
3337 ALC_API ALCdevice* ALC_APIENTRY alcCaptureOpenDevice(const ALCchar *deviceName, ALCuint frequency, ALCenum format, ALCsizei samples)
3339 ALCdevice *device = NULL;
3340 ALCenum err;
3342 DO_INITCONFIG();
3344 if(!CaptureBackend.name)
3346 alcSetError(NULL, ALC_INVALID_VALUE);
3347 return NULL;
3350 if(samples <= 0)
3352 alcSetError(NULL, ALC_INVALID_VALUE);
3353 return NULL;
3356 if(deviceName && (!deviceName[0] || strcasecmp(deviceName, alcDefaultName) == 0 || strcasecmp(deviceName, "openal-soft") == 0))
3357 deviceName = NULL;
3359 device = al_calloc(16, sizeof(ALCdevice));
3360 if(!device)
3362 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3363 return NULL;
3366 //Validate device
3367 InitRef(&device->ref, 1);
3368 device->Connected = ALC_TRUE;
3369 device->Type = Capture;
3371 AL_STRING_INIT(device->DeviceName);
3373 InitUIntMap(&device->BufferMap, ~0);
3374 InitUIntMap(&device->EffectMap, ~0);
3375 InitUIntMap(&device->FilterMap, ~0);
3376 InitUIntMap(&device->SfontMap, ~0);
3377 InitUIntMap(&device->PresetMap, ~0);
3378 InitUIntMap(&device->FontsoundMap, ~0);
3380 if(!CaptureBackend.getFactory)
3381 device->Backend = create_backend_wrapper(device, &CaptureBackend.Funcs,
3382 ALCbackend_Capture);
3383 else
3385 ALCbackendFactory *factory = CaptureBackend.getFactory();
3386 device->Backend = V(factory,createBackend)(device, ALCbackend_Capture);
3388 if(!device->Backend)
3390 al_free(device);
3391 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3392 return NULL;
3395 device->Flags |= DEVICE_FREQUENCY_REQUEST;
3396 device->Frequency = frequency;
3398 device->Flags |= DEVICE_CHANNELS_REQUEST | DEVICE_SAMPLE_TYPE_REQUEST;
3399 if(DecomposeDevFormat(format, &device->FmtChans, &device->FmtType) == AL_FALSE)
3401 al_free(device);
3402 alcSetError(NULL, ALC_INVALID_ENUM);
3403 return NULL;
3406 device->UpdateSize = samples;
3407 device->NumUpdates = 1;
3409 if((err=V(device->Backend,open)(deviceName)) != ALC_NO_ERROR)
3411 al_free(device);
3412 alcSetError(NULL, err);
3413 return NULL;
3416 do {
3417 device->next = DeviceList;
3418 } while(CompExchangePtr((XchgPtr*)&DeviceList, device->next, device) != device->next);
3420 TRACE("Created device %p, \"%s\"\n", device, al_string_get_cstr(device->DeviceName));
3421 return device;
3424 ALC_API ALCboolean ALC_APIENTRY alcCaptureCloseDevice(ALCdevice *Device)
3426 ALCdevice *volatile*list;
3428 LockLists();
3429 list = &DeviceList;
3430 while(*list && *list != Device)
3431 list = &(*list)->next;
3433 if(!*list || (*list)->Type != Capture)
3435 alcSetError(*list, ALC_INVALID_DEVICE);
3436 UnlockLists();
3437 return ALC_FALSE;
3440 *list = (*list)->next;
3441 UnlockLists();
3443 ALCdevice_DecRef(Device);
3445 return ALC_TRUE;
3448 ALC_API void ALC_APIENTRY alcCaptureStart(ALCdevice *device)
3450 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3451 alcSetError(device, ALC_INVALID_DEVICE);
3452 else
3454 ALCdevice_Lock(device);
3455 if(device->Connected)
3457 if(!(device->Flags&DEVICE_RUNNING))
3458 V0(device->Backend,start)();
3459 device->Flags |= DEVICE_RUNNING;
3461 ALCdevice_Unlock(device);
3464 if(device) ALCdevice_DecRef(device);
3467 ALC_API void ALC_APIENTRY alcCaptureStop(ALCdevice *device)
3469 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3470 alcSetError(device, ALC_INVALID_DEVICE);
3471 else
3473 ALCdevice_Lock(device);
3474 if((device->Flags&DEVICE_RUNNING))
3475 V0(device->Backend,stop)();
3476 device->Flags &= ~DEVICE_RUNNING;
3477 ALCdevice_Unlock(device);
3480 if(device) ALCdevice_DecRef(device);
3483 ALC_API void ALC_APIENTRY alcCaptureSamples(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3485 if(!(device=VerifyDevice(device)) || device->Type != Capture)
3486 alcSetError(device, ALC_INVALID_DEVICE);
3487 else
3489 ALCenum err = ALC_INVALID_VALUE;
3491 ALCdevice_Lock(device);
3492 if(samples >= 0 && V0(device->Backend,availableSamples)() >= (ALCuint)samples)
3493 err = V(device->Backend,captureSamples)(buffer, samples);
3494 ALCdevice_Unlock(device);
3496 if(err != ALC_NO_ERROR)
3497 alcSetError(device, err);
3499 if(device) ALCdevice_DecRef(device);
3503 /************************************************
3504 * ALC loopback functions
3505 ************************************************/
3507 /* alcLoopbackOpenDeviceSOFT
3509 * Open a loopback device, for manual rendering.
3511 ALC_API ALCdevice* ALC_APIENTRY alcLoopbackOpenDeviceSOFT(const ALCchar *deviceName)
3513 ALCbackendFactory *factory;
3514 ALCdevice *device;
3516 DO_INITCONFIG();
3518 /* Make sure the device name, if specified, is us. */
3519 if(deviceName && strcmp(deviceName, alcDefaultName) != 0)
3521 alcSetError(NULL, ALC_INVALID_VALUE);
3522 return NULL;
3525 device = al_calloc(16, sizeof(ALCdevice));
3526 if(!device)
3528 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3529 return NULL;
3532 //Validate device
3533 InitRef(&device->ref, 1);
3534 device->Connected = ALC_TRUE;
3535 device->Type = Loopback;
3536 device->LastError = ALC_NO_ERROR;
3538 device->Flags = 0;
3539 device->Bs2b = NULL;
3540 device->Bs2bLevel = 0;
3541 AL_STRING_INIT(device->DeviceName);
3543 device->ContextList = NULL;
3545 device->ClockBase = 0;
3546 device->SamplesDone = 0;
3548 device->MaxNoOfSources = 256;
3549 device->AuxiliaryEffectSlotMax = 4;
3550 device->NumAuxSends = MAX_SENDS;
3552 InitUIntMap(&device->BufferMap, ~0);
3553 InitUIntMap(&device->EffectMap, ~0);
3554 InitUIntMap(&device->FilterMap, ~0);
3555 InitUIntMap(&device->SfontMap, ~0);
3556 InitUIntMap(&device->PresetMap, ~0);
3557 InitUIntMap(&device->FontsoundMap, ~0);
3559 factory = ALCloopbackFactory_getFactory();
3560 device->Backend = V(factory,createBackend)(device, ALCbackend_Loopback);
3561 if(!device->Backend)
3563 al_free(device);
3564 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3565 return NULL;
3568 //Set output format
3569 device->NumUpdates = 0;
3570 device->UpdateSize = 0;
3572 device->Frequency = DEFAULT_OUTPUT_RATE;
3573 device->FmtChans = DevFmtChannelsDefault;
3574 device->FmtType = DevFmtTypeDefault;
3576 ConfigValueUInt(NULL, "sources", &device->MaxNoOfSources);
3577 if(device->MaxNoOfSources == 0) device->MaxNoOfSources = 256;
3579 ConfigValueUInt(NULL, "slots", &device->AuxiliaryEffectSlotMax);
3580 if(device->AuxiliaryEffectSlotMax == 0) device->AuxiliaryEffectSlotMax = 4;
3582 ConfigValueUInt(NULL, "sends", &device->NumAuxSends);
3583 if(device->NumAuxSends > MAX_SENDS) device->NumAuxSends = MAX_SENDS;
3585 device->NumStereoSources = 1;
3586 device->NumMonoSources = device->MaxNoOfSources - device->NumStereoSources;
3588 device->Synth = SynthCreate(device);
3589 if(!device->Synth)
3591 DELETE_OBJ(device->Backend);
3592 al_free(device);
3593 alcSetError(NULL, ALC_OUT_OF_MEMORY);
3594 return NULL;
3597 // Open the "backend"
3598 V(device->Backend,open)("Loopback");
3599 do {
3600 device->next = DeviceList;
3601 } while(CompExchangePtr((XchgPtr*)&DeviceList, device->next, device) != device->next);
3603 TRACE("Created device %p\n", device);
3604 return device;
3607 /* alcIsRenderFormatSupportedSOFT
3609 * Determines if the loopback device supports the given format for rendering.
3611 ALC_API ALCboolean ALC_APIENTRY alcIsRenderFormatSupportedSOFT(ALCdevice *device, ALCsizei freq, ALCenum channels, ALCenum type)
3613 ALCboolean ret = ALC_FALSE;
3615 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3616 alcSetError(device, ALC_INVALID_DEVICE);
3617 else if(freq <= 0)
3618 alcSetError(device, ALC_INVALID_VALUE);
3619 else
3621 if(IsValidALCType(type) && BytesFromDevFmt(type) > 0 &&
3622 IsValidALCChannels(channels) && ChannelsFromDevFmt(channels) > 0 &&
3623 freq >= MIN_OUTPUT_RATE)
3624 ret = ALC_TRUE;
3626 if(device) ALCdevice_DecRef(device);
3628 return ret;
3631 /* alcRenderSamplesSOFT
3633 * Renders some samples into a buffer, using the format last set by the
3634 * attributes given to alcCreateContext.
3636 FORCE_ALIGN ALC_API void ALC_APIENTRY alcRenderSamplesSOFT(ALCdevice *device, ALCvoid *buffer, ALCsizei samples)
3638 if(!(device=VerifyDevice(device)) || device->Type != Loopback)
3639 alcSetError(device, ALC_INVALID_DEVICE);
3640 else if(samples < 0 || (samples > 0 && buffer == NULL))
3641 alcSetError(device, ALC_INVALID_VALUE);
3642 else
3643 aluMixData(device, buffer, samples);
3644 if(device) ALCdevice_DecRef(device);
3648 /************************************************
3649 * ALC DSP pause/resume functions
3650 ************************************************/
3652 /* alcDevicePauseSOFT
3654 * Pause the DSP to stop audio processing.
3656 ALC_API void ALC_APIENTRY alcDevicePauseSOFT(ALCdevice *device)
3658 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3659 alcSetError(device, ALC_INVALID_DEVICE);
3660 else
3662 LockLists();
3663 if((device->Flags&DEVICE_RUNNING))
3664 V0(device->Backend,stop)();
3665 device->Flags &= ~DEVICE_RUNNING;
3666 device->Flags |= DEVICE_PAUSED;
3667 UnlockLists();
3669 if(device) ALCdevice_DecRef(device);
3672 /* alcDeviceResumeSOFT
3674 * Resume the DSP to restart audio processing.
3676 ALC_API void ALC_APIENTRY alcDeviceResumeSOFT(ALCdevice *device)
3678 if(!(device=VerifyDevice(device)) || device->Type != Playback)
3679 alcSetError(device, ALC_INVALID_DEVICE);
3680 else
3682 LockLists();
3683 if((device->Flags&DEVICE_PAUSED))
3685 device->Flags &= ~DEVICE_PAUSED;
3686 if(device->ContextList != NULL)
3688 if(V0(device->Backend,start)() != ALC_FALSE)
3689 device->Flags |= DEVICE_RUNNING;
3690 else
3692 alcSetError(device, ALC_INVALID_DEVICE);
3693 ALCdevice_Lock(device);
3694 aluHandleDisconnect(device);
3695 ALCdevice_Unlock(device);
3699 UnlockLists();
3701 if(device) ALCdevice_DecRef(device);