Subversion Repositories Games.Carmageddon

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 pmbaty 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.11.21 - 2023-11-15
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    11
23
#define MA_VERSION_REVISION 21
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
 
40
 
41
#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__)
42
    #define MA_SIZEOF_PTR   8
43
#else
44
    #define MA_SIZEOF_PTR   4
45
#endif
46
 
47
#include <stddef.h> /* For size_t. */
48
 
49
/* Sized types. */
50
#if defined(MA_USE_STDINT)
51
    #include <stdint.h>
52
    typedef int8_t   ma_int8;
53
    typedef uint8_t  ma_uint8;
54
    typedef int16_t  ma_int16;
55
    typedef uint16_t ma_uint16;
56
    typedef int32_t  ma_int32;
57
    typedef uint32_t ma_uint32;
58
    typedef int64_t  ma_int64;
59
    typedef uint64_t ma_uint64;
60
#else
61
    typedef   signed char           ma_int8;
62
    typedef unsigned char           ma_uint8;
63
    typedef   signed short          ma_int16;
64
    typedef unsigned short          ma_uint16;
65
    typedef   signed int            ma_int32;
66
    typedef unsigned int            ma_uint32;
67
    #if defined(_MSC_VER) && !defined(__clang__)
68
        typedef   signed __int64    ma_int64;
69
        typedef unsigned __int64    ma_uint64;
70
    #else
71
        #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
72
            #pragma GCC diagnostic push
73
            #pragma GCC diagnostic ignored "-Wlong-long"
74
            #if defined(__clang__)
75
                #pragma GCC diagnostic ignored "-Wc++11-long-long"
76
            #endif
77
        #endif
78
        typedef   signed long long  ma_int64;
79
        typedef unsigned long long  ma_uint64;
80
        #if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)))
81
            #pragma GCC diagnostic pop
82
        #endif
83
    #endif
84
#endif  /* MA_USE_STDINT */
85
 
86
#if MA_SIZEOF_PTR == 8
87
    typedef ma_uint64           ma_uintptr;
88
#else
89
    typedef ma_uint32           ma_uintptr;
90
#endif
91
 
92
typedef ma_uint8    ma_bool8;
93
typedef ma_uint32   ma_bool32;
94
#define MA_TRUE     1
95
#define MA_FALSE    0
96
 
97
/* These float types are not used universally by miniaudio. It's to simplify some macro expansion for atomic types. */
98
typedef float       ma_float;
99
typedef double      ma_double;
100
 
101
typedef void* ma_handle;
102
typedef void* ma_ptr;
103
 
104
/*
105
ma_proc is annoying because when compiling with GCC we get pendantic warnings about converting
106
between `void*` and `void (*)()`. We can't use `void (*)()` with MSVC however, because we'll get
107
warning C4191 about "type cast between incompatible function types". To work around this I'm going
108
to use a different data type depending on the compiler.
109
*/
110
#if defined(__GNUC__)
111
typedef void (*ma_proc)(void);
112
#else
113
typedef void* ma_proc;
114
#endif
115
 
116
#if defined(_MSC_VER) && !defined(_WCHAR_T_DEFINED)
117
typedef ma_uint16 wchar_t;
118
#endif
119
 
120
/* Define NULL for some compilers. */
121
#ifndef NULL
122
#define NULL 0
123
#endif
124
 
125
#if defined(SIZE_MAX)
126
    #define MA_SIZE_MAX    SIZE_MAX
127
#else
128
    #define MA_SIZE_MAX    0xFFFFFFFF  /* When SIZE_MAX is not defined by the standard library just default to the maximum 32-bit unsigned integer. */
129
#endif
130
 
131
 
132
/* Platform/backend detection. */
133
#if defined(_WIN32) || defined(__COSMOPOLITAN__)
134
    #define MA_WIN32
135
    #if defined(MA_FORCE_UWP) || (defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_PC_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) || (defined(WINAPI_FAMILY_PHONE_APP) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)))
136
        #define MA_WIN32_UWP
137
    #elif defined(WINAPI_FAMILY) && (defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES)
138
        #define MA_WIN32_GDK
139
    #else
140
        #define MA_WIN32_DESKTOP
141
    #endif
142
#endif
143
#if !defined(_WIN32)    /* If it's not Win32, assume POSIX. */
144
    #define MA_POSIX
145
 
146
    /*
147
    Use the MA_NO_PTHREAD_IN_HEADER option at your own risk. This is intentionally undocumented.
148
    You can use this to avoid including pthread.h in the header section. The downside is that it
149
    results in some fixed sized structures being declared for the various types that are used in
150
    miniaudio. The risk here is that these types might be too small for a given platform. This
151
    risk is yours to take and no support will be offered if you enable this option.
152
    */
153
    #ifndef MA_NO_PTHREAD_IN_HEADER
154
        #include <pthread.h>    /* Unfortunate #include, but needed for pthread_t, pthread_mutex_t and pthread_cond_t types. */
155
        typedef pthread_t       ma_pthread_t;
156
        typedef pthread_mutex_t ma_pthread_mutex_t;
157
        typedef pthread_cond_t  ma_pthread_cond_t;
158
    #else
159
        typedef ma_uintptr      ma_pthread_t;
160
        typedef union           ma_pthread_mutex_t { char __data[40]; ma_uint64 __alignment; } ma_pthread_mutex_t;
161
        typedef union           ma_pthread_cond_t  { char __data[48]; ma_uint64 __alignment; } ma_pthread_cond_t;
162
    #endif
163
 
164
    #if defined(__unix__)
165
        #define MA_UNIX
166
    #endif
167
    #if defined(__linux__)
168
        #define MA_LINUX
169
    #endif
170
    #if defined(__APPLE__)
171
        #define MA_APPLE
172
    #endif
173
    #if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
174
        #define MA_BSD
175
    #endif
176
    #if defined(__ANDROID__)
177
        #define MA_ANDROID
178
    #endif
179
    #if defined(__EMSCRIPTEN__)
180
        #define MA_EMSCRIPTEN
181
    #endif
182
    #if defined(__ORBIS__)
183
        #define MA_ORBIS
184
    #endif
185
    #if defined(__PROSPERO__)
186
        #define MA_PROSPERO
187
    #endif
188
    #if defined(__NX__)
189
        #define MA_NX
190
    #endif
191
    #if defined(__BEOS__) || defined(__HAIKU__)
192
        #define MA_BEOS
193
    #endif
194
    #if defined(__HAIKU__)
195
        #define MA_HAIKU
196
    #endif
197
#endif
198
 
199
#if defined(__has_c_attribute)
200
    #if __has_c_attribute(fallthrough)
201
        #define MA_FALLTHROUGH [[fallthrough]]
202
    #endif
203
#endif
204
#if !defined(MA_FALLTHROUGH) && defined(__has_attribute) && (defined(__clang__) || defined(__GNUC__))
205
    #if __has_attribute(fallthrough)
206
        #define MA_FALLTHROUGH __attribute__((fallthrough))
207
    #endif
208
#endif
209
#if !defined(MA_FALLTHROUGH)
210
    #define MA_FALLTHROUGH ((void)0)
211
#endif
212
 
213
#ifdef _MSC_VER
214
    #define MA_INLINE __forceinline
215
 
216
    /* noinline was introduced in Visual Studio 2005. */
217
    #if _MSC_VER >= 1400
218
        #define MA_NO_INLINE __declspec(noinline)
219
    #else
220
        #define MA_NO_INLINE
221
    #endif
222
#elif defined(__GNUC__)
223
    /*
224
    I've had a bug report where GCC is emitting warnings about functions possibly not being inlineable. This warning happens when
225
    the __attribute__((always_inline)) attribute is defined without an "inline" statement. I think therefore there must be some
226
    case where "__inline__" is not always defined, thus the compiler emitting these warnings. When using -std=c89 or -ansi on the
227
    command line, we cannot use the "inline" keyword and instead need to use "__inline__". In an attempt to work around this issue
228
    I am using "__inline__" only when we're compiling in strict ANSI mode.
229
    */
230
    #if defined(__STRICT_ANSI__)
231
        #define MA_GNUC_INLINE_HINT __inline__
232
    #else
233
        #define MA_GNUC_INLINE_HINT inline
234
    #endif
235
 
236
    #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)) || defined(__clang__)
237
        #define MA_INLINE MA_GNUC_INLINE_HINT __attribute__((always_inline))
238
        #define MA_NO_INLINE __attribute__((noinline))
239
    #else
240
        #define MA_INLINE MA_GNUC_INLINE_HINT
241
        #define MA_NO_INLINE __attribute__((noinline))
242
    #endif
243
#elif defined(__WATCOMC__)
244
    #define MA_INLINE __inline
245
    #define MA_NO_INLINE
246
#else
247
    #define MA_INLINE
248
    #define MA_NO_INLINE
249
#endif
250
 
251
/* MA_DLL is not officially supported. You're on your own if you want to use this. */
252
#if defined(MA_DLL)
253
    #if defined(_WIN32)
254
        #define MA_DLL_IMPORT  __declspec(dllimport)
255
        #define MA_DLL_EXPORT  __declspec(dllexport)
256
        #define MA_DLL_PRIVATE static
257
    #else
258
        #if defined(__GNUC__) && __GNUC__ >= 4
259
            #define MA_DLL_IMPORT  __attribute__((visibility("default")))
260
            #define MA_DLL_EXPORT  __attribute__((visibility("default")))
261
            #define MA_DLL_PRIVATE __attribute__((visibility("hidden")))
262
        #else
263
            #define MA_DLL_IMPORT
264
            #define MA_DLL_EXPORT
265
            #define MA_DLL_PRIVATE static
266
        #endif
267
    #endif
268
#endif
269
 
270
#if !defined(MA_API)
271
    #if defined(MA_DLL)
272
        #if defined(MINIAUDIO_IMPLEMENTATION) || defined(MA_IMPLEMENTATION)
273
            #define MA_API  MA_DLL_EXPORT
274
        #else
275
            #define MA_API  MA_DLL_IMPORT
276
        #endif
277
    #else
278
        #define MA_API extern
279
    #endif
280
#endif
281
 
282
#if !defined(MA_STATIC)
283
    #if defined(MA_DLL)
284
        #define MA_PRIVATE MA_DLL_PRIVATE
285
    #else
286
        #define MA_PRIVATE static
287
    #endif
288
#endif
289
 
290
 
291
/* SIMD alignment in bytes. Currently set to 32 bytes in preparation for future AVX optimizations. */
292
#define MA_SIMD_ALIGNMENT  32
293
 
294
/*
295
Special wchar_t type to ensure any structures in the public sections that reference it have a
296
consistent size across all platforms.
297
 
298
On Windows, wchar_t is 2 bytes, whereas everywhere else it's 4 bytes. Since Windows likes to use
299
wchar_t for it's IDs, we need a special explicitly sized wchar type that is always 2 bytes on all
300
platforms.
301
*/
302
#if !defined(MA_POSIX) && defined(MA_WIN32)
303
typedef wchar_t     ma_wchar_win32;
304
#else
305
typedef ma_uint16   ma_wchar_win32;
306
#endif
307
 
308
 
309
 
310
/*
311
Logging Levels
312
==============
313
Log levels are only used to give logging callbacks some context as to the severity of a log message
314
so they can do filtering. All log levels will be posted to registered logging callbacks. If you
315
don't want to output a certain log level you can discriminate against the log level in the callback.
316
 
317
MA_LOG_LEVEL_DEBUG
318
    Used for debugging. Useful for debug and test builds, but should be disabled in release builds.
319
 
320
MA_LOG_LEVEL_INFO
321
    Informational logging. Useful for debugging. This will never be called from within the data
322
    callback.
323
 
324
MA_LOG_LEVEL_WARNING
325
    Warnings. You should enable this in you development builds and action them when encounted. These
326
    logs usually indicate a potential problem or misconfiguration, but still allow you to keep
327
    running. This will never be called from within the data callback.
328
 
329
MA_LOG_LEVEL_ERROR
330
    Error logging. This will be fired when an operation fails and is subsequently aborted. This can
331
    be fired from within the data callback, in which case the device will be stopped. You should
332
    always have this log level enabled.
333
*/
334
typedef enum
335
{
336
    MA_LOG_LEVEL_DEBUG   = 4,
337
    MA_LOG_LEVEL_INFO    = 3,
338
    MA_LOG_LEVEL_WARNING = 2,
339
    MA_LOG_LEVEL_ERROR   = 1
340
} ma_log_level;
341
 
342
/*
343
Variables needing to be accessed atomically should be declared with this macro for two reasons:
344
 
345
    1) It allows people who read the code to identify a variable as such; and
346
    2) It forces alignment on platforms where it's required or optimal.
347
 
348
Note that for x86/64, alignment is not strictly necessary, but does have some performance
349
implications. Where supported by the compiler, alignment will be used, but otherwise if the CPU
350
architecture does not require it, it will simply leave it unaligned. This is the case with old
351
versions of Visual Studio, which I've confirmed with at least VC6.
352
*/
353
#if !defined(_MSC_VER) && defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
354
    #include <stdalign.h>
355
    #define MA_ATOMIC(alignment, type)            _Alignas(alignment) type
356
#else
357
    #if defined(__GNUC__)
358
        /* GCC-style compilers. */
359
        #define MA_ATOMIC(alignment, type)        type __attribute__((aligned(alignment)))
360
    #elif defined(_MSC_VER) && _MSC_VER > 1200  /* 1200 = VC6. Alignment not supported, but not necessary because x86 is the only supported target. */
361
        /* MSVC. */
362
        #define MA_ATOMIC(alignment, type)        __declspec(align(alignment)) type
363
    #else
364
        /* Other compilers. */
365
        #define MA_ATOMIC(alignment, type)        type
366
    #endif
367
#endif
368
 
369
typedef struct ma_context ma_context;
370
typedef struct ma_device ma_device;
371
 
372
typedef ma_uint8 ma_channel;
373
typedef enum
374
{
375
    MA_CHANNEL_NONE               = 0,
376
    MA_CHANNEL_MONO               = 1,
377
    MA_CHANNEL_FRONT_LEFT         = 2,
378
    MA_CHANNEL_FRONT_RIGHT        = 3,
379
    MA_CHANNEL_FRONT_CENTER       = 4,
380
    MA_CHANNEL_LFE                = 5,
381
    MA_CHANNEL_BACK_LEFT          = 6,
382
    MA_CHANNEL_BACK_RIGHT         = 7,
383
    MA_CHANNEL_FRONT_LEFT_CENTER  = 8,
384
    MA_CHANNEL_FRONT_RIGHT_CENTER = 9,
385
    MA_CHANNEL_BACK_CENTER        = 10,
386
    MA_CHANNEL_SIDE_LEFT          = 11,
387
    MA_CHANNEL_SIDE_RIGHT         = 12,
388
    MA_CHANNEL_TOP_CENTER         = 13,
389
    MA_CHANNEL_TOP_FRONT_LEFT     = 14,
390
    MA_CHANNEL_TOP_FRONT_CENTER   = 15,
391
    MA_CHANNEL_TOP_FRONT_RIGHT    = 16,
392
    MA_CHANNEL_TOP_BACK_LEFT      = 17,
393
    MA_CHANNEL_TOP_BACK_CENTER    = 18,
394
    MA_CHANNEL_TOP_BACK_RIGHT     = 19,
395
    MA_CHANNEL_AUX_0              = 20,
396
    MA_CHANNEL_AUX_1              = 21,
397
    MA_CHANNEL_AUX_2              = 22,
398
    MA_CHANNEL_AUX_3              = 23,
399
    MA_CHANNEL_AUX_4              = 24,
400
    MA_CHANNEL_AUX_5              = 25,
401
    MA_CHANNEL_AUX_6              = 26,
402
    MA_CHANNEL_AUX_7              = 27,
403
    MA_CHANNEL_AUX_8              = 28,
404
    MA_CHANNEL_AUX_9              = 29,
405
    MA_CHANNEL_AUX_10             = 30,
406
    MA_CHANNEL_AUX_11             = 31,
407
    MA_CHANNEL_AUX_12             = 32,
408
    MA_CHANNEL_AUX_13             = 33,
409
    MA_CHANNEL_AUX_14             = 34,
410
    MA_CHANNEL_AUX_15             = 35,
411
    MA_CHANNEL_AUX_16             = 36,
412
    MA_CHANNEL_AUX_17             = 37,
413
    MA_CHANNEL_AUX_18             = 38,
414
    MA_CHANNEL_AUX_19             = 39,
415
    MA_CHANNEL_AUX_20             = 40,
416
    MA_CHANNEL_AUX_21             = 41,
417
    MA_CHANNEL_AUX_22             = 42,
418
    MA_CHANNEL_AUX_23             = 43,
419
    MA_CHANNEL_AUX_24             = 44,
420
    MA_CHANNEL_AUX_25             = 45,
421
    MA_CHANNEL_AUX_26             = 46,
422
    MA_CHANNEL_AUX_27             = 47,
423
    MA_CHANNEL_AUX_28             = 48,
424
    MA_CHANNEL_AUX_29             = 49,
425
    MA_CHANNEL_AUX_30             = 50,
426
    MA_CHANNEL_AUX_31             = 51,
427
    MA_CHANNEL_LEFT               = MA_CHANNEL_FRONT_LEFT,
428
    MA_CHANNEL_RIGHT              = MA_CHANNEL_FRONT_RIGHT,
429
    MA_CHANNEL_POSITION_COUNT     = (MA_CHANNEL_AUX_31 + 1)
430
} _ma_channel_position; /* Do not use `_ma_channel_position` directly. Use `ma_channel` instead. */
431
 
432
typedef enum
433
{
434
    MA_SUCCESS                        =  0,
435
    MA_ERROR                          = -1,  /* A generic error. */
436
    MA_INVALID_ARGS                   = -2,
437
    MA_INVALID_OPERATION              = -3,
438
    MA_OUT_OF_MEMORY                  = -4,
439
    MA_OUT_OF_RANGE                   = -5,
440
    MA_ACCESS_DENIED                  = -6,
441
    MA_DOES_NOT_EXIST                 = -7,
442
    MA_ALREADY_EXISTS                 = -8,
443
    MA_TOO_MANY_OPEN_FILES            = -9,
444
    MA_INVALID_FILE                   = -10,
445
    MA_TOO_BIG                        = -11,
446
    MA_PATH_TOO_LONG                  = -12,
447
    MA_NAME_TOO_LONG                  = -13,
448
    MA_NOT_DIRECTORY                  = -14,
449
    MA_IS_DIRECTORY                   = -15,
450
    MA_DIRECTORY_NOT_EMPTY            = -16,
451
    MA_AT_END                         = -17,
452
    MA_NO_SPACE                       = -18,
453
    MA_BUSY                           = -19,
454
    MA_IO_ERROR                       = -20,
455
    MA_INTERRUPT                      = -21,
456
    MA_UNAVAILABLE                    = -22,
457
    MA_ALREADY_IN_USE                 = -23,
458
    MA_BAD_ADDRESS                    = -24,
459
    MA_BAD_SEEK                       = -25,
460
    MA_BAD_PIPE                       = -26,
461
    MA_DEADLOCK                       = -27,
462
    MA_TOO_MANY_LINKS                 = -28,
463
    MA_NOT_IMPLEMENTED                = -29,
464
    MA_NO_MESSAGE                     = -30,
465
    MA_BAD_MESSAGE                    = -31,
466
    MA_NO_DATA_AVAILABLE              = -32,
467
    MA_INVALID_DATA                   = -33,
468
    MA_TIMEOUT                        = -34,
469
    MA_NO_NETWORK                     = -35,
470
    MA_NOT_UNIQUE                     = -36,
471
    MA_NOT_SOCKET                     = -37,
472
    MA_NO_ADDRESS                     = -38,
473
    MA_BAD_PROTOCOL                   = -39,
474
    MA_PROTOCOL_UNAVAILABLE           = -40,
475
    MA_PROTOCOL_NOT_SUPPORTED         = -41,
476
    MA_PROTOCOL_FAMILY_NOT_SUPPORTED  = -42,
477
    MA_ADDRESS_FAMILY_NOT_SUPPORTED   = -43,
478
    MA_SOCKET_NOT_SUPPORTED           = -44,
479
    MA_CONNECTION_RESET               = -45,
480
    MA_ALREADY_CONNECTED              = -46,
481
    MA_NOT_CONNECTED                  = -47,
482
    MA_CONNECTION_REFUSED             = -48,
483
    MA_NO_HOST                        = -49,
484
    MA_IN_PROGRESS                    = -50,
485
    MA_CANCELLED                      = -51,
486
    MA_MEMORY_ALREADY_MAPPED          = -52,
487
 
488
    /* General non-standard errors. */
489
    MA_CRC_MISMATCH                   = -100,
490
 
491
    /* General miniaudio-specific errors. */
492
    MA_FORMAT_NOT_SUPPORTED           = -200,
493
    MA_DEVICE_TYPE_NOT_SUPPORTED      = -201,
494
    MA_SHARE_MODE_NOT_SUPPORTED       = -202,
495
    MA_NO_BACKEND                     = -203,
496
    MA_NO_DEVICE                      = -204,
497
    MA_API_NOT_FOUND                  = -205,
498
    MA_INVALID_DEVICE_CONFIG          = -206,
499
    MA_LOOP                           = -207,
500
    MA_BACKEND_NOT_ENABLED            = -208,
501
 
502
    /* State errors. */
503
    MA_DEVICE_NOT_INITIALIZED         = -300,
504
    MA_DEVICE_ALREADY_INITIALIZED     = -301,
505
    MA_DEVICE_NOT_STARTED             = -302,
506
    MA_DEVICE_NOT_STOPPED             = -303,
507
 
508
    /* Operation errors. */
509
    MA_FAILED_TO_INIT_BACKEND         = -400,
510
    MA_FAILED_TO_OPEN_BACKEND_DEVICE  = -401,
511
    MA_FAILED_TO_START_BACKEND_DEVICE = -402,
512
    MA_FAILED_TO_STOP_BACKEND_DEVICE  = -403
513
} ma_result;
514
 
515
 
516
#define MA_MIN_CHANNELS                 1
517
#ifndef MA_MAX_CHANNELS
518
#define MA_MAX_CHANNELS                 254
519
#endif
520
 
521
#ifndef MA_MAX_FILTER_ORDER
522
#define MA_MAX_FILTER_ORDER             8
523
#endif
524
 
525
typedef enum
526
{
527
    ma_stream_format_pcm = 0
528
} ma_stream_format;
529
 
530
typedef enum
531
{
532
    ma_stream_layout_interleaved = 0,
533
    ma_stream_layout_deinterleaved
534
} ma_stream_layout;
535
 
536
typedef enum
537
{
538
    ma_dither_mode_none = 0,
539
    ma_dither_mode_rectangle,
540
    ma_dither_mode_triangle
541
} ma_dither_mode;
542
 
543
typedef enum
544
{
545
    /*
546
    I like to keep these explicitly defined because they're used as a key into a lookup table. When items are
547
    added to this, make sure there are no gaps and that they're added to the lookup table in ma_get_bytes_per_sample().
548
    */
549
    ma_format_unknown = 0,     /* Mainly used for indicating an error, but also used as the default for the output format for decoders. */
550
    ma_format_u8      = 1,
551
    ma_format_s16     = 2,     /* Seems to be the most widely supported format. */
552
    ma_format_s24     = 3,     /* Tightly packed. 3 bytes per sample. */
553
    ma_format_s32     = 4,
554
    ma_format_f32     = 5,
555
    ma_format_count
556
} ma_format;
557
 
558
typedef enum
559
{
560
    /* Standard rates need to be in priority order. */
561
    ma_standard_sample_rate_48000  = 48000,     /* Most common */
562
    ma_standard_sample_rate_44100  = 44100,
563
 
564
    ma_standard_sample_rate_32000  = 32000,     /* Lows */
565
    ma_standard_sample_rate_24000  = 24000,
566
    ma_standard_sample_rate_22050  = 22050,
567
 
568
    ma_standard_sample_rate_88200  = 88200,     /* Highs */
569
    ma_standard_sample_rate_96000  = 96000,
570
    ma_standard_sample_rate_176400 = 176400,
571
    ma_standard_sample_rate_192000 = 192000,
572
 
573
    ma_standard_sample_rate_16000  = 16000,     /* Extreme lows */
574
    ma_standard_sample_rate_11025  = 11025,
575
    ma_standard_sample_rate_8000   = 8000,
576
 
577
    ma_standard_sample_rate_352800 = 352800,    /* Extreme highs */
578
    ma_standard_sample_rate_384000 = 384000,
579
 
580
    ma_standard_sample_rate_min    = ma_standard_sample_rate_8000,
581
    ma_standard_sample_rate_max    = ma_standard_sample_rate_384000,
582
    ma_standard_sample_rate_count  = 14         /* Need to maintain the count manually. Make sure this is updated if items are added to enum. */
583
} ma_standard_sample_rate;
584
 
585
 
586
typedef enum
587
{
588
    ma_channel_mix_mode_rectangular = 0,   /* Simple averaging based on the plane(s) the channel is sitting on. */
589
    ma_channel_mix_mode_simple,            /* Drop excess channels; zeroed out extra channels. */
590
    ma_channel_mix_mode_custom_weights,    /* Use custom weights specified in ma_channel_converter_config. */
591
    ma_channel_mix_mode_default = ma_channel_mix_mode_rectangular
592
} ma_channel_mix_mode;
593
 
594
typedef enum
595
{
596
    ma_standard_channel_map_microsoft,
597
    ma_standard_channel_map_alsa,
598
    ma_standard_channel_map_rfc3551,   /* Based off AIFF. */
599
    ma_standard_channel_map_flac,
600
    ma_standard_channel_map_vorbis,
601
    ma_standard_channel_map_sound4,    /* FreeBSD's sound(4). */
602
    ma_standard_channel_map_sndio,     /* www.sndio.org/tips.html */
603
    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. */
604
    ma_standard_channel_map_default = ma_standard_channel_map_microsoft
605
} ma_standard_channel_map;
606
 
607
typedef enum
608
{
609
    ma_performance_profile_low_latency = 0,
610
    ma_performance_profile_conservative
611
} ma_performance_profile;
612
 
613
 
614
typedef struct
615
{
616
    void* pUserData;
617
    void* (* onMalloc)(size_t sz, void* pUserData);
618
    void* (* onRealloc)(void* p, size_t sz, void* pUserData);
619
    void  (* onFree)(void* p, void* pUserData);
620
} ma_allocation_callbacks;
621
 
622
typedef struct
623
{
624
    ma_int32 state;
625
} ma_lcg;
626
 
627
 
628
/*
629
Atomics.
630
 
631
These are typesafe structures to prevent errors as a result of forgetting to reference variables atomically. It's too
632
easy to introduce subtle bugs where you accidentally do a regular assignment instead of an atomic load/store, etc. By
633
using a struct we can enforce the use of atomics at compile time.
634
 
635
These types are declared in the header section because we need to reference them in structs below, but functions for
636
using them are only exposed in the implementation section. I do not want these to be part of the public API.
637
 
638
There's a few downsides to this system. The first is that you need to declare a new struct for each type. Below are
639
some macros to help with the declarations. They will be named like so:
640
 
641
    ma_atomic_uint32 - atomic ma_uint32
642
    ma_atomic_int32  - atomic ma_int32
643
    ma_atomic_uint64 - atomic ma_uint64
644
    ma_atomic_float  - atomic float
645
    ma_atomic_bool32 - atomic ma_bool32
646
 
647
The other downside is that atomic pointers are extremely messy. You need to declare a new struct for each specific
648
type of pointer you need to make atomic. For example, an atomic ma_node* will look like this:
649
 
650
    MA_ATOMIC_SAFE_TYPE_IMPL_PTR(node)
651
 
652
Which will declare a type struct that's named like so:
653
 
654
    ma_atomic_ptr_node
655
 
656
Functions to use the atomic types are declared in the implementation section. All atomic functions are prefixed with
657
the name of the struct. For example:
658
 
659
    ma_atomic_uint32_set() - Atomic store of ma_uint32
660
    ma_atomic_uint32_get() - Atomic load of ma_uint32
661
    etc.
662
 
663
For pointer types it's the same, which makes them a bit messy to use due to the length of each function name, but in
664
return you get type safety and enforcement of atomic operations.
665
*/
666
#define MA_ATOMIC_SAFE_TYPE_DECL(c89TypeExtension, typeSize, type) \
667
    typedef struct \
668
    { \
669
        MA_ATOMIC(typeSize, ma_##type) value; \
670
    } ma_atomic_##type; \
671
 
672
#define MA_ATOMIC_SAFE_TYPE_DECL_PTR(type) \
673
    typedef struct \
674
    { \
675
        MA_ATOMIC(MA_SIZEOF_PTR, ma_##type*) value; \
676
    } ma_atomic_ptr_##type; \
677
 
678
MA_ATOMIC_SAFE_TYPE_DECL(32,  4, uint32)
679
MA_ATOMIC_SAFE_TYPE_DECL(i32, 4, int32)
680
MA_ATOMIC_SAFE_TYPE_DECL(64,  8, uint64)
681
MA_ATOMIC_SAFE_TYPE_DECL(f32, 4, float)
682
MA_ATOMIC_SAFE_TYPE_DECL(32,  4, bool32)
683
 
684
 
685
/* Spinlocks are 32-bit for compatibility reasons. */
686
typedef ma_uint32 ma_spinlock;
687
 
688
#ifndef MA_NO_THREADING
689
    /* Thread priorities should be ordered such that the default priority of the worker thread is 0. */
690
    typedef enum
691
    {
692
        ma_thread_priority_idle     = -5,
693
        ma_thread_priority_lowest   = -4,
694
        ma_thread_priority_low      = -3,
695
        ma_thread_priority_normal   = -2,
696
        ma_thread_priority_high     = -1,
697
        ma_thread_priority_highest  =  0,
698
        ma_thread_priority_realtime =  1,
699
        ma_thread_priority_default  =  0
700
    } ma_thread_priority;
701
 
702
    #if defined(MA_POSIX)
703
        typedef ma_pthread_t ma_thread;
704
    #elif defined(MA_WIN32)
705
        typedef ma_handle ma_thread;
706
    #endif
707
 
708
    #if defined(MA_POSIX)
709
        typedef ma_pthread_mutex_t ma_mutex;
710
    #elif defined(MA_WIN32)
711
        typedef ma_handle ma_mutex;
712
    #endif
713
 
714
    #if defined(MA_POSIX)
715
        typedef struct
716
        {
717
            ma_uint32 value;
718
            ma_pthread_mutex_t lock;
719
            ma_pthread_cond_t cond;
720
        } ma_event;
721
    #elif defined(MA_WIN32)
722
        typedef ma_handle ma_event;
723
    #endif
724
 
725
    #if defined(MA_POSIX)
726
        typedef struct
727
        {
728
            int value;
729
            ma_pthread_mutex_t lock;
730
            ma_pthread_cond_t cond;
731
        } ma_semaphore;
732
    #elif defined(MA_WIN32)
733
        typedef ma_handle ma_semaphore;
734
    #endif
735
#else
736
    /* 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. */
737
    #ifndef MA_NO_DEVICE_IO
738
        #error "MA_NO_THREADING cannot be used without MA_NO_DEVICE_IO";
739
    #endif
740
#endif  /* MA_NO_THREADING */
741
 
742
 
743
/*
744
Retrieves the version of miniaudio as separated integers. Each component can be NULL if it's not required.
745
*/
746
MA_API void ma_version(ma_uint32* pMajor, ma_uint32* pMinor, ma_uint32* pRevision);
747
 
748
/*
749
Retrieves the version of miniaudio as a string which can be useful for logging purposes.
750
*/
751
MA_API const char* ma_version_string(void);
752
 
753
 
754
/**************************************************************************************************************************************************************
755
 
756
Logging
757
 
758
**************************************************************************************************************************************************************/
759
#include <stdarg.h> /* For va_list. */
760
 
761
#if defined(__has_attribute)
762
    #if __has_attribute(format)
763
        #define MA_ATTRIBUTE_FORMAT(fmt, va) __attribute__((format(printf, fmt, va)))
764
    #endif
765
#endif
766
#ifndef MA_ATTRIBUTE_FORMAT
767
#define MA_ATTRIBUTE_FORMAT(fmt, va)
768
#endif
769
 
770
#ifndef MA_MAX_LOG_CALLBACKS
771
#define MA_MAX_LOG_CALLBACKS    4
772
#endif
773
 
774
 
775
/*
776
The callback for handling log messages.
777
 
778
 
779
Parameters
780
----------
781
pUserData (in)
782
    The user data pointer that was passed into ma_log_register_callback().
783
 
784
logLevel (in)
785
    The log level. This can be one of the following:
786
 
787
    +----------------------+
788
    | Log Level            |
789
    +----------------------+
790
    | MA_LOG_LEVEL_DEBUG   |
791
    | MA_LOG_LEVEL_INFO    |
792
    | MA_LOG_LEVEL_WARNING |
793
    | MA_LOG_LEVEL_ERROR   |
794
    +----------------------+
795
 
796
pMessage (in)
797
    The log message.
798
*/
799
typedef void (* ma_log_callback_proc)(void* pUserData, ma_uint32 level, const char* pMessage);
800
 
801
typedef struct
802
{
803
    ma_log_callback_proc onLog;
804
    void* pUserData;
805
} ma_log_callback;
806
 
807
MA_API ma_log_callback ma_log_callback_init(ma_log_callback_proc onLog, void* pUserData);
808
 
809
 
810
typedef struct
811
{
812
    ma_log_callback callbacks[MA_MAX_LOG_CALLBACKS];
813
    ma_uint32 callbackCount;
814
    ma_allocation_callbacks allocationCallbacks;    /* Need to store these persistently because ma_log_postv() might need to allocate a buffer on the heap. */
815
#ifndef MA_NO_THREADING
816
    ma_mutex lock;  /* For thread safety just to make it easier and safer for the logging implementation. */
817
#endif
818
} ma_log;
819
 
820
MA_API ma_result ma_log_init(const ma_allocation_callbacks* pAllocationCallbacks, ma_log* pLog);
821
MA_API void ma_log_uninit(ma_log* pLog);
822
MA_API ma_result ma_log_register_callback(ma_log* pLog, ma_log_callback callback);
823
MA_API ma_result ma_log_unregister_callback(ma_log* pLog, ma_log_callback callback);
824
MA_API ma_result ma_log_post(ma_log* pLog, ma_uint32 level, const char* pMessage);
825
MA_API ma_result ma_log_postv(ma_log* pLog, ma_uint32 level, const char* pFormat, va_list args);
826
MA_API ma_result ma_log_postf(ma_log* pLog, ma_uint32 level, const char* pFormat, ...) MA_ATTRIBUTE_FORMAT(3, 4);
827
 
828
 
829
/**************************************************************************************************************************************************************
830
 
831
Biquad Filtering
832
 
833
**************************************************************************************************************************************************************/
834
typedef union
835
{
836
    float    f32;
837
    ma_int32 s32;
838
} ma_biquad_coefficient;
839
 
840
typedef struct
841
{
842
    ma_format format;
843
    ma_uint32 channels;
844
    double b0;
845
    double b1;
846
    double b2;
847
    double a0;
848
    double a1;
849
    double a2;
850
} ma_biquad_config;
851
 
852
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);
853
 
854
typedef struct
855
{
856
    ma_format format;
857
    ma_uint32 channels;
858
    ma_biquad_coefficient b0;
859
    ma_biquad_coefficient b1;
860
    ma_biquad_coefficient b2;
861
    ma_biquad_coefficient a1;
862
    ma_biquad_coefficient a2;
863
    ma_biquad_coefficient* pR1;
864
    ma_biquad_coefficient* pR2;
865
 
866
    /* Memory management. */
867
    void* _pHeap;
868
    ma_bool32 _ownsHeap;
869
} ma_biquad;
870
 
871
MA_API ma_result ma_biquad_get_heap_size(const ma_biquad_config* pConfig, size_t* pHeapSizeInBytes);
872
MA_API ma_result ma_biquad_init_preallocated(const ma_biquad_config* pConfig, void* pHeap, ma_biquad* pBQ);
873
MA_API ma_result ma_biquad_init(const ma_biquad_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_biquad* pBQ);
874
MA_API void ma_biquad_uninit(ma_biquad* pBQ, const ma_allocation_callbacks* pAllocationCallbacks);
875
MA_API ma_result ma_biquad_reinit(const ma_biquad_config* pConfig, ma_biquad* pBQ);
876
MA_API ma_result ma_biquad_clear_cache(ma_biquad* pBQ);
877
MA_API ma_result ma_biquad_process_pcm_frames(ma_biquad* pBQ, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
878
MA_API ma_uint32 ma_biquad_get_latency(const ma_biquad* pBQ);
879
 
880
 
881
/**************************************************************************************************************************************************************
882
 
883
Low-Pass Filtering
884
 
885
**************************************************************************************************************************************************************/
886
typedef struct
887
{
888
    ma_format format;
889
    ma_uint32 channels;
890
    ma_uint32 sampleRate;
891
    double cutoffFrequency;
892
    double q;
893
} ma_lpf1_config, ma_lpf2_config;
894
 
895
MA_API ma_lpf1_config ma_lpf1_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
896
MA_API ma_lpf2_config ma_lpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
897
 
898
typedef struct
899
{
900
    ma_format format;
901
    ma_uint32 channels;
902
    ma_biquad_coefficient a;
903
    ma_biquad_coefficient* pR1;
904
 
905
    /* Memory management. */
906
    void* _pHeap;
907
    ma_bool32 _ownsHeap;
908
} ma_lpf1;
909
 
910
MA_API ma_result ma_lpf1_get_heap_size(const ma_lpf1_config* pConfig, size_t* pHeapSizeInBytes);
911
MA_API ma_result ma_lpf1_init_preallocated(const ma_lpf1_config* pConfig, void* pHeap, ma_lpf1* pLPF);
912
MA_API ma_result ma_lpf1_init(const ma_lpf1_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_lpf1* pLPF);
913
MA_API void ma_lpf1_uninit(ma_lpf1* pLPF, const ma_allocation_callbacks* pAllocationCallbacks);
914
MA_API ma_result ma_lpf1_reinit(const ma_lpf1_config* pConfig, ma_lpf1* pLPF);
915
MA_API ma_result ma_lpf1_clear_cache(ma_lpf1* pLPF);
916
MA_API ma_result ma_lpf1_process_pcm_frames(ma_lpf1* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
917
MA_API ma_uint32 ma_lpf1_get_latency(const ma_lpf1* pLPF);
918
 
919
typedef struct
920
{
921
    ma_biquad bq;   /* The second order low-pass filter is implemented as a biquad filter. */
922
} ma_lpf2;
923
 
924
MA_API ma_result ma_lpf2_get_heap_size(const ma_lpf2_config* pConfig, size_t* pHeapSizeInBytes);
925
MA_API ma_result ma_lpf2_init_preallocated(const ma_lpf2_config* pConfig, void* pHeap, ma_lpf2* pHPF);
926
MA_API ma_result ma_lpf2_init(const ma_lpf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_lpf2* pLPF);
927
MA_API void ma_lpf2_uninit(ma_lpf2* pLPF, const ma_allocation_callbacks* pAllocationCallbacks);
928
MA_API ma_result ma_lpf2_reinit(const ma_lpf2_config* pConfig, ma_lpf2* pLPF);
929
MA_API ma_result ma_lpf2_clear_cache(ma_lpf2* pLPF);
930
MA_API ma_result ma_lpf2_process_pcm_frames(ma_lpf2* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
931
MA_API ma_uint32 ma_lpf2_get_latency(const ma_lpf2* pLPF);
932
 
933
 
934
typedef struct
935
{
936
    ma_format format;
937
    ma_uint32 channels;
938
    ma_uint32 sampleRate;
939
    double cutoffFrequency;
940
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
941
} ma_lpf_config;
942
 
943
MA_API ma_lpf_config ma_lpf_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
944
 
945
typedef struct
946
{
947
    ma_format format;
948
    ma_uint32 channels;
949
    ma_uint32 sampleRate;
950
    ma_uint32 lpf1Count;
951
    ma_uint32 lpf2Count;
952
    ma_lpf1* pLPF1;
953
    ma_lpf2* pLPF2;
954
 
955
    /* Memory management. */
956
    void* _pHeap;
957
    ma_bool32 _ownsHeap;
958
} ma_lpf;
959
 
960
MA_API ma_result ma_lpf_get_heap_size(const ma_lpf_config* pConfig, size_t* pHeapSizeInBytes);
961
MA_API ma_result ma_lpf_init_preallocated(const ma_lpf_config* pConfig, void* pHeap, ma_lpf* pLPF);
962
MA_API ma_result ma_lpf_init(const ma_lpf_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_lpf* pLPF);
963
MA_API void ma_lpf_uninit(ma_lpf* pLPF, const ma_allocation_callbacks* pAllocationCallbacks);
964
MA_API ma_result ma_lpf_reinit(const ma_lpf_config* pConfig, ma_lpf* pLPF);
965
MA_API ma_result ma_lpf_clear_cache(ma_lpf* pLPF);
966
MA_API ma_result ma_lpf_process_pcm_frames(ma_lpf* pLPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
967
MA_API ma_uint32 ma_lpf_get_latency(const ma_lpf* pLPF);
968
 
969
 
970
/**************************************************************************************************************************************************************
971
 
972
High-Pass Filtering
973
 
974
**************************************************************************************************************************************************************/
975
typedef struct
976
{
977
    ma_format format;
978
    ma_uint32 channels;
979
    ma_uint32 sampleRate;
980
    double cutoffFrequency;
981
    double q;
982
} ma_hpf1_config, ma_hpf2_config;
983
 
984
MA_API ma_hpf1_config ma_hpf1_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency);
985
MA_API ma_hpf2_config ma_hpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
986
 
987
typedef struct
988
{
989
    ma_format format;
990
    ma_uint32 channels;
991
    ma_biquad_coefficient a;
992
    ma_biquad_coefficient* pR1;
993
 
994
    /* Memory management. */
995
    void* _pHeap;
996
    ma_bool32 _ownsHeap;
997
} ma_hpf1;
998
 
999
MA_API ma_result ma_hpf1_get_heap_size(const ma_hpf1_config* pConfig, size_t* pHeapSizeInBytes);
1000
MA_API ma_result ma_hpf1_init_preallocated(const ma_hpf1_config* pConfig, void* pHeap, ma_hpf1* pLPF);
1001
MA_API ma_result ma_hpf1_init(const ma_hpf1_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hpf1* pHPF);
1002
MA_API void ma_hpf1_uninit(ma_hpf1* pHPF, const ma_allocation_callbacks* pAllocationCallbacks);
1003
MA_API ma_result ma_hpf1_reinit(const ma_hpf1_config* pConfig, ma_hpf1* pHPF);
1004
MA_API ma_result ma_hpf1_process_pcm_frames(ma_hpf1* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1005
MA_API ma_uint32 ma_hpf1_get_latency(const ma_hpf1* pHPF);
1006
 
1007
typedef struct
1008
{
1009
    ma_biquad bq;   /* The second order high-pass filter is implemented as a biquad filter. */
1010
} ma_hpf2;
1011
 
1012
MA_API ma_result ma_hpf2_get_heap_size(const ma_hpf2_config* pConfig, size_t* pHeapSizeInBytes);
1013
MA_API ma_result ma_hpf2_init_preallocated(const ma_hpf2_config* pConfig, void* pHeap, ma_hpf2* pHPF);
1014
MA_API ma_result ma_hpf2_init(const ma_hpf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hpf2* pHPF);
1015
MA_API void ma_hpf2_uninit(ma_hpf2* pHPF, const ma_allocation_callbacks* pAllocationCallbacks);
1016
MA_API ma_result ma_hpf2_reinit(const ma_hpf2_config* pConfig, ma_hpf2* pHPF);
1017
MA_API ma_result ma_hpf2_process_pcm_frames(ma_hpf2* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1018
MA_API ma_uint32 ma_hpf2_get_latency(const ma_hpf2* pHPF);
1019
 
1020
 
1021
typedef struct
1022
{
1023
    ma_format format;
1024
    ma_uint32 channels;
1025
    ma_uint32 sampleRate;
1026
    double cutoffFrequency;
1027
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
1028
} ma_hpf_config;
1029
 
1030
MA_API ma_hpf_config ma_hpf_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
1031
 
1032
typedef struct
1033
{
1034
    ma_format format;
1035
    ma_uint32 channels;
1036
    ma_uint32 sampleRate;
1037
    ma_uint32 hpf1Count;
1038
    ma_uint32 hpf2Count;
1039
    ma_hpf1* pHPF1;
1040
    ma_hpf2* pHPF2;
1041
 
1042
    /* Memory management. */
1043
    void* _pHeap;
1044
    ma_bool32 _ownsHeap;
1045
} ma_hpf;
1046
 
1047
MA_API ma_result ma_hpf_get_heap_size(const ma_hpf_config* pConfig, size_t* pHeapSizeInBytes);
1048
MA_API ma_result ma_hpf_init_preallocated(const ma_hpf_config* pConfig, void* pHeap, ma_hpf* pLPF);
1049
MA_API ma_result ma_hpf_init(const ma_hpf_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hpf* pHPF);
1050
MA_API void ma_hpf_uninit(ma_hpf* pHPF, const ma_allocation_callbacks* pAllocationCallbacks);
1051
MA_API ma_result ma_hpf_reinit(const ma_hpf_config* pConfig, ma_hpf* pHPF);
1052
MA_API ma_result ma_hpf_process_pcm_frames(ma_hpf* pHPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1053
MA_API ma_uint32 ma_hpf_get_latency(const ma_hpf* pHPF);
1054
 
1055
 
1056
/**************************************************************************************************************************************************************
1057
 
1058
Band-Pass Filtering
1059
 
1060
**************************************************************************************************************************************************************/
1061
typedef struct
1062
{
1063
    ma_format format;
1064
    ma_uint32 channels;
1065
    ma_uint32 sampleRate;
1066
    double cutoffFrequency;
1067
    double q;
1068
} ma_bpf2_config;
1069
 
1070
MA_API ma_bpf2_config ma_bpf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, double q);
1071
 
1072
typedef struct
1073
{
1074
    ma_biquad bq;   /* The second order band-pass filter is implemented as a biquad filter. */
1075
} ma_bpf2;
1076
 
1077
MA_API ma_result ma_bpf2_get_heap_size(const ma_bpf2_config* pConfig, size_t* pHeapSizeInBytes);
1078
MA_API ma_result ma_bpf2_init_preallocated(const ma_bpf2_config* pConfig, void* pHeap, ma_bpf2* pBPF);
1079
MA_API ma_result ma_bpf2_init(const ma_bpf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_bpf2* pBPF);
1080
MA_API void ma_bpf2_uninit(ma_bpf2* pBPF, const ma_allocation_callbacks* pAllocationCallbacks);
1081
MA_API ma_result ma_bpf2_reinit(const ma_bpf2_config* pConfig, ma_bpf2* pBPF);
1082
MA_API ma_result ma_bpf2_process_pcm_frames(ma_bpf2* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1083
MA_API ma_uint32 ma_bpf2_get_latency(const ma_bpf2* pBPF);
1084
 
1085
 
1086
typedef struct
1087
{
1088
    ma_format format;
1089
    ma_uint32 channels;
1090
    ma_uint32 sampleRate;
1091
    double cutoffFrequency;
1092
    ma_uint32 order;    /* If set to 0, will be treated as a passthrough (no filtering will be applied). */
1093
} ma_bpf_config;
1094
 
1095
MA_API ma_bpf_config ma_bpf_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
1096
 
1097
typedef struct
1098
{
1099
    ma_format format;
1100
    ma_uint32 channels;
1101
    ma_uint32 bpf2Count;
1102
    ma_bpf2* pBPF2;
1103
 
1104
    /* Memory management. */
1105
    void* _pHeap;
1106
    ma_bool32 _ownsHeap;
1107
} ma_bpf;
1108
 
1109
MA_API ma_result ma_bpf_get_heap_size(const ma_bpf_config* pConfig, size_t* pHeapSizeInBytes);
1110
MA_API ma_result ma_bpf_init_preallocated(const ma_bpf_config* pConfig, void* pHeap, ma_bpf* pBPF);
1111
MA_API ma_result ma_bpf_init(const ma_bpf_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_bpf* pBPF);
1112
MA_API void ma_bpf_uninit(ma_bpf* pBPF, const ma_allocation_callbacks* pAllocationCallbacks);
1113
MA_API ma_result ma_bpf_reinit(const ma_bpf_config* pConfig, ma_bpf* pBPF);
1114
MA_API ma_result ma_bpf_process_pcm_frames(ma_bpf* pBPF, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1115
MA_API ma_uint32 ma_bpf_get_latency(const ma_bpf* pBPF);
1116
 
1117
 
1118
/**************************************************************************************************************************************************************
1119
 
1120
Notching Filter
1121
 
1122
**************************************************************************************************************************************************************/
1123
typedef struct
1124
{
1125
    ma_format format;
1126
    ma_uint32 channels;
1127
    ma_uint32 sampleRate;
1128
    double q;
1129
    double frequency;
1130
} ma_notch2_config, ma_notch_config;
1131
 
1132
MA_API ma_notch2_config ma_notch2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double q, double frequency);
1133
 
1134
typedef struct
1135
{
1136
    ma_biquad bq;
1137
} ma_notch2;
1138
 
1139
MA_API ma_result ma_notch2_get_heap_size(const ma_notch2_config* pConfig, size_t* pHeapSizeInBytes);
1140
MA_API ma_result ma_notch2_init_preallocated(const ma_notch2_config* pConfig, void* pHeap, ma_notch2* pFilter);
1141
MA_API ma_result ma_notch2_init(const ma_notch2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_notch2* pFilter);
1142
MA_API void ma_notch2_uninit(ma_notch2* pFilter, const ma_allocation_callbacks* pAllocationCallbacks);
1143
MA_API ma_result ma_notch2_reinit(const ma_notch2_config* pConfig, ma_notch2* pFilter);
1144
MA_API ma_result ma_notch2_process_pcm_frames(ma_notch2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1145
MA_API ma_uint32 ma_notch2_get_latency(const ma_notch2* pFilter);
1146
 
1147
 
1148
/**************************************************************************************************************************************************************
1149
 
1150
Peaking EQ Filter
1151
 
1152
**************************************************************************************************************************************************************/
1153
typedef struct
1154
{
1155
    ma_format format;
1156
    ma_uint32 channels;
1157
    ma_uint32 sampleRate;
1158
    double gainDB;
1159
    double q;
1160
    double frequency;
1161
} ma_peak2_config, ma_peak_config;
1162
 
1163
MA_API ma_peak2_config ma_peak2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency);
1164
 
1165
typedef struct
1166
{
1167
    ma_biquad bq;
1168
} ma_peak2;
1169
 
1170
MA_API ma_result ma_peak2_get_heap_size(const ma_peak2_config* pConfig, size_t* pHeapSizeInBytes);
1171
MA_API ma_result ma_peak2_init_preallocated(const ma_peak2_config* pConfig, void* pHeap, ma_peak2* pFilter);
1172
MA_API ma_result ma_peak2_init(const ma_peak2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_peak2* pFilter);
1173
MA_API void ma_peak2_uninit(ma_peak2* pFilter, const ma_allocation_callbacks* pAllocationCallbacks);
1174
MA_API ma_result ma_peak2_reinit(const ma_peak2_config* pConfig, ma_peak2* pFilter);
1175
MA_API ma_result ma_peak2_process_pcm_frames(ma_peak2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1176
MA_API ma_uint32 ma_peak2_get_latency(const ma_peak2* pFilter);
1177
 
1178
 
1179
/**************************************************************************************************************************************************************
1180
 
1181
Low Shelf Filter
1182
 
1183
**************************************************************************************************************************************************************/
1184
typedef struct
1185
{
1186
    ma_format format;
1187
    ma_uint32 channels;
1188
    ma_uint32 sampleRate;
1189
    double gainDB;
1190
    double shelfSlope;
1191
    double frequency;
1192
} ma_loshelf2_config, ma_loshelf_config;
1193
 
1194
MA_API ma_loshelf2_config ma_loshelf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double shelfSlope, double frequency);
1195
 
1196
typedef struct
1197
{
1198
    ma_biquad bq;
1199
} ma_loshelf2;
1200
 
1201
MA_API ma_result ma_loshelf2_get_heap_size(const ma_loshelf2_config* pConfig, size_t* pHeapSizeInBytes);
1202
MA_API ma_result ma_loshelf2_init_preallocated(const ma_loshelf2_config* pConfig, void* pHeap, ma_loshelf2* pFilter);
1203
MA_API ma_result ma_loshelf2_init(const ma_loshelf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_loshelf2* pFilter);
1204
MA_API void ma_loshelf2_uninit(ma_loshelf2* pFilter, const ma_allocation_callbacks* pAllocationCallbacks);
1205
MA_API ma_result ma_loshelf2_reinit(const ma_loshelf2_config* pConfig, ma_loshelf2* pFilter);
1206
MA_API ma_result ma_loshelf2_process_pcm_frames(ma_loshelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1207
MA_API ma_uint32 ma_loshelf2_get_latency(const ma_loshelf2* pFilter);
1208
 
1209
 
1210
/**************************************************************************************************************************************************************
1211
 
1212
High Shelf Filter
1213
 
1214
**************************************************************************************************************************************************************/
1215
typedef struct
1216
{
1217
    ma_format format;
1218
    ma_uint32 channels;
1219
    ma_uint32 sampleRate;
1220
    double gainDB;
1221
    double shelfSlope;
1222
    double frequency;
1223
} ma_hishelf2_config, ma_hishelf_config;
1224
 
1225
MA_API ma_hishelf2_config ma_hishelf2_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double shelfSlope, double frequency);
1226
 
1227
typedef struct
1228
{
1229
    ma_biquad bq;
1230
} ma_hishelf2;
1231
 
1232
MA_API ma_result ma_hishelf2_get_heap_size(const ma_hishelf2_config* pConfig, size_t* pHeapSizeInBytes);
1233
MA_API ma_result ma_hishelf2_init_preallocated(const ma_hishelf2_config* pConfig, void* pHeap, ma_hishelf2* pFilter);
1234
MA_API ma_result ma_hishelf2_init(const ma_hishelf2_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hishelf2* pFilter);
1235
MA_API void ma_hishelf2_uninit(ma_hishelf2* pFilter, const ma_allocation_callbacks* pAllocationCallbacks);
1236
MA_API ma_result ma_hishelf2_reinit(const ma_hishelf2_config* pConfig, ma_hishelf2* pFilter);
1237
MA_API ma_result ma_hishelf2_process_pcm_frames(ma_hishelf2* pFilter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1238
MA_API ma_uint32 ma_hishelf2_get_latency(const ma_hishelf2* pFilter);
1239
 
1240
 
1241
 
1242
/*
1243
Delay
1244
*/
1245
typedef struct
1246
{
1247
    ma_uint32 channels;
1248
    ma_uint32 sampleRate;
1249
    ma_uint32 delayInFrames;
1250
    ma_bool32 delayStart;       /* Set to true to delay the start of the output; false otherwise. */
1251
    float wet;                  /* 0..1. Default = 1. */
1252
    float dry;                  /* 0..1. Default = 1. */
1253
    float decay;                /* 0..1. Default = 0 (no feedback). Feedback decay. Use this for echo. */
1254
} ma_delay_config;
1255
 
1256
MA_API ma_delay_config ma_delay_config_init(ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 delayInFrames, float decay);
1257
 
1258
 
1259
typedef struct
1260
{
1261
    ma_delay_config config;
1262
    ma_uint32 cursor;               /* Feedback is written to this cursor. Always equal or in front of the read cursor. */
1263
    ma_uint32 bufferSizeInFrames;
1264
    float* pBuffer;
1265
} ma_delay;
1266
 
1267
MA_API ma_result ma_delay_init(const ma_delay_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_delay* pDelay);
1268
MA_API void ma_delay_uninit(ma_delay* pDelay, const ma_allocation_callbacks* pAllocationCallbacks);
1269
MA_API ma_result ma_delay_process_pcm_frames(ma_delay* pDelay, void* pFramesOut, const void* pFramesIn, ma_uint32 frameCount);
1270
MA_API void ma_delay_set_wet(ma_delay* pDelay, float value);
1271
MA_API float ma_delay_get_wet(const ma_delay* pDelay);
1272
MA_API void ma_delay_set_dry(ma_delay* pDelay, float value);
1273
MA_API float ma_delay_get_dry(const ma_delay* pDelay);
1274
MA_API void ma_delay_set_decay(ma_delay* pDelay, float value);
1275
MA_API float ma_delay_get_decay(const ma_delay* pDelay);
1276
 
1277
 
1278
/* Gainer for smooth volume changes. */
1279
typedef struct
1280
{
1281
    ma_uint32 channels;
1282
    ma_uint32 smoothTimeInFrames;
1283
} ma_gainer_config;
1284
 
1285
MA_API ma_gainer_config ma_gainer_config_init(ma_uint32 channels, ma_uint32 smoothTimeInFrames);
1286
 
1287
 
1288
typedef struct
1289
{
1290
    ma_gainer_config config;
1291
    ma_uint32 t;
1292
    float masterVolume;
1293
    float* pOldGains;
1294
    float* pNewGains;
1295
 
1296
    /* Memory management. */
1297
    void* _pHeap;
1298
    ma_bool32 _ownsHeap;
1299
} ma_gainer;
1300
 
1301
MA_API ma_result ma_gainer_get_heap_size(const ma_gainer_config* pConfig, size_t* pHeapSizeInBytes);
1302
MA_API ma_result ma_gainer_init_preallocated(const ma_gainer_config* pConfig, void* pHeap, ma_gainer* pGainer);
1303
MA_API ma_result ma_gainer_init(const ma_gainer_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_gainer* pGainer);
1304
MA_API void ma_gainer_uninit(ma_gainer* pGainer, const ma_allocation_callbacks* pAllocationCallbacks);
1305
MA_API ma_result ma_gainer_process_pcm_frames(ma_gainer* pGainer, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1306
MA_API ma_result ma_gainer_set_gain(ma_gainer* pGainer, float newGain);
1307
MA_API ma_result ma_gainer_set_gains(ma_gainer* pGainer, float* pNewGains);
1308
MA_API ma_result ma_gainer_set_master_volume(ma_gainer* pGainer, float volume);
1309
MA_API ma_result ma_gainer_get_master_volume(const ma_gainer* pGainer, float* pVolume);
1310
 
1311
 
1312
 
1313
/* Stereo panner. */
1314
typedef enum
1315
{
1316
    ma_pan_mode_balance = 0,    /* Does not blend one side with the other. Technically just a balance. Compatible with other popular audio engines and therefore the default. */
1317
    ma_pan_mode_pan             /* A true pan. The sound from one side will "move" to the other side and blend with it. */
1318
} ma_pan_mode;
1319
 
1320
typedef struct
1321
{
1322
    ma_format format;
1323
    ma_uint32 channels;
1324
    ma_pan_mode mode;
1325
    float pan;
1326
} ma_panner_config;
1327
 
1328
MA_API ma_panner_config ma_panner_config_init(ma_format format, ma_uint32 channels);
1329
 
1330
 
1331
typedef struct
1332
{
1333
    ma_format format;
1334
    ma_uint32 channels;
1335
    ma_pan_mode mode;
1336
    float pan;  /* -1..1 where 0 is no pan, -1 is left side, +1 is right side. Defaults to 0. */
1337
} ma_panner;
1338
 
1339
MA_API ma_result ma_panner_init(const ma_panner_config* pConfig, ma_panner* pPanner);
1340
MA_API ma_result ma_panner_process_pcm_frames(ma_panner* pPanner, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1341
MA_API void ma_panner_set_mode(ma_panner* pPanner, ma_pan_mode mode);
1342
MA_API ma_pan_mode ma_panner_get_mode(const ma_panner* pPanner);
1343
MA_API void ma_panner_set_pan(ma_panner* pPanner, float pan);
1344
MA_API float ma_panner_get_pan(const ma_panner* pPanner);
1345
 
1346
 
1347
 
1348
/* Fader. */
1349
typedef struct
1350
{
1351
    ma_format format;
1352
    ma_uint32 channels;
1353
    ma_uint32 sampleRate;
1354
} ma_fader_config;
1355
 
1356
MA_API ma_fader_config ma_fader_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate);
1357
 
1358
typedef struct
1359
{
1360
    ma_fader_config config;
1361
    float volumeBeg;            /* If volumeBeg and volumeEnd is equal to 1, no fading happens (ma_fader_process_pcm_frames() will run as a passthrough). */
1362
    float volumeEnd;
1363
    ma_uint64 lengthInFrames;   /* The total length of the fade. */
1364
    ma_int64  cursorInFrames;   /* The current time in frames. Incremented by ma_fader_process_pcm_frames(). Signed because it'll be offset by startOffsetInFrames in set_fade_ex(). */
1365
} ma_fader;
1366
 
1367
MA_API ma_result ma_fader_init(const ma_fader_config* pConfig, ma_fader* pFader);
1368
MA_API ma_result ma_fader_process_pcm_frames(ma_fader* pFader, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1369
MA_API void ma_fader_get_data_format(const ma_fader* pFader, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate);
1370
MA_API void ma_fader_set_fade(ma_fader* pFader, float volumeBeg, float volumeEnd, ma_uint64 lengthInFrames);
1371
MA_API void ma_fader_set_fade_ex(ma_fader* pFader, float volumeBeg, float volumeEnd, ma_uint64 lengthInFrames, ma_int64 startOffsetInFrames);
1372
MA_API float ma_fader_get_current_volume(const ma_fader* pFader);
1373
 
1374
 
1375
 
1376
/* Spatializer. */
1377
typedef struct
1378
{
1379
    float x;
1380
    float y;
1381
    float z;
1382
} ma_vec3f;
1383
 
1384
typedef struct
1385
{
1386
    ma_vec3f v;
1387
    ma_spinlock lock;
1388
} ma_atomic_vec3f;
1389
 
1390
typedef enum
1391
{
1392
    ma_attenuation_model_none,          /* No distance attenuation and no spatialization. */
1393
    ma_attenuation_model_inverse,       /* Equivalent to OpenAL's AL_INVERSE_DISTANCE_CLAMPED. */
1394
    ma_attenuation_model_linear,        /* Linear attenuation. Equivalent to OpenAL's AL_LINEAR_DISTANCE_CLAMPED. */
1395
    ma_attenuation_model_exponential    /* Exponential attenuation. Equivalent to OpenAL's AL_EXPONENT_DISTANCE_CLAMPED. */
1396
} ma_attenuation_model;
1397
 
1398
typedef enum
1399
{
1400
    ma_positioning_absolute,
1401
    ma_positioning_relative
1402
} ma_positioning;
1403
 
1404
typedef enum
1405
{
1406
    ma_handedness_right,
1407
    ma_handedness_left
1408
} ma_handedness;
1409
 
1410
 
1411
typedef struct
1412
{
1413
    ma_uint32 channelsOut;
1414
    ma_channel* pChannelMapOut;
1415
    ma_handedness handedness;   /* Defaults to right. Forward is -1 on the Z axis. In a left handed system, forward is +1 on the Z axis. */
1416
    float coneInnerAngleInRadians;
1417
    float coneOuterAngleInRadians;
1418
    float coneOuterGain;
1419
    float speedOfSound;
1420
    ma_vec3f worldUp;
1421
} ma_spatializer_listener_config;
1422
 
1423
MA_API ma_spatializer_listener_config ma_spatializer_listener_config_init(ma_uint32 channelsOut);
1424
 
1425
 
1426
typedef struct
1427
{
1428
    ma_spatializer_listener_config config;
1429
    ma_atomic_vec3f position;  /* The absolute position of the listener. */
1430
    ma_atomic_vec3f direction; /* The direction the listener is facing. The world up vector is config.worldUp. */
1431
    ma_atomic_vec3f velocity;
1432
    ma_bool32 isEnabled;
1433
 
1434
    /* Memory management. */
1435
    ma_bool32 _ownsHeap;
1436
    void* _pHeap;
1437
} ma_spatializer_listener;
1438
 
1439
MA_API ma_result ma_spatializer_listener_get_heap_size(const ma_spatializer_listener_config* pConfig, size_t* pHeapSizeInBytes);
1440
MA_API ma_result ma_spatializer_listener_init_preallocated(const ma_spatializer_listener_config* pConfig, void* pHeap, ma_spatializer_listener* pListener);
1441
MA_API ma_result ma_spatializer_listener_init(const ma_spatializer_listener_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_spatializer_listener* pListener);
1442
MA_API void ma_spatializer_listener_uninit(ma_spatializer_listener* pListener, const ma_allocation_callbacks* pAllocationCallbacks);
1443
MA_API ma_channel* ma_spatializer_listener_get_channel_map(ma_spatializer_listener* pListener);
1444
MA_API void ma_spatializer_listener_set_cone(ma_spatializer_listener* pListener, float innerAngleInRadians, float outerAngleInRadians, float outerGain);
1445
MA_API void ma_spatializer_listener_get_cone(const ma_spatializer_listener* pListener, float* pInnerAngleInRadians, float* pOuterAngleInRadians, float* pOuterGain);
1446
MA_API void ma_spatializer_listener_set_position(ma_spatializer_listener* pListener, float x, float y, float z);
1447
MA_API ma_vec3f ma_spatializer_listener_get_position(const ma_spatializer_listener* pListener);
1448
MA_API void ma_spatializer_listener_set_direction(ma_spatializer_listener* pListener, float x, float y, float z);
1449
MA_API ma_vec3f ma_spatializer_listener_get_direction(const ma_spatializer_listener* pListener);
1450
MA_API void ma_spatializer_listener_set_velocity(ma_spatializer_listener* pListener, float x, float y, float z);
1451
MA_API ma_vec3f ma_spatializer_listener_get_velocity(const ma_spatializer_listener* pListener);
1452
MA_API void ma_spatializer_listener_set_speed_of_sound(ma_spatializer_listener* pListener, float speedOfSound);
1453
MA_API float ma_spatializer_listener_get_speed_of_sound(const ma_spatializer_listener* pListener);
1454
MA_API void ma_spatializer_listener_set_world_up(ma_spatializer_listener* pListener, float x, float y, float z);
1455
MA_API ma_vec3f ma_spatializer_listener_get_world_up(const ma_spatializer_listener* pListener);
1456
MA_API void ma_spatializer_listener_set_enabled(ma_spatializer_listener* pListener, ma_bool32 isEnabled);
1457
MA_API ma_bool32 ma_spatializer_listener_is_enabled(const ma_spatializer_listener* pListener);
1458
 
1459
 
1460
typedef struct
1461
{
1462
    ma_uint32 channelsIn;
1463
    ma_uint32 channelsOut;
1464
    ma_channel* pChannelMapIn;
1465
    ma_attenuation_model attenuationModel;
1466
    ma_positioning positioning;
1467
    ma_handedness handedness;           /* Defaults to right. Forward is -1 on the Z axis. In a left handed system, forward is +1 on the Z axis. */
1468
    float minGain;
1469
    float maxGain;
1470
    float minDistance;
1471
    float maxDistance;
1472
    float rolloff;
1473
    float coneInnerAngleInRadians;
1474
    float coneOuterAngleInRadians;
1475
    float coneOuterGain;
1476
    float dopplerFactor;                /* Set to 0 to disable doppler effect. */
1477
    float directionalAttenuationFactor; /* Set to 0 to disable directional attenuation. */
1478
    float minSpatializationChannelGain; /* The minimal scaling factor to apply to channel gains when accounting for the direction of the sound relative to the listener. Must be in the range of 0..1. Smaller values means more aggressive directional panning, larger values means more subtle directional panning. */
1479
    ma_uint32 gainSmoothTimeInFrames;   /* When the gain of a channel changes during spatialization, the transition will be linearly interpolated over this number of frames. */
1480
} ma_spatializer_config;
1481
 
1482
MA_API ma_spatializer_config ma_spatializer_config_init(ma_uint32 channelsIn, ma_uint32 channelsOut);
1483
 
1484
 
1485
typedef struct
1486
{
1487
    ma_uint32 channelsIn;
1488
    ma_uint32 channelsOut;
1489
    ma_channel* pChannelMapIn;
1490
    ma_attenuation_model attenuationModel;
1491
    ma_positioning positioning;
1492
    ma_handedness handedness;           /* Defaults to right. Forward is -1 on the Z axis. In a left handed system, forward is +1 on the Z axis. */
1493
    float minGain;
1494
    float maxGain;
1495
    float minDistance;
1496
    float maxDistance;
1497
    float rolloff;
1498
    float coneInnerAngleInRadians;
1499
    float coneOuterAngleInRadians;
1500
    float coneOuterGain;
1501
    float dopplerFactor;                /* Set to 0 to disable doppler effect. */
1502
    float directionalAttenuationFactor; /* Set to 0 to disable directional attenuation. */
1503
    ma_uint32 gainSmoothTimeInFrames;   /* When the gain of a channel changes during spatialization, the transition will be linearly interpolated over this number of frames. */
1504
    ma_atomic_vec3f position;
1505
    ma_atomic_vec3f direction;
1506
    ma_atomic_vec3f velocity;  /* For doppler effect. */
1507
    float dopplerPitch; /* Will be updated by ma_spatializer_process_pcm_frames() and can be used by higher level functions to apply a pitch shift for doppler effect. */
1508
    float minSpatializationChannelGain;
1509
    ma_gainer gainer;   /* For smooth gain transitions. */
1510
    float* pNewChannelGainsOut; /* An offset of _pHeap. Used by ma_spatializer_process_pcm_frames() to store new channel gains. The number of elements in this array is equal to config.channelsOut. */
1511
 
1512
    /* Memory management. */
1513
    void* _pHeap;
1514
    ma_bool32 _ownsHeap;
1515
} ma_spatializer;
1516
 
1517
MA_API ma_result ma_spatializer_get_heap_size(const ma_spatializer_config* pConfig, size_t* pHeapSizeInBytes);
1518
MA_API ma_result ma_spatializer_init_preallocated(const ma_spatializer_config* pConfig, void* pHeap, ma_spatializer* pSpatializer);
1519
MA_API ma_result ma_spatializer_init(const ma_spatializer_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_spatializer* pSpatializer);
1520
MA_API void ma_spatializer_uninit(ma_spatializer* pSpatializer, const ma_allocation_callbacks* pAllocationCallbacks);
1521
MA_API ma_result ma_spatializer_process_pcm_frames(ma_spatializer* pSpatializer, ma_spatializer_listener* pListener, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1522
MA_API ma_result ma_spatializer_set_master_volume(ma_spatializer* pSpatializer, float volume);
1523
MA_API ma_result ma_spatializer_get_master_volume(const ma_spatializer* pSpatializer, float* pVolume);
1524
MA_API ma_uint32 ma_spatializer_get_input_channels(const ma_spatializer* pSpatializer);
1525
MA_API ma_uint32 ma_spatializer_get_output_channels(const ma_spatializer* pSpatializer);
1526
MA_API void ma_spatializer_set_attenuation_model(ma_spatializer* pSpatializer, ma_attenuation_model attenuationModel);
1527
MA_API ma_attenuation_model ma_spatializer_get_attenuation_model(const ma_spatializer* pSpatializer);
1528
MA_API void ma_spatializer_set_positioning(ma_spatializer* pSpatializer, ma_positioning positioning);
1529
MA_API ma_positioning ma_spatializer_get_positioning(const ma_spatializer* pSpatializer);
1530
MA_API void ma_spatializer_set_rolloff(ma_spatializer* pSpatializer, float rolloff);
1531
MA_API float ma_spatializer_get_rolloff(const ma_spatializer* pSpatializer);
1532
MA_API void ma_spatializer_set_min_gain(ma_spatializer* pSpatializer, float minGain);
1533
MA_API float ma_spatializer_get_min_gain(const ma_spatializer* pSpatializer);
1534
MA_API void ma_spatializer_set_max_gain(ma_spatializer* pSpatializer, float maxGain);
1535
MA_API float ma_spatializer_get_max_gain(const ma_spatializer* pSpatializer);
1536
MA_API void ma_spatializer_set_min_distance(ma_spatializer* pSpatializer, float minDistance);
1537
MA_API float ma_spatializer_get_min_distance(const ma_spatializer* pSpatializer);
1538
MA_API void ma_spatializer_set_max_distance(ma_spatializer* pSpatializer, float maxDistance);
1539
MA_API float ma_spatializer_get_max_distance(const ma_spatializer* pSpatializer);
1540
MA_API void ma_spatializer_set_cone(ma_spatializer* pSpatializer, float innerAngleInRadians, float outerAngleInRadians, float outerGain);
1541
MA_API void ma_spatializer_get_cone(const ma_spatializer* pSpatializer, float* pInnerAngleInRadians, float* pOuterAngleInRadians, float* pOuterGain);
1542
MA_API void ma_spatializer_set_doppler_factor(ma_spatializer* pSpatializer, float dopplerFactor);
1543
MA_API float ma_spatializer_get_doppler_factor(const ma_spatializer* pSpatializer);
1544
MA_API void ma_spatializer_set_directional_attenuation_factor(ma_spatializer* pSpatializer, float directionalAttenuationFactor);
1545
MA_API float ma_spatializer_get_directional_attenuation_factor(const ma_spatializer* pSpatializer);
1546
MA_API void ma_spatializer_set_position(ma_spatializer* pSpatializer, float x, float y, float z);
1547
MA_API ma_vec3f ma_spatializer_get_position(const ma_spatializer* pSpatializer);
1548
MA_API void ma_spatializer_set_direction(ma_spatializer* pSpatializer, float x, float y, float z);
1549
MA_API ma_vec3f ma_spatializer_get_direction(const ma_spatializer* pSpatializer);
1550
MA_API void ma_spatializer_set_velocity(ma_spatializer* pSpatializer, float x, float y, float z);
1551
MA_API ma_vec3f ma_spatializer_get_velocity(const ma_spatializer* pSpatializer);
1552
MA_API void ma_spatializer_get_relative_position_and_direction(const ma_spatializer* pSpatializer, const ma_spatializer_listener* pListener, ma_vec3f* pRelativePos, ma_vec3f* pRelativeDir);
1553
 
1554
 
1555
 
1556
/************************************************************************************************************************************************************
1557
*************************************************************************************************************************************************************
1558
 
1559
DATA CONVERSION
1560
===============
1561
 
1562
This section contains the APIs for data conversion. You will find everything here for channel mapping, sample format conversion, resampling, etc.
1563
 
1564
*************************************************************************************************************************************************************
1565
************************************************************************************************************************************************************/
1566
 
1567
/**************************************************************************************************************************************************************
1568
 
1569
Resampling
1570
 
1571
**************************************************************************************************************************************************************/
1572
typedef struct
1573
{
1574
    ma_format format;
1575
    ma_uint32 channels;
1576
    ma_uint32 sampleRateIn;
1577
    ma_uint32 sampleRateOut;
1578
    ma_uint32 lpfOrder;         /* The low-pass filter order. Setting this to 0 will disable low-pass filtering. */
1579
    double    lpfNyquistFactor; /* 0..1. Defaults to 1. 1 = Half the sampling frequency (Nyquist Frequency), 0.5 = Quarter the sampling frequency (half Nyquest Frequency), etc. */
1580
} ma_linear_resampler_config;
1581
 
1582
MA_API ma_linear_resampler_config ma_linear_resampler_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
1583
 
1584
typedef struct
1585
{
1586
    ma_linear_resampler_config config;
1587
    ma_uint32 inAdvanceInt;
1588
    ma_uint32 inAdvanceFrac;
1589
    ma_uint32 inTimeInt;
1590
    ma_uint32 inTimeFrac;
1591
    union
1592
    {
1593
        float* f32;
1594
        ma_int16* s16;
1595
    } x0; /* The previous input frame. */
1596
    union
1597
    {
1598
        float* f32;
1599
        ma_int16* s16;
1600
    } x1; /* The next input frame. */
1601
    ma_lpf lpf;
1602
 
1603
    /* Memory management. */
1604
    void* _pHeap;
1605
    ma_bool32 _ownsHeap;
1606
} ma_linear_resampler;
1607
 
1608
MA_API ma_result ma_linear_resampler_get_heap_size(const ma_linear_resampler_config* pConfig, size_t* pHeapSizeInBytes);
1609
MA_API ma_result ma_linear_resampler_init_preallocated(const ma_linear_resampler_config* pConfig, void* pHeap, ma_linear_resampler* pResampler);
1610
MA_API ma_result ma_linear_resampler_init(const ma_linear_resampler_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_linear_resampler* pResampler);
1611
MA_API void ma_linear_resampler_uninit(ma_linear_resampler* pResampler, const ma_allocation_callbacks* pAllocationCallbacks);
1612
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);
1613
MA_API ma_result ma_linear_resampler_set_rate(ma_linear_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
1614
MA_API ma_result ma_linear_resampler_set_rate_ratio(ma_linear_resampler* pResampler, float ratioInOut);
1615
MA_API ma_uint64 ma_linear_resampler_get_input_latency(const ma_linear_resampler* pResampler);
1616
MA_API ma_uint64 ma_linear_resampler_get_output_latency(const ma_linear_resampler* pResampler);
1617
MA_API ma_result ma_linear_resampler_get_required_input_frame_count(const ma_linear_resampler* pResampler, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount);
1618
MA_API ma_result ma_linear_resampler_get_expected_output_frame_count(const ma_linear_resampler* pResampler, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount);
1619
MA_API ma_result ma_linear_resampler_reset(ma_linear_resampler* pResampler);
1620
 
1621
 
1622
typedef struct ma_resampler_config ma_resampler_config;
1623
 
1624
typedef void ma_resampling_backend;
1625
typedef struct
1626
{
1627
    ma_result (* onGetHeapSize                )(void* pUserData, const ma_resampler_config* pConfig, size_t* pHeapSizeInBytes);
1628
    ma_result (* onInit                       )(void* pUserData, const ma_resampler_config* pConfig, void* pHeap, ma_resampling_backend** ppBackend);
1629
    void      (* onUninit                     )(void* pUserData, ma_resampling_backend* pBackend, const ma_allocation_callbacks* pAllocationCallbacks);
1630
    ma_result (* onProcess                    )(void* pUserData, ma_resampling_backend* pBackend, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
1631
    ma_result (* onSetRate                    )(void* pUserData, ma_resampling_backend* pBackend, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);                 /* Optional. Rate changes will be disabled. */
1632
    ma_uint64 (* onGetInputLatency            )(void* pUserData, const ma_resampling_backend* pBackend);                                                            /* Optional. Latency will be reported as 0. */
1633
    ma_uint64 (* onGetOutputLatency           )(void* pUserData, const ma_resampling_backend* pBackend);                                                            /* Optional. Latency will be reported as 0. */
1634
    ma_result (* onGetRequiredInputFrameCount )(void* pUserData, const ma_resampling_backend* pBackend, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount);   /* Optional. Latency mitigation will be disabled. */
1635
    ma_result (* onGetExpectedOutputFrameCount)(void* pUserData, const ma_resampling_backend* pBackend, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount);   /* Optional. Latency mitigation will be disabled. */
1636
    ma_result (* onReset                      )(void* pUserData, ma_resampling_backend* pBackend);
1637
} ma_resampling_backend_vtable;
1638
 
1639
typedef enum
1640
{
1641
    ma_resample_algorithm_linear = 0,    /* Fastest, lowest quality. Optional low-pass filtering. Default. */
1642
    ma_resample_algorithm_custom,
1643
} ma_resample_algorithm;
1644
 
1645
struct ma_resampler_config
1646
{
1647
    ma_format format;   /* Must be either ma_format_f32 or ma_format_s16. */
1648
    ma_uint32 channels;
1649
    ma_uint32 sampleRateIn;
1650
    ma_uint32 sampleRateOut;
1651
    ma_resample_algorithm algorithm;    /* When set to ma_resample_algorithm_custom, pBackendVTable will be used. */
1652
    ma_resampling_backend_vtable* pBackendVTable;
1653
    void* pBackendUserData;
1654
    struct
1655
    {
1656
        ma_uint32 lpfOrder;
1657
    } linear;
1658
};
1659
 
1660
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);
1661
 
1662
typedef struct
1663
{
1664
    ma_resampling_backend* pBackend;
1665
    ma_resampling_backend_vtable* pBackendVTable;
1666
    void* pBackendUserData;
1667
    ma_format format;
1668
    ma_uint32 channels;
1669
    ma_uint32 sampleRateIn;
1670
    ma_uint32 sampleRateOut;
1671
    union
1672
    {
1673
        ma_linear_resampler linear;
1674
    } state;    /* State for stock resamplers so we can avoid a malloc. For stock resamplers, pBackend will point here. */
1675
 
1676
    /* Memory management. */
1677
    void* _pHeap;
1678
    ma_bool32 _ownsHeap;
1679
} ma_resampler;
1680
 
1681
MA_API ma_result ma_resampler_get_heap_size(const ma_resampler_config* pConfig, size_t* pHeapSizeInBytes);
1682
MA_API ma_result ma_resampler_init_preallocated(const ma_resampler_config* pConfig, void* pHeap, ma_resampler* pResampler);
1683
 
1684
/*
1685
Initializes a new resampler object from a config.
1686
*/
1687
MA_API ma_result ma_resampler_init(const ma_resampler_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_resampler* pResampler);
1688
 
1689
/*
1690
Uninitializes a resampler.
1691
*/
1692
MA_API void ma_resampler_uninit(ma_resampler* pResampler, const ma_allocation_callbacks* pAllocationCallbacks);
1693
 
1694
/*
1695
Converts the given input data.
1696
 
1697
Both the input and output frames must be in the format specified in the config when the resampler was initialized.
1698
 
1699
On input, [pFrameCountOut] contains the number of output frames to process. On output it contains the number of output frames that
1700
were actually processed, which may be less than the requested amount which will happen if there's not enough input data. You can use
1701
ma_resampler_get_expected_output_frame_count() to know how many output frames will be processed for a given number of input frames.
1702
 
1703
On input, [pFrameCountIn] contains the number of input frames contained in [pFramesIn]. On output it contains the number of whole
1704
input frames that were actually processed. You can use ma_resampler_get_required_input_frame_count() to know how many input frames
1705
you should provide for a given number of output frames. [pFramesIn] can be NULL, in which case zeroes will be used instead.
1706
 
1707
If [pFramesOut] is NULL, a seek is performed. In this case, if [pFrameCountOut] is not NULL it will seek by the specified number of
1708
output frames. Otherwise, if [pFramesCountOut] is NULL and [pFrameCountIn] is not NULL, it will seek by the specified number of input
1709
frames. When seeking, [pFramesIn] is allowed to NULL, in which case the internal timing state will be updated, but no input will be
1710
processed. In this case, any internal filter state will be updated as if zeroes were passed in.
1711
 
1712
It is an error for [pFramesOut] to be non-NULL and [pFrameCountOut] to be NULL.
1713
 
1714
It is an error for both [pFrameCountOut] and [pFrameCountIn] to be NULL.
1715
*/
1716
MA_API ma_result ma_resampler_process_pcm_frames(ma_resampler* pResampler, const void* pFramesIn, ma_uint64* pFrameCountIn, void* pFramesOut, ma_uint64* pFrameCountOut);
1717
 
1718
 
1719
/*
1720
Sets the input and output sample rate.
1721
*/
1722
MA_API ma_result ma_resampler_set_rate(ma_resampler* pResampler, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
1723
 
1724
/*
1725
Sets the input and output sample rate as a ratio.
1726
 
1727
The ration is in/out.
1728
*/
1729
MA_API ma_result ma_resampler_set_rate_ratio(ma_resampler* pResampler, float ratio);
1730
 
1731
/*
1732
Retrieves the latency introduced by the resampler in input frames.
1733
*/
1734
MA_API ma_uint64 ma_resampler_get_input_latency(const ma_resampler* pResampler);
1735
 
1736
/*
1737
Retrieves the latency introduced by the resampler in output frames.
1738
*/
1739
MA_API ma_uint64 ma_resampler_get_output_latency(const ma_resampler* pResampler);
1740
 
1741
/*
1742
Calculates the number of whole input frames that would need to be read from the client in order to output the specified
1743
number of output frames.
1744
 
1745
The returned value does not include cached input frames. It only returns the number of extra frames that would need to be
1746
read from the input buffer in order to output the specified number of output frames.
1747
*/
1748
MA_API ma_result ma_resampler_get_required_input_frame_count(const ma_resampler* pResampler, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount);
1749
 
1750
/*
1751
Calculates the number of whole output frames that would be output after fully reading and consuming the specified number of
1752
input frames.
1753
*/
1754
MA_API ma_result ma_resampler_get_expected_output_frame_count(const ma_resampler* pResampler, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount);
1755
 
1756
/*
1757
Resets the resampler's timer and clears it's internal cache.
1758
*/
1759
MA_API ma_result ma_resampler_reset(ma_resampler* pResampler);
1760
 
1761
 
1762
/**************************************************************************************************************************************************************
1763
 
1764
Channel Conversion
1765
 
1766
**************************************************************************************************************************************************************/
1767
typedef enum
1768
{
1769
    ma_channel_conversion_path_unknown,
1770
    ma_channel_conversion_path_passthrough,
1771
    ma_channel_conversion_path_mono_out,    /* Converting to mono. */
1772
    ma_channel_conversion_path_mono_in,     /* Converting from mono. */
1773
    ma_channel_conversion_path_shuffle,     /* Simple shuffle. Will use this when all channels are present in both input and output channel maps, but just in a different order. */
1774
    ma_channel_conversion_path_weights      /* Blended based on weights. */
1775
} ma_channel_conversion_path;
1776
 
1777
typedef enum
1778
{
1779
    ma_mono_expansion_mode_duplicate = 0,   /* The default. */
1780
    ma_mono_expansion_mode_average,         /* Average the mono channel across all channels. */
1781
    ma_mono_expansion_mode_stereo_only,     /* Duplicate to the left and right channels only and ignore the others. */
1782
    ma_mono_expansion_mode_default = ma_mono_expansion_mode_duplicate
1783
} ma_mono_expansion_mode;
1784
 
1785
typedef struct
1786
{
1787
    ma_format format;
1788
    ma_uint32 channelsIn;
1789
    ma_uint32 channelsOut;
1790
    const ma_channel* pChannelMapIn;
1791
    const ma_channel* pChannelMapOut;
1792
    ma_channel_mix_mode mixingMode;
1793
    ma_bool32 calculateLFEFromSpatialChannels;  /* When an output LFE channel is present, but no input LFE, set to true to set the output LFE to the average of all spatial channels (LR, FR, etc.). Ignored when an input LFE is present. */
1794
    float** ppWeights;  /* [in][out]. Only used when mixingMode is set to ma_channel_mix_mode_custom_weights. */
1795
} ma_channel_converter_config;
1796
 
1797
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);
1798
 
1799
typedef struct
1800
{
1801
    ma_format format;
1802
    ma_uint32 channelsIn;
1803
    ma_uint32 channelsOut;
1804
    ma_channel_mix_mode mixingMode;
1805
    ma_channel_conversion_path conversionPath;
1806
    ma_channel* pChannelMapIn;
1807
    ma_channel* pChannelMapOut;
1808
    ma_uint8* pShuffleTable;    /* Indexed by output channel index. */
1809
    union
1810
    {
1811
        float**    f32;
1812
        ma_int32** s16;
1813
    } weights;  /* [in][out] */
1814
 
1815
    /* Memory management. */
1816
    void* _pHeap;
1817
    ma_bool32 _ownsHeap;
1818
} ma_channel_converter;
1819
 
1820
MA_API ma_result ma_channel_converter_get_heap_size(const ma_channel_converter_config* pConfig, size_t* pHeapSizeInBytes);
1821
MA_API ma_result ma_channel_converter_init_preallocated(const ma_channel_converter_config* pConfig, void* pHeap, ma_channel_converter* pConverter);
1822
MA_API ma_result ma_channel_converter_init(const ma_channel_converter_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_channel_converter* pConverter);
1823
MA_API void ma_channel_converter_uninit(ma_channel_converter* pConverter, const ma_allocation_callbacks* pAllocationCallbacks);
1824
MA_API ma_result ma_channel_converter_process_pcm_frames(ma_channel_converter* pConverter, void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount);
1825
MA_API ma_result ma_channel_converter_get_input_channel_map(const ma_channel_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap);
1826
MA_API ma_result ma_channel_converter_get_output_channel_map(const ma_channel_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap);
1827
 
1828
 
1829
/**************************************************************************************************************************************************************
1830
 
1831
Data Conversion
1832
 
1833
**************************************************************************************************************************************************************/
1834
typedef struct
1835
{
1836
    ma_format formatIn;
1837
    ma_format formatOut;
1838
    ma_uint32 channelsIn;
1839
    ma_uint32 channelsOut;
1840
    ma_uint32 sampleRateIn;
1841
    ma_uint32 sampleRateOut;
1842
    ma_channel* pChannelMapIn;
1843
    ma_channel* pChannelMapOut;
1844
    ma_dither_mode ditherMode;
1845
    ma_channel_mix_mode channelMixMode;
1846
    ma_bool32 calculateLFEFromSpatialChannels;  /* When an output LFE channel is present, but no input LFE, set to true to set the output LFE to the average of all spatial channels (LR, FR, etc.). Ignored when an input LFE is present. */
1847
    float** ppChannelWeights;  /* [in][out]. Only used when mixingMode is set to ma_channel_mix_mode_custom_weights. */
1848
    ma_bool32 allowDynamicSampleRate;
1849
    ma_resampler_config resampling;
1850
} ma_data_converter_config;
1851
 
1852
MA_API ma_data_converter_config ma_data_converter_config_init_default(void);
1853
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);
1854
 
1855
 
1856
typedef enum
1857
{
1858
    ma_data_converter_execution_path_passthrough,       /* No conversion. */
1859
    ma_data_converter_execution_path_format_only,       /* Only format conversion. */
1860
    ma_data_converter_execution_path_channels_only,     /* Only channel conversion. */
1861
    ma_data_converter_execution_path_resample_only,     /* Only resampling. */
1862
    ma_data_converter_execution_path_resample_first,    /* All conversions, but resample as the first step. */
1863
    ma_data_converter_execution_path_channels_first     /* All conversions, but channels as the first step. */
1864
} ma_data_converter_execution_path;
1865
 
1866
typedef struct
1867
{
1868
    ma_format formatIn;
1869
    ma_format formatOut;
1870
    ma_uint32 channelsIn;
1871
    ma_uint32 channelsOut;
1872
    ma_uint32 sampleRateIn;
1873
    ma_uint32 sampleRateOut;
1874
    ma_dither_mode ditherMode;
1875
    ma_data_converter_execution_path executionPath; /* The execution path the data converter will follow when processing. */
1876
    ma_channel_converter channelConverter;
1877
    ma_resampler resampler;
1878
    ma_bool8 hasPreFormatConversion;
1879
    ma_bool8 hasPostFormatConversion;
1880
    ma_bool8 hasChannelConverter;
1881
    ma_bool8 hasResampler;
1882
    ma_bool8 isPassthrough;
1883
 
1884
    /* Memory management. */
1885
    ma_bool8 _ownsHeap;
1886
    void* _pHeap;
1887
} ma_data_converter;
1888
 
1889
MA_API ma_result ma_data_converter_get_heap_size(const ma_data_converter_config* pConfig, size_t* pHeapSizeInBytes);
1890
MA_API ma_result ma_data_converter_init_preallocated(const ma_data_converter_config* pConfig, void* pHeap, ma_data_converter* pConverter);
1891
MA_API ma_result ma_data_converter_init(const ma_data_converter_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_converter* pConverter);
1892
MA_API void ma_data_converter_uninit(ma_data_converter* pConverter, const ma_allocation_callbacks* pAllocationCallbacks);
1893
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);
1894
MA_API ma_result ma_data_converter_set_rate(ma_data_converter* pConverter, ma_uint32 sampleRateIn, ma_uint32 sampleRateOut);
1895
MA_API ma_result ma_data_converter_set_rate_ratio(ma_data_converter* pConverter, float ratioInOut);
1896
MA_API ma_uint64 ma_data_converter_get_input_latency(const ma_data_converter* pConverter);
1897
MA_API ma_uint64 ma_data_converter_get_output_latency(const ma_data_converter* pConverter);
1898
MA_API ma_result ma_data_converter_get_required_input_frame_count(const ma_data_converter* pConverter, ma_uint64 outputFrameCount, ma_uint64* pInputFrameCount);
1899
MA_API ma_result ma_data_converter_get_expected_output_frame_count(const ma_data_converter* pConverter, ma_uint64 inputFrameCount, ma_uint64* pOutputFrameCount);
1900
MA_API ma_result ma_data_converter_get_input_channel_map(const ma_data_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap);
1901
MA_API ma_result ma_data_converter_get_output_channel_map(const ma_data_converter* pConverter, ma_channel* pChannelMap, size_t channelMapCap);
1902
MA_API ma_result ma_data_converter_reset(ma_data_converter* pConverter);
1903
 
1904
 
1905
/************************************************************************************************************************************************************
1906
 
1907
Format Conversion
1908
 
1909
************************************************************************************************************************************************************/
1910
MA_API void ma_pcm_u8_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1911
MA_API void ma_pcm_u8_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1912
MA_API void ma_pcm_u8_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1913
MA_API void ma_pcm_u8_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1914
MA_API void ma_pcm_s16_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1915
MA_API void ma_pcm_s16_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1916
MA_API void ma_pcm_s16_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1917
MA_API void ma_pcm_s16_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1918
MA_API void ma_pcm_s24_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1919
MA_API void ma_pcm_s24_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1920
MA_API void ma_pcm_s24_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1921
MA_API void ma_pcm_s24_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1922
MA_API void ma_pcm_s32_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1923
MA_API void ma_pcm_s32_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1924
MA_API void ma_pcm_s32_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1925
MA_API void ma_pcm_s32_to_f32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1926
MA_API void ma_pcm_f32_to_u8(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1927
MA_API void ma_pcm_f32_to_s16(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1928
MA_API void ma_pcm_f32_to_s24(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1929
MA_API void ma_pcm_f32_to_s32(void* pOut, const void* pIn, ma_uint64 count, ma_dither_mode ditherMode);
1930
MA_API void ma_pcm_convert(void* pOut, ma_format formatOut, const void* pIn, ma_format formatIn, ma_uint64 sampleCount, ma_dither_mode ditherMode);
1931
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);
1932
 
1933
/*
1934
Deinterleaves an interleaved buffer.
1935
*/
1936
MA_API void ma_deinterleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void* pInterleavedPCMFrames, void** ppDeinterleavedPCMFrames);
1937
 
1938
/*
1939
Interleaves a group of deinterleaved buffers.
1940
*/
1941
MA_API void ma_interleave_pcm_frames(ma_format format, ma_uint32 channels, ma_uint64 frameCount, const void** ppDeinterleavedPCMFrames, void* pInterleavedPCMFrames);
1942
 
1943
 
1944
/************************************************************************************************************************************************************
1945
 
1946
Channel Maps
1947
 
1948
************************************************************************************************************************************************************/
1949
/*
1950
This is used in the shuffle table to indicate that the channel index is undefined and should be ignored.
1951
*/
1952
#define MA_CHANNEL_INDEX_NULL   255
1953
 
1954
/*
1955
Retrieves the channel position of the specified channel in the given channel map.
1956
 
1957
The pChannelMap parameter can be null, in which case miniaudio's default channel map will be assumed.
1958
*/
1959
MA_API ma_channel ma_channel_map_get_channel(const ma_channel* pChannelMap, ma_uint32 channelCount, ma_uint32 channelIndex);
1960
 
1961
/*
1962
Initializes a blank channel map.
1963
 
1964
When a blank channel map is specified anywhere it indicates that the native channel map should be used.
1965
*/
1966
MA_API void ma_channel_map_init_blank(ma_channel* pChannelMap, ma_uint32 channels);
1967
 
1968
/*
1969
Helper for retrieving a standard channel map.
1970
 
1971
The output channel map buffer must have a capacity of at least `channelMapCap`.
1972
*/
1973
MA_API void ma_channel_map_init_standard(ma_standard_channel_map standardChannelMap, ma_channel* pChannelMap, size_t channelMapCap, ma_uint32 channels);
1974
 
1975
/*
1976
Copies a channel map.
1977
 
1978
Both input and output channel map buffers must have a capacity of at at least `channels`.
1979
*/
1980
MA_API void ma_channel_map_copy(ma_channel* pOut, const ma_channel* pIn, ma_uint32 channels);
1981
 
1982
/*
1983
Copies a channel map if one is specified, otherwise copies the default channel map.
1984
 
1985
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`.
1986
*/
1987
MA_API void ma_channel_map_copy_or_default(ma_channel* pOut, size_t channelMapCapOut, const ma_channel* pIn, ma_uint32 channels);
1988
 
1989
 
1990
/*
1991
Determines whether or not a channel map is valid.
1992
 
1993
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
1994
is usually treated as a passthrough.
1995
 
1996
Invalid channel maps:
1997
  - A channel map with no channels
1998
  - A channel map with more than one channel and a mono channel
1999
 
2000
The channel map buffer must have a capacity of at least `channels`.
2001
*/
2002
MA_API ma_bool32 ma_channel_map_is_valid(const ma_channel* pChannelMap, ma_uint32 channels);
2003
 
2004
/*
2005
Helper for comparing two channel maps for equality.
2006
 
2007
This assumes the channel count is the same between the two.
2008
 
2009
Both channels map buffers must have a capacity of at least `channels`.
2010
*/
2011
MA_API ma_bool32 ma_channel_map_is_equal(const ma_channel* pChannelMapA, const ma_channel* pChannelMapB, ma_uint32 channels);
2012
 
2013
/*
2014
Helper for determining if a channel map is blank (all channels set to MA_CHANNEL_NONE).
2015
 
2016
The channel map buffer must have a capacity of at least `channels`.
2017
*/
2018
MA_API ma_bool32 ma_channel_map_is_blank(const ma_channel* pChannelMap, ma_uint32 channels);
2019
 
2020
/*
2021
Helper for determining whether or not a channel is present in the given channel map.
2022
 
2023
The channel map buffer must have a capacity of at least `channels`.
2024
*/
2025
MA_API ma_bool32 ma_channel_map_contains_channel_position(ma_uint32 channels, const ma_channel* pChannelMap, ma_channel channelPosition);
2026
 
2027
/*
2028
Find a channel position in the given channel map. Returns MA_TRUE if the channel is found; MA_FALSE otherwise. The
2029
index of the channel is output to `pChannelIndex`.
2030
 
2031
The channel map buffer must have a capacity of at least `channels`.
2032
*/
2033
MA_API ma_bool32 ma_channel_map_find_channel_position(ma_uint32 channels, const ma_channel* pChannelMap, ma_channel channelPosition, ma_uint32* pChannelIndex);
2034
 
2035
/*
2036
Generates a string representing the given channel map.
2037
 
2038
This is for printing and debugging purposes, not serialization/deserialization.
2039
 
2040
Returns the length of the string, not including the null terminator.
2041
*/
2042
MA_API size_t ma_channel_map_to_string(const ma_channel* pChannelMap, ma_uint32 channels, char* pBufferOut, size_t bufferCap);
2043
 
2044
/*
2045
Retrieves a human readable version of a channel position.
2046
*/
2047
MA_API const char* ma_channel_position_to_string(ma_channel channel);
2048
 
2049
 
2050
/************************************************************************************************************************************************************
2051
 
2052
Conversion Helpers
2053
 
2054
************************************************************************************************************************************************************/
2055
 
2056
/*
2057
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
2058
determine the required size of the output buffer. frameCountOut should be set to the capacity of pOut. If pOut is NULL, frameCountOut is
2059
ignored.
2060
 
2061
A return value of 0 indicates an error.
2062
 
2063
This function is useful for one-off bulk conversions, but if you're streaming data you should use the ma_data_converter APIs instead.
2064
*/
2065
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);
2066
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);
2067
 
2068
 
2069
/************************************************************************************************************************************************************
2070
 
2071
Data Source
2072
 
2073
************************************************************************************************************************************************************/
2074
typedef void ma_data_source;
2075
 
2076
#define MA_DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT    0x00000001
2077
 
2078
typedef struct
2079
{
2080
    ma_result (* onRead)(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
2081
    ma_result (* onSeek)(ma_data_source* pDataSource, ma_uint64 frameIndex);
2082
    ma_result (* onGetDataFormat)(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
2083
    ma_result (* onGetCursor)(ma_data_source* pDataSource, ma_uint64* pCursor);
2084
    ma_result (* onGetLength)(ma_data_source* pDataSource, ma_uint64* pLength);
2085
    ma_result (* onSetLooping)(ma_data_source* pDataSource, ma_bool32 isLooping);
2086
    ma_uint32 flags;
2087
} ma_data_source_vtable;
2088
 
2089
typedef ma_data_source* (* ma_data_source_get_next_proc)(ma_data_source* pDataSource);
2090
 
2091
typedef struct
2092
{
2093
    const ma_data_source_vtable* vtable;
2094
} ma_data_source_config;
2095
 
2096
MA_API ma_data_source_config ma_data_source_config_init(void);
2097
 
2098
 
2099
typedef struct
2100
{
2101
    const ma_data_source_vtable* vtable;
2102
    ma_uint64 rangeBegInFrames;
2103
    ma_uint64 rangeEndInFrames;             /* Set to -1 for unranged (default). */
2104
    ma_uint64 loopBegInFrames;              /* Relative to rangeBegInFrames. */
2105
    ma_uint64 loopEndInFrames;              /* Relative to rangeBegInFrames. Set to -1 for the end of the range. */
2106
    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. */
2107
    ma_data_source* pNext;                  /* When set to NULL, onGetNext will be used. */
2108
    ma_data_source_get_next_proc onGetNext; /* Will be used when pNext is NULL. If both are NULL, no next will be used. */
2109
    MA_ATOMIC(4, ma_bool32) isLooping;
2110
} ma_data_source_base;
2111
 
2112
MA_API ma_result ma_data_source_init(const ma_data_source_config* pConfig, ma_data_source* pDataSource);
2113
MA_API void ma_data_source_uninit(ma_data_source* pDataSource);
2114
MA_API ma_result ma_data_source_read_pcm_frames(ma_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);   /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
2115
MA_API ma_result ma_data_source_seek_pcm_frames(ma_data_source* pDataSource, ma_uint64 frameCount, ma_uint64* pFramesSeeked); /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount, &framesRead); */
2116
MA_API ma_result ma_data_source_seek_to_pcm_frame(ma_data_source* pDataSource, ma_uint64 frameIndex);
2117
MA_API ma_result ma_data_source_get_data_format(ma_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
2118
MA_API ma_result ma_data_source_get_cursor_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pCursor);
2119
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. */
2120
MA_API ma_result ma_data_source_get_cursor_in_seconds(ma_data_source* pDataSource, float* pCursor);
2121
MA_API ma_result ma_data_source_get_length_in_seconds(ma_data_source* pDataSource, float* pLength);
2122
MA_API ma_result ma_data_source_set_looping(ma_data_source* pDataSource, ma_bool32 isLooping);
2123
MA_API ma_bool32 ma_data_source_is_looping(const ma_data_source* pDataSource);
2124
MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames);
2125
MA_API void ma_data_source_get_range_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames);
2126
MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 loopBegInFrames, ma_uint64 loopEndInFrames);
2127
MA_API void ma_data_source_get_loop_point_in_pcm_frames(const ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames);
2128
MA_API ma_result ma_data_source_set_current(ma_data_source* pDataSource, ma_data_source* pCurrentDataSource);
2129
MA_API ma_data_source* ma_data_source_get_current(const ma_data_source* pDataSource);
2130
MA_API ma_result ma_data_source_set_next(ma_data_source* pDataSource, ma_data_source* pNextDataSource);
2131
MA_API ma_data_source* ma_data_source_get_next(const ma_data_source* pDataSource);
2132
MA_API ma_result ma_data_source_set_next_callback(ma_data_source* pDataSource, ma_data_source_get_next_proc onGetNext);
2133
MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(const ma_data_source* pDataSource);
2134
 
2135
 
2136
typedef struct
2137
{
2138
    ma_data_source_base ds;
2139
    ma_format format;
2140
    ma_uint32 channels;
2141
    ma_uint32 sampleRate;
2142
    ma_uint64 cursor;
2143
    ma_uint64 sizeInFrames;
2144
    const void* pData;
2145
} ma_audio_buffer_ref;
2146
 
2147
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);
2148
MA_API void ma_audio_buffer_ref_uninit(ma_audio_buffer_ref* pAudioBufferRef);
2149
MA_API ma_result ma_audio_buffer_ref_set_data(ma_audio_buffer_ref* pAudioBufferRef, const void* pData, ma_uint64 sizeInFrames);
2150
MA_API ma_uint64 ma_audio_buffer_ref_read_pcm_frames(ma_audio_buffer_ref* pAudioBufferRef, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
2151
MA_API ma_result ma_audio_buffer_ref_seek_to_pcm_frame(ma_audio_buffer_ref* pAudioBufferRef, ma_uint64 frameIndex);
2152
MA_API ma_result ma_audio_buffer_ref_map(ma_audio_buffer_ref* pAudioBufferRef, void** ppFramesOut, ma_uint64* pFrameCount);
2153
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. */
2154
MA_API ma_bool32 ma_audio_buffer_ref_at_end(const ma_audio_buffer_ref* pAudioBufferRef);
2155
MA_API ma_result ma_audio_buffer_ref_get_cursor_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pCursor);
2156
MA_API ma_result ma_audio_buffer_ref_get_length_in_pcm_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pLength);
2157
MA_API ma_result ma_audio_buffer_ref_get_available_frames(const ma_audio_buffer_ref* pAudioBufferRef, ma_uint64* pAvailableFrames);
2158
 
2159
 
2160
 
2161
typedef struct
2162
{
2163
    ma_format format;
2164
    ma_uint32 channels;
2165
    ma_uint32 sampleRate;
2166
    ma_uint64 sizeInFrames;
2167
    const void* pData;  /* If set to NULL, will allocate a block of memory for you. */
2168
    ma_allocation_callbacks allocationCallbacks;
2169
} ma_audio_buffer_config;
2170
 
2171
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);
2172
 
2173
typedef struct
2174
{
2175
    ma_audio_buffer_ref ref;
2176
    ma_allocation_callbacks allocationCallbacks;
2177
    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(). */
2178
    ma_uint8 _pExtraData[1];        /* For allocating a buffer with the memory located directly after the other memory of the structure. */
2179
} ma_audio_buffer;
2180
 
2181
MA_API ma_result ma_audio_buffer_init(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
2182
MA_API ma_result ma_audio_buffer_init_copy(const ma_audio_buffer_config* pConfig, ma_audio_buffer* pAudioBuffer);
2183
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. */
2184
MA_API void ma_audio_buffer_uninit(ma_audio_buffer* pAudioBuffer);
2185
MA_API void ma_audio_buffer_uninit_and_free(ma_audio_buffer* pAudioBuffer);
2186
MA_API ma_uint64 ma_audio_buffer_read_pcm_frames(ma_audio_buffer* pAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_bool32 loop);
2187
MA_API ma_result ma_audio_buffer_seek_to_pcm_frame(ma_audio_buffer* pAudioBuffer, ma_uint64 frameIndex);
2188
MA_API ma_result ma_audio_buffer_map(ma_audio_buffer* pAudioBuffer, void** ppFramesOut, ma_uint64* pFrameCount);
2189
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. */
2190
MA_API ma_bool32 ma_audio_buffer_at_end(const ma_audio_buffer* pAudioBuffer);
2191
MA_API ma_result ma_audio_buffer_get_cursor_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pCursor);
2192
MA_API ma_result ma_audio_buffer_get_length_in_pcm_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pLength);
2193
MA_API ma_result ma_audio_buffer_get_available_frames(const ma_audio_buffer* pAudioBuffer, ma_uint64* pAvailableFrames);
2194
 
2195
 
2196
/*
2197
Paged Audio Buffer
2198
==================
2199
A paged audio buffer is made up of a linked list of pages. It's expandable, but not shrinkable. It
2200
can be used for cases where audio data is streamed in asynchronously while allowing data to be read
2201
at the same time.
2202
 
2203
This is lock-free, but not 100% thread safe. You can append a page and read from the buffer across
2204
simultaneously across different threads, however only one thread at a time can append, and only one
2205
thread at a time can read and seek.
2206
*/
2207
typedef struct ma_paged_audio_buffer_page ma_paged_audio_buffer_page;
2208
struct ma_paged_audio_buffer_page
2209
{
2210
    MA_ATOMIC(MA_SIZEOF_PTR, ma_paged_audio_buffer_page*) pNext;
2211
    ma_uint64 sizeInFrames;
2212
    ma_uint8 pAudioData[1];
2213
};
2214
 
2215
typedef struct
2216
{
2217
    ma_format format;
2218
    ma_uint32 channels;
2219
    ma_paged_audio_buffer_page head;                                /* Dummy head for the lock-free algorithm. Always has a size of 0. */
2220
    MA_ATOMIC(MA_SIZEOF_PTR, ma_paged_audio_buffer_page*) pTail;    /* Never null. Initially set to &head. */
2221
} ma_paged_audio_buffer_data;
2222
 
2223
MA_API ma_result ma_paged_audio_buffer_data_init(ma_format format, ma_uint32 channels, ma_paged_audio_buffer_data* pData);
2224
MA_API void ma_paged_audio_buffer_data_uninit(ma_paged_audio_buffer_data* pData, const ma_allocation_callbacks* pAllocationCallbacks);
2225
MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_head(ma_paged_audio_buffer_data* pData);
2226
MA_API ma_paged_audio_buffer_page* ma_paged_audio_buffer_data_get_tail(ma_paged_audio_buffer_data* pData);
2227
MA_API ma_result ma_paged_audio_buffer_data_get_length_in_pcm_frames(ma_paged_audio_buffer_data* pData, ma_uint64* pLength);
2228
MA_API ma_result ma_paged_audio_buffer_data_allocate_page(ma_paged_audio_buffer_data* pData, ma_uint64 pageSizeInFrames, const void* pInitialData, const ma_allocation_callbacks* pAllocationCallbacks, ma_paged_audio_buffer_page** ppPage);
2229
MA_API ma_result ma_paged_audio_buffer_data_free_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage, const ma_allocation_callbacks* pAllocationCallbacks);
2230
MA_API ma_result ma_paged_audio_buffer_data_append_page(ma_paged_audio_buffer_data* pData, ma_paged_audio_buffer_page* pPage);
2231
MA_API ma_result ma_paged_audio_buffer_data_allocate_and_append_page(ma_paged_audio_buffer_data* pData, ma_uint32 pageSizeInFrames, const void* pInitialData, const ma_allocation_callbacks* pAllocationCallbacks);
2232
 
2233
 
2234
typedef struct
2235
{
2236
    ma_paged_audio_buffer_data* pData;  /* Must not be null. */
2237
} ma_paged_audio_buffer_config;
2238
 
2239
MA_API ma_paged_audio_buffer_config ma_paged_audio_buffer_config_init(ma_paged_audio_buffer_data* pData);
2240
 
2241
 
2242
typedef struct
2243
{
2244
    ma_data_source_base ds;
2245
    ma_paged_audio_buffer_data* pData;              /* Audio data is read from here. Cannot be null. */
2246
    ma_paged_audio_buffer_page* pCurrent;
2247
    ma_uint64 relativeCursor;                       /* Relative to the current page. */
2248
    ma_uint64 absoluteCursor;
2249
} ma_paged_audio_buffer;
2250
 
2251
MA_API ma_result ma_paged_audio_buffer_init(const ma_paged_audio_buffer_config* pConfig, ma_paged_audio_buffer* pPagedAudioBuffer);
2252
MA_API void ma_paged_audio_buffer_uninit(ma_paged_audio_buffer* pPagedAudioBuffer);
2253
MA_API ma_result ma_paged_audio_buffer_read_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);   /* Returns MA_AT_END if no more pages available. */
2254
MA_API ma_result ma_paged_audio_buffer_seek_to_pcm_frame(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64 frameIndex);
2255
MA_API ma_result ma_paged_audio_buffer_get_cursor_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pCursor);
2256
MA_API ma_result ma_paged_audio_buffer_get_length_in_pcm_frames(ma_paged_audio_buffer* pPagedAudioBuffer, ma_uint64* pLength);
2257
 
2258
 
2259
 
2260
/************************************************************************************************************************************************************
2261
 
2262
Ring Buffer
2263
 
2264
************************************************************************************************************************************************************/
2265
typedef struct
2266
{
2267
    void* pBuffer;
2268
    ma_uint32 subbufferSizeInBytes;
2269
    ma_uint32 subbufferCount;
2270
    ma_uint32 subbufferStrideInBytes;
2271
    MA_ATOMIC(4, ma_uint32) encodedReadOffset;  /* Most significant bit is the loop flag. Lower 31 bits contains the actual offset in bytes. Must be used atomically. */
2272
    MA_ATOMIC(4, ma_uint32) encodedWriteOffset; /* Most significant bit is the loop flag. Lower 31 bits contains the actual offset in bytes. Must be used atomically. */
2273
    ma_bool8 ownsBuffer;                        /* Used to know whether or not miniaudio is responsible for free()-ing the buffer. */
2274
    ma_bool8 clearOnWriteAcquire;               /* When set, clears the acquired write buffer before returning from ma_rb_acquire_write(). */
2275
    ma_allocation_callbacks allocationCallbacks;
2276
} ma_rb;
2277
 
2278
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);
2279
MA_API ma_result ma_rb_init(size_t bufferSizeInBytes, void* pOptionalPreallocatedBuffer, const ma_allocation_callbacks* pAllocationCallbacks, ma_rb* pRB);
2280
MA_API void ma_rb_uninit(ma_rb* pRB);
2281
MA_API void ma_rb_reset(ma_rb* pRB);
2282
MA_API ma_result ma_rb_acquire_read(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut);
2283
MA_API ma_result ma_rb_commit_read(ma_rb* pRB, size_t sizeInBytes);
2284
MA_API ma_result ma_rb_acquire_write(ma_rb* pRB, size_t* pSizeInBytes, void** ppBufferOut);
2285
MA_API ma_result ma_rb_commit_write(ma_rb* pRB, size_t sizeInBytes);
2286
MA_API ma_result ma_rb_seek_read(ma_rb* pRB, size_t offsetInBytes);
2287
MA_API ma_result ma_rb_seek_write(ma_rb* pRB, size_t offsetInBytes);
2288
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. */
2289
MA_API ma_uint32 ma_rb_available_read(ma_rb* pRB);
2290
MA_API ma_uint32 ma_rb_available_write(ma_rb* pRB);
2291
MA_API size_t ma_rb_get_subbuffer_size(ma_rb* pRB);
2292
MA_API size_t ma_rb_get_subbuffer_stride(ma_rb* pRB);
2293
MA_API size_t ma_rb_get_subbuffer_offset(ma_rb* pRB, size_t subbufferIndex);
2294
MA_API void* ma_rb_get_subbuffer_ptr(ma_rb* pRB, size_t subbufferIndex, void* pBuffer);
2295
 
2296
 
2297
typedef struct
2298
{
2299
    ma_data_source_base ds;
2300
    ma_rb rb;
2301
    ma_format format;
2302
    ma_uint32 channels;
2303
    ma_uint32 sampleRate; /* Not required for the ring buffer itself, but useful for associating the data with some sample rate, particularly for data sources. */
2304
} ma_pcm_rb;
2305
 
2306
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);
2307
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);
2308
MA_API void ma_pcm_rb_uninit(ma_pcm_rb* pRB);
2309
MA_API void ma_pcm_rb_reset(ma_pcm_rb* pRB);
2310
MA_API ma_result ma_pcm_rb_acquire_read(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
2311
MA_API ma_result ma_pcm_rb_commit_read(ma_pcm_rb* pRB, ma_uint32 sizeInFrames);
2312
MA_API ma_result ma_pcm_rb_acquire_write(ma_pcm_rb* pRB, ma_uint32* pSizeInFrames, void** ppBufferOut);
2313
MA_API ma_result ma_pcm_rb_commit_write(ma_pcm_rb* pRB, ma_uint32 sizeInFrames);
2314
MA_API ma_result ma_pcm_rb_seek_read(ma_pcm_rb* pRB, ma_uint32 offsetInFrames);
2315
MA_API ma_result ma_pcm_rb_seek_write(ma_pcm_rb* pRB, ma_uint32 offsetInFrames);
2316
MA_API ma_int32 ma_pcm_rb_pointer_distance(ma_pcm_rb* pRB); /* Return value is in frames. */
2317
MA_API ma_uint32 ma_pcm_rb_available_read(ma_pcm_rb* pRB);
2318
MA_API ma_uint32 ma_pcm_rb_available_write(ma_pcm_rb* pRB);
2319
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_size(ma_pcm_rb* pRB);
2320
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_stride(ma_pcm_rb* pRB);
2321
MA_API ma_uint32 ma_pcm_rb_get_subbuffer_offset(ma_pcm_rb* pRB, ma_uint32 subbufferIndex);
2322
MA_API void* ma_pcm_rb_get_subbuffer_ptr(ma_pcm_rb* pRB, ma_uint32 subbufferIndex, void* pBuffer);
2323
MA_API ma_format ma_pcm_rb_get_format(const ma_pcm_rb* pRB);
2324
MA_API ma_uint32 ma_pcm_rb_get_channels(const ma_pcm_rb* pRB);
2325
MA_API ma_uint32 ma_pcm_rb_get_sample_rate(const ma_pcm_rb* pRB);
2326
MA_API void ma_pcm_rb_set_sample_rate(ma_pcm_rb* pRB, ma_uint32 sampleRate);
2327
 
2328
 
2329
/*
2330
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
2331
capture device writes to it, and then a playback device reads from it.
2332
 
2333
At the moment this is just a simple naive implementation, but in the future I want to implement some dynamic resampling to seamlessly
2334
handle desyncs. Note that the API is work in progress and may change at any time in any version.
2335
 
2336
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
2337
in frames. The internal sample rate of the capture device is also needed in order to calculate the size.
2338
*/
2339
typedef struct
2340
{
2341
    ma_pcm_rb rb;
2342
} ma_duplex_rb;
2343
 
2344
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);
2345
MA_API ma_result ma_duplex_rb_uninit(ma_duplex_rb* pRB);
2346
 
2347
 
2348
/************************************************************************************************************************************************************
2349
 
2350
Miscellaneous Helpers
2351
 
2352
************************************************************************************************************************************************************/
2353
/*
2354
Retrieves a human readable description of the given result code.
2355
*/
2356
MA_API const char* ma_result_description(ma_result result);
2357
 
2358
/*
2359
malloc()
2360
*/
2361
MA_API void* ma_malloc(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks);
2362
 
2363
/*
2364
calloc()
2365
*/
2366
MA_API void* ma_calloc(size_t sz, const ma_allocation_callbacks* pAllocationCallbacks);
2367
 
2368
/*
2369
realloc()
2370
*/
2371
MA_API void* ma_realloc(void* p, size_t sz, const ma_allocation_callbacks* pAllocationCallbacks);
2372
 
2373
/*
2374
free()
2375
*/
2376
MA_API void ma_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
2377
 
2378
/*
2379
Performs an aligned malloc, with the assumption that the alignment is a power of 2.
2380
*/
2381
MA_API void* ma_aligned_malloc(size_t sz, size_t alignment, const ma_allocation_callbacks* pAllocationCallbacks);
2382
 
2383
/*
2384
Free's an aligned malloc'd buffer.
2385
*/
2386
MA_API void ma_aligned_free(void* p, const ma_allocation_callbacks* pAllocationCallbacks);
2387
 
2388
/*
2389
Retrieves a friendly name for a format.
2390
*/
2391
MA_API const char* ma_get_format_name(ma_format format);
2392
 
2393
/*
2394
Blends two frames in floating point format.
2395
*/
2396
MA_API void ma_blend_f32(float* pOut, float* pInA, float* pInB, float factor, ma_uint32 channels);
2397
 
2398
/*
2399
Retrieves the size of a sample in bytes for the given format.
2400
 
2401
This API is efficient and is implemented using a lookup table.
2402
 
2403
Thread Safety: SAFE
2404
  This API is pure.
2405
*/
2406
MA_API ma_uint32 ma_get_bytes_per_sample(ma_format format);
2407
static MA_INLINE ma_uint32 ma_get_bytes_per_frame(ma_format format, ma_uint32 channels) { return ma_get_bytes_per_sample(format) * channels; }
2408
 
2409
/*
2410
Converts a log level to a string.
2411
*/
2412
MA_API const char* ma_log_level_to_string(ma_uint32 logLevel);
2413
 
2414
 
2415
 
2416
 
2417
/************************************************************************************************************************************************************
2418
 
2419
Synchronization
2420
 
2421
************************************************************************************************************************************************************/
2422
/*
2423
Locks a spinlock.
2424
*/
2425
MA_API ma_result ma_spinlock_lock(volatile ma_spinlock* pSpinlock);
2426
 
2427
/*
2428
Locks a spinlock, but does not yield() when looping.
2429
*/
2430
MA_API ma_result ma_spinlock_lock_noyield(volatile ma_spinlock* pSpinlock);
2431
 
2432
/*
2433
Unlocks a spinlock.
2434
*/
2435
MA_API ma_result ma_spinlock_unlock(volatile ma_spinlock* pSpinlock);
2436
 
2437
 
2438
#ifndef MA_NO_THREADING
2439
 
2440
/*
2441
Creates a mutex.
2442
 
2443
A mutex must be created from a valid context. A mutex is initially unlocked.
2444
*/
2445
MA_API ma_result ma_mutex_init(ma_mutex* pMutex);
2446
 
2447
/*
2448
Deletes a mutex.
2449
*/
2450
MA_API void ma_mutex_uninit(ma_mutex* pMutex);
2451
 
2452
/*
2453
Locks a mutex with an infinite timeout.
2454
*/
2455
MA_API void ma_mutex_lock(ma_mutex* pMutex);
2456
 
2457
/*
2458
Unlocks a mutex.
2459
*/
2460
MA_API void ma_mutex_unlock(ma_mutex* pMutex);
2461
 
2462
 
2463
/*
2464
Initializes an auto-reset event.
2465
*/
2466
MA_API ma_result ma_event_init(ma_event* pEvent);
2467
 
2468
/*
2469
Uninitializes an auto-reset event.
2470
*/
2471
MA_API void ma_event_uninit(ma_event* pEvent);
2472
 
2473
/*
2474
Waits for the specified auto-reset event to become signalled.
2475
*/
2476
MA_API ma_result ma_event_wait(ma_event* pEvent);
2477
 
2478
/*
2479
Signals the specified auto-reset event.
2480
*/
2481
MA_API ma_result ma_event_signal(ma_event* pEvent);
2482
#endif  /* MA_NO_THREADING */
2483
 
2484
 
2485
/*
2486
Fence
2487
=====
2488
This locks while the counter is larger than 0. Counter can be incremented and decremented by any
2489
thread, but care needs to be taken when waiting. It is possible for one thread to acquire the
2490
fence just as another thread returns from ma_fence_wait().
2491
 
2492
The idea behind a fence is to allow you to wait for a group of operations to complete. When an
2493
operation starts, the counter is incremented which locks the fence. When the operation completes,
2494
the fence will be released which decrements the counter. ma_fence_wait() will block until the
2495
counter hits zero.
2496
 
2497
If threading is disabled, ma_fence_wait() will spin on the counter.
2498
*/
2499
typedef struct
2500
{
2501
#ifndef MA_NO_THREADING
2502
    ma_event e;
2503
#endif
2504
    ma_uint32 counter;
2505
} ma_fence;
2506
 
2507
MA_API ma_result ma_fence_init(ma_fence* pFence);
2508
MA_API void ma_fence_uninit(ma_fence* pFence);
2509
MA_API ma_result ma_fence_acquire(ma_fence* pFence);    /* Increment counter. */
2510
MA_API ma_result ma_fence_release(ma_fence* pFence);    /* Decrement counter. */
2511
MA_API ma_result ma_fence_wait(ma_fence* pFence);       /* Wait for counter to reach 0. */
2512
 
2513
 
2514
 
2515
/*
2516
Notification callback for asynchronous operations.
2517
*/
2518
typedef void ma_async_notification;
2519
 
2520
typedef struct
2521
{
2522
    void (* onSignal)(ma_async_notification* pNotification);
2523
} ma_async_notification_callbacks;
2524
 
2525
MA_API ma_result ma_async_notification_signal(ma_async_notification* pNotification);
2526
 
2527
 
2528
/*
2529
Simple polling notification.
2530
 
2531
This just sets a variable when the notification has been signalled which is then polled with ma_async_notification_poll_is_signalled()
2532
*/
2533
typedef struct
2534
{
2535
    ma_async_notification_callbacks cb;
2536
    ma_bool32 signalled;
2537
} ma_async_notification_poll;
2538
 
2539
MA_API ma_result ma_async_notification_poll_init(ma_async_notification_poll* pNotificationPoll);
2540
MA_API ma_bool32 ma_async_notification_poll_is_signalled(const ma_async_notification_poll* pNotificationPoll);
2541
 
2542
 
2543
/*
2544
Event Notification
2545
 
2546
This uses an ma_event. If threading is disabled (MA_NO_THREADING), initialization will fail.
2547
*/
2548
typedef struct
2549
{
2550
    ma_async_notification_callbacks cb;
2551
#ifndef MA_NO_THREADING
2552
    ma_event e;
2553
#endif
2554
} ma_async_notification_event;
2555
 
2556
MA_API ma_result ma_async_notification_event_init(ma_async_notification_event* pNotificationEvent);
2557
MA_API ma_result ma_async_notification_event_uninit(ma_async_notification_event* pNotificationEvent);
2558
MA_API ma_result ma_async_notification_event_wait(ma_async_notification_event* pNotificationEvent);
2559
MA_API ma_result ma_async_notification_event_signal(ma_async_notification_event* pNotificationEvent);
2560
 
2561
 
2562
 
2563
 
2564
/************************************************************************************************************************************************************
2565
 
2566
Job Queue
2567
 
2568
************************************************************************************************************************************************************/
2569
 
2570
/*
2571
Slot Allocator
2572
--------------
2573
The idea of the slot allocator is for it to be used in conjunction with a fixed sized buffer. You use the slot allocator to allocator an index that can be used
2574
as the insertion point for an object.
2575
 
2576
Slots are reference counted to help mitigate the ABA problem in the lock-free queue we use for tracking jobs.
2577
 
2578
The slot index is stored in the low 32 bits. The reference counter is stored in the high 32 bits:
2579
 
2580
    +-----------------+-----------------+
2581
    | 32 Bits         | 32 Bits         |
2582
    +-----------------+-----------------+
2583
    | Reference Count | Slot Index      |
2584
    +-----------------+-----------------+
2585
*/
2586
typedef struct
2587
{
2588
    ma_uint32 capacity;    /* The number of slots to make available. */
2589
} ma_slot_allocator_config;
2590
 
2591
MA_API ma_slot_allocator_config ma_slot_allocator_config_init(ma_uint32 capacity);
2592
 
2593
 
2594
typedef struct
2595
{
2596
    MA_ATOMIC(4, ma_uint32) bitfield;   /* Must be used atomically because the allocation and freeing routines need to make copies of this which must never be optimized away by the compiler. */
2597
} ma_slot_allocator_group;
2598
 
2599
typedef struct
2600
{
2601
    ma_slot_allocator_group* pGroups;   /* Slots are grouped in chunks of 32. */
2602
    ma_uint32* pSlots;                  /* 32 bits for reference counting for ABA mitigation. */
2603
    ma_uint32 count;                    /* Allocation count. */
2604
    ma_uint32 capacity;
2605
 
2606
    /* Memory management. */
2607
    ma_bool32 _ownsHeap;
2608
    void* _pHeap;
2609
} ma_slot_allocator;
2610
 
2611
MA_API ma_result ma_slot_allocator_get_heap_size(const ma_slot_allocator_config* pConfig, size_t* pHeapSizeInBytes);
2612
MA_API ma_result ma_slot_allocator_init_preallocated(const ma_slot_allocator_config* pConfig, void* pHeap, ma_slot_allocator* pAllocator);
2613
MA_API ma_result ma_slot_allocator_init(const ma_slot_allocator_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_slot_allocator* pAllocator);
2614
MA_API void ma_slot_allocator_uninit(ma_slot_allocator* pAllocator, const ma_allocation_callbacks* pAllocationCallbacks);
2615
MA_API ma_result ma_slot_allocator_alloc(ma_slot_allocator* pAllocator, ma_uint64* pSlot);
2616
MA_API ma_result ma_slot_allocator_free(ma_slot_allocator* pAllocator, ma_uint64 slot);
2617
 
2618
 
2619
typedef struct ma_job ma_job;
2620
 
2621
/*
2622
Callback for processing a job. Each job type will have their own processing callback which will be
2623
called by ma_job_process().
2624
*/
2625
typedef ma_result (* ma_job_proc)(ma_job* pJob);
2626
 
2627
/* When a job type is added here an callback needs to be added go "g_jobVTable" in the implementation section. */
2628
typedef enum
2629
{
2630
    /* Miscellaneous. */
2631
    MA_JOB_TYPE_QUIT = 0,
2632
    MA_JOB_TYPE_CUSTOM,
2633
 
2634
    /* Resource Manager. */
2635
    MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER_NODE,
2636
    MA_JOB_TYPE_RESOURCE_MANAGER_FREE_DATA_BUFFER_NODE,
2637
    MA_JOB_TYPE_RESOURCE_MANAGER_PAGE_DATA_BUFFER_NODE,
2638
    MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_BUFFER,
2639
    MA_JOB_TYPE_RESOURCE_MANAGER_FREE_DATA_BUFFER,
2640
    MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_STREAM,
2641
    MA_JOB_TYPE_RESOURCE_MANAGER_FREE_DATA_STREAM,
2642
    MA_JOB_TYPE_RESOURCE_MANAGER_PAGE_DATA_STREAM,
2643
    MA_JOB_TYPE_RESOURCE_MANAGER_SEEK_DATA_STREAM,
2644
 
2645
    /* Device. */
2646
    MA_JOB_TYPE_DEVICE_AAUDIO_REROUTE,
2647
 
2648
    /* Count. Must always be last. */
2649
    MA_JOB_TYPE_COUNT
2650
} ma_job_type;
2651
 
2652
struct ma_job
2653
{
2654
    union
2655
    {
2656
        struct
2657
        {
2658
            ma_uint16 code;         /* Job type. */
2659
            ma_uint16 slot;         /* Index into a ma_slot_allocator. */
2660
            ma_uint32 refcount;
2661
        } breakup;
2662
        ma_uint64 allocation;
2663
    } toc;  /* 8 bytes. We encode the job code into the slot allocation data to save space. */
2664
    MA_ATOMIC(8, ma_uint64) next; /* refcount + slot for the next item. Does not include the job code. */
2665
    ma_uint32 order;    /* Execution order. Used to create a data dependency and ensure a job is executed in order. Usage is contextual depending on the job type. */
2666
 
2667
    union
2668
    {
2669
        /* Miscellaneous. */
2670
        struct
2671
        {
2672
            ma_job_proc proc;
2673
            ma_uintptr data0;
2674
            ma_uintptr data1;
2675
        } custom;
2676
 
2677
        /* Resource Manager */
2678
        union
2679
        {
2680
            struct
2681
            {
2682
                /*ma_resource_manager**/ void* pResourceManager;
2683
                /*ma_resource_manager_data_buffer_node**/ void* pDataBufferNode;
2684
                char* pFilePath;
2685
                wchar_t* pFilePathW;
2686
                ma_uint32 flags;                                /* Resource manager data source flags that were used when initializing the data buffer. */
2687
                ma_async_notification* pInitNotification;       /* Signalled when the data buffer has been initialized and the format/channels/rate can be retrieved. */
2688
                ma_async_notification* pDoneNotification;       /* Signalled when the data buffer has been fully decoded. Will be passed through to MA_JOB_TYPE_RESOURCE_MANAGER_PAGE_DATA_BUFFER_NODE when decoding. */
2689
                ma_fence* pInitFence;                           /* Released when initialization of the decoder is complete. */
2690
                ma_fence* pDoneFence;                           /* Released if initialization of the decoder fails. Passed through to PAGE_DATA_BUFFER_NODE untouched if init is successful. */
2691
            } loadDataBufferNode;
2692
            struct
2693
            {
2694
                /*ma_resource_manager**/ void* pResourceManager;
2695
                /*ma_resource_manager_data_buffer_node**/ void* pDataBufferNode;
2696
                ma_async_notification* pDoneNotification;
2697
                ma_fence* pDoneFence;
2698
            } freeDataBufferNode;
2699
            struct
2700
            {
2701
                /*ma_resource_manager**/ void* pResourceManager;
2702
                /*ma_resource_manager_data_buffer_node**/ void* pDataBufferNode;
2703
                /*ma_decoder**/ void* pDecoder;
2704
                ma_async_notification* pDoneNotification;       /* Signalled when the data buffer has been fully decoded. */
2705
                ma_fence* pDoneFence;                           /* Passed through from LOAD_DATA_BUFFER_NODE and released when the data buffer completes decoding or an error occurs. */
2706
            } pageDataBufferNode;
2707
 
2708
            struct
2709
            {
2710
                /*ma_resource_manager_data_buffer**/ void* pDataBuffer;
2711
                ma_async_notification* pInitNotification;       /* Signalled when the data buffer has been initialized and the format/channels/rate can be retrieved. */
2712
                ma_async_notification* pDoneNotification;       /* Signalled when the data buffer has been fully decoded. */
2713
                ma_fence* pInitFence;                           /* Released when the data buffer has been initialized and the format/channels/rate can be retrieved. */
2714
                ma_fence* pDoneFence;                           /* Released when the data buffer has been fully decoded. */
2715
                ma_uint64 rangeBegInPCMFrames;
2716
                ma_uint64 rangeEndInPCMFrames;
2717
                ma_uint64 loopPointBegInPCMFrames;
2718
                ma_uint64 loopPointEndInPCMFrames;
2719
                ma_uint32 isLooping;
2720
            } loadDataBuffer;
2721
            struct
2722
            {
2723
                /*ma_resource_manager_data_buffer**/ void* pDataBuffer;
2724
                ma_async_notification* pDoneNotification;
2725
                ma_fence* pDoneFence;
2726
            } freeDataBuffer;
2727
 
2728
            struct
2729
            {
2730
                /*ma_resource_manager_data_stream**/ void* pDataStream;
2731
                char* pFilePath;                            /* Allocated when the job is posted, freed by the job thread after loading. */
2732
                wchar_t* pFilePathW;                        /* ^ As above ^. Only used if pFilePath is NULL. */
2733
                ma_uint64 initialSeekPoint;
2734
                ma_async_notification* pInitNotification;   /* Signalled after the first two pages have been decoded and frames can be read from the stream. */
2735
                ma_fence* pInitFence;
2736
            } loadDataStream;
2737
            struct
2738
            {
2739
                /*ma_resource_manager_data_stream**/ void* pDataStream;
2740
                ma_async_notification* pDoneNotification;
2741
                ma_fence* pDoneFence;
2742
            } freeDataStream;
2743
            struct
2744
            {
2745
                /*ma_resource_manager_data_stream**/ void* pDataStream;
2746
                ma_uint32 pageIndex;                    /* The index of the page to decode into. */
2747
            } pageDataStream;
2748
            struct
2749
            {
2750
                /*ma_resource_manager_data_stream**/ void* pDataStream;
2751
                ma_uint64 frameIndex;
2752
            } seekDataStream;
2753
        } resourceManager;
2754
 
2755
        /* Device. */
2756
        union
2757
        {
2758
            union
2759
            {
2760
                struct
2761
                {
2762
                    /*ma_device**/ void* pDevice;
2763
                    /*ma_device_type*/ ma_uint32 deviceType;
2764
                } reroute;
2765
            } aaudio;
2766
        } device;
2767
    } data;
2768
};
2769
 
2770
MA_API ma_job ma_job_init(ma_uint16 code);
2771
MA_API ma_result ma_job_process(ma_job* pJob);
2772
 
2773
 
2774
/*
2775
When set, ma_job_queue_next() will not wait and no semaphore will be signaled in
2776
ma_job_queue_post(). ma_job_queue_next() will return MA_NO_DATA_AVAILABLE if nothing is available.
2777
 
2778
This flag should always be used for platforms that do not support multithreading.
2779
*/
2780
typedef enum
2781
{
2782
    MA_JOB_QUEUE_FLAG_NON_BLOCKING = 0x00000001
2783
} ma_job_queue_flags;
2784
 
2785
typedef struct
2786
{
2787
    ma_uint32 flags;
2788
    ma_uint32 capacity; /* The maximum number of jobs that can fit in the queue at a time. */
2789
} ma_job_queue_config;
2790
 
2791
MA_API ma_job_queue_config ma_job_queue_config_init(ma_uint32 flags, ma_uint32 capacity);
2792
 
2793
 
2794
typedef struct
2795
{
2796
    ma_uint32 flags;                /* Flags passed in at initialization time. */
2797
    ma_uint32 capacity;             /* The maximum number of jobs that can fit in the queue at a time. Set by the config. */
2798
    MA_ATOMIC(8, ma_uint64) head;   /* The first item in the list. Required for removing from the top of the list. */
2799
    MA_ATOMIC(8, ma_uint64) tail;   /* The last item in the list. Required for appending to the end of the list. */
2800
#ifndef MA_NO_THREADING
2801
    ma_semaphore sem;               /* Only used when MA_JOB_QUEUE_FLAG_NON_BLOCKING is unset. */
2802
#endif
2803
    ma_slot_allocator allocator;
2804
    ma_job* pJobs;
2805
#ifndef MA_USE_EXPERIMENTAL_LOCK_FREE_JOB_QUEUE
2806
    ma_spinlock lock;
2807
#endif
2808
 
2809
    /* Memory management. */
2810
    void* _pHeap;
2811
    ma_bool32 _ownsHeap;
2812
} ma_job_queue;
2813
 
2814
MA_API ma_result ma_job_queue_get_heap_size(const ma_job_queue_config* pConfig, size_t* pHeapSizeInBytes);
2815
MA_API ma_result ma_job_queue_init_preallocated(const ma_job_queue_config* pConfig, void* pHeap, ma_job_queue* pQueue);
2816
MA_API ma_result ma_job_queue_init(const ma_job_queue_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_job_queue* pQueue);
2817
MA_API void ma_job_queue_uninit(ma_job_queue* pQueue, const ma_allocation_callbacks* pAllocationCallbacks);
2818
MA_API ma_result ma_job_queue_post(ma_job_queue* pQueue, const ma_job* pJob);
2819
MA_API ma_result ma_job_queue_next(ma_job_queue* pQueue, ma_job* pJob); /* Returns MA_CANCELLED if the next job is a quit job. */
2820
 
2821
 
2822
 
2823
/************************************************************************************************************************************************************
2824
*************************************************************************************************************************************************************
2825
 
2826
DEVICE I/O
2827
==========
2828
 
2829
This section contains the APIs for device playback and capture. Here is where you'll find ma_device_init(), etc.
2830
 
2831
*************************************************************************************************************************************************************
2832
************************************************************************************************************************************************************/
2833
#ifndef MA_NO_DEVICE_IO
2834
/* Some backends are only supported on certain platforms. */
2835
#if defined(MA_WIN32)
2836
    #define MA_SUPPORT_WASAPI
2837
 
2838
    #if defined(MA_WIN32_DESKTOP)   /* DirectSound and WinMM backends are only supported on desktops. */
2839
        #define MA_SUPPORT_DSOUND
2840
        #define MA_SUPPORT_WINMM
2841
 
2842
        /* Don't enable JACK here if compiling with Cosmopolitan. It'll be enabled in the Linux section below. */
2843
        #if !defined(__COSMOPOLITAN__)
2844
            #define MA_SUPPORT_JACK    /* JACK is technically supported on Windows, but I don't know how many people use it in practice... */
2845
        #endif
2846
    #endif
2847
#endif
2848
#if defined(MA_UNIX) && !defined(MA_ORBIS) && !defined(MA_PROSPERO)
2849
    #if defined(MA_LINUX)
2850
        #if !defined(MA_ANDROID) && !defined(__COSMOPOLITAN__)   /* ALSA is not supported on Android. */
2851
            #define MA_SUPPORT_ALSA
2852
        #endif
2853
    #endif
2854
    #if !defined(MA_BSD) && !defined(MA_ANDROID) && !defined(MA_EMSCRIPTEN)
2855
        #define MA_SUPPORT_PULSEAUDIO
2856
        #define MA_SUPPORT_JACK
2857
    #endif
2858
    #if defined(__OpenBSD__)        /* <-- Change this to "#if defined(MA_BSD)" to enable sndio on all BSD flavors. */
2859
        #define MA_SUPPORT_SNDIO    /* sndio is only supported on OpenBSD for now. May be expanded later if there's demand. */
2860
    #endif
2861
    #if defined(__NetBSD__) || defined(__OpenBSD__)
2862
        #define MA_SUPPORT_AUDIO4   /* Only support audio(4) on platforms with known support. */
2863
    #endif
2864
    #if defined(__FreeBSD__) || defined(__DragonFly__)
2865
        #define MA_SUPPORT_OSS      /* Only support OSS on specific platforms with known support. */
2866
    #endif
2867
#endif
2868
#if defined(MA_ANDROID)
2869
    #define MA_SUPPORT_AAUDIO
2870
    #define MA_SUPPORT_OPENSL
2871
#endif
2872
#if defined(MA_APPLE)
2873
    #define MA_SUPPORT_COREAUDIO
2874
#endif
2875
#if defined(MA_EMSCRIPTEN)
2876
    #define MA_SUPPORT_WEBAUDIO
2877
#endif
2878
 
2879
/* All platforms should support custom backends. */
2880
#define MA_SUPPORT_CUSTOM
2881
 
2882
/* Explicitly disable the Null backend for Emscripten because it uses a background thread which is not properly supported right now. */
2883
#if !defined(MA_EMSCRIPTEN)
2884
#define MA_SUPPORT_NULL
2885
#endif
2886
 
2887
 
2888
#if defined(MA_SUPPORT_WASAPI) && !defined(MA_NO_WASAPI) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_WASAPI))
2889
    #define MA_HAS_WASAPI
2890
#endif
2891
#if defined(MA_SUPPORT_DSOUND) && !defined(MA_NO_DSOUND) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_DSOUND))
2892
    #define MA_HAS_DSOUND
2893
#endif
2894
#if defined(MA_SUPPORT_WINMM) && !defined(MA_NO_WINMM) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_WINMM))
2895
    #define MA_HAS_WINMM
2896
#endif
2897
#if defined(MA_SUPPORT_ALSA) && !defined(MA_NO_ALSA) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_ALSA))
2898
    #define MA_HAS_ALSA
2899
#endif
2900
#if defined(MA_SUPPORT_PULSEAUDIO) && !defined(MA_NO_PULSEAUDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_PULSEAUDIO))
2901
    #define MA_HAS_PULSEAUDIO
2902
#endif
2903
#if defined(MA_SUPPORT_JACK) && !defined(MA_NO_JACK) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_JACK))
2904
    #define MA_HAS_JACK
2905
#endif
2906
#if defined(MA_SUPPORT_COREAUDIO) && !defined(MA_NO_COREAUDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_COREAUDIO))
2907
    #define MA_HAS_COREAUDIO
2908
#endif
2909
#if defined(MA_SUPPORT_SNDIO) && !defined(MA_NO_SNDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_SNDIO))
2910
    #define MA_HAS_SNDIO
2911
#endif
2912
#if defined(MA_SUPPORT_AUDIO4) && !defined(MA_NO_AUDIO4) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_AUDIO4))
2913
    #define MA_HAS_AUDIO4
2914
#endif
2915
#if defined(MA_SUPPORT_OSS) && !defined(MA_NO_OSS) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_OSS))
2916
    #define MA_HAS_OSS
2917
#endif
2918
#if defined(MA_SUPPORT_AAUDIO) && !defined(MA_NO_AAUDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_AAUDIO))
2919
    #define MA_HAS_AAUDIO
2920
#endif
2921
#if defined(MA_SUPPORT_OPENSL) && !defined(MA_NO_OPENSL) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_OPENSL))
2922
    #define MA_HAS_OPENSL
2923
#endif
2924
#if defined(MA_SUPPORT_WEBAUDIO) && !defined(MA_NO_WEBAUDIO) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_WEBAUDIO))
2925
    #define MA_HAS_WEBAUDIO
2926
#endif
2927
#if defined(MA_SUPPORT_CUSTOM) && !defined(MA_NO_CUSTOM) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_CUSTOM))
2928
    #define MA_HAS_CUSTOM
2929
#endif
2930
#if defined(MA_SUPPORT_NULL) && !defined(MA_NO_NULL) && (!defined(MA_ENABLE_ONLY_SPECIFIC_BACKENDS) || defined(MA_ENABLE_NULL))
2931
    #define MA_HAS_NULL
2932
#endif
2933
 
2934
typedef enum
2935
{
2936
    ma_device_state_uninitialized = 0,
2937
    ma_device_state_stopped       = 1,  /* The device's default state after initialization. */
2938
    ma_device_state_started       = 2,  /* The device is started and is requesting and/or delivering audio data. */
2939
    ma_device_state_starting      = 3,  /* Transitioning from a stopped state to started. */
2940
    ma_device_state_stopping      = 4   /* Transitioning from a started state to stopped. */
2941
} ma_device_state;
2942
 
2943
MA_ATOMIC_SAFE_TYPE_DECL(i32, 4, device_state)
2944
 
2945
 
2946
#ifdef MA_SUPPORT_WASAPI
2947
/* We need a IMMNotificationClient object for WASAPI. */
2948
typedef struct
2949
{
2950
    void* lpVtbl;
2951
    ma_uint32 counter;
2952
    ma_device* pDevice;
2953
} ma_IMMNotificationClient;
2954
#endif
2955
 
2956
/* Backend enums must be in priority order. */
2957
typedef enum
2958
{
2959
    ma_backend_wasapi,
2960
    ma_backend_dsound,
2961
    ma_backend_winmm,
2962
    ma_backend_coreaudio,
2963
    ma_backend_sndio,
2964
    ma_backend_audio4,
2965
    ma_backend_oss,
2966
    ma_backend_pulseaudio,
2967
    ma_backend_alsa,
2968
    ma_backend_jack,
2969
    ma_backend_aaudio,
2970
    ma_backend_opensl,
2971
    ma_backend_webaudio,
2972
    ma_backend_custom,  /* <-- Custom backend, with callbacks defined by the context config. */
2973
    ma_backend_null     /* <-- Must always be the last item. Lowest priority, and used as the terminator for backend enumeration. */
2974
} ma_backend;
2975
 
2976
#define MA_BACKEND_COUNT (ma_backend_null+1)
2977
 
2978
 
2979
/*
2980
Device job thread. This is used by backends that require asynchronous processing of certain
2981
operations. It is not used by all backends.
2982
 
2983
The device job thread is made up of a thread and a job queue. You can post a job to the thread with
2984
ma_device_job_thread_post(). The thread will do the processing of the job.
2985
*/
2986
typedef struct
2987
{
2988
    ma_bool32 noThread; /* Set this to true if you want to process jobs yourself. */
2989
    ma_uint32 jobQueueCapacity;
2990
    ma_uint32 jobQueueFlags;
2991
} ma_device_job_thread_config;
2992
 
2993
MA_API ma_device_job_thread_config ma_device_job_thread_config_init(void);
2994
 
2995
typedef struct
2996
{
2997
    ma_thread thread;
2998
    ma_job_queue jobQueue;
2999
    ma_bool32 _hasThread;
3000
} ma_device_job_thread;
3001
 
3002
MA_API ma_result ma_device_job_thread_init(const ma_device_job_thread_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_device_job_thread* pJobThread);
3003
MA_API void ma_device_job_thread_uninit(ma_device_job_thread* pJobThread, const ma_allocation_callbacks* pAllocationCallbacks);
3004
MA_API ma_result ma_device_job_thread_post(ma_device_job_thread* pJobThread, const ma_job* pJob);
3005
MA_API ma_result ma_device_job_thread_next(ma_device_job_thread* pJobThread, ma_job* pJob);
3006
 
3007
 
3008
 
3009
/* Device notification types. */
3010
typedef enum
3011
{
3012
    ma_device_notification_type_started,
3013
    ma_device_notification_type_stopped,
3014
    ma_device_notification_type_rerouted,
3015
    ma_device_notification_type_interruption_began,
3016
    ma_device_notification_type_interruption_ended,
3017
    ma_device_notification_type_unlocked
3018
} ma_device_notification_type;
3019
 
3020
typedef struct
3021
{
3022
    ma_device* pDevice;
3023
    ma_device_notification_type type;
3024
    union
3025
    {
3026
        struct
3027
        {
3028
            int _unused;
3029
        } started;
3030
        struct
3031
        {
3032
            int _unused;
3033
        } stopped;
3034
        struct
3035
        {
3036
            int _unused;
3037
        } rerouted;
3038
        struct
3039
        {
3040
            int _unused;
3041
        } interruption;
3042
    } data;
3043
} ma_device_notification;
3044
 
3045
/*
3046
The notification callback for when the application should be notified of a change to the device.
3047
 
3048
This callback is used for notifying the application of changes such as when the device has started,
3049
stopped, rerouted or an interruption has occurred. Note that not all backends will post all
3050
notification types. For example, some backends will perform automatic stream routing without any
3051
kind of notification to the host program which means miniaudio will never know about it and will
3052
never be able to fire the rerouted notification. You should keep this in mind when designing your
3053
program.
3054
 
3055
The stopped notification will *not* get fired when a device is rerouted.
3056
 
3057
 
3058
Parameters
3059
----------
3060
pNotification (in)
3061
    A pointer to a structure containing information about the event. Use the `pDevice` member of
3062
    this object to retrieve the relevant device. The `type` member can be used to discriminate
3063
    against each of the notification types.
3064
 
3065
 
3066
Remarks
3067
-------
3068
Do not restart or uninitialize the device from the callback.
3069
 
3070
Not all notifications will be triggered by all backends, however the started and stopped events
3071
should be reliable for all backends. Some backends do not have a good way to detect device
3072
stoppages due to unplugging the device which may result in the stopped callback not getting
3073
fired. This has been observed with at least one BSD variant.
3074
 
3075
The rerouted notification is fired *after* the reroute has occurred. The stopped notification will
3076
*not* get fired when a device is rerouted. The following backends are known to do automatic stream
3077
rerouting, but do not have a way to be notified of the change:
3078
 
3079
  * DirectSound
3080
 
3081
The interruption notifications are used on mobile platforms for detecting when audio is interrupted
3082
due to things like an incoming phone call. Currently this is only implemented on iOS. None of the
3083
Android backends will report this notification.
3084
*/
3085
typedef void (* ma_device_notification_proc)(const ma_device_notification* pNotification);
3086
 
3087
 
3088
/*
3089
The callback for processing audio data from the device.
3090
 
3091
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
3092
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
3093
callback will be fired with a consistent frame count.
3094
 
3095
 
3096
Parameters
3097
----------
3098
pDevice (in)
3099
    A pointer to the relevant device.
3100
 
3101
pOutput (out)
3102
    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
3103
    full-duplex device and null for a capture and loopback device.
3104
 
3105
pInput (in)
3106
    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
3107
    playback device.
3108
 
3109
frameCount (in)
3110
    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
3111
    `periodSizeInFrames` and `periodSizeInMilliseconds` members of the device config are just hints, and are not necessarily exactly what you'll get. You must
3112
    not assume this will always be the same value each time the callback is fired.
3113
 
3114
 
3115
Remarks
3116
-------
3117
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
3118
callback. The following APIs cannot be called from inside the callback:
3119
 
3120
    ma_device_init()
3121
    ma_device_init_ex()
3122
    ma_device_uninit()
3123
    ma_device_start()
3124
    ma_device_stop()
3125
 
3126
The proper way to stop the device is to call `ma_device_stop()` from a different thread, normally the main application thread.
3127
*/
3128
typedef void (* ma_device_data_proc)(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
3129
 
3130
 
3131
 
3132
 
3133
/*
3134
DEPRECATED. Use ma_device_notification_proc instead.
3135
 
3136
The callback for when the device has been stopped.
3137
 
3138
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
3139
such as being unplugged or an internal error occurring.
3140
 
3141
 
3142
Parameters
3143
----------
3144
pDevice (in)
3145
    A pointer to the device that has just stopped.
3146
 
3147
 
3148
Remarks
3149
-------
3150
Do not restart or uninitialize the device from the callback.
3151
*/
3152
typedef void (* ma_stop_proc)(ma_device* pDevice);  /* DEPRECATED. Use ma_device_notification_proc instead. */
3153
 
3154
typedef enum
3155
{
3156
    ma_device_type_playback = 1,
3157
    ma_device_type_capture  = 2,
3158
    ma_device_type_duplex   = ma_device_type_playback | ma_device_type_capture, /* 3 */
3159
    ma_device_type_loopback = 4
3160
} ma_device_type;
3161
 
3162
typedef enum
3163
{
3164
    ma_share_mode_shared = 0,
3165
    ma_share_mode_exclusive
3166
} ma_share_mode;
3167
 
3168
/* iOS/tvOS/watchOS session categories. */
3169
typedef enum
3170
{
3171
    ma_ios_session_category_default = 0,        /* AVAudioSessionCategoryPlayAndRecord. */
3172
    ma_ios_session_category_none,               /* Leave the session category unchanged. */
3173
    ma_ios_session_category_ambient,            /* AVAudioSessionCategoryAmbient */
3174
    ma_ios_session_category_solo_ambient,       /* AVAudioSessionCategorySoloAmbient */
3175
    ma_ios_session_category_playback,           /* AVAudioSessionCategoryPlayback */
3176
    ma_ios_session_category_record,             /* AVAudioSessionCategoryRecord */
3177
    ma_ios_session_category_play_and_record,    /* AVAudioSessionCategoryPlayAndRecord */
3178
    ma_ios_session_category_multi_route         /* AVAudioSessionCategoryMultiRoute */
3179
} ma_ios_session_category;
3180
 
3181
/* iOS/tvOS/watchOS session category options */
3182
typedef enum
3183
{
3184
    ma_ios_session_category_option_mix_with_others                            = 0x01,   /* AVAudioSessionCategoryOptionMixWithOthers */
3185
    ma_ios_session_category_option_duck_others                                = 0x02,   /* AVAudioSessionCategoryOptionDuckOthers */
3186
    ma_ios_session_category_option_allow_bluetooth                            = 0x04,   /* AVAudioSessionCategoryOptionAllowBluetooth */
3187
    ma_ios_session_category_option_default_to_speaker                         = 0x08,   /* AVAudioSessionCategoryOptionDefaultToSpeaker */
3188
    ma_ios_session_category_option_interrupt_spoken_audio_and_mix_with_others = 0x11,   /* AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers */
3189
    ma_ios_session_category_option_allow_bluetooth_a2dp                       = 0x20,   /* AVAudioSessionCategoryOptionAllowBluetoothA2DP */
3190
    ma_ios_session_category_option_allow_air_play                             = 0x40,   /* AVAudioSessionCategoryOptionAllowAirPlay */
3191
} ma_ios_session_category_option;
3192
 
3193
/* OpenSL stream types. */
3194
typedef enum
3195
{
3196
    ma_opensl_stream_type_default = 0,              /* Leaves the stream type unset. */
3197
    ma_opensl_stream_type_voice,                    /* SL_ANDROID_STREAM_VOICE */
3198
    ma_opensl_stream_type_system,                   /* SL_ANDROID_STREAM_SYSTEM */
3199
    ma_opensl_stream_type_ring,                     /* SL_ANDROID_STREAM_RING */
3200
    ma_opensl_stream_type_media,                    /* SL_ANDROID_STREAM_MEDIA */
3201
    ma_opensl_stream_type_alarm,                    /* SL_ANDROID_STREAM_ALARM */
3202
    ma_opensl_stream_type_notification              /* SL_ANDROID_STREAM_NOTIFICATION */
3203
} ma_opensl_stream_type;
3204
 
3205
/* OpenSL recording presets. */
3206
typedef enum
3207
{
3208
    ma_opensl_recording_preset_default = 0,         /* Leaves the input preset unset. */
3209
    ma_opensl_recording_preset_generic,             /* SL_ANDROID_RECORDING_PRESET_GENERIC */
3210
    ma_opensl_recording_preset_camcorder,           /* SL_ANDROID_RECORDING_PRESET_CAMCORDER */
3211
    ma_opensl_recording_preset_voice_recognition,   /* SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION */
3212
    ma_opensl_recording_preset_voice_communication, /* SL_ANDROID_RECORDING_PRESET_VOICE_COMMUNICATION */
3213
    ma_opensl_recording_preset_voice_unprocessed    /* SL_ANDROID_RECORDING_PRESET_UNPROCESSED */
3214
} ma_opensl_recording_preset;
3215
 
3216
/* WASAPI audio thread priority characteristics. */
3217
typedef enum
3218
{
3219
    ma_wasapi_usage_default = 0,
3220
    ma_wasapi_usage_games,
3221
    ma_wasapi_usage_pro_audio,
3222
} ma_wasapi_usage;
3223
 
3224
/* AAudio usage types. */
3225
typedef enum
3226
{
3227
    ma_aaudio_usage_default = 0,                    /* Leaves the usage type unset. */
3228
    ma_aaudio_usage_media,                          /* AAUDIO_USAGE_MEDIA */
3229
    ma_aaudio_usage_voice_communication,            /* AAUDIO_USAGE_VOICE_COMMUNICATION */
3230
    ma_aaudio_usage_voice_communication_signalling, /* AAUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING */
3231
    ma_aaudio_usage_alarm,                          /* AAUDIO_USAGE_ALARM */
3232
    ma_aaudio_usage_notification,                   /* AAUDIO_USAGE_NOTIFICATION */
3233
    ma_aaudio_usage_notification_ringtone,          /* AAUDIO_USAGE_NOTIFICATION_RINGTONE */
3234
    ma_aaudio_usage_notification_event,             /* AAUDIO_USAGE_NOTIFICATION_EVENT */
3235
    ma_aaudio_usage_assistance_accessibility,       /* AAUDIO_USAGE_ASSISTANCE_ACCESSIBILITY */
3236
    ma_aaudio_usage_assistance_navigation_guidance, /* AAUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE */
3237
    ma_aaudio_usage_assistance_sonification,        /* AAUDIO_USAGE_ASSISTANCE_SONIFICATION */
3238
    ma_aaudio_usage_game,                           /* AAUDIO_USAGE_GAME */
3239
    ma_aaudio_usage_assitant,                       /* AAUDIO_USAGE_ASSISTANT */
3240
    ma_aaudio_usage_emergency,                      /* AAUDIO_SYSTEM_USAGE_EMERGENCY */
3241
    ma_aaudio_usage_safety,                         /* AAUDIO_SYSTEM_USAGE_SAFETY */
3242
    ma_aaudio_usage_vehicle_status,                 /* AAUDIO_SYSTEM_USAGE_VEHICLE_STATUS */
3243
    ma_aaudio_usage_announcement                    /* AAUDIO_SYSTEM_USAGE_ANNOUNCEMENT */
3244
} ma_aaudio_usage;
3245
 
3246
/* AAudio content types. */
3247
typedef enum
3248
{
3249
    ma_aaudio_content_type_default = 0,             /* Leaves the content type unset. */
3250
    ma_aaudio_content_type_speech,                  /* AAUDIO_CONTENT_TYPE_SPEECH */
3251
    ma_aaudio_content_type_music,                   /* AAUDIO_CONTENT_TYPE_MUSIC */
3252
    ma_aaudio_content_type_movie,                   /* AAUDIO_CONTENT_TYPE_MOVIE */
3253
    ma_aaudio_content_type_sonification             /* AAUDIO_CONTENT_TYPE_SONIFICATION */
3254
} ma_aaudio_content_type;
3255
 
3256
/* AAudio input presets. */
3257
typedef enum
3258
{
3259
    ma_aaudio_input_preset_default = 0,             /* Leaves the input preset unset. */
3260
    ma_aaudio_input_preset_generic,                 /* AAUDIO_INPUT_PRESET_GENERIC */
3261
    ma_aaudio_input_preset_camcorder,               /* AAUDIO_INPUT_PRESET_CAMCORDER */
3262
    ma_aaudio_input_preset_voice_recognition,       /* AAUDIO_INPUT_PRESET_VOICE_RECOGNITION */
3263
    ma_aaudio_input_preset_voice_communication,     /* AAUDIO_INPUT_PRESET_VOICE_COMMUNICATION */
3264
    ma_aaudio_input_preset_unprocessed,             /* AAUDIO_INPUT_PRESET_UNPROCESSED */
3265
    ma_aaudio_input_preset_voice_performance        /* AAUDIO_INPUT_PRESET_VOICE_PERFORMANCE */
3266
} ma_aaudio_input_preset;
3267
 
3268
typedef enum
3269
{
3270
    ma_aaudio_allow_capture_default = 0,            /* Leaves the allowed capture policy unset. */
3271
    ma_aaudio_allow_capture_by_all,                 /* AAUDIO_ALLOW_CAPTURE_BY_ALL */
3272
    ma_aaudio_allow_capture_by_system,              /* AAUDIO_ALLOW_CAPTURE_BY_SYSTEM */
3273
    ma_aaudio_allow_capture_by_none                 /* AAUDIO_ALLOW_CAPTURE_BY_NONE */
3274
} ma_aaudio_allowed_capture_policy;
3275
 
3276
typedef union
3277
{
3278
    ma_int64 counter;
3279
    double counterD;
3280
} ma_timer;
3281
 
3282
typedef union
3283
{
3284
    ma_wchar_win32 wasapi[64];      /* WASAPI uses a wchar_t string for identification. */
3285
    ma_uint8 dsound[16];            /* DirectSound uses a GUID for identification. */
3286
    /*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. */
3287
    char alsa[256];                 /* ALSA uses a name string for identification. */
3288
    char pulse[256];                /* PulseAudio uses a name string for identification. */
3289
    int jack;                       /* JACK always uses default devices. */
3290
    char coreaudio[256];            /* Core Audio uses a string for identification. */
3291
    char sndio[256];                /* "snd/0", etc. */
3292
    char audio4[256];               /* "/dev/audio", etc. */
3293
    char oss[64];                   /* "dev/dsp0", etc. "dev/dsp" for the default device. */
3294
    ma_int32 aaudio;                /* AAudio uses a 32-bit integer for identification. */
3295
    ma_uint32 opensl;               /* OpenSL|ES uses a 32-bit unsigned integer for identification. */
3296
    char webaudio[32];              /* Web Audio always uses default devices for now, but if this changes it'll be a GUID. */
3297
    union
3298
    {
3299
        int i;
3300
        char s[256];
3301
        void* p;
3302
    } custom;                       /* The custom backend could be anything. Give them a few options. */
3303
    int nullbackend;                /* The null backend uses an integer for device IDs. */
3304
} ma_device_id;
3305
 
3306
 
3307
typedef struct ma_context_config    ma_context_config;
3308
typedef struct ma_device_config     ma_device_config;
3309
typedef struct ma_backend_callbacks ma_backend_callbacks;
3310
 
3311
#define MA_DATA_FORMAT_FLAG_EXCLUSIVE_MODE (1U << 1)    /* If set, this is supported in exclusive mode. Otherwise not natively supported by exclusive mode. */
3312
 
3313
#ifndef MA_MAX_DEVICE_NAME_LENGTH
3314
#define MA_MAX_DEVICE_NAME_LENGTH   255
3315
#endif
3316
 
3317
typedef struct
3318
{
3319
    /* Basic info. This is the only information guaranteed to be filled in during device enumeration. */
3320
    ma_device_id id;
3321
    char name[MA_MAX_DEVICE_NAME_LENGTH + 1];   /* +1 for null terminator. */
3322
    ma_bool32 isDefault;
3323
 
3324
    ma_uint32 nativeDataFormatCount;
3325
    struct
3326
    {
3327
        ma_format format;       /* Sample format. If set to ma_format_unknown, all sample formats are supported. */
3328
        ma_uint32 channels;     /* If set to 0, all channels are supported. */
3329
        ma_uint32 sampleRate;   /* If set to 0, all sample rates are supported. */
3330
        ma_uint32 flags;        /* A combination of MA_DATA_FORMAT_FLAG_* flags. */
3331
    } 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. */
3332
} ma_device_info;
3333
 
3334
struct ma_device_config
3335
{
3336
    ma_device_type deviceType;
3337
    ma_uint32 sampleRate;
3338
    ma_uint32 periodSizeInFrames;
3339
    ma_uint32 periodSizeInMilliseconds;
3340
    ma_uint32 periods;
3341
    ma_performance_profile performanceProfile;
3342
    ma_bool8 noPreSilencedOutputBuffer; /* When set to true, the contents of the output buffer passed into the data callback will be left undefined rather than initialized to silence. */
3343
    ma_bool8 noClip;                    /* When set to true, the contents of the output buffer passed into the data callback will not be clipped after returning. Only applies when the playback sample format is f32. */
3344
    ma_bool8 noDisableDenormals;        /* Do not disable denormals when firing the data callback. */
3345
    ma_bool8 noFixedSizedCallback;      /* Disables strict fixed-sized data callbacks. Setting this to true will result in the period size being treated only as a hint to the backend. This is an optimization for those who don't need fixed sized callbacks. */
3346
    ma_device_data_proc dataCallback;
3347
    ma_device_notification_proc notificationCallback;
3348
    ma_stop_proc stopCallback;
3349
    void* pUserData;
3350
    ma_resampler_config resampling;
3351
    struct
3352
    {
3353
        const ma_device_id* pDeviceID;
3354
        ma_format format;
3355
        ma_uint32 channels;
3356
        ma_channel* pChannelMap;
3357
        ma_channel_mix_mode channelMixMode;
3358
        ma_bool32 calculateLFEFromSpatialChannels;  /* When an output LFE channel is present, but no input LFE, set to true to set the output LFE to the average of all spatial channels (LR, FR, etc.). Ignored when an input LFE is present. */
3359
        ma_share_mode shareMode;
3360
    } playback;
3361
    struct
3362
    {
3363
        const ma_device_id* pDeviceID;
3364
        ma_format format;
3365
        ma_uint32 channels;
3366
        ma_channel* pChannelMap;
3367
        ma_channel_mix_mode channelMixMode;
3368
        ma_bool32 calculateLFEFromSpatialChannels;  /* When an output LFE channel is present, but no input LFE, set to true to set the output LFE to the average of all spatial channels (LR, FR, etc.). Ignored when an input LFE is present. */
3369
        ma_share_mode shareMode;
3370
    } capture;
3371
 
3372
    struct
3373
    {
3374
        ma_wasapi_usage usage;              /* When configured, uses Avrt APIs to set the thread characteristics. */
3375
        ma_bool8 noAutoConvertSRC;          /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
3376
        ma_bool8 noDefaultQualitySRC;       /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */
3377
        ma_bool8 noAutoStreamRouting;       /* Disables automatic stream routing. */
3378
        ma_bool8 noHardwareOffloading;      /* Disables WASAPI's hardware offloading feature. */
3379
        ma_uint32 loopbackProcessID;        /* The process ID to include or exclude for loopback mode. Set to 0 to capture audio from all processes. Ignored when an explicit device ID is specified. */
3380
        ma_bool8 loopbackProcessExclude;    /* When set to true, excludes the process specified by loopbackProcessID. By default, the process will be included. */
3381
    } wasapi;
3382
    struct
3383
    {
3384
        ma_bool32 noMMap;           /* Disables MMap mode. */
3385
        ma_bool32 noAutoFormat;     /* Opens the ALSA device with SND_PCM_NO_AUTO_FORMAT. */
3386
        ma_bool32 noAutoChannels;   /* Opens the ALSA device with SND_PCM_NO_AUTO_CHANNELS. */
3387
        ma_bool32 noAutoResample;   /* Opens the ALSA device with SND_PCM_NO_AUTO_RESAMPLE. */
3388
    } alsa;
3389
    struct
3390
    {
3391
        const char* pStreamNamePlayback;
3392
        const char* pStreamNameCapture;
3393
    } pulse;
3394
    struct
3395
    {
3396
        ma_bool32 allowNominalSampleRateChange; /* Desktop only. When enabled, allows changing of the sample rate at the operating system level. */
3397
    } coreaudio;
3398
    struct
3399
    {
3400
        ma_opensl_stream_type streamType;
3401
        ma_opensl_recording_preset recordingPreset;
3402
        ma_bool32 enableCompatibilityWorkarounds;
3403
    } opensl;
3404
    struct
3405
    {
3406
        ma_aaudio_usage usage;
3407
        ma_aaudio_content_type contentType;
3408
        ma_aaudio_input_preset inputPreset;
3409
        ma_aaudio_allowed_capture_policy allowedCapturePolicy;
3410
        ma_bool32 noAutoStartAfterReroute;
3411
        ma_bool32 enableCompatibilityWorkarounds;
3412
    } aaudio;
3413
};
3414
 
3415
 
3416
/*
3417
The callback for handling device enumeration. This is fired from `ma_context_enumerate_devices()`.
3418
 
3419
 
3420
Parameters
3421
----------
3422
pContext (in)
3423
    A pointer to the context performing the enumeration.
3424
 
3425
deviceType (in)
3426
    The type of the device being enumerated. This will always be either `ma_device_type_playback` or `ma_device_type_capture`.
3427
 
3428
pInfo (in)
3429
    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,
3430
    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
3431
    is too inefficient.
3432
 
3433
pUserData (in)
3434
    The user data pointer passed into `ma_context_enumerate_devices()`.
3435
*/
3436
typedef ma_bool32 (* ma_enum_devices_callback_proc)(ma_context* pContext, ma_device_type deviceType, const ma_device_info* pInfo, void* pUserData);
3437
 
3438
 
3439
/*
3440
Describes some basic details about a playback or capture device.
3441
*/
3442
typedef struct
3443
{
3444
    const ma_device_id* pDeviceID;
3445
    ma_share_mode shareMode;
3446
    ma_format format;
3447
    ma_uint32 channels;
3448
    ma_uint32 sampleRate;
3449
    ma_channel channelMap[MA_MAX_CHANNELS];
3450
    ma_uint32 periodSizeInFrames;
3451
    ma_uint32 periodSizeInMilliseconds;
3452
    ma_uint32 periodCount;
3453
} ma_device_descriptor;
3454
 
3455
/*
3456
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
3457
to many devices. A device is created from a context.
3458
 
3459
The general flow goes like this:
3460
 
3461
  1) A context is created with `onContextInit()`
3462
     1a) Available devices can be enumerated with `onContextEnumerateDevices()` if required.
3463
     1b) Detailed information about a device can be queried with `onContextGetDeviceInfo()` if required.
3464
  2) A device is created from the context that was created in the first step using `onDeviceInit()`, and optionally a device ID that was
3465
     selected from device enumeration via `onContextEnumerateDevices()`.
3466
  3) A device is started or stopped with `onDeviceStart()` / `onDeviceStop()`
3467
  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
3468
     to `onDeviceInit()`. Conversion between the device's native format and the format requested by the application will be handled by
3469
     miniaudio internally.
3470
 
3471
Initialization of the context is quite simple. You need to do any necessary initialization of internal objects and then output the
3472
callbacks defined in this structure.
3473
 
3474
Once the context has been initialized you can initialize a device. Before doing so, however, the application may want to know which
3475
physical devices are available. This is where `onContextEnumerateDevices()` comes in. This is fairly simple. For each device, fire the
3476
given callback with, at a minimum, the basic information filled out in `ma_device_info`. When the callback returns `MA_FALSE`, enumeration
3477
needs to stop and the `onContextEnumerateDevices()` function returns with a success code.
3478
 
3479
Detailed device information can be retrieved from a device ID using `onContextGetDeviceInfo()`. This takes as input the device type and ID,
3480
and on output returns detailed information about the device in `ma_device_info`. The `onContextGetDeviceInfo()` callback must handle the
3481
case when the device ID is NULL, in which case information about the default device needs to be retrieved.
3482
 
3483
Once the context has been created and the device ID retrieved (if using anything other than the default device), the device can be created.
3484
This is a little bit more complicated than initialization of the context due to it's more complicated configuration. When initializing a
3485
device, a duplex device may be requested. This means a separate data format needs to be specified for both playback and capture. On input,
3486
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
3487
the requested format. The conversion between the format requested by the application and the device's native format will be handled
3488
internally by miniaudio.
3489
 
3490
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
3491
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
3492
sample rate. For the channel map, the default should be used when `ma_channel_map_is_blank()` returns true (all channels set to
3493
`MA_CHANNEL_NONE`). On input, the `periodSizeInFrames` or `periodSizeInMilliseconds` option should always be set. The backend should
3494
inspect both of these variables. If `periodSizeInFrames` is set, it should take priority, otherwise it needs to be derived from the period
3495
size in milliseconds (`periodSizeInMilliseconds`) and the sample rate, keeping in mind that the sample rate may be 0, in which case the
3496
sample rate will need to be determined before calculating the period size in frames. On output, all members of the `ma_device_descriptor`
3497
object should be set to a valid value, except for `periodSizeInMilliseconds` which is optional (`periodSizeInFrames` *must* be set).
3498
 
3499
Starting and stopping of the device is done with `onDeviceStart()` and `onDeviceStop()` and should be self-explanatory. If the backend uses
3500
asynchronous reading and writing, `onDeviceStart()` and `onDeviceStop()` should always be implemented.
3501
 
3502
The handling of data delivery between the application and the device is the most complicated part of the process. To make this a bit
3503
easier, some helper callbacks are available. If the backend uses a blocking read/write style of API, the `onDeviceRead()` and
3504
`onDeviceWrite()` callbacks can optionally be implemented. These are blocking and work just like reading and writing from a file. If the
3505
backend uses a callback for data delivery, that callback must call `ma_device_handle_backend_data_callback()` from within it's callback.
3506
This allows miniaudio to then process any necessary data conversion and then pass it to the miniaudio data callback.
3507
 
3508
If the backend requires absolute flexibility with it's data delivery, it can optionally implement the `onDeviceDataLoop()` callback
3509
which will allow it to implement the logic that will run on the audio thread. This is much more advanced and is completely optional.
3510
 
3511
The audio thread should run data delivery logic in a loop while `ma_device_get_state() == ma_device_state_started` and no errors have been
3512
encountered. Do not start or stop the device here. That will be handled from outside the `onDeviceDataLoop()` callback.
3513
 
3514
The invocation of the `onDeviceDataLoop()` callback will be handled by miniaudio. When you start the device, miniaudio will fire this
3515
callback. When the device is stopped, the `ma_device_get_state() == ma_device_state_started` condition will fail and the loop will be terminated
3516
which will then fall through to the part that stops the device. For an example on how to implement the `onDeviceDataLoop()` callback,
3517
look at `ma_device_audio_thread__default_read_write()`. Implement the `onDeviceDataLoopWakeup()` callback if you need a mechanism to
3518
wake up the audio thread.
3519
 
3520
If the backend supports an optimized retrieval of device information from an initialized `ma_device` object, it should implement the
3521
`onDeviceGetInfo()` callback. This is optional, in which case it will fall back to `onContextGetDeviceInfo()` which is less efficient.
3522
*/
3523
struct ma_backend_callbacks
3524
{
3525
    ma_result (* onContextInit)(ma_context* pContext, const ma_context_config* pConfig, ma_backend_callbacks* pCallbacks);
3526
    ma_result (* onContextUninit)(ma_context* pContext);
3527
    ma_result (* onContextEnumerateDevices)(ma_context* pContext, ma_enum_devices_callback_proc callback, void* pUserData);
3528
    ma_result (* onContextGetDeviceInfo)(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_device_info* pDeviceInfo);
3529
    ma_result (* onDeviceInit)(ma_device* pDevice, const ma_device_config* pConfig, ma_device_descriptor* pDescriptorPlayback, ma_device_descriptor* pDescriptorCapture);
3530
    ma_result (* onDeviceUninit)(ma_device* pDevice);
3531
    ma_result (* onDeviceStart)(ma_device* pDevice);
3532
    ma_result (* onDeviceStop)(ma_device* pDevice);
3533
    ma_result (* onDeviceRead)(ma_device* pDevice, void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesRead);
3534
    ma_result (* onDeviceWrite)(ma_device* pDevice, const void* pFrames, ma_uint32 frameCount, ma_uint32* pFramesWritten);
3535
    ma_result (* onDeviceDataLoop)(ma_device* pDevice);
3536
    ma_result (* onDeviceDataLoopWakeup)(ma_device* pDevice);
3537
    ma_result (* onDeviceGetInfo)(ma_device* pDevice, ma_device_type type, ma_device_info* pDeviceInfo);
3538
};
3539
 
3540
struct ma_context_config
3541
{
3542
    ma_log* pLog;
3543
    ma_thread_priority threadPriority;
3544
    size_t threadStackSize;
3545
    void* pUserData;
3546
    ma_allocation_callbacks allocationCallbacks;
3547
    struct
3548
    {
3549
        ma_bool32 useVerboseDeviceEnumeration;
3550
    } alsa;
3551
    struct
3552
    {
3553
        const char* pApplicationName;
3554
        const char* pServerName;
3555
        ma_bool32 tryAutoSpawn; /* Enables autospawning of the PulseAudio daemon if necessary. */
3556
    } pulse;
3557
    struct
3558
    {
3559
        ma_ios_session_category sessionCategory;
3560
        ma_uint32 sessionCategoryOptions;
3561
        ma_bool32 noAudioSessionActivate;   /* iOS only. When set to true, does not perform an explicit [[AVAudioSession sharedInstace] setActive:true] on initialization. */
3562
        ma_bool32 noAudioSessionDeactivate; /* iOS only. When set to true, does not perform an explicit [[AVAudioSession sharedInstace] setActive:false] on uninitialization. */
3563
    } coreaudio;
3564
    struct
3565
    {
3566
        const char* pClientName;
3567
        ma_bool32 tryStartServer;
3568
    } jack;
3569
    ma_backend_callbacks custom;
3570
};
3571
 
3572
/* WASAPI specific structure for some commands which must run on a common thread due to bugs in WASAPI. */
3573
typedef struct
3574
{
3575
    int code;
3576
    ma_event* pEvent;   /* This will be signalled when the event is complete. */
3577
    union
3578
    {
3579
        struct
3580
        {
3581
            int _unused;
3582
        } quit;
3583
        struct
3584
        {
3585
            ma_device_type deviceType;
3586
            void* pAudioClient;
3587
            void** ppAudioClientService;
3588
            ma_result* pResult; /* The result from creating the audio client service. */
3589
        } createAudioClient;
3590
        struct
3591
        {
3592
            ma_device* pDevice;
3593
            ma_device_type deviceType;
3594
        } releaseAudioClient;
3595
    } data;
3596
} ma_context_command__wasapi;
3597
 
3598
struct ma_context
3599
{
3600
    ma_backend_callbacks callbacks;
3601
    ma_backend backend;                 /* DirectSound, ALSA, etc. */
3602
    ma_log* pLog;
3603
    ma_log log; /* Only used if the log is owned by the context. The pLog member will be set to &log in this case. */
3604
    ma_thread_priority threadPriority;
3605
    size_t threadStackSize;
3606
    void* pUserData;
3607
    ma_allocation_callbacks allocationCallbacks;
3608
    ma_mutex deviceEnumLock;            /* Used to make ma_context_get_devices() thread safe. */
3609
    ma_mutex deviceInfoLock;            /* Used to make ma_context_get_device_info() thread safe. */
3610
    ma_uint32 deviceInfoCapacity;       /* Total capacity of pDeviceInfos. */
3611
    ma_uint32 playbackDeviceInfoCount;
3612
    ma_uint32 captureDeviceInfoCount;
3613
    ma_device_info* pDeviceInfos;       /* Playback devices first, then capture. */
3614
 
3615
    union
3616
    {
3617
#ifdef MA_SUPPORT_WASAPI
3618
        struct
3619
        {
3620
            ma_thread commandThread;
3621
            ma_mutex commandLock;
3622
            ma_semaphore commandSem;
3623
            ma_uint32 commandIndex;
3624
            ma_uint32 commandCount;
3625
            ma_context_command__wasapi commands[4];
3626
            ma_handle hAvrt;
3627
            ma_proc AvSetMmThreadCharacteristicsA;
3628
            ma_proc AvRevertMmThreadcharacteristics;
3629
            ma_handle hMMDevapi;
3630
            ma_proc ActivateAudioInterfaceAsync;
3631
        } wasapi;
3632
#endif
3633
#ifdef MA_SUPPORT_DSOUND
3634
        struct
3635
        {
3636
            ma_handle hDSoundDLL;
3637
            ma_proc DirectSoundCreate;
3638
            ma_proc DirectSoundEnumerateA;
3639
            ma_proc DirectSoundCaptureCreate;
3640
            ma_proc DirectSoundCaptureEnumerateA;
3641
        } dsound;
3642
#endif
3643
#ifdef MA_SUPPORT_WINMM
3644
        struct
3645
        {
3646
            ma_handle hWinMM;
3647
            ma_proc waveOutGetNumDevs;
3648
            ma_proc waveOutGetDevCapsA;
3649
            ma_proc waveOutOpen;
3650
            ma_proc waveOutClose;
3651
            ma_proc waveOutPrepareHeader;
3652
            ma_proc waveOutUnprepareHeader;
3653
            ma_proc waveOutWrite;
3654
            ma_proc waveOutReset;
3655
            ma_proc waveInGetNumDevs;
3656
            ma_proc waveInGetDevCapsA;
3657
            ma_proc waveInOpen;
3658
            ma_proc waveInClose;
3659
            ma_proc waveInPrepareHeader;
3660
            ma_proc waveInUnprepareHeader;
3661
            ma_proc waveInAddBuffer;
3662
            ma_proc waveInStart;
3663
            ma_proc waveInReset;
3664
        } winmm;
3665
#endif
3666
#ifdef MA_SUPPORT_ALSA
3667
        struct
3668
        {
3669
            ma_handle asoundSO;
3670
            ma_proc snd_pcm_open;
3671
            ma_proc snd_pcm_close;
3672
            ma_proc snd_pcm_hw_params_sizeof;
3673
            ma_proc snd_pcm_hw_params_any;
3674
            ma_proc snd_pcm_hw_params_set_format;
3675
            ma_proc snd_pcm_hw_params_set_format_first;
3676
            ma_proc snd_pcm_hw_params_get_format_mask;
3677
            ma_proc snd_pcm_hw_params_set_channels;
3678
            ma_proc snd_pcm_hw_params_set_channels_near;
3679
            ma_proc snd_pcm_hw_params_set_channels_minmax;
3680
            ma_proc snd_pcm_hw_params_set_rate_resample;
3681
            ma_proc snd_pcm_hw_params_set_rate;
3682
            ma_proc snd_pcm_hw_params_set_rate_near;
3683
            ma_proc snd_pcm_hw_params_set_buffer_size_near;
3684
            ma_proc snd_pcm_hw_params_set_periods_near;
3685
            ma_proc snd_pcm_hw_params_set_access;
3686
            ma_proc snd_pcm_hw_params_get_format;
3687
            ma_proc snd_pcm_hw_params_get_channels;
3688
            ma_proc snd_pcm_hw_params_get_channels_min;
3689
            ma_proc snd_pcm_hw_params_get_channels_max;
3690
            ma_proc snd_pcm_hw_params_get_rate;
3691
            ma_proc snd_pcm_hw_params_get_rate_min;
3692
            ma_proc snd_pcm_hw_params_get_rate_max;
3693
            ma_proc snd_pcm_hw_params_get_buffer_size;
3694
            ma_proc snd_pcm_hw_params_get_periods;
3695
            ma_proc snd_pcm_hw_params_get_access;
3696
            ma_proc snd_pcm_hw_params_test_format;
3697
            ma_proc snd_pcm_hw_params_test_channels;
3698
            ma_proc snd_pcm_hw_params_test_rate;
3699
            ma_proc snd_pcm_hw_params;
3700
            ma_proc snd_pcm_sw_params_sizeof;
3701
            ma_proc snd_pcm_sw_params_current;
3702
            ma_proc snd_pcm_sw_params_get_boundary;
3703
            ma_proc snd_pcm_sw_params_set_avail_min;
3704
            ma_proc snd_pcm_sw_params_set_start_threshold;
3705
            ma_proc snd_pcm_sw_params_set_stop_threshold;
3706
            ma_proc snd_pcm_sw_params;
3707
            ma_proc snd_pcm_format_mask_sizeof;
3708
            ma_proc snd_pcm_format_mask_test;
3709
            ma_proc snd_pcm_get_chmap;
3710
            ma_proc snd_pcm_state;
3711
            ma_proc snd_pcm_prepare;
3712
            ma_proc snd_pcm_start;
3713
            ma_proc snd_pcm_drop;
3714
            ma_proc snd_pcm_drain;
3715
            ma_proc snd_pcm_reset;
3716
            ma_proc snd_device_name_hint;
3717
            ma_proc snd_device_name_get_hint;
3718
            ma_proc snd_card_get_index;
3719
            ma_proc snd_device_name_free_hint;
3720
            ma_proc snd_pcm_mmap_begin;
3721
            ma_proc snd_pcm_mmap_commit;
3722
            ma_proc snd_pcm_recover;
3723
            ma_proc snd_pcm_readi;
3724
            ma_proc snd_pcm_writei;
3725
            ma_proc snd_pcm_avail;
3726
            ma_proc snd_pcm_avail_update;
3727
            ma_proc snd_pcm_wait;
3728
            ma_proc snd_pcm_nonblock;
3729
            ma_proc snd_pcm_info;
3730
            ma_proc snd_pcm_info_sizeof;
3731
            ma_proc snd_pcm_info_get_name;
3732
            ma_proc snd_pcm_poll_descriptors;
3733
            ma_proc snd_pcm_poll_descriptors_count;
3734
            ma_proc snd_pcm_poll_descriptors_revents;
3735
            ma_proc snd_config_update_free_global;
3736
 
3737
            ma_mutex internalDeviceEnumLock;
3738
            ma_bool32 useVerboseDeviceEnumeration;
3739
        } alsa;
3740
#endif
3741
#ifdef MA_SUPPORT_PULSEAUDIO
3742
        struct
3743
        {
3744
            ma_handle pulseSO;
3745
            ma_proc pa_mainloop_new;
3746
            ma_proc pa_mainloop_free;
3747
            ma_proc pa_mainloop_quit;
3748
            ma_proc pa_mainloop_get_api;
3749
            ma_proc pa_mainloop_iterate;
3750
            ma_proc pa_mainloop_wakeup;
3751
            ma_proc pa_threaded_mainloop_new;
3752
            ma_proc pa_threaded_mainloop_free;
3753
            ma_proc pa_threaded_mainloop_start;
3754
            ma_proc pa_threaded_mainloop_stop;
3755
            ma_proc pa_threaded_mainloop_lock;
3756
            ma_proc pa_threaded_mainloop_unlock;
3757
            ma_proc pa_threaded_mainloop_wait;
3758
            ma_proc pa_threaded_mainloop_signal;
3759
            ma_proc pa_threaded_mainloop_accept;
3760
            ma_proc pa_threaded_mainloop_get_retval;
3761
            ma_proc pa_threaded_mainloop_get_api;
3762
            ma_proc pa_threaded_mainloop_in_thread;
3763
            ma_proc pa_threaded_mainloop_set_name;
3764
            ma_proc pa_context_new;
3765
            ma_proc pa_context_unref;
3766
            ma_proc pa_context_connect;
3767
            ma_proc pa_context_disconnect;
3768
            ma_proc pa_context_set_state_callback;
3769
            ma_proc pa_context_get_state;
3770
            ma_proc pa_context_get_sink_info_list;
3771
            ma_proc pa_context_get_source_info_list;
3772
            ma_proc pa_context_get_sink_info_by_name;
3773
            ma_proc pa_context_get_source_info_by_name;
3774
            ma_proc pa_operation_unref;
3775
            ma_proc pa_operation_get_state;
3776
            ma_proc pa_channel_map_init_extend;
3777
            ma_proc pa_channel_map_valid;
3778
            ma_proc pa_channel_map_compatible;
3779
            ma_proc pa_stream_new;
3780
            ma_proc pa_stream_unref;
3781
            ma_proc pa_stream_connect_playback;
3782
            ma_proc pa_stream_connect_record;
3783
            ma_proc pa_stream_disconnect;
3784
            ma_proc pa_stream_get_state;
3785
            ma_proc pa_stream_get_sample_spec;
3786
            ma_proc pa_stream_get_channel_map;
3787
            ma_proc pa_stream_get_buffer_attr;
3788
            ma_proc pa_stream_set_buffer_attr;
3789
            ma_proc pa_stream_get_device_name;
3790
            ma_proc pa_stream_set_write_callback;
3791
            ma_proc pa_stream_set_read_callback;
3792
            ma_proc pa_stream_set_suspended_callback;
3793
            ma_proc pa_stream_set_moved_callback;
3794
            ma_proc pa_stream_is_suspended;
3795
            ma_proc pa_stream_flush;
3796
            ma_proc pa_stream_drain;
3797
            ma_proc pa_stream_is_corked;
3798
            ma_proc pa_stream_cork;
3799
            ma_proc pa_stream_trigger;
3800
            ma_proc pa_stream_begin_write;
3801
            ma_proc pa_stream_write;
3802
            ma_proc pa_stream_peek;
3803
            ma_proc pa_stream_drop;
3804
            ma_proc pa_stream_writable_size;
3805
            ma_proc pa_stream_readable_size;
3806
 
3807
            /*pa_mainloop**/ ma_ptr pMainLoop;
3808
            /*pa_context**/ ma_ptr pPulseContext;
3809
            char* pApplicationName; /* Set when the context is initialized. Used by devices for their local pa_context objects. */
3810
            char* pServerName;      /* Set when the context is initialized. Used by devices for their local pa_context objects. */
3811
        } pulse;
3812
#endif
3813
#ifdef MA_SUPPORT_JACK
3814
        struct
3815
        {
3816
            ma_handle jackSO;
3817
            ma_proc jack_client_open;
3818
            ma_proc jack_client_close;
3819
            ma_proc jack_client_name_size;
3820
            ma_proc jack_set_process_callback;
3821
            ma_proc jack_set_buffer_size_callback;
3822
            ma_proc jack_on_shutdown;
3823
            ma_proc jack_get_sample_rate;
3824
            ma_proc jack_get_buffer_size;
3825
            ma_proc jack_get_ports;
3826
            ma_proc jack_activate;
3827
            ma_proc jack_deactivate;
3828
            ma_proc jack_connect;
3829
            ma_proc jack_port_register;
3830
            ma_proc jack_port_name;
3831
            ma_proc jack_port_get_buffer;
3832
            ma_proc jack_free;
3833
 
3834
            char* pClientName;
3835
            ma_bool32 tryStartServer;
3836
        } jack;
3837
#endif
3838
#ifdef MA_SUPPORT_COREAUDIO
3839
        struct
3840
        {
3841
            ma_handle hCoreFoundation;
3842
            ma_proc CFStringGetCString;
3843
            ma_proc CFRelease;
3844
 
3845
            ma_handle hCoreAudio;
3846
            ma_proc AudioObjectGetPropertyData;
3847
            ma_proc AudioObjectGetPropertyDataSize;
3848
            ma_proc AudioObjectSetPropertyData;
3849
            ma_proc AudioObjectAddPropertyListener;
3850
            ma_proc AudioObjectRemovePropertyListener;
3851
 
3852
            ma_handle hAudioUnit;  /* Could possibly be set to AudioToolbox on later versions of macOS. */
3853
            ma_proc AudioComponentFindNext;
3854
            ma_proc AudioComponentInstanceDispose;
3855
            ma_proc AudioComponentInstanceNew;
3856
            ma_proc AudioOutputUnitStart;
3857
            ma_proc AudioOutputUnitStop;
3858
            ma_proc AudioUnitAddPropertyListener;
3859
            ma_proc AudioUnitGetPropertyInfo;
3860
            ma_proc AudioUnitGetProperty;
3861
            ma_proc AudioUnitSetProperty;
3862
            ma_proc AudioUnitInitialize;
3863
            ma_proc AudioUnitRender;
3864
 
3865
            /*AudioComponent*/ ma_ptr component;
3866
            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(). */
3867
        } coreaudio;
3868
#endif
3869
#ifdef MA_SUPPORT_SNDIO
3870
        struct
3871
        {
3872
            ma_handle sndioSO;
3873
            ma_proc sio_open;
3874
            ma_proc sio_close;
3875
            ma_proc sio_setpar;
3876
            ma_proc sio_getpar;
3877
            ma_proc sio_getcap;
3878
            ma_proc sio_start;
3879
            ma_proc sio_stop;
3880
            ma_proc sio_read;
3881
            ma_proc sio_write;
3882
            ma_proc sio_onmove;
3883
            ma_proc sio_nfds;
3884
            ma_proc sio_pollfd;
3885
            ma_proc sio_revents;
3886
            ma_proc sio_eof;
3887
            ma_proc sio_setvol;
3888
            ma_proc sio_onvol;
3889
            ma_proc sio_initpar;
3890
        } sndio;
3891
#endif
3892
#ifdef MA_SUPPORT_AUDIO4
3893
        struct
3894
        {
3895
            int _unused;
3896
        } audio4;
3897
#endif
3898
#ifdef MA_SUPPORT_OSS
3899
        struct
3900
        {
3901
            int versionMajor;
3902
            int versionMinor;
3903
        } oss;
3904
#endif
3905
#ifdef MA_SUPPORT_AAUDIO
3906
        struct
3907
        {
3908
            ma_handle hAAudio; /* libaaudio.so */
3909
            ma_proc AAudio_createStreamBuilder;
3910
            ma_proc AAudioStreamBuilder_delete;
3911
            ma_proc AAudioStreamBuilder_setDeviceId;
3912
            ma_proc AAudioStreamBuilder_setDirection;
3913
            ma_proc AAudioStreamBuilder_setSharingMode;
3914
            ma_proc AAudioStreamBuilder_setFormat;
3915
            ma_proc AAudioStreamBuilder_setChannelCount;
3916
            ma_proc AAudioStreamBuilder_setSampleRate;
3917
            ma_proc AAudioStreamBuilder_setBufferCapacityInFrames;
3918
            ma_proc AAudioStreamBuilder_setFramesPerDataCallback;
3919
            ma_proc AAudioStreamBuilder_setDataCallback;
3920
            ma_proc AAudioStreamBuilder_setErrorCallback;
3921
            ma_proc AAudioStreamBuilder_setPerformanceMode;
3922
            ma_proc AAudioStreamBuilder_setUsage;
3923
            ma_proc AAudioStreamBuilder_setContentType;
3924
            ma_proc AAudioStreamBuilder_setInputPreset;
3925
            ma_proc AAudioStreamBuilder_setAllowedCapturePolicy;
3926
            ma_proc AAudioStreamBuilder_openStream;
3927
            ma_proc AAudioStream_close;
3928
            ma_proc AAudioStream_getState;
3929
            ma_proc AAudioStream_waitForStateChange;
3930
            ma_proc AAudioStream_getFormat;
3931
            ma_proc AAudioStream_getChannelCount;
3932
            ma_proc AAudioStream_getSampleRate;
3933
            ma_proc AAudioStream_getBufferCapacityInFrames;
3934
            ma_proc AAudioStream_getFramesPerDataCallback;
3935
            ma_proc AAudioStream_getFramesPerBurst;
3936
            ma_proc AAudioStream_requestStart;
3937
            ma_proc AAudioStream_requestStop;
3938
            ma_device_job_thread jobThread; /* For processing operations outside of the error callback, specifically device disconnections and rerouting. */
3939
        } aaudio;
3940
#endif
3941
#ifdef MA_SUPPORT_OPENSL
3942
        struct
3943
        {
3944
            ma_handle libOpenSLES;
3945
            ma_handle SL_IID_ENGINE;
3946
            ma_handle SL_IID_AUDIOIODEVICECAPABILITIES;
3947
            ma_handle SL_IID_ANDROIDSIMPLEBUFFERQUEUE;
3948
            ma_handle SL_IID_RECORD;
3949
            ma_handle SL_IID_PLAY;
3950
            ma_handle SL_IID_OUTPUTMIX;
3951
            ma_handle SL_IID_ANDROIDCONFIGURATION;
3952
            ma_proc   slCreateEngine;
3953
        } opensl;
3954
#endif
3955
#ifdef MA_SUPPORT_WEBAUDIO
3956
        struct
3957
        {
3958
            int _unused;
3959
        } webaudio;
3960
#endif
3961
#ifdef MA_SUPPORT_NULL
3962
        struct
3963
        {
3964
            int _unused;
3965
        } null_backend;
3966
#endif
3967
    };
3968
 
3969
    union
3970
    {
3971
#if defined(MA_WIN32)
3972
        struct
3973
        {
3974
            /*HMODULE*/ ma_handle hOle32DLL;
3975
            ma_proc CoInitialize;
3976
            ma_proc CoInitializeEx;
3977
            ma_proc CoUninitialize;
3978
            ma_proc CoCreateInstance;
3979
            ma_proc CoTaskMemFree;
3980
            ma_proc PropVariantClear;
3981
            ma_proc StringFromGUID2;
3982
 
3983
            /*HMODULE*/ ma_handle hUser32DLL;
3984
            ma_proc GetForegroundWindow;
3985
            ma_proc GetDesktopWindow;
3986
 
3987
            /*HMODULE*/ ma_handle hAdvapi32DLL;
3988
            ma_proc RegOpenKeyExA;
3989
            ma_proc RegCloseKey;
3990
            ma_proc RegQueryValueExA;
3991
 
3992
            /*HRESULT*/ long CoInitializeResult;
3993
        } win32;
3994
#endif
3995
#ifdef MA_POSIX
3996
        struct
3997
        {
3998
            int _unused;
3999
        } posix;
4000
#endif
4001
        int _unused;
4002
    };
4003
};
4004
 
4005
struct ma_device
4006
{
4007
    ma_context* pContext;
4008
    ma_device_type type;
4009
    ma_uint32 sampleRate;
4010
    ma_atomic_device_state state;               /* The state of the device is variable and can change at any time on any thread. Must be used atomically. */
4011
    ma_device_data_proc onData;                 /* Set once at initialization time and should not be changed after. */
4012
    ma_device_notification_proc onNotification; /* Set once at initialization time and should not be changed after. */
4013
    ma_stop_proc onStop;                        /* DEPRECATED. Use the notification callback instead. Set once at initialization time and should not be changed after. */
4014
    void* pUserData;                            /* Application defined data. */
4015
    ma_mutex startStopLock;
4016
    ma_event wakeupEvent;
4017
    ma_event startEvent;
4018
    ma_event stopEvent;
4019
    ma_thread thread;
4020
    ma_result workResult;                       /* This is set by the worker thread after it's finished doing a job. */
4021
    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(). */
4022
    ma_bool8 noPreSilencedOutputBuffer;
4023
    ma_bool8 noClip;
4024
    ma_bool8 noDisableDenormals;
4025
    ma_bool8 noFixedSizedCallback;
4026
    ma_atomic_float masterVolumeFactor;         /* Linear 0..1. Can be read and written simultaneously by different threads. Must be used atomically. */
4027
    ma_duplex_rb duplexRB;                      /* Intermediary buffer for duplex device on asynchronous backends. */
4028
    struct
4029
    {
4030
        ma_resample_algorithm algorithm;
4031
        ma_resampling_backend_vtable* pBackendVTable;
4032
        void* pBackendUserData;
4033
        struct
4034
        {
4035
            ma_uint32 lpfOrder;
4036
        } linear;
4037
    } resampling;
4038
    struct
4039
    {
4040
        ma_device_id* pID;                  /* Set to NULL if using default ID, otherwise set to the address of "id". */
4041
        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. */
4042
        char name[MA_MAX_DEVICE_NAME_LENGTH + 1];                     /* Maybe temporary. Likely to be replaced with a query API. */
4043
        ma_share_mode shareMode;            /* Set to whatever was passed in when the device was initialized. */
4044
        ma_format format;
4045
        ma_uint32 channels;
4046
        ma_channel channelMap[MA_MAX_CHANNELS];
4047
        ma_format internalFormat;
4048
        ma_uint32 internalChannels;
4049
        ma_uint32 internalSampleRate;
4050
        ma_channel internalChannelMap[MA_MAX_CHANNELS];
4051
        ma_uint32 internalPeriodSizeInFrames;
4052
        ma_uint32 internalPeriods;
4053
        ma_channel_mix_mode channelMixMode;
4054
        ma_bool32 calculateLFEFromSpatialChannels;
4055
        ma_data_converter converter;
4056
        void* pIntermediaryBuffer;          /* For implementing fixed sized buffer callbacks. Will be null if using variable sized callbacks. */
4057
        ma_uint32 intermediaryBufferCap;
4058
        ma_uint32 intermediaryBufferLen;    /* How many valid frames are sitting in the intermediary buffer. */
4059
        void* pInputCache;                  /* In external format. Can be null. */
4060
        ma_uint64 inputCacheCap;
4061
        ma_uint64 inputCacheConsumed;
4062
        ma_uint64 inputCacheRemaining;
4063
    } playback;
4064
    struct
4065
    {
4066
        ma_device_id* pID;                  /* Set to NULL if using default ID, otherwise set to the address of "id". */
4067
        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. */
4068
        char name[MA_MAX_DEVICE_NAME_LENGTH + 1];                     /* Maybe temporary. Likely to be replaced with a query API. */
4069
        ma_share_mode shareMode;            /* Set to whatever was passed in when the device was initialized. */
4070
        ma_format format;
4071
        ma_uint32 channels;
4072
        ma_channel channelMap[MA_MAX_CHANNELS];
4073
        ma_format internalFormat;
4074
        ma_uint32 internalChannels;
4075
        ma_uint32 internalSampleRate;
4076
        ma_channel internalChannelMap[MA_MAX_CHANNELS];
4077
        ma_uint32 internalPeriodSizeInFrames;
4078
        ma_uint32 internalPeriods;
4079
        ma_channel_mix_mode channelMixMode;
4080
        ma_bool32 calculateLFEFromSpatialChannels;
4081
        ma_data_converter converter;
4082
        void* pIntermediaryBuffer;          /* For implementing fixed sized buffer callbacks. Will be null if using variable sized callbacks. */
4083
        ma_uint32 intermediaryBufferCap;
4084
        ma_uint32 intermediaryBufferLen;    /* How many valid frames are sitting in the intermediary buffer. */
4085
    } capture;
4086
 
4087
    union
4088
    {
4089
#ifdef MA_SUPPORT_WASAPI
4090
        struct
4091
        {
4092
            /*IAudioClient**/ ma_ptr pAudioClientPlayback;
4093
            /*IAudioClient**/ ma_ptr pAudioClientCapture;
4094
            /*IAudioRenderClient**/ ma_ptr pRenderClient;
4095
            /*IAudioCaptureClient**/ ma_ptr pCaptureClient;
4096
            /*IMMDeviceEnumerator**/ ma_ptr pDeviceEnumerator;      /* Used for IMMNotificationClient notifications. Required for detecting default device changes. */
4097
            ma_IMMNotificationClient notificationClient;
4098
            /*HANDLE*/ ma_handle hEventPlayback;                    /* Auto reset. Initialized to signaled. */
4099
            /*HANDLE*/ ma_handle hEventCapture;                     /* Auto reset. Initialized to unsignaled. */
4100
            ma_uint32 actualBufferSizeInFramesPlayback;             /* 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. */
4101
            ma_uint32 actualBufferSizeInFramesCapture;
4102
            ma_uint32 originalPeriodSizeInFrames;
4103
            ma_uint32 originalPeriodSizeInMilliseconds;
4104
            ma_uint32 originalPeriods;
4105
            ma_performance_profile originalPerformanceProfile;
4106
            ma_uint32 periodSizeInFramesPlayback;
4107
            ma_uint32 periodSizeInFramesCapture;
4108
            void* pMappedBufferCapture;
4109
            ma_uint32 mappedBufferCaptureCap;
4110
            ma_uint32 mappedBufferCaptureLen;
4111
            void* pMappedBufferPlayback;
4112
            ma_uint32 mappedBufferPlaybackCap;
4113
            ma_uint32 mappedBufferPlaybackLen;
4114
            ma_atomic_bool32 isStartedCapture;                      /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
4115
            ma_atomic_bool32 isStartedPlayback;                     /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
4116
            ma_uint32 loopbackProcessID;
4117
            ma_bool8 loopbackProcessExclude;
4118
            ma_bool8 noAutoConvertSRC;                              /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
4119
            ma_bool8 noDefaultQualitySRC;                           /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */
4120
            ma_bool8 noHardwareOffloading;
4121
            ma_bool8 allowCaptureAutoStreamRouting;
4122
            ma_bool8 allowPlaybackAutoStreamRouting;
4123
            ma_bool8 isDetachedPlayback;
4124
            ma_bool8 isDetachedCapture;
4125
            ma_wasapi_usage usage;
4126
            void* hAvrtHandle;
4127
            ma_mutex rerouteLock;
4128
        } wasapi;
4129
#endif
4130
#ifdef MA_SUPPORT_DSOUND
4131
        struct
4132
        {
4133
            /*LPDIRECTSOUND*/ ma_ptr pPlayback;
4134
            /*LPDIRECTSOUNDBUFFER*/ ma_ptr pPlaybackPrimaryBuffer;
4135
            /*LPDIRECTSOUNDBUFFER*/ ma_ptr pPlaybackBuffer;
4136
            /*LPDIRECTSOUNDCAPTURE*/ ma_ptr pCapture;
4137
            /*LPDIRECTSOUNDCAPTUREBUFFER*/ ma_ptr pCaptureBuffer;
4138
        } dsound;
4139
#endif
4140
#ifdef MA_SUPPORT_WINMM
4141
        struct
4142
        {
4143
            /*HWAVEOUT*/ ma_handle hDevicePlayback;
4144
            /*HWAVEIN*/ ma_handle hDeviceCapture;
4145
            /*HANDLE*/ ma_handle hEventPlayback;
4146
            /*HANDLE*/ ma_handle hEventCapture;
4147
            ma_uint32 fragmentSizeInFrames;
4148
            ma_uint32 iNextHeaderPlayback;             /* [0,periods). Used as an index into pWAVEHDRPlayback. */
4149
            ma_uint32 iNextHeaderCapture;              /* [0,periods). Used as an index into pWAVEHDRCapture. */
4150
            ma_uint32 headerFramesConsumedPlayback;    /* The number of PCM frames consumed in the buffer in pWAVEHEADER[iNextHeader]. */
4151
            ma_uint32 headerFramesConsumedCapture;     /* ^^^ */
4152
            /*WAVEHDR**/ ma_uint8* pWAVEHDRPlayback;   /* One instantiation for each period. */
4153
            /*WAVEHDR**/ ma_uint8* pWAVEHDRCapture;    /* One instantiation for each period. */
4154
            ma_uint8* pIntermediaryBufferPlayback;
4155
            ma_uint8* pIntermediaryBufferCapture;
4156
            ma_uint8* _pHeapData;                      /* Used internally and is used for the heap allocated data for the intermediary buffer and the WAVEHDR structures. */
4157
        } winmm;
4158
#endif
4159
#ifdef MA_SUPPORT_ALSA
4160
        struct
4161
        {
4162
            /*snd_pcm_t**/ ma_ptr pPCMPlayback;
4163
            /*snd_pcm_t**/ ma_ptr pPCMCapture;
4164
            /*struct pollfd**/ void* pPollDescriptorsPlayback;
4165
            /*struct pollfd**/ void* pPollDescriptorsCapture;
4166
            int pollDescriptorCountPlayback;
4167
            int pollDescriptorCountCapture;
4168
            int wakeupfdPlayback;   /* eventfd for waking up from poll() when the playback device is stopped. */
4169
            int wakeupfdCapture;    /* eventfd for waking up from poll() when the capture device is stopped. */
4170
            ma_bool8 isUsingMMapPlayback;
4171
            ma_bool8 isUsingMMapCapture;
4172
        } alsa;
4173
#endif
4174
#ifdef MA_SUPPORT_PULSEAUDIO
4175
        struct
4176
        {
4177
            /*pa_mainloop**/ ma_ptr pMainLoop;
4178
            /*pa_context**/ ma_ptr pPulseContext;
4179
            /*pa_stream**/ ma_ptr pStreamPlayback;
4180
            /*pa_stream**/ ma_ptr pStreamCapture;
4181
        } pulse;
4182
#endif
4183
#ifdef MA_SUPPORT_JACK
4184
        struct
4185
        {
4186
            /*jack_client_t**/ ma_ptr pClient;
4187
            /*jack_port_t**/ ma_ptr* ppPortsPlayback;
4188
            /*jack_port_t**/ ma_ptr* ppPortsCapture;
4189
            float* pIntermediaryBufferPlayback; /* Typed as a float because JACK is always floating point. */
4190
            float* pIntermediaryBufferCapture;
4191
        } jack;
4192
#endif
4193
#ifdef MA_SUPPORT_COREAUDIO
4194
        struct
4195
        {
4196
            ma_uint32 deviceObjectIDPlayback;
4197
            ma_uint32 deviceObjectIDCapture;
4198
            /*AudioUnit*/ ma_ptr audioUnitPlayback;
4199
            /*AudioUnit*/ ma_ptr audioUnitCapture;
4200
            /*AudioBufferList**/ ma_ptr pAudioBufferList;   /* Only used for input devices. */
4201
            ma_uint32 audioBufferCapInFrames;               /* Only used for input devices. The capacity in frames of each buffer in pAudioBufferList. */
4202
            ma_event stopEvent;
4203
            ma_uint32 originalPeriodSizeInFrames;
4204
            ma_uint32 originalPeriodSizeInMilliseconds;
4205
            ma_uint32 originalPeriods;
4206
            ma_performance_profile originalPerformanceProfile;
4207
            ma_bool32 isDefaultPlaybackDevice;
4208
            ma_bool32 isDefaultCaptureDevice;
4209
            ma_bool32 isSwitchingPlaybackDevice;   /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
4210
            ma_bool32 isSwitchingCaptureDevice;    /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
4211
            void* pNotificationHandler;             /* Only used on mobile platforms. Obj-C object for handling route changes. */
4212
        } coreaudio;
4213
#endif
4214
#ifdef MA_SUPPORT_SNDIO
4215
        struct
4216
        {
4217
            ma_ptr handlePlayback;
4218
            ma_ptr handleCapture;
4219
            ma_bool32 isStartedPlayback;
4220
            ma_bool32 isStartedCapture;
4221
        } sndio;
4222
#endif
4223
#ifdef MA_SUPPORT_AUDIO4
4224
        struct
4225
        {
4226
            int fdPlayback;
4227
            int fdCapture;
4228
        } audio4;
4229
#endif
4230
#ifdef MA_SUPPORT_OSS
4231
        struct
4232
        {
4233
            int fdPlayback;
4234
            int fdCapture;
4235
        } oss;
4236
#endif
4237
#ifdef MA_SUPPORT_AAUDIO
4238
        struct
4239
        {
4240
            /*AAudioStream**/ ma_ptr pStreamPlayback;
4241
            /*AAudioStream**/ ma_ptr pStreamCapture;
4242
            ma_aaudio_usage usage;
4243
            ma_aaudio_content_type contentType;
4244
            ma_aaudio_input_preset inputPreset;
4245
            ma_aaudio_allowed_capture_policy allowedCapturePolicy;
4246
            ma_bool32 noAutoStartAfterReroute;
4247
        } aaudio;
4248
#endif
4249
#ifdef MA_SUPPORT_OPENSL
4250
        struct
4251
        {
4252
            /*SLObjectItf*/ ma_ptr pOutputMixObj;
4253
            /*SLOutputMixItf*/ ma_ptr pOutputMix;
4254
            /*SLObjectItf*/ ma_ptr pAudioPlayerObj;
4255
            /*SLPlayItf*/ ma_ptr pAudioPlayer;
4256
            /*SLObjectItf*/ ma_ptr pAudioRecorderObj;
4257
            /*SLRecordItf*/ ma_ptr pAudioRecorder;
4258
            /*SLAndroidSimpleBufferQueueItf*/ ma_ptr pBufferQueuePlayback;
4259
            /*SLAndroidSimpleBufferQueueItf*/ ma_ptr pBufferQueueCapture;
4260
            ma_bool32 isDrainingCapture;
4261
            ma_bool32 isDrainingPlayback;
4262
            ma_uint32 currentBufferIndexPlayback;
4263
            ma_uint32 currentBufferIndexCapture;
4264
            ma_uint8* pBufferPlayback;      /* This is malloc()'d and is used for storing audio data. Typed as ma_uint8 for easy offsetting. */
4265
            ma_uint8* pBufferCapture;
4266
        } opensl;
4267
#endif
4268
#ifdef MA_SUPPORT_WEBAUDIO
4269
        struct
4270
        {
4271
            /* AudioWorklets path. */
4272
            /* EMSCRIPTEN_WEBAUDIO_T */ int audioContext;
4273
            /* EMSCRIPTEN_WEBAUDIO_T */ int audioWorklet;
4274
            float* pIntermediaryBuffer;
4275
            void* pStackBuffer;
4276
            ma_result initResult;   /* Set to MA_BUSY while initialization is in progress. */
4277
            int deviceIndex;        /* We store the device in a list on the JavaScript side. This is used to map our C object to the JS object. */
4278
        } webaudio;
4279
#endif
4280
#ifdef MA_SUPPORT_NULL
4281
        struct
4282
        {
4283
            ma_thread deviceThread;
4284
            ma_event operationEvent;
4285
            ma_event operationCompletionEvent;
4286
            ma_semaphore operationSemaphore;
4287
            ma_uint32 operation;
4288
            ma_result operationResult;
4289
            ma_timer timer;
4290
            double priorRunTime;
4291
            ma_uint32 currentPeriodFramesRemainingPlayback;
4292
            ma_uint32 currentPeriodFramesRemainingCapture;
4293
            ma_uint64 lastProcessedFramePlayback;
4294
            ma_uint64 lastProcessedFrameCapture;
4295
            ma_atomic_bool32 isStarted; /* Read and written by multiple threads. Must be used atomically, and must be 32-bit for compiler compatibility. */
4296
        } null_device;
4297
#endif
4298
    };
4299
};
4300
#if defined(_MSC_VER) && !defined(__clang__)
4301
    #pragma warning(pop)
4302
#elif defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
4303
    #pragma GCC diagnostic pop  /* For ISO C99 doesn't support unnamed structs/unions [-Wpedantic] */
4304
#endif
4305
 
4306
/*
4307
Initializes a `ma_context_config` object.
4308
 
4309
 
4310
Return Value
4311
------------
4312
A `ma_context_config` initialized to defaults.
4313
 
4314
 
4315
Remarks
4316
-------
4317
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
4318
is updated and new members are added to `ma_context_config`. It also sets logical defaults.
4319
 
4320
You can override members of the returned object by changing it's members directly.
4321
 
4322
 
4323
See Also
4324
--------
4325
ma_context_init()
4326
*/
4327
MA_API ma_context_config ma_context_config_init(void);
4328
 
4329
/*
4330
Initializes a context.
4331
 
4332
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
4333
device. There is one context to many devices, and a device is created from a context. A context is required to enumerate devices.
4334
 
4335
 
4336
Parameters
4337
----------
4338
backends (in, optional)
4339
    A list of backends to try initializing, in priority order. Can be NULL, in which case it uses default priority order.
4340
 
4341
backendCount (in, optional)
4342
    The number of items in `backend`. Ignored if `backend` is NULL.
4343
 
4344
pConfig (in, optional)
4345
    The context configuration.
4346
 
4347
pContext (in)
4348
    A pointer to the context object being initialized.
4349
 
4350
 
4351
Return Value
4352
------------
4353
MA_SUCCESS if successful; any other error code otherwise.
4354
 
4355
 
4356
Thread Safety
4357
-------------
4358
Unsafe. Do not call this function across multiple threads as some backends read and write to global state.
4359
 
4360
 
4361
Remarks
4362
-------
4363
When `backends` is NULL, the default priority order will be used. Below is a list of backends in priority order:
4364
 
4365
    |-------------|-----------------------|--------------------------------------------------------|
4366
    | Name        | Enum Name             | Supported Operating Systems                            |
4367
    |-------------|-----------------------|--------------------------------------------------------|
4368
    | WASAPI      | ma_backend_wasapi     | Windows Vista+                                         |
4369
    | DirectSound | ma_backend_dsound     | Windows XP+                                            |
4370
    | WinMM       | ma_backend_winmm      | Windows XP+ (may work on older versions, but untested) |
4371
    | Core Audio  | ma_backend_coreaudio  | macOS, iOS                                             |
4372
    | ALSA        | ma_backend_alsa       | Linux                                                  |
4373
    | PulseAudio  | ma_backend_pulseaudio | Cross Platform (disabled on Windows, BSD and Android)  |
4374
    | JACK        | ma_backend_jack       | Cross Platform (disabled on BSD and Android)           |
4375
    | sndio       | ma_backend_sndio      | OpenBSD                                                |
4376
    | audio(4)    | ma_backend_audio4     | NetBSD, OpenBSD                                        |
4377
    | OSS         | ma_backend_oss        | FreeBSD                                                |
4378
    | AAudio      | ma_backend_aaudio     | Android 8+                                             |
4379
    | OpenSL|ES   | ma_backend_opensl     | Android (API level 16+)                                |
4380
    | Web Audio   | ma_backend_webaudio   | Web (via Emscripten)                                   |
4381
    | Null        | ma_backend_null       | Cross Platform (not used on Web)                       |
4382
    |-------------|-----------------------|--------------------------------------------------------|
4383
 
4384
The context can be configured via the `pConfig` argument. The config object is initialized with `ma_context_config_init()`. Individual configuration settings
4385
can then be set directly on the structure. Below are the members of the `ma_context_config` object.
4386
 
4387
    pLog
4388
        A pointer to the `ma_log` to post log messages to. Can be NULL if the application does not
4389
        require logging. See the `ma_log` API for details on how to use the logging system.
4390
 
4391
    threadPriority
4392
        The desired priority to use for the audio thread. Allowable values include the following:
4393
 
4394
        |--------------------------------------|
4395
        | Thread Priority                      |
4396
        |--------------------------------------|
4397
        | ma_thread_priority_idle              |
4398
        | ma_thread_priority_lowest            |
4399
        | ma_thread_priority_low               |
4400
        | ma_thread_priority_normal            |
4401
        | ma_thread_priority_high              |
4402
        | ma_thread_priority_highest (default) |
4403
        | ma_thread_priority_realtime          |
4404
        | ma_thread_priority_default           |
4405
        |--------------------------------------|
4406
 
4407
    threadStackSize
4408
        The desired size of the stack for the audio thread. Defaults to the operating system's default.
4409
 
4410
    pUserData
4411
        A pointer to application-defined data. This can be accessed from the context object directly such as `context.pUserData`.
4412
 
4413
    allocationCallbacks
4414
        Structure containing custom allocation callbacks. Leaving this at defaults will cause it to use MA_MALLOC, MA_REALLOC and MA_FREE. These allocation
4415
        callbacks will be used for anything tied to the context, including devices.
4416
 
4417
    alsa.useVerboseDeviceEnumeration
4418
        ALSA will typically enumerate many different devices which can be intrusive and not user-friendly. To combat this, miniaudio will enumerate only unique
4419
        card/device pairs by default. The problem with this is that you lose a bit of flexibility and control. Setting alsa.useVerboseDeviceEnumeration makes
4420
        it so the ALSA backend includes all devices. Defaults to false.
4421
 
4422
    pulse.pApplicationName
4423
        PulseAudio only. The application name to use when initializing the PulseAudio context with `pa_context_new()`.
4424
 
4425
    pulse.pServerName
4426
        PulseAudio only. The name of the server to connect to with `pa_context_connect()`.
4427
 
4428
    pulse.tryAutoSpawn
4429
        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
4430
        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
4431
        intrusive for the end user.
4432
 
4433
    coreaudio.sessionCategory
4434
        iOS only. The session category to use for the shared AudioSession instance. Below is a list of allowable values and their Core Audio equivalents.
4435
 
4436
        |-----------------------------------------|-------------------------------------|
4437
        | miniaudio Token                         | Core Audio Token                    |
4438
        |-----------------------------------------|-------------------------------------|
4439
        | ma_ios_session_category_ambient         | AVAudioSessionCategoryAmbient       |
4440
        | ma_ios_session_category_solo_ambient    | AVAudioSessionCategorySoloAmbient   |
4441
        | ma_ios_session_category_playback        | AVAudioSessionCategoryPlayback      |
4442
        | ma_ios_session_category_record          | AVAudioSessionCategoryRecord        |
4443
        | ma_ios_session_category_play_and_record | AVAudioSessionCategoryPlayAndRecord |
4444
        | ma_ios_session_category_multi_route     | AVAudioSessionCategoryMultiRoute    |
4445
        | ma_ios_session_category_none            | AVAudioSessionCategoryAmbient       |
4446
        | ma_ios_session_category_default         | AVAudioSessionCategoryAmbient       |
4447
        |-----------------------------------------|-------------------------------------|
4448
 
4449
    coreaudio.sessionCategoryOptions
4450
        iOS only. Session category options to use with the shared AudioSession instance. Below is a list of allowable values and their Core Audio equivalents.
4451
 
4452
        |---------------------------------------------------------------------------|------------------------------------------------------------------|
4453
        | miniaudio Token                                                           | Core Audio Token                                                 |
4454
        |---------------------------------------------------------------------------|------------------------------------------------------------------|
4455
        | ma_ios_session_category_option_mix_with_others                            | AVAudioSessionCategoryOptionMixWithOthers                        |
4456
        | ma_ios_session_category_option_duck_others                                | AVAudioSessionCategoryOptionDuckOthers                           |
4457
        | ma_ios_session_category_option_allow_bluetooth                            | AVAudioSessionCategoryOptionAllowBluetooth                       |
4458
        | ma_ios_session_category_option_default_to_speaker                         | AVAudioSessionCategoryOptionDefaultToSpeaker                     |
4459
        | ma_ios_session_category_option_interrupt_spoken_audio_and_mix_with_others | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers |
4460
        | ma_ios_session_category_option_allow_bluetooth_a2dp                       | AVAudioSessionCategoryOptionAllowBluetoothA2DP                   |
4461
        | ma_ios_session_category_option_allow_air_play                             | AVAudioSessionCategoryOptionAllowAirPlay                         |
4462
        |---------------------------------------------------------------------------|------------------------------------------------------------------|
4463
 
4464
    coreaudio.noAudioSessionActivate
4465
        iOS only. When set to true, does not perform an explicit [[AVAudioSession sharedInstace] setActive:true] on initialization.
4466
 
4467
    coreaudio.noAudioSessionDeactivate
4468
        iOS only. When set to true, does not perform an explicit [[AVAudioSession sharedInstace] setActive:false] on uninitialization.
4469
 
4470
    jack.pClientName
4471
        The name of the client to pass to `jack_client_open()`.
4472
 
4473
    jack.tryStartServer
4474
        Whether or not to try auto-starting the JACK server. Defaults to false.
4475
 
4476
 
4477
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
4478
relevant backends every time it's initialized.
4479
 
4480
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
4481
reason for this is that a pointer to the context is stored in the `ma_device` structure.
4482
 
4483
 
4484
Example 1 - Default Initialization
4485
----------------------------------
4486
The example below shows how to initialize the context using the default configuration.
4487
 
4488
```c
4489
ma_context context;
4490
ma_result result = ma_context_init(NULL, 0, NULL, &context);
4491
if (result != MA_SUCCESS) {
4492
    // Error.
4493
}
4494
```
4495
 
4496
 
4497
Example 2 - Custom Configuration
4498
--------------------------------
4499
The example below shows how to initialize the context using custom backend priorities and a custom configuration. In this hypothetical example, the program
4500
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
4501
want an error to be returned if no valid backend is available which they achieve by excluding the Null backend.
4502
 
4503
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.
4504
 
4505
```c
4506
ma_backend backends[] = {
4507
    ma_backend_alsa,
4508
    ma_backend_pulseaudio,
4509
    ma_backend_wasapi,
4510
    ma_backend_dsound
4511
};
4512
 
4513
ma_log log;
4514
ma_log_init(&log);
4515
ma_log_register_callback(&log, ma_log_callback_init(my_log_callbac, pMyLogUserData));
4516
 
4517
ma_context_config config = ma_context_config_init();
4518
config.pLog = &log; // Specify a custom log object in the config so any logs that are posted from ma_context_init() are captured.
4519
 
4520
ma_context context;
4521
ma_result result = ma_context_init(backends, sizeof(backends)/sizeof(backends[0]), &config, &context);
4522
if (result != MA_SUCCESS) {
4523
    // Error.
4524
    if (result == MA_NO_BACKEND) {
4525
        // Couldn't find an appropriate backend.
4526
    }
4527
}
4528
 
4529
// You could also attach a log callback post-initialization:
4530
ma_log_register_callback(ma_context_get_log(&context), ma_log_callback_init(my_log_callback, pMyLogUserData));
4531
```
4532
 
4533
 
4534
See Also
4535
--------
4536
ma_context_config_init()
4537
ma_context_uninit()
4538
*/
4539
MA_API ma_result ma_context_init(const ma_backend backends[], ma_uint32 backendCount, const ma_context_config* pConfig, ma_context* pContext);
4540
 
4541
/*
4542
Uninitializes a context.
4543
 
4544
 
4545
Return Value
4546
------------
4547
MA_SUCCESS if successful; any other error code otherwise.
4548
 
4549
 
4550
Thread Safety
4551
-------------
4552
Unsafe. Do not call this function across multiple threads as some backends read and write to global state.
4553
 
4554
 
4555
Remarks
4556
-------
4557
Results are undefined if you call this while any device created by this context is still active.
4558
 
4559
 
4560
See Also
4561
--------
4562
ma_context_init()
4563
*/
4564
MA_API ma_result ma_context_uninit(ma_context* pContext);
4565
 
4566
/*
4567
Retrieves the size of the ma_context object.
4568
 
4569
This is mainly for the purpose of bindings to know how much memory to allocate.
4570
*/
4571
MA_API size_t ma_context_sizeof(void);
4572
 
4573
/*
4574
Retrieves a pointer to the log object associated with this context.
4575
 
4576
 
4577
Remarks
4578
-------
4579
Pass the returned pointer to `ma_log_post()`, `ma_log_postv()` or `ma_log_postf()` to post a log
4580
message.
4581
 
4582
You can attach your own logging callback to the log with `ma_log_register_callback()`
4583
 
4584
 
4585
Return Value
4586
------------
4587
A pointer to the `ma_log` object that the context uses to post log messages. If some error occurs,
4588
NULL will be returned.
4589
*/
4590
MA_API ma_log* ma_context_get_log(ma_context* pContext);
4591
 
4592
/*
4593
Enumerates over every device (both playback and capture).
4594
 
4595
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
4596
an internal heap allocation, or it simply suits your code better.
4597
 
4598
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
4599
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,
4600
but don't call it from within the enumeration callback.
4601
 
4602
Returning false from the callback will stop enumeration. Returning true will continue enumeration.
4603
 
4604
 
4605
Parameters
4606
----------
4607
pContext (in)
4608
    A pointer to the context performing the enumeration.
4609
 
4610
callback (in)
4611
    The callback to fire for each enumerated device.
4612
 
4613
pUserData (in)
4614
    A pointer to application-defined data passed to the callback.
4615
 
4616
 
4617
Return Value
4618
------------
4619
MA_SUCCESS if successful; any other error code otherwise.
4620
 
4621
 
4622
Thread Safety
4623
-------------
4624
Safe. This is guarded using a simple mutex lock.
4625
 
4626
 
4627
Remarks
4628
-------
4629
Do _not_ assume the first enumerated device of a given type is the default device.
4630
 
4631
Some backends and platforms may only support default playback and capture devices.
4632
 
4633
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,
4634
do not try to call `ma_context_get_device_info()` from within the callback.
4635
 
4636
Consider using `ma_context_get_devices()` for a simpler and safer API, albeit at the expense of an internal heap allocation.
4637
 
4638
 
4639
Example 1 - Simple Enumeration
4640
------------------------------
4641
ma_bool32 ma_device_enum_callback(ma_context* pContext, ma_device_type deviceType, const ma_device_info* pInfo, void* pUserData)
4642
{
4643
    printf("Device Name: %s\n", pInfo->name);
4644
    return MA_TRUE;
4645
}
4646
 
4647
ma_result result = ma_context_enumerate_devices(&context, my_device_enum_callback, pMyUserData);
4648
if (result != MA_SUCCESS) {
4649
    // Error.
4650
}
4651
 
4652
 
4653
See Also
4654
--------
4655
ma_context_get_devices()
4656
*/
4657
MA_API ma_result ma_context_enumerate_devices(ma_context* pContext, ma_enum_devices_callback_proc callback, void* pUserData);
4658
 
4659
/*
4660
Retrieves basic information about every active playback and/or capture device.
4661
 
4662
This function will allocate memory internally for the device lists and return a pointer to them through the `ppPlaybackDeviceInfos` and `ppCaptureDeviceInfos`
4663
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.
4664
 
4665
 
4666
Parameters
4667
----------
4668
pContext (in)
4669
    A pointer to the context performing the enumeration.
4670
 
4671
ppPlaybackDeviceInfos (out)
4672
    A pointer to a pointer that will receive the address of a buffer containing the list of `ma_device_info` structures for playback devices.
4673
 
4674
pPlaybackDeviceCount (out)
4675
    A pointer to an unsigned integer that will receive the number of playback devices.
4676
 
4677
ppCaptureDeviceInfos (out)
4678
    A pointer to a pointer that will receive the address of a buffer containing the list of `ma_device_info` structures for capture devices.
4679
 
4680
pCaptureDeviceCount (out)
4681
    A pointer to an unsigned integer that will receive the number of capture devices.
4682
 
4683
 
4684
Return Value
4685
------------
4686
MA_SUCCESS if successful; any other error code otherwise.
4687
 
4688
 
4689
Thread Safety
4690
-------------
4691
Unsafe. Since each call to this function invalidates the pointers from the previous call, you should not be calling this simultaneously across multiple
4692
threads. Instead, you need to make a copy of the returned data with your own higher level synchronization.
4693
 
4694
 
4695
Remarks
4696
-------
4697
It is _not_ safe to assume the first device in the list is the default device.
4698
 
4699
You can pass in NULL for the playback or capture lists in which case they'll be ignored.
4700
 
4701
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.
4702
 
4703
 
4704
See Also
4705
--------
4706
ma_context_get_devices()
4707
*/
4708
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);
4709
 
4710
/*
4711
Retrieves information about a device of the given type, with the specified ID and share mode.
4712
 
4713
 
4714
Parameters
4715
----------
4716
pContext (in)
4717
    A pointer to the context performing the query.
4718
 
4719
deviceType (in)
4720
    The type of the device being queried. Must be either `ma_device_type_playback` or `ma_device_type_capture`.
4721
 
4722
pDeviceID (in)
4723
    The ID of the device being queried.
4724
 
4725
pDeviceInfo (out)
4726
    A pointer to the `ma_device_info` structure that will receive the device information.
4727
 
4728
 
4729
Return Value
4730
------------
4731
MA_SUCCESS if successful; any other error code otherwise.
4732
 
4733
 
4734
Thread Safety
4735
-------------
4736
Safe. This is guarded using a simple mutex lock.
4737
 
4738
 
4739
Remarks
4740
-------
4741
Do _not_ call this from within the `ma_context_enumerate_devices()` callback.
4742
 
4743
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
4744
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
4745
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
4746
the requested share mode is unsupported.
4747
 
4748
This leaves pDeviceInfo unmodified in the result of an error.
4749
*/
4750
MA_API ma_result ma_context_get_device_info(ma_context* pContext, ma_device_type deviceType, const ma_device_id* pDeviceID, ma_device_info* pDeviceInfo);
4751
 
4752
/*
4753
Determines if the given context supports loopback mode.
4754
 
4755
 
4756
Parameters
4757
----------
4758
pContext (in)
4759
    A pointer to the context getting queried.
4760
 
4761
 
4762
Return Value
4763
------------
4764
MA_TRUE if the context supports loopback mode; MA_FALSE otherwise.
4765
*/
4766
MA_API ma_bool32 ma_context_is_loopback_supported(ma_context* pContext);
4767
 
4768
 
4769
 
4770
/*
4771
Initializes a device config with default settings.
4772
 
4773
 
4774
Parameters
4775
----------
4776
deviceType (in)
4777
    The type of the device this config is being initialized for. This must set to one of the following:
4778
 
4779
    |-------------------------|
4780
    | Device Type             |
4781
    |-------------------------|
4782
    | ma_device_type_playback |
4783
    | ma_device_type_capture  |
4784
    | ma_device_type_duplex   |
4785
    | ma_device_type_loopback |
4786
    |-------------------------|
4787
 
4788
 
4789
Return Value
4790
------------
4791
A new device config object with default settings. You will typically want to adjust the config after this function returns. See remarks.
4792
 
4793
 
4794
Thread Safety
4795
-------------
4796
Safe.
4797
 
4798
 
4799
Callback Safety
4800
---------------
4801
Safe, but don't try initializing a device in a callback.
4802
 
4803
 
4804
Remarks
4805
-------
4806
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
4807
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
4808
before initializing the device.
4809
 
4810
See `ma_device_init()` for details on specific configuration options.
4811
 
4812
 
4813
Example 1 - Simple Configuration
4814
--------------------------------
4815
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
4816
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
4817
to the `ma_device_config` structure.
4818
 
4819
```c
4820
ma_device_config config = ma_device_config_init(ma_device_type_playback);
4821
config.playback.format   = ma_format_f32;
4822
config.playback.channels = 2;
4823
config.sampleRate        = 48000;
4824
config.dataCallback      = ma_data_callback;
4825
config.pUserData         = pMyUserData;
4826
```
4827
 
4828
 
4829
See Also
4830
--------
4831
ma_device_init()
4832
ma_device_init_ex()
4833
*/
4834
MA_API ma_device_config ma_device_config_init(ma_device_type deviceType);
4835
 
4836
 
4837
/*
4838
Initializes a device.
4839
 
4840
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
4841
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
4842
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
4843
device is done via a callback which is fired by miniaudio at periodic time intervals.
4844
 
4845
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
4846
or milliseconds, whichever is more convenient. Generally speaking, the smaller the period, the lower the latency at the expense of higher CPU usage and
4847
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
4848
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
4849
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
4850
backend is ultimately responsible for what it gives you. You cannot assume you will get exactly what you ask for.
4851
 
4852
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
4853
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
4854
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.
4855
 
4856
 
4857
Parameters
4858
----------
4859
pContext (in, optional)
4860
    A pointer to the context that owns the device. This can be null, in which case it creates a default context internally.
4861
 
4862
pConfig (in)
4863
    A pointer to the device configuration. Cannot be null. See remarks for details.
4864
 
4865
pDevice (out)
4866
    A pointer to the device object being initialized.
4867
 
4868
 
4869
Return Value
4870
------------
4871
MA_SUCCESS if successful; any other error code otherwise.
4872
 
4873
 
4874
Thread Safety
4875
-------------
4876
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
4877
calling this at the same time as `ma_device_uninit()`.
4878
 
4879
 
4880
Callback Safety
4881
---------------
4882
Unsafe. It is not safe to call this inside any callback.
4883
 
4884
 
4885
Remarks
4886
-------
4887
Setting `pContext` to NULL will result in miniaudio creating a default context internally and is equivalent to passing in a context initialized like so:
4888
 
4889
    ```c
4890
    ma_context_init(NULL, 0, NULL, &context);
4891
    ```
4892
 
4893
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
4894
device.pContext for the initialization of other devices.
4895
 
4896
The device can be configured via the `pConfig` argument. The config object is initialized with `ma_device_config_init()`. Individual configuration settings can
4897
then be set directly on the structure. Below are the members of the `ma_device_config` object.
4898
 
4899
    deviceType
4900
        Must be `ma_device_type_playback`, `ma_device_type_capture`, `ma_device_type_duplex` of `ma_device_type_loopback`.
4901
 
4902
    sampleRate
4903
        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.
4904
 
4905
    periodSizeInFrames
4906
        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
4907
        be used depending on the selected performance profile. This value affects latency. See below for details.
4908
 
4909
    periodSizeInMilliseconds
4910
        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
4911
        used depending on the selected performance profile. The value affects latency. See below for details.
4912
 
4913
    periods
4914
        The number of periods making up the device's entire buffer. The total buffer size is `periodSizeInFrames` or `periodSizeInMilliseconds` multiplied by
4915
        this value. This is just a hint as backends will be the ones who ultimately decide how your periods will be configured.
4916
 
4917
    performanceProfile
4918
        A hint to miniaudio as to the performance requirements of your program. Can be either `ma_performance_profile_low_latency` (default) or
4919
        `ma_performance_profile_conservative`. This mainly affects the size of default buffers and can usually be left at it's default value.
4920
 
4921
    noPreSilencedOutputBuffer
4922
        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
4923
        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
4924
        callback will write to every sample in the output buffer, or if you are doing your own clearing.
4925
 
4926
    noClip
4927
        When set to true, the contents of the output buffer are left alone after returning and it will be left up to the backend itself to decide whether or
4928
        not to clip. When set to false (default), the contents of the output buffer passed into the data callback will be clipped after returning. This only
4929
        applies when the playback sample format is f32.
4930
 
4931
    noDisableDenormals
4932
        By default, miniaudio will disable denormals when the data callback is called. Setting this to true will prevent the disabling of denormals.
4933
 
4934
    noFixedSizedCallback
4935
        Allows miniaudio to fire the data callback with any frame count. When this is set to false (the default), the data callback will be fired with a
4936
        consistent frame count as specified by `periodSizeInFrames` or `periodSizeInMilliseconds`. When set to true, miniaudio will fire the callback with
4937
        whatever the backend requests, which could be anything.
4938
 
4939
    dataCallback
4940
        The callback to fire whenever data is ready to be delivered to or from the device.
4941
 
4942
    notificationCallback
4943
        The callback to fire when something has changed with the device, such as whether or not it has been started or stopped.
4944
 
4945
    pUserData
4946
        The user data pointer to use with the device. You can access this directly from the device object like `device.pUserData`.
4947
 
4948
    resampling.algorithm
4949
        The resampling algorithm to use when miniaudio needs to perform resampling between the rate specified by `sampleRate` and the device's native rate. The
4950
        default value is `ma_resample_algorithm_linear`, and the quality can be configured with `resampling.linear.lpfOrder`.
4951
 
4952
    resampling.pBackendVTable
4953
        A pointer to an optional vtable that can be used for plugging in a custom resampler.
4954
 
4955
    resampling.pBackendUserData
4956
        A pointer that will passed to callbacks in pBackendVTable.
4957
 
4958
    resampling.linear.lpfOrder
4959
        The linear resampler applies a low-pass filter as part of it's processing for anti-aliasing. This setting controls the order of the filter. The higher
4960
        the value, the better the quality, in general. Setting this to 0 will disable low-pass filtering altogether. The maximum value is
4961
        `MA_MAX_FILTER_ORDER`. The default value is `min(4, MA_MAX_FILTER_ORDER)`.
4962
 
4963
    playback.pDeviceID
4964
        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
4965
        default playback device. Retrieve the device ID from the `ma_device_info` structure, which can be retrieved using device enumeration.
4966
 
4967
    playback.format
4968
        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
4969
        initialization from the device object directly with `device.playback.format`.
4970
 
4971
    playback.channels
4972
        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
4973
        from the device object directly with `device.playback.channels`.
4974
 
4975
    playback.pChannelMap
4976
        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
4977
        device object direct with `device.playback.pChannelMap`. When set, the buffer should contain `channels` items.
4978
 
4979
    playback.shareMode
4980
        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
4981
        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
4982
        ma_share_mode_shared and reinitializing.
4983
 
4984
    capture.pDeviceID
4985
        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
4986
        default capture device. Retrieve the device ID from the `ma_device_info` structure, which can be retrieved using device enumeration.
4987
 
4988
    capture.format
4989
        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
4990
        initialization from the device object directly with `device.capture.format`.
4991
 
4992
    capture.channels
4993
        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
4994
        from the device object directly with `device.capture.channels`.
4995
 
4996
    capture.pChannelMap
4997
        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
4998
        device object direct with `device.capture.pChannelMap`. When set, the buffer should contain `channels` items.
4999
 
5000
    capture.shareMode
5001
        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
5002
        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
5003
        ma_share_mode_shared and reinitializing.
5004
 
5005
    wasapi.noAutoConvertSRC
5006
        WASAPI only. When set to true, disables WASAPI's automatic resampling and forces the use of miniaudio's resampler. Defaults to false.
5007
 
5008
    wasapi.noDefaultQualitySRC
5009
        WASAPI only. Only used when `wasapi.noAutoConvertSRC` is set to false. When set to true, disables the use of `AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY`.
5010
        You should usually leave this set to false, which is the default.
5011
 
5012
    wasapi.noAutoStreamRouting
5013
        WASAPI only. When set to true, disables automatic stream routing on the WASAPI backend. Defaults to false.
5014
 
5015
    wasapi.noHardwareOffloading
5016
        WASAPI only. When set to true, disables the use of WASAPI's hardware offloading feature. Defaults to false.
5017
 
5018
    alsa.noMMap
5019
        ALSA only. When set to true, disables MMap mode. Defaults to false.
5020
 
5021
    alsa.noAutoFormat
5022
        ALSA only. When set to true, disables ALSA's automatic format conversion by including the SND_PCM_NO_AUTO_FORMAT flag. Defaults to false.
5023
 
5024
    alsa.noAutoChannels
5025
        ALSA only. When set to true, disables ALSA's automatic channel conversion by including the SND_PCM_NO_AUTO_CHANNELS flag. Defaults to false.
5026
 
5027
    alsa.noAutoResample
5028
        ALSA only. When set to true, disables ALSA's automatic resampling by including the SND_PCM_NO_AUTO_RESAMPLE flag. Defaults to false.
5029
 
5030
    pulse.pStreamNamePlayback
5031
        PulseAudio only. Sets the stream name for playback.
5032
 
5033
    pulse.pStreamNameCapture
5034
        PulseAudio only. Sets the stream name for capture.
5035
 
5036
    coreaudio.allowNominalSampleRateChange
5037
        Core Audio only. Desktop only. When enabled, allows the sample rate of the device to be changed at the operating system level. This
5038
        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
5039
        that is known to be natively supported by the hardware thereby avoiding the cost of resampling. When set to true, miniaudio will
5040
        find the closest match between the sample rate requested in the device config and the sample rates natively supported by the
5041
        hardware. When set to false, the sample rate currently set by the operating system will always be used.
5042
 
5043
    opensl.streamType
5044
        OpenSL only. Explicitly sets the stream type. If left unset (`ma_opensl_stream_type_default`), the
5045
        stream type will be left unset. Think of this as the type of audio you're playing.
5046
 
5047
    opensl.recordingPreset
5048
        OpenSL only. Explicitly sets the type of recording your program will be doing. When left
5049
        unset, the recording preset will be left unchanged.
5050
 
5051
    aaudio.usage
5052
        AAudio only. Explicitly sets the nature of the audio the program will be consuming. When
5053
        left unset, the usage will be left unchanged.
5054
 
5055
    aaudio.contentType
5056
        AAudio only. Sets the content type. When left unset, the content type will be left unchanged.
5057
 
5058
    aaudio.inputPreset
5059
        AAudio only. Explicitly sets the type of recording your program will be doing. When left
5060
        unset, the input preset will be left unchanged.
5061
 
5062
    aaudio.noAutoStartAfterReroute
5063
        AAudio only. Controls whether or not the device should be automatically restarted after a
5064
        stream reroute. When set to false (default) the device will be restarted automatically;
5065
        otherwise the device will be stopped.
5066
 
5067
 
5068
Once initialized, the device's config is immutable. If you need to change the config you will need to initialize a new device.
5069
 
5070
After initializing the device it will be in a stopped state. To start it, use `ma_device_start()`.
5071
 
5072
If both `periodSizeInFrames` and `periodSizeInMilliseconds` are set to zero, it will default to `MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_LOW_LATENCY` or
5073
`MA_DEFAULT_PERIOD_SIZE_IN_MILLISECONDS_CONSERVATIVE`, depending on whether or not `performanceProfile` is set to `ma_performance_profile_low_latency` or
5074
`ma_performance_profile_conservative`.
5075
 
5076
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
5077
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
5078
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,
5079
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.
5080
Starting with Windows 10, miniaudio will use low-latency shared mode where possible which may make exclusive mode unnecessary.
5081
 
5082
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
5083
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
5084
on an optimized pass-through fast path. You can retrieve the format, channel count and sample rate by inspecting the `playback/capture.format`,
5085
`playback/capture.channels` and `sampleRate` members of the device object.
5086
 
5087
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
5088
asking for permissions. Please refer to the official documentation for ActivateAudioInterfaceAsync() for more information.
5089
 
5090
ALSA Specific: When initializing the default device, requesting shared mode will try using the "dmix" device for playback and the "dsnoop" device for capture.
5091
If these fail it will try falling back to the "hw" device.
5092
 
5093
 
5094
Example 1 - Simple Initialization
5095
---------------------------------
5096
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
5097
playback device this is usually all you need.
5098
 
5099
```c
5100
ma_device_config config = ma_device_config_init(ma_device_type_playback);
5101
config.playback.format   = ma_format_f32;
5102
config.playback.channels = 2;
5103
config.sampleRate        = 48000;
5104
config.dataCallback      = ma_data_callback;
5105
config.pMyUserData       = pMyUserData;
5106
 
5107
ma_device device;
5108
ma_result result = ma_device_init(NULL, &config, &device);
5109
if (result != MA_SUCCESS) {
5110
    // Error
5111
}
5112
```
5113
 
5114
 
5115
Example 2 - Advanced Initialization
5116
-----------------------------------
5117
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
5118
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
5119
enumeration.
5120
 
5121
```c
5122
ma_context context;
5123
ma_result result = ma_context_init(NULL, 0, NULL, &context);
5124
if (result != MA_SUCCESS) {
5125
    // Error
5126
}
5127
 
5128
ma_device_info* pPlaybackDeviceInfos;
5129
ma_uint32 playbackDeviceCount;
5130
result = ma_context_get_devices(&context, &pPlaybackDeviceInfos, &playbackDeviceCount, NULL, NULL);
5131
if (result != MA_SUCCESS) {
5132
    // Error
5133
}
5134
 
5135
// ... choose a device from pPlaybackDeviceInfos ...
5136
 
5137
ma_device_config config = ma_device_config_init(ma_device_type_playback);
5138
config.playback.pDeviceID       = pMyChosenDeviceID;    // <-- Get this from the `id` member of one of the `ma_device_info` objects returned by ma_context_get_devices().
5139
config.playback.format          = ma_format_f32;
5140
config.playback.channels        = 2;
5141
config.sampleRate               = 48000;
5142
config.dataCallback             = ma_data_callback;
5143
config.pUserData                = pMyUserData;
5144
config.periodSizeInMilliseconds = 10;
5145
config.periods                  = 3;
5146
 
5147
ma_device device;
5148
result = ma_device_init(&context, &config, &device);
5149
if (result != MA_SUCCESS) {
5150
    // Error
5151
}
5152
```
5153
 
5154
 
5155
See Also
5156
--------
5157
ma_device_config_init()
5158
ma_device_uninit()
5159
ma_device_start()
5160
ma_context_init()
5161
ma_context_get_devices()
5162
ma_context_enumerate_devices()
5163
*/
5164
MA_API ma_result ma_device_init(ma_context* pContext, const ma_device_config* pConfig, ma_device* pDevice);
5165
 
5166
/*
5167
Initializes a device without a context, with extra parameters for controlling the configuration of the internal self-managed context.
5168
 
5169
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
5170
allows you to configure the internally created context.
5171
 
5172
 
5173
Parameters
5174
----------
5175
backends (in, optional)
5176
    A list of backends to try initializing, in priority order. Can be NULL, in which case it uses default priority order.
5177
 
5178
backendCount (in, optional)
5179
    The number of items in `backend`. Ignored if `backend` is NULL.
5180
 
5181
pContextConfig (in, optional)
5182
    The context configuration.
5183
 
5184
pConfig (in)
5185
    A pointer to the device configuration. Cannot be null. See remarks for details.
5186
 
5187
pDevice (out)
5188
    A pointer to the device object being initialized.
5189
 
5190
 
5191
Return Value
5192
------------
5193
MA_SUCCESS if successful; any other error code otherwise.
5194
 
5195
 
5196
Thread Safety
5197
-------------
5198
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
5199
calling this at the same time as `ma_device_uninit()`.
5200
 
5201
 
5202
Callback Safety
5203
---------------
5204
Unsafe. It is not safe to call this inside any callback.
5205
 
5206
 
5207
Remarks
5208
-------
5209
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
5210
your own context.
5211
 
5212
See the documentation for `ma_context_init()` for information on the different context configuration options.
5213
 
5214
 
5215
See Also
5216
--------
5217
ma_device_init()
5218
ma_device_uninit()
5219
ma_device_config_init()
5220
ma_context_init()
5221
*/
5222
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);
5223
 
5224
/*
5225
Uninitializes a device.
5226
 
5227
This will explicitly stop the device. You do not need to call `ma_device_stop()` beforehand, but it's harmless if you do.
5228
 
5229
 
5230
Parameters
5231
----------
5232
pDevice (in)
5233
    A pointer to the device to stop.
5234
 
5235
 
5236
Return Value
5237
------------
5238
Nothing
5239
 
5240
 
5241
Thread Safety
5242
-------------
5243
Unsafe. As soon as this API is called the device should be considered undefined.
5244
 
5245
 
5246
Callback Safety
5247
---------------
5248
Unsafe. It is not safe to call this inside any callback. Doing this will result in a deadlock.
5249
 
5250
 
5251
See Also
5252
--------
5253
ma_device_init()
5254
ma_device_stop()
5255
*/
5256
MA_API void ma_device_uninit(ma_device* pDevice);
5257
 
5258
 
5259
/*
5260
Retrieves a pointer to the context that owns the given device.
5261
*/
5262
MA_API ma_context* ma_device_get_context(ma_device* pDevice);
5263
 
5264
/*
5265
Helper function for retrieving the log object associated with the context that owns this device.
5266
*/
5267
MA_API ma_log* ma_device_get_log(ma_device* pDevice);
5268
 
5269
 
5270
/*
5271
Retrieves information about the device.
5272
 
5273
 
5274
Parameters
5275
----------
5276
pDevice (in)
5277
    A pointer to the device whose information is being retrieved.
5278
 
5279
type (in)
5280
    The device type. This parameter is required for duplex devices. When retrieving device
5281
    information, you are doing so for an individual playback or capture device.
5282
 
5283
pDeviceInfo (out)
5284
    A pointer to the `ma_device_info` that will receive the device information.
5285
 
5286
 
5287
Return Value
5288
------------
5289
MA_SUCCESS if successful; any other error code otherwise.
5290
 
5291
 
5292
Thread Safety
5293
-------------
5294
Unsafe. This should be considered unsafe because it may be calling into the backend which may or
5295
may not be safe.
5296
 
5297
 
5298
Callback Safety
5299
---------------
5300
Unsafe. You should avoid calling this in the data callback because it may call into the backend
5301
which may or may not be safe.
5302
*/
5303
MA_API ma_result ma_device_get_info(ma_device* pDevice, ma_device_type type, ma_device_info* pDeviceInfo);
5304
 
5305
 
5306
/*
5307
Retrieves the name of the device.
5308
 
5309
 
5310
Parameters
5311
----------
5312
pDevice (in)
5313
    A pointer to the device whose information is being retrieved.
5314
 
5315
type (in)
5316
    The device type. This parameter is required for duplex devices. When retrieving device
5317
    information, you are doing so for an individual playback or capture device.
5318
 
5319
pName (out)
5320
    A pointer to the buffer that will receive the name.
5321
 
5322
nameCap (in)
5323
    The capacity of the output buffer, including space for the null terminator.
5324
 
5325
pLengthNotIncludingNullTerminator (out, optional)
5326
    A pointer to the variable that will receive the length of the name, not including the null
5327
    terminator.
5328
 
5329
 
5330
Return Value
5331
------------
5332
MA_SUCCESS if successful; any other error code otherwise.
5333
 
5334
 
5335
Thread Safety
5336
-------------
5337
Unsafe. This should be considered unsafe because it may be calling into the backend which may or
5338
may not be safe.
5339
 
5340
 
5341
Callback Safety
5342
---------------
5343
Unsafe. You should avoid calling this in the data callback because it may call into the backend
5344
which may or may not be safe.
5345
 
5346
 
5347
Remarks
5348
-------
5349
If the name does not fully fit into the output buffer, it'll be truncated. You can pass in NULL to
5350
`pName` if you want to first get the length of the name for the purpose of memory allocation of the
5351
output buffer. Allocating a buffer of size `MA_MAX_DEVICE_NAME_LENGTH + 1` should be enough for
5352
most cases and will avoid the need for the inefficiency of calling this function twice.
5353
 
5354
This is implemented in terms of `ma_device_get_info()`.
5355
*/
5356
MA_API ma_result ma_device_get_name(ma_device* pDevice, ma_device_type type, char* pName, size_t nameCap, size_t* pLengthNotIncludingNullTerminator);
5357
 
5358
 
5359
/*
5360
Starts the device. For playback devices this begins playback. For capture devices it begins recording.
5361
 
5362
Use `ma_device_stop()` to stop the device.
5363
 
5364
 
5365
Parameters
5366
----------
5367
pDevice (in)
5368
    A pointer to the device to start.
5369
 
5370
 
5371
Return Value
5372
------------
5373
MA_SUCCESS if successful; any other error code otherwise.
5374
 
5375
 
5376
Thread Safety
5377
-------------
5378
Safe. It's safe to call this from any thread with the exception of the callback thread.
5379
 
5380
 
5381
Callback Safety
5382
---------------
5383
Unsafe. It is not safe to call this inside any callback.
5384
 
5385
 
5386
Remarks
5387
-------
5388
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
5389
audio data in the buffer, which needs to be done before the device begins playback.
5390
 
5391
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.
5392
 
5393
Do not call this in any callback.
5394
 
5395
 
5396
See Also
5397
--------
5398
ma_device_stop()
5399
*/
5400
MA_API ma_result ma_device_start(ma_device* pDevice);
5401
 
5402
/*
5403
Stops the device. For playback devices this stops playback. For capture devices it stops recording.
5404
 
5405
Use `ma_device_start()` to start the device again.
5406
 
5407
 
5408
Parameters
5409
----------
5410
pDevice (in)
5411
    A pointer to the device to stop.
5412
 
5413
 
5414
Return Value
5415
------------
5416
MA_SUCCESS if successful; any other error code otherwise.
5417
 
5418
 
5419
Thread Safety
5420
-------------
5421
Safe. It's safe to call this from any thread with the exception of the callback thread.
5422
 
5423
 
5424
Callback Safety
5425
---------------
5426
Unsafe. It is not safe to call this inside any callback. Doing this will result in a deadlock.
5427
 
5428
 
5429
Remarks
5430
-------
5431
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
5432
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
5433
that was specified at initialization time).
5434
 
5435
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
5436
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
5437
speakers or received from the microphone which can in turn result in de-syncs.
5438
 
5439
Do not call this in any callback.
5440
 
5441
 
5442
See Also
5443
--------
5444
ma_device_start()
5445
*/
5446
MA_API ma_result ma_device_stop(ma_device* pDevice);
5447
 
5448
/*
5449
Determines whether or not the device is started.
5450
 
5451
 
5452
Parameters
5453
----------
5454
pDevice (in)
5455
    A pointer to the device whose start state is being retrieved.
5456
 
5457
 
5458
Return Value
5459
------------
5460
True if the device is started, false otherwise.
5461
 
5462
 
5463
Thread Safety
5464
-------------
5465
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
5466
value will be out of sync.
5467
 
5468
 
5469
Callback Safety
5470
---------------
5471
Safe. This is implemented as a simple accessor.
5472
 
5473
 
5474
See Also
5475
--------
5476
ma_device_start()
5477
ma_device_stop()
5478
*/
5479
MA_API ma_bool32 ma_device_is_started(const ma_device* pDevice);
5480
 
5481
 
5482
/*
5483
Retrieves the state of the device.
5484
 
5485
 
5486
Parameters
5487
----------
5488
pDevice (in)
5489
    A pointer to the device whose state is being retrieved.
5490
 
5491
 
5492
Return Value
5493
------------
5494
The current state of the device. The return value will be one of the following:
5495
 
5496
    +-------------------------------+------------------------------------------------------------------------------+
5497
    | ma_device_state_uninitialized | Will only be returned if the device is in the middle of initialization.      |
5498
    +-------------------------------+------------------------------------------------------------------------------+
5499
    | ma_device_state_stopped       | The device is stopped. The initial state of the device after initialization. |
5500
    +-------------------------------+------------------------------------------------------------------------------+
5501
    | ma_device_state_started       | The device started and requesting and/or delivering audio data.              |
5502
    +-------------------------------+------------------------------------------------------------------------------+
5503
    | ma_device_state_starting      | The device is in the process of starting.                                    |
5504
    +-------------------------------+------------------------------------------------------------------------------+
5505
    | ma_device_state_stopping      | The device is in the process of stopping.                                    |
5506
    +-------------------------------+------------------------------------------------------------------------------+
5507
 
5508
 
5509
Thread Safety
5510
-------------
5511
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,
5512
there's a possibility the return value could be out of sync. See remarks.
5513
 
5514
 
5515
Callback Safety
5516
---------------
5517
Safe. This is implemented as a simple accessor.
5518
 
5519
 
5520
Remarks
5521
-------
5522
The general flow of a devices state goes like this:
5523
 
5524
    ```
5525
    ma_device_init()  -> ma_device_state_uninitialized -> ma_device_state_stopped
5526
    ma_device_start() -> ma_device_state_starting      -> ma_device_state_started
5527
    ma_device_stop()  -> ma_device_state_stopping      -> ma_device_state_stopped
5528
    ```
5529
 
5530
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
5531
value returned by this function could potentially be out of sync. If this is significant to your program you need to implement your own
5532
synchronization.
5533
*/
5534
MA_API ma_device_state ma_device_get_state(const ma_device* pDevice);
5535
 
5536
 
5537
/*
5538
Performs post backend initialization routines for setting up internal data conversion.
5539
 
5540
This should be called whenever the backend is initialized. The only time this should be called from
5541
outside of miniaudio is if you're implementing a custom backend, and you would only do it if you
5542
are reinitializing the backend due to rerouting or reinitializing for some reason.
5543
 
5544
 
5545
Parameters
5546
----------
5547
pDevice [in]
5548
    A pointer to the device.
5549
 
5550
deviceType [in]
5551
    The type of the device that was just reinitialized.
5552
 
5553
pPlaybackDescriptor [in]
5554
    The descriptor of the playback device containing the internal data format and buffer sizes.
5555
 
5556
pPlaybackDescriptor [in]
5557
    The descriptor of the capture device containing the internal data format and buffer sizes.
5558
 
5559
 
5560
Return Value
5561
------------
5562
MA_SUCCESS if successful; any other error otherwise.
5563
 
5564
 
5565
Thread Safety
5566
-------------
5567
Unsafe. This will be reinitializing internal data converters which may be in use by another thread.
5568
 
5569
 
5570
Callback Safety
5571
---------------
5572
Unsafe. This will be reinitializing internal data converters which may be in use by the callback.
5573
 
5574
 
5575
Remarks
5576
-------
5577
For a duplex device, you can call this for only one side of the system. This is why the deviceType
5578
is specified as a parameter rather than deriving it from the device.
5579
 
5580
You do not need to call this manually unless you are doing a custom backend, in which case you need
5581
only do it if you're manually performing rerouting or reinitialization.
5582
*/
5583
MA_API ma_result ma_device_post_init(ma_device* pDevice, ma_device_type deviceType, const ma_device_descriptor* pPlaybackDescriptor, const ma_device_descriptor* pCaptureDescriptor);
5584
 
5585
 
5586
/*
5587
Sets the master volume factor for the device.
5588
 
5589
The volume factor must be between 0 (silence) and 1 (full volume). Use `ma_device_set_master_volume_db()` to use decibel notation, where 0 is full volume and
5590
values less than 0 decreases the volume.
5591
 
5592
 
5593
Parameters
5594
----------
5595
pDevice (in)
5596
    A pointer to the device whose volume is being set.
5597
 
5598
volume (in)
5599
    The new volume factor. Must be >= 0.
5600
 
5601
 
5602
Return Value
5603
------------
5604
MA_SUCCESS if the volume was set successfully.
5605
MA_INVALID_ARGS if pDevice is NULL.
5606
MA_INVALID_ARGS if volume is negative.
5607
 
5608
 
5609
Thread Safety
5610
-------------
5611
Safe. This just sets a local member of the device object.
5612
 
5613
 
5614
Callback Safety
5615
---------------
5616
Safe. If you set the volume in the data callback, that data written to the output buffer will have the new volume applied.
5617
 
5618
 
5619
Remarks
5620
-------
5621
This applies the volume factor across all channels.
5622
 
5623
This does not change the operating system's volume. It only affects the volume for the given `ma_device` object's audio stream.
5624
 
5625
 
5626
See Also
5627
--------
5628
ma_device_get_master_volume()
5629
ma_device_set_master_volume_db()
5630
ma_device_get_master_volume_db()
5631
*/
5632
MA_API ma_result ma_device_set_master_volume(ma_device* pDevice, float volume);
5633
 
5634
/*
5635
Retrieves the master volume factor for the device.
5636
 
5637
 
5638
Parameters
5639
----------
5640
pDevice (in)
5641
    A pointer to the device whose volume factor is being retrieved.
5642
 
5643
pVolume (in)
5644
    A pointer to the variable that will receive the volume factor. The returned value will be in the range of [0, 1].
5645
 
5646
 
5647
Return Value
5648
------------
5649
MA_SUCCESS if successful.
5650
MA_INVALID_ARGS if pDevice is NULL.
5651
MA_INVALID_ARGS if pVolume is NULL.
5652
 
5653
 
5654
Thread Safety
5655
-------------
5656
Safe. This just a simple member retrieval.
5657
 
5658
 
5659
Callback Safety
5660
---------------
5661
Safe.
5662
 
5663
 
5664
Remarks
5665
-------
5666
If an error occurs, `*pVolume` will be set to 0.
5667
 
5668
 
5669
See Also
5670
--------
5671
ma_device_set_master_volume()
5672
ma_device_set_master_volume_gain_db()
5673
ma_device_get_master_volume_gain_db()
5674
*/
5675
MA_API ma_result ma_device_get_master_volume(ma_device* pDevice, float* pVolume);
5676
 
5677
/*
5678
Sets the master volume for the device as gain in decibels.
5679
 
5680
A gain of 0 is full volume, whereas a gain of < 0 will decrease the volume.
5681
 
5682
 
5683
Parameters
5684
----------
5685
pDevice (in)
5686
    A pointer to the device whose gain is being set.
5687
 
5688
gainDB (in)
5689
    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.
5690
 
5691
 
5692
Return Value
5693
------------
5694
MA_SUCCESS if the volume was set successfully.
5695
MA_INVALID_ARGS if pDevice is NULL.
5696
MA_INVALID_ARGS if the gain is > 0.
5697
 
5698
 
5699
Thread Safety
5700
-------------
5701
Safe. This just sets a local member of the device object.
5702
 
5703
 
5704
Callback Safety
5705
---------------
5706
Safe. If you set the volume in the data callback, that data written to the output buffer will have the new volume applied.
5707
 
5708
 
5709
Remarks
5710
-------
5711
This applies the gain across all channels.
5712
 
5713
This does not change the operating system's volume. It only affects the volume for the given `ma_device` object's audio stream.
5714
 
5715
 
5716
See Also
5717
--------
5718
ma_device_get_master_volume_gain_db()
5719
ma_device_set_master_volume()
5720
ma_device_get_master_volume()
5721
*/
5722
MA_API ma_result ma_device_set_master_volume_db(ma_device* pDevice, float gainDB);
5723
 
5724
/*
5725
Retrieves the master gain in decibels.
5726
 
5727
 
5728
Parameters
5729
----------
5730
pDevice (in)
5731
    A pointer to the device whose gain is being retrieved.
5732
 
5733
pGainDB (in)
5734
    A pointer to the variable that will receive the gain in decibels. The returned value will be <= 0.
5735
 
5736
 
5737
Return Value
5738
------------
5739
MA_SUCCESS if successful.
5740
MA_INVALID_ARGS if pDevice is NULL.
5741
MA_INVALID_ARGS if pGainDB is NULL.
5742
 
5743
 
5744
Thread Safety
5745
-------------
5746
Safe. This just a simple member retrieval.
5747
 
5748
 
5749
Callback Safety
5750
---------------
5751
Safe.
5752
 
5753
 
5754
Remarks
5755
-------
5756
If an error occurs, `*pGainDB` will be set to 0.
5757
 
5758
 
5759
See Also
5760
--------
5761
ma_device_set_master_volume_db()
5762
ma_device_set_master_volume()
5763
ma_device_get_master_volume()
5764
*/
5765
MA_API ma_result ma_device_get_master_volume_db(ma_device* pDevice, float* pGainDB);
5766
 
5767
 
5768
/*
5769
Called from the data callback of asynchronous backends to allow miniaudio to process the data and fire the miniaudio data callback.
5770
 
5771
 
5772
Parameters
5773
----------
5774
pDevice (in)
5775
    A pointer to device whose processing the data callback.
5776
 
5777
pOutput (out)
5778
    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
5779
    this can be NULL, in which case pInput must not be NULL.
5780
 
5781
pInput (in)
5782
    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
5783
    NULL, in which case `pOutput` must not be NULL.
5784
 
5785
frameCount (in)
5786
    The number of frames being processed.
5787
 
5788
 
5789
Return Value
5790
------------
5791
MA_SUCCESS if successful; any other result code otherwise.
5792
 
5793
 
5794
Thread Safety
5795
-------------
5796
This function should only ever be called from the internal data callback of the backend. It is safe to call this simultaneously between a
5797
playback and capture device in duplex setups.
5798
 
5799
 
5800
Callback Safety
5801
---------------
5802
Do not call this from the miniaudio data callback. It should only ever be called from the internal data callback of the backend.
5803
 
5804
 
5805
Remarks
5806
-------
5807
If both `pOutput` and `pInput` are NULL, and error will be returned. In duplex scenarios, both `pOutput` and `pInput` can be non-NULL, in
5808
which case `pInput` will be processed first, followed by `pOutput`.
5809
 
5810
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
5811
callback.
5812
*/
5813
MA_API ma_result ma_device_handle_backend_data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount);
5814
 
5815
 
5816
/*
5817
Calculates an appropriate buffer size from a descriptor, native sample rate and performance profile.
5818
 
5819
This function is used by backends for helping determine an appropriately sized buffer to use with
5820
the device depending on the values of `periodSizeInFrames` and `periodSizeInMilliseconds` in the
5821
`pDescriptor` object. Since buffer size calculations based on time depends on the sample rate, a
5822
best guess at the device's native sample rate is also required which is where `nativeSampleRate`
5823
comes in. In addition, the performance profile is also needed for cases where both the period size
5824
in frames and milliseconds are both zero.
5825
 
5826
 
5827
Parameters
5828
----------
5829
pDescriptor (in)
5830
    A pointer to device descriptor whose `periodSizeInFrames` and `periodSizeInMilliseconds` members
5831
    will be used for the calculation of the buffer size.
5832
 
5833
nativeSampleRate (in)
5834
    The device's native sample rate. This is only ever used when the `periodSizeInFrames` member of
5835
    `pDescriptor` is zero. In this case, `periodSizeInMilliseconds` will be used instead, in which
5836
    case a sample rate is required to convert to a size in frames.
5837
 
5838
performanceProfile (in)
5839
    When both the `periodSizeInFrames` and `periodSizeInMilliseconds` members of `pDescriptor` are
5840
    zero, miniaudio will fall back to a buffer size based on the performance profile. The profile
5841
    to use for this calculation is determine by this parameter.
5842
 
5843
 
5844
Return Value
5845
------------
5846
The calculated buffer size in frames.
5847
 
5848
 
5849
Thread Safety
5850
-------------
5851
This is safe so long as nothing modifies `pDescriptor` at the same time. However, this function
5852
should only ever be called from within the backend's device initialization routine and therefore
5853
shouldn't have any multithreading concerns.
5854
 
5855
 
5856
Callback Safety
5857
---------------
5858
This is safe to call within the data callback, but there is no reason to ever do this.
5859
 
5860
 
5861
Remarks
5862
-------
5863
If `nativeSampleRate` is zero, this function will fall back to `pDescriptor->sampleRate`. If that
5864
is also zero, `MA_DEFAULT_SAMPLE_RATE` will be used instead.
5865
*/
5866
MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_descriptor(const ma_device_descriptor* pDescriptor, ma_uint32 nativeSampleRate, ma_performance_profile performanceProfile);
5867
 
5868
 
5869
 
5870
/*
5871
Retrieves a friendly name for a backend.
5872
*/
5873
MA_API const char* ma_get_backend_name(ma_backend backend);
5874
 
5875
/*
5876
Retrieves the backend enum from the given name.
5877
*/
5878
MA_API ma_result ma_get_backend_from_name(const char* pBackendName, ma_backend* pBackend);
5879
 
5880
/*
5881
Determines whether or not the given backend is available by the compilation environment.
5882
*/
5883
MA_API ma_bool32 ma_is_backend_enabled(ma_backend backend);
5884
 
5885
/*
5886
Retrieves compile-time enabled backends.
5887
 
5888
 
5889
Parameters
5890
----------
5891
pBackends (out, optional)
5892
    A pointer to the buffer that will receive the enabled backends. Set to NULL to retrieve the backend count. Setting
5893
    the capacity of the buffer to `MA_BUFFER_COUNT` will guarantee it's large enough for all backends.
5894
 
5895
backendCap (in)
5896
    The capacity of the `pBackends` buffer.
5897
 
5898
pBackendCount (out)
5899
    A pointer to the variable that will receive the enabled backend count.
5900
 
5901
 
5902
Return Value
5903
------------
5904
MA_SUCCESS if successful.
5905
MA_INVALID_ARGS if `pBackendCount` is NULL.
5906
MA_NO_SPACE if the capacity of `pBackends` is not large enough.
5907
 
5908
If `MA_NO_SPACE` is returned, the `pBackends` buffer will be filled with `*pBackendCount` values.
5909
 
5910
 
5911
Thread Safety
5912
-------------
5913
Safe.
5914
 
5915
 
5916
Callback Safety
5917
---------------
5918
Safe.
5919
 
5920
 
5921
Remarks
5922
-------
5923
If you want to retrieve the number of backends so you can determine the capacity of `pBackends` buffer, you can call
5924
this function with `pBackends` set to NULL.
5925
 
5926
This will also enumerate the null backend. If you don't want to include this you need to check for `ma_backend_null`
5927
when you enumerate over the returned backends and handle it appropriately. Alternatively, you can disable it at
5928
compile time with `MA_NO_NULL`.
5929
 
5930
The returned backends are determined based on compile time settings, not the platform it's currently running on. For
5931
example, PulseAudio will be returned if it was enabled at compile time, even when the user doesn't actually have
5932
PulseAudio installed.
5933
 
5934
 
5935
Example 1
5936
---------
5937
The example below retrieves the enabled backend count using a fixed sized buffer allocated on the stack. The buffer is
5938
given a capacity of `MA_BACKEND_COUNT` which will guarantee it'll be large enough to store all available backends.
5939
Since `MA_BACKEND_COUNT` is always a relatively small value, this should be suitable for most scenarios.
5940
 
5941
```
5942
ma_backend enabledBackends[MA_BACKEND_COUNT];
5943
size_t enabledBackendCount;
5944
 
5945
result = ma_get_enabled_backends(enabledBackends, MA_BACKEND_COUNT, &enabledBackendCount);
5946
if (result != MA_SUCCESS) {
5947
    // Failed to retrieve enabled backends. Should never happen in this example since all inputs are valid.
5948
}
5949
```
5950
 
5951
 
5952
See Also
5953
--------
5954
ma_is_backend_enabled()
5955
*/
5956
MA_API ma_result ma_get_enabled_backends(ma_backend* pBackends, size_t backendCap, size_t* pBackendCount);
5957
 
5958
/*
5959
Determines whether or not loopback mode is support by a backend.
5960
*/
5961
MA_API ma_bool32 ma_is_loopback_supported(ma_backend backend);
5962
 
5963
#endif  /* MA_NO_DEVICE_IO */
5964
 
5965
 
5966
 
5967
/************************************************************************************************************************************************************
5968
 
5969
Utilities
5970
 
5971
************************************************************************************************************************************************************/
5972
 
5973
/*
5974
Calculates a buffer size in milliseconds from the specified number of frames and sample rate.
5975
*/
5976
MA_API ma_uint32 ma_calculate_buffer_size_in_milliseconds_from_frames(ma_uint32 bufferSizeInFrames, ma_uint32 sampleRate);
5977
 
5978
/*
5979
Calculates a buffer size in frames from the specified number of milliseconds and sample rate.
5980
*/
5981
MA_API ma_uint32 ma_calculate_buffer_size_in_frames_from_milliseconds(ma_uint32 bufferSizeInMilliseconds, ma_uint32 sampleRate);
5982
 
5983
/*
5984
Copies PCM frames from one buffer to another.
5985
*/
5986
MA_API void ma_copy_pcm_frames(void* dst, const void* src, ma_uint64 frameCount, ma_format format, ma_uint32 channels);
5987
 
5988
/*
5989
Copies silent frames into the given buffer.
5990
 
5991
Remarks
5992
-------
5993
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
5994
makes more sense for the purpose of mixing to initialize it to the center point.
5995
*/
5996
MA_API void ma_silence_pcm_frames(void* p, ma_uint64 frameCount, ma_format format, ma_uint32 channels);
5997
 
5998
 
5999
/*
6000
Offsets a pointer by the specified number of PCM frames.
6001
*/
6002
MA_API void* ma_offset_pcm_frames_ptr(void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels);
6003
MA_API const void* ma_offset_pcm_frames_const_ptr(const void* p, ma_uint64 offsetInFrames, ma_format format, ma_uint32 channels);
6004
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); }
6005
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); }
6006
 
6007
 
6008
/*
6009
Clips samples.
6010
*/
6011
MA_API void ma_clip_samples_u8(ma_uint8* pDst, const ma_int16* pSrc, ma_uint64 count);
6012
MA_API void ma_clip_samples_s16(ma_int16* pDst, const ma_int32* pSrc, ma_uint64 count);
6013
MA_API void ma_clip_samples_s24(ma_uint8* pDst, const ma_int64* pSrc, ma_uint64 count);
6014
MA_API void ma_clip_samples_s32(ma_int32* pDst, const ma_int64* pSrc, ma_uint64 count);
6015
MA_API void ma_clip_samples_f32(float* pDst, const float* pSrc, ma_uint64 count);
6016
MA_API void ma_clip_pcm_frames(void* pDst, const void* pSrc, ma_uint64 frameCount, ma_format format, ma_uint32 channels);
6017
 
6018
/*
6019
Helper for applying a volume factor to samples.
6020
 
6021
Note that the source and destination buffers can be the same, in which case it'll perform the operation in-place.
6022
*/
6023
MA_API void ma_copy_and_apply_volume_factor_u8(ma_uint8* pSamplesOut, const ma_uint8* pSamplesIn, ma_uint64 sampleCount, float factor);
6024
MA_API void ma_copy_and_apply_volume_factor_s16(ma_int16* pSamplesOut, const ma_int16* pSamplesIn, ma_uint64 sampleCount, float factor);
6025
MA_API void ma_copy_and_apply_volume_factor_s24(void* pSamplesOut, const void* pSamplesIn, ma_uint64 sampleCount, float factor);
6026
MA_API void ma_copy_and_apply_volume_factor_s32(ma_int32* pSamplesOut, const ma_int32* pSamplesIn, ma_uint64 sampleCount, float factor);
6027
MA_API void ma_copy_and_apply_volume_factor_f32(float* pSamplesOut, const float* pSamplesIn, ma_uint64 sampleCount, float factor);
6028
 
6029
MA_API void ma_apply_volume_factor_u8(ma_uint8* pSamples, ma_uint64 sampleCount, float factor);
6030
MA_API void ma_apply_volume_factor_s16(ma_int16* pSamples, ma_uint64 sampleCount, float factor);
6031
MA_API void ma_apply_volume_factor_s24(void* pSamples, ma_uint64 sampleCount, float factor);
6032
MA_API void ma_apply_volume_factor_s32(ma_int32* pSamples, ma_uint64 sampleCount, float factor);
6033
MA_API void ma_apply_volume_factor_f32(float* pSamples, ma_uint64 sampleCount, float factor);
6034
 
6035
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_u8(ma_uint8* pFramesOut, const ma_uint8* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
6036
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s16(ma_int16* pFramesOut, const ma_int16* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
6037
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s24(void* pFramesOut, const void* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
6038
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_s32(ma_int32* pFramesOut, const ma_int32* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
6039
MA_API void ma_copy_and_apply_volume_factor_pcm_frames_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float factor);
6040
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);
6041
 
6042
MA_API void ma_apply_volume_factor_pcm_frames_u8(ma_uint8* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
6043
MA_API void ma_apply_volume_factor_pcm_frames_s16(ma_int16* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
6044
MA_API void ma_apply_volume_factor_pcm_frames_s24(void* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
6045
MA_API void ma_apply_volume_factor_pcm_frames_s32(ma_int32* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
6046
MA_API void ma_apply_volume_factor_pcm_frames_f32(float* pFrames, ma_uint64 frameCount, ma_uint32 channels, float factor);
6047
MA_API void ma_apply_volume_factor_pcm_frames(void* pFrames, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float factor);
6048
 
6049
MA_API void ma_copy_and_apply_volume_factor_per_channel_f32(float* pFramesOut, const float* pFramesIn, ma_uint64 frameCount, ma_uint32 channels, float* pChannelGains);
6050
 
6051
 
6052
MA_API void ma_copy_and_apply_volume_and_clip_samples_u8(ma_uint8* pDst, const ma_int16* pSrc, ma_uint64 count, float volume);
6053
MA_API void ma_copy_and_apply_volume_and_clip_samples_s16(ma_int16* pDst, const ma_int32* pSrc, ma_uint64 count, float volume);
6054
MA_API void ma_copy_and_apply_volume_and_clip_samples_s24(ma_uint8* pDst, const ma_int64* pSrc, ma_uint64 count, float volume);
6055
MA_API void ma_copy_and_apply_volume_and_clip_samples_s32(ma_int32* pDst, const ma_int64* pSrc, ma_uint64 count, float volume);
6056
MA_API void ma_copy_and_apply_volume_and_clip_samples_f32(float* pDst, const float* pSrc, ma_uint64 count, float volume);
6057
MA_API void ma_copy_and_apply_volume_and_clip_pcm_frames(void* pDst, const void* pSrc, ma_uint64 frameCount, ma_format format, ma_uint32 channels, float volume);
6058
 
6059
 
6060
/*
6061
Helper for converting a linear factor to gain in decibels.
6062
*/
6063
MA_API float ma_volume_linear_to_db(float factor);
6064
 
6065
/*
6066
Helper for converting gain in decibels to a linear factor.
6067
*/
6068
MA_API float ma_volume_db_to_linear(float gain);
6069
 
6070
 
6071
/*
6072
Mixes the specified number of frames in floating point format with a volume factor.
6073
 
6074
This will run on an optimized path when the volume is equal to 1.
6075
*/
6076
MA_API ma_result ma_mix_pcm_frames_f32(float* pDst, const float* pSrc, ma_uint64 frameCount, ma_uint32 channels, float volume);
6077
 
6078
 
6079
 
6080
 
6081
/************************************************************************************************************************************************************
6082
 
6083
VFS
6084
===
6085
 
6086
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
6087
appropriate for a given situation.
6088
 
6089
************************************************************************************************************************************************************/
6090
typedef void      ma_vfs;
6091
typedef ma_handle ma_vfs_file;
6092
 
6093
typedef enum
6094
{
6095
    MA_OPEN_MODE_READ  = 0x00000001,
6096
    MA_OPEN_MODE_WRITE = 0x00000002
6097
} ma_open_mode_flags;
6098
 
6099
typedef enum
6100
{
6101
    ma_seek_origin_start,
6102
    ma_seek_origin_current,
6103
    ma_seek_origin_end  /* Not used by decoders. */
6104
} ma_seek_origin;
6105
 
6106
typedef struct
6107
{
6108
    ma_uint64 sizeInBytes;
6109
} ma_file_info;
6110
 
6111
typedef struct
6112
{
6113
    ma_result (* onOpen) (ma_vfs* pVFS, const char* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile);
6114
    ma_result (* onOpenW)(ma_vfs* pVFS, const wchar_t* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile);
6115
    ma_result (* onClose)(ma_vfs* pVFS, ma_vfs_file file);
6116
    ma_result (* onRead) (ma_vfs* pVFS, ma_vfs_file file, void* pDst, size_t sizeInBytes, size_t* pBytesRead);
6117
    ma_result (* onWrite)(ma_vfs* pVFS, ma_vfs_file file, const void* pSrc, size_t sizeInBytes, size_t* pBytesWritten);
6118
    ma_result (* onSeek) (ma_vfs* pVFS, ma_vfs_file file, ma_int64 offset, ma_seek_origin origin);
6119
    ma_result (* onTell) (ma_vfs* pVFS, ma_vfs_file file, ma_int64* pCursor);
6120
    ma_result (* onInfo) (ma_vfs* pVFS, ma_vfs_file file, ma_file_info* pInfo);
6121
} ma_vfs_callbacks;
6122
 
6123
MA_API ma_result ma_vfs_open(ma_vfs* pVFS, const char* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile);
6124
MA_API ma_result ma_vfs_open_w(ma_vfs* pVFS, const wchar_t* pFilePath, ma_uint32 openMode, ma_vfs_file* pFile);
6125
MA_API ma_result ma_vfs_close(ma_vfs* pVFS, ma_vfs_file file);
6126
MA_API ma_result ma_vfs_read(ma_vfs* pVFS, ma_vfs_file file, void* pDst, size_t sizeInBytes, size_t* pBytesRead);
6127
MA_API ma_result ma_vfs_write(ma_vfs* pVFS, ma_vfs_file file, const void* pSrc, size_t sizeInBytes, size_t* pBytesWritten);
6128
MA_API ma_result ma_vfs_seek(ma_vfs* pVFS, ma_vfs_file file, ma_int64 offset, ma_seek_origin origin);
6129
MA_API ma_result ma_vfs_tell(ma_vfs* pVFS, ma_vfs_file file, ma_int64* pCursor);
6130
MA_API ma_result ma_vfs_info(ma_vfs* pVFS, ma_vfs_file file, ma_file_info* pInfo);
6131
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);
6132
 
6133
typedef struct
6134
{
6135
    ma_vfs_callbacks cb;
6136
    ma_allocation_callbacks allocationCallbacks;    /* Only used for the wchar_t version of open() on non-Windows platforms. */
6137
} ma_default_vfs;
6138
 
6139
MA_API ma_result ma_default_vfs_init(ma_default_vfs* pVFS, const ma_allocation_callbacks* pAllocationCallbacks);
6140
 
6141
 
6142
 
6143
typedef ma_result (* ma_read_proc)(void* pUserData, void* pBufferOut, size_t bytesToRead, size_t* pBytesRead);
6144
typedef ma_result (* ma_seek_proc)(void* pUserData, ma_int64 offset, ma_seek_origin origin);
6145
typedef ma_result (* ma_tell_proc)(void* pUserData, ma_int64* pCursor);
6146
 
6147
 
6148
 
6149
#if !defined(MA_NO_DECODING) || !defined(MA_NO_ENCODING)
6150
typedef enum
6151
{
6152
    ma_encoding_format_unknown = 0,
6153
    ma_encoding_format_wav,
6154
    ma_encoding_format_flac,
6155
    ma_encoding_format_mp3,
6156
    ma_encoding_format_vorbis
6157
} ma_encoding_format;
6158
#endif
6159
 
6160
/************************************************************************************************************************************************************
6161
 
6162
Decoding
6163
========
6164
 
6165
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
6166
you do your own synchronization.
6167
 
6168
************************************************************************************************************************************************************/
6169
#ifndef MA_NO_DECODING
6170
typedef struct ma_decoder ma_decoder;
6171
 
6172
 
6173
typedef struct
6174
{
6175
    ma_format preferredFormat;
6176
    ma_uint32 seekPointCount;   /* Set to > 0 to generate a seektable if the decoding backend supports it. */
6177
} ma_decoding_backend_config;
6178
 
6179
MA_API ma_decoding_backend_config ma_decoding_backend_config_init(ma_format preferredFormat, ma_uint32 seekPointCount);
6180
 
6181
 
6182
typedef struct
6183
{
6184
    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);
6185
    ma_result (* onInitFile  )(void* pUserData, const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend);               /* Optional. */
6186
    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. */
6187
    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. */
6188
    void      (* onUninit    )(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks);
6189
} ma_decoding_backend_vtable;
6190
 
6191
 
6192
typedef ma_result (* ma_decoder_read_proc)(ma_decoder* pDecoder, void* pBufferOut, size_t bytesToRead, size_t* pBytesRead);         /* Returns the number of bytes read. */
6193
typedef ma_result (* ma_decoder_seek_proc)(ma_decoder* pDecoder, ma_int64 byteOffset, ma_seek_origin origin);
6194
typedef ma_result (* ma_decoder_tell_proc)(ma_decoder* pDecoder, ma_int64* pCursor);
6195
 
6196
typedef struct
6197
{
6198
    ma_format format;      /* Set to 0 or ma_format_unknown to use the stream's internal format. */
6199
    ma_uint32 channels;    /* Set to 0 to use the stream's internal channels. */
6200
    ma_uint32 sampleRate;  /* Set to 0 to use the stream's internal sample rate. */
6201
    ma_channel* pChannelMap;
6202
    ma_channel_mix_mode channelMixMode;
6203
    ma_dither_mode ditherMode;
6204
    ma_resampler_config resampling;
6205
    ma_allocation_callbacks allocationCallbacks;
6206
    ma_encoding_format encodingFormat;
6207
    ma_uint32 seekPointCount;   /* When set to > 0, specifies the number of seek points to use for the generation of a seek table. Not all decoding backends support this. */
6208
    ma_decoding_backend_vtable** ppCustomBackendVTables;
6209
    ma_uint32 customBackendCount;
6210
    void* pCustomBackendUserData;
6211
} ma_decoder_config;
6212
 
6213
struct ma_decoder
6214
{
6215
    ma_data_source_base ds;
6216
    ma_data_source* pBackend;                   /* The decoding backend we'll be pulling data from. */
6217
    const ma_decoding_backend_vtable* pBackendVTable; /* The vtable for the decoding backend. This needs to be stored so we can access the onUninit() callback. */
6218
    void* pBackendUserData;
6219
    ma_decoder_read_proc onRead;
6220
    ma_decoder_seek_proc onSeek;
6221
    ma_decoder_tell_proc onTell;
6222
    void* pUserData;
6223
    ma_uint64 readPointerInPCMFrames;      /* In output sample rate. Used for keeping track of how many frames are available for decoding. */
6224
    ma_format outputFormat;
6225
    ma_uint32 outputChannels;
6226
    ma_uint32 outputSampleRate;
6227
    ma_data_converter converter;    /* Data conversion is achieved by running frames through this. */
6228
    void* pInputCache;              /* In input format. Can be null if it's not needed. */
6229
    ma_uint64 inputCacheCap;        /* The capacity of the input cache. */
6230
    ma_uint64 inputCacheConsumed;   /* The number of frames that have been consumed in the cache. Used for determining the next valid frame. */
6231
    ma_uint64 inputCacheRemaining;  /* The number of valid frames remaining in the cahce. */
6232
    ma_allocation_callbacks allocationCallbacks;
6233
    union
6234
    {
6235
        struct
6236
        {
6237
            ma_vfs* pVFS;
6238
            ma_vfs_file file;
6239
        } vfs;
6240
        struct
6241
        {
6242
            const ma_uint8* pData;
6243
            size_t dataSize;
6244
            size_t currentReadPos;
6245
        } memory;               /* Only used for decoders that were opened against a block of memory. */
6246
    } data;
6247
};
6248
 
6249
MA_API ma_decoder_config ma_decoder_config_init(ma_format outputFormat, ma_uint32 outputChannels, ma_uint32 outputSampleRate);
6250
MA_API ma_decoder_config ma_decoder_config_init_default(void);
6251
 
6252
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);
6253
MA_API ma_result ma_decoder_init_memory(const void* pData, size_t dataSize, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
6254
MA_API ma_result ma_decoder_init_vfs(ma_vfs* pVFS, const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
6255
MA_API ma_result ma_decoder_init_vfs_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
6256
MA_API ma_result ma_decoder_init_file(const char* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
6257
MA_API ma_result ma_decoder_init_file_w(const wchar_t* pFilePath, const ma_decoder_config* pConfig, ma_decoder* pDecoder);
6258
 
6259
/*
6260
Uninitializes a decoder.
6261
*/
6262
MA_API ma_result ma_decoder_uninit(ma_decoder* pDecoder);
6263
 
6264
/*
6265
Reads PCM frames from the given decoder.
6266
 
6267
This is not thread safe without your own synchronization.
6268
*/
6269
MA_API ma_result ma_decoder_read_pcm_frames(ma_decoder* pDecoder, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
6270
 
6271
/*
6272
Seeks to a PCM frame based on it's absolute index.
6273
 
6274
This is not thread safe without your own synchronization.
6275
*/
6276
MA_API ma_result ma_decoder_seek_to_pcm_frame(ma_decoder* pDecoder, ma_uint64 frameIndex);
6277
 
6278
/*
6279
Retrieves the decoder's output data format.
6280
*/
6281
MA_API ma_result ma_decoder_get_data_format(ma_decoder* pDecoder, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
6282
 
6283
/*
6284
Retrieves the current position of the read cursor in PCM frames.
6285
*/
6286
MA_API ma_result ma_decoder_get_cursor_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pCursor);
6287
 
6288
/*
6289
Retrieves the length of the decoder in PCM frames.
6290
 
6291
Do not call this on streams of an undefined length, such as internet radio.
6292
 
6293
If the length is unknown or an error occurs, 0 will be returned.
6294
 
6295
This will always return 0 for Vorbis decoders. This is due to a limitation with stb_vorbis in push mode which is what miniaudio
6296
uses internally.
6297
 
6298
For MP3's, this will decode the entire file. Do not call this in time critical scenarios.
6299
 
6300
This function is not thread safe without your own synchronization.
6301
*/
6302
MA_API ma_result ma_decoder_get_length_in_pcm_frames(ma_decoder* pDecoder, ma_uint64* pLength);
6303
 
6304
/*
6305
Retrieves the number of frames that can be read before reaching the end.
6306
 
6307
This calls `ma_decoder_get_length_in_pcm_frames()` so you need to be aware of the rules for that function, in
6308
particular ensuring you do not call it on streams of an undefined length, such as internet radio.
6309
 
6310
If the total length of the decoder cannot be retrieved, such as with Vorbis decoders, `MA_NOT_IMPLEMENTED` will be
6311
returned.
6312
*/
6313
MA_API ma_result ma_decoder_get_available_frames(ma_decoder* pDecoder, ma_uint64* pAvailableFrames);
6314
 
6315
/*
6316
Helper for opening and decoding a file into a heap allocated block of memory. Free the returned pointer with ma_free(). On input,
6317
pConfig should be set to what you want. On output it will be set to what you got.
6318
*/
6319
MA_API ma_result ma_decode_from_vfs(ma_vfs* pVFS, const char* pFilePath, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
6320
MA_API ma_result ma_decode_file(const char* pFilePath, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
6321
MA_API ma_result ma_decode_memory(const void* pData, size_t dataSize, ma_decoder_config* pConfig, ma_uint64* pFrameCountOut, void** ppPCMFramesOut);
6322
 
6323
#endif  /* MA_NO_DECODING */
6324
 
6325
 
6326
/************************************************************************************************************************************************************
6327
 
6328
Encoding
6329
========
6330
 
6331
Encoders do not perform any format conversion for you. If your target format does not support the format, and error will be returned.
6332
 
6333
************************************************************************************************************************************************************/
6334
#ifndef MA_NO_ENCODING
6335
typedef struct ma_encoder ma_encoder;
6336
 
6337
typedef ma_result (* ma_encoder_write_proc)           (ma_encoder* pEncoder, const void* pBufferIn, size_t bytesToWrite, size_t* pBytesWritten);
6338
typedef ma_result (* ma_encoder_seek_proc)            (ma_encoder* pEncoder, ma_int64 offset, ma_seek_origin origin);
6339
typedef ma_result (* ma_encoder_init_proc)            (ma_encoder* pEncoder);
6340
typedef void      (* ma_encoder_uninit_proc)          (ma_encoder* pEncoder);
6341
typedef ma_result (* ma_encoder_write_pcm_frames_proc)(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten);
6342
 
6343
typedef struct
6344
{
6345
    ma_encoding_format encodingFormat;
6346
    ma_format format;
6347
    ma_uint32 channels;
6348
    ma_uint32 sampleRate;
6349
    ma_allocation_callbacks allocationCallbacks;
6350
} ma_encoder_config;
6351
 
6352
MA_API ma_encoder_config ma_encoder_config_init(ma_encoding_format encodingFormat, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);
6353
 
6354
struct ma_encoder
6355
{
6356
    ma_encoder_config config;
6357
    ma_encoder_write_proc onWrite;
6358
    ma_encoder_seek_proc onSeek;
6359
    ma_encoder_init_proc onInit;
6360
    ma_encoder_uninit_proc onUninit;
6361
    ma_encoder_write_pcm_frames_proc onWritePCMFrames;
6362
    void* pUserData;
6363
    void* pInternalEncoder;
6364
    union
6365
    {
6366
        struct
6367
        {
6368
            ma_vfs* pVFS;
6369
            ma_vfs_file file;
6370
        } vfs;
6371
    } data;
6372
};
6373
 
6374
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);
6375
MA_API ma_result ma_encoder_init_vfs(ma_vfs* pVFS, const char* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
6376
MA_API ma_result ma_encoder_init_vfs_w(ma_vfs* pVFS, const wchar_t* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
6377
MA_API ma_result ma_encoder_init_file(const char* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
6378
MA_API ma_result ma_encoder_init_file_w(const wchar_t* pFilePath, const ma_encoder_config* pConfig, ma_encoder* pEncoder);
6379
MA_API void ma_encoder_uninit(ma_encoder* pEncoder);
6380
MA_API ma_result ma_encoder_write_pcm_frames(ma_encoder* pEncoder, const void* pFramesIn, ma_uint64 frameCount, ma_uint64* pFramesWritten);
6381
 
6382
#endif /* MA_NO_ENCODING */
6383
 
6384
 
6385
/************************************************************************************************************************************************************
6386
 
6387
Generation
6388
 
6389
************************************************************************************************************************************************************/
6390
#ifndef MA_NO_GENERATION
6391
typedef enum
6392
{
6393
    ma_waveform_type_sine,
6394
    ma_waveform_type_square,
6395
    ma_waveform_type_triangle,
6396
    ma_waveform_type_sawtooth
6397
} ma_waveform_type;
6398
 
6399
typedef struct
6400
{
6401
    ma_format format;
6402
    ma_uint32 channels;
6403
    ma_uint32 sampleRate;
6404
    ma_waveform_type type;
6405
    double amplitude;
6406
    double frequency;
6407
} ma_waveform_config;
6408
 
6409
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);
6410
 
6411
typedef struct
6412
{
6413
    ma_data_source_base ds;
6414
    ma_waveform_config config;
6415
    double advance;
6416
    double time;
6417
} ma_waveform;
6418
 
6419
MA_API ma_result ma_waveform_init(const ma_waveform_config* pConfig, ma_waveform* pWaveform);
6420
MA_API void ma_waveform_uninit(ma_waveform* pWaveform);
6421
MA_API ma_result ma_waveform_read_pcm_frames(ma_waveform* pWaveform, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
6422
MA_API ma_result ma_waveform_seek_to_pcm_frame(ma_waveform* pWaveform, ma_uint64 frameIndex);
6423
MA_API ma_result ma_waveform_set_amplitude(ma_waveform* pWaveform, double amplitude);
6424
MA_API ma_result ma_waveform_set_frequency(ma_waveform* pWaveform, double frequency);
6425
MA_API ma_result ma_waveform_set_type(ma_waveform* pWaveform, ma_waveform_type type);
6426
MA_API ma_result ma_waveform_set_sample_rate(ma_waveform* pWaveform, ma_uint32 sampleRate);
6427
 
6428
typedef struct
6429
{
6430
    ma_format format;
6431
    ma_uint32 channels;
6432
    ma_uint32 sampleRate;
6433
    double dutyCycle;
6434
    double amplitude;
6435
    double frequency;
6436
} ma_pulsewave_config;
6437
 
6438
MA_API ma_pulsewave_config ma_pulsewave_config_init(ma_format format, ma_uint32 channels, ma_uint32 sampleRate, double dutyCycle, double amplitude, double frequency);
6439
 
6440
typedef struct
6441
{
6442
    ma_waveform waveform;
6443
    ma_pulsewave_config config;
6444
} ma_pulsewave;
6445
 
6446
MA_API ma_result ma_pulsewave_init(const ma_pulsewave_config* pConfig, ma_pulsewave* pWaveform);
6447
MA_API void ma_pulsewave_uninit(ma_pulsewave* pWaveform);
6448
MA_API ma_result ma_pulsewave_read_pcm_frames(ma_pulsewave* pWaveform, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
6449
MA_API ma_result ma_pulsewave_seek_to_pcm_frame(ma_pulsewave* pWaveform, ma_uint64 frameIndex);
6450
MA_API ma_result ma_pulsewave_set_amplitude(ma_pulsewave* pWaveform, double amplitude);
6451
MA_API ma_result ma_pulsewave_set_frequency(ma_pulsewave* pWaveform, double frequency);
6452
MA_API ma_result ma_pulsewave_set_sample_rate(ma_pulsewave* pWaveform, ma_uint32 sampleRate);
6453
MA_API ma_result ma_pulsewave_set_duty_cycle(ma_pulsewave* pWaveform, double dutyCycle);
6454
 
6455
typedef enum
6456
{
6457
    ma_noise_type_white,
6458
    ma_noise_type_pink,
6459
    ma_noise_type_brownian
6460
} ma_noise_type;
6461
 
6462
 
6463
typedef struct
6464
{
6465
    ma_format format;
6466
    ma_uint32 channels;
6467
    ma_noise_type type;
6468
    ma_int32 seed;
6469
    double amplitude;
6470
    ma_bool32 duplicateChannels;
6471
} ma_noise_config;
6472
 
6473
MA_API ma_noise_config ma_noise_config_init(ma_format format, ma_uint32 channels, ma_noise_type type, ma_int32 seed, double amplitude);
6474
 
6475
typedef struct
6476
{
6477
    ma_data_source_base ds;
6478
    ma_noise_config config;
6479
    ma_lcg lcg;
6480
    union
6481
    {
6482
        struct
6483
        {
6484
            double** bin;
6485
            double* accumulation;
6486
            ma_uint32* counter;
6487
        } pink;
6488
        struct
6489
        {
6490
            double* accumulation;
6491
        } brownian;
6492
    } state;
6493
 
6494
    /* Memory management. */
6495
    void* _pHeap;
6496
    ma_bool32 _ownsHeap;
6497
} ma_noise;
6498
 
6499
MA_API ma_result ma_noise_get_heap_size(const ma_noise_config* pConfig, size_t* pHeapSizeInBytes);
6500
MA_API ma_result ma_noise_init_preallocated(const ma_noise_config* pConfig, void* pHeap, ma_noise* pNoise);
6501
MA_API ma_result ma_noise_init(const ma_noise_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_noise* pNoise);
6502
MA_API void ma_noise_uninit(ma_noise* pNoise, const ma_allocation_callbacks* pAllocationCallbacks);
6503
MA_API ma_result ma_noise_read_pcm_frames(ma_noise* pNoise, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
6504
MA_API ma_result ma_noise_set_amplitude(ma_noise* pNoise, double amplitude);
6505
MA_API ma_result ma_noise_set_seed(ma_noise* pNoise, ma_int32 seed);
6506
MA_API ma_result ma_noise_set_type(ma_noise* pNoise, ma_noise_type type);
6507
 
6508
#endif  /* MA_NO_GENERATION */
6509
 
6510
 
6511
 
6512
/************************************************************************************************************************************************************
6513
 
6514
Resource Manager
6515
 
6516
************************************************************************************************************************************************************/
6517
/* The resource manager cannot be enabled if there is no decoder. */
6518
#if !defined(MA_NO_RESOURCE_MANAGER) && defined(MA_NO_DECODING)
6519
#define MA_NO_RESOURCE_MANAGER
6520
#endif
6521
 
6522
#ifndef MA_NO_RESOURCE_MANAGER
6523
typedef struct ma_resource_manager                  ma_resource_manager;
6524
typedef struct ma_resource_manager_data_buffer_node ma_resource_manager_data_buffer_node;
6525
typedef struct ma_resource_manager_data_buffer      ma_resource_manager_data_buffer;
6526
typedef struct ma_resource_manager_data_stream      ma_resource_manager_data_stream;
6527
typedef struct ma_resource_manager_data_source      ma_resource_manager_data_source;
6528
 
6529
typedef enum
6530
{
6531
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM         = 0x00000001,   /* When set, does not load the entire data source in memory. Disk I/O will happen on job threads. */
6532
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE         = 0x00000002,   /* Decode data before storing in memory. When set, decoding is done at the resource manager level rather than the mixing thread. Results in faster mixing, but higher memory usage. */
6533
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC          = 0x00000004,   /* When set, the resource manager will load the data source asynchronously. */
6534
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT      = 0x00000008,   /* When set, waits for initialization of the underlying data source before returning from ma_resource_manager_data_source_init(). */
6535
    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH = 0x00000010    /* Gives the resource manager a hint that the length of the data source is unknown and calling `ma_data_source_get_length_in_pcm_frames()` should be avoided. */
6536
} ma_resource_manager_data_source_flags;
6537
 
6538
 
6539
/*
6540
Pipeline notifications used by the resource manager. Made up of both an async notification and a fence, both of which are optional.
6541
*/
6542
typedef struct
6543
{
6544
    ma_async_notification* pNotification;
6545
    ma_fence* pFence;
6546
} ma_resource_manager_pipeline_stage_notification;
6547
 
6548
typedef struct
6549
{
6550
    ma_resource_manager_pipeline_stage_notification init;    /* Initialization of the decoder. */
6551
    ma_resource_manager_pipeline_stage_notification done;    /* Decoding fully completed. */
6552
} ma_resource_manager_pipeline_notifications;
6553
 
6554
MA_API ma_resource_manager_pipeline_notifications ma_resource_manager_pipeline_notifications_init(void);
6555
 
6556
 
6557
 
6558
/* BEGIN BACKWARDS COMPATIBILITY */
6559
/* TODO: Remove this block in version 0.12. */
6560
#if 1
6561
#define ma_resource_manager_job                         ma_job
6562
#define ma_resource_manager_job_init                    ma_job_init
6563
#define MA_JOB_TYPE_RESOURCE_MANAGER_QUEUE_FLAG_NON_BLOCKING MA_JOB_QUEUE_FLAG_NON_BLOCKING
6564
#define ma_resource_manager_job_queue_config            ma_job_queue_config
6565
#define ma_resource_manager_job_queue_config_init       ma_job_queue_config_init
6566
#define ma_resource_manager_job_queue                   ma_job_queue
6567
#define ma_resource_manager_job_queue_get_heap_size     ma_job_queue_get_heap_size
6568
#define ma_resource_manager_job_queue_init_preallocated ma_job_queue_init_preallocated
6569
#define ma_resource_manager_job_queue_init              ma_job_queue_init
6570
#define ma_resource_manager_job_queue_uninit            ma_job_queue_uninit
6571
#define ma_resource_manager_job_queue_post              ma_job_queue_post
6572
#define ma_resource_manager_job_queue_next              ma_job_queue_next
6573
#endif
6574
/* END BACKWARDS COMPATIBILITY */
6575
 
6576
 
6577
 
6578
 
6579
/* Maximum job thread count will be restricted to this, but this may be removed later and replaced with a heap allocation thereby removing any limitation. */
6580
#ifndef MA_RESOURCE_MANAGER_MAX_JOB_THREAD_COUNT
6581
#define MA_RESOURCE_MANAGER_MAX_JOB_THREAD_COUNT    64
6582
#endif
6583
 
6584
typedef enum
6585
{
6586
    /* Indicates ma_resource_manager_next_job() should not block. Only valid when the job thread count is 0. */
6587
    MA_RESOURCE_MANAGER_FLAG_NON_BLOCKING = 0x00000001,
6588
 
6589
    /* Disables any kind of multithreading. Implicitly enables MA_RESOURCE_MANAGER_FLAG_NON_BLOCKING. */
6590
    MA_RESOURCE_MANAGER_FLAG_NO_THREADING = 0x00000002
6591
} ma_resource_manager_flags;
6592
 
6593
typedef struct
6594
{
6595
    const char* pFilePath;
6596
    const wchar_t* pFilePathW;
6597
    const ma_resource_manager_pipeline_notifications* pNotifications;
6598
    ma_uint64 initialSeekPointInPCMFrames;
6599
    ma_uint64 rangeBegInPCMFrames;
6600
    ma_uint64 rangeEndInPCMFrames;
6601
    ma_uint64 loopPointBegInPCMFrames;
6602
    ma_uint64 loopPointEndInPCMFrames;
6603
    ma_bool32 isLooping;
6604
    ma_uint32 flags;
6605
} ma_resource_manager_data_source_config;
6606
 
6607
MA_API ma_resource_manager_data_source_config ma_resource_manager_data_source_config_init(void);
6608
 
6609
 
6610
typedef enum
6611
{
6612
    ma_resource_manager_data_supply_type_unknown = 0,   /* Used for determining whether or the data supply has been initialized. */
6613
    ma_resource_manager_data_supply_type_encoded,       /* Data supply is an encoded buffer. Connector is ma_decoder. */
6614
    ma_resource_manager_data_supply_type_decoded,       /* Data supply is a decoded buffer. Connector is ma_audio_buffer. */
6615
    ma_resource_manager_data_supply_type_decoded_paged  /* Data supply is a linked list of decoded buffers. Connector is ma_paged_audio_buffer. */
6616
} ma_resource_manager_data_supply_type;
6617
 
6618
typedef struct
6619
{
6620
    MA_ATOMIC(4, ma_resource_manager_data_supply_type) type;    /* Read and written from different threads so needs to be accessed atomically. */
6621
    union
6622
    {
6623
        struct
6624
        {
6625
            const void* pData;
6626
            size_t sizeInBytes;
6627
        } encoded;
6628
        struct
6629
        {
6630
            const void* pData;
6631
            ma_uint64 totalFrameCount;
6632
            ma_uint64 decodedFrameCount;
6633
            ma_format format;
6634
            ma_uint32 channels;
6635
            ma_uint32 sampleRate;
6636
        } decoded;
6637
        struct
6638
        {
6639
            ma_paged_audio_buffer_data data;
6640
            ma_uint64 decodedFrameCount;
6641
            ma_uint32 sampleRate;
6642
        } decodedPaged;
6643
    } backend;
6644
} ma_resource_manager_data_supply;
6645
 
6646
struct ma_resource_manager_data_buffer_node
6647
{
6648
    ma_uint32 hashedName32;                         /* The hashed name. This is the key. */
6649
    ma_uint32 refCount;
6650
    MA_ATOMIC(4, ma_result) result;                 /* Result from asynchronous loading. When loading set to MA_BUSY. When fully loaded set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. */
6651
    MA_ATOMIC(4, ma_uint32) executionCounter;       /* For allocating execution orders for jobs. */
6652
    MA_ATOMIC(4, ma_uint32) executionPointer;       /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
6653
    ma_bool32 isDataOwnedByResourceManager;         /* Set to true when the underlying data buffer was allocated the resource manager. Set to false if it is owned by the application (via ma_resource_manager_register_*()). */
6654
    ma_resource_manager_data_supply data;
6655
    ma_resource_manager_data_buffer_node* pParent;
6656
    ma_resource_manager_data_buffer_node* pChildLo;
6657
    ma_resource_manager_data_buffer_node* pChildHi;
6658
};
6659
 
6660
struct ma_resource_manager_data_buffer
6661
{
6662
    ma_data_source_base ds;                         /* Base data source. A data buffer is a data source. */
6663
    ma_resource_manager* pResourceManager;          /* A pointer to the resource manager that owns this buffer. */
6664
    ma_resource_manager_data_buffer_node* pNode;    /* The data node. This is reference counted and is what supplies the data. */
6665
    ma_uint32 flags;                                /* The flags that were passed used to initialize the buffer. */
6666
    MA_ATOMIC(4, ma_uint32) executionCounter;       /* For allocating execution orders for jobs. */
6667
    MA_ATOMIC(4, ma_uint32) executionPointer;       /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
6668
    ma_uint64 seekTargetInPCMFrames;                /* Only updated by the public API. Never written nor read from the job thread. */
6669
    ma_bool32 seekToCursorOnNextRead;               /* On the next read we need to seek to the frame cursor. */
6670
    MA_ATOMIC(4, ma_result) result;                 /* Keeps track of a result of decoding. Set to MA_BUSY while the buffer is still loading. Set to MA_SUCCESS when loading is finished successfully. Otherwise set to some other code. */
6671
    MA_ATOMIC(4, ma_bool32) isLooping;              /* Can be read and written by different threads at the same time. Must be used atomically. */
6672
    ma_atomic_bool32 isConnectorInitialized;        /* Used for asynchronous loading to ensure we don't try to initialize the connector multiple times while waiting for the node to fully load. */
6673
    union
6674
    {
6675
        ma_decoder decoder;                 /* Supply type is ma_resource_manager_data_supply_type_encoded */
6676
        ma_audio_buffer buffer;             /* Supply type is ma_resource_manager_data_supply_type_decoded */
6677
        ma_paged_audio_buffer pagedBuffer;  /* Supply type is ma_resource_manager_data_supply_type_decoded_paged */
6678
    } connector;    /* Connects this object to the node's data supply. */
6679
};
6680
 
6681
struct ma_resource_manager_data_stream
6682
{
6683
    ma_data_source_base ds;                     /* Base data source. A data stream is a data source. */
6684
    ma_resource_manager* pResourceManager;      /* A pointer to the resource manager that owns this data stream. */
6685
    ma_uint32 flags;                            /* The flags that were passed used to initialize the stream. */
6686
    ma_decoder decoder;                         /* Used for filling pages with data. This is only ever accessed by the job thread. The public API should never touch this. */
6687
    ma_bool32 isDecoderInitialized;             /* Required for determining whether or not the decoder should be uninitialized in MA_JOB_TYPE_RESOURCE_MANAGER_FREE_DATA_STREAM. */
6688
    ma_uint64 totalLengthInPCMFrames;           /* This is calculated when first loaded by the MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_STREAM. */
6689
    ma_uint32 relativeCursor;                   /* The playback cursor, relative to the current page. Only ever accessed by the public API. Never accessed by the job thread. */
6690
    MA_ATOMIC(8, ma_uint64) absoluteCursor;     /* The playback cursor, in absolute position starting from the start of the file. */
6691
    ma_uint32 currentPageIndex;                 /* Toggles between 0 and 1. Index 0 is the first half of pPageData. Index 1 is the second half. Only ever accessed by the public API. Never accessed by the job thread. */
6692
    MA_ATOMIC(4, ma_uint32) executionCounter;   /* For allocating execution orders for jobs. */
6693
    MA_ATOMIC(4, ma_uint32) executionPointer;   /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
6694
 
6695
    /* Written by the public API, read by the job thread. */
6696
    MA_ATOMIC(4, ma_bool32) isLooping;          /* Whether or not the stream is looping. It's important to set the looping flag at the data stream level for smooth loop transitions. */
6697
 
6698
    /* Written by the job thread, read by the public API. */
6699
    void* pPageData;                            /* Buffer containing the decoded data of each page. Allocated once at initialization time. */
6700
    MA_ATOMIC(4, ma_uint32) pageFrameCount[2];  /* The number of valid PCM frames in each page. Used to determine the last valid frame. */
6701
 
6702
    /* Written and read by both the public API and the job thread. These must be atomic. */
6703
    MA_ATOMIC(4, ma_result) result;             /* Result from asynchronous loading. When loading set to MA_BUSY. When initialized set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. If an error occurs when loading, set to an error code. */
6704
    MA_ATOMIC(4, ma_bool32) isDecoderAtEnd;     /* Whether or not the decoder has reached the end. */
6705
    MA_ATOMIC(4, ma_bool32) isPageValid[2];     /* Booleans to indicate whether or not a page is valid. Set to false by the public API, set to true by the job thread. Set to false as the pages are consumed, true when they are filled. */
6706
    MA_ATOMIC(4, ma_bool32) seekCounter;        /* When 0, no seeking is being performed. When > 0, a seek is being performed and reading should be delayed with MA_BUSY. */
6707
};
6708
 
6709
struct ma_resource_manager_data_source
6710
{
6711
    union
6712
    {
6713
        ma_resource_manager_data_buffer buffer;
6714
        ma_resource_manager_data_stream stream;
6715
    } backend;  /* Must be the first item because we need the first item to be the data source callbacks for the buffer or stream. */
6716
 
6717
    ma_uint32 flags;                          /* The flags that were passed in to ma_resource_manager_data_source_init(). */
6718
    MA_ATOMIC(4, ma_uint32) executionCounter;     /* For allocating execution orders for jobs. */
6719
    MA_ATOMIC(4, ma_uint32) executionPointer;     /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
6720
};
6721
 
6722
typedef struct
6723
{
6724
    ma_allocation_callbacks allocationCallbacks;
6725
    ma_log* pLog;
6726
    ma_format decodedFormat;        /* The decoded format to use. Set to ma_format_unknown (default) to use the file's native format. */
6727
    ma_uint32 decodedChannels;      /* The decoded channel count to use. Set to 0 (default) to use the file's native channel count. */
6728
    ma_uint32 decodedSampleRate;    /* the decoded sample rate to use. Set to 0 (default) to use the file's native sample rate. */
6729
    ma_uint32 jobThreadCount;       /* Set to 0 if you want to self-manage your job threads. Defaults to 1. */
6730
    size_t jobThreadStackSize;
6731
    ma_uint32 jobQueueCapacity;     /* The maximum number of jobs that can fit in the queue at a time. Defaults to MA_JOB_TYPE_RESOURCE_MANAGER_QUEUE_CAPACITY. Cannot be zero. */
6732
    ma_uint32 flags;
6733
    ma_vfs* pVFS;                   /* Can be NULL in which case defaults will be used. */
6734
    ma_decoding_backend_vtable** ppCustomDecodingBackendVTables;
6735
    ma_uint32 customDecodingBackendCount;
6736
    void* pCustomDecodingBackendUserData;
6737
} ma_resource_manager_config;
6738
 
6739
MA_API ma_resource_manager_config ma_resource_manager_config_init(void);
6740
 
6741
struct ma_resource_manager
6742
{
6743
    ma_resource_manager_config config;
6744
    ma_resource_manager_data_buffer_node* pRootDataBufferNode;      /* The root buffer in the binary tree. */
6745
#ifndef MA_NO_THREADING
6746
    ma_mutex dataBufferBSTLock;                                     /* For synchronizing access to the data buffer binary tree. */
6747
    ma_thread jobThreads[MA_RESOURCE_MANAGER_MAX_JOB_THREAD_COUNT]; /* The threads for executing jobs. */
6748
#endif
6749
    ma_job_queue jobQueue;                                          /* Multi-consumer, multi-producer job queue for managing jobs for asynchronous decoding and streaming. */
6750
    ma_default_vfs defaultVFS;                                      /* Only used if a custom VFS is not specified. */
6751
    ma_log log;                                                     /* Only used if no log was specified in the config. */
6752
};
6753
 
6754
/* Init. */
6755
MA_API ma_result ma_resource_manager_init(const ma_resource_manager_config* pConfig, ma_resource_manager* pResourceManager);
6756
MA_API void ma_resource_manager_uninit(ma_resource_manager* pResourceManager);
6757
MA_API ma_log* ma_resource_manager_get_log(ma_resource_manager* pResourceManager);
6758
 
6759
/* Registration. */
6760
MA_API ma_result ma_resource_manager_register_file(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags);
6761
MA_API ma_result ma_resource_manager_register_file_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags);
6762
MA_API ma_result ma_resource_manager_register_decoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);  /* Does not copy. Increments the reference count if already exists and returns MA_SUCCESS. */
6763
MA_API ma_result ma_resource_manager_register_decoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, ma_uint64 frameCount, ma_format format, ma_uint32 channels, ma_uint32 sampleRate);
6764
MA_API ma_result ma_resource_manager_register_encoded_data(ma_resource_manager* pResourceManager, const char* pName, const void* pData, size_t sizeInBytes);    /* Does not copy. Increments the reference count if already exists and returns MA_SUCCESS. */
6765
MA_API ma_result ma_resource_manager_register_encoded_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName, const void* pData, size_t sizeInBytes);
6766
MA_API ma_result ma_resource_manager_unregister_file(ma_resource_manager* pResourceManager, const char* pFilePath);
6767
MA_API ma_result ma_resource_manager_unregister_file_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath);
6768
MA_API ma_result ma_resource_manager_unregister_data(ma_resource_manager* pResourceManager, const char* pName);
6769
MA_API ma_result ma_resource_manager_unregister_data_w(ma_resource_manager* pResourceManager, const wchar_t* pName);
6770
 
6771
/* Data Buffers. */
6772
MA_API ma_result ma_resource_manager_data_buffer_init_ex(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source_config* pConfig, ma_resource_manager_data_buffer* pDataBuffer);
6773
MA_API ma_result ma_resource_manager_data_buffer_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_buffer* pDataBuffer);
6774
MA_API ma_result ma_resource_manager_data_buffer_init_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_buffer* pDataBuffer);
6775
MA_API ma_result ma_resource_manager_data_buffer_init_copy(ma_resource_manager* pResourceManager, const ma_resource_manager_data_buffer* pExistingDataBuffer, ma_resource_manager_data_buffer* pDataBuffer);
6776
MA_API ma_result ma_resource_manager_data_buffer_uninit(ma_resource_manager_data_buffer* pDataBuffer);
6777
MA_API ma_result ma_resource_manager_data_buffer_read_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
6778
MA_API ma_result ma_resource_manager_data_buffer_seek_to_pcm_frame(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64 frameIndex);
6779
MA_API ma_result ma_resource_manager_data_buffer_get_data_format(ma_resource_manager_data_buffer* pDataBuffer, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
6780
MA_API ma_result ma_resource_manager_data_buffer_get_cursor_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pCursor);
6781
MA_API ma_result ma_resource_manager_data_buffer_get_length_in_pcm_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pLength);
6782
MA_API ma_result ma_resource_manager_data_buffer_result(const ma_resource_manager_data_buffer* pDataBuffer);
6783
MA_API ma_result ma_resource_manager_data_buffer_set_looping(ma_resource_manager_data_buffer* pDataBuffer, ma_bool32 isLooping);
6784
MA_API ma_bool32 ma_resource_manager_data_buffer_is_looping(const ma_resource_manager_data_buffer* pDataBuffer);
6785
MA_API ma_result ma_resource_manager_data_buffer_get_available_frames(ma_resource_manager_data_buffer* pDataBuffer, ma_uint64* pAvailableFrames);
6786
 
6787
/* Data Streams. */
6788
MA_API ma_result ma_resource_manager_data_stream_init_ex(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source_config* pConfig, ma_resource_manager_data_stream* pDataStream);
6789
MA_API ma_result ma_resource_manager_data_stream_init(ma_resource_manager* pResourceManager, const char* pFilePath, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_stream* pDataStream);
6790
MA_API ma_result ma_resource_manager_data_stream_init_w(ma_resource_manager* pResourceManager, const wchar_t* pFilePath, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_stream* pDataStream);
6791
MA_API ma_result ma_resource_manager_data_stream_uninit(ma_resource_manager_data_stream* pDataStream);
6792
MA_API ma_result ma_resource_manager_data_stream_read_pcm_frames(ma_resource_manager_data_stream* pDataStream, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
6793
MA_API ma_result ma_resource_manager_data_stream_seek_to_pcm_frame(ma_resource_manager_data_stream* pDataStream, ma_uint64 frameIndex);
6794
MA_API ma_result ma_resource_manager_data_stream_get_data_format(ma_resource_manager_data_stream* pDataStream, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
6795
MA_API ma_result ma_resource_manager_data_stream_get_cursor_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pCursor);
6796
MA_API ma_result ma_resource_manager_data_stream_get_length_in_pcm_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pLength);
6797
MA_API ma_result ma_resource_manager_data_stream_result(const ma_resource_manager_data_stream* pDataStream);
6798
MA_API ma_result ma_resource_manager_data_stream_set_looping(ma_resource_manager_data_stream* pDataStream, ma_bool32 isLooping);
6799
MA_API ma_bool32 ma_resource_manager_data_stream_is_looping(const ma_resource_manager_data_stream* pDataStream);
6800
MA_API ma_result ma_resource_manager_data_stream_get_available_frames(ma_resource_manager_data_stream* pDataStream, ma_uint64* pAvailableFrames);
6801
 
6802
/* Data Sources. */
6803
MA_API ma_result ma_resource_manager_data_source_init_ex(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source_config* pConfig, ma_resource_manager_data_source* pDataSource);
6804
MA_API ma_result ma_resource_manager_data_source_init(ma_resource_manager* pResourceManager, const char* pName, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_source* pDataSource);
6805
MA_API ma_result ma_resource_manager_data_source_init_w(ma_resource_manager* pResourceManager, const wchar_t* pName, ma_uint32 flags, const ma_resource_manager_pipeline_notifications* pNotifications, ma_resource_manager_data_source* pDataSource);
6806
MA_API ma_result ma_resource_manager_data_source_init_copy(ma_resource_manager* pResourceManager, const ma_resource_manager_data_source* pExistingDataSource, ma_resource_manager_data_source* pDataSource);
6807
MA_API ma_result ma_resource_manager_data_source_uninit(ma_resource_manager_data_source* pDataSource);
6808
MA_API ma_result ma_resource_manager_data_source_read_pcm_frames(ma_resource_manager_data_source* pDataSource, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
6809
MA_API ma_result ma_resource_manager_data_source_seek_to_pcm_frame(ma_resource_manager_data_source* pDataSource, ma_uint64 frameIndex);
6810
MA_API ma_result ma_resource_manager_data_source_get_data_format(ma_resource_manager_data_source* pDataSource, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
6811
MA_API ma_result ma_resource_manager_data_source_get_cursor_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pCursor);
6812
MA_API ma_result ma_resource_manager_data_source_get_length_in_pcm_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pLength);
6813
MA_API ma_result ma_resource_manager_data_source_result(const ma_resource_manager_data_source* pDataSource);
6814
MA_API ma_result ma_resource_manager_data_source_set_looping(ma_resource_manager_data_source* pDataSource, ma_bool32 isLooping);
6815
MA_API ma_bool32 ma_resource_manager_data_source_is_looping(const ma_resource_manager_data_source* pDataSource);
6816
MA_API ma_result ma_resource_manager_data_source_get_available_frames(ma_resource_manager_data_source* pDataSource, ma_uint64* pAvailableFrames);
6817
 
6818
/* Job management. */
6819
MA_API ma_result ma_resource_manager_post_job(ma_resource_manager* pResourceManager, const ma_job* pJob);
6820
MA_API ma_result ma_resource_manager_post_job_quit(ma_resource_manager* pResourceManager);  /* Helper for posting a quit job. */
6821
MA_API ma_result ma_resource_manager_next_job(ma_resource_manager* pResourceManager, ma_job* pJob);
6822
MA_API ma_result ma_resource_manager_process_job(ma_resource_manager* pResourceManager, ma_job* pJob);  /* DEPRECATED. Use ma_job_process(). Will be removed in version 0.12. */
6823
MA_API ma_result ma_resource_manager_process_next_job(ma_resource_manager* pResourceManager);   /* Returns MA_CANCELLED if a MA_JOB_TYPE_QUIT job is found. In non-blocking mode, returns MA_NO_DATA_AVAILABLE if no jobs are available. */
6824
#endif  /* MA_NO_RESOURCE_MANAGER */
6825
 
6826
 
6827
 
6828
/************************************************************************************************************************************************************
6829
 
6830
Node Graph
6831
 
6832
************************************************************************************************************************************************************/
6833
#ifndef MA_NO_NODE_GRAPH
6834
/* Must never exceed 254. */
6835
#ifndef MA_MAX_NODE_BUS_COUNT
6836
#define MA_MAX_NODE_BUS_COUNT       254
6837
#endif
6838
 
6839
/* Used internally by miniaudio for memory management. Must never exceed MA_MAX_NODE_BUS_COUNT. */
6840
#ifndef MA_MAX_NODE_LOCAL_BUS_COUNT
6841
#define MA_MAX_NODE_LOCAL_BUS_COUNT 2
6842
#endif
6843
 
6844
/* Use this when the bus count is determined by the node instance rather than the vtable. */
6845
#define MA_NODE_BUS_COUNT_UNKNOWN   255
6846
 
6847
typedef struct ma_node_graph ma_node_graph;
6848
typedef void ma_node;
6849
 
6850
 
6851
/* Node flags. */
6852
typedef enum
6853
{
6854
    MA_NODE_FLAG_PASSTHROUGH                = 0x00000001,
6855
    MA_NODE_FLAG_CONTINUOUS_PROCESSING      = 0x00000002,
6856
    MA_NODE_FLAG_ALLOW_NULL_INPUT           = 0x00000004,
6857
    MA_NODE_FLAG_DIFFERENT_PROCESSING_RATES = 0x00000008,
6858
    MA_NODE_FLAG_SILENT_OUTPUT              = 0x00000010
6859
} ma_node_flags;
6860
 
6861
 
6862
/* The playback state of a node. Either started or stopped. */
6863
typedef enum
6864
{
6865
    ma_node_state_started = 0,
6866
    ma_node_state_stopped = 1
6867
} ma_node_state;
6868
 
6869
 
6870
typedef struct
6871
{
6872
    /*
6873
    Extended processing callback. This callback is used for effects that process input and output
6874
    at different rates (i.e. they perform resampling). This is similar to the simple version, only
6875
    they take two separate frame counts: one for input, and one for output.
6876
 
6877
    On input, `pFrameCountOut` is equal to the capacity of the output buffer for each bus, whereas
6878
    `pFrameCountIn` will be equal to the number of PCM frames in each of the buffers in `ppFramesIn`.
6879
 
6880
    On output, set `pFrameCountOut` to the number of PCM frames that were actually output and set
6881
    `pFrameCountIn` to the number of input frames that were consumed.
6882
    */
6883
    void (* onProcess)(ma_node* pNode, const float** ppFramesIn, ma_uint32* pFrameCountIn, float** ppFramesOut, ma_uint32* pFrameCountOut);
6884
 
6885
    /*
6886
    A callback for retrieving the number of a input frames that are required to output the
6887
    specified number of output frames. You would only want to implement this when the node performs
6888
    resampling. This is optional, even for nodes that perform resampling, but it does offer a
6889
    small reduction in latency as it allows miniaudio to calculate the exact number of input frames
6890
    to read at a time instead of having to estimate.
6891
    */
6892
    ma_result (* onGetRequiredInputFrameCount)(ma_node* pNode, ma_uint32 outputFrameCount, ma_uint32* pInputFrameCount);
6893
 
6894
    /*
6895
    The number of input buses. This is how many sub-buffers will be contained in the `ppFramesIn`
6896
    parameters of the callbacks above.
6897
    */
6898
    ma_uint8 inputBusCount;
6899
 
6900
    /*
6901
    The number of output buses. This is how many sub-buffers will be contained in the `ppFramesOut`
6902
    parameters of the callbacks above.
6903
    */
6904
    ma_uint8 outputBusCount;
6905
 
6906
    /*
6907
    Flags describing characteristics of the node. This is currently just a placeholder for some
6908
    ideas for later on.
6909
    */
6910
    ma_uint32 flags;
6911
} ma_node_vtable;
6912
 
6913
typedef struct
6914
{
6915
    const ma_node_vtable* vtable;       /* Should never be null. Initialization of the node will fail if so. */
6916
    ma_node_state initialState;         /* Defaults to ma_node_state_started. */
6917
    ma_uint32 inputBusCount;            /* Only used if the vtable specifies an input bus count of `MA_NODE_BUS_COUNT_UNKNOWN`, otherwise must be set to `MA_NODE_BUS_COUNT_UNKNOWN` (default). */
6918
    ma_uint32 outputBusCount;           /* Only used if the vtable specifies an output bus count of `MA_NODE_BUS_COUNT_UNKNOWN`, otherwise  be set to `MA_NODE_BUS_COUNT_UNKNOWN` (default). */
6919
    const ma_uint32* pInputChannels;    /* The number of elements are determined by the input bus count as determined by the vtable, or `inputBusCount` if the vtable specifies `MA_NODE_BUS_COUNT_UNKNOWN`. */
6920
    const ma_uint32* pOutputChannels;   /* The number of elements are determined by the output bus count as determined by the vtable, or `outputBusCount` if the vtable specifies `MA_NODE_BUS_COUNT_UNKNOWN`. */
6921
} ma_node_config;
6922
 
6923
MA_API ma_node_config ma_node_config_init(void);
6924
 
6925
 
6926
/*
6927
A node has multiple output buses. An output bus is attached to an input bus as an item in a linked
6928
list. Think of the input bus as a linked list, with the output bus being an item in that list.
6929
*/
6930
typedef struct ma_node_output_bus ma_node_output_bus;
6931
struct ma_node_output_bus
6932
{
6933
    /* Immutable. */
6934
    ma_node* pNode;                                         /* The node that owns this output bus. The input node. Will be null for dummy head and tail nodes. */
6935
    ma_uint8 outputBusIndex;                                /* The index of the output bus on pNode that this output bus represents. */
6936
    ma_uint8 channels;                                      /* The number of channels in the audio stream for this bus. */
6937
 
6938
    /* Mutable via multiple threads. Must be used atomically. The weird ordering here is for packing reasons. */
6939
    ma_uint8 inputNodeInputBusIndex;                        /* The index of the input bus on the input. Required for detaching. Will only be used within the spinlock so does not need to be atomic. */
6940
    MA_ATOMIC(4, ma_uint32) flags;                          /* Some state flags for tracking the read state of the output buffer. A combination of MA_NODE_OUTPUT_BUS_FLAG_*. */
6941
    MA_ATOMIC(4, ma_uint32) refCount;                       /* Reference count for some thread-safety when detaching. */
6942
    MA_ATOMIC(4, ma_bool32) isAttached;                     /* This is used to prevent iteration of nodes that are in the middle of being detached. Used for thread safety. */
6943
    MA_ATOMIC(4, ma_spinlock) lock;                         /* Unfortunate lock, but significantly simplifies the implementation. Required for thread-safe attaching and detaching. */
6944
    MA_ATOMIC(4, float) volume;                             /* Linear. */
6945
    MA_ATOMIC(MA_SIZEOF_PTR, ma_node_output_bus*) pNext;    /* If null, it's the tail node or detached. */
6946
    MA_ATOMIC(MA_SIZEOF_PTR, ma_node_output_bus*) pPrev;    /* If null, it's the head node or detached. */
6947
    MA_ATOMIC(MA_SIZEOF_PTR, ma_node*) pInputNode;          /* The node that this output bus is attached to. Required for detaching. */
6948
};
6949
 
6950
/*
6951
A node has multiple input buses. The output buses of a node are connecting to the input busses of
6952
another. An input bus is essentially just a linked list of output buses.
6953
*/
6954
typedef struct ma_node_input_bus ma_node_input_bus;
6955
struct ma_node_input_bus
6956
{
6957
    /* Mutable via multiple threads. */
6958
    ma_node_output_bus head;                /* Dummy head node for simplifying some lock-free thread-safety stuff. */
6959
    MA_ATOMIC(4, ma_uint32) nextCounter;    /* This is used to determine whether or not the input bus is finding the next node in the list. Used for thread safety when detaching output buses. */
6960
    MA_ATOMIC(4, ma_spinlock) lock;         /* Unfortunate lock, but significantly simplifies the implementation. Required for thread-safe attaching and detaching. */
6961
 
6962
    /* Set once at startup. */
6963
    ma_uint8 channels;                      /* The number of channels in the audio stream for this bus. */
6964
};
6965
 
6966
 
6967
typedef struct ma_node_base ma_node_base;
6968
struct ma_node_base
6969
{
6970
    /* These variables are set once at startup. */
6971
    ma_node_graph* pNodeGraph;              /* The graph this node belongs to. */
6972
    const ma_node_vtable* vtable;
6973
    float* pCachedData;                     /* Allocated on the heap. Fixed size. Needs to be stored on the heap because reading from output buses is done in separate function calls. */
6974
    ma_uint16 cachedDataCapInFramesPerBus;  /* The capacity of the input data cache in frames, per bus. */
6975
 
6976
    /* These variables are read and written only from the audio thread. */
6977
    ma_uint16 cachedFrameCountOut;
6978
    ma_uint16 cachedFrameCountIn;
6979
    ma_uint16 consumedFrameCountIn;
6980
 
6981
    /* These variables are read and written between different threads. */
6982
    MA_ATOMIC(4, ma_node_state) state;      /* When set to stopped, nothing will be read, regardless of the times in stateTimes. */
6983
    MA_ATOMIC(8, ma_uint64) stateTimes[2];  /* Indexed by ma_node_state. Specifies the time based on the global clock that a node should be considered to be in the relevant state. */
6984
    MA_ATOMIC(8, ma_uint64) localTime;      /* The node's local clock. This is just a running sum of the number of output frames that have been processed. Can be modified by any thread with `ma_node_set_time()`. */
6985
    ma_uint32 inputBusCount;
6986
    ma_uint32 outputBusCount;
6987
    ma_node_input_bus* pInputBuses;
6988
    ma_node_output_bus* pOutputBuses;
6989
 
6990
    /* Memory management. */
6991
    ma_node_input_bus _inputBuses[MA_MAX_NODE_LOCAL_BUS_COUNT];
6992
    ma_node_output_bus _outputBuses[MA_MAX_NODE_LOCAL_BUS_COUNT];
6993
    void* _pHeap;   /* A heap allocation for internal use only. pInputBuses and/or pOutputBuses will point to this if the bus count exceeds MA_MAX_NODE_LOCAL_BUS_COUNT. */
6994
    ma_bool32 _ownsHeap;    /* If set to true, the node owns the heap allocation and _pHeap will be freed in ma_node_uninit(). */
6995
};
6996
 
6997
MA_API ma_result ma_node_get_heap_size(ma_node_graph* pNodeGraph, const ma_node_config* pConfig, size_t* pHeapSizeInBytes);
6998
MA_API ma_result ma_node_init_preallocated(ma_node_graph* pNodeGraph, const ma_node_config* pConfig, void* pHeap, ma_node* pNode);
6999
MA_API ma_result ma_node_init(ma_node_graph* pNodeGraph, const ma_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_node* pNode);
7000
MA_API void ma_node_uninit(ma_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7001
MA_API ma_node_graph* ma_node_get_node_graph(const ma_node* pNode);
7002
MA_API ma_uint32 ma_node_get_input_bus_count(const ma_node* pNode);
7003
MA_API ma_uint32 ma_node_get_output_bus_count(const ma_node* pNode);
7004
MA_API ma_uint32 ma_node_get_input_channels(const ma_node* pNode, ma_uint32 inputBusIndex);
7005
MA_API ma_uint32 ma_node_get_output_channels(const ma_node* pNode, ma_uint32 outputBusIndex);
7006
MA_API ma_result ma_node_attach_output_bus(ma_node* pNode, ma_uint32 outputBusIndex, ma_node* pOtherNode, ma_uint32 otherNodeInputBusIndex);
7007
MA_API ma_result ma_node_detach_output_bus(ma_node* pNode, ma_uint32 outputBusIndex);
7008
MA_API ma_result ma_node_detach_all_output_buses(ma_node* pNode);
7009
MA_API ma_result ma_node_set_output_bus_volume(ma_node* pNode, ma_uint32 outputBusIndex, float volume);
7010
MA_API float ma_node_get_output_bus_volume(const ma_node* pNode, ma_uint32 outputBusIndex);
7011
MA_API ma_result ma_node_set_state(ma_node* pNode, ma_node_state state);
7012
MA_API ma_node_state ma_node_get_state(const ma_node* pNode);
7013
MA_API ma_result ma_node_set_state_time(ma_node* pNode, ma_node_state state, ma_uint64 globalTime);
7014
MA_API ma_uint64 ma_node_get_state_time(const ma_node* pNode, ma_node_state state);
7015
MA_API ma_node_state ma_node_get_state_by_time(const ma_node* pNode, ma_uint64 globalTime);
7016
MA_API ma_node_state ma_node_get_state_by_time_range(const ma_node* pNode, ma_uint64 globalTimeBeg, ma_uint64 globalTimeEnd);
7017
MA_API ma_uint64 ma_node_get_time(const ma_node* pNode);
7018
MA_API ma_result ma_node_set_time(ma_node* pNode, ma_uint64 localTime);
7019
 
7020
 
7021
typedef struct
7022
{
7023
    ma_uint32 channels;
7024
    ma_uint16 nodeCacheCapInFrames;
7025
} ma_node_graph_config;
7026
 
7027
MA_API ma_node_graph_config ma_node_graph_config_init(ma_uint32 channels);
7028
 
7029
 
7030
struct ma_node_graph
7031
{
7032
    /* Immutable. */
7033
    ma_node_base base;                  /* The node graph itself is a node so it can be connected as an input to different node graph. This has zero inputs and calls ma_node_graph_read_pcm_frames() to generate it's output. */
7034
    ma_node_base endpoint;              /* Special node that all nodes eventually connect to. Data is read from this node in ma_node_graph_read_pcm_frames(). */
7035
    ma_uint16 nodeCacheCapInFrames;
7036
 
7037
    /* Read and written by multiple threads. */
7038
    MA_ATOMIC(4, ma_bool32) isReading;
7039
};
7040
 
7041
MA_API ma_result ma_node_graph_init(const ma_node_graph_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_node_graph* pNodeGraph);
7042
MA_API void ma_node_graph_uninit(ma_node_graph* pNodeGraph, const ma_allocation_callbacks* pAllocationCallbacks);
7043
MA_API ma_node* ma_node_graph_get_endpoint(ma_node_graph* pNodeGraph);
7044
MA_API ma_result ma_node_graph_read_pcm_frames(ma_node_graph* pNodeGraph, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
7045
MA_API ma_uint32 ma_node_graph_get_channels(const ma_node_graph* pNodeGraph);
7046
MA_API ma_uint64 ma_node_graph_get_time(const ma_node_graph* pNodeGraph);
7047
MA_API ma_result ma_node_graph_set_time(ma_node_graph* pNodeGraph, ma_uint64 globalTime);
7048
 
7049
 
7050
 
7051
/* Data source node. 0 input buses, 1 output bus. Used for reading from a data source. */
7052
typedef struct
7053
{
7054
    ma_node_config nodeConfig;
7055
    ma_data_source* pDataSource;
7056
} ma_data_source_node_config;
7057
 
7058
MA_API ma_data_source_node_config ma_data_source_node_config_init(ma_data_source* pDataSource);
7059
 
7060
 
7061
typedef struct
7062
{
7063
    ma_node_base base;
7064
    ma_data_source* pDataSource;
7065
} ma_data_source_node;
7066
 
7067
MA_API ma_result ma_data_source_node_init(ma_node_graph* pNodeGraph, const ma_data_source_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source_node* pDataSourceNode);
7068
MA_API void ma_data_source_node_uninit(ma_data_source_node* pDataSourceNode, const ma_allocation_callbacks* pAllocationCallbacks);
7069
MA_API ma_result ma_data_source_node_set_looping(ma_data_source_node* pDataSourceNode, ma_bool32 isLooping);
7070
MA_API ma_bool32 ma_data_source_node_is_looping(ma_data_source_node* pDataSourceNode);
7071
 
7072
 
7073
/* Splitter Node. 1 input, many outputs. Used for splitting/copying a stream so it can be as input into two separate output nodes. */
7074
typedef struct
7075
{
7076
    ma_node_config nodeConfig;
7077
    ma_uint32 channels;
7078
    ma_uint32 outputBusCount;
7079
} ma_splitter_node_config;
7080
 
7081
MA_API ma_splitter_node_config ma_splitter_node_config_init(ma_uint32 channels);
7082
 
7083
 
7084
typedef struct
7085
{
7086
    ma_node_base base;
7087
} ma_splitter_node;
7088
 
7089
MA_API ma_result ma_splitter_node_init(ma_node_graph* pNodeGraph, const ma_splitter_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_splitter_node* pSplitterNode);
7090
MA_API void ma_splitter_node_uninit(ma_splitter_node* pSplitterNode, const ma_allocation_callbacks* pAllocationCallbacks);
7091
 
7092
 
7093
/*
7094
Biquad Node
7095
*/
7096
typedef struct
7097
{
7098
    ma_node_config nodeConfig;
7099
    ma_biquad_config biquad;
7100
} ma_biquad_node_config;
7101
 
7102
MA_API ma_biquad_node_config ma_biquad_node_config_init(ma_uint32 channels, float b0, float b1, float b2, float a0, float a1, float a2);
7103
 
7104
 
7105
typedef struct
7106
{
7107
    ma_node_base baseNode;
7108
    ma_biquad biquad;
7109
} ma_biquad_node;
7110
 
7111
MA_API ma_result ma_biquad_node_init(ma_node_graph* pNodeGraph, const ma_biquad_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_biquad_node* pNode);
7112
MA_API ma_result ma_biquad_node_reinit(const ma_biquad_config* pConfig, ma_biquad_node* pNode);
7113
MA_API void ma_biquad_node_uninit(ma_biquad_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7114
 
7115
 
7116
/*
7117
Low Pass Filter Node
7118
*/
7119
typedef struct
7120
{
7121
    ma_node_config nodeConfig;
7122
    ma_lpf_config lpf;
7123
} ma_lpf_node_config;
7124
 
7125
MA_API ma_lpf_node_config ma_lpf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
7126
 
7127
 
7128
typedef struct
7129
{
7130
    ma_node_base baseNode;
7131
    ma_lpf lpf;
7132
} ma_lpf_node;
7133
 
7134
MA_API ma_result ma_lpf_node_init(ma_node_graph* pNodeGraph, const ma_lpf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_lpf_node* pNode);
7135
MA_API ma_result ma_lpf_node_reinit(const ma_lpf_config* pConfig, ma_lpf_node* pNode);
7136
MA_API void ma_lpf_node_uninit(ma_lpf_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7137
 
7138
 
7139
/*
7140
High Pass Filter Node
7141
*/
7142
typedef struct
7143
{
7144
    ma_node_config nodeConfig;
7145
    ma_hpf_config hpf;
7146
} ma_hpf_node_config;
7147
 
7148
MA_API ma_hpf_node_config ma_hpf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
7149
 
7150
 
7151
typedef struct
7152
{
7153
    ma_node_base baseNode;
7154
    ma_hpf hpf;
7155
} ma_hpf_node;
7156
 
7157
MA_API ma_result ma_hpf_node_init(ma_node_graph* pNodeGraph, const ma_hpf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hpf_node* pNode);
7158
MA_API ma_result ma_hpf_node_reinit(const ma_hpf_config* pConfig, ma_hpf_node* pNode);
7159
MA_API void ma_hpf_node_uninit(ma_hpf_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7160
 
7161
 
7162
/*
7163
Band Pass Filter Node
7164
*/
7165
typedef struct
7166
{
7167
    ma_node_config nodeConfig;
7168
    ma_bpf_config bpf;
7169
} ma_bpf_node_config;
7170
 
7171
MA_API ma_bpf_node_config ma_bpf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double cutoffFrequency, ma_uint32 order);
7172
 
7173
 
7174
typedef struct
7175
{
7176
    ma_node_base baseNode;
7177
    ma_bpf bpf;
7178
} ma_bpf_node;
7179
 
7180
MA_API ma_result ma_bpf_node_init(ma_node_graph* pNodeGraph, const ma_bpf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_bpf_node* pNode);
7181
MA_API ma_result ma_bpf_node_reinit(const ma_bpf_config* pConfig, ma_bpf_node* pNode);
7182
MA_API void ma_bpf_node_uninit(ma_bpf_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7183
 
7184
 
7185
/*
7186
Notching Filter Node
7187
*/
7188
typedef struct
7189
{
7190
    ma_node_config nodeConfig;
7191
    ma_notch_config notch;
7192
} ma_notch_node_config;
7193
 
7194
MA_API ma_notch_node_config ma_notch_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double q, double frequency);
7195
 
7196
 
7197
typedef struct
7198
{
7199
    ma_node_base baseNode;
7200
    ma_notch2 notch;
7201
} ma_notch_node;
7202
 
7203
MA_API ma_result ma_notch_node_init(ma_node_graph* pNodeGraph, const ma_notch_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_notch_node* pNode);
7204
MA_API ma_result ma_notch_node_reinit(const ma_notch_config* pConfig, ma_notch_node* pNode);
7205
MA_API void ma_notch_node_uninit(ma_notch_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7206
 
7207
 
7208
/*
7209
Peaking Filter Node
7210
*/
7211
typedef struct
7212
{
7213
    ma_node_config nodeConfig;
7214
    ma_peak_config peak;
7215
} ma_peak_node_config;
7216
 
7217
MA_API ma_peak_node_config ma_peak_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency);
7218
 
7219
 
7220
typedef struct
7221
{
7222
    ma_node_base baseNode;
7223
    ma_peak2 peak;
7224
} ma_peak_node;
7225
 
7226
MA_API ma_result ma_peak_node_init(ma_node_graph* pNodeGraph, const ma_peak_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_peak_node* pNode);
7227
MA_API ma_result ma_peak_node_reinit(const ma_peak_config* pConfig, ma_peak_node* pNode);
7228
MA_API void ma_peak_node_uninit(ma_peak_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7229
 
7230
 
7231
/*
7232
Low Shelf Filter Node
7233
*/
7234
typedef struct
7235
{
7236
    ma_node_config nodeConfig;
7237
    ma_loshelf_config loshelf;
7238
} ma_loshelf_node_config;
7239
 
7240
MA_API ma_loshelf_node_config ma_loshelf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency);
7241
 
7242
 
7243
typedef struct
7244
{
7245
    ma_node_base baseNode;
7246
    ma_loshelf2 loshelf;
7247
} ma_loshelf_node;
7248
 
7249
MA_API ma_result ma_loshelf_node_init(ma_node_graph* pNodeGraph, const ma_loshelf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_loshelf_node* pNode);
7250
MA_API ma_result ma_loshelf_node_reinit(const ma_loshelf_config* pConfig, ma_loshelf_node* pNode);
7251
MA_API void ma_loshelf_node_uninit(ma_loshelf_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7252
 
7253
 
7254
/*
7255
High Shelf Filter Node
7256
*/
7257
typedef struct
7258
{
7259
    ma_node_config nodeConfig;
7260
    ma_hishelf_config hishelf;
7261
} ma_hishelf_node_config;
7262
 
7263
MA_API ma_hishelf_node_config ma_hishelf_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, double gainDB, double q, double frequency);
7264
 
7265
 
7266
typedef struct
7267
{
7268
    ma_node_base baseNode;
7269
    ma_hishelf2 hishelf;
7270
} ma_hishelf_node;
7271
 
7272
MA_API ma_result ma_hishelf_node_init(ma_node_graph* pNodeGraph, const ma_hishelf_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_hishelf_node* pNode);
7273
MA_API ma_result ma_hishelf_node_reinit(const ma_hishelf_config* pConfig, ma_hishelf_node* pNode);
7274
MA_API void ma_hishelf_node_uninit(ma_hishelf_node* pNode, const ma_allocation_callbacks* pAllocationCallbacks);
7275
 
7276
 
7277
typedef struct
7278
{
7279
    ma_node_config nodeConfig;
7280
    ma_delay_config delay;
7281
} ma_delay_node_config;
7282
 
7283
MA_API ma_delay_node_config ma_delay_node_config_init(ma_uint32 channels, ma_uint32 sampleRate, ma_uint32 delayInFrames, float decay);
7284
 
7285
 
7286
typedef struct
7287
{
7288
    ma_node_base baseNode;
7289
    ma_delay delay;
7290
} ma_delay_node;
7291
 
7292
MA_API ma_result ma_delay_node_init(ma_node_graph* pNodeGraph, const ma_delay_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_delay_node* pDelayNode);
7293
MA_API void ma_delay_node_uninit(ma_delay_node* pDelayNode, const ma_allocation_callbacks* pAllocationCallbacks);
7294
MA_API void ma_delay_node_set_wet(ma_delay_node* pDelayNode, float value);
7295
MA_API float ma_delay_node_get_wet(const ma_delay_node* pDelayNode);
7296
MA_API void ma_delay_node_set_dry(ma_delay_node* pDelayNode, float value);
7297
MA_API float ma_delay_node_get_dry(const ma_delay_node* pDelayNode);
7298
MA_API void ma_delay_node_set_decay(ma_delay_node* pDelayNode, float value);
7299
MA_API float ma_delay_node_get_decay(const ma_delay_node* pDelayNode);
7300
#endif  /* MA_NO_NODE_GRAPH */
7301
 
7302
 
7303
/* SECTION: miniaudio_engine.h */
7304
/************************************************************************************************************************************************************
7305
 
7306
Engine
7307
 
7308
************************************************************************************************************************************************************/
7309
#if !defined(MA_NO_ENGINE) && !defined(MA_NO_NODE_GRAPH)
7310
typedef struct ma_engine ma_engine;
7311
typedef struct ma_sound  ma_sound;
7312
 
7313
 
7314
/* Sound flags. */
7315
typedef enum
7316
{
7317
    /* Resource manager flags. */
7318
    MA_SOUND_FLAG_STREAM                = 0x00000001,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM */
7319
    MA_SOUND_FLAG_DECODE                = 0x00000002,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE */
7320
    MA_SOUND_FLAG_ASYNC                 = 0x00000004,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC */
7321
    MA_SOUND_FLAG_WAIT_INIT             = 0x00000008,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT */
7322
    MA_SOUND_FLAG_UNKNOWN_LENGTH        = 0x00000010,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH */
7323
 
7324
    /* ma_sound specific flags. */
7325
    MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT = 0x00001000,   /* Do not attach to the endpoint by default. Useful for when setting up nodes in a complex graph system. */
7326
    MA_SOUND_FLAG_NO_PITCH              = 0x00002000,   /* Disable pitch shifting with ma_sound_set_pitch() and ma_sound_group_set_pitch(). This is an optimization. */
7327
    MA_SOUND_FLAG_NO_SPATIALIZATION     = 0x00004000    /* Disable spatialization. */
7328
} ma_sound_flags;
7329
 
7330
#ifndef MA_ENGINE_MAX_LISTENERS
7331
#define MA_ENGINE_MAX_LISTENERS             4
7332
#endif
7333
 
7334
#define MA_LISTENER_INDEX_CLOSEST           ((ma_uint8)-1)
7335
 
7336
typedef enum
7337
{
7338
    ma_engine_node_type_sound,
7339
    ma_engine_node_type_group
7340
} ma_engine_node_type;
7341
 
7342
typedef struct
7343
{
7344
    ma_engine* pEngine;
7345
    ma_engine_node_type type;
7346
    ma_uint32 channelsIn;
7347
    ma_uint32 channelsOut;
7348
    ma_uint32 sampleRate;               /* Only used when the type is set to ma_engine_node_type_sound. */
7349
    ma_uint32 volumeSmoothTimeInPCMFrames;  /* The number of frames to smooth over volume changes. Defaults to 0 in which case no smoothing is used. */
7350
    ma_mono_expansion_mode monoExpansionMode;
7351
    ma_bool8 isPitchDisabled;           /* Pitching can be explicitly disabled with MA_SOUND_FLAG_NO_PITCH to optimize processing. */
7352
    ma_bool8 isSpatializationDisabled;  /* Spatialization can be explicitly disabled with MA_SOUND_FLAG_NO_SPATIALIZATION. */
7353
    ma_uint8 pinnedListenerIndex;       /* The index of the listener this node should always use for spatialization. If set to MA_LISTENER_INDEX_CLOSEST the engine will use the closest listener. */
7354
} ma_engine_node_config;
7355
 
7356
MA_API ma_engine_node_config ma_engine_node_config_init(ma_engine* pEngine, ma_engine_node_type type, ma_uint32 flags);
7357
 
7358
 
7359
/* Base node object for both ma_sound and ma_sound_group. */
7360
typedef struct
7361
{
7362
    ma_node_base baseNode;                              /* Must be the first member for compatiblity with the ma_node API. */
7363
    ma_engine* pEngine;                                 /* A pointer to the engine. Set based on the value from the config. */
7364
    ma_uint32 sampleRate;                               /* The sample rate of the input data. For sounds backed by a data source, this will be the data source's sample rate. Otherwise it'll be the engine's sample rate. */
7365
    ma_uint32 volumeSmoothTimeInPCMFrames;
7366
    ma_mono_expansion_mode monoExpansionMode;
7367
    ma_fader fader;
7368
    ma_linear_resampler resampler;                      /* For pitch shift. */
7369
    ma_spatializer spatializer;
7370
    ma_panner panner;
7371
    ma_gainer volumeGainer;                             /* This will only be used if volumeSmoothTimeInPCMFrames is > 0. */
7372
    ma_atomic_float volume;                             /* Defaults to 1. */
7373
    MA_ATOMIC(4, float) pitch;
7374
    float oldPitch;                                     /* For determining whether or not the resampler needs to be updated to reflect the new pitch. The resampler will be updated on the mixing thread. */
7375
    float oldDopplerPitch;                              /* For determining whether or not the resampler needs to be updated to take a new doppler pitch into account. */
7376
    MA_ATOMIC(4, ma_bool32) isPitchDisabled;            /* When set to true, pitching will be disabled which will allow the resampler to be bypassed to save some computation. */
7377
    MA_ATOMIC(4, ma_bool32) isSpatializationDisabled;   /* Set to false by default. When set to false, will not have spatialisation applied. */
7378
    MA_ATOMIC(4, ma_uint32) pinnedListenerIndex;        /* The index of the listener this node should always use for spatialization. If set to MA_LISTENER_INDEX_CLOSEST the engine will use the closest listener. */
7379
 
7380
    /* When setting a fade, it's not done immediately in ma_sound_set_fade(). It's deferred to the audio thread which means we need to store the settings here. */
7381
    struct
7382
    {
7383
        ma_atomic_float volumeBeg;
7384
        ma_atomic_float volumeEnd;
7385
        ma_atomic_uint64 fadeLengthInFrames;            /* <-- Defaults to (~(ma_uint64)0) which is used to indicate that no fade should be applied. */
7386
        ma_atomic_uint64 absoluteGlobalTimeInFrames;    /* <-- The time to start the fade. */
7387
    } fadeSettings;
7388
 
7389
    /* Memory management. */
7390
    ma_bool8 _ownsHeap;
7391
    void* _pHeap;
7392
} ma_engine_node;
7393
 
7394
MA_API ma_result ma_engine_node_get_heap_size(const ma_engine_node_config* pConfig, size_t* pHeapSizeInBytes);
7395
MA_API ma_result ma_engine_node_init_preallocated(const ma_engine_node_config* pConfig, void* pHeap, ma_engine_node* pEngineNode);
7396
MA_API ma_result ma_engine_node_init(const ma_engine_node_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_engine_node* pEngineNode);
7397
MA_API void ma_engine_node_uninit(ma_engine_node* pEngineNode, const ma_allocation_callbacks* pAllocationCallbacks);
7398
 
7399
 
7400
#define MA_SOUND_SOURCE_CHANNEL_COUNT   0xFFFFFFFF
7401
 
7402
/* Callback for when a sound reaches the end. */
7403
typedef void (* ma_sound_end_proc)(void* pUserData, ma_sound* pSound);
7404
 
7405
typedef struct
7406
{
7407
    const char* pFilePath;                      /* Set this to load from the resource manager. */
7408
    const wchar_t* pFilePathW;                  /* Set this to load from the resource manager. */
7409
    ma_data_source* pDataSource;                /* Set this to load from an existing data source. */
7410
    ma_node* pInitialAttachment;                /* If set, the sound will be attached to an input of this node. This can be set to a ma_sound. If set to NULL, the sound will be attached directly to the endpoint unless MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT is set in `flags`. */
7411
    ma_uint32 initialAttachmentInputBusIndex;   /* The index of the input bus of pInitialAttachment to attach the sound to. */
7412
    ma_uint32 channelsIn;                       /* Ignored if using a data source as input (the data source's channel count will be used always). Otherwise, setting to 0 will cause the engine's channel count to be used. */
7413
    ma_uint32 channelsOut;                      /* Set this to 0 (default) to use the engine's channel count. Set to MA_SOUND_SOURCE_CHANNEL_COUNT to use the data source's channel count (only used if using a data source as input). */
7414
    ma_mono_expansion_mode monoExpansionMode;   /* Controls how the mono channel should be expanded to other channels when spatialization is disabled on a sound. */
7415
    ma_uint32 flags;                            /* A combination of MA_SOUND_FLAG_* flags. */
7416
    ma_uint32 volumeSmoothTimeInPCMFrames;      /* The number of frames to smooth over volume changes. Defaults to 0 in which case no smoothing is used. */
7417
    ma_uint64 initialSeekPointInPCMFrames;      /* Initializes the sound such that it's seeked to this location by default. */
7418
    ma_uint64 rangeBegInPCMFrames;
7419
    ma_uint64 rangeEndInPCMFrames;
7420
    ma_uint64 loopPointBegInPCMFrames;
7421
    ma_uint64 loopPointEndInPCMFrames;
7422
    ma_bool32 isLooping;
7423
    ma_sound_end_proc endCallback;              /* Fired when the sound reaches the end. Will be fired from the audio thread. Do not restart, uninitialize or otherwise change the state of the sound from here. Instead fire an event or set a variable to indicate to a different thread to change the start of the sound. Will not be fired in response to a scheduled stop with ma_sound_set_stop_time_*(). */
7424
    void* pEndCallbackUserData;
7425
#ifndef MA_NO_RESOURCE_MANAGER
7426
    ma_resource_manager_pipeline_notifications initNotifications;
7427
#endif
7428
    ma_fence* pDoneFence;                       /* Deprecated. Use initNotifications instead. Released when the resource manager has finished decoding the entire sound. Not used with streams. */
7429
} ma_sound_config;
7430
 
7431
MA_API ma_sound_config ma_sound_config_init(void);                  /* Deprecated. Will be removed in version 0.12. Use ma_sound_config_2() instead. */
7432
MA_API ma_sound_config ma_sound_config_init_2(ma_engine* pEngine);  /* Will be renamed to ma_sound_config_init() in version 0.12. */
7433
 
7434
struct ma_sound
7435
{
7436
    ma_engine_node engineNode;          /* Must be the first member for compatibility with the ma_node API. */
7437
    ma_data_source* pDataSource;
7438
    MA_ATOMIC(8, ma_uint64) seekTarget; /* The PCM frame index to seek to in the mixing thread. Set to (~(ma_uint64)0) to not perform any seeking. */
7439
    MA_ATOMIC(4, ma_bool32) atEnd;
7440
    ma_sound_end_proc endCallback;
7441
    void* pEndCallbackUserData;
7442
    ma_bool8 ownsDataSource;
7443
 
7444
    /*
7445
    We're declaring a resource manager data source object here to save us a malloc when loading a
7446
    sound via the resource manager, which I *think* will be the most common scenario.
7447
    */
7448
#ifndef MA_NO_RESOURCE_MANAGER
7449
    ma_resource_manager_data_source* pResourceManagerDataSource;
7450
#endif
7451
};
7452
 
7453
/* Structure specifically for sounds played with ma_engine_play_sound(). Making this a separate structure to reduce overhead. */
7454
typedef struct ma_sound_inlined ma_sound_inlined;
7455
struct ma_sound_inlined
7456
{
7457
    ma_sound sound;
7458
    ma_sound_inlined* pNext;
7459
    ma_sound_inlined* pPrev;
7460
};
7461
 
7462
/* A sound group is just a sound. */
7463
typedef ma_sound_config ma_sound_group_config;
7464
typedef ma_sound        ma_sound_group;
7465
 
7466
MA_API ma_sound_group_config ma_sound_group_config_init(void);                  /* Deprecated. Will be removed in version 0.12. Use ma_sound_config_2() instead. */
7467
MA_API ma_sound_group_config ma_sound_group_config_init_2(ma_engine* pEngine);  /* Will be renamed to ma_sound_config_init() in version 0.12. */
7468
 
7469
typedef void (* ma_engine_process_proc)(void* pUserData, float* pFramesOut, ma_uint64 frameCount);
7470
 
7471
typedef struct
7472
{
7473
#if !defined(MA_NO_RESOURCE_MANAGER)
7474
    ma_resource_manager* pResourceManager;          /* Can be null in which case a resource manager will be created for you. */
7475
#endif
7476
#if !defined(MA_NO_DEVICE_IO)
7477
    ma_context* pContext;
7478
    ma_device* pDevice;                             /* If set, the caller is responsible for calling ma_engine_data_callback() in the device's data callback. */
7479
    ma_device_id* pPlaybackDeviceID;                /* The ID of the playback device to use with the default listener. */
7480
    ma_device_data_proc dataCallback;               /* Can be null. Can be used to provide a custom device data callback. */
7481
    ma_device_notification_proc notificationCallback;
7482
#endif
7483
    ma_log* pLog;                                   /* When set to NULL, will use the context's log. */
7484
    ma_uint32 listenerCount;                        /* Must be between 1 and MA_ENGINE_MAX_LISTENERS. */
7485
    ma_uint32 channels;                             /* The number of channels to use when mixing and spatializing. When set to 0, will use the native channel count of the device. */
7486
    ma_uint32 sampleRate;                           /* The sample rate. When set to 0 will use the native channel count of the device. */
7487
    ma_uint32 periodSizeInFrames;                   /* If set to something other than 0, updates will always be exactly this size. The underlying device may be a different size, but from the perspective of the mixer that won't matter.*/
7488
    ma_uint32 periodSizeInMilliseconds;             /* Used if periodSizeInFrames is unset. */
7489
    ma_uint32 gainSmoothTimeInFrames;               /* The number of frames to interpolate the gain of spatialized sounds across. If set to 0, will use gainSmoothTimeInMilliseconds. */
7490
    ma_uint32 gainSmoothTimeInMilliseconds;         /* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
7491
    ma_uint32 defaultVolumeSmoothTimeInPCMFrames;   /* Defaults to 0. Controls the default amount of smoothing to apply to volume changes to sounds. High values means more smoothing at the expense of high latency (will take longer to reach the new volume). */
7492
    ma_allocation_callbacks allocationCallbacks;
7493
    ma_bool32 noAutoStart;                          /* When set to true, requires an explicit call to ma_engine_start(). This is false by default, meaning the engine will be started automatically in ma_engine_init(). */
7494
    ma_bool32 noDevice;                             /* When set to true, don't create a default device. ma_engine_read_pcm_frames() can be called manually to read data. */
7495
    ma_mono_expansion_mode monoExpansionMode;       /* Controls how the mono channel should be expanded to other channels when spatialization is disabled on a sound. */
7496
    ma_vfs* pResourceManagerVFS;                    /* A pointer to a pre-allocated VFS object to use with the resource manager. This is ignored if pResourceManager is not NULL. */
7497
    ma_engine_process_proc onProcess;               /* Fired at the end of each call to ma_engine_read_pcm_frames(). For engine's that manage their own internal device (the default configuration), this will be fired from the audio thread, and you do not need to call ma_engine_read_pcm_frames() manually in order to trigger this. */
7498
    void* pProcessUserData;                         /* User data that's passed into onProcess. */
7499
} ma_engine_config;
7500
 
7501
MA_API ma_engine_config ma_engine_config_init(void);
7502
 
7503
 
7504
struct ma_engine
7505
{
7506
    ma_node_graph nodeGraph;                /* An engine is a node graph. It should be able to be plugged into any ma_node_graph API (with a cast) which means this must be the first member of this struct. */
7507
#if !defined(MA_NO_RESOURCE_MANAGER)
7508
    ma_resource_manager* pResourceManager;
7509
#endif
7510
#if !defined(MA_NO_DEVICE_IO)
7511
    ma_device* pDevice;                     /* Optionally set via the config, otherwise allocated by the engine in ma_engine_init(). */
7512
#endif
7513
    ma_log* pLog;
7514
    ma_uint32 sampleRate;
7515
    ma_uint32 listenerCount;
7516
    ma_spatializer_listener listeners[MA_ENGINE_MAX_LISTENERS];
7517
    ma_allocation_callbacks allocationCallbacks;
7518
    ma_bool8 ownsResourceManager;
7519
    ma_bool8 ownsDevice;
7520
    ma_spinlock inlinedSoundLock;               /* For synchronizing access so the inlined sound list. */
7521
    ma_sound_inlined* pInlinedSoundHead;        /* The first inlined sound. Inlined sounds are tracked in a linked list. */
7522
    MA_ATOMIC(4, ma_uint32) inlinedSoundCount;  /* The total number of allocated inlined sound objects. Used for debugging. */
7523
    ma_uint32 gainSmoothTimeInFrames;           /* The number of frames to interpolate the gain of spatialized sounds across. */
7524
    ma_uint32 defaultVolumeSmoothTimeInPCMFrames;
7525
    ma_mono_expansion_mode monoExpansionMode;
7526
    ma_engine_process_proc onProcess;
7527
    void* pProcessUserData;
7528
};
7529
 
7530
MA_API ma_result ma_engine_init(const ma_engine_config* pConfig, ma_engine* pEngine);
7531
MA_API void ma_engine_uninit(ma_engine* pEngine);
7532
MA_API ma_result ma_engine_read_pcm_frames(ma_engine* pEngine, void* pFramesOut, ma_uint64 frameCount, ma_uint64* pFramesRead);
7533
MA_API ma_node_graph* ma_engine_get_node_graph(ma_engine* pEngine);
7534
#if !defined(MA_NO_RESOURCE_MANAGER)
7535
MA_API ma_resource_manager* ma_engine_get_resource_manager(ma_engine* pEngine);
7536
#endif
7537
MA_API ma_device* ma_engine_get_device(ma_engine* pEngine);
7538
MA_API ma_log* ma_engine_get_log(ma_engine* pEngine);
7539
MA_API ma_node* ma_engine_get_endpoint(ma_engine* pEngine);
7540
MA_API ma_uint64 ma_engine_get_time_in_pcm_frames(const ma_engine* pEngine);
7541
MA_API ma_uint64 ma_engine_get_time_in_milliseconds(const ma_engine* pEngine);
7542
MA_API ma_result ma_engine_set_time_in_pcm_frames(ma_engine* pEngine, ma_uint64 globalTime);
7543
MA_API ma_result ma_engine_set_time_in_milliseconds(ma_engine* pEngine, ma_uint64 globalTime);
7544
MA_API ma_uint64 ma_engine_get_time(const ma_engine* pEngine);                  /* Deprecated. Use ma_engine_get_time_in_pcm_frames(). Will be removed in version 0.12. */
7545
MA_API ma_result ma_engine_set_time(ma_engine* pEngine, ma_uint64 globalTime);  /* Deprecated. Use ma_engine_set_time_in_pcm_frames(). Will be removed in version 0.12. */
7546
MA_API ma_uint32 ma_engine_get_channels(const ma_engine* pEngine);
7547
MA_API ma_uint32 ma_engine_get_sample_rate(const ma_engine* pEngine);
7548
 
7549
MA_API ma_result ma_engine_start(ma_engine* pEngine);
7550
MA_API ma_result ma_engine_stop(ma_engine* pEngine);
7551
MA_API ma_result ma_engine_set_volume(ma_engine* pEngine, float volume);
7552
MA_API float ma_engine_get_volume(ma_engine* pEngine);
7553
MA_API ma_result ma_engine_set_gain_db(ma_engine* pEngine, float gainDB);
7554
MA_API float ma_engine_get_gain_db(ma_engine* pEngine);
7555
 
7556
MA_API ma_uint32 ma_engine_get_listener_count(const ma_engine* pEngine);
7557
MA_API ma_uint32 ma_engine_find_closest_listener(const ma_engine* pEngine, float absolutePosX, float absolutePosY, float absolutePosZ);
7558
MA_API void ma_engine_listener_set_position(ma_engine* pEngine, ma_uint32 listenerIndex, float x, float y, float z);
7559
MA_API ma_vec3f ma_engine_listener_get_position(const ma_engine* pEngine, ma_uint32 listenerIndex);
7560
MA_API void ma_engine_listener_set_direction(ma_engine* pEngine, ma_uint32 listenerIndex, float x, float y, float z);
7561
MA_API ma_vec3f ma_engine_listener_get_direction(const ma_engine* pEngine, ma_uint32 listenerIndex);
7562
MA_API void ma_engine_listener_set_velocity(ma_engine* pEngine, ma_uint32 listenerIndex, float x, float y, float z);
7563
MA_API ma_vec3f ma_engine_listener_get_velocity(const ma_engine* pEngine, ma_uint32 listenerIndex);
7564
MA_API void ma_engine_listener_set_cone(ma_engine* pEngine, ma_uint32 listenerIndex, float innerAngleInRadians, float outerAngleInRadians, float outerGain);
7565
MA_API void ma_engine_listener_get_cone(const ma_engine* pEngine, ma_uint32 listenerIndex, float* pInnerAngleInRadians, float* pOuterAngleInRadians, float* pOuterGain);
7566
MA_API void ma_engine_listener_set_world_up(ma_engine* pEngine, ma_uint32 listenerIndex, float x, float y, float z);
7567
MA_API ma_vec3f ma_engine_listener_get_world_up(const ma_engine* pEngine, ma_uint32 listenerIndex);
7568
MA_API void ma_engine_listener_set_enabled(ma_engine* pEngine, ma_uint32 listenerIndex, ma_bool32 isEnabled);
7569
MA_API ma_bool32 ma_engine_listener_is_enabled(const ma_engine* pEngine, ma_uint32 listenerIndex);
7570
 
7571
#ifndef MA_NO_RESOURCE_MANAGER
7572
MA_API ma_result ma_engine_play_sound_ex(ma_engine* pEngine, const char* pFilePath, ma_node* pNode, ma_uint32 nodeInputBusIndex);
7573
MA_API ma_result ma_engine_play_sound(ma_engine* pEngine, const char* pFilePath, ma_sound_group* pGroup);   /* Fire and forget. */
7574
#endif
7575
 
7576
#ifndef MA_NO_RESOURCE_MANAGER
7577
MA_API ma_result ma_sound_init_from_file(ma_engine* pEngine, const char* pFilePath, ma_uint32 flags, ma_sound_group* pGroup, ma_fence* pDoneFence, ma_sound* pSound);
7578
MA_API ma_result ma_sound_init_from_file_w(ma_engine* pEngine, const wchar_t* pFilePath, ma_uint32 flags, ma_sound_group* pGroup, ma_fence* pDoneFence, ma_sound* pSound);
7579
MA_API ma_result ma_sound_init_copy(ma_engine* pEngine, const ma_sound* pExistingSound, ma_uint32 flags, ma_sound_group* pGroup, ma_sound* pSound);
7580
#endif
7581
MA_API ma_result ma_sound_init_from_data_source(ma_engine* pEngine, ma_data_source* pDataSource, ma_uint32 flags, ma_sound_group* pGroup, ma_sound* pSound);
7582
MA_API ma_result ma_sound_init_ex(ma_engine* pEngine, const ma_sound_config* pConfig, ma_sound* pSound);
7583
MA_API void ma_sound_uninit(ma_sound* pSound);
7584
MA_API ma_engine* ma_sound_get_engine(const ma_sound* pSound);
7585
MA_API ma_data_source* ma_sound_get_data_source(const ma_sound* pSound);
7586
MA_API ma_result ma_sound_start(ma_sound* pSound);
7587
MA_API ma_result ma_sound_stop(ma_sound* pSound);
7588
MA_API ma_result ma_sound_stop_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 fadeLengthInFrames);     /* Will overwrite any scheduled stop and fade. */
7589
MA_API ma_result ma_sound_stop_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 fadeLengthInFrames);   /* Will overwrite any scheduled stop and fade. */
7590
MA_API void ma_sound_set_volume(ma_sound* pSound, float volume);
7591
MA_API float ma_sound_get_volume(const ma_sound* pSound);
7592
MA_API void ma_sound_set_pan(ma_sound* pSound, float pan);
7593
MA_API float ma_sound_get_pan(const ma_sound* pSound);
7594
MA_API void ma_sound_set_pan_mode(ma_sound* pSound, ma_pan_mode panMode);
7595
MA_API ma_pan_mode ma_sound_get_pan_mode(const ma_sound* pSound);
7596
MA_API void ma_sound_set_pitch(ma_sound* pSound, float pitch);
7597
MA_API float ma_sound_get_pitch(const ma_sound* pSound);
7598
MA_API void ma_sound_set_spatialization_enabled(ma_sound* pSound, ma_bool32 enabled);
7599
MA_API ma_bool32 ma_sound_is_spatialization_enabled(const ma_sound* pSound);
7600
MA_API void ma_sound_set_pinned_listener_index(ma_sound* pSound, ma_uint32 listenerIndex);
7601
MA_API ma_uint32 ma_sound_get_pinned_listener_index(const ma_sound* pSound);
7602
MA_API ma_uint32 ma_sound_get_listener_index(const ma_sound* pSound);
7603
MA_API ma_vec3f ma_sound_get_direction_to_listener(const ma_sound* pSound);
7604
MA_API void ma_sound_set_position(ma_sound* pSound, float x, float y, float z);
7605
MA_API ma_vec3f ma_sound_get_position(const ma_sound* pSound);
7606
MA_API void ma_sound_set_direction(ma_sound* pSound, float x, float y, float z);
7607
MA_API ma_vec3f ma_sound_get_direction(const ma_sound* pSound);
7608
MA_API void ma_sound_set_velocity(ma_sound* pSound, float x, float y, float z);
7609
MA_API ma_vec3f ma_sound_get_velocity(const ma_sound* pSound);
7610
MA_API void ma_sound_set_attenuation_model(ma_sound* pSound, ma_attenuation_model attenuationModel);
7611
MA_API ma_attenuation_model ma_sound_get_attenuation_model(const ma_sound* pSound);
7612
MA_API void ma_sound_set_positioning(ma_sound* pSound, ma_positioning positioning);
7613
MA_API ma_positioning ma_sound_get_positioning(const ma_sound* pSound);
7614
MA_API void ma_sound_set_rolloff(ma_sound* pSound, float rolloff);
7615
MA_API float ma_sound_get_rolloff(const ma_sound* pSound);
7616
MA_API void ma_sound_set_min_gain(ma_sound* pSound, float minGain);
7617
MA_API float ma_sound_get_min_gain(const ma_sound* pSound);
7618
MA_API void ma_sound_set_max_gain(ma_sound* pSound, float maxGain);
7619
MA_API float ma_sound_get_max_gain(const ma_sound* pSound);
7620
MA_API void ma_sound_set_min_distance(ma_sound* pSound, float minDistance);
7621
MA_API float ma_sound_get_min_distance(const ma_sound* pSound);
7622
MA_API void ma_sound_set_max_distance(ma_sound* pSound, float maxDistance);
7623
MA_API float ma_sound_get_max_distance(const ma_sound* pSound);
7624
MA_API void ma_sound_set_cone(ma_sound* pSound, float innerAngleInRadians, float outerAngleInRadians, float outerGain);
7625
MA_API void ma_sound_get_cone(const ma_sound* pSound, float* pInnerAngleInRadians, float* pOuterAngleInRadians, float* pOuterGain);
7626
MA_API void ma_sound_set_doppler_factor(ma_sound* pSound, float dopplerFactor);
7627
MA_API float ma_sound_get_doppler_factor(const ma_sound* pSound);
7628
MA_API void ma_sound_set_directional_attenuation_factor(ma_sound* pSound, float directionalAttenuationFactor);
7629
MA_API float ma_sound_get_directional_attenuation_factor(const ma_sound* pSound);
7630
MA_API void ma_sound_set_fade_in_pcm_frames(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames);
7631
MA_API void ma_sound_set_fade_in_milliseconds(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds);
7632
MA_API void ma_sound_set_fade_start_in_pcm_frames(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames, ma_uint64 absoluteGlobalTimeInFrames);
7633
MA_API void ma_sound_set_fade_start_in_milliseconds(ma_sound* pSound, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds, ma_uint64 absoluteGlobalTimeInMilliseconds);
7634
MA_API float ma_sound_get_current_fade_volume(const ma_sound* pSound);
7635
MA_API void ma_sound_set_start_time_in_pcm_frames(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInFrames);
7636
MA_API void ma_sound_set_start_time_in_milliseconds(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInMilliseconds);
7637
MA_API void ma_sound_set_stop_time_in_pcm_frames(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInFrames);
7638
MA_API void ma_sound_set_stop_time_in_milliseconds(ma_sound* pSound, ma_uint64 absoluteGlobalTimeInMilliseconds);
7639
MA_API void ma_sound_set_stop_time_with_fade_in_pcm_frames(ma_sound* pSound, ma_uint64 stopAbsoluteGlobalTimeInFrames, ma_uint64 fadeLengthInFrames);
7640
MA_API void ma_sound_set_stop_time_with_fade_in_milliseconds(ma_sound* pSound, ma_uint64 stopAbsoluteGlobalTimeInMilliseconds, ma_uint64 fadeLengthInMilliseconds);
7641
MA_API ma_bool32 ma_sound_is_playing(const ma_sound* pSound);
7642
MA_API ma_uint64 ma_sound_get_time_in_pcm_frames(const ma_sound* pSound);
7643
MA_API ma_uint64 ma_sound_get_time_in_milliseconds(const ma_sound* pSound);
7644
MA_API void ma_sound_set_looping(ma_sound* pSound, ma_bool32 isLooping);
7645
MA_API ma_bool32 ma_sound_is_looping(const ma_sound* pSound);
7646
MA_API ma_bool32 ma_sound_at_end(const ma_sound* pSound);
7647
MA_API ma_result ma_sound_seek_to_pcm_frame(ma_sound* pSound, ma_uint64 frameIndex); /* Just a wrapper around ma_data_source_seek_to_pcm_frame(). */
7648
MA_API ma_result ma_sound_get_data_format(ma_sound* pSound, ma_format* pFormat, ma_uint32* pChannels, ma_uint32* pSampleRate, ma_channel* pChannelMap, size_t channelMapCap);
7649
MA_API ma_result ma_sound_get_cursor_in_pcm_frames(ma_sound* pSound, ma_uint64* pCursor);
7650
MA_API ma_result ma_sound_get_length_in_pcm_frames(ma_sound* pSound, ma_uint64* pLength);
7651
MA_API ma_result ma_sound_get_cursor_in_seconds(ma_sound* pSound, float* pCursor);
7652
MA_API ma_result ma_sound_get_length_in_seconds(ma_sound* pSound, float* pLength);
7653
MA_API ma_result ma_sound_set_end_callback(ma_sound* pSound, ma_sound_end_proc callback, void* pUserData);
7654
 
7655
MA_API ma_result ma_sound_group_init(ma_engine* pEngine, ma_uint32 flags, ma_sound_group* pParentGroup, ma_sound_group* pGroup);
7656
MA_API ma_result ma_sound_group_init_ex(ma_engine* pEngine, const ma_sound_group_config* pConfig, ma_sound_group* pGroup);
7657
MA_API void ma_sound_group_uninit(ma_sound_group* pGroup);
7658
MA_API ma_engine* ma_sound_group_get_engine(const ma_sound_group* pGroup);
7659
MA_API ma_result ma_sound_group_start(ma_sound_group* pGroup);
7660
MA_API ma_result ma_sound_group_stop(ma_sound_group* pGroup);
7661
MA_API void ma_sound_group_set_volume(ma_sound_group* pGroup, float volume);
7662
MA_API float ma_sound_group_get_volume(const ma_sound_group* pGroup);
7663
MA_API void ma_sound_group_set_pan(ma_sound_group* pGroup, float pan);
7664
MA_API float ma_sound_group_get_pan(const ma_sound_group* pGroup);
7665
MA_API void ma_sound_group_set_pan_mode(ma_sound_group* pGroup, ma_pan_mode panMode);
7666
MA_API ma_pan_mode ma_sound_group_get_pan_mode(const ma_sound_group* pGroup);
7667
MA_API void ma_sound_group_set_pitch(ma_sound_group* pGroup, float pitch);
7668
MA_API float ma_sound_group_get_pitch(const ma_sound_group* pGroup);
7669
MA_API void ma_sound_group_set_spatialization_enabled(ma_sound_group* pGroup, ma_bool32 enabled);
7670
MA_API ma_bool32 ma_sound_group_is_spatialization_enabled(const ma_sound_group* pGroup);
7671
MA_API void ma_sound_group_set_pinned_listener_index(ma_sound_group* pGroup, ma_uint32 listenerIndex);
7672
MA_API ma_uint32 ma_sound_group_get_pinned_listener_index(const ma_sound_group* pGroup);
7673
MA_API ma_uint32 ma_sound_group_get_listener_index(const ma_sound_group* pGroup);
7674
MA_API ma_vec3f ma_sound_group_get_direction_to_listener(const ma_sound_group* pGroup);
7675
MA_API void ma_sound_group_set_position(ma_sound_group* pGroup, float x, float y, float z);
7676
MA_API ma_vec3f ma_sound_group_get_position(const ma_sound_group* pGroup);
7677
MA_API void ma_sound_group_set_direction(ma_sound_group* pGroup, float x, float y, float z);
7678
MA_API ma_vec3f ma_sound_group_get_direction(const ma_sound_group* pGroup);
7679
MA_API void ma_sound_group_set_velocity(ma_sound_group* pGroup, float x, float y, float z);
7680
MA_API ma_vec3f ma_sound_group_get_velocity(const ma_sound_group* pGroup);
7681
MA_API void ma_sound_group_set_attenuation_model(ma_sound_group* pGroup, ma_attenuation_model attenuationModel);
7682
MA_API ma_attenuation_model ma_sound_group_get_attenuation_model(const ma_sound_group* pGroup);
7683
MA_API void ma_sound_group_set_positioning(ma_sound_group* pGroup, ma_positioning positioning);
7684
MA_API ma_positioning ma_sound_group_get_positioning(const ma_sound_group* pGroup);
7685
MA_API void ma_sound_group_set_rolloff(ma_sound_group* pGroup, float rolloff);
7686
MA_API float ma_sound_group_get_rolloff(const ma_sound_group* pGroup);
7687
MA_API void ma_sound_group_set_min_gain(ma_sound_group* pGroup, float minGain);
7688
MA_API float ma_sound_group_get_min_gain(const ma_sound_group* pGroup);
7689
MA_API void ma_sound_group_set_max_gain(ma_sound_group* pGroup, float maxGain);
7690
MA_API float ma_sound_group_get_max_gain(const ma_sound_group* pGroup);
7691
MA_API void ma_sound_group_set_min_distance(ma_sound_group* pGroup, float minDistance);
7692
MA_API float ma_sound_group_get_min_distance(const ma_sound_group* pGroup);
7693
MA_API void ma_sound_group_set_max_distance(ma_sound_group* pGroup, float maxDistance);
7694
MA_API float ma_sound_group_get_max_distance(const ma_sound_group* pGroup);
7695
MA_API void ma_sound_group_set_cone(ma_sound_group* pGroup, float innerAngleInRadians, float outerAngleInRadians, float outerGain);
7696
MA_API void ma_sound_group_get_cone(const ma_sound_group* pGroup, float* pInnerAngleInRadians, float* pOuterAngleInRadians, float* pOuterGain);
7697
MA_API void ma_sound_group_set_doppler_factor(ma_sound_group* pGroup, float dopplerFactor);
7698
MA_API float ma_sound_group_get_doppler_factor(const ma_sound_group* pGroup);
7699
MA_API void ma_sound_group_set_directional_attenuation_factor(ma_sound_group* pGroup, float directionalAttenuationFactor);
7700
MA_API float ma_sound_group_get_directional_attenuation_factor(const ma_sound_group* pGroup);
7701
MA_API void ma_sound_group_set_fade_in_pcm_frames(ma_sound_group* pGroup, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInFrames);
7702
MA_API void ma_sound_group_set_fade_in_milliseconds(ma_sound_group* pGroup, float volumeBeg, float volumeEnd, ma_uint64 fadeLengthInMilliseconds);
7703
MA_API float ma_sound_group_get_current_fade_volume(ma_sound_group* pGroup);
7704
MA_API void ma_sound_group_set_start_time_in_pcm_frames(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInFrames);
7705
MA_API void ma_sound_group_set_start_time_in_milliseconds(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInMilliseconds);
7706
MA_API void ma_sound_group_set_stop_time_in_pcm_frames(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInFrames);
7707
MA_API void ma_sound_group_set_stop_time_in_milliseconds(ma_sound_group* pGroup, ma_uint64 absoluteGlobalTimeInMilliseconds);
7708
MA_API ma_bool32 ma_sound_group_is_playing(const ma_sound_group* pGroup);
7709
MA_API ma_uint64 ma_sound_group_get_time_in_pcm_frames(const ma_sound_group* pGroup);
7710
#endif  /* MA_NO_ENGINE */
7711
/* END SECTION: miniaudio_engine.h */
7712
 
7713
#ifdef __cplusplus
7714
}
7715
#endif
7716
#endif  /* miniaudio_h */
7717
 
7718
/*
7719
This software is available as a choice of the following licenses. Choose
7720
whichever you prefer.
7721
 
7722
===============================================================================
7723
ALTERNATIVE 1 - Public Domain (www.unlicense.org)
7724
===============================================================================
7725
This is free and unencumbered software released into the public domain.
7726
 
7727
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
7728
software, either in source code form or as a compiled binary, for any purpose,
7729
commercial or non-commercial, and by any means.
7730
 
7731
In jurisdictions that recognize copyright laws, the author or authors of this
7732
software dedicate any and all copyright interest in the software to the public
7733
domain. We make this dedication for the benefit of the public at large and to
7734
the detriment of our heirs and successors. We intend this dedication to be an
7735
overt act of relinquishment in perpetuity of all present and future rights to
7736
this software under copyright law.
7737
 
7738
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7739
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7740
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7741
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
7742
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
7743
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7744
 
7745
For more information, please refer to <http://unlicense.org/>
7746
 
7747
===============================================================================
7748
ALTERNATIVE 2 - MIT No Attribution
7749
===============================================================================
7750
Copyright 2023 David Reid
7751
 
7752
Permission is hereby granted, free of charge, to any person obtaining a copy of
7753
this software and associated documentation files (the "Software"), to deal in
7754
the Software without restriction, including without limitation the rights to
7755
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7756
of the Software, and to permit persons to whom the Software is furnished to do
7757
so.
7758
 
7759
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7760
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7761
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7762
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7763
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7764
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
7765
SOFTWARE.
7766
*/