Parcourir la source

vendor/miniaudio: update to 0.11.22

Laytan il y a 2 mois
Parent
commit
53a9ecb577

+ 2 - 2
vendor/miniaudio/common.odin

@@ -20,9 +20,9 @@ foreign import lib { LIB }
 
 
 BINDINGS_VERSION_MAJOR    :: 0
 BINDINGS_VERSION_MAJOR    :: 0
 BINDINGS_VERSION_MINOR    :: 11
 BINDINGS_VERSION_MINOR    :: 11
-BINDINGS_VERSION_REVISION :: 21 
+BINDINGS_VERSION_REVISION :: 22
 BINDINGS_VERSION          :: [3]u32{BINDINGS_VERSION_MAJOR, BINDINGS_VERSION_MINOR, BINDINGS_VERSION_REVISION}
 BINDINGS_VERSION          :: [3]u32{BINDINGS_VERSION_MAJOR, BINDINGS_VERSION_MINOR, BINDINGS_VERSION_REVISION}
-BINDINGS_VERSION_STRING   :: "0.11.21"
+BINDINGS_VERSION_STRING   :: "0.11.22"
 
 
 @(init)
 @(init)
 version_check :: proc() {
 version_check :: proc() {

+ 2 - 2
vendor/miniaudio/data_conversion.odin

@@ -194,7 +194,7 @@ foreign lib {
 	resampler_get_expected_output_frame_count :: proc(pResampler: ^resampler, inputFrameCount: u64, pOutputFrameCount: ^u64) -> result ---
 	resampler_get_expected_output_frame_count :: proc(pResampler: ^resampler, inputFrameCount: u64, pOutputFrameCount: ^u64) -> result ---
 
 
 	/*
 	/*
-	Resets the resampler's timer and clears it's internal cache.
+	Resets the resampler's timer and clears its internal cache.
 	*/
 	*/
 	resampler_reset :: proc(pResampler: ^resampler) -> result ---
 	resampler_reset :: proc(pResampler: ^resampler) -> result ---
 }
 }
@@ -421,7 +421,7 @@ foreign lib {
 	/*
 	/*
 	Copies a channel map.
 	Copies a channel map.
 
 
-	Both input and output channel map buffers must have a capacity of at at least `channels`.
+	Both input and output channel map buffers must have a capacity of at least `channels`.
 	*/
 	*/
 	channel_map_copy :: proc(pOut: [^]channel, pIn: [^]channel, channels: u32) ---
 	channel_map_copy :: proc(pOut: [^]channel, pIn: [^]channel, channels: u32) ---
 
 

+ 2 - 2
vendor/miniaudio/decoding.odin

@@ -71,7 +71,7 @@ decoder :: struct  {
 	pInputCache:            rawptr,            /* In input format. Can be null if it's not needed. */
 	pInputCache:            rawptr,            /* In input format. Can be null if it's not needed. */
 	inputCacheCap:          u64,               /* The capacity of the input cache. */
 	inputCacheCap:          u64,               /* The capacity of the input cache. */
 	inputCacheConsumed:     u64,               /* The number of frames that have been consumed in the cache. Used for determining the next valid frame. */
 	inputCacheConsumed:     u64,               /* The number of frames that have been consumed in the cache. Used for determining the next valid frame. */
-	inputCacheRemaining:    u64,               /* The number of valid frames remaining in the cahce. */
+	inputCacheRemaining:    u64,               /* The number of valid frames remaining in the cache. */
 	allocationCallbacks:    allocation_callbacks,
 	allocationCallbacks:    allocation_callbacks,
 	data: struct #raw_union {
 	data: struct #raw_union {
 		vfs: struct {
 		vfs: struct {
@@ -111,7 +111,7 @@ foreign lib {
 	decoder_read_pcm_frames :: proc(pDecoder: ^decoder, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
 	decoder_read_pcm_frames :: proc(pDecoder: ^decoder, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
 
 
 	/*
 	/*
-	Seeks to a PCM frame based on it's absolute index.
+	Seeks to a PCM frame based on its absolute index.
 
 
 	This is not thread safe without your own synchronization.
 	This is not thread safe without your own synchronization.
 	*/
 	*/

+ 13 - 5
vendor/miniaudio/device_io_procs.odin

@@ -12,6 +12,8 @@ foreign lib {
 	device_job_thread_uninit :: proc(pJobThread: ^device_job_thread, pAllocationCallbacks: ^allocation_callbacks) ---
 	device_job_thread_uninit :: proc(pJobThread: ^device_job_thread, pAllocationCallbacks: ^allocation_callbacks) ---
 	device_job_thread_post   :: proc(pJobThread: ^device_job_thread, pJob: ^job) -> result ---
 	device_job_thread_post   :: proc(pJobThread: ^device_job_thread, pJob: ^job) -> result ---
 	device_job_thread_next   :: proc(pJobThread: ^device_job_thread, pJob: ^job) -> result ---
 	device_job_thread_next   :: proc(pJobThread: ^device_job_thread, pJob: ^job) -> result ---
+
+	device_id_equal :: proc(pA: ^device_id, pB: ^device_id) -> b32 ---
 	
 	
 	/*
 	/*
 	Initializes a `ma_context_config` object.
 	Initializes a `ma_context_config` object.
@@ -370,6 +372,9 @@ foreign lib {
 	This function will allocate memory internally for the device lists and return a pointer to them through the `ppPlaybackDeviceInfos` and `ppCaptureDeviceInfos`
 	This function will allocate memory internally for the device lists and return a pointer to them through the `ppPlaybackDeviceInfos` and `ppCaptureDeviceInfos`
 	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.
 	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.
 
 
+	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
+	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,
+	but don't call it from within the enumeration callback.
 
 
 	Parameters
 	Parameters
 	----------
 	----------
@@ -411,7 +416,7 @@ foreign lib {
 
 
 	See Also
 	See Also
 	--------
 	--------
-	ma_context_get_devices()
+	ma_context_enumerate_devices()
 	*/
 	*/
 	context_get_devices :: proc(pContext: ^context_type, ppPlaybackDeviceInfos: ^[^]device_info, pPlaybackDeviceCount: ^u32, ppCaptureDeviceInfos: ^[^]device_info, pCaptureDeviceCount: ^u32) -> result ---
 	context_get_devices :: proc(pContext: ^context_type, ppPlaybackDeviceInfos: ^[^]device_info, pPlaybackDeviceCount: ^u32, ppCaptureDeviceInfos: ^[^]device_info, pCaptureDeviceCount: ^u32) -> result ---
 
 
@@ -550,7 +555,7 @@ foreign lib {
 	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
 	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
 	device is done via a callback which is fired by miniaudio at periodic time intervals.
 	device is done via a callback which is fired by miniaudio at periodic time intervals.
 
 
-	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
+	The frequency at which data is delivered to and from a device depends on the size of its period. The size of the period can be defined in terms of PCM frames
 	or milliseconds, whichever is more convenient. Generally speaking, the smaller the period, the lower the latency at the expense of higher CPU usage and
 	or milliseconds, whichever is more convenient. Generally speaking, the smaller the period, the lower the latency at the expense of higher CPU usage and
 	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
 	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
 	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
 	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
@@ -624,7 +629,7 @@ foreign lib {
 
 
 			performanceProfile
 			performanceProfile
 					A hint to miniaudio as to the performance requirements of your program. Can be either `ma_performance_profile_low_latency` (default) or
 					A hint to miniaudio as to the performance requirements of your program. Can be either `ma_performance_profile_low_latency` (default) or
-					`ma_performance_profile_conservative`. This mainly affects the size of default buffers and can usually be left at it's default value.
+					`ma_performance_profile_conservative`. This mainly affects the size of default buffers and can usually be left at its default value.
 
 
 			noPreSilencedOutputBuffer
 			noPreSilencedOutputBuffer
 					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
 					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
@@ -664,7 +669,7 @@ foreign lib {
 					A pointer that will passed to callbacks in pBackendVTable.
 					A pointer that will passed to callbacks in pBackendVTable.
 
 
 			resampling.linear.lpfOrder
 			resampling.linear.lpfOrder
-					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
+					The linear resampler applies a low-pass filter as part of its processing for anti-aliasing. This setting controls the order of the filter. The higher
 					the value, the better the quality, in general. Setting this to 0 will disable low-pass filtering altogether. The maximum value is
 					the value, the better the quality, in general. Setting this to 0 will disable low-pass filtering altogether. The maximum value is
 					`MA_MAX_FILTER_ORDER`. The default value is `min(4, MA_MAX_FILTER_ORDER)`.
 					`MA_MAX_FILTER_ORDER`. The default value is `min(4, MA_MAX_FILTER_ORDER)`.
 
 
@@ -741,6 +746,9 @@ foreign lib {
 			pulse.pStreamNameCapture
 			pulse.pStreamNameCapture
 					PulseAudio only. Sets the stream name for capture.
 					PulseAudio only. Sets the stream name for capture.
 
 
+			pulse.channelMap
+				PulseAudio only. Sets the channel map that is requested from PulseAudio. See MA_PA_CHANNEL_MAP_* constants. Defaults to MA_PA_CHANNEL_MAP_AIFF.
+
 			coreaudio.allowNominalSampleRateChange
 			coreaudio.allowNominalSampleRateChange
 					Core Audio only. Desktop only. When enabled, allows the sample rate of the device to be changed at the operating system level. This
 					Core Audio only. Desktop only. When enabled, allows the sample rate of the device to be changed at the operating system level. This
 					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
 					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
@@ -914,7 +922,7 @@ foreign lib {
 
 
 	Remarks
 	Remarks
 	-------
 	-------
-	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
+	You only need to use this function if you want to configure the context differently to its defaults. You should never use this function if you want to manage
 	your own context.
 	your own context.
 
 
 	See the documentation for `ma_context_init()` for information on the different context configuration options.
 	See the documentation for `ma_context_init()` for information on the different context configuration options.

+ 10 - 3
vendor/miniaudio/device_io_types.odin

@@ -427,6 +427,7 @@ device_config :: struct {
 	pulse: struct {
 	pulse: struct {
 		pStreamNamePlayback: cstring,
 		pStreamNamePlayback: cstring,
 		pStreamNameCapture:  cstring,
 		pStreamNameCapture:  cstring,
+		channelMap:          i32,
 	},
 	},
 	coreaudio: struct {
 	coreaudio: struct {
 		allowNominalSampleRateChange: b32, /* Desktop only. When enabled, allows changing of the sample rate at the operating system level. */
 		allowNominalSampleRateChange: b32, /* Desktop only. When enabled, allows changing of the sample rate at the operating system level. */
@@ -443,6 +444,7 @@ device_config :: struct {
 		allowedCapturePolicy:           aaudio_allowed_capture_policy,
 		allowedCapturePolicy:           aaudio_allowed_capture_policy,
 		noAutoStartAfterReroute:        b32,
 		noAutoStartAfterReroute:        b32,
 		enableCompatibilityWorkarounds: b32,
 		enableCompatibilityWorkarounds: b32,
+		allowSetBufferCapacity:         b32,
 	},
 	},
 }
 }
 
 
@@ -514,7 +516,7 @@ and on output returns detailed information about the device in `ma_device_info`.
 case when the device ID is NULL, in which case information about the default device needs to be retrieved.
 case when the device ID is NULL, in which case information about the default device needs to be retrieved.
 
 
 Once the context has been created and the device ID retrieved (if using anything other than the default device), the device can be created.
 Once the context has been created and the device ID retrieved (if using anything other than the default device), the device can be created.
-This is a little bit more complicated than initialization of the context due to it's more complicated configuration. When initializing a
+This is a little bit more complicated than initialization of the context due to its more complicated configuration. When initializing a
 device, a duplex device may be requested. This means a separate data format needs to be specified for both playback and capture. On input,
 device, a duplex device may be requested. This means a separate data format needs to be specified for both playback and capture. On input,
 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
 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
 the requested format. The conversion between the format requested by the application and the device's native format will be handled
 the requested format. The conversion between the format requested by the application and the device's native format will be handled
@@ -535,10 +537,10 @@ asynchronous reading and writing, `onDeviceStart()` and `onDeviceStop()` should
 The handling of data delivery between the application and the device is the most complicated part of the process. To make this a bit
 The handling of data delivery between the application and the device is the most complicated part of the process. To make this a bit
 easier, some helper callbacks are available. If the backend uses a blocking read/write style of API, the `onDeviceRead()` and
 easier, some helper callbacks are available. If the backend uses a blocking read/write style of API, the `onDeviceRead()` and
 `onDeviceWrite()` callbacks can optionally be implemented. These are blocking and work just like reading and writing from a file. If the
 `onDeviceWrite()` callbacks can optionally be implemented. These are blocking and work just like reading and writing from a file. If the
-backend uses a callback for data delivery, that callback must call `ma_device_handle_backend_data_callback()` from within it's callback.
+backend uses a callback for data delivery, that callback must call `ma_device_handle_backend_data_callback()` from within its callback.
 This allows miniaudio to then process any necessary data conversion and then pass it to the miniaudio data callback.
 This allows miniaudio to then process any necessary data conversion and then pass it to the miniaudio data callback.
 
 
-If the backend requires absolute flexibility with it's data delivery, it can optionally implement the `onDeviceDataLoop()` callback
+If the backend requires absolute flexibility with its data delivery, it can optionally implement the `onDeviceDataLoop()` callback
 which will allow it to implement the logic that will run on the audio thread. This is much more advanced and is completely optional.
 which will allow it to implement the logic that will run on the audio thread. This is much more advanced and is completely optional.
 
 
 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
 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
@@ -575,6 +577,9 @@ context_config :: struct {
 	threadStackSize: c.size_t,
 	threadStackSize: c.size_t,
 	pUserData: rawptr,
 	pUserData: rawptr,
 	allocationCallbacks: allocation_callbacks,
 	allocationCallbacks: allocation_callbacks,
+	dsound: struct {
+		hWnd: handle, /* HWND. Optional window handle to pass into SetCooperativeLevel(). Will default to the foreground window, and if that fails, the desktop window. */
+	},
 	alsa: struct {
 	alsa: struct {
 		useVerboseDeviceEnumeration: b32,
 		useVerboseDeviceEnumeration: b32,
 	},
 	},
@@ -649,6 +654,7 @@ context_type :: struct {
 		} when SUPPORT_WASAPI else struct {}),
 		} when SUPPORT_WASAPI else struct {}),
 		
 		
 		dsound: (struct {
 		dsound: (struct {
+			hWnd:                         handle, /* Can be null. */
 			hDSoundDLL:                   handle,
 			hDSoundDLL:                   handle,
 			DirectSoundCreate:            proc "system" (),
 			DirectSoundCreate:            proc "system" (),
 			DirectSoundEnumerateA:        proc "system" (),
 			DirectSoundEnumerateA:        proc "system" (),
@@ -1195,6 +1201,7 @@ device :: struct {
 		aaudio: (struct {
 		aaudio: (struct {
 			/*AAudioStream**/ pStreamPlayback: rawptr,
 			/*AAudioStream**/ pStreamPlayback: rawptr,
 			/*AAudioStream**/ pStreamCapture: rawptr,
 			/*AAudioStream**/ pStreamCapture: rawptr,
+			rerouteLock: mutex,
 			usage: aaudio_usage,
 			usage: aaudio_usage,
 			contentType: aaudio_content_type,
 			contentType: aaudio_content_type,
 			inputPreset: aaudio_input_preset,
 			inputPreset: aaudio_input_preset,

+ 58 - 34
vendor/miniaudio/doc.odin

@@ -295,7 +295,7 @@ avoids the same sound being loaded multiple times.
 
 
 The node graph is used for mixing and effect processing. The idea is that you connect a number of
 The node graph is used for mixing and effect processing. The idea is that you connect a number of
 nodes into the graph by connecting each node's outputs to another node's inputs. Each node can
 nodes into the graph by connecting each node's outputs to another node's inputs. Each node can
-implement it's own effect. By chaining nodes together, advanced mixing and effect processing can
+implement its own effect. By chaining nodes together, advanced mixing and effect processing can
 be achieved.
 be achieved.
 
 
 The engine encapsulates both the resource manager and the node graph to create a simple, easy to
 The engine encapsulates both the resource manager and the node graph to create a simple, easy to
@@ -400,7 +400,7 @@ the be started and/or stopped at a specific time. This can be done with the foll
     ```
     ```
 
 
 The start/stop time needs to be specified based on the absolute timer which is controlled by the
 The start/stop time needs to be specified based on the absolute timer which is controlled by the
-engine. The current global time time in PCM frames can be retrieved with
+engine. The current global time in PCM frames can be retrieved with
 `ma_engine_get_time_in_pcm_frames()`. The engine's global time can be changed with
 `ma_engine_get_time_in_pcm_frames()`. The engine's global time can be changed with
 `ma_engine_set_time_in_pcm_frames()` for synchronization purposes if required. Note that scheduling
 `ma_engine_set_time_in_pcm_frames()` for synchronization purposes if required. Note that scheduling
 a start time still requires an explicit call to `ma_sound_start()` before anything will play:
 a start time still requires an explicit call to `ma_sound_start()` before anything will play:
@@ -432,11 +432,11 @@ Sounds and sound groups are nodes in the engine's node graph and can be plugged
 API. This makes it possible to connect sounds and sound groups to effect nodes to produce complex
 API. This makes it possible to connect sounds and sound groups to effect nodes to produce complex
 effect chains.
 effect chains.
 
 
-A sound can have it's volume changed with `ma_sound_set_volume()`. If you prefer decibel volume
+A sound can have its volume changed with `ma_sound_set_volume()`. If you prefer decibel volume
 control you can use `ma_volume_db_to_linear()` to convert from decibel representation to linear.
 control you can use `ma_volume_db_to_linear()` to convert from decibel representation to linear.
 
 
 Panning and pitching is supported with `ma_sound_set_pan()` and `ma_sound_set_pitch()`. If you know
 Panning and pitching is supported with `ma_sound_set_pan()` and `ma_sound_set_pitch()`. If you know
-a sound will never have it's pitch changed with `ma_sound_set_pitch()` or via the doppler effect,
+a sound will never have its pitch changed with `ma_sound_set_pitch()` or via the doppler effect,
 you can specify the `MA_SOUND_FLAG_NO_PITCH` flag when initializing the sound for an optimization.
 you can specify the `MA_SOUND_FLAG_NO_PITCH` flag when initializing the sound for an optimization.
 
 
 By default, sounds and sound groups have spatialization enabled. If you don't ever want to
 By default, sounds and sound groups have spatialization enabled. If you don't ever want to
@@ -485,21 +485,12 @@ link the relevant frameworks but should compile cleanly out of the box with Xcod
 through the command line requires linking to `-lpthread` and `-lm`.
 through the command line requires linking to `-lpthread` and `-lm`.
 
 
 Due to the way miniaudio links to frameworks at runtime, your application may not pass Apple's
 Due to the way miniaudio links to frameworks at runtime, your application may not pass Apple's
-notarization process. To fix this there are two options. The first is to use the
-`MA_NO_RUNTIME_LINKING` option, like so:
-
-    ```c
-    #ifdef __APPLE__
-        #define MA_NO_RUNTIME_LINKING
-    #endif
-    #define MINIAUDIO_IMPLEMENTATION
-    #include "miniaudio.h"
-    ```
-
-This will require linking with `-framework CoreFoundation -framework CoreAudio -framework AudioToolbox`.
-If you get errors about AudioToolbox, try with `-framework AudioUnit` instead. You may get this when
-using older versions of iOS. Alternatively, if you would rather keep using runtime linking you can
-add the following to your entitlements.xcent file:
+notarization process. To fix this there are two options. The first is to compile with
+`-DMA_NO_RUNTIME_LINKING` which in turn will require linking with
+`-framework CoreFoundation -framework CoreAudio -framework AudioToolbox`. If you get errors about
+AudioToolbox, try with `-framework AudioUnit` instead. You may get this when using older versions
+of iOS. Alternatively, if you would rather keep using runtime linking you can add the following to
+your entitlements.xcent file:
 
 
     ```
     ```
     <key>com.apple.security.cs.allow-dyld-environment-variables</key>
     <key>com.apple.security.cs.allow-dyld-environment-variables</key>
@@ -557,7 +548,7 @@ To run locally, you'll need to use emrun:
 
 
 2.7. Build Options
 2.7. Build Options
 ------------------
 ------------------
-`#define` these options before including miniaudio.h.
+`#define` these options before including miniaudio.c, or pass them as compiler flags:
 
 
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
     | Option                           | Description                                                        |
     | Option                           | Description                                                        |
@@ -588,6 +579,8 @@ To run locally, you'll need to use emrun:
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
     | MA_NO_WEBAUDIO                   | Disables the Web Audio backend.                                    |
     | MA_NO_WEBAUDIO                   | Disables the Web Audio backend.                                    |
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
+    | MA_NO_CUSTOM                     | Disables support for custom backends.                              |
+    +----------------------------------+--------------------------------------------------------------------+
     | MA_NO_NULL                       | Disables the null backend.                                         |
     | MA_NO_NULL                       | Disables the null backend.                                         |
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
     | MA_ENABLE_ONLY_SPECIFIC_BACKENDS | Disables all backends by default and requires `MA_ENABLE_*` to     |
     | MA_ENABLE_ONLY_SPECIFIC_BACKENDS | Disables all backends by default and requires `MA_ENABLE_*` to     |
@@ -632,6 +625,9 @@ To run locally, you'll need to use emrun:
     | MA_ENABLE_WEBAUDIO               | Used in conjunction with MA_ENABLE_ONLY_SPECIFIC_BACKENDS to       |
     | MA_ENABLE_WEBAUDIO               | Used in conjunction with MA_ENABLE_ONLY_SPECIFIC_BACKENDS to       |
     |                                  | enable the Web Audio backend.                                      |
     |                                  | enable the Web Audio backend.                                      |
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
+    | MA_ENABLE_CUSTOM                 | Used in conjunction with MA_ENABLE_ONLY_SPECIFIC_BACKENDS to       |
+    |                                  | enable custom backends.                                            |
+    +----------------------------------+--------------------------------------------------------------------+
     | MA_ENABLE_NULL                   | Used in conjunction with MA_ENABLE_ONLY_SPECIFIC_BACKENDS to       |
     | MA_ENABLE_NULL                   | Used in conjunction with MA_ENABLE_ONLY_SPECIFIC_BACKENDS to       |
     |                                  | enable the null backend.                                           |
     |                                  | enable the null backend.                                           |
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
@@ -695,11 +691,30 @@ To run locally, you'll need to use emrun:
     |                                  | You may need to enable this if your target platform does not allow |
     |                                  | You may need to enable this if your target platform does not allow |
     |                                  | runtime linking via `dlopen()`.                                    |
     |                                  | runtime linking via `dlopen()`.                                    |
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
+    | MA_USE_STDINT                    | (Pass this in a compiler flag. Do not #define this before          |
+	|                                  | miniaudio.c) Forces the use of stdint.h for sized types.           |
+    +----------------------------------+--------------------------------------------------------------------+
     | MA_DEBUG_OUTPUT                  | Enable `printf()` output of debug logs (`MA_LOG_LEVEL_DEBUG`).     |
     | MA_DEBUG_OUTPUT                  | Enable `printf()` output of debug logs (`MA_LOG_LEVEL_DEBUG`).     |
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
     | MA_COINIT_VALUE                  | Windows only. The value to pass to internal calls to               |
     | MA_COINIT_VALUE                  | Windows only. The value to pass to internal calls to               |
     |                                  | `CoInitializeEx()`. Defaults to `COINIT_MULTITHREADED`.            |
     |                                  | `CoInitializeEx()`. Defaults to `COINIT_MULTITHREADED`.            |
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
+    | MA_FORCE_UWP                     | Windows only. Affects only the WASAPI backend. Will force the      |
+    |                                  | WASAPI backend to use the UWP code path instead of the regular     |
+    |                                  | desktop path. This is normally auto-detected and should rarely be  |
+    |                                  | needed to be used explicitly, but can be useful for debugging.     |
+    +----------------------------------+--------------------------------------------------------------------+
+    | MA_ON_THREAD_ENTRY               | Defines some code that will be executed as soon as an internal     |
+    |                                  | miniaudio-managed thread is created. This will be the first thing  |
+    |                                  | to be executed by the thread entry point.                          |
+    +----------------------------------+--------------------------------------------------------------------+
+    | MA_ON_THREAD_EXIT                | Defines some code that will be executed from the entry point of an |
+    |                                  | internal miniaudio-managed thread upon exit. This will be the last |
+    |                                  | thing to be executed before the thread's entry point exits.        |
+    +----------------------------------+--------------------------------------------------------------------+
+    | MA_THREAD_DEFAULT_STACK_SIZE     | If set, specifies the default stack size used by miniaudio-managed |
+    |                                  | threads.                                                           |
+    +----------------------------------+--------------------------------------------------------------------+
     | MA_API                           | Controls how public APIs should be decorated. Default is `extern`. |
     | MA_API                           | Controls how public APIs should be decorated. Default is `extern`. |
     +----------------------------------+--------------------------------------------------------------------+
     +----------------------------------+--------------------------------------------------------------------+
 
 
@@ -1311,7 +1326,7 @@ only works for sounds that were initialized with `ma_sound_init_from_file()` and
 
 
 When you initialize a sound, if you specify a sound group the sound will be attached to that group
 When you initialize a sound, if you specify a sound group the sound will be attached to that group
 automatically. If you set it to NULL, it will be automatically attached to the engine's endpoint.
 automatically. If you set it to NULL, it will be automatically attached to the engine's endpoint.
-If you would instead rather leave the sound unattached by default, you can can specify the
+If you would instead rather leave the sound unattached by default, you can specify the
 `MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT` flag. This is useful if you want to set up a complex node
 `MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT` flag. This is useful if you want to set up a complex node
 graph.
 graph.
 
 
@@ -1688,6 +1703,7 @@ combination of the following flags:
     MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE
     MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE
     MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC
     MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC
     MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT
     MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT
+    MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING
     ```
     ```
 
 
 When no flags are specified (set to 0), the sound will be fully loaded into memory, but not
 When no flags are specified (set to 0), the sound will be fully loaded into memory, but not
@@ -1708,6 +1724,14 @@ can instead stream audio data which you can do by specifying the
 second pages. When a new page needs to be decoded, a job will be posted to the job queue and then
 second pages. When a new page needs to be decoded, a job will be posted to the job queue and then
 subsequently processed in a job thread.
 subsequently processed in a job thread.
 
 
+The `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING` flag can be used so that the sound will loop
+when it reaches the end by default. It's recommended you use this flag when you want to have a
+looping streaming sound. If you try loading a very short sound as a stream, you will get a glitch.
+This is because the resource manager needs to pre-fill the initial buffer at initialization time,
+and if you don't specify the `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING` flag, the resource
+manager will assume the sound is not looping and will stop filling the buffer when it reaches the
+end, therefore resulting in a discontinuous buffer.
+
 For in-memory sounds, reference counting is used to ensure the data is loaded only once. This means
 For in-memory sounds, reference counting is used to ensure the data is loaded only once. This means
 multiple calls to `ma_resource_manager_data_source_init()` with the same file path will result in
 multiple calls to `ma_resource_manager_data_source_init()` with the same file path will result in
 the file data only being loaded once. Each call to `ma_resource_manager_data_source_init()` must be
 the file data only being loaded once. Each call to `ma_resource_manager_data_source_init()` must be
@@ -1722,7 +1746,7 @@ actual file paths. When `ma_resource_manager_data_source_init()` is called (with
 `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM` flag), the resource manager will look for these
 `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM` flag), the resource manager will look for these
 explicitly registered data buffers and, if found, will use it as the backing data for the data
 explicitly registered data buffers and, if found, will use it as the backing data for the data
 source. Note that the resource manager does *not* make a copy of this data so it is up to the
 source. Note that the resource manager does *not* make a copy of this data so it is up to the
-caller to ensure the pointer stays valid for it's lifetime. Use
+caller to ensure the pointer stays valid for its lifetime. Use
 `ma_resource_manager_unregister_data()` to unregister the self-managed data. You can also use
 `ma_resource_manager_unregister_data()` to unregister the self-managed data. You can also use
 `ma_resource_manager_register_file()` and `ma_resource_manager_unregister_file()` to register and
 `ma_resource_manager_register_file()` and `ma_resource_manager_unregister_file()` to register and
 unregister a file. It does not make sense to use the `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM`
 unregister a file. It does not make sense to use the `MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM`
@@ -2033,7 +2057,7 @@ In the above graph, it starts with two data sources whose outputs are attached t
 splitter node. It's at this point that the two data sources are mixed. After mixing, the splitter
 splitter node. It's at this point that the two data sources are mixed. After mixing, the splitter
 performs it's processing routine and produces two outputs which is simply a duplication of the
 performs it's processing routine and produces two outputs which is simply a duplication of the
 input stream. One output is attached to a low pass filter, whereas the other output is attached to
 input stream. One output is attached to a low pass filter, whereas the other output is attached to
-a echo/delay. The outputs of the the low pass filter and the echo are attached to the endpoint, and
+a echo/delay. The outputs of the low pass filter and the echo are attached to the endpoint, and
 since they're both connected to the same input bus, they'll be mixed.
 since they're both connected to the same input bus, they'll be mixed.
 
 
 Each input bus must be configured to accept the same number of channels, but the number of channels
 Each input bus must be configured to accept the same number of channels, but the number of channels
@@ -2074,7 +2098,7 @@ data from the graph:
     ```
     ```
 
 
 When you read audio data, miniaudio starts at the node graph's endpoint node which then pulls in
 When you read audio data, miniaudio starts at the node graph's endpoint node which then pulls in
-data from it's input attachments, which in turn recursively pull in data from their inputs, and so
+data from its input attachments, which in turn recursively pull in data from their inputs, and so
 on. At the start of the graph there will be some kind of data source node which will have zero
 on. At the start of the graph there will be some kind of data source node which will have zero
 inputs and will instead read directly from a data source. The base nodes don't literally need to
 inputs and will instead read directly from a data source. The base nodes don't literally need to
 read from a `ma_data_source` object, but they will always have some kind of underlying object that
 read from a `ma_data_source` object, but they will always have some kind of underlying object that
@@ -2320,7 +2344,7 @@ You can start and stop a node with the following:
 
 
 By default the node is in a started state, but since it won't be connected to anything won't
 By default the node is in a started state, but since it won't be connected to anything won't
 actually be invoked by the node graph until it's connected. When you stop a node, data will not be
 actually be invoked by the node graph until it's connected. When you stop a node, data will not be
-read from any of it's input connections. You can use this property to stop a group of sounds
+read from any of its input connections. You can use this property to stop a group of sounds
 atomically.
 atomically.
 
 
 You can configure the initial state of a node in it's config:
 You can configure the initial state of a node in it's config:
@@ -2413,29 +2437,29 @@ audio thread is finished so that control is not handed back to the caller thereb
 chance to free the node's memory.
 chance to free the node's memory.
 
 
 When the audio thread is processing a node, it does so by reading from each of the output buses of
 When the audio thread is processing a node, it does so by reading from each of the output buses of
-the node. In order for a node to process data for one of it's output buses, it needs to read from
-each of it's input buses, and so on an so forth. It follows that once all output buses of a node
+the node. In order for a node to process data for one of its output buses, it needs to read from
+each of its input buses, and so on an so forth. It follows that once all output buses of a node
 are detached, the node as a whole will be disconnected and no further processing will occur unless
 are detached, the node as a whole will be disconnected and no further processing will occur unless
 it's output buses are reattached, which won't be happening when the node is being uninitialized.
 it's output buses are reattached, which won't be happening when the node is being uninitialized.
 By having `ma_node_detach_output_bus()` wait until the audio thread is finished with it, we can
 By having `ma_node_detach_output_bus()` wait until the audio thread is finished with it, we can
 simplify a few things, at the expense of making `ma_node_detach_output_bus()` a bit slower. By
 simplify a few things, at the expense of making `ma_node_detach_output_bus()` a bit slower. By
 doing this, the implementation of `ma_node_uninit()` becomes trivial - just detach all output
 doing this, the implementation of `ma_node_uninit()` becomes trivial - just detach all output
-nodes, followed by each of the attachments to each of it's input nodes, and then do any final clean
+nodes, followed by each of the attachments to each of its input nodes, and then do any final clean
 up.
 up.
 
 
 With the above design, the worst-case scenario is `ma_node_detach_output_bus()` taking as long as
 With the above design, the worst-case scenario is `ma_node_detach_output_bus()` taking as long as
 it takes to process the output bus being detached. This will happen if it's called at just the
 it takes to process the output bus being detached. This will happen if it's called at just the
 wrong moment where the audio thread has just iterated it and has just started processing. The
 wrong moment where the audio thread has just iterated it and has just started processing. The
 caller of `ma_node_detach_output_bus()` will stall until the audio thread is finished, which
 caller of `ma_node_detach_output_bus()` will stall until the audio thread is finished, which
-includes the cost of recursively processing it's inputs. This is the biggest compromise made with
-the approach taken by miniaudio for it's lock-free processing system. The cost of detaching nodes
+includes the cost of recursively processing its inputs. This is the biggest compromise made with
+the approach taken by miniaudio for its lock-free processing system. The cost of detaching nodes
 earlier in the pipeline (data sources, for example) will be cheaper than the cost of detaching
 earlier in the pipeline (data sources, for example) will be cheaper than the cost of detaching
 higher level nodes, such as some kind of final post-processing endpoint. If you need to do mass
 higher level nodes, such as some kind of final post-processing endpoint. If you need to do mass
 detachments, detach starting from the lowest level nodes and work your way towards the final
 detachments, detach starting from the lowest level nodes and work your way towards the final
 endpoint node (but don't try detaching the node graph's endpoint). If the audio thread is not
 endpoint node (but don't try detaching the node graph's endpoint). If the audio thread is not
 running, detachment will be fast and detachment in any order will be the same. The reason nodes
 running, detachment will be fast and detachment in any order will be the same. The reason nodes
 need to wait for their input attachments to complete is due to the potential for desyncs between
 need to wait for their input attachments to complete is due to the potential for desyncs between
-data sources. If the node was to terminate processing mid way through processing it's inputs,
+data sources. If the node was to terminate processing mid way through processing its inputs,
 there's a chance that some of the underlying data sources will have been read, but then others not.
 there's a chance that some of the underlying data sources will have been read, but then others not.
 That will then result in a potential desynchronization when detaching and reattaching higher-level
 That will then result in a potential desynchronization when detaching and reattaching higher-level
 nodes. A possible solution to this is to have an option when detaching to terminate processing
 nodes. A possible solution to this is to have an option when detaching to terminate processing
@@ -2806,7 +2830,7 @@ weights. Custom weights can be passed in as the last parameter of
 `ma_channel_converter_config_init()`.
 `ma_channel_converter_config_init()`.
 
 
 Predefined channel maps can be retrieved with `ma_channel_map_init_standard()`. This takes a
 Predefined channel maps can be retrieved with `ma_channel_map_init_standard()`. This takes a
-`ma_standard_channel_map` enum as it's first parameter, which can be one of the following:
+`ma_standard_channel_map` enum as its first parameter, which can be one of the following:
 
 
     +-----------------------------------+-----------------------------------------------------------+
     +-----------------------------------+-----------------------------------------------------------+
     | Name                              | Description                                               |
     | Name                              | Description                                               |
@@ -2892,7 +2916,7 @@ like the following:
         ma_resample_algorithm_linear);
         ma_resample_algorithm_linear);
 
 
     ma_resampler resampler;
     ma_resampler resampler;
-    ma_result result = ma_resampler_init(&config, &resampler);
+    ma_result result = ma_resampler_init(&config, NULL, &resampler);
     if (result != MA_SUCCESS) {
     if (result != MA_SUCCESS) {
         // An error occurred...
         // An error occurred...
     }
     }
@@ -3134,7 +3158,7 @@ Biquad filtering is achieved with the `ma_biquad` API. Example:
 
 
     ```c
     ```c
     ma_biquad_config config = ma_biquad_config_init(ma_format_f32, channels, b0, b1, b2, a0, a1, a2);
     ma_biquad_config config = ma_biquad_config_init(ma_format_f32, channels, b0, b1, b2, a0, a1, a2);
-    ma_result result = ma_biquad_init(&config, &biquad);
+    ma_result result = ma_biquad_init(&config, NULL, &biquad);
     if (result != MA_SUCCESS) {
     if (result != MA_SUCCESS) {
         // Error.
         // Error.
     }
     }

+ 8 - 4
vendor/miniaudio/engine.odin

@@ -18,7 +18,8 @@ sound_flag :: enum c.int {
 	ASYNC                 = 2,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC */
 	ASYNC                 = 2,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC */
 	WAIT_INIT             = 3,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT */
 	WAIT_INIT             = 3,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT */
 	UNKNOWN_LENGTH        = 4,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH */
 	UNKNOWN_LENGTH        = 4,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH */
-	
+	LOOPING               = 5,   /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING */
+
 	/* ma_sound specific flags. */
 	/* ma_sound specific flags. */
 	NO_DEFAULT_ATTACHMENT = 12,  /* Do not attach to the endpoint by default. Useful for when setting up nodes in a complex graph system. */
 	NO_DEFAULT_ATTACHMENT = 12,  /* Do not attach to the endpoint by default. Useful for when setting up nodes in a complex graph system. */
 	NO_PITCH              = 13,  /* Disable pitch shifting with ma_sound_set_pitch() and ma_sound_group_set_pitch(). This is an optimization. */
 	NO_PITCH              = 13,  /* Disable pitch shifting with ma_sound_set_pitch() and ma_sound_group_set_pitch(). This is an optimization. */
@@ -51,7 +52,7 @@ engine_node_config :: struct {
 
 
 /* Base node object for both ma_sound and ma_sound_group. */
 /* Base node object for both ma_sound and ma_sound_group. */
 engine_node :: struct {
 engine_node :: struct {
-	baseNode:                    node_base,           /* Must be the first member for compatiblity with the ma_node API. */
+	baseNode:                    node_base,           /* Must be the first member for compatibility with the ma_node API. */
 	pEngine:                     ^engine,             /* A pointer to the engine. Set based on the value from the config. */
 	pEngine:                     ^engine,             /* A pointer to the engine. Set based on the value from the config. */
 	sampleRate:                  u32,                 /* 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. */
 	sampleRate:                  u32,                 /* 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. */
 	volumeSmoothTimeInPCMFrames: u32,
 	volumeSmoothTimeInPCMFrames: u32,
@@ -113,7 +114,6 @@ sound_config :: struct {
 	rangeEndInPCMFrames:            u64,
 	rangeEndInPCMFrames:            u64,
 	loopPointBegInPCMFrames:        u64,
 	loopPointBegInPCMFrames:        u64,
 	loopPointEndInPCMFrames:        u64,
 	loopPointEndInPCMFrames:        u64,
-	isLooping:                      b32,
 
 
 	endCallback:          sound_end_proc, /* 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_*(). */
 	endCallback:          sound_end_proc, /* 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_*(). */
 	pEndCallbackUserData: rawptr,
 	pEndCallbackUserData: rawptr,
@@ -121,6 +121,8 @@ sound_config :: struct {
 	initNotifications: resource_manager_pipeline_notifications,
 	initNotifications: resource_manager_pipeline_notifications,
 
 
 	pDoneFence: ^fence, /* Deprecated. Use initNotifications instead. Released when the resource manager has finished decoding the entire sound. Not used with streams. */
 	pDoneFence: ^fence, /* Deprecated. Use initNotifications instead. Released when the resource manager has finished decoding the entire sound. Not used with streams. */
+
+	isLooping: b32, /* Deprecated. Use the MA_SOUND_FLAG_LOOPING in `flags` instead. */
 }
 }
 
 
 sound :: struct {
 sound :: struct {
@@ -226,6 +228,7 @@ foreign lib {
 	sound_is_looping                         :: proc(pSound: ^sound) -> b32 ---
 	sound_is_looping                         :: proc(pSound: ^sound) -> b32 ---
 	sound_at_end                             :: proc(pSound: ^sound) -> b32 ---
 	sound_at_end                             :: proc(pSound: ^sound) -> b32 ---
 	sound_seek_to_pcm_frame                  :: proc(pSound: ^sound, frameIndex: u64) -> result --- /* Just a wrapper around ma_data_source_seek_to_pcm_frame(). */
 	sound_seek_to_pcm_frame                  :: proc(pSound: ^sound, frameIndex: u64) -> result --- /* Just a wrapper around ma_data_source_seek_to_pcm_frame(). */
+	sound_seek_to_second                     :: proc(pSound: ^sound, seekPointInSeconds: f32) -> result --- /* Abstraction to ma_sound_seek_to_pcm_frame() */
 	sound_get_data_format                    :: proc(pSound: ^sound, pFormat: ^format, pChannels, pSampleRate: ^u32, pChannelMap: ^channel, channelMapCap: c.size_t) -> result ---
 	sound_get_data_format                    :: proc(pSound: ^sound, pFormat: ^format, pChannels, pSampleRate: ^u32, pChannelMap: ^channel, channelMapCap: c.size_t) -> result ---
 	sound_get_cursor_in_pcm_frames           :: proc(pSound: ^sound, pCursor: ^u64) -> result ---
 	sound_get_cursor_in_pcm_frames           :: proc(pSound: ^sound, pCursor: ^u64) -> result ---
 	sound_get_length_in_pcm_frames           :: proc(pSound: ^sound, pLength: ^u64) -> result ---
 	sound_get_length_in_pcm_frames           :: proc(pSound: ^sound, pLength: ^u64) -> result ---
@@ -323,6 +326,7 @@ engine_config :: struct {
 	gainSmoothTimeInMilliseconds: u32,                    /* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
 	gainSmoothTimeInMilliseconds: u32,                    /* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
 
 
 	defaultVolumeSmoothTimeInPCMFrames: u32,              /* 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). */
 	defaultVolumeSmoothTimeInPCMFrames: u32,              /* 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). */
+	preMixStackSizeInBytes:             u32,              /* A stack is used for internal processing in the node graph. This allows you to configure the size of this stack. Smaller values will reduce the maximum depth of your node graph. You should rarely need to modify this. */
 
 
 	allocationCallbacks:          allocation_callbacks,
 	allocationCallbacks:          allocation_callbacks,
 	noAutoStart:                  b32,                    /* 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(). */
 	noAutoStart:                  b32,                    /* 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(). */
@@ -344,7 +348,7 @@ engine :: struct {
 	allocationCallbacks:    allocation_callbacks,
 	allocationCallbacks:    allocation_callbacks,
 	ownsResourceManager:    b8,
 	ownsResourceManager:    b8,
 	ownsDevice:             b8,
 	ownsDevice:             b8,
-	inlinedSoundLock:       spinlock,                     /* For synchronizing access so the inlined sound list. */
+	inlinedSoundLock:       spinlock,                     /* For synchronizing access to the inlined sound list. */
 	pInlinedSoundHead:      ^sound_inlined,               /* The first inlined sound. Inlined sounds are tracked in a linked list. */
 	pInlinedSoundHead:      ^sound_inlined,               /* The first inlined sound. Inlined sounds are tracked in a linked list. */
 	inlinedSoundCount:      u32, /*atomic*/               /* The total number of allocated inlined sound objects. Used for debugging. */
 	inlinedSoundCount:      u32, /*atomic*/               /* The total number of allocated inlined sound objects. Used for debugging. */
 	gainSmoothTimeInFrames: u32,                          /* The number of frames to interpolate the gain of spatialized sounds across. */
 	gainSmoothTimeInFrames: u32,                          /* The number of frames to interpolate the gain of spatialized sounds across. */

BIN
vendor/miniaudio/lib/miniaudio.lib


+ 23 - 9
vendor/miniaudio/node_graph.odin

@@ -19,6 +19,13 @@ MAX_NODE_LOCAL_BUS_COUNT :: 2
 /* Use this when the bus count is determined by the node instance rather than the vtable. */
 /* Use this when the bus count is determined by the node instance rather than the vtable. */
 NODE_BUS_COUNT_UNKNOWN :: 255
 NODE_BUS_COUNT_UNKNOWN :: 255
 
 
+/* For some internal memory management of ma_node_graph. */
+stack :: struct {
+	offset:      uint,
+	sizeInBytes: uint,
+	_data:       [1]byte,
+}
+
 node :: struct {}
 node :: struct {}
 
 
 /* Node flags. */
 /* Node flags. */
@@ -53,7 +60,7 @@ node_vtable :: struct {
 	onProcess: proc "c" (pNode: ^node, ppFramesIn: ^[^]f32, pFrameCountIn: ^u32, ppFramesOut: ^[^]f32, pFrameCountOut: ^u32),
 	onProcess: proc "c" (pNode: ^node, ppFramesIn: ^[^]f32, pFrameCountIn: ^u32, ppFramesOut: ^[^]f32, pFrameCountOut: ^u32),
 
 
 	/*
 	/*
-	A callback for retrieving the number of a input frames that are required to output the
+	A callback for retrieving the number of input frames that are required to output the
 	specified number of output frames. You would only want to implement this when the node performs
 	specified number of output frames. You would only want to implement this when the node performs
 	resampling. This is optional, even for nodes that perform resampling, but it does offer a
 	resampling. This is optional, even for nodes that perform resampling, but it does offer a
 	small reduction in latency as it allows miniaudio to calculate the exact number of input frames
 	small reduction in latency as it allows miniaudio to calculate the exact number of input frames
@@ -134,8 +141,12 @@ node_input_bus :: struct {
 
 
 node_base :: struct {
 node_base :: struct {
 	/* These variables are set once at startup. */
 	/* These variables are set once at startup. */
-	pNodeGraph:                  ^node_graph,     /* The graph this node belongs to. */
+	pNodeGraph:                  ^node_graph,       /* The graph this node belongs to. */
 	vtable:                      ^node_vtable,
 	vtable:                      ^node_vtable,
+	inputBusCount:               u32,
+	outputBusCount:              u32,
+	pInputBuses:                 [^]node_input_bus  `fmt:"v,inputBusCount"`,
+	pOutputBuses:                [^]node_output_bus `fmt:"v,outputBusCount"`,
 	pCachedData:                 [^]f32,            /* Allocated on the heap. Fixed size. Needs to be stored on the heap because reading from output buses is done in separate function calls. */
 	pCachedData:                 [^]f32,            /* Allocated on the heap. Fixed size. Needs to be stored on the heap because reading from output buses is done in separate function calls. */
 	cachedDataCapInFramesPerBus: u16,               /* The capacity of the input data cache in frames, per bus. */
 	cachedDataCapInFramesPerBus: u16,               /* The capacity of the input data cache in frames, per bus. */
 
 
@@ -148,10 +159,6 @@ node_base :: struct {
 	state:          node_state, /*atomic*/      /* When set to stopped, nothing will be read, regardless of the times in stateTimes. */
 	state:          node_state, /*atomic*/      /* When set to stopped, nothing will be read, regardless of the times in stateTimes. */
 	stateTimes:     [2]u64, /*atomic*/          /* 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. */
 	stateTimes:     [2]u64, /*atomic*/          /* 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. */
 	localTime:      u64, /*atomic*/             /* 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()`. */
 	localTime:      u64, /*atomic*/             /* 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()`. */
-	inputBusCount:  u32,
-	outputBusCount: u32,
-	pInputBuses:    [^]node_input_bus,
-	pOutputBuses:   [^]node_output_bus,
 
 
 	/* Memory management. */
 	/* Memory management. */
 	_inputBuses:  [MAX_NODE_LOCAL_BUS_COUNT]node_input_bus,
 	_inputBuses:  [MAX_NODE_LOCAL_BUS_COUNT]node_input_bus,
@@ -189,18 +196,25 @@ foreign lib {
 }
 }
 
 
 node_graph_config :: struct {
 node_graph_config :: struct {
-	channels:             u32,
-	nodeCacheCapInFrames: u16,
+	channels:               u32,
+	processingSizeInFrames: u32,  /* This is the preferred processing size for node processing callbacks unless overridden by a node itself. Can be 0 in which case it will be based on the frame count passed into ma_node_graph_read_pcm_frames(), but will not be well defined. */
+	preMixStackSizeInBytes: uint, /* Defaults to 512KB per channel. Reducing this will save memory, but the depth of your node graph will be more restricted. */
 }
 }
 
 
 node_graph :: struct {
 node_graph :: struct {
 	/* Immutable. */
 	/* Immutable. */
 	base:                 node_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. */
 	base:                 node_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. */
 	endpoint:             node_base,       /* Special node that all nodes eventually connect to. Data is read from this node in ma_node_graph_read_pcm_frames(). */
 	endpoint:             node_base,       /* Special node that all nodes eventually connect to. Data is read from this node in ma_node_graph_read_pcm_frames(). */
-	nodeCacheCapInFrames: u16,
+
+	pProcessingCache:               [^]f32, /* This will be allocated when processingSizeInFrames is non-zero. This is needed because ma_node_graph_read_pcm_frames() can be called with a variable number of frames, and we may need to do some buffering in situations where the caller requests a frame count that's not a multiple of processingSizeInFrames. */
+	processingCacheFramesRemaining: u32,
+	processingSizeInFrames:         u32,
 
 
 	/* Read and written by multiple threads. */
 	/* Read and written by multiple threads. */
 	isReading:            b32, /*atomic*/
 	isReading:            b32, /*atomic*/
+
+	/* Modified only by the audio thread. */
+	pPreMixStack: ^stack,
 }
 }
 
 
 @(default_calling_convention="c", link_prefix="ma_")
 @(default_calling_convention="c", link_prefix="ma_")

+ 2 - 1
vendor/miniaudio/resource_manager.odin

@@ -16,6 +16,7 @@ resource_manager_data_source_flag :: enum c.int {
 	ASYNC          = 2,   /* When set, the resource manager will load the data source asynchronously. */
 	ASYNC          = 2,   /* When set, the resource manager will load the data source asynchronously. */
 	WAIT_INIT      = 3,   /* When set, waits for initialization of the underlying data source before returning from ma_resource_manager_data_source_init(). */
 	WAIT_INIT      = 3,   /* When set, waits for initialization of the underlying data source before returning from ma_resource_manager_data_source_init(). */
 	UNKNOWN_LENGTH = 4,   /* 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. */
 	UNKNOWN_LENGTH = 4,   /* 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. */
+	LOOPING        = 5,   /* When set, configures the data source to loop by default. */
 }
 }
 
 
 resource_manager_data_source_flags :: bit_set[resource_manager_data_source_flag; u32]
 resource_manager_data_source_flags :: bit_set[resource_manager_data_source_flag; u32]
@@ -79,8 +80,8 @@ resource_manager_data_source_config :: struct {
 	rangeEndInPCMFrames:         u64,
 	rangeEndInPCMFrames:         u64,
 	loopPointBegInPCMFrames:     u64,
 	loopPointBegInPCMFrames:     u64,
 	loopPointEndInPCMFrames:     u64,
 	loopPointEndInPCMFrames:     u64,
-	isLooping:                   b32,
 	flags:                       u32,
 	flags:                       u32,
+	isLooping:                   b32, /* Deprecated. Use the MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING flag in `flags` instead. */
 }
 }
 
 
 resource_manager_data_supply_type :: enum c.int {
 resource_manager_data_supply_type :: enum c.int {

Fichier diff supprimé car celui-ci est trop grand
+ 228 - 112
vendor/miniaudio/src/miniaudio.h


+ 5 - 0
vendor/miniaudio/synchronization.odin

@@ -62,6 +62,11 @@ when !NO_THREADING {
 	Signals the specified auto-reset event.
 	Signals the specified auto-reset event.
 	*/
 	*/
 	event_signal :: proc(pEvent: ^event) -> result ---
 	event_signal :: proc(pEvent: ^event) -> result ---
+
+	semaphore_init    :: proc(initialValue: i32, pSemaphore: ^semaphore) -> result ---
+	semaphore_uninit  :: proc(pSemaphore: ^semaphore) ---
+	semaphore_wait    :: proc(pSemaphore: ^semaphore) -> result ---
+	semaphore_release :: proc(pSemaphore: ^semaphore) -> result ---
 } /* NO_THREADING */
 } /* NO_THREADING */
 
 
 }
 }

+ 3 - 1
vendor/miniaudio/utilities.odin

@@ -7,7 +7,7 @@ foreign import lib { LIB }
 @(default_calling_convention="c", link_prefix="ma_")
 @(default_calling_convention="c", link_prefix="ma_")
 foreign lib {
 foreign lib {
 	/*
 	/*
-	Calculates a buffer size in milliseconds from the specified number of frames and sample rate.
+	Calculates a buffer size in milliseconds (rounded up) from the specified number of frames and sample rate.
 	*/
 	*/
 	calculate_buffer_size_in_milliseconds_from_frames :: proc(bufferSizeInFrames: u32, sampleRate: u32) -> u32 ---
 	calculate_buffer_size_in_milliseconds_from_frames :: proc(bufferSizeInFrames: u32, sampleRate: u32) -> u32 ---
 
 
@@ -163,6 +163,8 @@ foreign lib {
 	data_source_read_pcm_frames              :: proc(pDataSource: ^data_source, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---   /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
 	data_source_read_pcm_frames              :: proc(pDataSource: ^data_source, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---   /* Must support pFramesOut = NULL in which case a forward seek should be performed. */
 	data_source_seek_pcm_frames              :: proc(pDataSource: ^data_source, frameCount: u64, pFramesSeeked: ^u64) -> result --- /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount); */
 	data_source_seek_pcm_frames              :: proc(pDataSource: ^data_source, frameCount: u64, pFramesSeeked: ^u64) -> result --- /* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount); */
 	data_source_seek_to_pcm_frame            :: proc(pDataSource: ^data_source, frameIndex: u64) -> result ---
 	data_source_seek_to_pcm_frame            :: proc(pDataSource: ^data_source, frameIndex: u64) -> result ---
+	data_source_seek_seconds                 :: proc(pDataSource: ^data_source, secondCount: f32, pSecondsSeeked: ^f32) -> result --- /* Can only seek forward. Abstraction to ma_data_source_seek_pcm_frames() */
+	data_source_seek_to_seconds              :: proc(pDataSource: ^data_source, seekPointInSeconds: f32) -> result --- /* Abstraction to ma_data_source_seek_to_pcm_frame() */
 	data_source_get_data_format              :: proc(pDataSource: ^data_source, pFormat: ^format, pChannels: ^u32, pSampleRate: ^u32, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
 	data_source_get_data_format              :: proc(pDataSource: ^data_source, pFormat: ^format, pChannels: ^u32, pSampleRate: ^u32, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
 	data_source_get_cursor_in_pcm_frames     :: proc(pDataSource: ^data_source, pCursor: ^u64) -> result ---
 	data_source_get_cursor_in_pcm_frames     :: proc(pDataSource: ^data_source, pCursor: ^u64) -> result ---
 	data_source_get_length_in_pcm_frames     :: proc(pDataSource: ^data_source, pLength: ^u64) -> result ---    /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */
 	data_source_get_length_in_pcm_frames     :: proc(pDataSource: ^data_source, pLength: ^u64) -> result ---    /* Returns MA_NOT_IMPLEMENTED if the length is unknown or cannot be determined. Decoders can return this. */

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff