26 #define ALC_SOFT_HRTF 1
27 #define ALC_HRTF_SOFT 0x1992
32 /* KDevelop's parser doesn't recognize the C99-standard restrict keyword, but
33 * recent versions (at least 4.5.1) do recognize GCC's __restrict. */
34 #define restrict __restrict
35 /* KDevelop won't see the ALIGN macro from config.h when viewing files that
36 * don't include it directly (e.g. headers). */
43 typedef ALint64SOFT ALint64
;
44 typedef ALuint64SOFT ALuint64
;
46 typedef ptrdiff_t ALintptrEXT
;
47 typedef ptrdiff_t ALsizeiptrEXT
;
51 #define U64(x) ((ALuint64)(x##ui64))
52 #elif SIZEOF_LONG == 8
53 #define U64(x) ((ALuint64)(x##ul))
54 #elif SIZEOF_LONG_LONG == 8
55 #define U64(x) ((ALuint64)(x##ull))
60 #if defined(__cplusplus)
62 #elif defined(__GNUC__)
63 #define UNUSED(x) UNUSED_##x __attribute__((unused))
64 #elif defined(__LCLINT__)
65 #define UNUSED(x) /*@unused@*/ x
71 #ifdef HAVE_GCC_FORMAT
72 #define PRINTF_STYLE(x, y) __attribute__((format(printf, (x), (y))))
74 #define PRINTF_STYLE(x, y)
77 #if defined(__GNUC__) && defined(__i386__)
78 /* force_align_arg_pointer is required for proper function arguments aligning
79 * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
80 * thread functions will be properly aligned on the stack, even though GCC may
81 * generate code with the assumption that it is. */
82 #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
90 ALubyte b
[sizeof(ALuint
)];
92 #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
94 #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
97 #define DERIVE_FROM_TYPE(t) t t##_parent
98 #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
99 #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
102 #define DECLARE_FORWARD(T1, T2, rettype, func) \
103 rettype T1##_##func(T1 *obj) \
104 { return T2##_##func(STATIC_CAST(T2, obj)); }
106 #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
107 rettype T1##_##func(T1 *obj, argtype1 a) \
108 { return T2##_##func(STATIC_CAST(T2, obj), a); }
110 #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
111 rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
112 { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
115 #define GET_VTABLE1(T1) (&(T1##_vtable))
116 #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
118 #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
119 #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
121 #define DECLARE_THUNK(T1, T2, rettype, func) \
122 static rettype T1##_##T2##_##func(T2 *obj) \
123 { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
125 #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
126 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
127 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
129 #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
130 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
131 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
133 #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
134 static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
135 { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
138 /* Helper to extract an argument list for VCALL. Not used directly. */
139 #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
141 /* Call a "virtual" method on an object, with arguments. */
142 #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
143 /* Call a "virtual" method on an object, with no arguments. */
144 #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
146 #define DELETE_OBJ(obj) do { \
149 V0((obj),Destruct)(); \
150 V0((obj),Delete)(); \
162 #define DEFAULT_OUTPUT_RATE (44100)
163 #define MIN_OUTPUT_RATE (8000)
166 /* Find the next power-of-2 for non-power-of-2 numbers. */
167 inline ALuint
NextPowerOf2(ALuint value
)
181 /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
183 inline ALint
fastf2i(ALfloat f
)
187 #elif defined(_MSC_VER) && defined(_M_IX86)
197 /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
199 inline ALuint
fastf2u(ALfloat f
)
200 { return fastf2i(f
); }
209 ALCenum (*OpenPlayback
)(ALCdevice
*, const ALCchar
*);
210 void (*ClosePlayback
)(ALCdevice
*);
211 ALCboolean (*ResetPlayback
)(ALCdevice
*);
212 ALCboolean (*StartPlayback
)(ALCdevice
*);
213 void (*StopPlayback
)(ALCdevice
*);
215 ALCenum (*OpenCapture
)(ALCdevice
*, const ALCchar
*);
216 void (*CloseCapture
)(ALCdevice
*);
217 void (*StartCapture
)(ALCdevice
*);
218 void (*StopCapture
)(ALCdevice
*);
219 ALCenum (*CaptureSamples
)(ALCdevice
*, void*, ALCuint
);
220 ALCuint (*AvailableSamples
)(ALCdevice
*);
222 ALint64 (*GetLatency
)(ALCdevice
*);
225 ALCboolean
alc_solaris_init(BackendFuncs
*func_list
);
226 void alc_solaris_deinit(void);
227 void alc_solaris_probe(enum DevProbe type
);
228 ALCboolean
alc_sndio_init(BackendFuncs
*func_list
);
229 void alc_sndio_deinit(void);
230 void alc_sndio_probe(enum DevProbe type
);
231 ALCboolean
alcMMDevApiInit(BackendFuncs
*func_list
);
232 void alcMMDevApiDeinit(void);
233 void alcMMDevApiProbe(enum DevProbe type
);
234 ALCboolean
alcDSoundInit(BackendFuncs
*func_list
);
235 void alcDSoundDeinit(void);
236 void alcDSoundProbe(enum DevProbe type
);
237 ALCboolean
alcWinMMInit(BackendFuncs
*FuncList
);
238 void alcWinMMDeinit(void);
239 void alcWinMMProbe(enum DevProbe type
);
240 ALCboolean
alc_pa_init(BackendFuncs
*func_list
);
241 void alc_pa_deinit(void);
242 void alc_pa_probe(enum DevProbe type
);
243 ALCboolean
alc_wave_init(BackendFuncs
*func_list
);
244 void alc_wave_deinit(void);
245 void alc_wave_probe(enum DevProbe type
);
246 ALCboolean
alc_ca_init(BackendFuncs
*func_list
);
247 void alc_ca_deinit(void);
248 void alc_ca_probe(enum DevProbe type
);
249 ALCboolean
alc_opensl_init(BackendFuncs
*func_list
);
250 void alc_opensl_deinit(void);
251 void alc_opensl_probe(enum DevProbe type
);
252 ALCboolean
alc_qsa_init(BackendFuncs
*func_list
);
253 void alc_qsa_deinit(void);
254 void alc_qsa_probe(enum DevProbe type
);
260 InverseDistanceClamped
= AL_INVERSE_DISTANCE_CLAMPED
,
261 LinearDistanceClamped
= AL_LINEAR_DISTANCE_CLAMPED
,
262 ExponentDistanceClamped
= AL_EXPONENT_DISTANCE_CLAMPED
,
263 InverseDistance
= AL_INVERSE_DISTANCE
,
264 LinearDistance
= AL_LINEAR_DISTANCE
,
265 ExponentDistance
= AL_EXPONENT_DISTANCE
,
266 DisableDistance
= AL_NONE
,
268 DefaultDistanceModel
= InverseDistanceClamped
296 DevFmtByte
= ALC_BYTE_SOFT
,
297 DevFmtUByte
= ALC_UNSIGNED_BYTE_SOFT
,
298 DevFmtShort
= ALC_SHORT_SOFT
,
299 DevFmtUShort
= ALC_UNSIGNED_SHORT_SOFT
,
300 DevFmtInt
= ALC_INT_SOFT
,
301 DevFmtUInt
= ALC_UNSIGNED_INT_SOFT
,
302 DevFmtFloat
= ALC_FLOAT_SOFT
,
304 DevFmtTypeDefault
= DevFmtFloat
306 enum DevFmtChannels
{
307 DevFmtMono
= ALC_MONO_SOFT
,
308 DevFmtStereo
= ALC_STEREO_SOFT
,
309 DevFmtQuad
= ALC_QUAD_SOFT
,
310 DevFmtX51
= ALC_5POINT1_SOFT
,
311 DevFmtX61
= ALC_6POINT1_SOFT
,
312 DevFmtX71
= ALC_7POINT1_SOFT
,
314 /* Similar to 5.1, except using the side channels instead of back */
315 DevFmtX51Side
= 0x80000000,
317 DevFmtChannelsDefault
= DevFmtStereo
320 ALuint
BytesFromDevFmt(enum DevFmtType type
);
321 ALuint
ChannelsFromDevFmt(enum DevFmtChannels chans
);
322 inline ALuint
FrameSizeFromDevFmt(enum DevFmtChannels chans
, enum DevFmtType type
)
324 return ChannelsFromDevFmt(chans
) * BytesFromDevFmt(type
);
328 extern const struct EffectList
{
343 /* Size for temporary storage of buffer data, in ALfloats. Larger values need
344 * more memory, while smaller values may need more iterations. The value needs
345 * to be a sensible size, however, as it constrains the max stepping value used
346 * for mixing, as well as the maximum number of samples per mixing iteration.
348 #define BUFFERSIZE (2048u)
351 struct ALCdevice_struct
353 volatile RefCount ref
;
355 ALCboolean Connected
;
356 enum DeviceType Type
;
361 enum DevFmtChannels FmtChans
;
362 enum DevFmtType FmtType
;
366 volatile ALCenum LastError
;
368 // Maximum number of sources that can be created
369 ALuint MaxNoOfSources
;
370 // Maximum number of slots that can be created
371 ALuint AuxiliaryEffectSlotMax
;
373 ALCuint NumMonoSources
;
374 ALCuint NumStereoSources
;
377 // Map of Buffers for this device
380 // Map of Effects for this device
383 // Map of Filters for this device
386 /* HRTF filter tables */
387 const struct Hrtf
*Hrtf
;
389 // Stereo-to-binaural filter
396 ALuint ChannelOffsets
[MaxChannels
];
398 enum Channel Speaker2Chan
[MaxChannels
];
399 ALfloat SpeakerAngle
[MaxChannels
];
402 /* Temp storage used for mixing. +1 for the predictive sample. */
403 ALIGN(16) ALfloat SampleData1
[BUFFERSIZE
+1];
404 ALIGN(16) ALfloat SampleData2
[BUFFERSIZE
+1];
406 // Dry path buffer mix
407 ALIGN(16) ALfloat DryBuffer
[MaxChannels
][BUFFERSIZE
];
409 ALIGN(16) ALfloat ClickRemoval
[MaxChannels
];
410 ALIGN(16) ALfloat PendingClicks
[MaxChannels
];
412 /* Default effect slot */
413 struct ALeffectslot
*DefaultSlot
;
415 // Contexts created on this device
416 ALCcontext
*volatile ContextList
;
418 struct ALCbackend
*Backend
;
421 void *ExtraData
; // For the backend's use
423 ALCdevice
*volatile next
;
426 // Frequency was requested by the app or config file
427 #define DEVICE_FREQUENCY_REQUEST (1<<1)
428 // Channel configuration was requested by the config file
429 #define DEVICE_CHANNELS_REQUEST (1<<2)
430 // Sample type was requested by the config file
431 #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
432 // HRTF was requested by the app
433 #define DEVICE_HRTF_REQUEST (1<<4)
435 // Stereo sources cover 120-degree angles around +/-90
436 #define DEVICE_WIDE_STEREO (1<<16)
438 // Specifies if the device is currently running
439 #define DEVICE_RUNNING (1<<31)
441 /* Invalid channel offset */
442 #define INVALID_OFFSET (~0u)
445 /* Must be less than 15 characters (16 including terminating null) for
446 * compatibility with pthread_setname_np limitations. */
447 #define MIXER_THREAD_NAME "alsoft-mixer"
450 struct ALCcontext_struct
452 volatile RefCount ref
;
454 struct ALlistener
*Listener
;
457 UIntMap EffectSlotMap
;
459 volatile ALenum LastError
;
461 volatile ALenum UpdateSources
;
463 volatile enum DistanceModel DistanceModel
;
464 volatile ALboolean SourceDistanceModel
;
466 volatile ALfloat DopplerFactor
;
467 volatile ALfloat DopplerVelocity
;
468 volatile ALfloat SpeedOfSound
;
469 volatile ALenum DeferUpdates
;
471 struct ALsource
**ActiveSources
;
472 ALsizei ActiveSourceCount
;
473 ALsizei MaxActiveSources
;
475 struct ALeffectslot
**ActiveEffectSlots
;
476 ALsizei ActiveEffectSlotCount
;
477 ALsizei MaxActiveEffectSlots
;
480 const ALCchar
*ExtensionList
;
482 ALCcontext
*volatile next
;
485 ALCcontext
*GetContextRef(void);
487 void ALCcontext_IncRef(ALCcontext
*context
);
488 void ALCcontext_DecRef(ALCcontext
*context
);
490 void AppendAllDevicesList(const ALCchar
*name
);
491 void AppendCaptureDeviceList(const ALCchar
*name
);
493 ALint64
ALCdevice_GetLatencyDefault(ALCdevice
*device
);
495 void ALCdevice_Lock(ALCdevice
*device
);
496 void ALCdevice_Unlock(ALCdevice
*device
);
497 ALint64
ALCdevice_GetLatency(ALCdevice
*device
);
499 inline void LockContext(ALCcontext
*context
)
500 { ALCdevice_Lock(context
->Device
); }
502 inline void UnlockContext(ALCcontext
*context
)
503 { ALCdevice_Unlock(context
->Device
); }
506 void *al_malloc(size_t alignment
, size_t size
);
507 void *al_calloc(size_t alignment
, size_t size
);
508 void al_free(void *ptr
);
513 DERIVE_FROM_TYPE(fenv_t
);
521 void SetMixerFPUMode(FPUCtl
*ctl
);
522 void RestoreFPUMode(const FPUCtl
*ctl
);
525 typedef struct RingBuffer RingBuffer
;
526 RingBuffer
*CreateRingBuffer(ALsizei frame_size
, ALsizei length
);
527 void DestroyRingBuffer(RingBuffer
*ring
);
528 ALsizei
RingBufferSize(RingBuffer
*ring
);
529 void WriteRingBuffer(RingBuffer
*ring
, const ALubyte
*data
, ALsizei len
);
530 void ReadRingBuffer(RingBuffer
*ring
, ALubyte
*data
, ALsizei len
);
532 void ReadALConfig(void);
533 void FreeALConfig(void);
534 int ConfigValueExists(const char *blockName
, const char *keyName
);
535 const char *GetConfigValue(const char *blockName
, const char *keyName
, const char *def
);
536 int GetConfigValueBool(const char *blockName
, const char *keyName
, int def
);
537 int ConfigValueStr(const char *blockName
, const char *keyName
, const char **ret
);
538 int ConfigValueInt(const char *blockName
, const char *keyName
, int *ret
);
539 int ConfigValueUInt(const char *blockName
, const char *keyName
, unsigned int *ret
);
540 int ConfigValueFloat(const char *blockName
, const char *keyName
, float *ret
);
542 void SetRTPriority(void);
544 void SetDefaultChannelOrder(ALCdevice
*device
);
545 void SetDefaultWFXChannelOrder(ALCdevice
*device
);
547 const ALCchar
*DevFmtTypeString(enum DevFmtType type
);
548 const ALCchar
*DevFmtChannelsString(enum DevFmtChannels chans
);
550 #define HRIR_BITS (7)
551 #define HRIR_LENGTH (1<<HRIR_BITS)
552 #define HRIR_MASK (HRIR_LENGTH-1)
553 #define HRTFDELAY_BITS (20)
554 #define HRTFDELAY_FRACONE (1<<HRTFDELAY_BITS)
555 #define HRTFDELAY_MASK (HRTFDELAY_FRACONE-1)
556 const struct Hrtf
*GetHrtf(ALCdevice
*device
);
557 void FindHrtfFormat(const ALCdevice
*device
, enum DevFmtChannels
*chans
, ALCuint
*srate
);
558 void FreeHrtfs(void);
559 ALuint
GetHrtfIrSize(const struct Hrtf
*Hrtf
);
560 ALfloat
CalcHrtfDelta(ALfloat oldGain
, ALfloat newGain
, const ALfloat olddir
[3], const ALfloat newdir
[3]);
561 void GetLerpedHrtfCoeffs(const struct Hrtf
*Hrtf
, ALfloat elevation
, ALfloat azimuth
, ALfloat gain
, ALfloat (*coeffs
)[2], ALuint
*delays
);
562 ALuint
GetMovingHrtfCoeffs(const struct Hrtf
*Hrtf
, ALfloat elevation
, ALfloat azimuth
, ALfloat gain
, ALfloat delta
, ALint counter
, ALfloat (*coeffs
)[2], ALuint
*delays
, ALfloat (*coeffStep
)[2], ALint
*delayStep
);
565 extern FILE *LogFile
;
568 #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
570 void al_print(const char *type
, const char *func
, const char *fmt
, ...) PRINTF_STYLE(3,4);
571 #define AL_PRINT(T, MSG, ...) al_print((T), __FUNCTION__, MSG, __VA_ARGS__)
581 extern enum LogLevel LogLevel
;
583 #define TRACEREF(...) do { \
584 if(LogLevel >= LogRef) \
585 AL_PRINT("(--)", __VA_ARGS__); \
588 #define TRACE(...) do { \
589 if(LogLevel >= LogTrace) \
590 AL_PRINT("(II)", __VA_ARGS__); \
593 #define WARN(...) do { \
594 if(LogLevel >= LogWarning) \
595 AL_PRINT("(WW)", __VA_ARGS__); \
598 #define ERR(...) do { \
599 if(LogLevel >= LogError) \
600 AL_PRINT("(EE)", __VA_ARGS__); \
604 extern ALint RTPrioLevel
;
607 extern ALuint CPUCapFlags
;
614 void FillCPUCaps(ALuint capfilter
);
617 #define SET_ERROR_AND_RETURN(ctx, err) do { \
618 alSetError((ctx), (err)); \
622 #define SET_ERROR_AND_RETURN_VALUE(ctx, err, val) do { \
623 alSetError((ctx), (err)); \
627 #define SET_ERROR_AND_GOTO(ctx, err, lbl) do { \
628 alSetError((ctx), (err)); \
633 /* Small hack to use a pointer-to-array type as a normal argument type.
634 * Shouldn't be used directly. */
635 typedef ALfloat ALfloatBUFFERSIZE
[BUFFERSIZE
];