alMain.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. #ifndef AL_MAIN_H
  2. #define AL_MAIN_H
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <stdarg.h>
  6. #include <assert.h>
  7. #include <math.h>
  8. #include <limits.h>
  9. #ifdef HAVE_STRINGS_H
  10. #include <strings.h>
  11. #endif
  12. #ifdef HAVE_FENV_H
  13. #include <fenv.h>
  14. #endif
  15. #include "AL/al.h"
  16. #include "AL/alc.h"
  17. #include "AL/alext.h"
  18. #if defined(_WIN64)
  19. #define SZFMT "%I64u"
  20. #elif defined(_WIN32)
  21. #define SZFMT "%u"
  22. #else
  23. #define SZFMT "%zu"
  24. #endif
  25. #include "static_assert.h"
  26. #include "align.h"
  27. #include "atomic.h"
  28. #include "uintmap.h"
  29. #include "vector.h"
  30. #include "alstring.h"
  31. #include "hrtf.h"
  32. #ifndef ALC_SOFT_device_clock
  33. #define ALC_SOFT_device_clock 1
  34. typedef int64_t ALCint64SOFT;
  35. typedef uint64_t ALCuint64SOFT;
  36. #define ALC_DEVICE_CLOCK_SOFT 0x1600
  37. typedef void (ALC_APIENTRY*LPALCGETINTEGER64VSOFT)(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
  38. #ifdef AL_ALEXT_PROTOTYPES
  39. ALC_API void ALC_APIENTRY alcGetInteger64vSOFT(ALCdevice *device, ALCenum pname, ALsizei size, ALCint64SOFT *values);
  40. #endif
  41. #endif
  42. typedef ALint64SOFT ALint64;
  43. typedef ALuint64SOFT ALuint64;
  44. #ifndef U64
  45. #if defined(_MSC_VER)
  46. #define U64(x) ((ALuint64)(x##ui64))
  47. #elif SIZEOF_LONG == 8
  48. #define U64(x) ((ALuint64)(x##ul))
  49. #elif SIZEOF_LONG_LONG == 8
  50. #define U64(x) ((ALuint64)(x##ull))
  51. #endif
  52. #endif
  53. #ifndef UINT64_MAX
  54. #define UINT64_MAX U64(18446744073709551615)
  55. #endif
  56. #ifndef UNUSED
  57. #if defined(__cplusplus)
  58. #define UNUSED(x)
  59. #elif defined(__GNUC__)
  60. #define UNUSED(x) UNUSED_##x __attribute__((unused))
  61. #elif defined(__LCLINT__)
  62. #define UNUSED(x) /*@unused@*/ x
  63. #else
  64. #define UNUSED(x) x
  65. #endif
  66. #endif
  67. #ifdef __GNUC__
  68. #define DECL_CONST __attribute__((const))
  69. #define DECL_FORMAT(x, y, z) __attribute__((format(x, (y), (z))))
  70. #else
  71. #define DECL_CONST
  72. #define DECL_FORMAT(x, y, z)
  73. #endif
  74. #if defined(__GNUC__) && defined(__i386__)
  75. /* force_align_arg_pointer is required for proper function arguments aligning
  76. * when SSE code is used. Some systems (Windows, QNX) do not guarantee our
  77. * thread functions will be properly aligned on the stack, even though GCC may
  78. * generate code with the assumption that it is. */
  79. #define FORCE_ALIGN __attribute__((force_align_arg_pointer))
  80. #else
  81. #define FORCE_ALIGN
  82. #endif
  83. #ifdef HAVE_C99_VLA
  84. #define DECL_VLA(T, _name, _size) T _name[(_size)]
  85. #else
  86. #define DECL_VLA(T, _name, _size) T *_name = alloca((_size) * sizeof(T))
  87. #endif
  88. #ifndef PATH_MAX
  89. #ifdef MAX_PATH
  90. #define PATH_MAX MAX_PATH
  91. #else
  92. #define PATH_MAX 4096
  93. #endif
  94. #endif
  95. static const union {
  96. ALuint u;
  97. ALubyte b[sizeof(ALuint)];
  98. } EndianTest = { 1 };
  99. #define IS_LITTLE_ENDIAN (EndianTest.b[0] == 1)
  100. #define COUNTOF(x) (sizeof((x))/sizeof((x)[0]))
  101. #define DERIVE_FROM_TYPE(t) t t##_parent
  102. #define STATIC_CAST(to, obj) (&(obj)->to##_parent)
  103. #ifdef __GNUC__
  104. #define STATIC_UPCAST(to, from, obj) __extension__({ \
  105. static_assert(__builtin_types_compatible_p(from, __typeof(*(obj))), \
  106. "Invalid upcast object from type"); \
  107. (to*)((char*)(obj) - offsetof(to, from##_parent)); \
  108. })
  109. #else
  110. #define STATIC_UPCAST(to, from, obj) ((to*)((char*)(obj) - offsetof(to, from##_parent)))
  111. #endif
  112. #define DECLARE_FORWARD(T1, T2, rettype, func) \
  113. rettype T1##_##func(T1 *obj) \
  114. { return T2##_##func(STATIC_CAST(T2, obj)); }
  115. #define DECLARE_FORWARD1(T1, T2, rettype, func, argtype1) \
  116. rettype T1##_##func(T1 *obj, argtype1 a) \
  117. { return T2##_##func(STATIC_CAST(T2, obj), a); }
  118. #define DECLARE_FORWARD2(T1, T2, rettype, func, argtype1, argtype2) \
  119. rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b) \
  120. { return T2##_##func(STATIC_CAST(T2, obj), a, b); }
  121. #define DECLARE_FORWARD3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
  122. rettype T1##_##func(T1 *obj, argtype1 a, argtype2 b, argtype3 c) \
  123. { return T2##_##func(STATIC_CAST(T2, obj), a, b, c); }
  124. #define GET_VTABLE1(T1) (&(T1##_vtable))
  125. #define GET_VTABLE2(T1, T2) (&(T1##_##T2##_vtable))
  126. #define SET_VTABLE1(T1, obj) ((obj)->vtbl = GET_VTABLE1(T1))
  127. #define SET_VTABLE2(T1, T2, obj) (STATIC_CAST(T2, obj)->vtbl = GET_VTABLE2(T1, T2))
  128. #define DECLARE_THUNK(T1, T2, rettype, func) \
  129. static rettype T1##_##T2##_##func(T2 *obj) \
  130. { return T1##_##func(STATIC_UPCAST(T1, T2, obj)); }
  131. #define DECLARE_THUNK1(T1, T2, rettype, func, argtype1) \
  132. static rettype T1##_##T2##_##func(T2 *obj, argtype1 a) \
  133. { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a); }
  134. #define DECLARE_THUNK2(T1, T2, rettype, func, argtype1, argtype2) \
  135. static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b) \
  136. { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b); }
  137. #define DECLARE_THUNK3(T1, T2, rettype, func, argtype1, argtype2, argtype3) \
  138. static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c) \
  139. { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c); }
  140. #define DECLARE_THUNK4(T1, T2, rettype, func, argtype1, argtype2, argtype3, argtype4) \
  141. static rettype T1##_##T2##_##func(T2 *obj, argtype1 a, argtype2 b, argtype3 c, argtype4 d) \
  142. { return T1##_##func(STATIC_UPCAST(T1, T2, obj), a, b, c, d); }
  143. #define DECLARE_DEFAULT_ALLOCATORS(T) \
  144. static void* T##_New(size_t size) { return al_malloc(16, size); } \
  145. static void T##_Delete(void *ptr) { al_free(ptr); }
  146. /* Helper to extract an argument list for VCALL. Not used directly. */
  147. #define EXTRACT_VCALL_ARGS(...) __VA_ARGS__))
  148. /* Call a "virtual" method on an object, with arguments. */
  149. #define V(obj, func) ((obj)->vtbl->func((obj), EXTRACT_VCALL_ARGS
  150. /* Call a "virtual" method on an object, with no arguments. */
  151. #define V0(obj, func) ((obj)->vtbl->func((obj) EXTRACT_VCALL_ARGS
  152. #define DELETE_OBJ(obj) do { \
  153. if((obj) != NULL) \
  154. { \
  155. V0((obj),Destruct)(); \
  156. V0((obj),Delete)(); \
  157. } \
  158. } while(0)
  159. #define EXTRACT_NEW_ARGS(...) __VA_ARGS__); \
  160. } \
  161. } while(0)
  162. #define NEW_OBJ(_res, T) do { \
  163. _res = T##_New(sizeof(T)); \
  164. if(_res) \
  165. { \
  166. memset(_res, 0, sizeof(T)); \
  167. T##_Construct(_res, EXTRACT_NEW_ARGS
  168. #ifdef __cplusplus
  169. extern "C" {
  170. #endif
  171. struct Hrtf;
  172. #define DEFAULT_OUTPUT_RATE (44100)
  173. #define MIN_OUTPUT_RATE (8000)
  174. /* Find the next power-of-2 for non-power-of-2 numbers. */
  175. inline ALuint NextPowerOf2(ALuint value)
  176. {
  177. if(value > 0)
  178. {
  179. value--;
  180. value |= value>>1;
  181. value |= value>>2;
  182. value |= value>>4;
  183. value |= value>>8;
  184. value |= value>>16;
  185. }
  186. return value+1;
  187. }
  188. /* Fast float-to-int conversion. Assumes the FPU is already in round-to-zero
  189. * mode. */
  190. inline ALint fastf2i(ALfloat f)
  191. {
  192. #ifdef HAVE_LRINTF
  193. return lrintf(f);
  194. #elif defined(_MSC_VER) && defined(_M_IX86)
  195. ALint i;
  196. __asm fld f
  197. __asm fistp i
  198. return i;
  199. #else
  200. return (ALint)f;
  201. #endif
  202. }
  203. /* Fast float-to-uint conversion. Assumes the FPU is already in round-to-zero
  204. * mode. */
  205. inline ALuint fastf2u(ALfloat f)
  206. { return fastf2i(f); }
  207. enum DevProbe {
  208. ALL_DEVICE_PROBE,
  209. CAPTURE_DEVICE_PROBE
  210. };
  211. typedef struct {
  212. ALCenum (*OpenPlayback)(ALCdevice*, const ALCchar*);
  213. void (*ClosePlayback)(ALCdevice*);
  214. ALCboolean (*ResetPlayback)(ALCdevice*);
  215. ALCboolean (*StartPlayback)(ALCdevice*);
  216. void (*StopPlayback)(ALCdevice*);
  217. ALCenum (*OpenCapture)(ALCdevice*, const ALCchar*);
  218. void (*CloseCapture)(ALCdevice*);
  219. void (*StartCapture)(ALCdevice*);
  220. void (*StopCapture)(ALCdevice*);
  221. ALCenum (*CaptureSamples)(ALCdevice*, void*, ALCuint);
  222. ALCuint (*AvailableSamples)(ALCdevice*);
  223. } BackendFuncs;
  224. ALCboolean alc_sndio_init(BackendFuncs *func_list);
  225. void alc_sndio_deinit(void);
  226. void alc_sndio_probe(enum DevProbe type);
  227. ALCboolean alc_ca_init(BackendFuncs *func_list);
  228. void alc_ca_deinit(void);
  229. void alc_ca_probe(enum DevProbe type);
  230. ALCboolean alc_opensl_init(BackendFuncs *func_list);
  231. void alc_opensl_deinit(void);
  232. void alc_opensl_probe(enum DevProbe type);
  233. ALCboolean alc_qsa_init(BackendFuncs *func_list);
  234. void alc_qsa_deinit(void);
  235. void alc_qsa_probe(enum DevProbe type);
  236. struct ALCbackend;
  237. enum DistanceModel {
  238. InverseDistanceClamped = AL_INVERSE_DISTANCE_CLAMPED,
  239. LinearDistanceClamped = AL_LINEAR_DISTANCE_CLAMPED,
  240. ExponentDistanceClamped = AL_EXPONENT_DISTANCE_CLAMPED,
  241. InverseDistance = AL_INVERSE_DISTANCE,
  242. LinearDistance = AL_LINEAR_DISTANCE,
  243. ExponentDistance = AL_EXPONENT_DISTANCE,
  244. DisableDistance = AL_NONE,
  245. DefaultDistanceModel = InverseDistanceClamped
  246. };
  247. enum Channel {
  248. FrontLeft = 0,
  249. FrontRight,
  250. FrontCenter,
  251. LFE,
  252. BackLeft,
  253. BackRight,
  254. BackCenter,
  255. SideLeft,
  256. SideRight,
  257. BFormatW,
  258. BFormatX,
  259. BFormatY,
  260. BFormatZ,
  261. InvalidChannel
  262. };
  263. /* Device formats */
  264. enum DevFmtType {
  265. DevFmtByte = ALC_BYTE_SOFT,
  266. DevFmtUByte = ALC_UNSIGNED_BYTE_SOFT,
  267. DevFmtShort = ALC_SHORT_SOFT,
  268. DevFmtUShort = ALC_UNSIGNED_SHORT_SOFT,
  269. DevFmtInt = ALC_INT_SOFT,
  270. DevFmtUInt = ALC_UNSIGNED_INT_SOFT,
  271. DevFmtFloat = ALC_FLOAT_SOFT,
  272. DevFmtTypeDefault = DevFmtFloat
  273. };
  274. enum DevFmtChannels {
  275. DevFmtMono = ALC_MONO_SOFT,
  276. DevFmtStereo = ALC_STEREO_SOFT,
  277. DevFmtQuad = ALC_QUAD_SOFT,
  278. DevFmtX51 = ALC_5POINT1_SOFT,
  279. DevFmtX61 = ALC_6POINT1_SOFT,
  280. DevFmtX71 = ALC_7POINT1_SOFT,
  281. /* Similar to 5.1, except using rear channels instead of sides */
  282. DevFmtX51Rear = 0x80000000,
  283. DevFmtBFormat3D,
  284. DevFmtChannelsDefault = DevFmtStereo
  285. };
  286. #define MAX_OUTPUT_CHANNELS (8)
  287. ALuint BytesFromDevFmt(enum DevFmtType type) DECL_CONST;
  288. ALuint ChannelsFromDevFmt(enum DevFmtChannels chans) DECL_CONST;
  289. inline ALuint FrameSizeFromDevFmt(enum DevFmtChannels chans, enum DevFmtType type)
  290. {
  291. return ChannelsFromDevFmt(chans) * BytesFromDevFmt(type);
  292. }
  293. extern const struct EffectList {
  294. const char *name;
  295. int type;
  296. const char *ename;
  297. ALenum val;
  298. } EffectList[];
  299. enum DeviceType {
  300. Playback,
  301. Capture,
  302. Loopback
  303. };
  304. enum HrtfMode {
  305. DisabledHrtf,
  306. BasicHrtf,
  307. FullHrtf
  308. };
  309. /* The maximum number of Ambisonics coefficients. For a given order (o), the
  310. * size needed will be (o+1)**2, thus zero-order has 1, first-order has 4,
  311. * second-order has 9, and third-order has 16. */
  312. #define MAX_AMBI_COEFFS 16
  313. typedef ALfloat ChannelConfig[MAX_AMBI_COEFFS];
  314. #define HRTF_HISTORY_BITS (6)
  315. #define HRTF_HISTORY_LENGTH (1<<HRTF_HISTORY_BITS)
  316. #define HRTF_HISTORY_MASK (HRTF_HISTORY_LENGTH-1)
  317. typedef struct HrtfState {
  318. alignas(16) ALfloat History[HRTF_HISTORY_LENGTH];
  319. alignas(16) ALfloat Values[HRIR_LENGTH][2];
  320. } HrtfState;
  321. typedef struct HrtfParams {
  322. alignas(16) ALfloat Coeffs[HRIR_LENGTH][2];
  323. alignas(16) ALfloat CoeffStep[HRIR_LENGTH][2];
  324. ALuint Delay[2];
  325. ALint DelayStep[2];
  326. } HrtfParams;
  327. /* Size for temporary storage of buffer data, in ALfloats. Larger values need
  328. * more memory, while smaller values may need more iterations. The value needs
  329. * to be a sensible size, however, as it constrains the max stepping value used
  330. * for mixing, as well as the maximum number of samples per mixing iteration.
  331. */
  332. #define BUFFERSIZE (2048u)
  333. struct ALCdevice_struct
  334. {
  335. RefCount ref;
  336. ALCboolean Connected;
  337. enum DeviceType Type;
  338. ALuint Frequency;
  339. ALuint UpdateSize;
  340. ALuint NumUpdates;
  341. enum DevFmtChannels FmtChans;
  342. enum DevFmtType FmtType;
  343. ALboolean IsHeadphones;
  344. al_string DeviceName;
  345. ATOMIC(ALCenum) LastError;
  346. // Maximum number of sources that can be created
  347. ALuint MaxNoOfSources;
  348. // Maximum number of slots that can be created
  349. ALuint AuxiliaryEffectSlotMax;
  350. ALCuint NumMonoSources;
  351. ALCuint NumStereoSources;
  352. ALuint NumAuxSends;
  353. // Map of Buffers for this device
  354. UIntMap BufferMap;
  355. // Map of Effects for this device
  356. UIntMap EffectMap;
  357. // Map of Filters for this device
  358. UIntMap FilterMap;
  359. /* HRTF filter tables */
  360. vector_HrtfEntry Hrtf_List;
  361. al_string Hrtf_Name;
  362. const struct Hrtf *Hrtf;
  363. ALCenum Hrtf_Status;
  364. enum HrtfMode Hrtf_Mode;
  365. HrtfState Hrtf_State[MAX_OUTPUT_CHANNELS];
  366. HrtfParams Hrtf_Params[MAX_OUTPUT_CHANNELS];
  367. ALuint Hrtf_Offset;
  368. // Stereo-to-binaural filter
  369. struct bs2b *Bs2b;
  370. // Device flags
  371. ALuint Flags;
  372. enum Channel ChannelName[MAX_OUTPUT_CHANNELS];
  373. ChannelConfig AmbiCoeffs[MAX_OUTPUT_CHANNELS];
  374. ALfloat AmbiScale; /* Scale for first-order XYZ inputs using AmbCoeffs. */
  375. ALuint NumChannels;
  376. ALuint64 ClockBase;
  377. ALuint SamplesDone;
  378. /* Temp storage used for each source when mixing. */
  379. alignas(16) ALfloat SourceData[BUFFERSIZE];
  380. alignas(16) ALfloat ResampledData[BUFFERSIZE];
  381. alignas(16) ALfloat FilteredData[BUFFERSIZE];
  382. /* Dry path buffer mix. */
  383. alignas(16) ALfloat (*DryBuffer)[BUFFERSIZE];
  384. /* Running count of the mixer invocations, in 31.1 fixed point. This
  385. * actually increments *twice* when mixing, first at the start and then at
  386. * the end, so the bottom bit indicates if the device is currently mixing
  387. * and the upper bits indicates how many mixes have been done.
  388. */
  389. RefCount MixCount;
  390. /* Default effect slot */
  391. struct ALeffectslot *DefaultSlot;
  392. // Contexts created on this device
  393. ATOMIC(ALCcontext*) ContextList;
  394. struct ALCbackend *Backend;
  395. void *ExtraData; // For the backend's use
  396. ALCdevice *volatile next;
  397. /* Memory space used by the default slot (Playback devices only) */
  398. alignas(16) ALCbyte _slot_mem[];
  399. };
  400. // Frequency was requested by the app or config file
  401. #define DEVICE_FREQUENCY_REQUEST (1<<1)
  402. // Channel configuration was requested by the config file
  403. #define DEVICE_CHANNELS_REQUEST (1<<2)
  404. // Sample type was requested by the config file
  405. #define DEVICE_SAMPLE_TYPE_REQUEST (1<<3)
  406. // Specifies if the DSP is paused at user request
  407. #define DEVICE_PAUSED (1<<30)
  408. // Specifies if the device is currently running
  409. #define DEVICE_RUNNING (1<<31)
  410. /* Nanosecond resolution for the device clock time. */
  411. #define DEVICE_CLOCK_RES U64(1000000000)
  412. /* Must be less than 15 characters (16 including terminating null) for
  413. * compatibility with pthread_setname_np limitations. */
  414. #define MIXER_THREAD_NAME "alsoft-mixer"
  415. #define RECORD_THREAD_NAME "alsoft-record"
  416. struct ALCcontext_struct
  417. {
  418. RefCount ref;
  419. struct ALlistener *Listener;
  420. UIntMap SourceMap;
  421. UIntMap EffectSlotMap;
  422. ATOMIC(ALenum) LastError;
  423. ATOMIC(ALenum) UpdateSources;
  424. volatile enum DistanceModel DistanceModel;
  425. volatile ALboolean SourceDistanceModel;
  426. volatile ALfloat DopplerFactor;
  427. volatile ALfloat DopplerVelocity;
  428. volatile ALfloat SpeedOfSound;
  429. volatile ALenum DeferUpdates;
  430. struct ALvoice *Voices;
  431. ALsizei VoiceCount;
  432. ALsizei MaxVoices;
  433. VECTOR(struct ALeffectslot*) ActiveAuxSlots;
  434. ALCdevice *Device;
  435. const ALCchar *ExtensionList;
  436. ALCcontext *volatile next;
  437. /* Memory space used by the listener */
  438. alignas(16) ALCbyte _listener_mem[];
  439. };
  440. ALCcontext *GetContextRef(void);
  441. void ALCcontext_IncRef(ALCcontext *context);
  442. void ALCcontext_DecRef(ALCcontext *context);
  443. void AppendAllDevicesList(const ALCchar *name);
  444. void AppendCaptureDeviceList(const ALCchar *name);
  445. void ALCdevice_Lock(ALCdevice *device);
  446. void ALCdevice_Unlock(ALCdevice *device);
  447. void ALCcontext_DeferUpdates(ALCcontext *context);
  448. void ALCcontext_ProcessUpdates(ALCcontext *context);
  449. inline void LockContext(ALCcontext *context)
  450. { ALCdevice_Lock(context->Device); }
  451. inline void UnlockContext(ALCcontext *context)
  452. { ALCdevice_Unlock(context->Device); }
  453. void *al_malloc(size_t alignment, size_t size);
  454. void *al_calloc(size_t alignment, size_t size);
  455. void al_free(void *ptr);
  456. typedef struct {
  457. #ifdef HAVE_FENV_H
  458. DERIVE_FROM_TYPE(fenv_t);
  459. #else
  460. int state;
  461. #endif
  462. #ifdef HAVE_SSE
  463. int sse_state;
  464. #endif
  465. } FPUCtl;
  466. void SetMixerFPUMode(FPUCtl *ctl);
  467. void RestoreFPUMode(const FPUCtl *ctl);
  468. typedef struct RingBuffer RingBuffer;
  469. RingBuffer *CreateRingBuffer(ALsizei frame_size, ALsizei length);
  470. void DestroyRingBuffer(RingBuffer *ring);
  471. ALsizei RingBufferSize(RingBuffer *ring);
  472. void WriteRingBuffer(RingBuffer *ring, const ALubyte *data, ALsizei len);
  473. void ReadRingBuffer(RingBuffer *ring, ALubyte *data, ALsizei len);
  474. typedef struct ll_ringbuffer ll_ringbuffer_t;
  475. typedef struct ll_ringbuffer_data {
  476. char *buf;
  477. size_t len;
  478. } ll_ringbuffer_data_t;
  479. ll_ringbuffer_t *ll_ringbuffer_create(size_t sz, size_t elem_sz);
  480. void ll_ringbuffer_free(ll_ringbuffer_t *rb);
  481. void ll_ringbuffer_get_read_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
  482. void ll_ringbuffer_get_write_vector(const ll_ringbuffer_t *rb, ll_ringbuffer_data_t *vec);
  483. size_t ll_ringbuffer_read(ll_ringbuffer_t *rb, char *dest, size_t cnt);
  484. size_t ll_ringbuffer_peek(ll_ringbuffer_t *rb, char *dest, size_t cnt);
  485. void ll_ringbuffer_read_advance(ll_ringbuffer_t *rb, size_t cnt);
  486. size_t ll_ringbuffer_read_space(const ll_ringbuffer_t *rb);
  487. int ll_ringbuffer_mlock(ll_ringbuffer_t *rb);
  488. void ll_ringbuffer_reset(ll_ringbuffer_t *rb);
  489. size_t ll_ringbuffer_write(ll_ringbuffer_t *rb, const char *src, size_t cnt);
  490. void ll_ringbuffer_write_advance(ll_ringbuffer_t *rb, size_t cnt);
  491. size_t ll_ringbuffer_write_space(const ll_ringbuffer_t *rb);
  492. void ReadALConfig(void);
  493. void FreeALConfig(void);
  494. int ConfigValueExists(const char *devName, const char *blockName, const char *keyName);
  495. const char *GetConfigValue(const char *devName, const char *blockName, const char *keyName, const char *def);
  496. int GetConfigValueBool(const char *devName, const char *blockName, const char *keyName, int def);
  497. int ConfigValueStr(const char *devName, const char *blockName, const char *keyName, const char **ret);
  498. int ConfigValueInt(const char *devName, const char *blockName, const char *keyName, int *ret);
  499. int ConfigValueUInt(const char *devName, const char *blockName, const char *keyName, unsigned int *ret);
  500. int ConfigValueFloat(const char *devName, const char *blockName, const char *keyName, float *ret);
  501. int ConfigValueBool(const char *devName, const char *blockName, const char *keyName, int *ret);
  502. void SetRTPriority(void);
  503. void SetDefaultChannelOrder(ALCdevice *device);
  504. void SetDefaultWFXChannelOrder(ALCdevice *device);
  505. const ALCchar *DevFmtTypeString(enum DevFmtType type) DECL_CONST;
  506. const ALCchar *DevFmtChannelsString(enum DevFmtChannels chans) DECL_CONST;
  507. /**
  508. * GetChannelIdxByName
  509. *
  510. * Returns the device's channel index given a channel name (e.g. FrontCenter),
  511. * or -1 if it doesn't exist.
  512. */
  513. inline ALint GetChannelIdxByName(const ALCdevice *device, enum Channel chan)
  514. {
  515. ALint i = 0;
  516. for(i = 0;i < MAX_OUTPUT_CHANNELS;i++)
  517. {
  518. if(device->ChannelName[i] == chan)
  519. return i;
  520. }
  521. return -1;
  522. }
  523. extern FILE *LogFile;
  524. #if defined(__GNUC__) && !defined(_WIN32) && !defined(IN_IDE_PARSER)
  525. #define AL_PRINT(T, MSG, ...) fprintf(LogFile, "AL lib: %s %s: "MSG, T, __FUNCTION__ , ## __VA_ARGS__)
  526. #else
  527. void al_print(const char *type, const char *func, const char *fmt, ...) DECL_FORMAT(printf, 3,4);
  528. #define AL_PRINT(T, ...) al_print((T), __FUNCTION__, __VA_ARGS__)
  529. #endif
  530. enum LogLevel {
  531. NoLog,
  532. LogError,
  533. LogWarning,
  534. LogTrace,
  535. LogRef
  536. };
  537. extern enum LogLevel LogLevel;
  538. #define TRACEREF(...) do { \
  539. if(LogLevel >= LogRef) \
  540. AL_PRINT("(--)", __VA_ARGS__); \
  541. } while(0)
  542. #define TRACE(...) do { \
  543. if(LogLevel >= LogTrace) \
  544. AL_PRINT("(II)", __VA_ARGS__); \
  545. } while(0)
  546. #define WARN(...) do { \
  547. if(LogLevel >= LogWarning) \
  548. AL_PRINT("(WW)", __VA_ARGS__); \
  549. } while(0)
  550. #define ERR(...) do { \
  551. if(LogLevel >= LogError) \
  552. AL_PRINT("(EE)", __VA_ARGS__); \
  553. } while(0)
  554. extern ALint RTPrioLevel;
  555. extern ALuint CPUCapFlags;
  556. enum {
  557. CPU_CAP_SSE = 1<<0,
  558. CPU_CAP_SSE2 = 1<<1,
  559. CPU_CAP_SSE3 = 1<<2,
  560. CPU_CAP_SSE4_1 = 1<<3,
  561. CPU_CAP_NEON = 1<<4,
  562. };
  563. void FillCPUCaps(ALuint capfilter);
  564. FILE *OpenDataFile(const char *fname, const char *subdir);
  565. vector_al_string SearchDataFiles(const char *match, const char *subdir);
  566. /* Small hack to use a pointer-to-array type as a normal argument type.
  567. * Shouldn't be used directly. */
  568. typedef ALfloat ALfloatBUFFERSIZE[BUFFERSIZE];
  569. #ifdef __cplusplus
  570. }
  571. #endif
  572. #endif