1 /*
2 Audio playback and capture library. Choice of public domain or MIT-0. See license statements at the end of this file.
3 miniaudio - v0.10.42 - 2021-08-22
4
5 David Reid - mackron@gmail.com
6
7 Website: https://miniaud.io
8 Documentation: https://miniaud.io/docs
9 GitHub: https://github.com/mackron/miniaudio
10 */
11 #ifndef miniaudio_h
12 #define miniaudio_h
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 #define MA_STRINGIFY(x) #x
19 #define MA_XSTRINGIFY(x) MA_STRINGIFY(x)
20
21 #define MA_VERSION_MAJOR 0
22 #define MA_VERSION_MINOR 10
23 #define MA_VERSION_REVISION 42
24 #define MA_VERSION_STRING MA_XSTRINGIFY(MA_VERSION_MAJOR) "." MA_XSTRINGIFY(MA_VERSION_MINOR) "." MA_XSTRINGIFY(MA_VERSION_REVISION)
25
26 #if defined(_MSC_VER) && !defined(__clang__)
27 #pragma warning(push)
28 #pragma warning(disable:4201) /* nonstandard extension used: nameless struct/union */
29 #pragma warning(disable:4214) /* nonstandard extension used: bit field types other than int */
30 #pragma warning(disable:4324) /* structure was padded due to alignment specifier */
31 #elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
32 #pragma GCC diagnostic push
33 #pragma GCC diagnostic ignored "-Wpedantic" /* For ISO C99 doesn't support unnamed structs/unions [-Wpedantic] */
34 #if defined(__clang__)
35 #pragma GCC diagnostic ignored "-Wc11-extensions" /* anonymous unions are a C11 extension */
36 #endif
37 #endif
38
39 /* Platform/backend detection. */
40 #ifdef _WIN32
41 #define MA_WIN32
42 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP || WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
43 #define MA_WIN32_UWP
44 #else
45 #define MA_WIN32_DESKTOP
46 #endif
47 #else
48 #define MA_POSIX
49 #include <pthread.h> /* Unfortunate #include, but needed for pthread_t, pthread_mutex_t and pthread_cond_t types. */
50
51 #ifdef __unix__
52 #define MA_UNIX
53 #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
54 #define MA_BSD
55 #endif
56 #endif
57 #ifdef __linux__
58 #define MA_LINUX
59 #endif
60 #ifdef __APPLE__
61 #define MA_APPLE
62 #endif
63 #ifdef __ANDROID__
64 #define MA_ANDROID
65 #endif
66 #ifdef __EMSCRIPTEN__
67 #define MA_EMSCRIPTEN
68 #endif
69 #endif
70
71 #include <stddef.h> /* For size_t. */
72
73 /* Sized types. */
74 typedef signed char ma_int8;
75 typedef unsigned char ma_uint8;
76 typedef signed short ma_int16;
77 typedef unsigned short ma_uint16;
78 typedef signed int ma_int32;
79 typedef unsigned int ma_uint32;
80 #if defined(_MSC_VER)
81 typedef signed __int64 ma_int64;
82 typedef unsigned __int64 ma_uint64;
83 #else
84 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
85 #pragma GCC diagnostic push
86 #pragma GCC diagnostic ignored "-Wlong-long"
87 #if defined(__clang__)
88 #pragma GCC diagnostic ignored "-Wc++11-long-long"
89 #endif
90 #endif
91 typedef signed long long ma_int64;
92 typedef unsigned long long ma_uint64;
93 #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
94 #pragma GCC diagnostic pop
95 #endif
96 #endif
97 #if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__powerpc64__)
98 typedef ma_uint64 ma_uintptr;
99 #else
100 typedef ma_uint32 ma_uintptr;
101 #endif
102
103 typedef ma_uint8 ma_bool8;
104 typedef ma_uint32 ma_bool32;
105 #define MA_TRUE 1
106 #define MA_FALSE 0
107
108 typedef void* ma_handle;
109 typedef void* ma_ptr;
110 typedef void (* ma_proc)(void);
111
112 #if defined(_MSC_VER) && !defined(_WCHAR_T_DEFINED)
113 typedef ma_uint16 wchar_t;
114 #endif
115
116 /* Define NULL for some compilers. */
117 #ifndef NULL
118 #define NULL 0
119 #endif
120
121 #if defined(SIZE_MAX)
122 #define MA_SIZE_MAX SIZE_MAX
123 #else
124 #define MA_SIZE_MAX 0xFFFFFFFF /* When SIZE_MAX is not defined by the standard library just default to the maximum 32-bit unsigned integer. */
125 #endif
126
127
128 #ifdef _MSC_VER
129 #define MA_INLINE __forceinline
130 #elif defined(__GNUC__)
131 /*
132 I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
133 the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
134 case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
135 command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
136 I am using "__inline__" only when we're compiling in strict ANSI mode.
137 */
138 #if defined(__STRICT_ANSI__)
139 #define MA_INLINE __inline__ __attribute__((always_inline))
140 #else
141 #define MA_INLINE inline __attribute__((always_inline))
142 #endif
143 #elif defined(__WATCOMC__)
144 #define MA_INLINE __inline
145 #else
146 #define MA_INLINE
147 #endif
148
149 #if !defined(MA_API)
150 #if defined(MA_DLL)
151 #if defined(_WIN32)
152 #define MA_DLL_IMPORT __declspec(dllimport)
153 #define MA_DLL_EXPORT __declspec(dllexport)
154 #define MA_DLL_PRIVATE static
155 #else
156 #if defined(__GNUC__) && __GNUC__ >= 4
157 #define MA_DLL_IMPORT __attribute__((visibility("default")))
158 #define MA_DLL_EXPORT __attribute__((visibility("default")))
159 #define MA_DLL_PRIVATE __attribute__((visibility("hidden")))
160 #else
161 #define MA_DLL_IMPORT
162 #define MA_DLL_EXPORT
163 #define MA_DLL_PRIVATE static
164 #endif
165 #endif
166
167 #if defined(MINIAUDIO_IMPLEMENTATION) || defined(MA_IMPLEMENTATION)
168 #define MA_API MA_DLL_EXPORT
169 #else
170 #define MA_API MA_DLL_IMPORT
171 #endif
172 #define MA_PRIVATE MA_DLL_PRIVATE
173 #else
174 #define MA_API extern
175 #define MA_PRIVATE static
176 #endif
177 #endif
178
179 /* SIMD alignment in bytes. Currently set to 64 bytes in preparation for future AVX-512 optimizations. */
180 #define MA_SIMD_ALIGNMENT 64
181
182
183 /*
184 Logging Levels
185 ==============
186 Log levels are only used to give logging callbacks some context as to the severity of a log message
187 so they can do filtering. All log levels will be posted to registered logging callbacks, except for
188 MA_LOG_LEVEL_DEBUG which will only get processed if MA_DEBUG_OUTPUT is enabled.
189
190 MA_LOG_LEVEL_DEBUG
191 Used for debugging. These log messages are only posted when `MA_DEBUG_OUTPUT` is enabled.
192
193 MA_LOG_LEVEL_INFO
194 Informational logging. Useful for debugging. This will also enable warning and error logs. This
195 will never be called from within the data callback.
196
197 MA_LOG_LEVEL_WARNING
198 Warnings. You should enable this in you development builds and action them when encounted. This
199 will also enable error logs. These logs usually indicate a potential problem or
200 misconfiguration, but still allow you to keep running. This will never be called from within
201 the data callback.
202
203 MA_LOG_LEVEL_ERROR
204 Error logging. This will be fired when an operation fails and is subsequently aborted. This can
205 be fired from within the data callback, in which case the device will be stopped. You should
206 always have this log level enabled.
207 */
208 #define MA_LOG_LEVEL_DEBUG 4
209 #define MA_LOG_LEVEL_INFO 3
210 #define MA_LOG_LEVEL_WARNING 2
211 #define MA_LOG_LEVEL_ERROR 1
212
213 /* Deprecated. */
214 #define MA_LOG_LEVEL_VERBOSE MA_LOG_LEVEL_DEBUG
215
216 /* Deprecated. */
217 #ifndef MA_LOG_LEVEL
218 #define MA_LOG_LEVEL MA_LOG_LEVEL_ERROR
219 #endif
220
221 /*
222 An annotation for variables which must be used atomically. This doesn't actually do anything - it's
223 just used as a way for humans to identify variables that should be used atomically.
224 */
225 #define MA_ATOMIC
226
227 typedef struct ma_context ma_context;
228 typedef struct ma_device ma_device;
229
230 typedef ma_uint8 ma_channel;
231 #define MA_CHANNEL_NONE 0
232 #define MA_CHANNEL_MONO 1
233 #define MA_CHANNEL_FRONT_LEFT 2
234 #define MA_CHANNEL_FRONT_RIGHT 3
235 #define MA_CHANNEL_FRONT_CENTER 4
236 #define MA_CHANNEL_LFE 5
237 #define MA_CHANNEL_BACK_LEFT 6
238 #define MA_CHANNEL_BACK_RIGHT 7
239 #define MA_CHANNEL_FRONT_LEFT_CENTER 8
240 #define MA_CHANNEL_FRONT_RIGHT_CENTER 9
241 #define MA_CHANNEL_BACK_CENTER 10
242 #define MA_CHANNEL_SIDE_LEFT 11
243 #define MA_CHANNEL_SIDE_RIGHT 12
244 #define MA_CHANNEL_TOP_CENTER 13
245 #define MA_CHANNEL_TOP_FRONT_LEFT 14
246 #define MA_CHANNEL_TOP_FRONT_CENTER 15
247 #define MA_CHANNEL_TOP_FRONT_RIGHT 16
248 #define MA_CHANNEL_TOP_BACK_LEFT 17
249 #define MA_CHANNEL_TOP_BACK_CENTER 18
250 #define MA_CHANNEL_TOP_BACK_RIGHT 19
251 #define MA_CHANNEL_AUX_0 20
252 #define MA_CHANNEL_AUX_1 21
253 #define MA_CHANNEL_AUX_2 22
254 #define MA_CHANNEL_AUX_3 23
255 #define MA_CHANNEL_AUX_4 24
256 #define MA_CHANNEL_AUX_5 25
257 #define MA_CHANNEL_AUX_6 26
258 #define MA_CHANNEL_AUX_7 27
259 #define MA_CHANNEL_AUX_8 28
260 #define MA_CHANNEL_AUX_9 29
261 #define MA_CHANNEL_AUX_10 30
262 #define MA_CHANNEL_AUX_11 31
263 #define MA_CHANNEL_AUX_12 32
264 #define MA_CHANNEL_AUX_13 33
265 #define MA_CHANNEL_AUX_14 34
266 #define MA_CHANNEL_AUX_15 35
267 #define MA_CHANNEL_AUX_16 36
268 #define MA_CHANNEL_AUX_17 37
269 #define MA_CHANNEL_AUX_18 38
270 #define MA_CHANNEL_AUX_19 39
271 #define MA_CHANNEL_AUX_20 40
272 #define MA_CHANNEL_AUX_21 41
273 #define MA_CHANNEL_AUX_22 42
274 #define MA_CHANNEL_AUX_23 43
275 #define MA_CHANNEL_AUX_24 44
276 #define MA_CHANNEL_AUX_25 45
277 #define MA_CHANNEL_AUX_26 46
278 #define MA_CHANNEL_AUX_27 47
279 #define MA_CHANNEL_AUX_28 48
280 #define MA_CHANNEL_AUX_29 49
281 #define MA_CHANNEL_AUX_30 50
282 #define MA_CHANNEL_AUX_31 51
283 #define MA_CHANNEL_LEFT MA_CHANNEL_FRONT_LEFT
284 #define MA_CHANNEL_RIGHT MA_CHANNEL_FRONT_RIGHT
285 #define MA_CHANNEL_POSITION_COUNT (MA_CHANNEL_AUX_31 + 1)
286
287
288 typedef int ma_result;
289 #define MA_SUCCESS 0
290 #define MA_ERROR -1 /* A generic error. */
291 #define MA_INVALID_ARGS -2
292 #define MA_INVALID_OPERATION -3
293 #define MA_OUT_OF_MEMORY -4
294 #define MA_OUT_OF_RANGE -5
295 #define MA_ACCESS_DENIED -6
296 #define MA_DOES_NOT_EXIST -7
297 #define MA_ALREADY_EXISTS -8
298 #define MA_TOO_MANY_OPEN_FILES -9
299 #define MA_INVALID_FILE -10
300 #define MA_TOO_BIG -11
301 #define MA_PATH_TOO_LONG -12
302 #define MA_NAME_TOO_LONG -13
303 #define MA_NOT_DIRECTORY -14
304 #define MA_IS_DIRECTORY -15
305 #define MA_DIRECTORY_NOT_EMPTY -16
306 #define MA_AT_END -17
307 #define MA_NO_SPACE -18
308 #define MA_BUSY -19
309 #define MA_IO_ERROR -20
310 #define MA_INTERRUPT -21
311 #define MA_UNAVAILABLE -22
312 #define MA_ALREADY_IN_USE -23
313 #define MA_BAD_ADDRESS -24
314 #define MA_BAD_SEEK -25
315 #define MA_BAD_PIPE -26
316 #define MA_DEADLOCK -27
317 #define MA_TOO_MANY_LINKS -28
318 #define MA_NOT_IMPLEMENTED -29
319 #define MA_NO_MESSAGE -30
320 #define MA_BAD_MESSAGE -31
321 #define MA_NO_DATA_AVAILABLE -32
322 #define MA_INVALID_DATA -33
323 #define MA_TIMEOUT -34
324 #define MA_NO_NETWORK -35
325 #define MA_NOT_UNIQUE -36
326 #define MA_NOT_SOCKET -37
327 #define MA_NO_ADDRESS -38
328 #define MA_BAD_PROTOCOL -39
329 #define MA_PROTOCOL_UNAVAILABLE -40
330 #define MA_PROTOCOL_NOT_SUPPORTED -41
331 #define MA_PROTOCOL_FAMILY_NOT_SUPPORTED -42
332 #define MA_ADDRESS_FAMILY_NOT_SUPPORTED -43
333 #define MA_SOCKET_NOT_SUPPORTED -44
334 #define MA_CONNECTION_RESET -45
335 #define MA_ALREADY_CONNECTED -46
336 #define MA_NOT_CONNECTED -47
337 #define MA_CONNECTION_REFUSED -48
338 #define MA_NO_HOST -49
339 #define MA_IN_PROGRESS -50
340 #define MA_CANCELLED -51
341 #define MA_MEMORY_ALREADY_MAPPED -52
342
343 /* General miniaudio-specific errors. */
344 #define MA_FORMAT_NOT_SUPPORTED -100
345 #define MA_DEVICE_TYPE_NOT_SUPPORTED -101
346 #define MA_SHARE_MODE_NOT_SUPPORTED -102
347 #define MA_NO_BACKEND -103
348 #define MA_NO_DEVICE -104
349 #define MA_API_NOT_FOUND -105
350 #define MA_INVALID_DEVICE_CONFIG -106
351 #define MA_LOOP -107
352
353 /* State errors. */
354 #define MA_DEVICE_NOT_INITIALIZED -200
355 #define MA_DEVICE_ALREADY_INITIALIZED -201
356 #define MA_DEVICE_NOT_STARTED -202
357 #define MA_DEVICE_NOT_STOPPED -203
358
359 /* Operation errors. */
360 #define MA_FAILED_TO_INIT_BACKEND -300
361 #define MA_FAILED_TO_OPEN_BACKEND_DEVICE -301
362 #define MA_FAILED_TO_START_BACKEND_DEVICE -302
363 #define MA_FAILED_TO_STOP_BACKEND_DEVICE -303
364
365
366 #define MA_MIN_CHANNELS 1
367 #ifndef MA_MAX_CHANNELS
368 #define MA_MAX_CHANNELS 32
369 #endif
370
371
372 #ifndef MA_MAX_FILTER_ORDER
373 #define MA_MAX_FILTER_ORDER 8
374 #endif
375
376 typedef enum
377 {
378 ma_stream_format_pcm = 0
379 } ma_stream_format;
380
381 typedef enum
382 {
383 ma_stream_layout_interleaved = 0,
384 ma_stream_layout_deinterleaved
385 } ma_stream_layout;
386
387 typedef enum
388 {
389 ma_dither_mode_none = 0,
390 ma_dither_mode_rectangle,
391 ma_dither_mode_triangle
392 } ma_dither_mode;
393
394 typedef enum
395 {
396 /*
397 I like to keep these explicitly defined because they're used as a key into a lookup table. When items are
398 added to this, make sure there are no gaps and that they're added to the lookup table in ma_get_bytes_per_sample().
399 */
400 ma_format_unknown = 0, /* Mainly used for indicating an error, but also used as the default for the output format for decoders. */
401 ma_format_u8 = 1,
402 ma_format_s16 = 2, /* Seems to be the most widely supported format. */
403 ma_format_s24 = 3, /* Tightly packed. 3 bytes per sample. */
404 ma_format_s32 = 4,
405 ma_format_f32 = 5,
406 ma_format_count
407 } ma_format;
408
409 typedef enum
410 {
411 /* Standard rates need to be in priority order. */
412 ma_standard_sample_rate_48000 = 48000, /* Most common */
413 ma_standard_sample_rate_44100 = 44100,
414
415 ma_standard_sample_rate_32000 = 32000, /* Lows */
416 ma_standard_sample_rate_24000 = 24000,
417 ma_standard_sample_rate_22050 = 22050,
418
419 ma_standard_sample_rate_88200 = 88200, /* Highs */
420 ma_standard_sample_rate_96000 = 96000,
421 ma_standard_sample_rate_176400 = 176400,
422 ma_standard_sample_rate_192000 = 192000,
423
424 ma_standard_sample_rate_16000 = 16000, /* Extreme lows */
425 ma_standard_sample_rate_11025 = 11250,
426 ma_standard_sample_rate_8000 = 8000,
427
428 ma_standard_sample_rate_352800 = 352800, /* Extreme highs */
429 ma_standard_sample_rate_384000 = 384000,
430
431 ma_standard_sample_rate_min = ma_standard_sample_rate_8000,
432 ma_standard_sample_rate_max = ma_standard_sample_rate_384000,
433 ma_standard_sample_rate_count = 14 /* Need to maintain the count manually. Make sure this is updated if items are added to enum. */
434 } ma_standard_sample_rate;
435
436 /* These are deprecated. Use ma_standard_sample_rate_min and ma_standard_sample_rate_max. */
437 #define MA_MIN_SAMPLE_RATE (ma_uint32)ma_standard_sample_rate_min
438 #define MA_MAX_SAMPLE_RATE (ma_uint32)ma_standard_sample_rate_max
439
440
441 typedef enum
442 {
443 ma_channel_mix_mode_rectangular = 0, /* Simple averaging based on the plane(s) the channel is sitting on. */
444 ma_channel_mix_mode_simple, /* Drop excess channels; zeroed out extra channels. */
445 ma_channel_mix_mode_custom_weights, /* Use custom weights specified in ma_channel_router_config. */
446 ma_channel_mix_mode_planar_blend = ma_channel_mix_mode_rectangular,
447 ma_channel_mix_mode_default = ma_channel_mix_mode_rectangular
448 } ma_channel_mix_mode;
449
450 typedef enum
451 {
452 ma_standard_channel_map_microsoft,
453 ma_standard_channel_map_alsa,
454 ma_standard_channel_map_rfc3551, /* Based off AIFF. */
455 ma_standard_channel_map_flac,
456 ma_standard_channel_map_vorbis,
457 ma_standard_channel_map_sound4, /* FreeBSD's sound(4). */
458 ma_standard_channel_map_sndio, /* www.sndio.org/tips.html */
459 ma_standard_channel_map_webaudio = ma_standard_channel_map_flac, /* https://webaudio.github.io/web-audio-api/#ChannelOrdering. Only 1, 2, 4 and 6 channels are defined, but can fill in the gaps with logical assumptions. */
460 ma_standard_channel_map_default = ma_standard_channel_map_microsoft
461 } ma_standard_channel_map;
462
463 typedef enum
464 {
465 ma_performance_profile_low_latency = 0,
466 ma_performance_profile_conservative
467 } ma_performance_profile;
468
469
470 typedef struct
471 {
472 void* pUserData;
473 void* (* onMalloc)(size_t sz, void* pUserData);
474 void* (* onRealloc)(void* p, size_t sz, void* pUserData);
475 void (* onFree)(void* p, void* pUserData);
476 } ma_allocation_callbacks;
477
478 typedef struct
479 {
480 ma_int32 state;
481 } ma_lcg;
482
483
484 #ifndef MA_NO_THREADING
485 /* Thread priorities should be ordered such that the default priority of the worker thread is 0. */
486 typedef enum
487 {
488 ma_thread_priority_idle = -5,
489 ma_thread_priority_lowest = -4,
490 ma_thread_priority_low = -3,
491 ma_thread_priority_normal = -2,
492 ma_thread_priority_high = -1,
493 ma_thread_priority_highest = 0,
494 ma_thread_priority_realtime = 1,
495 ma_thread_priority_default = 0
496 } ma_thread_priority;
497
498 /* Spinlocks are 32-bit for compatibility reasons. */
499 typedef ma_uint32 ma_spinlock;
500
501 #if defined(MA_WIN32)
502 typedef ma_handle ma_thread;
503 #endif
504 #if defined(MA_POSIX)
505 typedef pthread_t ma_thread;
506 #endif
507
508 #if defined(MA_WIN32)
509 typedef ma_handle ma_mutex;
510 #endif
511 #if defined(MA_POSIX)
512 typedef pthread_mutex_t ma_mutex;
513 #endif
514
515 #if defined(MA_WIN32)
516 typedef ma_handle ma_event;
517 #endif
518 #if defined(MA_POSIX)
519 typedef struct
520 {
521 ma_uint32 value;
522 pthread_mutex_t lock;
523 pthread_cond_t cond;
524 } ma_event;
525 #endif /* MA_POSIX */
526
527 #if defined(MA_WIN32)
528 typedef ma_handle ma_semaphore;
529 #endif
530 #if defined(MA_POSIX)
531 typedef struct
532 {
533 int value;
534 pthread_mutex_t lock;
535 pthread_cond_t cond;
536 } ma_semaphore;
537 #endif /* MA_POSIX */
538 #else
539 /* MA_NO_THREADING is set which means threading is disabled. Threading is required by some API families. If any of these are enabled we need to throw an error. */
540 #ifndef MA_NO_DEVICE_IO
541 #error "MA_NO_THREADING cannot be used without MA_NO_DEVICE_IO";
542 #endif
543 #endif /* MA_NO_THREADING */
544
545
546 /*
547 Retrieves the version of miniaudio as separated integers. Each component can be NULL if it's not required.
548 */
549 MA_API void ma_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* pRevision);
550
551 /*
552 Retrieves the version of miniaudio as a string which can be useful for logging purposes.
553 */
554 MA_API const char* ma_version_string(void);
555
556
557 /**************************************************************************************************************************************************************
558
559 Logging
560
561 **************************************************************************************************************************************************************/
562 #include <stdarg.h> /* For va_list. */
563
564 #if defined(__has_attribute)
565 #if __has_attribute(format)
566 #define MA_ATTRIBUTE_FORMAT(fmt, va) __attribute__((format(printf, fmt, va)))
567 #endif
568 #endif
569 #ifndef MA_ATTRIBUTE_FORMAT
570 #define MA_ATTRIBUTE_FORMAT(fmt,va)
571 #endif
572
573 #ifndef MA_MAX_LOG_CALLBACKS
574 #define MA_MAX_LOG_CALLBACKS 4
575 #endif
576
577 typedef void (* ma_log_callback_proc)(void* pUserData, ma_uint32 level, const char* pMessage);
578
579 typedef struct
580 {
581 ma_log_callback_proc onLog;
582 void* pUserData;
583 } ma_log_callback;
584
585 MA_API ma_log_callback ma_log_callback_init(ma_log_callback_proc onLog, void* pUserData);
586
587
588 typedef struct
589 {
590 ma_log_callback callbacks[MA_MAX_LOG_CALLBACKS];
591 ma_uint32 callbackCount;
592 ma_allocation_callbacks allocationCallbacks; /* Need to store these persistently because ma_log_postv() might need to allocate a buffer on the heap. */
593 #ifndef MA_NO_THREADING
594 ma_mutex lock; /* For thread safety just to make it easier and safer for the logging implementation. */
595 #endif
596 } ma_log;
597
598 MA_API ma_result ma_log_init(const ma_allocation_callbacks* pAllocationCallbacks, ma_log* pLog);
599 MA_API void ma_log_uninit(ma_log* pLog);
600 MA_API ma_result ma_log_register_callback(ma_log* pLog, ma_log_callback callback);
601 MA_API ma_result ma_log_unregister_callback(ma_log* pLog, ma_log_callback callback);
602 MA_API ma_result ma_log_post(ma_log* pLog, ma_uint32 level, const char* pMessage);
603 MA_API ma_result ma_log_postv(ma_log* pLog, ma_uint32 level, const char* pFormat, va_list args);
604 MA_API ma_result ma_log_postf(ma_log* pLog, ma_uint32 level, const char* pFormat, ...) MA_ATTRIBUTE_FORMAT(3, 4);
605
606
607 /**************************************************************************************************************************************************************
608
609 Biquad Filtering
610
611 **************************************************************************************************************************************************************/
612 typedef union
613 {
614 float f32;
615 ma_int32 s32;
616 } ma_biquad_coefficient;
617
618 typedef struct
619 {
620 ma_format format;
621 ma_uint32 channels;
622 double b0;
623 double b1;
624 double b2;
625 double a0;
626 double a1;
627 double a2;
628 } ma_biquad_config;
629
630 MA_API ma_biquad_config ma_biquad_config_init(ma_format format, ma_uint32 channels, double b0, double b1, double b2, double a0, double a1, double a2);
631
632 typedef struct
633 {
634 ma_format format;
635 ma_uint32 channels;
636 ma_biquad_coefficient b0;
637 ma_biquad_coefficient b1;
638 ma_biquad_coefficient b2;
639 ma_biquad_coefficient a1;
640 ma_biquad_coefficient a2;
641 ma_biquad_coefficient r1[MA_MAX_CHANNELS];
642 ma_biquad_coefficient r2[MA_MAX_CHANNELS];
643 } ma_biquad;
644
645 MA_API ma_result ma_biquad_init(const ma_biquad_config* pConfig, ma_biquad* pBQ);
646 MA_API ma_result ma_biquad_reinit(const ma_biquad_config* pConfig, ma_biquad* pBQ);
647 MA_API ma_result ma_biquad_process_pcm_frames(ma_biquad* pBQ, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
648 MA_API ma_uint32 ma_biquad_get_latency(const ma_biquad* pBQ);
649
650
651 /**************************************************************************************************************************************************************
652
653 Low-Pass Filtering
654
655 **************************************************************************************************************************************************************/
656 typedef struct
657 {
658 ma_format format;
659 ma_uint32 channels;
660 ma_uint32 sampleRate;
661 double cutoffFrequency;
662 double q;
663 } ma_lpf1_config, ma_lpf2_config;
664
665 MA_API ma_lpf1_config ma_lpf1_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
666 MA_API ma_lpf2_config ma_lpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
667
668 typedef struct
669 {
670 ma_format format;
671 ma_uint32 channels;
672 ma_biquad_coefficient a;
673 ma_biquad_coefficient r1[MA_MAX_CHANNELS];
674 } ma_lpf1;
675
676 MA_API ma_result ma_lpf1_init(const ma_lpf1_config* pConfig, ma_lpf1* pLPF);
677 MA_API ma_result ma_lpf1_reinit(const ma_lpf1_config* pConfig, ma_lpf1* pLPF);
678 MA_API ma_result ma_lpf1_process_pcm_frames(ma_lpf1* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
679 MA_API ma_uint32 ma_lpf1_get_latency(const ma_lpf1* pLPF);
680
681 typedef struct
682 {
683 ma_biquad bq; /* The second order low-pass filter is implemented as a biquad filter. */
684 } ma_lpf2;
685
686 MA_API ma_result ma_lpf2_init(const ma_lpf2_config* pConfig, ma_lpf2* pLPF);
687 MA_API ma_result ma_lpf2_reinit(const ma_lpf2_config* pConfig, ma_lpf2* pLPF);
688 MA_API ma_result ma_lpf2_process_pcm_frames(ma_lpf2* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
689 MA_API ma_uint32 ma_lpf2_get_latency(const ma_lpf2* pLPF);
690
691
692 typedef struct
693 {
694 ma_format format;
695 ma_uint32 channels;
696 ma_uint32 sampleRate;
697 double cutoffFrequency;
698 ma_uint32 order; /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
699 } ma_lpf_config;
700
701 MA_API ma_lpf_config ma_lpf_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
702
703 typedef struct
704 {
705 ma_format format;
706 ma_uint32 channels;
707 ma_uint32 sampleRate;
708 ma_uint32 lpf1Count;
709 ma_uint32 lpf2Count;
710 ma_lpf1 lpf1[1];
711 ma_lpf2 lpf2[MA_MAX_FILTER_ORDER/2];
712 } ma_lpf;
713
714 MA_API ma_result ma_lpf_init(const ma_lpf_config* pConfig, ma_lpf* pLPF);
715 MA_API ma_result ma_lpf_reinit(const ma_lpf_config* pConfig, ma_lpf* pLPF);
716 MA_API ma_result ma_lpf_process_pcm_frames(ma_lpf* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
717 MA_API ma_uint32 ma_lpf_get_latency(const ma_lpf* pLPF);
718
719
720 /**************************************************************************************************************************************************************
721
722 High-Pass Filtering
723
724 **************************************************************************************************************************************************************/
725 typedef struct
726 {
727 ma_format format;
728 ma_uint32 channels;
729 ma_uint32 sampleRate;
730 double cutoffFrequency;
731 double q;
732 } ma_hpf1_config, ma_hpf2_config;
733
734 MA_API ma_hpf1_config ma_hpf1_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
735 MA_API ma_hpf2_config ma_hpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
736
737 typedef struct
738 {
739 ma_format format;
740 ma_uint32 channels;
741 ma_biquad_coefficient a;
742 ma_biquad_coefficient r1[MA_MAX_CHANNELS];
743 } ma_hpf1;
744
745 MA_API ma_result ma_hpf1_init(const ma_hpf1_config* pConfig, ma_hpf1* pHPF);
746 MA_API ma_result ma_hpf1_reinit(const ma_hpf1_config* pConfig, ma_hpf1* pHPF);
747 MA_API ma_result ma_hpf1_process_pcm_frames(ma_hpf1* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
748 MA_API ma_uint32 ma_hpf1_get_latency(const ma_hpf1* pHPF);
749
750 typedef struct
751 {
752 ma_biquad bq; /* The second order high-pass filter is implemented as a biquad filter. */
753 } ma_hpf2;
754
755 MA_API ma_result ma_hpf2_init(const ma_hpf2_config* pConfig, ma_hpf2* pHPF);
756 MA_API ma_result ma_hpf2_reinit(const ma_hpf2_config* pConfig, ma_hpf2* pHPF);
757 MA_API ma_result ma_hpf2_process_pcm_frames(ma_hpf2* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
758 MA_API ma_uint32 ma_hpf2_get_latency(const ma_hpf2* pHPF);
759
760
761 typedef struct
762 {
763 ma_format format;
764 ma_uint32 channels;
765 ma_uint32 sampleRate;
766 double cutoffFrequency;
767 ma_uint32 order; /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
768 } ma_hpf_config;
769
770 MA_API ma_hpf_config ma_hpf_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
771
772 typedef struct
773 {
774 ma_format format;
775 ma_uint32 channels;
776 ma_uint32 sampleRate;
777 ma_uint32 hpf1Count;
778 ma_uint32 hpf2Count;
779 ma_hpf1 hpf1[1];
780 ma_hpf2 hpf2[MA_MAX_FILTER_ORDER/2];
781 } ma_hpf;
782
783 MA_API ma_result ma_hpf_init(const ma_hpf_config* pConfig, ma_hpf* pHPF);
784 MA_API ma_result ma_hpf_reinit(const ma_hpf_config* pConfig, ma_hpf* pHPF);
785 MA_API ma_result ma_hpf_process_pcm_frames(ma_hpf* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
786 MA_API ma_uint32 ma_hpf_get_latency(const ma_hpf* pHPF);
787
788
789 /**************************************************************************************************************************************************************
790
791 Band-Pass Filtering
792
793 **************************************************************************************************************************************************************/
794 typedef struct
795 {
796 ma_format format;
797 ma_uint32 channels;
798 ma_uint32 sampleRate;
799 double cutoffFrequency;
800 double q;
801 } ma_bpf2_config;
802
803 MA_API ma_bpf2_config ma_bpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
804
805 typedef struct
806 {
807 ma_biquad bq; /* The second order band-pass filter is implemented as a biquad filter. */
808 } ma_bpf2;
809
810 MA_API ma_result ma_bpf2_init(const ma_bpf2_config* pConfig, ma_bpf2* pBPF);
811 MA_API ma_result ma_bpf2_reinit(const ma_bpf2_config* pConfig, ma_bpf2* pBPF);
812 MA_API ma_result ma_bpf2_process_pcm_frames(ma_bpf2* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
813 MA_API ma_uint32 ma_bpf2_get_latency(const ma_bpf2* pBPF);
814
815
816 typedef struct
817 {
818 ma_format format;
819 ma_uint32 channels;
820 ma_uint32 sampleRate;
821 double cutoffFrequency;
822 ma_uint32 order; /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
823 } ma_bpf_config;
824
825 MA_API ma_bpf_config ma_bpf_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
826
827 typedef struct
828 {
829 ma_format format;
830 ma_uint32 channels;
831 ma_uint32 bpf2Count;
832 ma_bpf2 bpf2[MA_MAX_FILTER_ORDER/2];
833 } ma_bpf;
834
835 MA_API ma_result ma_bpf_init(const ma_bpf_config* pConfig, ma_bpf* pBPF);
836 MA_API ma_result ma_bpf_reinit(const ma_bpf_config* pConfig, ma_bpf* pBPF);
837 MA_API ma_result ma_bpf_process_pcm_frames(ma_bpf* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
838 MA_API ma_uint32 ma_bpf_get_latency(const ma_bpf* pBPF);
839
840
841 /**************************************************************************************************************************************************************
842
843 Notching Filter
844
845 **************************************************************************************************************************************************************/
846 typedef struct
847 {
848 ma_format format;
849 ma_uint32 channels;
850 ma_uint32 sampleRate;
851 double q;
852 double frequency;
853 } ma_notch2_config, ma_notch_config;
854
855 MA_API ma_notch2_config ma_notch2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double q, double frequency);
856
857 typedef struct
858 {
859 ma_biquad bq;
860 } ma_notch2;
861
862 MA_API ma_result ma_notch2_init(const ma_notch2_config* pConfig, ma_notch2* pFilter);
863 MA_API ma_result ma_notch2_reinit(const ma_notch2_config* pConfig, ma_notch2* pFilter);
864 MA_API ma_result ma_notch2_process_pcm_frames(ma_notch2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
865 MA_API ma_uint32 ma_notch2_get_latency(const ma_notch2* pFilter);
866
867
868 /**************************************************************************************************************************************************************
869
870 Peaking EQ Filter
871
872 **************************************************************************************************************************************************************/
873 typedef struct
874 {
875 ma_format format;
876 ma_uint32 channels;
877 ma_uint32 sampleRate;
878 double gainDB;
879 double q;
880 double frequency;
881 } ma_peak2_config, ma_peak_config;
882
883 MA_API ma_peak2_config ma_peak2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency);
884
885 typedef struct
886 {
887 ma_biquad bq;
888 } ma_peak2;
889
890 MA_API ma_result ma_peak2_init(const ma_peak2_config* pConfig, ma_peak2* pFilter);
891 MA_API ma_result ma_peak2_reinit(const ma_peak2_config* pConfig, ma_peak2* pFilter);
892 MA_API ma_result ma_peak2_process_pcm_frames(ma_peak2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
893 MA_API ma_uint32 ma_peak2_get_latency(const ma_peak2* pFilter);
894
895
896 /**************************************************************************************************************************************************************
897
898 Low Shelf Filter
899
900 **************************************************************************************************************************************************************/
901 typedef struct
902 {
903 ma_format format;
904 ma_uint32 channels;
905 ma_uint32 sampleRate;
906 double gainDB;
907 double shelfSlope;
908 double frequency;
909 } ma_loshelf2_config, ma_loshelf_config;
910
911 MA_API ma_loshelf2_config ma_loshelf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double shelfSlope, double frequency);
912
913 typedef struct
914 {
915 ma_biquad bq;
916 } ma_loshelf2;
917
918 MA_API ma_result ma_loshelf2_init(const ma_loshelf2_config* pConfig, ma_loshelf2* pFilter);
919 MA_API ma_result ma_loshelf2_reinit(const ma_loshelf2_config* pConfig, ma_loshelf2* pFilter);
920 MA_API ma_result ma_loshelf2_process_pcm_frames(ma_loshelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
921 MA_API ma_uint32 ma_loshelf2_get_latency(const ma_loshelf2* pFilter);
922
923
924 /**************************************************************************************************************************************************************
925
926 High Shelf Filter
927
928 **************************************************************************************************************************************************************/
929 typedef struct
930 {
931 ma_format format;
932 ma_uint32 channels;
933 ma_uint32 sampleRate;
934 double gainDB;
935 double shelfSlope;
936 double frequency;
937 } ma_hishelf2_config, ma_hishelf_config;
938
939 MA_API ma_hishelf2_config ma_hishelf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double shelfSlope, double frequency);
940
941 typedef struct
942 {
943 ma_biquad bq;
944 } ma_hishelf2;
945
946 MA_API ma_result ma_hishelf2_init(const ma_hishelf2_config* pConfig, ma_hishelf2* pFilter);
947 MA_API ma_result ma_hishelf2_reinit(const ma_hishelf2_config* pConfig, ma_hishelf2* pFilter);
948 MA_API ma_result ma_hishelf2_process_pcm_frames(ma_hishelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
949 MA_API ma_uint32 ma_hishelf2_get_latency(const ma_hishelf2* pFilter);
950
951
952
953 /************************************************************************************************************************************************************
954 *************************************************************************************************************************************************************
955
956 DATA CONVERSION
957 ===============
958
959 This section contains the APIs for data conversion. You will find everything here for channel mapping, sample format conversion, resampling, etc.
960
961 *************************************************************************************************************************************************************
962 ************************************************************************************************************************************************************/
963
964 /**************************************************************************************************************************************************************
965
966 Resampling
967
968 **************************************************************************************************************************************************************/
969 typedef struct
970 {
971 ma_format format;
972 ma_uint32 channels;
973 ma_uint32 sampleRateIn;
974 ma_uint32 sampleRateOut;
975 ma_uint32 lpfOrder; /* The low-pass filter order. Setting this to 0 will disable low-pass filtering. */
976 double lpfNyquistFactor; /* 0..1. Defaults to 1. 1 = Half the sampling frequency (Nyquist Frequency), 0.5 = Quarter the sampling frequency (half Nyquest Frequency), etc. */
977 } ma_linear_resampler_config;
978
979 MA_API ma_linear_resampler_config ma_linear_resampler_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
980
981 typedef struct
982 {
983 ma_linear_resampler_config config;
984 ma_uint32 inAdvanceInt;
985 ma_uint32 inAdvanceFrac;
986 ma_uint32 inTimeInt;
987 ma_uint32 inTimeFrac;
988 union
989 {
990 float f32[MA_MAX_CHANNELS];
991 ma_int16 s16[MA_MAX_CHANNELS];
992 } x0; /* The previous input frame. */
993 union
994 {
995 float f32[MA_MAX_CHANNELS];
996 ma_int16 s16[MA_MAX_CHANNELS];
997 } x1; /* The next input frame. */
998 ma_lpf lpf;
999 } ma_linear_resampler;
1000
1001 MA_API ma_result ma_linear_resampler_init(const ma_linear_resampler_config* pConfig, ma_linear_resampler* pResampler);
1002 MA_API void ma_linear_resampler_uninit(ma_linear_resampler* pResampler);
1003 MA_API ma_result ma_linear_resampler_process_pcm_frames(ma_linear_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
1004 MA_API ma_result ma_linear_resampler_set_rate(ma_linear_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
1005 MA_API ma_result ma_linear_resampler_set_rate_ratio(ma_linear_resampler* pResampler, float ratioInOut);
1006 MA_API ma_uint64 ma_linear_resampler_get_required_input_frame_count(const ma_linear_resampler* pResampler, ma_uint64 outputFrameCount);
1007 MA_API ma_uint64 ma_linear_resampler_get_expected_output_frame_count(const ma_linear_resampler* pResampler, ma_uint64 inputFrameCount);
1008 MA_API ma_uint64 ma_linear_resampler_get_input_latency(const ma_linear_resampler* pResampler);
1009 MA_API ma_uint64 ma_linear_resampler_get_output_latency(const ma_linear_resampler* pResampler);
1010
1011 typedef enum
1012 {
1013 ma_resample_algorithm_linear = 0, /* Fastest, lowest quality. Optional low-pass filtering. Default. */
1014 ma_resample_algorithm_speex
1015 } ma_resample_algorithm;
1016
1017 typedef struct
1018 {
1019 ma_format format; /* Must be either ma_format_f32 or ma_format_s16. */
1020 ma_uint32 channels;
1021 ma_uint32 sampleRateIn;
1022 ma_uint32 sampleRateOut;
1023 ma_resample_algorithm algorithm;
1024 struct
1025 {
1026 ma_uint32 lpfOrder;
1027 double lpfNyquistFactor;
1028 } linear;
1029 struct
1030 {
1031 int quality; /* 0 to 10. Defaults to 3. */
1032 } speex;
1033 } ma_resampler_config;
1034
1035 MA_API ma_resampler_config ma_resampler_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut, ma_resample_algorithm algorithm);
1036
1037 typedef struct
1038 {
1039 ma_resampler_config config;
1040 union
1041 {
1042 ma_linear_resampler linear;
1043 struct
1044 {
1045 void* pSpeexResamplerState; /* SpeexResamplerState* */
1046 } speex;
1047 } state;
1048 } ma_resampler;
1049
1050 /*
1051 Initializes a new resampler object from a config.
1052 */
1053 MA_API ma_result ma_resampler_init(const ma_resampler_config* pConfig, ma_resampler* pResampler);
1054
1055 /*
1056 Uninitializes a resampler.
1057 */
1058 MA_API void ma_resampler_uninit(ma_resampler* pResampler);
1059
1060 /*
1061 Converts the given input data.
1062
1063 Both the input and output frames must be in the format specified in the config when the resampler was initilized.
1064
1065 On input, [pFrameCountOut] contains the number of output frames to process. On output it contains the number of output frames that
1066 were actually processed, which may be less than the requested amount which will happen if there's not enough input data. You can use
1067 ma_resampler_get_expected_output_frame_count() to know how many output frames will be processed for a given number of input frames.
1068
1069 On input, [pFrameCountIn] contains the number of input frames contained in [pFramesIn]. On output it contains the number of whole
1070 input frames that were actually processed. You can use ma_resampler_get_required_input_frame_count() to know how many input frames
1071 you should provide for a given number of output frames. [pFramesIn] can be NULL, in which case zeroes will be used instead.
1072
1073 If [pFramesOut] is NULL, a seek is performed. In this case, if [pFrameCountOut] is not NULL it will seek by the specified number of
1074 output frames. Otherwise, if [pFramesCountOut] is NULL and [pFrameCountIn] is not NULL, it will seek by the specified number of input
1075 frames. When seeking, [pFramesIn] is allowed to NULL, in which case the internal timing state will be updated, but no input will be
1076 processed. In this case, any internal filter state will be updated as if zeroes were passed in.
1077
1078 It is an error for [pFramesOut] to be non-NULL and [pFrameCountOut] to be NULL.
1079
1080 It is an error for both [pFrameCountOut] and [pFrameCountIn] to be NULL.
1081 */
1082 MA_API ma_result ma_resampler_process_pcm_frames(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
1083
1084
1085 /*
1086 Sets the input and output sample sample rate.
1087 */
1088 MA_API ma_result ma_resampler_set_rate(ma_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
1089
1090 /*
1091 Sets the input and output sample rate as a ratio.
1092
1093 The ration is in/out.
1094 */
1095 MA_API ma_result ma_resampler_set_rate_ratio(ma_resampler* pResampler, float ratio);
1096
1097
1098 /*
1099 Calculates the number of whole input frames that would need to be read from the client in order to output the specified
1100 number of output frames.
1101
1102 The returned value does not include cached input frames. It only returns the number of extra frames that would need to be
1103 read from the input buffer in order to output the specified number of output frames.
1104 */
1105 MA_API ma_uint64 ma_resampler_get_required_input_frame_count(const ma_resampler* pResampler, ma_uint64 outputFrameCount);
1106
1107 /*
1108 Calculates the number of whole output frames that would be output after fully reading and consuming the specified number of
1109 input frames.
1110 */
1111 MA_API ma_uint64 ma_resampler_get_expected_output_frame_count(const ma_resampler* pResampler, ma_uint64 inputFrameCount);
1112
1113
1114 /*
1115 Retrieves the latency introduced by the resampler in input frames.
1116 */
1117 MA_API ma_uint64 ma_resampler_get_input_latency(const ma_resampler* pResampler);
1118
1119 /*
1120 Retrieves the latency introduced by the resampler in output frames.
1121 */
1122 MA_API ma_uint64 ma_resampler_get_output_latency(const ma_resampler* pResampler);
1123
1124
1125
1126 /**************************************************************************************************************************************************************
1127
1128 Channel Conversion
1129
1130 **************************************************************************************************************************************************************/
1131 typedef struct
1132 {
1133 ma_format format;
1134 ma_uint32 channelsIn;
1135 ma_uint32 channelsOut;
1136 ma_channel channelMapIn[MA_MAX_CHANNELS];
1137 ma_channel channelMapOut[MA_MAX_CHANNELS];
1138 ma_channel_mix_mode mixingMode;
1139 float weights[MA_MAX_CHANNELS][MA_MAX_CHANNELS]; /* [in][out]. Only used when mixingMode is set to ma_channel_mix_mode_custom_weights. */
1140 } ma_channel_converter_config;
1141
1142 MA_API ma_channel_converter_config ma_channel_converter_config_init(ma_format format, ma_uint32 channelsIn, const ma_channel* pChannelMapIn, ma_uint32 channelsOut, const ma_channel* pChannelMapOut, ma_channel_mix_mode mixingMode);
1143
1144 typedef struct
1145 {
1146 ma_format format;
1147 ma_uint32 channelsIn;
1148 ma_uint32 channelsOut;
1149 ma_channel channelMapIn[MA_MAX_CHANNELS];
1150 ma_channel channelMapOut[MA_MAX_CHANNELS];
1151 ma_channel_mix_mode mixingMode;
1152 union
1153 {
1154 float f32[MA_MAX_CHANNELS][MA_MAX_CHANNELS];
1155 ma_int32 s16[MA_MAX_CHANNELS][MA_MAX_CHANNELS];
1156 } weights;
1157 ma_bool8 isPassthrough;
1158 ma_bool8 isSimpleShuffle;
1159 ma_bool8 isSimpleMonoExpansion;
1160 ma_bool8 isStereoToMono;
1161 ma_uint8 shuffleTable[MA_MAX_CHANNELS];
1162 } ma_channel_converter;
1163
1164 MA_API ma_result ma_channel_converter_init(const ma_channel_converter_config* pConfig, ma_channel_converter* pConverter);
1165 MA_API void ma_channel_converter_uninit(ma_channel_converter* pConverter);
1166 MA_API ma_result ma_channel_converter_process_pcm_frames(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1167
1168
1169 /**************************************************************************************************************************************************************
1170
1171 Data Conversion
1172
1173 **************************************************************************************************************************************************************/
1174 typedef struct
1175 {
1176 ma_format formatIn;
1177 ma_format formatOut;
1178 ma_uint32 channelsIn;
1179 ma_uint32 channelsOut;
1180 ma_uint32 sampleRateIn;
1181 ma_uint32 sampleRateOut;
1182 ma_channel channelMapIn[MA_MAX_CHANNELS];
1183 ma_channel channelMapOut[MA_MAX_CHANNELS];
1184 ma_dither_mode ditherMode;
1185 ma_channel_mix_mode channelMixMode;
1186 float channelWeights[MA_MAX_CHANNELS][MA_MAX_CHANNELS]; /* [in][out]. Only used when channelMixMode is set to ma_channel_mix_mode_custom_weights. */
1187 struct
1188 {
1189 ma_resample_algorithm algorithm;
1190 ma_bool32 allowDynamicSampleRate;
1191 struct
1192 {
1193 ma_uint32 lpfOrder;
1194 double lpfNyquistFactor;
1195 } linear;
1196 struct
1197 {
1198 int quality;
1199 } speex;
1200 } resampling;
1201 } ma_data_converter_config;
1202
1203 MA_API ma_data_converter_config ma_data_converter_config_init_default(void);
1204 MA_API ma_data_converter_config ma_data_converter_config_init(ma_format formatIn, ma_format formatOut, ma_uint32 channelsIn, ma_uint32 channelsOut, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
1205
1206 typedef struct
1207 {
1208 ma_data_converter_config config;
1209 ma_channel_converter channelConverter;
1210 ma_resampler resampler;
1211 ma_bool8 hasPreFormatConversion;
1212 ma_bool8 hasPostFormatConversion;
1213 ma_bool8 hasChannelConverter;
1214 ma_bool8 hasResampler;
1215 ma_bool8 isPassthrough;
1216 } ma_data_converter;
1217
1218 MA_API ma_result ma_data_converter_init(const ma_data_converter_config* pConfig, ma_data_converter* pConverter);
1219 MA_API void ma_data_converter_uninit(ma_data_converter* pConverter);
1220 MA_API ma_result ma_data_converter_process_pcm_frames(ma_data_converter* pConverter, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
1221 MA_API ma_result ma_data_converter_set_rate(ma_data_converter* pConverter, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
1222 MA_API ma_result ma_data_converter_set_rate_ratio(ma_data_converter* pConverter, float ratioInOut);
1223 MA_API ma_uint64 ma_data_converter_get_required_input_frame_count(const ma_data_converter* pConverter, ma_uint64 outputFrameCount);
1224 MA_API ma_uint64 ma_data_converter_get_expected_output_frame_count(const ma_data_converter* pConverter, ma_uint64 inputFrameCount);
1225 MA_API ma_uint64 ma_data_converter_get_input_latency(const ma_data_converter* pConverter);
1226 MA_API ma_uint64 ma_data_converter_get_output_latency(const ma_data_converter* pConverter);
1227
1228
1229 /************************************************************************************************************************************************************
1230
1231 Format Conversion
1232
1233 ************************************************************************************************************************************************************/
1234 MA_API void ma_pcm_u8_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1235 MA_API void ma_pcm_u8_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1236 MA_API void ma_pcm_u8_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1237 MA_API void ma_pcm_u8_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1238 MA_API void ma_pcm_s16_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1239 MA_API void ma_pcm_s16_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1240 MA_API void ma_pcm_s16_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1241 MA_API void ma_pcm_s16_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1242 MA_API void ma_pcm_s24_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1243 MA_API void ma_pcm_s24_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1244 MA_API void ma_pcm_s24_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1245 MA_API void ma_pcm_s24_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1246 MA_API void ma_pcm_s32_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1247 MA_API void ma_pcm_s32_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1248 MA_API void ma_pcm_s32_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1249 MA_API void ma_pcm_s32_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1250 MA_API void ma_pcm_f32_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1251 MA_API void ma_pcm_f32_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1252 MA_API void ma_pcm_f32_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1253 MA_API void ma_pcm_f32_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1254 MA_API void ma_pcm_convert(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 sampleCount, ma_dither_mode ditherMode);
1255 MA_API void ma_convert_pcm_frames_format(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 frameCount, ma_uint32 channels, ma_dither_mode ditherMode);
1256
1257 /*
1258 Deinterleaves an interleaved buffer.
1259 */
1260 MA_API void ma_deinterleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void* pInterleavedPCMFrames, void** ppDeinterleavedPCMFrames);
1261
1262 /*
1263 Interleaves a group of deinterleaved buffers.
1264 */
1265 MA_API void ma_interleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void** ppDeinterleavedPCMFrames, void* pInterleavedPCMFrames);
1266
1267
1268 /************************************************************************************************************************************************************
1269
1270 Channel Maps
1271
1272 ************************************************************************************************************************************************************/
1273 /*
1274 This is used in the shuffle table to indicate that the channel index is undefined and should be ignored.
1275 */
1276 #define MA_CHANNEL_INDEX_NULL 255
1277
1278 /* Retrieves the channel position of the specified channel based on miniaudio's default channel map. */
1279 MA_API ma_channel ma_channel_map_get_default_channel(ma_uint32 channelCount, ma_uint32 channelIndex);
1280
1281 /*
1282 Retrieves the channel position of the specified channel in the given channel map.
1283
1284 The pChannelMap parameter can be null, in which case miniaudio's default channel map will be assumed.
1285 */
1286 MA_API ma_channel ma_channel_map_get_channel(const ma_channel* pChannelMap, ma_uint32 channelCount, ma_uint32 channelIndex);
1287
1288 /*
1289 Initializes a blank channel map.
1290
1291 When a blank channel map is specified anywhere it indicates that the native channel map should be used.
1292 */
1293 MA_API void ma_channel_map_init_blank(ma_uint32 channels, ma_channel* pChannelMap);
1294
1295 /*
1296 Helper for retrieving a standard channel map.
1297
1298 The output channel map buffer must have a capacity of at least `channels`.
1299 */
1300 MA_API void ma_get_standard_channel_map(ma_standard_channel_map standardChannelMap, ma_uint32 channels, ma_channel* pChannelMap);
1301
1302 /*
1303 Copies a channel map.
1304
1305 Both input and output channel map buffers must have a capacity of at at least `channels`.
1306 */
1307 MA_API void ma_channel_map_copy(ma_channel* pOut, const ma_channel* pIn, ma_uint32 channels);
1308
1309 /*
1310 Copies a channel map if one is specified, otherwise copies the default channel map.
1311
1312 The output buffer must have a capacity of at least `channels`. If not NULL, the input channel map must also have a capacity of at least `channels`.
1313 */
1314 MA_API void ma_channel_map_copy_or_default(ma_channel* pOut, const ma_channel* pIn, ma_uint32 channels);
1315
1316
1317 /*
1318 Determines whether or not a channel map is valid.
1319
1320 A blank channel map is valid (all channels set to MA_CHANNEL_NONE). The way a blank channel map is handled is context specific, but
1321 is usually treated as a passthrough.
1322
1323 Invalid channel maps:
1324 - A channel map with no channels
1325 - A channel map with more than one channel and a mono channel
1326
1327 The channel map buffer must have a capacity of at least `channels`.
1328 */
1329 MA_API ma_bool32 ma_channel_map_valid(ma_uint32 channels, const ma_channel* pChannelMap);
1330
1331 /*
1332 Helper for comparing two channel maps for equality.
1333
1334 This assumes the channel count is the same between the two.
1335
1336 Both channels map buffers must have a capacity of at least `channels`.
1337 */
1338 MA_API ma_bool32 ma_channel_map_equal(ma_uint32 channels, const ma_channel* pChannelMapA, const ma_channel* pChannelMapB);
1339
1340 /*
1341 Helper for determining if a channel map is blank (all channels set to MA_CHANNEL_NONE).
1342
1343 The channel map buffer must have a capacity of at least `channels`.
1344 */
1345 MA_API ma_bool32 ma_channel_map_blank(ma_uint32 channels, const ma_channel* pChannelMap);
1346
1347 /*
1348 Helper for determining whether or not a channel is present in the given channel map.
1349
1350 The channel map buffer must have a capacity of at least `channels`.
1351 */
1352 MA_API ma_bool32 ma_channel_map_contains_channel_position(ma_uint32 channels, const ma_channel* pChannelMap, ma_channel channelPosition);
1353
1354
1355 /************************************************************************************************************************************************************
1356
1357 Conversion Helpers
1358
1359 ************************************************************************************************************************************************************/
1360
1361 /*
1362 High-level helper for doing a full format conversion in one go. Returns the number of output frames. Call this with pOut set to NULL to
1363 determine the required size of the output buffer. frameCountOut should be set to the capacity of pOut. If pOut is NULL, frameCountOut is
1364 ignored.
1365
1366 A return value of 0 indicates an error.
1367
1368 This function is useful for one-off bulk conversions, but if you're streaming data you should use the ma_data_converter APIs instead.
1369 */
1370 MA_API ma_uint64 ma_convert_frames(void* pOut, ma_uint64 frameCountOut, ma_format formatOut, ma_uint32 channelsOut, ma_uint32 sampleRateOut, const void* pIn, ma_uint64 frameCountIn, ma_format formatIn, ma_uint32 channelsIn, ma_uint32 sampleRateIn);
1371 MA_API ma_uint64 ma_convert_frames_ex(void* pOut, ma_uint64 frameCountOut, const void* pIn, ma_uint64 frameCountIn, const ma_data_converter_config* pConfig);
1372
1373
1374 /************************************************************************************************************************************************************
1375
1376 Ring Buffer
1377
1378 ************************************************************************************************************************************************************/
1379 typedef struct
1380 {
1381 void* pBuffer;
1382 ma_uint32 subbufferSizeInBytes;
1383 ma_uint32 subbufferCount;
1384 ma_uint32 subbufferStrideInBytes;
1385 MA_ATOMIC ma_uint32 encodedReadOffset; /* Most significant bit is the loop flag. Lower 31 bits contains the actual offset in bytes. Must be used atomically. */
1386 MA_ATOMIC ma_uint32 encodedWriteOffset; /* Most significant bit is the loop flag. Lower 31 bits contains the actual offset in bytes. Must be used atomically. */
1387 ma_bool8 ownsBuffer; /* Used to know whether or not miniaudio is responsible for free()-ing the buffer. */
1388 ma_bool8 clearOnWriteAcquire; /* When set, clears the acquired write buffer before returning from ma_rb_acquire_write(). */
1389 ma_allocation_callbacks allocationCallbacks;
1390 } ma_rb;
1391
1392 MA_API ma_result ma_rb_init_ex(size_t subbufferSizeInBytes, size_t subbufferCount, size_t subbufferStrideInBytes, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_rb* pRB);
1393 MA_API ma_result ma_rb_init(size_t bufferSizeInBytes, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_rb* pRB);
1394 MA_API void ma_rb_uninit(ma_rb* pRB);
1395 MA_API void ma_rb_reset(ma_rb* pRB);
1396 MA_API ma_result ma_rb_acquire_read(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut);
1397 MA_API ma_result ma_rb_commit_read(ma_rb* pRB, size_t sizeInBytes, void* pBufferOut);
1398 MA_API ma_result ma_rb_acquire_write(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut);
1399 MA_API ma_result ma_rb_commit_write(ma_rb* pRB, size_t sizeInBytes, void* pBufferOut);
1400 MA_API ma_result ma_rb_seek_read(ma_rb* pRB, size_t offsetInBytes);
1401 MA_API ma_result ma_rb_seek_write(ma_rb* pRB, size_t offsetInBytes);
1402 MA_API ma_int32 ma_rb_pointer_distance(ma_rb* pRB); /* Returns the distance between the write pointer and the read pointer. Should never be negative for a correct program. Will return the number of bytes that can be read before the read pointer hits the write pointer. */
1403 MA_API ma_uint32 ma_rb_available_read(ma_rb* pRB);
1404 MA_API ma_uint32 ma_rb_available_write(ma_rb* pRB);
1405 MA_API size_t ma_rb_get_subbuffer_size(ma_rb* pRB);
1406 MA_API size_t ma_rb_get_subbuffer_stride(ma_rb* pRB);
1407 MA_API size_t ma_rb_get_subbuffer_offset(ma_rb* pRB, size_t subbufferIndex);
1408 MA_API void* ma_rb_get_subbuffer_ptr(ma_rb* pRB, size_t subbufferIndex, void* pBuffer);
1409
1410
1411 typedef struct
1412 {
1413 ma_rb rb;
1414 ma_format format;
1415 ma_uint32 channels;
1416 } ma_pcm_rb;
1417
1418 MA_API ma_result ma_pcm_rb_init_ex(ma_format format, ma_uint32 channels, ma_uint32 subbufferSizeInFrames, ma_uint32 subbufferCount, ma_uint32 subbufferStrideInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_pcm_rb* pRB);
1419 MA_API ma_result ma_pcm_rb_init(ma_format format, ma_uint32 channels, ma_uint32 bufferSizeInFrames, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_pcm_rb* pRB);
1420 MA_API void ma_pcm_rb_uninit(ma_pcm_rb* pRB);
1421 MA_API void ma_pcm_rb_reset(ma_pcm_rb* pRB);
1422 MA_API ma_result ma_pcm_rb_acquire_read(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
1423 MA_API ma_result ma_pcm_rb_commit_read(ma_pcm_rb* pRB, ma_uint32 sizeInFrames, void* pBufferOut);
1424 MA_API ma_result ma_pcm_rb_acquire_write(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
1425 MA_API ma_result ma_pcm_rb_commit_write(ma_pcm_rb* pRB, ma_uint32 sizeInFrames, void* pBufferOut);
1426 MA_API ma_result ma_pcm_rb_seek_read(ma_pcm_rb* pRB, ma_uint32 offsetInFrames);
1427 MA_API ma_result ma_pcm_rb_seek_write(ma_pcm_rb* pRB, ma_uint32 offsetInFrames);
1428 MA_API ma_int32 ma_pcm_rb_pointer_distance(ma_pcm_rb* pRB); /* Return value is in frames. */
1429 MA_API ma_uint32 ma_pcm_rb_available_read(ma_pcm_rb* pRB);
1430 MA_API ma_uint32 ma_pcm_rb_available_write(ma_pcm_rb* pRB);
1431 MA_API ma_uint32 ma_pcm_rb_get_subbuffer_size(ma_pcm_rb* pRB);
1432 MA_API ma_uint32 ma_pcm_rb_get_subbuffer_stride(ma_pcm_rb* pRB);
1433 MA_API ma_uint32 ma_pcm_rb_get_subbuffer_offset(ma_pcm_rb* pRB, ma_uint32 subbufferIndex);
1434 MA_API void* ma_pcm_rb_get_subbuffer_ptr(ma_pcm_rb* pRB, ma_uint32 subbufferIndex, void* pBuffer);
1435
1436
1437 /*
1438 The idea of the duplex ring buffer is to act as the intermediary buffer when running two asynchronous devices in a duplex set up. The
1439 capture device writes to it, and then a playback device reads from it.
1440
1441 At the moment this is just a simple naive implementation, but in the future I want to implement some dynamic resampling to seamlessly
1442 handle desyncs. Note that the API is work in progress and may change at any time in any version.
1443
1444 The size of the buffer is based on the capture side since that's what'll be written to the buffer. It is based on the capture period size
1445 in frames. The internal sample rate of the capture device is also needed in order to calculate the size.
1446 */
1447 typedef struct
1448 {
1449 ma_pcm_rb rb;
1450 } ma_duplex_rb;
1451
1452 MA_API ma_result ma_duplex_rb_init(ma_format captureFormat, ma_uint32 captureChannels, ma_uint32 sampleRate, ma_uint32 captureInternalSampleRate, ma_uint32 captureInternalPeriodSizeInFrames, const ma_allocation_callbacks* pAllocationCallbacks, ma_duplex_rb* pRB);
1453 MA_API ma_result ma_duplex_rb_uninit(ma_duplex_rb* pRB);
1454
1455
1456 /************************************************************************************************************************************************************
1457
1458 Miscellaneous Helpers
1459
1460 ************************************************************************************************************************************************************/
1461 /*
1462 Retrieves a human readable description of the given result code.
1463 */
1464 MA_API const char* ma_result_description(ma_result result);
1465
1466 /*
1467 malloc(). Calls MA_MALLOC().
1468 */
1469 MA_API void* ma_malloc(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks);
1470
1471 /*
1472 realloc(). Calls MA_REALLOC().
1473 */
1474 MA_API void* ma_realloc(void* p, size_t sz, const ma_allocation_callbacks* pAllocationCallbacks);
1475
1476 /*
1477 free(). Calls MA_FREE().
1478 */
1479 MA_API void ma_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
1480
1481 /*
1482 Performs an aligned malloc, with the assumption that the alignment is a power of 2.
1483 */
1484 MA_API void* ma_aligned_malloc(size_t sz, size_t alignment, const ma_allocation_callbacks* pAllocationCallbacks);
1485
1486 /*
1487 Free's an aligned malloc'd buffer.
1488 */
1489 MA_API void ma_aligned_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
1490
1491 /*
1492 Retrieves a friendly name for a format.
1493 */
1494 MA_API const char* ma_get_format_name(ma_format format);
1495
1496 /*
1497 Blends two frames in floating point format.
1498 */
1499 MA_API void ma_blend_f32(float* pOut, float* pInA, float* pInB, float factor, ma_uint32 channels);
1500
1501 /*
1502 Retrieves the size of a sample in bytes for the given format.
1503
1504 This API is efficient and is implemented using a lookup table.
1505
1506 Thread Safety: SAFE
1507 This API is pure.
1508 */
1509 MA_API ma_uint32 ma_get_bytes_per_sample(ma_format format);
ma_get_bytes_per_frame(ma_format format,ma_uint32 channels)1510 static MA_INLINE ma_uint32 ma_get_bytes_per_frame(ma_format format, ma_uint32 channels) { return ma_get_bytes_per_sample(format) * channels; }
1511
1512 /*
1513 Converts a log level to a string.
1514 */
1515 MA_API const char* ma_log_level_to_string(ma_uint32 logLevel);
1516
1517
1518
1519 /************************************************************************************************************************************************************
1520 *************************************************************************************************************************************************************
1521
1522 DEVICE I/O
1523 ==========
1524
1525 This section contains the APIs for device playback and capture. Here is where you'll find ma_device_init(), etc.
1526
1527 *************************************************************************************************************************************************************
1528 ************************************************************************************************************************************************************/
1529 #ifndef MA_NO_DEVICE_IO
1530 /* Some backends are only supported on certain platforms. */
1531 #if defined(MA_WIN32)
1532 #define MA_SUPPORT_WASAPI
1533 #if defined(MA_WIN32_DESKTOP) /* DirectSound and WinMM backends are only supported on desktops. */
1534 #define MA_SUPPORT_DSOUND
1535 #define MA_SUPPORT_WINMM
1536 #define MA_SUPPORT_JACK /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */
1537 #endif
1538 #endif
1539 #if defined(MA_UNIX)
1540 #if defined(MA_LINUX)
1541 #if !defined(MA_ANDROID) /* ALSA is not supported on Android. */
1542 #define MA_SUPPORT_ALSA
1543 #endif
1544 #endif
1545 #if !defined(MA_BSD) && !defined(MA_ANDROID) && !defined(MA_EMSCRIPTEN)
1546 #define MA_SUPPORT_PULSEAUDIO
1547 #define MA_SUPPORT_JACK
1548 #endif
1549 #if defined(MA_ANDROID)
1550 #define MA_SUPPORT_AAUDIO
1551 #define MA_SUPPORT_OPENSL
1552 #endif
1553 #if defined(__OpenBSD__) /* <-- Change this to "#if defined(MA_BSD)" to enable sndio on all BSD flavors. */
1554 #define MA_SUPPORT_SNDIO /* sndio is only supported on OpenBSD for now. May be expanded later if there's demand. */
1555 #endif
1556 #if defined(__NetBSD__) || defined(__OpenBSD__)
1557 #define MA_SUPPORT_AUDIO4 /* Only support audio(4) on platforms with known support. */
1558 #endif
1559 #if defined(__FreeBSD__) || defined(__DragonFly__)
1560 #define MA_SUPPORT_OSS /* Only support OSS on specific platforms with known support. */
1561 #endif
1562 #endif
1563 #if defined(MA_APPLE)
1564 #define MA_SUPPORT_COREAUDIO
1565 #endif
1566 #if defined(MA_EMSCRIPTEN)
1567 #define MA_SUPPORT_WEBAUDIO
1568 #endif
1569
1570 /* All platforms should support custom backends. */
1571 #define MA_SUPPORT_CUSTOM
1572
1573 /* Explicitly disable the Null backend for Emscripten because it uses a background thread which is not properly supported right now. */
1574 #if !defined(MA_EMSCRIPTEN)
1575 #define MA_SUPPORT_NULL
1576 #endif
1577
1578
1579 #if defined(MA_SUPPORT_WASAPI) && !defined(MA_NO_WASAPI) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_WASAPI))
1580 #define MA_HAS_WASAPI
1581 #endif
1582 #if defined(MA_SUPPORT_DSOUND) && !defined(MA_NO_DSOUND) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_DSOUND))
1583 #define MA_HAS_DSOUND
1584 #endif
1585 #if defined(MA_SUPPORT_WINMM) && !defined(MA_NO_WINMM) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_WINMM))
1586 #define MA_HAS_WINMM
1587 #endif
1588 #if defined(MA_SUPPORT_ALSA) && !defined(MA_NO_ALSA) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_ALSA))
1589 #define MA_HAS_ALSA
1590 #endif
1591 #if defined(MA_SUPPORT_PULSEAUDIO) && !defined(MA_NO_PULSEAUDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_PULSEAUDIO))
1592 #define MA_HAS_PULSEAUDIO
1593 #endif
1594 #if defined(MA_SUPPORT_JACK) && !defined(MA_NO_JACK) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_JACK))
1595 #define MA_HAS_JACK
1596 #endif
1597 #if defined(MA_SUPPORT_COREAUDIO) && !defined(MA_NO_COREAUDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_COREAUDIO))
1598 #define MA_HAS_COREAUDIO
1599 #endif
1600 #if defined(MA_SUPPORT_SNDIO) && !defined(MA_NO_SNDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_SNDIO))
1601 #define MA_HAS_SNDIO
1602 #endif
1603 #if defined(MA_SUPPORT_AUDIO4) && !defined(MA_NO_AUDIO4) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_AUDIO4))
1604 #define MA_HAS_AUDIO4
1605 #endif
1606 #if defined(MA_SUPPORT_OSS) && !defined(MA_NO_OSS) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_OSS))
1607 #define MA_HAS_OSS
1608 #endif
1609 #if defined(MA_SUPPORT_AAUDIO) && !defined(MA_NO_AAUDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_AAUDIO))
1610 #define MA_HAS_AAUDIO
1611 #endif
1612 #if defined(MA_SUPPORT_OPENSL) && !defined(MA_NO_OPENSL) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_OPENSL))
1613 #define MA_HAS_OPENSL
1614 #endif
1615 #if defined(MA_SUPPORT_WEBAUDIO) && !defined(MA_NO_WEBAUDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_WEBAUDIO))
1616 #define MA_HAS_WEBAUDIO
1617 #endif
1618 #if defined(MA_SUPPORT_CUSTOM) && !defined(MA_NO_CUSTOM) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_CUSTOM))
1619 #define MA_HAS_CUSTOM
1620 #endif
1621 #if defined(MA_SUPPORT_NULL) && !defined(MA_NO_NULL) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_NULL))
1622 #define MA_HAS_NULL
1623 #endif
1624
1625 #define MA_STATE_UNINITIALIZED 0
1626 #define MA_STATE_STOPPED 1 /* The device's default state after initialization. */
1627 #define MA_STATE_STARTED 2 /* The device is started and is requesting and/or delivering audio data. */
1628 #define MA_STATE_STARTING 3 /* Transitioning from a stopped state to started. */
1629 #define MA_STATE_STOPPING 4 /* Transitioning from a started state to stopped. */
1630
1631 #ifdef MA_SUPPORT_WASAPI
1632 /* We need a IMMNotificationClient object for WASAPI. */
1633 typedef struct
1634 {
1635 void* lpVtbl;
1636 ma_uint32 counter;
1637 ma_device* pDevice;
1638 } ma_IMMNotificationClient;
1639 #endif
1640
1641 /* Backend enums must be in priority order. */
1642 typedef enum
1643 {
1644 ma_backend_wasapi,
1645 ma_backend_dsound,
1646 ma_backend_winmm,
1647 ma_backend_coreaudio,
1648 ma_backend_sndio,
1649 ma_backend_audio4,
1650 ma_backend_oss,
1651 ma_backend_pulseaudio,
1652 ma_backend_alsa,
1653 ma_backend_jack,
1654 ma_backend_aaudio,
1655 ma_backend_opensl,
1656 ma_backend_webaudio,
1657 ma_backend_custom, /* <-- Custom backend, with callbacks defined by the context config. */
1658 ma_backend_null /* <-- Must always be the last item. Lowest priority, and used as the terminator for backend enumeration. */
1659 } ma_backend;
1660
1661 #define MA_BACKEND_COUNT (ma_backend_null+1)
1662
1663
1664 /*
1665 The callback for processing audio data from the device.
1666
1667 The data callback is fired by miniaudio whenever the device needs to have more data delivered to a playback device, or when a capture device has some data
1668 available. This is called as soon as the backend asks for more data which means it may be called with inconsistent frame counts. You cannot assume the
1669 callback will be fired with a consistent frame count.
1670
1671
1672 Parameters
1673 ----------
1674 pDevice (in)
1675 A pointer to the relevant device.
1676
1677 pOutput (out)
1678 A pointer to the output buffer that will receive audio data that will later be played back through the speakers. This will be non-null for a playback or
1679 full-duplex device and null for a capture and loopback device.
1680
1681 pInput (in)
1682 A pointer to the buffer containing input data from a recording device. This will be non-null for a capture, full-duplex or loopback device and null for a
1683 playback device.
1684
1685 frameCount (in)
1686 The number of PCM frames to process. Note that this will not necessarily be equal to what you requested when you initialized the device. The
1687 `periodSizeInFrames` and `periodSizeInMilliseconds` members of the device config are just hints, and are not necessarily exactly what you'll get. You must
1688 not assume this will always be the same value each time the callback is fired.
1689
1690
1691 Remarks
1692 -------
1693 You cannot stop and start the device from inside the callback or else you'll get a deadlock. You must also not uninitialize the device from inside the
1694 callback. The following APIs cannot be called from inside the callback:
1695
1696 ma_device_init()
1697 ma_device_init_ex()
1698 ma_device_uninit()
1699 ma_device_start()
1700 ma_device_stop()
1701
1702 The proper way to stop the device is to call `ma_device_stop()` from a different thread, normally the main application thread.
1703 */
1704 typedef void (* ma_device_callback_proc)(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
1705
1706 /*
1707 The callback for when the device has been stopped.
1708
1709 This will be called when the device is stopped explicitly with `ma_device_stop()` and also called implicitly when the device is stopped through external forces
1710 such as being unplugged or an internal error occuring.
1711
1712
1713 Parameters
1714 ----------
1715 pDevice (in)
1716 A pointer to the device that has just stopped.
1717
1718
1719 Remarks
1720 -------
1721 Do not restart or uninitialize the device from the callback.
1722 */
1723 typedef void (* ma_stop_proc)(ma_device* pDevice);
1724
1725 /*
1726 The callback for handling log messages.
1727
1728
1729 Parameters
1730 ----------
1731 pContext (in)
1732 A pointer to the context the log message originated from.
1733
1734 pDevice (in)
1735 A pointer to the device the log message originate from, if any. This can be null, in which case the message came from the context.
1736
1737 logLevel (in)
1738 The log level. This can be one of the following:
1739
1740 +----------------------+
1741 | Log Level |
1742 +----------------------+
1743 | MA_LOG_LEVEL_DEBUG |
1744 | MA_LOG_LEVEL_INFO |
1745 | MA_LOG_LEVEL_WARNING |
1746 | MA_LOG_LEVEL_ERROR |
1747 +----------------------+
1748
1749 message (in)
1750 The log message.
1751
1752
1753 Remarks
1754 -------
1755 Do not modify the state of the device from inside the callback.
1756 */
1757 typedef void (* ma_log_proc)(ma_context* pContext, ma_device* pDevice, ma_uint32 logLevel, const char* message);
1758
1759 typedef enum
1760 {
1761 ma_device_type_playback = 1,
1762 ma_device_type_capture = 2,
1763 ma_device_type_duplex = ma_device_type_playback | ma_device_type_capture, /* 3 */
1764 ma_device_type_loopback = 4
1765 } ma_device_type;
1766
1767 typedef enum
1768 {
1769 ma_share_mode_shared = 0,
1770 ma_share_mode_exclusive
1771 } ma_share_mode;
1772
1773 /* iOS/tvOS/watchOS session categories. */
1774 typedef enum
1775 {
1776 ma_ios_session_category_default = 0, /* AVAudioSessionCategoryPlayAndRecord with AVAudioSessionCategoryOptionDefaultToSpeaker. */
1777 ma_ios_session_category_none, /* Leave the session category unchanged. */
1778 ma_ios_session_category_ambient, /* AVAudioSessionCategoryAmbient */
1779 ma_ios_session_category_solo_ambient, /* AVAudioSessionCategorySoloAmbient */
1780 ma_ios_session_category_playback, /* AVAudioSessionCategoryPlayback */
1781 ma_ios_session_category_record, /* AVAudioSessionCategoryRecord */
1782 ma_ios_session_category_play_and_record, /* AVAudioSessionCategoryPlayAndRecord */
1783 ma_ios_session_category_multi_route /* AVAudioSessionCategoryMultiRoute */
1784 } ma_ios_session_category;
1785
1786 /* iOS/tvOS/watchOS session category options */
1787 typedef enum
1788 {
1789 ma_ios_session_category_option_mix_with_others = 0x01, /* AVAudioSessionCategoryOptionMixWithOthers */
1790 ma_ios_session_category_option_duck_others = 0x02, /* AVAudioSessionCategoryOptionDuckOthers */
1791 ma_ios_session_category_option_allow_bluetooth = 0x04, /* AVAudioSessionCategoryOptionAllowBluetooth */
1792 ma_ios_session_category_option_default_to_speaker = 0x08, /* AVAudioSessionCategoryOptionDefaultToSpeaker */
1793 ma_ios_session_category_option_interrupt_spoken_audio_and_mix_with_others = 0x11, /* AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers */
1794 ma_ios_session_category_option_allow_bluetooth_a2dp = 0x20, /* AVAudioSessionCategoryOptionAllowBluetoothA2DP */
1795 ma_ios_session_category_option_allow_air_play = 0x40, /* AVAudioSessionCategoryOptionAllowAirPlay */
1796 } ma_ios_session_category_option;
1797
1798 /* OpenSL stream types. */
1799 typedef enum
1800 {
1801 ma_opensl_stream_type_default = 0, /* Leaves the stream type unset. */
1802 ma_opensl_stream_type_voice, /* SL_ANDROID_STREAM_VOICE */
1803 ma_opensl_stream_type_system, /* SL_ANDROID_STREAM_SYSTEM */
1804 ma_opensl_stream_type_ring, /* SL_ANDROID_STREAM_RING */
1805 ma_opensl_stream_type_media, /* SL_ANDROID_STREAM_MEDIA */
1806 ma_opensl_stream_type_alarm, /* SL_ANDROID_STREAM_ALARM */
1807 ma_opensl_stream_type_notification /* SL_ANDROID_STREAM_NOTIFICATION */
1808 } ma_opensl_stream_type;
1809
1810 /* OpenSL recording presets. */
1811 typedef enum
1812 {
1813 ma_opensl_recording_preset_default = 0, /* Leaves the input preset unset. */
1814 ma_opensl_recording_preset_generic, /* SL_ANDROID_RECORDING_PRESET_GENERIC */
1815 ma_opensl_recording_preset_camcorder, /* SL_ANDROID_RECORDING_PRESET_CAMCORDER */
1816 ma_opensl_recording_preset_voice_recognition, /* SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION */
1817 ma_opensl_recording_preset_voice_communication, /* SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION */
1818 ma_opensl_recording_preset_voice_unprocessed /* SL_ANDROID_RECORDING_PRESET_UNPROCESSED */
1819 } ma_opensl_recording_preset;
1820
1821 /* AAudio usage types. */
1822 typedef enum
1823 {
1824 ma_aaudio_usage_default = 0, /* Leaves the usage type unset. */
1825 ma_aaudio_usage_announcement, /* AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT */
1826 ma_aaudio_usage_emergency, /* AAUDIO_SYSTEM_USAGE_EMERGENCY */
1827 ma_aaudio_usage_safety, /* AAUDIO_SYSTEM_USAGE_SAFETY */
1828 ma_aaudio_usage_vehicle_status, /* AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS */
1829 ma_aaudio_usage_alarm, /* AAUDIO_USAGE_ALARM */
1830 ma_aaudio_usage_assistance_accessibility, /* AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY */
1831 ma_aaudio_usage_assistance_navigation_guidance, /* AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE */
1832 ma_aaudio_usage_assistance_sonification, /* AAUDIO_USAGE_ASSISTANCE_SONIFICATION */
1833 ma_aaudio_usage_assitant, /* AAUDIO_USAGE_ASSISTANT */
1834 ma_aaudio_usage_game, /* AAUDIO_USAGE_GAME */
1835 ma_aaudio_usage_media, /* AAUDIO_USAGE_MEDIA */
1836 ma_aaudio_usage_notification, /* AAUDIO_USAGE_NOTIFICATION */
1837 ma_aaudio_usage_notification_event, /* AAUDIO_USAGE_NOTIFICATION_EVENT */
1838 ma_aaudio_usage_notification_ringtone, /* AAUDIO_USAGE_NOTIFICATION_RINGTONE */
1839 ma_aaudio_usage_voice_communication, /* AAUDIO_USAGE_VOICE_COMMUNICATION */
1840 ma_aaudio_usage_voice_communication_signalling /* AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING */
1841 } ma_aaudio_usage;
1842
1843 /* AAudio content types. */
1844 typedef enum
1845 {
1846 ma_aaudio_content_type_default = 0, /* Leaves the content type unset. */
1847 ma_aaudio_content_type_movie, /* AAUDIO_CONTENT_TYPE_MOVIE */
1848 ma_aaudio_content_type_music, /* AAUDIO_CONTENT_TYPE_MUSIC */
1849 ma_aaudio_content_type_sonification, /* AAUDIO_CONTENT_TYPE_SONIFICATION */
1850 ma_aaudio_content_type_speech /* AAUDIO_CONTENT_TYPE_SPEECH */
1851 } ma_aaudio_content_type;
1852
1853 /* AAudio input presets. */
1854 typedef enum
1855 {
1856 ma_aaudio_input_preset_default = 0, /* Leaves the input preset unset. */
1857 ma_aaudio_input_preset_generic, /* AAUDIO_INPUT_PRESET_GENERIC */
1858 ma_aaudio_input_preset_camcorder, /* AAUDIO_INPUT_PRESET_CAMCORDER */
1859 ma_aaudio_input_preset_unprocessed, /* AAUDIO_INPUT_PRESET_UNPROCESSED */
1860 ma_aaudio_input_preset_voice_recognition, /* AAUDIO_INPUT_PRESET_VOICE_RECOGNITION */
1861 ma_aaudio_input_preset_voice_communication, /* AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION */
1862 ma_aaudio_input_preset_voice_performance /* AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE */
1863 } ma_aaudio_input_preset;
1864
1865
1866 typedef union
1867 {
1868 ma_int64 counter;
1869 double counterD;
1870 } ma_timer;
1871
1872 typedef union
1873 {
1874 wchar_t wasapi[64]; /* WASAPI uses a wchar_t string for identification. */
1875 ma_uint8 dsound[16]; /* DirectSound uses a GUID for identification. */
1876 /*UINT_PTR*/ ma_uint32 winmm; /* When creating a device, WinMM expects a Win32 UINT_PTR for device identification. In practice it's actually just a UINT. */
1877 char alsa[256]; /* ALSA uses a name string for identification. */
1878 char pulse[256]; /* PulseAudio uses a name string for identification. */
1879 int jack; /* JACK always uses default devices. */
1880 char coreaudio[256]; /* Core Audio uses a string for identification. */
1881 char sndio[256]; /* "snd/0", etc. */
1882 char audio4[256]; /* "/dev/audio", etc. */
1883 char oss[64]; /* "dev/dsp0", etc. "dev/dsp" for the default device. */
1884 ma_int32 aaudio; /* AAudio uses a 32-bit integer for identification. */
1885 ma_uint32 opensl; /* OpenSL|ES uses a 32-bit unsigned integer for identification. */
1886 char webaudio[32]; /* Web Audio always uses default devices for now, but if this changes it'll be a GUID. */
1887 union
1888 {
1889 int i;
1890 char s[256];
1891 void* p;
1892 } custom; /* The custom backend could be anything. Give them a few options. */
1893 int nullbackend; /* The null backend uses an integer for device IDs. */
1894 } ma_device_id;
1895
1896
1897 typedef struct ma_context_config ma_context_config;
1898 typedef struct ma_device_config ma_device_config;
1899 typedef struct ma_backend_callbacks ma_backend_callbacks;
1900
1901 #define MA_DATA_FORMAT_FLAG_EXCLUSIVE_MODE (1U << 1) /* If set, this is supported in exclusive mode. Otherwise not natively supported by exclusive mode. */
1902
1903 typedef struct
1904 {
1905 /* Basic info. This is the only information guaranteed to be filled in during device enumeration. */
1906 ma_device_id id;
1907 char name[256];
1908 ma_bool32 isDefault;
1909
1910 /*
1911 Detailed info. As much of this is filled as possible with ma_context_get_device_info(). Note that you are allowed to initialize
1912 a device with settings outside of this range, but it just means the data will be converted using miniaudio's data conversion
1913 pipeline before sending the data to/from the device. Most programs will need to not worry about these values, but it's provided
1914 here mainly for informational purposes or in the rare case that someone might find it useful.
1915
1916 These will be set to 0 when returned by ma_context_enumerate_devices() or ma_context_get_devices().
1917 */
1918 ma_uint32 formatCount;
1919 ma_format formats[ma_format_count];
1920 ma_uint32 minChannels;
1921 ma_uint32 maxChannels;
1922 ma_uint32 minSampleRate;
1923 ma_uint32 maxSampleRate;
1924
1925
1926 /* Experimental. Don't use these right now. */
1927 ma_uint32 nativeDataFormatCount;
1928 struct
1929 {
1930 ma_format format; /* Sample format. If set to ma_format_unknown, all sample formats are supported. */
1931 ma_uint32 channels; /* If set to 0, all channels are supported. */
1932 ma_uint32 sampleRate; /* If set to 0, all sample rates are supported. */
1933 ma_uint32 flags; /* A combination of MA_DATA_FORMAT_FLAG_* flags. */
1934 } nativeDataFormats[/*ma_format_count * ma_standard_sample_rate_count * MA_MAX_CHANNELS*/ 64]; /* Not sure how big to make this. There can be *many* permutations for virtual devices which can support anything. */
1935 } ma_device_info;
1936
1937 struct ma_device_config
1938 {
1939 ma_device_type deviceType;
1940 ma_uint32 sampleRate;
1941 ma_uint32 periodSizeInFrames;
1942 ma_uint32 periodSizeInMilliseconds;
1943 ma_uint32 periods;
1944 ma_performance_profile performanceProfile;
1945 ma_bool8 noPreZeroedOutputBuffer; /* When set to true, the contents of the output buffer passed into the data callback will be left undefined rather than initialized to zero. */
1946 ma_bool8 noClip; /* When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. Only applies when the playback sample format is f32. */
1947 ma_device_callback_proc dataCallback;
1948 ma_stop_proc stopCallback;
1949 void* pUserData;
1950 struct
1951 {
1952 ma_resample_algorithm algorithm;
1953 struct
1954 {
1955 ma_uint32 lpfOrder;
1956 } linear;
1957 struct
1958 {
1959 int quality;
1960 } speex;
1961 } resampling;
1962 struct
1963 {
1964 const ma_device_id* pDeviceID;
1965 ma_format format;
1966 ma_uint32 channels;
1967 ma_channel channelMap[MA_MAX_CHANNELS];
1968 ma_channel_mix_mode channelMixMode;
1969 ma_share_mode shareMode;
1970 } playback;
1971 struct
1972 {
1973 const ma_device_id* pDeviceID;
1974 ma_format format;
1975 ma_uint32 channels;
1976 ma_channel channelMap[MA_MAX_CHANNELS];
1977 ma_channel_mix_mode channelMixMode;
1978 ma_share_mode shareMode;
1979 } capture;
1980
1981 struct
1982 {
1983 ma_bool8 noAutoConvertSRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
1984 ma_bool8 noDefaultQualitySRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */
1985 ma_bool8 noAutoStreamRouting; /* Disables automatic stream routing. */
1986 ma_bool8 noHardwareOffloading; /* Disables WASAPI's hardware offloading feature. */
1987 } wasapi;
1988 struct
1989 {
1990 ma_bool32 noMMap; /* Disables MMap mode. */
1991 ma_bool32 noAutoFormat; /* Opens the ALSA device with SND_PCM_NO_AUTO_FORMAT. */
1992 ma_bool32 noAutoChannels; /* Opens the ALSA device with SND_PCM_NO_AUTO_CHANNELS. */
1993 ma_bool32 noAutoResample; /* Opens the ALSA device with SND_PCM_NO_AUTO_RESAMPLE. */
1994 } alsa;
1995 struct
1996 {
1997 const char* pStreamNamePlayback;
1998 const char* pStreamNameCapture;
1999 } pulse;
2000 struct
2001 {
2002 ma_bool32 allowNominalSampleRateChange; /* Desktop only. When enabled, allows changing of the sample rate at the operating system level. */
2003 } coreaudio;
2004 struct
2005 {
2006 ma_opensl_stream_type streamType;
2007 ma_opensl_recording_preset recordingPreset;
2008 } opensl;
2009 struct
2010 {
2011 ma_aaudio_usage usage;
2012 ma_aaudio_content_type contentType;
2013 ma_aaudio_input_preset inputPreset;
2014 } aaudio;
2015 };
2016
2017
2018 /*
2019 The callback for handling device enumeration. This is fired from `ma_context_enumerated_devices()`.
2020
2021
2022 Parameters
2023 ----------
2024 pContext (in)
2025 A pointer to the context performing the enumeration.
2026
2027 deviceType (in)
2028 The type of the device being enumerated. This will always be either `ma_device_type_playback` or `ma_device_type_capture`.
2029
2030 pInfo (in)
2031 A pointer to a `ma_device_info` containing the ID and name of the enumerated device. Note that this will not include detailed information about the device,
2032 only basic information (ID and name). The reason for this is that it would otherwise require opening the backend device to probe for the information which
2033 is too inefficient.
2034
2035 pUserData (in)
2036 The user data pointer passed into `ma_context_enumerate_devices()`.
2037 */
2038 typedef ma_bool32 (* ma_enum_devices_callback_proc)(ma_context* pContext, ma_device_type deviceType, const ma_device_info* pInfo, void* pUserData);
2039
2040
2041 /*
2042 Describes some basic details about a playback or capture device.
2043 */
2044 typedef struct
2045 {
2046 const ma_device_id* pDeviceID;
2047 ma_share_mode shareMode;
2048 ma_format format;
2049 ma_uint32 channels;
2050 ma_uint32 sampleRate;
2051 ma_channel channelMap[MA_MAX_CHANNELS];
2052 ma_uint32 periodSizeInFrames;
2053 ma_uint32 periodSizeInMilliseconds;
2054 ma_uint32 periodCount;
2055 } ma_device_descriptor;
2056
2057 /*
2058 These are the callbacks required to be implemented for a backend. These callbacks are grouped into two parts: context and device. There is one context
2059 to many devices. A device is created from a context.
2060
2061 The general flow goes like this:
2062
2063 1) A context is created with `onContextInit()`
2064 1a) Available devices can be enumerated with `onContextEnumerateDevices()` if required.
2065 1b) Detailed information about a device can be queried with `onContextGetDeviceInfo()` if required.
2066 2) A device is created from the context that was created in the first step using `onDeviceInit()`, and optionally a device ID that was
2067 selected from device enumeration via `onContextEnumerateDevices()`.
2068 3) A device is started or stopped with `onDeviceStart()` / `onDeviceStop()`
2069 4) Data is delivered to and from the device by the backend. This is always done based on the native format returned by the prior call
2070 to `onDeviceInit()`. Conversion between the device's native format and the format requested by the application will be handled by
2071 miniaudio internally.
2072
2073 Initialization of the context is quite simple. You need to do any necessary initialization of internal objects and then output the
2074 callbacks defined in this structure.
2075
2076 Once the context has been initialized you can initialize a device. Before doing so, however, the application may want to know which
2077 physical devices are available. This is where `onContextEnumerateDevices()` comes in. This is fairly simple. For each device, fire the
2078 given callback with, at a minimum, the basic information filled out in `ma_device_info`. When the callback returns `MA_FALSE`, enumeration
2079 needs to stop and the `onContextEnumerateDevices()` function return with a success code.
2080
2081 Detailed device information can be retrieved from a device ID using `onContextGetDeviceInfo()`. This takes as input the device type and ID,
2082 and on output returns detailed information about the device in `ma_device_info`. The `onContextGetDeviceInfo()` callback must handle the
2083 case when the device ID is NULL, in which case information about the default device needs to be retrieved.
2084
2085 Once the context has been created and the device ID retrieved (if using anything other than the default device), the device can be created.
2086 This is a little bit more complicated than initialization of the context due to it's more complicated configuration. When initializing a
2087 device, a duplex device may be requested. This means a separate data format needs to be specified for both playback and capture. On input,
2088 the data format is set to what the application wants. On output it's set to the native format which should match as closely as possible to
2089 the requested format. The conversion between the format requested by the application and the device's native format will be handled
2090 internally by miniaudio.
2091
2092 On input, if the sample format is set to `ma_format_unknown`, the backend is free to use whatever sample format it desires, so long as it's
2093 supported by miniaudio. When the channel count is set to 0, the backend should use the device's native channel count. The same applies for
2094 sample rate. For the channel map, the default should be used when `ma_channel_map_blank()` returns true (all channels set to
2095 `MA_CHANNEL_NONE`). On input, the `periodSizeInFrames` or `periodSizeInMilliseconds` option should always be set. The backend should
2096 inspect both of these variables. If `periodSizeInFrames` is set, it should take priority, otherwise it needs to be derived from the period
2097 size in milliseconds (`periodSizeInMilliseconds`) and the sample rate, keeping in mind that the sample rate may be 0, in which case the
2098 sample rate will need to be determined before calculating the period size in frames. On output, all members of the `ma_device_data_format`
2099 object should be set to a valid value, except for `periodSizeInMilliseconds` which is optional (`periodSizeInFrames` *must* be set).
2100
2101 Starting and stopping of the device is done with `onDeviceStart()` and `onDeviceStop()` and should be self-explanatory. If the backend uses
2102 asynchronous reading and writing, `onDeviceStart()` and `onDeviceStop()` should always be implemented.
2103
2104 The handling of data delivery between the application and the device is the most complicated part of the process. To make this a bit
2105 easier, some helper callbacks are available. If the backend uses a blocking read/write style of API, the `onDeviceRead()` and
2106 `onDeviceWrite()` callbacks can optionally be implemented. These are blocking and work just like reading and writing from a file. If the
2107 backend uses a callback for data delivery, that callback must call `ma_device_handle_backend_data_callback()` from within it's callback.
2108 This allows miniaudio to then process any necessary data conversion and then pass it to the miniaudio data callback.
2109
2110 If the backend requires absolute flexibility with it's data delivery, it can optionally implement the `onDeviceDataLoop()` callback
2111 which will allow it to implement the logic that will run on the audio thread. This is much more advanced and is completely optional.
2112
2113 The audio thread should run data delivery logic in a loop while `ma_device_get_state() == MA_STATE_STARTED` and no errors have been
2114 encounted. Do not start or stop the device here. That will be handled from outside the `onDeviceDataLoop()` callback.
2115
2116 The invocation of the `onDeviceDataLoop()` callback will be handled by miniaudio. When you start the device, miniaudio will fire this
2117 callback. When the device is stopped, the `ma_device_get_state() == MA_STATE_STARTED` condition will fail and the loop will be terminated
2118 which will then fall through to the part that stops the device. For an example on how to implement the `onDeviceDataLoop()` callback,
2119 look at `ma_device_audio_thread__default_read_write()`. Implement the `onDeviceDataLoopWakeup()` callback if you need a mechanism to
2120 wake up the audio thread.
2121 */
2122 struct ma_backend_callbacks
2123 {
2124 ma_result (* onContextInit)(ma_context* pContext, const ma_context_config* pConfig, ma_backend_callbacks* pCallbacks);
2125 ma_result (* onContextUninit)(ma_context* pContext);
2126 ma_result (* onContextEnumerateDevices)(ma_context* pContext, ma_enum_devices_callback_proc callback, void* pUserData);
2127 ma_result (* onContextGetDeviceInfo)(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_device_info* pDeviceInfo);
2128 ma_result (* onDeviceInit)(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture);
2129 ma_result (* onDeviceUninit)(ma_device* pDevice);
2130 ma_result (* onDeviceStart)(ma_device* pDevice);
2131 ma_result (* onDeviceStop)(ma_device* pDevice);
2132 ma_result (* onDeviceRead)(ma_device* pDevice, void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesRead);
2133 ma_result (* onDeviceWrite)(ma_device* pDevice, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten);
2134 ma_result (* onDeviceDataLoop)(ma_device* pDevice);
2135 ma_result (* onDeviceDataLoopWakeup)(ma_device* pDevice);
2136 };
2137
2138 struct ma_context_config
2139 {
2140 ma_log_proc logCallback; /* Legacy logging callback. Will be removed in version 0.11. */
2141 ma_log* pLog;
2142 ma_thread_priority threadPriority;
2143 size_t threadStackSize;
2144 void* pUserData;
2145 ma_allocation_callbacks allocationCallbacks;
2146 struct
2147 {
2148 ma_bool32 useVerboseDeviceEnumeration;
2149 } alsa;
2150 struct
2151 {
2152 const char* pApplicationName;
2153 const char* pServerName;
2154 ma_bool32 tryAutoSpawn; /* Enables autospawning of the PulseAudio daemon if necessary. */
2155 } pulse;
2156 struct
2157 {
2158 ma_ios_session_category sessionCategory;
2159 ma_uint32 sessionCategoryOptions;
2160 ma_bool32 noAudioSessionActivate; /* iOS only. When set to true, does not perform an explicit [[AVAudioSession sharedInstace] setActive:true] on initialization. */
2161 ma_bool32 noAudioSessionDeactivate; /* iOS only. When set to true, does not perform an explicit [[AVAudioSession sharedInstace] setActive:false] on uninitialization. */
2162 } coreaudio;
2163 struct
2164 {
2165 const char* pClientName;
2166 ma_bool32 tryStartServer;
2167 } jack;
2168 ma_backend_callbacks custom;
2169 };
2170
2171 /* WASAPI specific structure for some commands which must run on a common thread due to bugs in WASAPI. */
2172 typedef struct
2173 {
2174 int code;
2175 ma_event* pEvent; /* This will be signalled when the event is complete. */
2176 union
2177 {
2178 struct
2179 {
2180 int _unused;
2181 } quit;
2182 struct
2183 {
2184 ma_device_type deviceType;
2185 void* pAudioClient;
2186 void** ppAudioClientService;
2187 ma_result* pResult; /* The result from creating the audio client service. */
2188 } createAudioClient;
2189 struct
2190 {
2191 ma_device* pDevice;
2192 ma_device_type deviceType;
2193 } releaseAudioClient;
2194 } data;
2195 } ma_context_command__wasapi;
2196
2197 struct ma_context
2198 {
2199 ma_backend_callbacks callbacks;
2200 ma_backend backend; /* DirectSound, ALSA, etc. */
2201 ma_log* pLog;
2202 ma_log log; /* Only used if the log is owned by the context. The pLog member will be set to &log in this case. */
2203 ma_log_proc logCallback; /* Legacy callback. Will be removed in version 0.11. */
2204 ma_thread_priority threadPriority;
2205 size_t threadStackSize;
2206 void* pUserData;
2207 ma_allocation_callbacks allocationCallbacks;
2208 ma_mutex deviceEnumLock; /* Used to make ma_context_get_devices() thread safe. */
2209 ma_mutex deviceInfoLock; /* Used to make ma_context_get_device_info() thread safe. */
2210 ma_uint32 deviceInfoCapacity; /* Total capacity of pDeviceInfos. */
2211 ma_uint32 playbackDeviceInfoCount;
2212 ma_uint32 captureDeviceInfoCount;
2213 ma_device_info* pDeviceInfos; /* Playback devices first, then capture. */
2214
2215 union
2216 {
2217 #ifdef MA_SUPPORT_WASAPI
2218 struct
2219 {
2220 ma_thread commandThread;
2221 ma_mutex commandLock;
2222 ma_semaphore commandSem;
2223 ma_uint32 commandIndex;
2224 ma_uint32 commandCount;
2225 ma_context_command__wasapi commands[4];
2226 } wasapi;
2227 #endif
2228 #ifdef MA_SUPPORT_DSOUND
2229 struct
2230 {
2231 ma_handle hDSoundDLL;
2232 ma_proc DirectSoundCreate;
2233 ma_proc DirectSoundEnumerateA;
2234 ma_proc DirectSoundCaptureCreate;
2235 ma_proc DirectSoundCaptureEnumerateA;
2236 } dsound;
2237 #endif
2238 #ifdef MA_SUPPORT_WINMM
2239 struct
2240 {
2241 ma_handle hWinMM;
2242 ma_proc waveOutGetNumDevs;
2243 ma_proc waveOutGetDevCapsA;
2244 ma_proc waveOutOpen;
2245 ma_proc waveOutClose;
2246 ma_proc waveOutPrepareHeader;
2247 ma_proc waveOutUnprepareHeader;
2248 ma_proc waveOutWrite;
2249 ma_proc waveOutReset;
2250 ma_proc waveInGetNumDevs;
2251 ma_proc waveInGetDevCapsA;
2252 ma_proc waveInOpen;
2253 ma_proc waveInClose;
2254 ma_proc waveInPrepareHeader;
2255 ma_proc waveInUnprepareHeader;
2256 ma_proc waveInAddBuffer;
2257 ma_proc waveInStart;
2258 ma_proc waveInReset;
2259 } winmm;
2260 #endif
2261 #ifdef MA_SUPPORT_ALSA
2262 struct
2263 {
2264 ma_handle asoundSO;
2265 ma_proc snd_pcm_open;
2266 ma_proc snd_pcm_close;
2267 ma_proc snd_pcm_hw_params_sizeof;
2268 ma_proc snd_pcm_hw_params_any;
2269 ma_proc snd_pcm_hw_params_set_format;
2270 ma_proc snd_pcm_hw_params_set_format_first;
2271 ma_proc snd_pcm_hw_params_get_format_mask;
2272 ma_proc snd_pcm_hw_params_set_channels;
2273 ma_proc snd_pcm_hw_params_set_channels_near;
2274 ma_proc snd_pcm_hw_params_set_channels_minmax;
2275 ma_proc snd_pcm_hw_params_set_rate_resample;
2276 ma_proc snd_pcm_hw_params_set_rate;
2277 ma_proc snd_pcm_hw_params_set_rate_near;
2278 ma_proc snd_pcm_hw_params_set_buffer_size_near;
2279 ma_proc snd_pcm_hw_params_set_periods_near;
2280 ma_proc snd_pcm_hw_params_set_access;
2281 ma_proc snd_pcm_hw_params_get_format;
2282 ma_proc snd_pcm_hw_params_get_channels;
2283 ma_proc snd_pcm_hw_params_get_channels_min;
2284 ma_proc snd_pcm_hw_params_get_channels_max;
2285 ma_proc snd_pcm_hw_params_get_rate;
2286 ma_proc snd_pcm_hw_params_get_rate_min;
2287 ma_proc snd_pcm_hw_params_get_rate_max;
2288 ma_proc snd_pcm_hw_params_get_buffer_size;
2289 ma_proc snd_pcm_hw_params_get_periods;
2290 ma_proc snd_pcm_hw_params_get_access;
2291 ma_proc snd_pcm_hw_params_test_format;
2292 ma_proc snd_pcm_hw_params_test_channels;
2293 ma_proc snd_pcm_hw_params_test_rate;
2294 ma_proc snd_pcm_hw_params;
2295 ma_proc snd_pcm_sw_params_sizeof;
2296 ma_proc snd_pcm_sw_params_current;
2297 ma_proc snd_pcm_sw_params_get_boundary;
2298 ma_proc snd_pcm_sw_params_set_avail_min;
2299 ma_proc snd_pcm_sw_params_set_start_threshold;
2300 ma_proc snd_pcm_sw_params_set_stop_threshold;
2301 ma_proc snd_pcm_sw_params;
2302 ma_proc snd_pcm_format_mask_sizeof;
2303 ma_proc snd_pcm_format_mask_test;
2304 ma_proc snd_pcm_get_chmap;
2305 ma_proc snd_pcm_state;
2306 ma_proc snd_pcm_prepare;
2307 ma_proc snd_pcm_start;
2308 ma_proc snd_pcm_drop;
2309 ma_proc snd_pcm_drain;
2310 ma_proc snd_pcm_reset;
2311 ma_proc snd_device_name_hint;
2312 ma_proc snd_device_name_get_hint;
2313 ma_proc snd_card_get_index;
2314 ma_proc snd_device_name_free_hint;
2315 ma_proc snd_pcm_mmap_begin;
2316 ma_proc snd_pcm_mmap_commit;
2317 ma_proc snd_pcm_recover;
2318 ma_proc snd_pcm_readi;
2319 ma_proc snd_pcm_writei;
2320 ma_proc snd_pcm_avail;
2321 ma_proc snd_pcm_avail_update;
2322 ma_proc snd_pcm_wait;
2323 ma_proc snd_pcm_nonblock;
2324 ma_proc snd_pcm_info;
2325 ma_proc snd_pcm_info_sizeof;
2326 ma_proc snd_pcm_info_get_name;
2327 ma_proc snd_pcm_poll_descriptors;
2328 ma_proc snd_pcm_poll_descriptors_count;
2329 ma_proc snd_pcm_poll_descriptors_revents;
2330 ma_proc snd_config_update_free_global;
2331
2332 ma_mutex internalDeviceEnumLock;
2333 ma_bool32 useVerboseDeviceEnumeration;
2334 } alsa;
2335 #endif
2336 #ifdef MA_SUPPORT_PULSEAUDIO
2337 struct
2338 {
2339 ma_handle pulseSO;
2340 ma_proc pa_mainloop_new;
2341 ma_proc pa_mainloop_free;
2342 ma_proc pa_mainloop_quit;
2343 ma_proc pa_mainloop_get_api;
2344 ma_proc pa_mainloop_iterate;
2345 ma_proc pa_mainloop_wakeup;
2346 ma_proc pa_threaded_mainloop_new;
2347 ma_proc pa_threaded_mainloop_free;
2348 ma_proc pa_threaded_mainloop_start;
2349 ma_proc pa_threaded_mainloop_stop;
2350 ma_proc pa_threaded_mainloop_lock;
2351 ma_proc pa_threaded_mainloop_unlock;
2352 ma_proc pa_threaded_mainloop_wait;
2353 ma_proc pa_threaded_mainloop_signal;
2354 ma_proc pa_threaded_mainloop_accept;
2355 ma_proc pa_threaded_mainloop_get_retval;
2356 ma_proc pa_threaded_mainloop_get_api;
2357 ma_proc pa_threaded_mainloop_in_thread;
2358 ma_proc pa_threaded_mainloop_set_name;
2359 ma_proc pa_context_new;
2360 ma_proc pa_context_unref;
2361 ma_proc pa_context_connect;
2362 ma_proc pa_context_disconnect;
2363 ma_proc pa_context_set_state_callback;
2364 ma_proc pa_context_get_state;
2365 ma_proc pa_context_get_sink_info_list;
2366 ma_proc pa_context_get_source_info_list;
2367 ma_proc pa_context_get_sink_info_by_name;
2368 ma_proc pa_context_get_source_info_by_name;
2369 ma_proc pa_operation_unref;
2370 ma_proc pa_operation_get_state;
2371 ma_proc pa_channel_map_init_extend;
2372 ma_proc pa_channel_map_valid;
2373 ma_proc pa_channel_map_compatible;
2374 ma_proc pa_stream_new;
2375 ma_proc pa_stream_unref;
2376 ma_proc pa_stream_connect_playback;
2377 ma_proc pa_stream_connect_record;
2378 ma_proc pa_stream_disconnect;
2379 ma_proc pa_stream_get_state;
2380 ma_proc pa_stream_get_sample_spec;
2381 ma_proc pa_stream_get_channel_map;
2382 ma_proc pa_stream_get_buffer_attr;
2383 ma_proc pa_stream_set_buffer_attr;
2384 ma_proc pa_stream_get_device_name;
2385 ma_proc pa_stream_set_write_callback;
2386 ma_proc pa_stream_set_read_callback;
2387 ma_proc pa_stream_set_suspended_callback;
2388 ma_proc pa_stream_is_suspended;
2389 ma_proc pa_stream_flush;
2390 ma_proc pa_stream_drain;
2391 ma_proc pa_stream_is_corked;
2392 ma_proc pa_stream_cork;
2393 ma_proc pa_stream_trigger;
2394 ma_proc pa_stream_begin_write;
2395 ma_proc pa_stream_write;
2396 ma_proc pa_stream_peek;
2397 ma_proc pa_stream_drop;
2398 ma_proc pa_stream_writable_size;
2399 ma_proc pa_stream_readable_size;
2400
2401 /*pa_mainloop**/ ma_ptr pMainLoop;
2402 /*pa_context**/ ma_ptr pPulseContext;
2403 } pulse;
2404 #endif
2405 #ifdef MA_SUPPORT_JACK
2406 struct
2407 {
2408 ma_handle jackSO;
2409 ma_proc jack_client_open;
2410 ma_proc jack_client_close;
2411 ma_proc jack_client_name_size;
2412 ma_proc jack_set_process_callback;
2413 ma_proc jack_set_buffer_size_callback;
2414 ma_proc jack_on_shutdown;
2415 ma_proc jack_get_sample_rate;
2416 ma_proc jack_get_buffer_size;
2417 ma_proc jack_get_ports;
2418 ma_proc jack_activate;
2419 ma_proc jack_deactivate;
2420 ma_proc jack_connect;
2421 ma_proc jack_port_register;
2422 ma_proc jack_port_name;
2423 ma_proc jack_port_get_buffer;
2424 ma_proc jack_free;
2425
2426 char* pClientName;
2427 ma_bool32 tryStartServer;
2428 } jack;
2429 #endif
2430 #ifdef MA_SUPPORT_COREAUDIO
2431 struct
2432 {
2433 ma_handle hCoreFoundation;
2434 ma_proc CFStringGetCString;
2435 ma_proc CFRelease;
2436
2437 ma_handle hCoreAudio;
2438 ma_proc AudioObjectGetPropertyData;
2439 ma_proc AudioObjectGetPropertyDataSize;
2440 ma_proc AudioObjectSetPropertyData;
2441 ma_proc AudioObjectAddPropertyListener;
2442 ma_proc AudioObjectRemovePropertyListener;
2443
2444 ma_handle hAudioUnit; /* Could possibly be set to AudioToolbox on later versions of macOS. */
2445 ma_proc AudioComponentFindNext;
2446 ma_proc AudioComponentInstanceDispose;
2447 ma_proc AudioComponentInstanceNew;
2448 ma_proc AudioOutputUnitStart;
2449 ma_proc AudioOutputUnitStop;
2450 ma_proc AudioUnitAddPropertyListener;
2451 ma_proc AudioUnitGetPropertyInfo;
2452 ma_proc AudioUnitGetProperty;
2453 ma_proc AudioUnitSetProperty;
2454 ma_proc AudioUnitInitialize;
2455 ma_proc AudioUnitRender;
2456
2457 /*AudioComponent*/ ma_ptr component;
2458 ma_bool32 noAudioSessionDeactivate; /* For tracking whether or not the iOS audio session should be explicitly deactivated. Set from the config in ma_context_init__coreaudio(). */
2459 } coreaudio;
2460 #endif
2461 #ifdef MA_SUPPORT_SNDIO
2462 struct
2463 {
2464 ma_handle sndioSO;
2465 ma_proc sio_open;
2466 ma_proc sio_close;
2467 ma_proc sio_setpar;
2468 ma_proc sio_getpar;
2469 ma_proc sio_getcap;
2470 ma_proc sio_start;
2471 ma_proc sio_stop;
2472 ma_proc sio_read;
2473 ma_proc sio_write;
2474 ma_proc sio_onmove;
2475 ma_proc sio_nfds;
2476 ma_proc sio_pollfd;
2477 ma_proc sio_revents;
2478 ma_proc sio_eof;
2479 ma_proc sio_setvol;
2480 ma_proc sio_onvol;
2481 ma_proc sio_initpar;
2482 } sndio;
2483 #endif
2484 #ifdef MA_SUPPORT_AUDIO4
2485 struct
2486 {
2487 int _unused;
2488 } audio4;
2489 #endif
2490 #ifdef MA_SUPPORT_OSS
2491 struct
2492 {
2493 int versionMajor;
2494 int versionMinor;
2495 } oss;
2496 #endif
2497 #ifdef MA_SUPPORT_AAUDIO
2498 struct
2499 {
2500 ma_handle hAAudio; /* libaaudio.so */
2501 ma_proc AAudio_createStreamBuilder;
2502 ma_proc AAudioStreamBuilder_delete;
2503 ma_proc AAudioStreamBuilder_setDeviceId;
2504 ma_proc AAudioStreamBuilder_setDirection;
2505 ma_proc AAudioStreamBuilder_setSharingMode;
2506 ma_proc AAudioStreamBuilder_setFormat;
2507 ma_proc AAudioStreamBuilder_setChannelCount;
2508 ma_proc AAudioStreamBuilder_setSampleRate;
2509 ma_proc AAudioStreamBuilder_setBufferCapacityInFrames;
2510 ma_proc AAudioStreamBuilder_setFramesPerDataCallback;
2511 ma_proc AAudioStreamBuilder_setDataCallback;
2512 ma_proc AAudioStreamBuilder_setErrorCallback;
2513 ma_proc AAudioStreamBuilder_setPerformanceMode;
2514 ma_proc AAudioStreamBuilder_setUsage;
2515 ma_proc AAudioStreamBuilder_setContentType;
2516 ma_proc AAudioStreamBuilder_setInputPreset;
2517 ma_proc AAudioStreamBuilder_openStream;
2518 ma_proc AAudioStream_close;
2519 ma_proc AAudioStream_getState;
2520 ma_proc AAudioStream_waitForStateChange;
2521 ma_proc AAudioStream_getFormat;
2522 ma_proc AAudioStream_getChannelCount;
2523 ma_proc AAudioStream_getSampleRate;
2524 ma_proc AAudioStream_getBufferCapacityInFrames;
2525 ma_proc AAudioStream_getFramesPerDataCallback;
2526 ma_proc AAudioStream_getFramesPerBurst;
2527 ma_proc AAudioStream_requestStart;
2528 ma_proc AAudioStream_requestStop;
2529 } aaudio;
2530 #endif
2531 #ifdef MA_SUPPORT_OPENSL
2532 struct
2533 {
2534 ma_handle libOpenSLES;
2535 ma_handle SL_IID_ENGINE;
2536 ma_handle SL_IID_AUDIOIODEVICECAPABILITIES;
2537 ma_handle SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
2538 ma_handle SL_IID_RECORD;
2539 ma_handle SL_IID_PLAY;
2540 ma_handle SL_IID_OUTPUTMIX;
2541 ma_handle SL_IID_ANDROIDCONFIGURATION;
2542 ma_proc slCreateEngine;
2543 } opensl;
2544 #endif
2545 #ifdef MA_SUPPORT_WEBAUDIO
2546 struct
2547 {
2548 int _unused;
2549 } webaudio;
2550 #endif
2551 #ifdef MA_SUPPORT_NULL
2552 struct
2553 {
2554 int _unused;
2555 } null_backend;
2556 #endif
2557 };
2558
2559 union
2560 {
2561 #ifdef MA_WIN32
2562 struct
2563 {
2564 /*HMODULE*/ ma_handle hOle32DLL;
2565 ma_proc CoInitializeEx;
2566 ma_proc CoUninitialize;
2567 ma_proc CoCreateInstance;
2568 ma_proc CoTaskMemFree;
2569 ma_proc PropVariantClear;
2570 ma_proc StringFromGUID2;
2571
2572 /*HMODULE*/ ma_handle hUser32DLL;
2573 ma_proc GetForegroundWindow;
2574 ma_proc GetDesktopWindow;
2575
2576 /*HMODULE*/ ma_handle hAdvapi32DLL;
2577 ma_proc RegOpenKeyExA;
2578 ma_proc RegCloseKey;
2579 ma_proc RegQueryValueExA;
2580 } win32;
2581 #endif
2582 #ifdef MA_POSIX
2583 struct
2584 {
2585 ma_handle pthreadSO;
2586 ma_proc pthread_create;
2587 ma_proc pthread_join;
2588 ma_proc pthread_mutex_init;
2589 ma_proc pthread_mutex_destroy;
2590 ma_proc pthread_mutex_lock;
2591 ma_proc pthread_mutex_unlock;
2592 ma_proc pthread_cond_init;
2593 ma_proc pthread_cond_destroy;
2594 ma_proc pthread_cond_wait;
2595 ma_proc pthread_cond_signal;
2596 ma_proc pthread_attr_init;
2597 ma_proc pthread_attr_destroy;
2598 ma_proc pthread_attr_setschedpolicy;
2599 ma_proc pthread_attr_getschedparam;
2600 ma_proc pthread_attr_setschedparam;
2601 } posix;
2602 #endif
2603 int _unused;
2604 };
2605 };
2606
2607 struct ma_device
2608 {
2609 ma_context* pContext;
2610 ma_device_type type;
2611 ma_uint32 sampleRate;
2612 MA_ATOMIC ma_uint32 state; /* The state of the device is variable and can change at any time on any thread. Must be used atomically. */
2613 ma_device_callback_proc onData; /* Set once at initialization time and should not be changed after. */
2614 ma_stop_proc onStop; /* Set once at initialization time and should not be changed after. */
2615 void* pUserData; /* Application defined data. */
2616 ma_mutex startStopLock;
2617 ma_event wakeupEvent;
2618 ma_event startEvent;
2619 ma_event stopEvent;
2620 ma_thread thread;
2621 ma_result workResult; /* This is set by the worker thread after it's finished doing a job. */
2622 ma_bool8 isOwnerOfContext; /* When set to true, uninitializing the device will also uninitialize the context. Set to true when NULL is passed into ma_device_init(). */
2623 ma_bool8 noPreZeroedOutputBuffer;
2624 ma_bool8 noClip;
2625 MA_ATOMIC float masterVolumeFactor; /* Linear 0..1. Can be read and written simultaneously by different threads. Must be used atomically. */
2626 ma_duplex_rb duplexRB; /* Intermediary buffer for duplex device on asynchronous backends. */
2627 struct
2628 {
2629 ma_resample_algorithm algorithm;
2630 struct
2631 {
2632 ma_uint32 lpfOrder;
2633 } linear;
2634 struct
2635 {
2636 int quality;
2637 } speex;
2638 } resampling;
2639 struct
2640 {
2641 ma_device_id id; /* If using an explicit device, will be set to a copy of the ID used for initialization. Otherwise cleared to 0. */
2642 char name[256]; /* Maybe temporary. Likely to be replaced with a query API. */
2643 ma_share_mode shareMode; /* Set to whatever was passed in when the device was initialized. */
2644 ma_format format;
2645 ma_uint32 channels;
2646 ma_channel channelMap[MA_MAX_CHANNELS];
2647 ma_format internalFormat;
2648 ma_uint32 internalChannels;
2649 ma_uint32 internalSampleRate;
2650 ma_channel internalChannelMap[MA_MAX_CHANNELS];
2651 ma_uint32 internalPeriodSizeInFrames;
2652 ma_uint32 internalPeriods;
2653 ma_channel_mix_mode channelMixMode;
2654 ma_data_converter converter;
2655 } playback;
2656 struct
2657 {
2658 ma_device_id id; /* If using an explicit device, will be set to a copy of the ID used for initialization. Otherwise cleared to 0. */
2659 char name[256]; /* Maybe temporary. Likely to be replaced with a query API. */
2660 ma_share_mode shareMode; /* Set to whatever was passed in when the device was initialized. */
2661 ma_format format;
2662 ma_uint32 channels;
2663 ma_channel channelMap[MA_MAX_CHANNELS];
2664 ma_format internalFormat;
2665 ma_uint32 internalChannels;
2666 ma_uint32 internalSampleRate;
2667 ma_channel internalChannelMap[MA_MAX_CHANNELS];
2668 ma_uint32 internalPeriodSizeInFrames;
2669 ma_uint32 internalPeriods;
2670 ma_channel_mix_mode channelMixMode;
2671 ma_data_converter converter;
2672 } capture;
2673
2674 union
2675 {
2676 #ifdef MA_SUPPORT_WASAPI
2677 struct
2678 {
2679 /*IAudioClient**/ ma_ptr pAudioClientPlayback;
2680 /*IAudioClient**/ ma_ptr pAudioClientCapture;
2681 /*IAudioRenderClient**/ ma_ptr pRenderClient;
2682 /*IAudioCaptureClient**/ ma_ptr pCaptureClient;
2683 /*IMMDeviceEnumerator**/ ma_ptr pDeviceEnumerator; /* Used for IMMNotificationClient notifications. Required for detecting default device changes. */
2684 ma_IMMNotificationClient notificationClient;
2685 /*HANDLE*/ ma_handle hEventPlayback; /* Auto reset. Initialized to signaled. */
2686 /*HANDLE*/ ma_handle hEventCapture; /* Auto reset. Initialized to unsignaled. */
2687 ma_uint32 actualPeriodSizeInFramesPlayback; /* Value from GetBufferSize(). internalPeriodSizeInFrames is not set to the _actual_ buffer size when low-latency shared mode is being used due to the way the IAudioClient3 API works. */
2688 ma_uint32 actualPeriodSizeInFramesCapture;
2689 ma_uint32 originalPeriodSizeInFrames;
2690 ma_uint32 originalPeriodSizeInMilliseconds;
2691 ma_uint32 originalPeriods;
2692 ma_performance_profile originalPerformanceProfile;
2693 ma_uint32 periodSizeInFramesPlayback;
2694 ma_uint32 periodSizeInFramesCapture;
2695 MA_ATOMIC ma_bool32 isStartedCapture; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
2696 MA_ATOMIC ma_bool32 isStartedPlayback; /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
2697 ma_bool8 noAutoConvertSRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
2698 ma_bool8 noDefaultQualitySRC; /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */
2699 ma_bool8 noHardwareOffloading;
2700 ma_bool8 allowCaptureAutoStreamRouting;
2701 ma_bool8 allowPlaybackAutoStreamRouting;
2702 ma_bool8 isDetachedPlayback;
2703 ma_bool8 isDetachedCapture;
2704 } wasapi;
2705 #endif
2706 #ifdef MA_SUPPORT_DSOUND
2707 struct
2708 {
2709 /*LPDIRECTSOUND*/ ma_ptr pPlayback;
2710 /*LPDIRECTSOUNDBUFFER*/ ma_ptr pPlaybackPrimaryBuffer;
2711 /*LPDIRECTSOUNDBUFFER*/ ma_ptr pPlaybackBuffer;
2712 /*LPDIRECTSOUNDCAPTURE*/ ma_ptr pCapture;
2713 /*LPDIRECTSOUNDCAPTUREBUFFER*/ ma_ptr pCaptureBuffer;
2714 } dsound;
2715 #endif
2716 #ifdef MA_SUPPORT_WINMM
2717 struct
2718 {
2719 /*HWAVEOUT*/ ma_handle hDevicePlayback;
2720 /*HWAVEIN*/ ma_handle hDeviceCapture;
2721 /*HANDLE*/ ma_handle hEventPlayback;
2722 /*HANDLE*/ ma_handle hEventCapture;
2723 ma_uint32 fragmentSizeInFrames;
2724 ma_uint32 iNextHeaderPlayback; /* [0,periods). Used as an index into pWAVEHDRPlayback. */
2725 ma_uint32 iNextHeaderCapture; /* [0,periods). Used as an index into pWAVEHDRCapture. */
2726 ma_uint32 headerFramesConsumedPlayback; /* The number of PCM frames consumed in the buffer in pWAVEHEADER[iNextHeader]. */
2727 ma_uint32 headerFramesConsumedCapture; /* ^^^ */
2728 /*WAVEHDR**/ ma_uint8* pWAVEHDRPlayback; /* One instantiation for each period. */
2729 /*WAVEHDR**/ ma_uint8* pWAVEHDRCapture; /* One instantiation for each period. */
2730 ma_uint8* pIntermediaryBufferPlayback;
2731 ma_uint8* pIntermediaryBufferCapture;
2732 ma_uint8* _pHeapData; /* Used internally and is used for the heap allocated data for the intermediary buffer and the WAVEHDR structures. */
2733 } winmm;
2734 #endif
2735 #ifdef MA_SUPPORT_ALSA
2736 struct
2737 {
2738 /*snd_pcm_t**/ ma_ptr pPCMPlayback;
2739 /*snd_pcm_t**/ ma_ptr pPCMCapture;
2740 /*struct pollfd**/ void* pPollDescriptorsPlayback;
2741 /*struct pollfd**/ void* pPollDescriptorsCapture;
2742 int pollDescriptorCountPlayback;
2743 int pollDescriptorCountCapture;
2744 int wakeupfdPlayback; /* eventfd for waking up from poll() when the playback device is stopped. */
2745 int wakeupfdCapture; /* eventfd for waking up from poll() when the capture device is stopped. */
2746 ma_bool8 isUsingMMapPlayback;
2747 ma_bool8 isUsingMMapCapture;
2748 } alsa;
2749 #endif
2750 #ifdef MA_SUPPORT_PULSEAUDIO
2751 struct
2752 {
2753 /*pa_stream**/ ma_ptr pStreamPlayback;
2754 /*pa_stream**/ ma_ptr pStreamCapture;
2755 } pulse;
2756 #endif
2757 #ifdef MA_SUPPORT_JACK
2758 struct
2759 {
2760 /*jack_client_t**/ ma_ptr pClient;
2761 /*jack_port_t**/ ma_ptr pPortsPlayback[MA_MAX_CHANNELS];
2762 /*jack_port_t**/ ma_ptr pPortsCapture[MA_MAX_CHANNELS];
2763 float* pIntermediaryBufferPlayback; /* Typed as a float because JACK is always floating point. */
2764 float* pIntermediaryBufferCapture;
2765 } jack;
2766 #endif
2767 #ifdef MA_SUPPORT_COREAUDIO
2768 struct
2769 {
2770 ma_uint32 deviceObjectIDPlayback;
2771 ma_uint32 deviceObjectIDCapture;
2772 /*AudioUnit*/ ma_ptr audioUnitPlayback;
2773 /*AudioUnit*/ ma_ptr audioUnitCapture;
2774 /*AudioBufferList**/ ma_ptr pAudioBufferList; /* Only used for input devices. */
2775 ma_uint32 audioBufferCapInFrames; /* Only used for input devices. The capacity in frames of each buffer in pAudioBufferList. */
2776 ma_event stopEvent;
2777 ma_uint32 originalPeriodSizeInFrames;
2778 ma_uint32 originalPeriodSizeInMilliseconds;
2779 ma_uint32 originalPeriods;
2780 ma_performance_profile originalPerformanceProfile;
2781 ma_bool32 isDefaultPlaybackDevice;
2782 ma_bool32 isDefaultCaptureDevice;
2783 ma_bool32 isSwitchingPlaybackDevice; /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
2784 ma_bool32 isSwitchingCaptureDevice; /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
2785 void* pRouteChangeHandler; /* Only used on mobile platforms. Obj-C object for handling route changes. */
2786 } coreaudio;
2787 #endif
2788 #ifdef MA_SUPPORT_SNDIO
2789 struct
2790 {
2791 ma_ptr handlePlayback;
2792 ma_ptr handleCapture;
2793 ma_bool32 isStartedPlayback;
2794 ma_bool32 isStartedCapture;
2795 } sndio;
2796 #endif
2797 #ifdef MA_SUPPORT_AUDIO4
2798 struct
2799 {
2800 int fdPlayback;
2801 int fdCapture;
2802 } audio4;
2803 #endif
2804 #ifdef MA_SUPPORT_OSS
2805 struct
2806 {
2807 int fdPlayback;
2808 int fdCapture;
2809 } oss;
2810 #endif
2811 #ifdef MA_SUPPORT_AAUDIO
2812 struct
2813 {
2814 /*AAudioStream**/ ma_ptr pStreamPlayback;
2815 /*AAudioStream**/ ma_ptr pStreamCapture;
2816 } aaudio;
2817 #endif
2818 #ifdef MA_SUPPORT_OPENSL
2819 struct
2820 {
2821 /*SLObjectItf*/ ma_ptr pOutputMixObj;
2822 /*SLOutputMixItf*/ ma_ptr pOutputMix;
2823 /*SLObjectItf*/ ma_ptr pAudioPlayerObj;
2824 /*SLPlayItf*/ ma_ptr pAudioPlayer;
2825 /*SLObjectItf*/ ma_ptr pAudioRecorderObj;
2826 /*SLRecordItf*/ ma_ptr pAudioRecorder;
2827 /*SLAndroidSimpleBufferQueueItf*/ ma_ptr pBufferQueuePlayback;
2828 /*SLAndroidSimpleBufferQueueItf*/ ma_ptr pBufferQueueCapture;
2829 ma_bool32 isDrainingCapture;
2830 ma_bool32 isDrainingPlayback;
2831 ma_uint32 currentBufferIndexPlayback;
2832 ma_uint32 currentBufferIndexCapture;
2833 ma_uint8* pBufferPlayback; /* This is malloc()'d and is used for storing audio data. Typed as ma_uint8 for easy offsetting. */
2834 ma_uint8* pBufferCapture;
2835 } opensl;
2836 #endif
2837 #ifdef MA_SUPPORT_WEBAUDIO
2838 struct
2839 {
2840 int indexPlayback; /* We use a factory on the JavaScript side to manage devices and use an index for JS/C interop. */
2841 int indexCapture;
2842 } webaudio;
2843 #endif
2844 #ifdef MA_SUPPORT_NULL
2845 struct
2846 {
2847 ma_thread deviceThread;
2848 ma_event operationEvent;
2849 ma_event operationCompletionEvent;
2850 ma_semaphore operationSemaphore;
2851 ma_uint32 operation;
2852 ma_result operationResult;
2853 ma_timer timer;
2854 double priorRunTime;
2855 ma_uint32 currentPeriodFramesRemainingPlayback;
2856 ma_uint32 currentPeriodFramesRemainingCapture;
2857 ma_uint64 lastProcessedFramePlayback;
2858 ma_uint64 lastProcessedFrameCapture;
2859 MA_ATOMIC ma_bool32 isStarted; /* Read and written by multiple threads. Must be used atomically, and must be 32-bit for compiler compatibility. */
2860 } null_device;
2861 #endif
2862 };
2863 };
2864 #if defined(_MSC_VER) && !defined(__clang__)
2865 #pragma warning(pop)
2866 #elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
2867 #pragma GCC diagnostic pop /* For ISO C99 doesn't support unnamed structs/unions [-Wpedantic] */
2868 #endif
2869
2870 /*
2871 Initializes a `ma_context_config` object.
2872
2873
2874 Return Value
2875 ------------
2876 A `ma_context_config` initialized to defaults.
2877
2878
2879 Remarks
2880 -------
2881 You must always use this to initialize the default state of the `ma_context_config` object. Not using this will result in your program breaking when miniaudio
2882 is updated and new members are added to `ma_context_config`. It also sets logical defaults.
2883
2884 You can override members of the returned object by changing it's members directly.
2885
2886
2887 See Also
2888 --------
2889 ma_context_init()
2890 */
2891 MA_API ma_context_config ma_context_config_init(void);
2892
2893 /*
2894 Initializes a context.
2895
2896 The context is used for selecting and initializing an appropriate backend and to represent the backend at a more global level than that of an individual
2897 device. There is one context to many devices, and a device is created from a context. A context is required to enumerate devices.
2898
2899
2900 Parameters
2901 ----------
2902 backends (in, optional)
2903 A list of backends to try initializing, in priority order. Can be NULL, in which case it uses default priority order.
2904
2905 backendCount (in, optional)
2906 The number of items in `backend`. Ignored if `backend` is NULL.
2907
2908 pConfig (in, optional)
2909 The context configuration.
2910
2911 pContext (in)
2912 A pointer to the context object being initialized.
2913
2914
2915 Return Value
2916 ------------
2917 MA_SUCCESS if successful; any other error code otherwise.
2918
2919
2920 Thread Safety
2921 -------------
2922 Unsafe. Do not call this function across multiple threads as some backends read and write to global state.
2923
2924
2925 Remarks
2926 -------
2927 When `backends` is NULL, the default priority order will be used. Below is a list of backends in priority order:
2928
2929 |-------------|-----------------------|--------------------------------------------------------|
2930 | Name | Enum Name | Supported Operating Systems |
2931 |-------------|-----------------------|--------------------------------------------------------|
2932 | WASAPI | ma_backend_wasapi | Windows Vista+ |
2933 | DirectSound | ma_backend_dsound | Windows XP+ |
2934 | WinMM | ma_backend_winmm | Windows XP+ (may work on older versions, but untested) |
2935 | Core Audio | ma_backend_coreaudio | macOS, iOS |
2936 | ALSA | ma_backend_alsa | Linux |
2937 | PulseAudio | ma_backend_pulseaudio | Cross Platform (disabled on Windows, BSD and Android) |
2938 | JACK | ma_backend_jack | Cross Platform (disabled on BSD and Android) |
2939 | sndio | ma_backend_sndio | OpenBSD |
2940 | audio(4) | ma_backend_audio4 | NetBSD, OpenBSD |
2941 | OSS | ma_backend_oss | FreeBSD |
2942 | AAudio | ma_backend_aaudio | Android 8+ |
2943 | OpenSL|ES | ma_backend_opensl | Android (API level 16+) |
2944 | Web Audio | ma_backend_webaudio | Web (via Emscripten) |
2945 | Null | ma_backend_null | Cross Platform (not used on Web) |
2946 |-------------|-----------------------|--------------------------------------------------------|
2947
2948 The context can be configured via the `pConfig` argument. The config object is initialized with `ma_context_config_init()`. Individual configuration settings
2949 can then be set directly on the structure. Below are the members of the `ma_context_config` object.
2950
2951 pLog
2952 A pointer to the `ma_log` to post log messages to. Can be NULL if the application does not
2953 require logging. See the `ma_log` API for details on how to use the logging system.
2954
2955 threadPriority
2956 The desired priority to use for the audio thread. Allowable values include the following:
2957
2958 |--------------------------------------|
2959 | Thread Priority |
2960 |--------------------------------------|
2961 | ma_thread_priority_idle |
2962 | ma_thread_priority_lowest |
2963 | ma_thread_priority_low |
2964 | ma_thread_priority_normal |
2965 | ma_thread_priority_high |
2966 | ma_thread_priority_highest (default) |
2967 | ma_thread_priority_realtime |
2968 | ma_thread_priority_default |
2969 |--------------------------------------|
2970
2971 pUserData
2972 A pointer to application-defined data. This can be accessed from the context object directly such as `context.pUserData`.
2973
2974 allocationCallbacks
2975 Structure containing custom allocation callbacks. Leaving this at defaults will cause it to use MA_MALLOC, MA_REALLOC and MA_FREE. These allocation
2976 callbacks will be used for anything tied to the context, including devices.
2977
2978 alsa.useVerboseDeviceEnumeration
2979 ALSA will typically enumerate many different devices which can be intrusive and not user-friendly. To combat this, miniaudio will enumerate only unique
2980 card/device pairs by default. The problem with this is that you lose a bit of flexibility and control. Setting alsa.useVerboseDeviceEnumeration makes
2981 it so the ALSA backend includes all devices. Defaults to false.
2982
2983 pulse.pApplicationName
2984 PulseAudio only. The application name to use when initializing the PulseAudio context with `pa_context_new()`.
2985
2986 pulse.pServerName
2987 PulseAudio only. The name of the server to connect to with `pa_context_connect()`.
2988
2989 pulse.tryAutoSpawn
2990 PulseAudio only. Whether or not to try automatically starting the PulseAudio daemon. Defaults to false. If you set this to true, keep in mind that
2991 miniaudio uses a trial and error method to find the most appropriate backend, and this will result in the PulseAudio daemon starting which may be
2992 intrusive for the end user.
2993
2994 coreaudio.sessionCategory
2995 iOS only. The session category to use for the shared AudioSession instance. Below is a list of allowable values and their Core Audio equivalents.
2996
2997 |-----------------------------------------|-------------------------------------|
2998 | miniaudio Token | Core Audio Token |
2999 |-----------------------------------------|-------------------------------------|
3000 | ma_ios_session_category_ambient | AVAudioSessionCategoryAmbient |
3001 | ma_ios_session_category_solo_ambient | AVAudioSessionCategorySoloAmbient |
3002 | ma_ios_session_category_playback | AVAudioSessionCategoryPlayback |
3003 | ma_ios_session_category_record | AVAudioSessionCategoryRecord |
3004 | ma_ios_session_category_play_and_record | AVAudioSessionCategoryPlayAndRecord |
3005 | ma_ios_session_category_multi_route | AVAudioSessionCategoryMultiRoute |
3006 | ma_ios_session_category_none | AVAudioSessionCategoryAmbient |
3007 | ma_ios_session_category_default | AVAudioSessionCategoryAmbient |
3008 |-----------------------------------------|-------------------------------------|
3009
3010 coreaudio.sessionCategoryOptions
3011 iOS only. Session category options to use with the shared AudioSession instance. Below is a list of allowable values and their Core Audio equivalents.
3012
3013 |---------------------------------------------------------------------------|------------------------------------------------------------------|
3014 | miniaudio Token | Core Audio Token |
3015 |---------------------------------------------------------------------------|------------------------------------------------------------------|
3016 | ma_ios_session_category_option_mix_with_others | AVAudioSessionCategoryOptionMixWithOthers |
3017 | ma_ios_session_category_option_duck_others | AVAudioSessionCategoryOptionDuckOthers |
3018 | ma_ios_session_category_option_allow_bluetooth | AVAudioSessionCategoryOptionAllowBluetooth |
3019 | ma_ios_session_category_option_default_to_speaker | AVAudioSessionCategoryOptionDefaultToSpeaker |
3020 | ma_ios_session_category_option_interrupt_spoken_audio_and_mix_with_others | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers |
3021 | ma_ios_session_category_option_allow_bluetooth_a2dp | AVAudioSessionCategoryOptionAllowBluetoothA2DP |
3022 | ma_ios_session_category_option_allow_air_play | AVAudioSessionCategoryOptionAllowAirPlay |
3023 |---------------------------------------------------------------------------|------------------------------------------------------------------|
3024
3025 jack.pClientName
3026 The name of the client to pass to `jack_client_open()`.
3027
3028 jack.tryStartServer
3029 Whether or not to try auto-starting the JACK server. Defaults to false.
3030
3031
3032 It is recommended that only a single context is active at any given time because it's a bulky data structure which performs run-time linking for the
3033 relevant backends every time it's initialized.
3034
3035 The location of the context cannot change throughout it's lifetime. Consider allocating the `ma_context` object with `malloc()` if this is an issue. The
3036 reason for this is that a pointer to the context is stored in the `ma_device` structure.
3037
3038
3039 Example 1 - Default Initialization
3040 ----------------------------------
3041 The example below shows how to initialize the context using the default configuration.
3042
3043 ```c
3044 ma_context context;
3045 ma_result result = ma_context_init(NULL, 0, NULL, &context);
3046 if (result != MA_SUCCESS) {
3047 // Error.
3048 }
3049 ```
3050
3051
3052 Example 2 - Custom Configuration
3053 --------------------------------
3054 The example below shows how to initialize the context using custom backend priorities and a custom configuration. In this hypothetical example, the program
3055 wants to prioritize ALSA over PulseAudio on Linux. They also want to avoid using the WinMM backend on Windows because it's latency is too high. They also
3056 want an error to be returned if no valid backend is available which they achieve by excluding the Null backend.
3057
3058 For the configuration, the program wants to capture any log messages so they can, for example, route it to a log file and user interface.
3059
3060 ```c
3061 ma_backend backends[] = {
3062 ma_backend_alsa,
3063 ma_backend_pulseaudio,
3064 ma_backend_wasapi,
3065 ma_backend_dsound
3066 };
3067
3068 ma_context_config config = ma_context_config_init();
3069 config.logCallback = my_log_callback;
3070 config.pUserData = pMyUserData;
3071
3072 ma_context context;
3073 ma_result result = ma_context_init(backends, sizeof(backends)/sizeof(backends[0]), &config, &context);
3074 if (result != MA_SUCCESS) {
3075 // Error.
3076 if (result == MA_NO_BACKEND) {
3077 // Couldn't find an appropriate backend.
3078 }
3079 }
3080 ```
3081
3082
3083 See Also
3084 --------
3085 ma_context_config_init()
3086 ma_context_uninit()
3087 */
3088 MA_API ma_result ma_context_init(const ma_backend backends[], ma_uint32 backendCount, const ma_context_config* pConfig, ma_context* pContext);
3089
3090 /*
3091 Uninitializes a context.
3092
3093
3094 Return Value
3095 ------------
3096 MA_SUCCESS if successful; any other error code otherwise.
3097
3098
3099 Thread Safety
3100 -------------
3101 Unsafe. Do not call this function across multiple threads as some backends read and write to global state.
3102
3103
3104 Remarks
3105 -------
3106 Results are undefined if you call this while any device created by this context is still active.
3107
3108
3109 See Also
3110 --------
3111 ma_context_init()
3112 */
3113 MA_API ma_result ma_context_uninit(ma_context* pContext);
3114
3115 /*
3116 Retrieves the size of the ma_context object.
3117
3118 This is mainly for the purpose of bindings to know how much memory to allocate.
3119 */
3120 MA_API size_t ma_context_sizeof(void);
3121
3122 /*
3123 Retrieves a pointer to the log object associated with this context.
3124
3125
3126 Remarks
3127 -------
3128 Pass the returned pointer to `ma_log_post()`, `ma_log_postv()` or `ma_log_postf()` to post a log
3129 message.
3130
3131
3132 Return Value
3133 ------------
3134 A pointer to the `ma_log` object that the context uses to post log messages. If some error occurs,
3135 NULL will be returned.
3136 */
3137 MA_API ma_log* ma_context_get_log(ma_context* pContext);
3138
3139 /*
3140 Enumerates over every device (both playback and capture).
3141
3142 This is a lower-level enumeration function to the easier to use `ma_context_get_devices()`. Use `ma_context_enumerate_devices()` if you would rather not incur
3143 an internal heap allocation, or it simply suits your code better.
3144
3145 Note that this only retrieves the ID and name/description of the device. The reason for only retrieving basic information is that it would otherwise require
3146 opening the backend device in order to probe it for more detailed information which can be inefficient. Consider using `ma_context_get_device_info()` for this,
3147 but don't call it from within the enumeration callback.
3148
3149 Returning false from the callback will stop enumeration. Returning true will continue enumeration.
3150
3151
3152 Parameters
3153 ----------
3154 pContext (in)
3155 A pointer to the context performing the enumeration.
3156
3157 callback (in)
3158 The callback to fire for each enumerated device.
3159
3160 pUserData (in)
3161 A pointer to application-defined data passed to the callback.
3162
3163
3164 Return Value
3165 ------------
3166 MA_SUCCESS if successful; any other error code otherwise.
3167
3168
3169 Thread Safety
3170 -------------
3171 Safe. This is guarded using a simple mutex lock.
3172
3173
3174 Remarks
3175 -------
3176 Do _not_ assume the first enumerated device of a given type is the default device.
3177
3178 Some backends and platforms may only support default playback and capture devices.
3179
3180 In general, you should not do anything complicated from within the callback. In particular, do not try initializing a device from within the callback. Also,
3181 do not try to call `ma_context_get_device_info()` from within the callback.
3182
3183 Consider using `ma_context_get_devices()` for a simpler and safer API, albeit at the expense of an internal heap allocation.
3184
3185
3186 Example 1 - Simple Enumeration
3187 ------------------------------
3188 ma_bool32 ma_device_enum_callback(ma_context* pContext, ma_device_type deviceType, const ma_device_info* pInfo, void* pUserData)
3189 {
3190 printf("Device Name: %s\n", pInfo->name);
3191 return MA_TRUE;
3192 }
3193
3194 ma_result result = ma_context_enumerate_devices(&context, my_device_enum_callback, pMyUserData);
3195 if (result != MA_SUCCESS) {
3196 // Error.
3197 }
3198
3199
3200 See Also
3201 --------
3202 ma_context_get_devices()
3203 */
3204 MA_API ma_result ma_context_enumerate_devices(ma_context* pContext, ma_enum_devices_callback_proc callback, void* pUserData);
3205
3206 /*
3207 Retrieves basic information about every active playback and/or capture device.
3208
3209 This function will allocate memory internally for the device lists and return a pointer to them through the `ppPlaybackDeviceInfos` and `ppCaptureDeviceInfos`
3210 parameters. If you do not want to incur the overhead of these allocations consider using `ma_context_enumerate_devices()` which will instead use a callback.
3211
3212
3213 Parameters
3214 ----------
3215 pContext (in)
3216 A pointer to the context performing the enumeration.
3217
3218 ppPlaybackDeviceInfos (out)
3219 A pointer to a pointer that will receive the address of a buffer containing the list of `ma_device_info` structures for playback devices.
3220
3221 pPlaybackDeviceCount (out)
3222 A pointer to an unsigned integer that will receive the number of playback devices.
3223
3224 ppCaptureDeviceInfos (out)
3225 A pointer to a pointer that will receive the address of a buffer containing the list of `ma_device_info` structures for capture devices.
3226
3227 pCaptureDeviceCount (out)
3228 A pointer to an unsigned integer that will receive the number of capture devices.
3229
3230
3231 Return Value
3232 ------------
3233 MA_SUCCESS if successful; any other error code otherwise.
3234
3235
3236 Thread Safety
3237 -------------
3238 Unsafe. Since each call to this function invalidates the pointers from the previous call, you should not be calling this simultaneously across multiple
3239 threads. Instead, you need to make a copy of the returned data with your own higher level synchronization.
3240
3241
3242 Remarks
3243 -------
3244 It is _not_ safe to assume the first device in the list is the default device.
3245
3246 You can pass in NULL for the playback or capture lists in which case they'll be ignored.
3247
3248 The returned pointers will become invalid upon the next call this this function, or when the context is uninitialized. Do not free the returned pointers.
3249
3250
3251 See Also
3252 --------
3253 ma_context_get_devices()
3254 */
3255 MA_API ma_result ma_context_get_devices(ma_context* pContext, ma_device_info** ppPlaybackDeviceInfos, ma_uint32* pPlaybackDeviceCount, ma_device_info** ppCaptureDeviceInfos, ma_uint32* pCaptureDeviceCount);
3256
3257 /*
3258 Retrieves information about a device of the given type, with the specified ID and share mode.
3259
3260
3261 Parameters
3262 ----------
3263 pContext (in)
3264 A pointer to the context performing the query.
3265
3266 deviceType (in)
3267 The type of the device being queried. Must be either `ma_device_type_playback` or `ma_device_type_capture`.
3268
3269 pDeviceID (in)
3270 The ID of the device being queried.
3271
3272 shareMode (in)
3273 The share mode to query for device capabilities. This should be set to whatever you're intending on using when initializing the device. If you're unsure,
3274 set this to `ma_share_mode_shared`.
3275
3276 pDeviceInfo (out)
3277 A pointer to the `ma_device_info` structure that will receive the device information.
3278
3279
3280 Return Value
3281 ------------
3282 MA_SUCCESS if successful; any other error code otherwise.
3283
3284
3285 Thread Safety
3286 -------------
3287 Safe. This is guarded using a simple mutex lock.
3288
3289
3290 Remarks
3291 -------
3292 Do _not_ call this from within the `ma_context_enumerate_devices()` callback.
3293
3294 It's possible for a device to have different information and capabilities depending on whether or not it's opened in shared or exclusive mode. For example, in
3295 shared mode, WASAPI always uses floating point samples for mixing, but in exclusive mode it can be anything. Therefore, this function allows you to specify
3296 which share mode you want information for. Note that not all backends and devices support shared or exclusive mode, in which case this function will fail if
3297 the requested share mode is unsupported.
3298
3299 This leaves pDeviceInfo unmodified in the result of an error.
3300 */
3301 MA_API ma_result ma_context_get_device_info(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_share_mode shareMode, ma_device_info* pDeviceInfo);
3302
3303 /*
3304 Determines if the given context supports loopback mode.
3305
3306
3307 Parameters
3308 ----------
3309 pContext (in)
3310 A pointer to the context getting queried.
3311
3312
3313 Return Value
3314 ------------
3315 MA_TRUE if the context supports loopback mode; MA_FALSE otherwise.
3316 */
3317 MA_API ma_bool32 ma_context_is_loopback_supported(ma_context* pContext);
3318
3319
3320
3321 /*
3322 Initializes a device config with default settings.
3323
3324
3325 Parameters
3326 ----------
3327 deviceType (in)
3328 The type of the device this config is being initialized for. This must set to one of the following:
3329
3330 |-------------------------|
3331 | Device Type |
3332 |-------------------------|
3333 | ma_device_type_playback |
3334 | ma_device_type_capture |
3335 | ma_device_type_duplex |
3336 | ma_device_type_loopback |
3337 |-------------------------|
3338
3339
3340 Return Value
3341 ------------
3342 A new device config object with default settings. You will typically want to adjust the config after this function returns. See remarks.
3343
3344
3345 Thread Safety
3346 -------------
3347 Safe.
3348
3349
3350 Callback Safety
3351 ---------------
3352 Safe, but don't try initializing a device in a callback.
3353
3354
3355 Remarks
3356 -------
3357 The returned config will be initialized to defaults. You will normally want to customize a few variables before initializing the device. See Example 1 for a
3358 typical configuration which sets the sample format, channel count, sample rate, data callback and user data. These are usually things you will want to change
3359 before initializing the device.
3360
3361 See `ma_device_init()` for details on specific configuration options.
3362
3363
3364 Example 1 - Simple Configuration
3365 --------------------------------
3366 The example below is what a program will typically want to configure for each device at a minimum. Notice how `ma_device_config_init()` is called first, and
3367 then the returned object is modified directly. This is important because it ensures that your program continues to work as new configuration options are added
3368 to the `ma_device_config` structure.
3369
3370 ```c
3371 ma_device_config config = ma_device_config_init(ma_device_type_playback);
3372 config.playback.format = ma_format_f32;
3373 config.playback.channels = 2;
3374 config.sampleRate = 48000;
3375 config.dataCallback = ma_data_callback;
3376 config.pUserData = pMyUserData;
3377 ```
3378
3379
3380 See Also
3381 --------
3382 ma_device_init()
3383 ma_device_init_ex()
3384 */
3385 MA_API ma_device_config ma_device_config_init(ma_device_type deviceType);
3386
3387
3388 /*
3389 Initializes a device.
3390
3391 A device represents a physical audio device. The idea is you send or receive audio data from the device to either play it back through a speaker, or capture it
3392 from a microphone. Whether or not you should send or receive data from the device (or both) depends on the type of device you are initializing which can be
3393 playback, capture, full-duplex or loopback. (Note that loopback mode is only supported on select backends.) Sending and receiving audio data to and from the
3394 device is done via a callback which is fired by miniaudio at periodic time intervals.
3395
3396 The frequency at which data is delivered to and from a device depends on the size of it's period. The size of the period can be defined in terms of PCM frames
3397 or milliseconds, whichever is more convenient. Generally speaking, the smaller the period, the lower the latency at the expense of higher CPU usage and
3398 increased risk of glitching due to the more frequent and granular data deliver intervals. The size of a period will depend on your requirements, but
3399 miniaudio's defaults should work fine for most scenarios. If you're building a game you should leave this fairly small, whereas if you're building a simple
3400 media player you can make it larger. Note that the period size you request is actually just a hint - miniaudio will tell the backend what you want, but the
3401 backend is ultimately responsible for what it gives you. You cannot assume you will get exactly what you ask for.
3402
3403 When delivering data to and from a device you need to make sure it's in the correct format which you can set through the device configuration. You just set the
3404 format that you want to use and miniaudio will perform all of the necessary conversion for you internally. When delivering data to and from the callback you
3405 can assume the format is the same as what you requested when you initialized the device. See Remarks for more details on miniaudio's data conversion pipeline.
3406
3407
3408 Parameters
3409 ----------
3410 pContext (in, optional)
3411 A pointer to the context that owns the device. This can be null, in which case it creates a default context internally.
3412
3413 pConfig (in)
3414 A pointer to the device configuration. Cannot be null. See remarks for details.
3415
3416 pDevice (out)
3417 A pointer to the device object being initialized.
3418
3419
3420 Return Value
3421 ------------
3422 MA_SUCCESS if successful; any other error code otherwise.
3423
3424
3425 Thread Safety
3426 -------------
3427 Unsafe. It is not safe to call this function simultaneously for different devices because some backends depend on and mutate global state. The same applies to
3428 calling this at the same time as `ma_device_uninit()`.
3429
3430
3431 Callback Safety
3432 ---------------
3433 Unsafe. It is not safe to call this inside any callback.
3434
3435
3436 Remarks
3437 -------
3438 Setting `pContext` to NULL will result in miniaudio creating a default context internally and is equivalent to passing in a context initialized like so:
3439
3440 ```c
3441 ma_context_init(NULL, 0, NULL, &context);
3442 ```
3443
3444 Do not set `pContext` to NULL if you are needing to open multiple devices. You can, however, use NULL when initializing the first device, and then use
3445 device.pContext for the initialization of other devices.
3446
3447 The device can be configured via the `pConfig` argument. The config object is initialized with `ma_device_config_init()`. Individual configuration settings can
3448 then be set directly on the structure. Below are the members of the `ma_device_config` object.
3449
3450 deviceType
3451 Must be `ma_device_type_playback`, `ma_device_type_capture`, `ma_device_type_duplex` of `ma_device_type_loopback`.
3452
3453 sampleRate
3454 The sample rate, in hertz. The most common sample rates are 48000 and 44100. Setting this to 0 will use the device's native sample rate.
3455
3456 periodSizeInFrames
3457 The desired size of a period in PCM frames. If this is 0, `periodSizeInMilliseconds` will be used instead. If both are 0 the default buffer size will
3458 be used depending on the selected performance profile. This value affects latency. See below for details.
3459
3460 periodSizeInMilliseconds
3461 The desired size of a period in milliseconds. If this is 0, `periodSizeInFrames` will be used instead. If both are 0 the default buffer size will be
3462 used depending on the selected performance profile. The value affects latency. See below for details.
3463
3464 periods
3465 The number of periods making up the device's entire buffer. The total buffer size is `periodSizeInFrames` or `periodSizeInMilliseconds` multiplied by
3466 this value. This is just a hint as backends will be the ones who ultimately decide how your periods will be configured.
3467
3468 performanceProfile
3469 A hint to miniaudio as to the performance requirements of your program. Can be either `ma_performance_profile_low_latency` (default) or
3470 `ma_performance_profile_conservative`. This mainly affects the size of default buffers and can usually be left at it's default value.
3471
3472 noPreZeroedOutputBuffer
3473 When set to true, the contents of the output buffer passed into the data callback will be left undefined. When set to false (default), the contents of
3474 the output buffer will be cleared the zero. You can use this to avoid the overhead of zeroing out the buffer if you can guarantee that your data
3475 callback will write to every sample in the output buffer, or if you are doing your own clearing.
3476
3477 noClip
3478 When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. When set to false (default), the
3479 contents of the output buffer are left alone after returning and it will be left up to the backend itself to decide whether or not the clip. This only
3480 applies when the playback sample format is f32.
3481
3482 dataCallback
3483 The callback to fire whenever data is ready to be delivered to or from the device.
3484
3485 stopCallback
3486 The callback to fire whenever the device has stopped, either explicitly via `ma_device_stop()`, or implicitly due to things like the device being
3487 disconnected.
3488
3489 pUserData
3490 The user data pointer to use with the device. You can access this directly from the device object like `device.pUserData`.
3491
3492 resampling.algorithm
3493 The resampling algorithm to use when miniaudio needs to perform resampling between the rate specified by `sampleRate` and the device's native rate. The
3494 default value is `ma_resample_algorithm_linear`, and the quality can be configured with `resampling.linear.lpfOrder`.
3495
3496 resampling.linear.lpfOrder
3497 The linear resampler applies a low-pass filter as part of it's procesing for anti-aliasing. This setting controls the order of the filter. The higher
3498 the value, the better the quality, in general. Setting this to 0 will disable low-pass filtering altogether. The maximum value is
3499 `MA_MAX_FILTER_ORDER`. The default value is `min(4, MA_MAX_FILTER_ORDER)`.
3500
3501 playback.pDeviceID
3502 A pointer to a `ma_device_id` structure containing the ID of the playback device to initialize. Setting this NULL (default) will use the system's
3503 default playback device. Retrieve the device ID from the `ma_device_info` structure, which can be retrieved using device enumeration.
3504
3505 playback.format
3506 The sample format to use for playback. When set to `ma_format_unknown` the device's native format will be used. This can be retrieved after
3507 initialization from the device object directly with `device.playback.format`.
3508
3509 playback.channels
3510 The number of channels to use for playback. When set to 0 the device's native channel count will be used. This can be retrieved after initialization
3511 from the device object directly with `device.playback.channels`.
3512
3513 playback.channelMap
3514 The channel map to use for playback. When left empty, the device's native channel map will be used. This can be retrieved after initialization from the
3515 device object direct with `device.playback.channelMap`.
3516
3517 playback.shareMode
3518 The preferred share mode to use for playback. Can be either `ma_share_mode_shared` (default) or `ma_share_mode_exclusive`. Note that if you specify
3519 exclusive mode, but it's not supported by the backend, initialization will fail. You can then fall back to shared mode if desired by changing this to
3520 ma_share_mode_shared and reinitializing.
3521
3522 capture.pDeviceID
3523 A pointer to a `ma_device_id` structure containing the ID of the capture device to initialize. Setting this NULL (default) will use the system's
3524 default capture device. Retrieve the device ID from the `ma_device_info` structure, which can be retrieved using device enumeration.
3525
3526 capture.format
3527 The sample format to use for capture. When set to `ma_format_unknown` the device's native format will be used. This can be retrieved after
3528 initialization from the device object directly with `device.capture.format`.
3529
3530 capture.channels
3531 The number of channels to use for capture. When set to 0 the device's native channel count will be used. This can be retrieved after initialization
3532 from the device object directly with `device.capture.channels`.
3533
3534 capture.channelMap
3535 The channel map to use for capture. When left empty, the device's native channel map will be used. This can be retrieved after initialization from the
3536 device object direct with `device.capture.channelMap`.
3537
3538 capture.shareMode
3539 The preferred share mode to use for capture. Can be either `ma_share_mode_shared` (default) or `ma_share_mode_exclusive`. Note that if you specify
3540 exclusive mode, but it's not supported by the backend, initialization will fail. You can then fall back to shared mode if desired by changing this to
3541 ma_share_mode_shared and reinitializing.
3542
3543 wasapi.noAutoConvertSRC
3544 WASAPI only. When set to true, disables WASAPI's automatic resampling and forces the use of miniaudio's resampler. Defaults to false.
3545
3546 wasapi.noDefaultQualitySRC
3547 WASAPI only. Only used when `wasapi.noAutoConvertSRC` is set to false. When set to true, disables the use of `AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY`.
3548 You should usually leave this set to false, which is the default.
3549
3550 wasapi.noAutoStreamRouting
3551 WASAPI only. When set to true, disables automatic stream routing on the WASAPI backend. Defaults to false.
3552
3553 wasapi.noHardwareOffloading
3554 WASAPI only. When set to true, disables the use of WASAPI's hardware offloading feature. Defaults to false.
3555
3556 alsa.noMMap
3557 ALSA only. When set to true, disables MMap mode. Defaults to false.
3558
3559 alsa.noAutoFormat
3560 ALSA only. When set to true, disables ALSA's automatic format conversion by including the SND_PCM_NO_AUTO_FORMAT flag. Defaults to false.
3561
3562 alsa.noAutoChannels
3563 ALSA only. When set to true, disables ALSA's automatic channel conversion by including the SND_PCM_NO_AUTO_CHANNELS flag. Defaults to false.
3564
3565 alsa.noAutoResample
3566 ALSA only. When set to true, disables ALSA's automatic resampling by including the SND_PCM_NO_AUTO_RESAMPLE flag. Defaults to false.
3567
3568 pulse.pStreamNamePlayback
3569 PulseAudio only. Sets the stream name for playback.
3570
3571 pulse.pStreamNameCapture
3572 PulseAudio only. Sets the stream name for capture.
3573
3574 coreaudio.allowNominalSampleRateChange
3575 Core Audio only. Desktop only. When enabled, allows the sample rate of the device to be changed at the operating system level. This
3576 is disabled by default in order to prevent intrusive changes to the user's system. This is useful if you want to use a sample rate
3577 that is known to be natively supported by the hardware thereby avoiding the cost of resampling. When set to true, miniaudio will
3578 find the closest match between the sample rate requested in the device config and the sample rates natively supported by the
3579 hardware. When set to false, the sample rate currently set by the operating system will always be used.
3580
3581
3582 Once initialized, the device's config is immutable. If you need to change the config you will need to initialize a new device.
3583
3584 After initializing the device it will be in a stopped state. To start it, use `ma_device_start()`.
3585
3586 If both `periodSizeInFrames` and `periodSizeInMilliseconds` are set to zero, it will default to `MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_LOW_LATENCY` or
3587 `MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_CONSERVATIVE`, depending on whether or not `performanceProfile` is set to `ma_performance_profile_low_latency` or
3588 `ma_performance_profile_conservative`.
3589
3590 If you request exclusive mode and the backend does not support it an error will be returned. For robustness, you may want to first try initializing the device
3591 in exclusive mode, and then fall back to shared mode if required. Alternatively you can just request shared mode (the default if you leave it unset in the
3592 config) which is the most reliable option. Some backends do not have a practical way of choosing whether or not the device should be exclusive or not (ALSA,
3593 for example) in which case it just acts as a hint. Unless you have special requirements you should try avoiding exclusive mode as it's intrusive to the user.
3594 Starting with Windows 10, miniaudio will use low-latency shared mode where possible which may make exclusive mode unnecessary.
3595
3596 When sending or receiving data to/from a device, miniaudio will internally perform a format conversion to convert between the format specified by the config
3597 and the format used internally by the backend. If you pass in 0 for the sample format, channel count, sample rate _and_ channel map, data transmission will run
3598 on an optimized pass-through fast path. You can retrieve the format, channel count and sample rate by inspecting the `playback/capture.format`,
3599 `playback/capture.channels` and `sampleRate` members of the device object.
3600
3601 When compiling for UWP you must ensure you call this function on the main UI thread because the operating system may need to present the user with a message
3602 asking for permissions. Please refer to the official documentation for ActivateAudioInterfaceAsync() for more information.
3603
3604 ALSA Specific: When initializing the default device, requesting shared mode will try using the "dmix" device for playback and the "dsnoop" device for capture.
3605 If these fail it will try falling back to the "hw" device.
3606
3607
3608 Example 1 - Simple Initialization
3609 ---------------------------------
3610 This example shows how to initialize a simple playback device using a standard configuration. If you are just needing to do simple playback from the default
3611 playback device this is usually all you need.
3612
3613 ```c
3614 ma_device_config config = ma_device_config_init(ma_device_type_playback);
3615 config.playback.format = ma_format_f32;
3616 config.playback.channels = 2;
3617 config.sampleRate = 48000;
3618 config.dataCallback = ma_data_callback;
3619 config.pMyUserData = pMyUserData;
3620
3621 ma_device device;
3622 ma_result result = ma_device_init(NULL, &config, &device);
3623 if (result != MA_SUCCESS) {
3624 // Error
3625 }
3626 ```
3627
3628
3629 Example 2 - Advanced Initialization
3630 -----------------------------------
3631 This example shows how you might do some more advanced initialization. In this hypothetical example we want to control the latency by setting the buffer size
3632 and period count. We also want to allow the user to be able to choose which device to output from which means we need a context so we can perform device
3633 enumeration.
3634
3635 ```c
3636 ma_context context;
3637 ma_result result = ma_context_init(NULL, 0, NULL, &context);
3638 if (result != MA_SUCCESS) {
3639 // Error
3640 }
3641
3642 ma_device_info* pPlaybackDeviceInfos;
3643 ma_uint32 playbackDeviceCount;
3644 result = ma_context_get_devices(&context, &pPlaybackDeviceInfos, &playbackDeviceCount, NULL, NULL);
3645 if (result != MA_SUCCESS) {
3646 // Error
3647 }
3648
3649 // ... choose a device from pPlaybackDeviceInfos ...
3650
3651 ma_device_config config = ma_device_config_init(ma_device_type_playback);
3652 config.playback.pDeviceID = pMyChosenDeviceID; // <-- Get this from the `id` member of one of the `ma_device_info` objects returned by ma_context_get_devices().
3653 config.playback.format = ma_format_f32;
3654 config.playback.channels = 2;
3655 config.sampleRate = 48000;
3656 config.dataCallback = ma_data_callback;
3657 config.pUserData = pMyUserData;
3658 config.periodSizeInMilliseconds = 10;
3659 config.periods = 3;
3660
3661 ma_device device;
3662 result = ma_device_init(&context, &config, &device);
3663 if (result != MA_SUCCESS) {
3664 // Error
3665 }
3666 ```
3667
3668
3669 See Also
3670 --------
3671 ma_device_config_init()
3672 ma_device_uninit()
3673 ma_device_start()
3674 ma_context_init()
3675 ma_context_get_devices()
3676 ma_context_enumerate_devices()
3677 */
3678 MA_API ma_result ma_device_init(ma_context* pContext, const ma_device_config* pConfig, ma_device* pDevice);
3679
3680 /*
3681 Initializes a device without a context, with extra parameters for controlling the configuration of the internal self-managed context.
3682
3683 This is the same as `ma_device_init()`, only instead of a context being passed in, the parameters from `ma_context_init()` are passed in instead. This function
3684 allows you to configure the internally created context.
3685
3686
3687 Parameters
3688 ----------
3689 backends (in, optional)
3690 A list of backends to try initializing, in priority order. Can be NULL, in which case it uses default priority order.
3691
3692 backendCount (in, optional)
3693 The number of items in `backend`. Ignored if `backend` is NULL.
3694
3695 pContextConfig (in, optional)
3696 The context configuration.
3697
3698 pConfig (in)
3699 A pointer to the device configuration. Cannot be null. See remarks for details.
3700
3701 pDevice (out)
3702 A pointer to the device object being initialized.
3703
3704
3705 Return Value
3706 ------------
3707 MA_SUCCESS if successful; any other error code otherwise.
3708
3709
3710 Thread Safety
3711 -------------
3712 Unsafe. It is not safe to call this function simultaneously for different devices because some backends depend on and mutate global state. The same applies to
3713 calling this at the same time as `ma_device_uninit()`.
3714
3715
3716 Callback Safety
3717 ---------------
3718 Unsafe. It is not safe to call this inside any callback.
3719
3720
3721 Remarks
3722 -------
3723 You only need to use this function if you want to configure the context differently to it's defaults. You should never use this function if you want to manage
3724 your own context.
3725
3726 See the documentation for `ma_context_init()` for information on the different context configuration options.
3727
3728
3729 See Also
3730 --------
3731 ma_device_init()
3732 ma_device_uninit()
3733 ma_device_config_init()
3734 ma_context_init()
3735 */
3736 MA_API ma_result ma_device_init_ex(const ma_backend backends[], ma_uint32 backendCount, const ma_context_config* pContextConfig, const ma_device_config* pConfig, ma_device* pDevice);
3737
3738 /*
3739 Uninitializes a device.
3740
3741 This will explicitly stop the device. You do not need to call `ma_device_stop()` beforehand, but it's harmless if you do.
3742
3743
3744 Parameters
3745 ----------
3746 pDevice (in)
3747 A pointer to the device to stop.
3748
3749
3750 Return Value
3751 ------------
3752 Nothing
3753
3754
3755 Thread Safety
3756 -------------
3757 Unsafe. As soon as this API is called the device should be considered undefined.
3758
3759
3760 Callback Safety
3761 ---------------
3762 Unsafe. It is not safe to call this inside any callback. Doing this will result in a deadlock.
3763
3764
3765 See Also
3766 --------
3767 ma_device_init()
3768 ma_device_stop()
3769 */
3770 MA_API void ma_device_uninit(ma_device* pDevice);
3771
3772
3773 /*
3774 Retrieves a pointer to the context that owns the given device.
3775 */
3776 MA_API ma_context* ma_device_get_context(ma_device* pDevice);
3777
3778 /*
3779 Helper function for retrieving the log object associated with the context that owns this device.
3780 */
3781 MA_API ma_log* ma_device_get_log(ma_device* pDevice);
3782
3783
3784 /*
3785 Starts the device. For playback devices this begins playback. For capture devices it begins recording.
3786
3787 Use `ma_device_stop()` to stop the device.
3788
3789
3790 Parameters
3791 ----------
3792 pDevice (in)
3793 A pointer to the device to start.
3794
3795
3796 Return Value
3797 ------------
3798 MA_SUCCESS if successful; any other error code otherwise.
3799
3800
3801 Thread Safety
3802 -------------
3803 Safe. It's safe to call this from any thread with the exception of the callback thread.
3804
3805
3806 Callback Safety
3807 ---------------
3808 Unsafe. It is not safe to call this inside any callback.
3809
3810
3811 Remarks
3812 -------
3813 For a playback device, this will retrieve an initial chunk of audio data from the client before returning. The reason for this is to ensure there is valid
3814 audio data in the buffer, which needs to be done before the device begins playback.
3815
3816 This API waits until the backend device has been started for real by the worker thread. It also waits on a mutex for thread-safety.
3817
3818 Do not call this in any callback.
3819
3820
3821 See Also
3822 --------
3823 ma_device_stop()
3824 */
3825 MA_API ma_result ma_device_start(ma_device* pDevice);
3826
3827 /*
3828 Stops the device. For playback devices this stops playback. For capture devices it stops recording.
3829
3830 Use `ma_device_start()` to start the device again.
3831
3832
3833 Parameters
3834 ----------
3835 pDevice (in)
3836 A pointer to the device to stop.
3837
3838
3839 Return Value
3840 ------------
3841 MA_SUCCESS if successful; any other error code otherwise.
3842
3843
3844 Thread Safety
3845 -------------
3846 Safe. It's safe to call this from any thread with the exception of the callback thread.
3847
3848
3849 Callback Safety
3850 ---------------
3851 Unsafe. It is not safe to call this inside any callback. Doing this will result in a deadlock.
3852
3853
3854 Remarks
3855 -------
3856 This API needs to wait on the worker thread to stop the backend device properly before returning. It also waits on a mutex for thread-safety. In addition, some
3857 backends need to wait for the device to finish playback/recording of the current fragment which can take some time (usually proportionate to the buffer size
3858 that was specified at initialization time).
3859
3860 Backends are required to either pause the stream in-place or drain the buffer if pausing is not possible. The reason for this is that stopping the device and
3861 the resuming it with ma_device_start() (which you might do when your program loses focus) may result in a situation where those samples are never output to the
3862 speakers or received from the microphone which can in turn result in de-syncs.
3863
3864 Do not call this in any callback.
3865
3866 This will be called implicitly by `ma_device_uninit()`.
3867
3868
3869 See Also
3870 --------
3871 ma_device_start()
3872 */
3873 MA_API ma_result ma_device_stop(ma_device* pDevice);
3874
3875 /*
3876 Determines whether or not the device is started.
3877
3878
3879 Parameters
3880 ----------
3881 pDevice (in)
3882 A pointer to the device whose start state is being retrieved.
3883
3884
3885 Return Value
3886 ------------
3887 True if the device is started, false otherwise.
3888
3889
3890 Thread Safety
3891 -------------
3892 Safe. If another thread calls `ma_device_start()` or `ma_device_stop()` at this same time as this function is called, there's a very small chance the return
3893 value will be out of sync.
3894
3895
3896 Callback Safety
3897 ---------------
3898 Safe. This is implemented as a simple accessor.
3899
3900
3901 See Also
3902 --------
3903 ma_device_start()
3904 ma_device_stop()
3905 */
3906 MA_API ma_bool32 ma_device_is_started(const ma_device* pDevice);
3907
3908
3909 /*
3910 Retrieves the state of the device.
3911
3912
3913 Parameters
3914 ----------
3915 pDevice (in)
3916 A pointer to the device whose state is being retrieved.
3917
3918
3919 Return Value
3920 ------------
3921 The current state of the device. The return value will be one of the following:
3922
3923 +------------------------+------------------------------------------------------------------------------+
3924 | MA_STATE_UNINITIALIZED | Will only be returned if the device is in the middle of initialization. |
3925 +------------------------+------------------------------------------------------------------------------+
3926 | MA_STATE_STOPPED | The device is stopped. The initial state of the device after initialization. |
3927 +------------------------+------------------------------------------------------------------------------+
3928 | MA_STATE_STARTED | The device started and requesting and/or delivering audio data. |
3929 +------------------------+------------------------------------------------------------------------------+
3930 | MA_STATE_STARTING | The device is in the process of starting. |
3931 +------------------------+------------------------------------------------------------------------------+
3932 | MA_STATE_STOPPING | The device is in the process of stopping. |
3933 +------------------------+------------------------------------------------------------------------------+
3934
3935
3936 Thread Safety
3937 -------------
3938 Safe. This is implemented as a simple accessor. Note that if the device is started or stopped at the same time as this function is called,
3939 there's a possibility the return value could be out of sync. See remarks.
3940
3941
3942 Callback Safety
3943 ---------------
3944 Safe. This is implemented as a simple accessor.
3945
3946
3947 Remarks
3948 -------
3949 The general flow of a devices state goes like this:
3950
3951 ```
3952 ma_device_init() -> MA_STATE_UNINITIALIZED -> MA_STATE_STOPPED
3953 ma_device_start() -> MA_STATE_STARTING -> MA_STATE_STARTED
3954 ma_device_stop() -> MA_STATE_STOPPING -> MA_STATE_STOPPED
3955 ```
3956
3957 When the state of the device is changed with `ma_device_start()` or `ma_device_stop()` at this same time as this function is called, the
3958 value returned by this function could potentially be out of sync. If this is significant to your program you need to implement your own
3959 synchronization.
3960 */
3961 MA_API ma_uint32 ma_device_get_state(const ma_device* pDevice);
3962
3963
3964 /*
3965 Sets the master volume factor for the device.
3966
3967 The volume factor must be between 0 (silence) and 1 (full volume). Use `ma_device_set_master_gain_db()` to use decibel notation, where 0 is full volume and
3968 values less than 0 decreases the volume.
3969
3970
3971 Parameters
3972 ----------
3973 pDevice (in)
3974 A pointer to the device whose volume is being set.
3975
3976 volume (in)
3977 The new volume factor. Must be within the range of [0, 1].
3978
3979
3980 Return Value
3981 ------------
3982 MA_SUCCESS if the volume was set successfully.
3983 MA_INVALID_ARGS if pDevice is NULL.
3984 MA_INVALID_ARGS if the volume factor is not within the range of [0, 1].
3985
3986
3987 Thread Safety
3988 -------------
3989 Safe. This just sets a local member of the device object.
3990
3991
3992 Callback Safety
3993 ---------------
3994 Safe. If you set the volume in the data callback, that data written to the output buffer will have the new volume applied.
3995
3996
3997 Remarks
3998 -------
3999 This applies the volume factor across all channels.
4000
4001 This does not change the operating system's volume. It only affects the volume for the given `ma_device` object's audio stream.
4002
4003
4004 See Also
4005 --------
4006 ma_device_get_master_volume()
4007 ma_device_set_master_volume_gain_db()
4008 ma_device_get_master_volume_gain_db()
4009 */
4010 MA_API ma_result ma_device_set_master_volume(ma_device* pDevice, float volume);
4011
4012 /*
4013 Retrieves the master volume factor for the device.
4014
4015
4016 Parameters
4017 ----------
4018 pDevice (in)
4019 A pointer to the device whose volume factor is being retrieved.
4020
4021 pVolume (in)
4022 A pointer to the variable that will receive the volume factor. The returned value will be in the range of [0, 1].
4023
4024
4025 Return Value
4026 ------------
4027 MA_SUCCESS if successful.
4028 MA_INVALID_ARGS if pDevice is NULL.
4029 MA_INVALID_ARGS if pVolume is NULL.
4030
4031
4032 Thread Safety
4033 -------------
4034 Safe. This just a simple member retrieval.
4035
4036
4037 Callback Safety
4038 ---------------
4039 Safe.
4040
4041
4042 Remarks
4043 -------
4044 If an error occurs, `*pVolume` will be set to 0.
4045
4046
4047 See Also
4048 --------
4049 ma_device_set_master_volume()
4050 ma_device_set_master_volume_gain_db()
4051 ma_device_get_master_volume_gain_db()
4052 */
4053 MA_API ma_result ma_device_get_master_volume(ma_device* pDevice, float* pVolume);
4054
4055 /*
4056 Sets the master volume for the device as gain in decibels.
4057
4058 A gain of 0 is full volume, whereas a gain of < 0 will decrease the volume.
4059
4060
4061 Parameters
4062 ----------
4063 pDevice (in)
4064 A pointer to the device whose gain is being set.
4065
4066 gainDB (in)
4067 The new volume as gain in decibels. Must be less than or equal to 0, where 0 is full volume and anything less than 0 decreases the volume.
4068
4069
4070 Return Value
4071 ------------
4072 MA_SUCCESS if the volume was set successfully.
4073 MA_INVALID_ARGS if pDevice is NULL.
4074 MA_INVALID_ARGS if the gain is > 0.
4075
4076
4077 Thread Safety
4078 -------------
4079 Safe. This just sets a local member of the device object.
4080
4081
4082 Callback Safety
4083 ---------------
4084 Safe. If you set the volume in the data callback, that data written to the output buffer will have the new volume applied.
4085
4086
4087 Remarks
4088 -------
4089 This applies the gain across all channels.
4090
4091 This does not change the operating system's volume. It only affects the volume for the given `ma_device` object's audio stream.
4092
4093
4094 See Also
4095 --------
4096 ma_device_get_master_volume_gain_db()
4097 ma_device_set_master_volume()
4098 ma_device_get_master_volume()
4099 */
4100 MA_API ma_result ma_device_set_master_gain_db(ma_device* pDevice, float gainDB);
4101
4102 /*
4103 Retrieves the master gain in decibels.
4104
4105
4106 Parameters
4107 ----------
4108 pDevice (in)
4109 A pointer to the device whose gain is being retrieved.
4110
4111 pGainDB (in)
4112 A pointer to the variable that will receive the gain in decibels. The returned value will be <= 0.
4113
4114
4115 Return Value
4116 ------------
4117 MA_SUCCESS if successful.
4118 MA_INVALID_ARGS if pDevice is NULL.
4119 MA_INVALID_ARGS if pGainDB is NULL.
4120
4121
4122 Thread Safety
4123 -------------
4124 Safe. This just a simple member retrieval.
4125
4126
4127 Callback Safety
4128 ---------------
4129 Safe.
4130
4131
4132 Remarks
4133 -------
4134 If an error occurs, `*pGainDB` will be set to 0.
4135
4136
4137 See Also
4138 --------
4139 ma_device_set_master_volume_gain_db()
4140 ma_device_set_master_volume()
4141 ma_device_get_master_volume()
4142 */
4143 MA_API ma_result ma_device_get_master_gain_db(ma_device* pDevice, float* pGainDB);
4144
4145
4146 /*
4147 Called from the data callback of asynchronous backends to allow miniaudio to process the data and fire the miniaudio data callback.
4148
4149
4150 Parameters
4151 ----------
4152 pDevice (in)
4153 A pointer to device whose processing the data callback.
4154
4155 pOutput (out)
4156 A pointer to the buffer that will receive the output PCM frame data. On a playback device this must not be NULL. On a duplex device
4157 this can be NULL, in which case pInput must not be NULL.
4158
4159 pInput (in)
4160 A pointer to the buffer containing input PCM frame data. On a capture device this must not be NULL. On a duplex device this can be
4161 NULL, in which case `pOutput` must not be NULL.
4162
4163 frameCount (in)
4164 The number of frames being processed.
4165
4166
4167 Return Value
4168 ------------
4169 MA_SUCCESS if successful; any other result code otherwise.
4170
4171
4172 Thread Safety
4173 -------------
4174 This function should only ever be called from the internal data callback of the backend. It is safe to call this simultaneously between a
4175 playback and capture device in duplex setups.
4176
4177
4178 Callback Safety
4179 ---------------
4180 Do not call this from the miniaudio data callback. It should only ever be called from the internal data callback of the backend.
4181
4182
4183 Remarks
4184 -------
4185 If both `pOutput` and `pInput` are NULL, and error will be returned. In duplex scenarios, both `pOutput` and `pInput` can be non-NULL, in
4186 which case `pInput` will be processed first, followed by `pOutput`.
4187
4188 If you are implementing a custom backend, and that backend uses a callback for data delivery, you'll need to call this from inside that
4189 callback.
4190 */
4191 MA_API ma_result ma_device_handle_backend_data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
4192
4193
4194 /*
4195 Calculates an appropriate buffer size from a descriptor, native sample rate and performance profile.
4196
4197 This function is used by backends for helping determine an appropriately sized buffer to use with
4198 the device depending on the values of `periodSizeInFrames` and `periodSizeInMilliseconds` in the
4199 `pDescriptor` object. Since buffer size calculations based on time depends on the sample rate, a
4200 best guess at the device's native sample rate is also required which is where `nativeSampleRate`
4201 comes in. In addition, the performance profile is also needed for cases where both the period size
4202 in frames and milliseconds are both zero.
4203
4204
4205 Parameters
4206 ----------
4207 pDescriptor (in)
4208 A pointer to device descriptor whose `periodSizeInFrames` and `periodSizeInMilliseconds` members
4209 will be used for the calculation of the buffer size.
4210
4211 nativeSampleRate (in)
4212 The device's native sample rate. This is only ever used when the `periodSizeInFrames` member of
4213 `pDescriptor` is zero. In this case, `periodSizeInMilliseconds` will be used instead, in which
4214 case a sample rate is required to convert to a size in frames.
4215
4216 performanceProfile (in)
4217 When both the `periodSizeInFrames` and `periodSizeInMilliseconds` members of `pDescriptor` are
4218 zero, miniaudio will fall back to a buffer size based on the performance profile. The profile
4219 to use for this calculation is determine by this parameter.
4220
4221
4222 Return Value
4223 ------------
4224 The calculated buffer size in frames.
4225
4226
4227 Thread Safety
4228 -------------
4229 This is safe so long as nothing modifies `pDescriptor` at the same time. However, this function
4230 should only ever be called from within the backend's device initialization routine and therefore
4231 shouldn't have any multithreading concerns.
4232
4233
4234 Callback Safety
4235 ---------------
4236 This is safe to call within the data callback, but there is no reason to ever do this.
4237
4238
4239 Remarks
4240 -------
4241 If `nativeSampleRate` is zero, this function will fall back to `pDescriptor->sampleRate`. If that
4242 is also zero, `MA_DEFAULT_SAMPLE_RATE` will be used instead.
4243 */
4244 MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_descriptor(const ma_device_descriptor* pDescriptor, ma_uint32 nativeSampleRate, ma_performance_profile performanceProfile);
4245
4246
4247
4248 /*
4249 Retrieves a friendly name for a backend.
4250 */
4251 MA_API const char* ma_get_backend_name(ma_backend backend);
4252
4253 /*
4254 Determines whether or not the given backend is available by the compilation environment.
4255 */
4256 MA_API ma_bool32 ma_is_backend_enabled(ma_backend backend);
4257
4258 /*
4259 Retrieves compile-time enabled backends.
4260
4261
4262 Parameters
4263 ----------
4264 pBackends (out, optional)
4265 A pointer to the buffer that will receive the enabled backends. Set to NULL to retrieve the backend count. Setting
4266 the capacity of the buffer to `MA_BUFFER_COUNT` will guarantee it's large enough for all backends.
4267
4268 backendCap (in)
4269 The capacity of the `pBackends` buffer.
4270
4271 pBackendCount (out)
4272 A pointer to the variable that will receive the enabled backend count.
4273
4274
4275 Return Value
4276 ------------
4277 MA_SUCCESS if successful.
4278 MA_INVALID_ARGS if `pBackendCount` is NULL.
4279 MA_NO_SPACE if the capacity of `pBackends` is not large enough.
4280
4281 If `MA_NO_SPACE` is returned, the `pBackends` buffer will be filled with `*pBackendCount` values.
4282
4283
4284 Thread Safety
4285 -------------
4286 Safe.
4287
4288
4289 Callback Safety
4290 ---------------
4291 Safe.
4292
4293
4294 Remarks
4295 -------
4296 If you want to retrieve the number of backends so you can determine the capacity of `pBackends` buffer, you can call
4297 this function with `pBackends` set to NULL.
4298
4299 This will also enumerate the null backend. If you don't want to include this you need to check for `ma_backend_null`
4300 when you enumerate over the returned backends and handle it appropriately. Alternatively, you can disable it at
4301 compile time with `MA_NO_NULL`.
4302
4303 The returned backends are determined based on compile time settings, not the platform it's currently running on. For
4304 example, PulseAudio will be returned if it was enabled at compile time, even when the user doesn't actually have
4305 PulseAudio installed.
4306
4307
4308 Example 1
4309 ---------
4310 The example below retrieves the enabled backend count using a fixed sized buffer allocated on the stack. The buffer is
4311 given a capacity of `MA_BACKEND_COUNT` which will guarantee it'll be large enough to store all available backends.
4312 Since `MA_BACKEND_COUNT` is always a relatively small value, this should be suitable for most scenarios.
4313
4314 ```
4315 ma_backend enabledBackends[MA_BACKEND_COUNT];
4316 size_t enabledBackendCount;
4317
4318 result = ma_get_enabled_backends(enabledBackends, MA_BACKEND_COUNT, &enabledBackendCount);
4319 if (result != MA_SUCCESS) {
4320 // Failed to retrieve enabled backends. Should never happen in this example since all inputs are valid.
4321 }
4322 ```
4323
4324
4325 See Also
4326 --------
4327 ma_is_backend_enabled()
4328 */
4329 MA_API ma_result ma_get_enabled_backends(ma_backend* pBackends, size_t backendCap, size_t* pBackendCount);
4330
4331 /*
4332 Determines whether or not loopback mode is support by a backend.
4333 */
4334 MA_API ma_bool32 ma_is_loopback_supported(ma_backend backend);
4335
4336 #endif /* MA_NO_DEVICE_IO */
4337
4338
4339 #ifndef MA_NO_THREADING
4340
4341 /*
4342 Locks a spinlock.
4343 */
4344 MA_API ma_result ma_spinlock_lock(volatile ma_spinlock* pSpinlock);
4345
4346 /*
4347 Locks a spinlock, but does not yield() when looping.
4348 */
4349 MA_API ma_result ma_spinlock_lock_noyield(volatile ma_spinlock* pSpinlock);
4350
4351 /*
4352 Unlocks a spinlock.
4353 */
4354 MA_API ma_result ma_spinlock_unlock(volatile ma_spinlock* pSpinlock);
4355
4356
4357 /*
4358 Creates a mutex.
4359
4360 A mutex must be created from a valid context. A mutex is initially unlocked.
4361 */
4362 MA_API ma_result ma_mutex_init(ma_mutex* pMutex);
4363
4364 /*
4365 Deletes a mutex.
4366 */
4367 MA_API void ma_mutex_uninit(ma_mutex* pMutex);
4368
4369 /*
4370 Locks a mutex with an infinite timeout.
4371 */
4372 MA_API void ma_mutex_lock(ma_mutex* pMutex);
4373
4374 /*
4375 Unlocks a mutex.
4376 */
4377 MA_API void ma_mutex_unlock(ma_mutex* pMutex);
4378
4379
4380 /*
4381 Initializes an auto-reset event.
4382 */
4383 MA_API ma_result ma_event_init(ma_event* pEvent);
4384
4385 /*
4386 Uninitializes an auto-reset event.
4387 */
4388 MA_API void ma_event_uninit(ma_event* pEvent);
4389
4390 /*
4391 Waits for the specified auto-reset event to become signalled.
4392 */
4393 MA_API ma_result ma_event_wait(ma_event* pEvent);
4394
4395 /*
4396 Signals the specified auto-reset event.
4397 */
4398 MA_API ma_result ma_event_signal(ma_event* pEvent);
4399 #endif /* MA_NO_THREADING */
4400
4401
4402 /************************************************************************************************************************************************************
4403
4404 Utiltities
4405
4406 ************************************************************************************************************************************************************/
4407
4408 /*
4409 Adjust buffer size based on a scaling factor.
4410
4411 This just multiplies the base size by the scaling factor, making sure it's a size of at least 1.
4412 */
4413 MA_API ma_uint32 ma_scale_buffer_size(ma_uint32 baseBufferSize, float scale);
4414
4415 /*
4416 Calculates a buffer size in milliseconds from the specified number of frames and sample rate.
4417 */
4418 MA_API ma_uint32 ma_calculate_buffer_size_in_milliseconds_from_frames(ma_uint32 bufferSizeInFrames, ma_uint32 sampleRate);
4419
4420 /*
4421 Calculates a buffer size in frames from the specified number of milliseconds and sample rate.
4422 */
4423 MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_milliseconds(ma_uint32 bufferSizeInMilliseconds, ma_uint32 sampleRate);
4424
4425 /*
4426 Copies PCM frames from one buffer to another.
4427 */
4428 MA_API void ma_copy_pcm_frames(void* dst, const void* src, ma_uint64 frameCount, ma_format format, ma_uint32 channels);
4429
4430 /*
4431 Copies silent frames into the given buffer.
4432
4433 Remarks
4434 -------
4435 For all formats except `ma_format_u8`, the output buffer will be filled with 0. For `ma_format_u8` it will be filled with 128. The reason for this is that it
4436 makes more sense for the purpose of mixing to initialize it to the center point.
4437 */
4438 MA_API void ma_silence_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels);
ma_zero_pcm_frames(void * p,ma_uint64 frameCount,ma_format format,ma_uint32 channels)4439 static MA_INLINE void ma_zero_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels) { ma_silence_pcm_frames(p, frameCount, format, channels); }
4440
4441
4442 /*
4443 Offsets a pointer by the specified number of PCM frames.
4444 */
4445 MA_API void* ma_offset_pcm_frames_ptr(void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels);
4446 MA_API const void* ma_offset_pcm_frames_const_ptr(const void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels);
ma_offset_pcm_frames_ptr_f32(float * p,ma_uint64 offsetInFrames,ma_uint32 channels)4447 static MA_INLINE float* ma_offset_pcm_frames_ptr_f32(float* p, ma_uint64 offsetInFrames, ma_uint32 channels) { return (float*)ma_offset_pcm_frames_ptr((void*)p, offsetInFrames, ma_format_f32, channels); }
ma_offset_pcm_frames_const_ptr_f32(const float * p,ma_uint64 offsetInFrames,ma_uint32 channels)4448 static MA_INLINE const float* ma_offset_pcm_frames_const_ptr_f32(const float* p, ma_uint64 offsetInFrames, ma_uint32 channels) { return (const float*)ma_offset_pcm_frames_const_ptr((const void*)p, offsetInFrames, ma_format_f32, channels); }
4449
4450
4451 /*
4452 Clips f32 samples.
4453 */
4454 MA_API void ma_clip_samples_f32(float* p, ma_uint64 sampleCount);
ma_clip_pcm_frames_f32(float * p,ma_uint64 frameCount,ma_uint32 channels)4455 static MA_INLINE void ma_clip_pcm_frames_f32(float* p, ma_uint64 frameCount, ma_uint32 channels) { ma_clip_samples_f32(p, frameCount*channels); }
4456
4457 /*
4458 Helper for applying a volume factor to samples.
4459
4460 Note that the source and destination buffers can be the same, in which case it'll perform the operation in-place.
4461 */
4462 MA_API void ma_copy_and_apply_volume_factor_u8(ma_uint8* pSamplesOut, const ma_uint8* pSamplesIn, ma_uint64 sampleCount, float factor);
4463 MA_API void ma_copy_and_apply_volume_factor_s16(ma_int16* pSamplesOut, const ma_int16* pSamplesIn, ma_uint64 sampleCount, float factor);
4464 MA_API void ma_copy_and_apply_volume_factor_s24(void* pSamplesOut, const void* pSamplesIn, ma_uint64 sampleCount, float factor);
4465 MA_API void ma_copy_and_apply_volume_factor_s32(ma_int32* pSamplesOut, const ma_int32* pSamplesIn, ma_uint64 sampleCount, float factor);
4466 MA_API void ma_copy_and_apply_volume_factor_f32(float* pSamplesOut, const float* pSamplesIn, ma_uint64 sampleCount, float factor);
4467
4468 MA_API void ma_apply_volume_factor_u8(ma_uint8* pSamples, ma_uint64 sampleCount, float factor);
4469 MA_API void ma_apply_volume_factor_s16(ma_int16* pSamples, ma_uint64 sampleCount, float factor);
4470 MA_API void ma_apply_volume_factor_s24(void* pSamples, ma_uint64 sampleCount, float factor);
4471 MA_API void ma_apply_volume_factor_s32(ma_int32* pSamples, ma_uint64 sampleCount, float factor);
4472 MA_API void ma_apply_volume_factor_f32(float* pSamples, ma_uint64 sampleCount, float factor);
4473
4474 MA_API void ma_copy_and_apply_volume_factor_pcm_frames_u8(ma_uint8* pPCMFramesOut, const ma_uint8* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
4475 MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s16(ma_int16* pPCMFramesOut, const ma_int16* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
4476 MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s24(void* pPCMFramesOut, const void* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
4477 MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s32(ma_int32* pPCMFramesOut, const ma_int32* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
4478 MA_API void ma_copy_and_apply_volume_factor_pcm_frames_f32(float* pPCMFramesOut, const float* pPCMFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
4479 MA_API void ma_copy_and_apply_volume_factor_pcm_frames(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor);
4480
4481 MA_API void ma_apply_volume_factor_pcm_frames_u8(ma_uint8* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
4482 MA_API void ma_apply_volume_factor_pcm_frames_s16(ma_int16* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
4483 MA_API void ma_apply_volume_factor_pcm_frames_s24(void* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
4484 MA_API void ma_apply_volume_factor_pcm_frames_s32(ma_int32* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
4485 MA_API void ma_apply_volume_factor_pcm_frames_f32(float* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
4486 MA_API void ma_apply_volume_factor_pcm_frames(void* pFrames, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor);
4487
4488
4489 /*
4490 Helper for converting a linear factor to gain in decibels.
4491 */
4492 MA_API float ma_factor_to_gain_db(float factor);
4493
4494 /*
4495 Helper for converting gain in decibels to a linear factor.
4496 */
4497 MA_API float ma_gain_db_to_factor(float gain);
4498
4499
4500 typedef void ma_data_source;
4501
4502 typedef struct
4503 {
4504 ma_result (* onRead)(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
4505 ma_result (* onSeek)(ma_data_source* pDataSource, ma_uint64 frameIndex);
4506 ma_result (* onMap)(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
4507 ma_result (* onUnmap)(ma_data_source* pDataSource, ma_uint64 frameCount);
4508 ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
4509 ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor);
4510 ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength);
4511 } ma_data_source_vtable, ma_data_source_callbacks; /* TODO: Remove ma_data_source_callbacks in version 0.11. */
4512
4513 typedef ma_data_source* (* ma_data_source_get_next_proc)(ma_data_source* pDataSource);
4514
4515 typedef struct
4516 {
4517 const ma_data_source_vtable* vtable; /* Can be null, which is useful for proxies. */
4518 } ma_data_source_config;
4519
4520 MA_API ma_data_source_config ma_data_source_config_init(void);
4521
4522
4523 typedef struct
4524 {
4525 ma_data_source_callbacks cb; /* TODO: Remove this. */
4526
4527 /* Variables below are placeholder and not yet used. */
4528 const ma_data_source_vtable* vtable;
4529 ma_uint64 rangeBegInFrames;
4530 ma_uint64 rangeEndInFrames; /* Set to -1 for unranged (default). */
4531 ma_uint64 loopBegInFrames; /* Relative to rangeBegInFrames. */
4532 ma_uint64 loopEndInFrames; /* Relative to rangeBegInFrames. Set to -1 for the end of the range. */
4533 ma_data_source* pCurrent; /* When non-NULL, the data source being initialized will act as a proxy and will route all operations to pCurrent. Used in conjunction with pNext/onGetNext for seamless chaining. */
4534 ma_data_source* pNext; /* When set to NULL, onGetNext will be used. */
4535 ma_data_source_get_next_proc onGetNext; /* Will be used when pNext is NULL. If both are NULL, no next will be used. */
4536 } ma_data_source_base;
4537
4538 MA_API ma_result ma_data_source_init(const ma_data_source_config* pConfig, ma_data_source* pDataSource);
4539 MA_API void ma_data_source_uninit(ma_data_source* pDataSource);
4540 MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead, ma_bool32 loop); /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
4541 MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked, ma_bool32 loop); /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount); */
4542 MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex);
4543 MA_API ma_result ma_data_source_map(ma_data_source* pDataSource, void** ppFramesOut, ma_uint64* pFrameCount); /* Returns MA_NOT_IMPLEMENTED if mapping is not supported. */
4544 MA_API ma_result ma_data_source_unmap(ma_data_source* pDataSource, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. */
4545 MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
4546 MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor);
4547 MA_API ma_result ma_data_source_get_length_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLength); /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */
4548 #if defined(MA_EXPERIMENTAL__DATA_LOOPING_AND_CHAINING)
4549 MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames);
4550 MA_API void ma_data_source_get_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames);
4551 MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 loopBegInFrames, ma_uint64 loopEndInFrames);
4552 MA_API void ma_data_source_get_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames);
4553 MA_API ma_result ma_data_source_set_current(ma_data_source* pDataSource, ma_data_source* pCurrentDataSource);
4554 MA_API ma_data_source* ma_data_source_get_current(ma_data_source* pDataSource);
4555 MA_API ma_result ma_data_source_set_next(ma_data_source* pDataSource, ma_data_source* pNextDataSource);
4556 MA_API ma_data_source* ma_data_source_get_next(ma_data_source* pDataSource);
4557 MA_API ma_result ma_data_source_set_next_callback(ma_data_source* pDataSource, ma_data_source_get_next_proc onGetNext);
4558 MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(ma_data_source* pDataSource);
4559 #endif
4560
4561
4562 typedef struct
4563 {
4564 ma_data_source_base ds;
4565 ma_format format;
4566 ma_uint32 channels;
4567 ma_uint64 cursor;
4568 ma_uint64 sizeInFrames;
4569 const void* pData;
4570 } ma_audio_buffer_ref;
4571
4572 MA_API ma_result ma_audio_buffer_ref_init(ma_format format, ma_uint32 channels, const void* pData, ma_uint64 sizeInFrames, ma_audio_buffer_ref* pAudioBufferRef);
4573 MA_API void ma_audio_buffer_ref_uninit(ma_audio_buffer_ref* pAudioBufferRef);
4574 MA_API ma_result ma_audio_buffer_ref_set_data(ma_audio_buffer_ref* pAudioBufferRef, const void* pData, ma_uint64 sizeInFrames);
4575 MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudioBufferRef, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
4576 MA_API ma_result ma_audio_buffer_ref_seek_to_pcm_frame(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameIndex);
4577 MA_API ma_result ma_audio_buffer_ref_map(ma_audio_buffer_ref* pAudioBufferRef, void** ppFramesOut, ma_uint64* pFrameCount);
4578 MA_API ma_result ma_audio_buffer_ref_unmap(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
4579 MA_API ma_bool32 ma_audio_buffer_ref_at_end(const ma_audio_buffer_ref* pAudioBufferRef);
4580 MA_API ma_result ma_audio_buffer_ref_get_cursor_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pCursor);
4581 MA_API ma_result ma_audio_buffer_ref_get_length_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pLength);
4582 MA_API ma_result ma_audio_buffer_ref_get_available_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pAvailableFrames);
4583
4584
4585
4586 typedef struct
4587 {
4588 ma_format format;
4589 ma_uint32 channels;
4590 ma_uint64 sizeInFrames;
4591 const void* pData; /* If set to NULL, will allocate a block of memory for you. */
4592 ma_allocation_callbacks allocationCallbacks;
4593 } ma_audio_buffer_config;
4594
4595 MA_API ma_audio_buffer_config ma_audio_buffer_config_init(ma_format format, ma_uint32 channels, ma_uint64 sizeInFrames, const void* pData, const ma_allocation_callbacks* pAllocationCallbacks);
4596
4597 typedef struct
4598 {
4599 ma_audio_buffer_ref ref;
4600 ma_allocation_callbacks allocationCallbacks;
4601 ma_bool32 ownsData; /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
4602 ma_uint8 _pExtraData[1]; /* For allocating a buffer with the memory located directly after the other memory of the structure. */
4603 } ma_audio_buffer;
4604
4605 MA_API ma_result ma_audio_buffer_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
4606 MA_API ma_result ma_audio_buffer_init_copy(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
4607 MA_API ma_result ma_audio_buffer_alloc_and_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer** ppAudioBuffer); /* Always copies the data. Doesn't make sense to use this otherwise. Use ma_audio_buffer_uninit_and_free() to uninit. */
4608 MA_API void ma_audio_buffer_uninit(ma_audio_buffer* pAudioBuffer);
4609 MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer);
4610 MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
4611 MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex);
4612 MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
4613 MA_API ma_result ma_audio_buffer_unmap(ma_audio_buffer* pAudioBuffer, ma_uint64 frameCount); /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
4614 MA_API ma_bool32 ma_audio_buffer_at_end(const ma_audio_buffer* pAudioBuffer);
4615 MA_API ma_result ma_audio_buffer_get_cursor_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pCursor);
4616 MA_API ma_result ma_audio_buffer_get_length_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pLength);
4617 MA_API ma_result ma_audio_buffer_get_available_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames);
4618
4619
4620
4621 /************************************************************************************************************************************************************
4622
4623 VFS
4624 ===
4625
4626 The VFS object (virtual file system) is what's used to customize file access. This is useful in cases where stdio FILE* based APIs may not be entirely
4627 appropriate for a given situation.
4628
4629 ************************************************************************************************************************************************************/
4630 typedef void ma_vfs;
4631 typedef ma_handle ma_vfs_file;
4632
4633 #define MA_OPEN_MODE_READ 0x00000001
4634 #define MA_OPEN_MODE_WRITE 0x00000002
4635
4636 typedef enum
4637 {
4638 ma_seek_origin_start,
4639 ma_seek_origin_current,
4640 ma_seek_origin_end /* Not used by decoders. */
4641 } ma_seek_origin;
4642
4643 typedef struct
4644 {
4645 ma_uint64 sizeInBytes;
4646 } ma_file_info;
4647
4648 typedef struct
4649 {
4650 ma_result (* onOpen) (ma_vfs* pVFS, const char* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile);
4651 ma_result (* onOpenW)(ma_vfs* pVFS, const wchar_t* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile);
4652 ma_result (* onClose)(ma_vfs* pVFS, ma_vfs_file file);
4653 ma_result (* onRead) (ma_vfs* pVFS, ma_vfs_file file, void* pDst, size_t sizeInBytes, size_t* pBytesRead);
4654 ma_result (* onWrite)(ma_vfs* pVFS, ma_vfs_file file, const void* pSrc, size_t sizeInBytes, size_t* pBytesWritten);
4655 ma_result (* onSeek) (ma_vfs* pVFS, ma_vfs_file file, ma_int64 offset, ma_seek_origin origin);
4656 ma_result (* onTell) (ma_vfs* pVFS, ma_vfs_file file, ma_int64* pCursor);
4657 ma_result (* onInfo) (ma_vfs* pVFS, ma_vfs_file file, ma_file_info* pInfo);
4658 } ma_vfs_callbacks;
4659
4660 MA_API ma_result ma_vfs_open(ma_vfs* pVFS, const char* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile);
4661 MA_API ma_result ma_vfs_open_w(ma_vfs* pVFS, const wchar_t* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile);
4662 MA_API ma_result ma_vfs_close(ma_vfs* pVFS, ma_vfs_file file);
4663 MA_API ma_result ma_vfs_read(ma_vfs* pVFS, ma_vfs_file file, void* pDst, size_t sizeInBytes, size_t* pBytesRead);
4664 MA_API ma_result ma_vfs_write(ma_vfs* pVFS, ma_vfs_file file, const void* pSrc, size_t sizeInBytes, size_t* pBytesWritten);
4665 MA_API ma_result ma_vfs_seek(ma_vfs* pVFS, ma_vfs_file file, ma_int64 offset, ma_seek_origin origin);
4666 MA_API ma_result ma_vfs_tell(ma_vfs* pVFS, ma_vfs_file file, ma_int64* pCursor);
4667 MA_API ma_result ma_vfs_info(ma_vfs* pVFS, ma_vfs_file file, ma_file_info* pInfo);
4668 MA_API ma_result ma_vfs_open_and_read_file(ma_vfs* pVFS, const char* pFilePath, void** ppData, size_t* pSize, const ma_allocation_callbacks* pAllocationCallbacks);
4669
4670 typedef struct
4671 {
4672 ma_vfs_callbacks cb;
4673 ma_allocation_callbacks allocationCallbacks; /* Only used for the wchar_t version of open() on non-Windows platforms. */
4674 } ma_default_vfs;
4675
4676 MA_API ma_result ma_default_vfs_init(ma_default_vfs* pVFS, const ma_allocation_callbacks* pAllocationCallbacks);
4677
4678
4679
4680 typedef ma_result (* ma_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead, size_t* pBytesRead);
4681 typedef ma_result (* ma_seek_proc)(void* pUserData, ma_int64 offset, ma_seek_origin origin);
4682 typedef ma_result (* ma_tell_proc)(void* pUserData, ma_int64* pCursor);
4683
4684
4685
4686 #if !defined(MA_NO_DECODING) || !defined(MA_NO_ENCODING)
4687 typedef enum
4688 {
4689 ma_resource_format_wav
4690 } ma_resource_format;
4691
4692 typedef enum
4693 {
4694 ma_encoding_format_unknown = 0,
4695 ma_encoding_format_wav,
4696 ma_encoding_format_flac,
4697 ma_encoding_format_mp3,
4698 ma_encoding_format_vorbis
4699 } ma_encoding_format;
4700 #endif
4701
4702 /************************************************************************************************************************************************************
4703
4704 Decoding
4705 ========
4706
4707 Decoders are independent of the main device API. Decoding APIs can be called freely inside the device's data callback, but they are not thread safe unless
4708 you do your own synchronization.
4709
4710 ************************************************************************************************************************************************************/
4711 #ifndef MA_NO_DECODING
4712 typedef struct ma_decoder ma_decoder;
4713
4714
4715 typedef struct
4716 {
4717 ma_format preferredFormat;
4718 } ma_decoding_backend_config;
4719
4720 MA_API ma_decoding_backend_config ma_decoding_backend_config_init(ma_format preferredFormat);
4721
4722
4723 typedef struct
4724 {
4725 ma_result (* onInit )(void* pUserData, ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend);
4726 ma_result (* onInitFile )(void* pUserData, const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend); /* Optional. */
4727 ma_result (* onInitFileW )(void* pUserData, const wchar_t* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend); /* Optional. */
4728 ma_result (* onInitMemory )(void* pUserData, const void* pData, size_t dataSize, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend); /* Optional. */
4729 void (* onUninit )(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks);
4730 ma_result (* onGetChannelMap)(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap);
4731 } ma_decoding_backend_vtable;
4732
4733
4734 /* TODO: Convert read and seek to be consistent with the VFS API (ma_result return value, bytes read moved to an output parameter). */
4735 typedef size_t (* ma_decoder_read_proc)(ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead); /* Returns the number of bytes read. */
4736 typedef ma_bool32 (* ma_decoder_seek_proc)(ma_decoder* pDecoder, ma_int64 byteOffset, ma_seek_origin origin);
4737 typedef ma_result (* ma_decoder_tell_proc)(ma_decoder* pDecoder, ma_int64* pCursor);
4738
4739 typedef struct
4740 {
4741 ma_format format; /* Set to 0 or ma_format_unknown to use the stream's internal format. */
4742 ma_uint32 channels; /* Set to 0 to use the stream's internal channels. */
4743 ma_uint32 sampleRate; /* Set to 0 to use the stream's internal sample rate. */
4744 ma_channel channelMap[MA_MAX_CHANNELS];
4745 ma_channel_mix_mode channelMixMode;
4746 ma_dither_mode ditherMode;
4747 struct
4748 {
4749 ma_resample_algorithm algorithm;
4750 struct
4751 {
4752 ma_uint32 lpfOrder;
4753 } linear;
4754 struct
4755 {
4756 int quality;
4757 } speex;
4758 } resampling;
4759 ma_allocation_callbacks allocationCallbacks;
4760 ma_encoding_format encodingFormat;
4761 ma_decoding_backend_vtable** ppCustomBackendVTables;
4762 ma_uint32 customBackendCount;
4763 void* pCustomBackendUserData;
4764 } ma_decoder_config;
4765
4766 struct ma_decoder
4767 {
4768 ma_data_source_base ds;
4769 ma_data_source* pBackend; /* The decoding backend we'll be pulling data from. */
4770 const ma_decoding_backend_vtable* pBackendVTable; /* The vtable for the decoding backend. This needs to be stored so we can access the onUninit() callback. */
4771 void* pBackendUserData;
4772 ma_decoder_read_proc onRead;
4773 ma_decoder_seek_proc onSeek;
4774 ma_decoder_tell_proc onTell;
4775 void* pUserData;
4776 ma_uint64 readPointerInPCMFrames; /* In output sample rate. Used for keeping track of how many frames are available for decoding. */
4777 ma_format outputFormat;
4778 ma_uint32 outputChannels;
4779 ma_uint32 outputSampleRate;
4780 ma_channel outputChannelMap[MA_MAX_CHANNELS];
4781 ma_data_converter converter; /* <-- Data conversion is achieved by running frames through this. */
4782 ma_allocation_callbacks allocationCallbacks;
4783 union
4784 {
4785 struct
4786 {
4787 ma_vfs* pVFS;
4788 ma_vfs_file file;
4789 } vfs;
4790 struct
4791 {
4792 const ma_uint8* pData;
4793 size_t dataSize;
4794 size_t currentReadPos;
4795 } memory; /* Only used for decoders that were opened against a block of memory. */
4796 } data;
4797 };
4798
4799 MA_API ma_decoder_config ma_decoder_config_init(ma_format outputFormat, ma_uint32 outputChannels, ma_uint32 outputSampleRate);
4800 MA_API ma_decoder_config ma_decoder_config_init_default(void);
4801
4802 MA_API ma_result ma_decoder_init(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4803 MA_API ma_result ma_decoder_init_memory(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4804 MA_API ma_result ma_decoder_init_vfs(ma_vfs* pVFS, const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4805 MA_API ma_result ma_decoder_init_vfs_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4806 MA_API ma_result ma_decoder_init_file(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4807 MA_API ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4808
4809 /*
4810 Uninitializes a decoder.
4811 */
4812 MA_API ma_result ma_decoder_uninit(ma_decoder* pDecoder);
4813
4814 /*
4815 Retrieves the current position of the read cursor in PCM frames.
4816 */
4817 MA_API ma_result ma_decoder_get_cursor_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pCursor);
4818
4819 /*
4820 Retrieves the length of the decoder in PCM frames.
4821
4822 Do not call this on streams of an undefined length, such as internet radio.
4823
4824 If the length is unknown or an error occurs, 0 will be returned.
4825
4826 This will always return 0 for Vorbis decoders. This is due to a limitation with stb_vorbis in push mode which is what miniaudio
4827 uses internally.
4828
4829 For MP3's, this will decode the entire file. Do not call this in time critical scenarios.
4830
4831 This function is not thread safe without your own synchronization.
4832 */
4833 MA_API ma_uint64 ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder);
4834
4835 /*
4836 Reads PCM frames from the given decoder.
4837
4838 This is not thread safe without your own synchronization.
4839 */
4840 MA_API ma_uint64 ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount);
4841
4842 /*
4843 Seeks to a PCM frame based on it's absolute index.
4844
4845 This is not thread safe without your own synchronization.
4846 */
4847 MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex);
4848
4849 /*
4850 Retrieves the number of frames that can be read before reaching the end.
4851
4852 This calls `ma_decoder_get_length_in_pcm_frames()` so you need to be aware of the rules for that function, in
4853 particular ensuring you do not call it on streams of an undefined length, such as internet radio.
4854
4855 If the total length of the decoder cannot be retrieved, such as with Vorbis decoders, `MA_NOT_IMPLEMENTED` will be
4856 returned.
4857 */
4858 MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames);
4859
4860 /*
4861 Helper for opening and decoding a file into a heap allocated block of memory. Free the returned pointer with ma_free(). On input,
4862 pConfig should be set to what you want. On output it will be set to what you got.
4863 */
4864 MA_API ma_result ma_decode_from_vfs(ma_vfs* pVFS, const char* pFilePath, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
4865 MA_API ma_result ma_decode_file(const char* pFilePath, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
4866 MA_API ma_result ma_decode_memory(const void* pData, size_t dataSize, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
4867
4868
4869
4870
4871 /*
4872 DEPRECATED
4873
4874 Set the "encodingFormat" variable in the decoder config instead:
4875
4876 decoderConfig.encodingFormat = ma_encoding_format_wav;
4877
4878 These functions will be removed in version 0.11.
4879 */
4880 MA_API ma_result ma_decoder_init_wav(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4881 MA_API ma_result ma_decoder_init_flac(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4882 MA_API ma_result ma_decoder_init_mp3(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4883 MA_API ma_result ma_decoder_init_vorbis(ma_decoder_read_proc onRead, ma_decoder_seek_proc onSeek, void* pUserData, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4884 MA_API ma_result ma_decoder_init_memory_wav(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4885 MA_API ma_result ma_decoder_init_memory_flac(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4886 MA_API ma_result ma_decoder_init_memory_mp3(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4887 MA_API ma_result ma_decoder_init_memory_vorbis(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4888 MA_API ma_result ma_decoder_init_vfs_wav(ma_vfs* pVFS, const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4889 MA_API ma_result ma_decoder_init_vfs_flac(ma_vfs* pVFS, const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4890 MA_API ma_result ma_decoder_init_vfs_mp3(ma_vfs* pVFS, const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4891 MA_API ma_result ma_decoder_init_vfs_vorbis(ma_vfs* pVFS, const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4892 MA_API ma_result ma_decoder_init_vfs_wav_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4893 MA_API ma_result ma_decoder_init_vfs_flac_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4894 MA_API ma_result ma_decoder_init_vfs_mp3_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4895 MA_API ma_result ma_decoder_init_vfs_vorbis_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4896 MA_API ma_result ma_decoder_init_file_wav(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4897 MA_API ma_result ma_decoder_init_file_flac(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4898 MA_API ma_result ma_decoder_init_file_mp3(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4899 MA_API ma_result ma_decoder_init_file_vorbis(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4900 MA_API ma_result ma_decoder_init_file_wav_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4901 MA_API ma_result ma_decoder_init_file_flac_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4902 MA_API ma_result ma_decoder_init_file_mp3_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4903 MA_API ma_result ma_decoder_init_file_vorbis_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
4904
4905 #endif /* MA_NO_DECODING */
4906
4907
4908 /************************************************************************************************************************************************************
4909
4910 Encoding
4911 ========
4912
4913 Encoders do not perform any format conversion for you. If your target format does not support the format, and error will be returned.
4914
4915 ************************************************************************************************************************************************************/
4916 #ifndef MA_NO_ENCODING
4917 typedef struct ma_encoder ma_encoder;
4918
4919 typedef size_t (* ma_encoder_write_proc) (ma_encoder* pEncoder, const void* pBufferIn, size_t bytesToWrite); /* Returns the number of bytes written. */
4920 typedef ma_bool32 (* ma_encoder_seek_proc) (ma_encoder* pEncoder, int byteOffset, ma_seek_origin origin);
4921 typedef ma_result (* ma_encoder_init_proc) (ma_encoder* pEncoder);
4922 typedef void (* ma_encoder_uninit_proc) (ma_encoder* pEncoder);
4923 typedef ma_uint64 (* ma_encoder_write_pcm_frames_proc)(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount);
4924
4925 typedef struct
4926 {
4927 ma_resource_format resourceFormat;
4928 ma_format format;
4929 ma_uint32 channels;
4930 ma_uint32 sampleRate;
4931 ma_allocation_callbacks allocationCallbacks;
4932 } ma_encoder_config;
4933
4934 MA_API ma_encoder_config ma_encoder_config_init(ma_resource_format resourceFormat, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);
4935
4936 struct ma_encoder
4937 {
4938 ma_encoder_config config;
4939 ma_encoder_write_proc onWrite;
4940 ma_encoder_seek_proc onSeek;
4941 ma_encoder_init_proc onInit;
4942 ma_encoder_uninit_proc onUninit;
4943 ma_encoder_write_pcm_frames_proc onWritePCMFrames;
4944 void* pUserData;
4945 void* pInternalEncoder; /* <-- The drwav/drflac/stb_vorbis/etc. objects. */
4946 void* pFile; /* FILE*. Only used when initialized with ma_encoder_init_file(). */
4947 };
4948
4949 MA_API ma_result ma_encoder_init(ma_encoder_write_proc onWrite, ma_encoder_seek_proc onSeek, void* pUserData, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
4950 MA_API ma_result ma_encoder_init_file(const char* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
4951 MA_API ma_result ma_encoder_init_file_w(const wchar_t* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
4952 MA_API void ma_encoder_uninit(ma_encoder* pEncoder);
4953 MA_API ma_uint64 ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount);
4954
4955 #endif /* MA_NO_ENCODING */
4956
4957
4958 /************************************************************************************************************************************************************
4959
4960 Generation
4961
4962 ************************************************************************************************************************************************************/
4963 #ifndef MA_NO_GENERATION
4964 typedef enum
4965 {
4966 ma_waveform_type_sine,
4967 ma_waveform_type_square,
4968 ma_waveform_type_triangle,
4969 ma_waveform_type_sawtooth
4970 } ma_waveform_type;
4971
4972 typedef struct
4973 {
4974 ma_format format;
4975 ma_uint32 channels;
4976 ma_uint32 sampleRate;
4977 ma_waveform_type type;
4978 double amplitude;
4979 double frequency;
4980 } ma_waveform_config;
4981
4982 MA_API ma_waveform_config ma_waveform_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, ma_waveform_type type, double amplitude, double frequency);
4983
4984 typedef struct
4985 {
4986 ma_data_source_base ds;
4987 ma_waveform_config config;
4988 double advance;
4989 double time;
4990 } ma_waveform;
4991
4992 MA_API ma_result ma_waveform_init(const ma_waveform_config* pConfig, ma_waveform* pWaveform);
4993 MA_API void ma_waveform_uninit(ma_waveform* pWaveform);
4994 MA_API ma_uint64 ma_waveform_read_pcm_frames(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount);
4995 MA_API ma_result ma_waveform_seek_to_pcm_frame(ma_waveform* pWaveform, ma_uint64 frameIndex);
4996 MA_API ma_result ma_waveform_set_amplitude(ma_waveform* pWaveform, double amplitude);
4997 MA_API ma_result ma_waveform_set_frequency(ma_waveform* pWaveform, double frequency);
4998 MA_API ma_result ma_waveform_set_type(ma_waveform* pWaveform, ma_waveform_type type);
4999 MA_API ma_result ma_waveform_set_sample_rate(ma_waveform* pWaveform, ma_uint32 sampleRate);
5000
5001 typedef enum
5002 {
5003 ma_noise_type_white,
5004 ma_noise_type_pink,
5005 ma_noise_type_brownian
5006 } ma_noise_type;
5007
5008 typedef struct
5009 {
5010 ma_format format;
5011 ma_uint32 channels;
5012 ma_noise_type type;
5013 ma_int32 seed;
5014 double amplitude;
5015 ma_bool32 duplicateChannels;
5016 } ma_noise_config;
5017
5018 MA_API ma_noise_config ma_noise_config_init(ma_format format, ma_uint32 channels, ma_noise_type type, ma_int32 seed, double amplitude);
5019
5020 typedef struct
5021 {
5022 ma_data_source_vtable ds;
5023 ma_noise_config config;
5024 ma_lcg lcg;
5025 union
5026 {
5027 struct
5028 {
5029 double bin[MA_MAX_CHANNELS][16];
5030 double accumulation[MA_MAX_CHANNELS];
5031 ma_uint32 counter[MA_MAX_CHANNELS];
5032 } pink;
5033 struct
5034 {
5035 double accumulation[MA_MAX_CHANNELS];
5036 } brownian;
5037 } state;
5038 } ma_noise;
5039
5040 MA_API ma_result ma_noise_init(const ma_noise_config* pConfig, ma_noise* pNoise);
5041 MA_API void ma_noise_uninit(ma_noise* pNoise);
5042 MA_API ma_uint64 ma_noise_read_pcm_frames(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount);
5043 MA_API ma_result ma_noise_set_amplitude(ma_noise* pNoise, double amplitude);
5044 MA_API ma_result ma_noise_set_seed(ma_noise* pNoise, ma_int32 seed);
5045 MA_API ma_result ma_noise_set_type(ma_noise* pNoise, ma_noise_type type);
5046
5047 #endif /* MA_NO_GENERATION */
5048
5049 #ifdef __cplusplus
5050 }
5051 #endif
5052 #endif /* miniaudio_h */
5053
5054 /*
5055 This software is available as a choice of the following licenses. Choose
5056 whichever you prefer.
5057
5058 ===============================================================================
5059 ALTERNATIVE 1 - Public Domain (www.unlicense.org)
5060 ===============================================================================
5061 This is free and unencumbered software released into the public domain.
5062
5063 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
5064 software, either in source code form or as a compiled binary, for any purpose,
5065 commercial or non-commercial, and by any means.
5066
5067 In jurisdictions that recognize copyright laws, the author or authors of this
5068 software dedicate any and all copyright interest in the software to the public
5069 domain. We make this dedication for the benefit of the public at large and to
5070 the detriment of our heirs and successors. We intend this dedication to be an
5071 overt act of relinquishment in perpetuity of all present and future rights to
5072 this software under copyright law.
5073
5074 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5075 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5076 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5077 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
5078 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
5079 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5080
5081 For more information, please refer to <http://unlicense.org/>
5082
5083 ===============================================================================
5084 ALTERNATIVE 2 - MIT No Attribution
5085 ===============================================================================
5086 Copyright 2020 David Reid
5087
5088 Permission is hereby granted, free of charge, to any person obtaining a copy of
5089 this software and associated documentation files (the "Software"), to deal in
5090 the Software without restriction, including without limitation the rights to
5091 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
5092 of the Software, and to permit persons to whom the Software is furnished to do
5093 so.
5094
5095 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5096 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5097 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5098 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5099 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5100 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5101 SOFTWARE.
5102 */
5103