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