* Starting from version 0.12, miniaudio will be switching to a split .c/h pair, away from a single header. In preparation for this, a file named "miniaudio.c" has been added to repository. Currently this is just a simple wrapper around miniaudio.h and `MINIAUDIO_IMPLEMENTATION`. Nothing has changed in miniaudio.h, however when version 0.12 is released you will need to use miniaudio.c for the implementation. It's recommended you start the transition away from `MINIAUDIO_IMPLEMENTATION` and towards miniaudio.c. If you want to keep building your project as a single translation unit, you can do `#include "miniaudio.c"` which will continue to be supported with version 0.12 and beyond.
* Starting from version 0.12, miniaudio will be switching to a split .c/h pair, away from a single header. In preparation for this, a file named "miniaudio.c" has been added to repository. Currently this is just a simple wrapper around miniaudio.h and `MINIAUDIO_IMPLEMENTATION`. Nothing has changed in miniaudio.h, however when version 0.12 is released you will need to use miniaudio.c for the implementation. It's recommended you start the transition away from `MINIAUDIO_IMPLEMENTATION` and towards miniaudio.c. If you want to keep building your project as a single translation unit, you can do `#include "miniaudio.c"` which will continue to be supported with version 0.12 and beyond.
* In the extras folder, the `miniaudio_libvorbis.h` and `miniaudio_libopus.h` files have been deprecated. They have been replaced with versions in the `extras/decoders` folder. They are now split into a separate .c and .h files. The old files still exist for compatibility, but you need to transition over to the new versions. The transition should be trivial. Compile the .c files like a normal source file, and include the .h file like a normal header.
* In the extras folder, the `miniaudio_libvorbis.h` and `miniaudio_libopus.h` files have been deprecated. They have been replaced with versions in the `extras/decoders` folder. They are now split into a separate .c and .h files. The old files still exist for compatibility, but you need to transition over to the new versions. The transition should be trivial. Compile the .c files like a normal source file, and include the .h file like a normal header.
MA_APIma_resultma_data_source_read_pcm_frames(ma_data_source*pDataSource,void*pFramesOut,ma_uint64frameCount,ma_uint64*pFramesRead);/* Must support pFramesOut = NULL in which case a forward seek should be performed. */
MA_APIma_resultma_data_source_read_pcm_frames(ma_data_source*pDataSource,void*pFramesOut,ma_uint64frameCount,ma_uint64*pFramesRead);/* Must support pFramesOut = NULL in which case a forward seek should be performed. */
MA_APIma_resultma_data_source_seek_pcm_frames(ma_data_source*pDataSource,ma_uint64frameCount,ma_uint64*pFramesSeeked);/* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount, &framesRead); */
MA_APIma_resultma_data_source_seek_pcm_frames(ma_data_source*pDataSource,ma_uint64frameCount,ma_uint64*pFramesSeeked);/* Can only seek forward. Equivalent to ma_data_source_read_pcm_frames(pDataSource, NULL, frameCount, &framesRead); */
MA_APIma_resultma_data_source_seek_seconds(ma_data_source*pDataSource,floatsecondCount,float*pSecondsSeeked);/* Can only seek forward. Abstraction to ma_data_source_seek_pcm_frames() */
MA_APIma_resultma_data_source_seek_to_second(ma_data_source*pDataSource,floatseekPointInSeconds);/* Abstraction to ma_data_source_seek_to_pcm_frame() */
MA_APIma_resultma_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. */
MA_APIma_resultma_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. */
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
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 allocate an index that can be used
as the insertion point for an object.
as the insertion point for an object.
Slots are reference counted to help mitigate the ABA problem in the lock-free queue we use for tracking jobs.
Slots are reference counted to help mitigate the ABA problem in the lock-free queue we use for tracking jobs.
...
@@ -3303,6 +3310,8 @@ typedef union
...
@@ -3303,6 +3310,8 @@ typedef union
intnullbackend;/* The null backend uses an integer for device IDs. */
intnullbackend;/* The null backend uses an integer for device IDs. */
@@ -3481,7 +3492,7 @@ and on output returns detailed information about the device in `ma_device_info`.
...
@@ -3481,7 +3492,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
...
@@ -3502,10 +3513,10 @@ asynchronous reading and writing, `onDeviceStart()` and `onDeviceStop()` should
...
@@ -3502,10 +3513,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
...
@@ -4244,6 +4255,7 @@ struct ma_device
...
@@ -4244,6 +4255,7 @@ struct ma_device
{
{
/*AAudioStream**/ma_ptrpStreamPlayback;
/*AAudioStream**/ma_ptrpStreamPlayback;
/*AAudioStream**/ma_ptrpStreamCapture;
/*AAudioStream**/ma_ptrpStreamCapture;
ma_mutexrerouteLock;
ma_aaudio_usageusage;
ma_aaudio_usageusage;
ma_aaudio_content_typecontentType;
ma_aaudio_content_typecontentType;
ma_aaudio_input_presetinputPreset;
ma_aaudio_input_presetinputPreset;
...
@@ -4667,6 +4679,10 @@ Retrieves basic information about every active playback and/or capture device.
...
@@ -4667,6 +4679,10 @@ Retrieves basic information about every active playback and/or capture device.
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
----------
----------
...
@@ -4708,7 +4724,7 @@ The returned pointers will become invalid upon the next call this this function,
...
@@ -4708,7 +4724,7 @@ The returned pointers will become invalid upon the next call this this function,
@@ -4847,7 +4863,7 @@ from a microphone. Whether or not you should send or receive data from the devic
...
@@ -4847,7 +4863,7 @@ from a microphone. Whether or not you should send or receive data from the devic
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
...
@@ -4921,7 +4937,7 @@ then be set directly on the structure. Below are the members of the `ma_device_c
...
@@ -4921,7 +4937,7 @@ then be set directly on the structure. Below are the members of the `ma_device_c
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
...
@@ -4961,7 +4977,7 @@ then be set directly on the structure. Below are the members of the `ma_device_c
...
@@ -4961,7 +4977,7 @@ then be set directly on the structure. Below are the members of the `ma_device_c
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)`.
...
@@ -5038,6 +5054,9 @@ then be set directly on the structure. Below are the members of the `ma_device_c
...
@@ -5038,6 +5054,9 @@ then be set directly on the structure. Below are the members of the `ma_device_c
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
...
@@ -5211,7 +5230,7 @@ Unsafe. It is not safe to call this inside any callback.
...
@@ -5211,7 +5230,7 @@ Unsafe. It is not safe to call this inside any callback.
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.
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.
*/
*/
...
@@ -6537,7 +6556,8 @@ typedef enum
...
@@ -6537,7 +6556,8 @@ typedef enum
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. */
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. */
MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC=0x00000004,/* When set, the resource manager will load the data source asynchronously. */
MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC=0x00000004,/* When set, the resource manager will load the data source asynchronously. */
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(). */
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(). */
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. */
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. */
MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING=0x00000020/* When set, configures the data source to loop by default. */
}ma_resource_manager_data_source_flags;
}ma_resource_manager_data_source_flags;
...
@@ -6605,8 +6625,8 @@ typedef struct
...
@@ -6605,8 +6625,8 @@ typedef struct
ma_uint64rangeEndInPCMFrames;
ma_uint64rangeEndInPCMFrames;
ma_uint64loopPointBegInPCMFrames;
ma_uint64loopPointBegInPCMFrames;
ma_uint64loopPointEndInPCMFrames;
ma_uint64loopPointEndInPCMFrames;
ma_bool32isLooping;
ma_uint32flags;
ma_uint32flags;
ma_bool32isLooping;/* Deprecated. Use the MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_LOOPING flag in `flags` instead. */
ma_node_graph*pNodeGraph;/* The graph this node belongs to. */
ma_node_graph*pNodeGraph;/* The graph this node belongs to. */
constma_node_vtable*vtable;
constma_node_vtable*vtable;
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. */
ma_uint32inputBusCount;
ma_uint16cachedDataCapInFramesPerBus;/* The capacity of the input data cache in frames, per bus. */
ma_uint32outputBusCount;
ma_node_input_bus*pInputBuses;
ma_node_output_bus*pOutputBuses;
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. */
ma_uint16cachedDataCapInFramesPerBus;/* The capacity of the input data cache in frames, per bus. */
/* These variables are read and written only from the audio thread. */
/* These variables are read and written only from the audio thread. */
ma_uint16cachedFrameCountOut;
ma_uint16cachedFrameCountOut;
...
@@ -6984,13 +7018,9 @@ struct ma_node_base
...
@@ -6984,13 +7018,9 @@ struct ma_node_base
ma_uint16consumedFrameCountIn;
ma_uint16consumedFrameCountIn;
/* These variables are read and written between different threads. */
/* These variables are read and written between different threads. */
MA_ATOMIC(4,ma_node_state)state;/* When set to stopped, nothing will be read, regardless of the times in stateTimes. */
MA_ATOMIC(4,ma_node_state)state;/* When set to stopped, nothing will be read, regardless of the times in stateTimes. */
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. */
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. */
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()`. */
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()`. */
ma_uint32processingSizeInFrames;/* 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. */
size_tpreMixStackSizeInBytes;/* Defaults to 512KB per channel. Reducing this will save memory, but the depth of your node graph will be more restricted. */
ma_node_basebase;/* 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. */
ma_node_basebase;/* 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. */
ma_node_baseendpoint;/* Special node that all nodes eventually connect to. Data is read from this node in ma_node_graph_read_pcm_frames(). */
ma_node_baseendpoint;/* Special node that all nodes eventually connect to. Data is read from this node in ma_node_graph_read_pcm_frames(). */
ma_uint16nodeCacheCapInFrames;
float*pProcessingCache;/* 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. */
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. */
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. */
/* Base node object for both ma_sound and ma_sound_group. */
/* Base node object for both ma_sound and ma_sound_group. */
typedefstruct
typedefstruct
{
{
ma_node_basebaseNode;/* Must be the first member for compatiblity with the ma_node API. */
ma_node_basebaseNode;/* Must be the first member for compatibility with the ma_node API. */
ma_engine*pEngine;/* A pointer to the engine. Set based on the value from the config. */
ma_engine*pEngine;/* A pointer to the engine. Set based on the value from the config. */
ma_uint32sampleRate;/* 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. */
ma_uint32sampleRate;/* 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. */
ma_uint32volumeSmoothTimeInPCMFrames;
ma_uint32volumeSmoothTimeInPCMFrames;
...
@@ -7424,13 +7461,13 @@ typedef struct
...
@@ -7424,13 +7461,13 @@ typedef struct
ma_uint64rangeEndInPCMFrames;
ma_uint64rangeEndInPCMFrames;
ma_uint64loopPointBegInPCMFrames;
ma_uint64loopPointBegInPCMFrames;
ma_uint64loopPointEndInPCMFrames;
ma_uint64loopPointEndInPCMFrames;
ma_bool32isLooping;
ma_sound_end_procendCallback;/* 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_*(). */
ma_sound_end_procendCallback;/* 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_*(). */
ma_fence*pDoneFence;/* Deprecated. Use initNotifications instead. Released when the resource manager has finished decoding the entire sound. Not used with streams. */
ma_fence*pDoneFence;/* Deprecated. Use initNotifications instead. Released when the resource manager has finished decoding the entire sound. Not used with streams. */
ma_bool32isLooping;/* Deprecated. Use the MA_SOUND_FLAG_LOOPING flag in `flags` instead. */
}ma_sound_config;
}ma_sound_config;
MA_APIma_sound_configma_sound_config_init(void);/* Deprecated. Will be removed in version 0.12. Use ma_sound_config_2() instead. */
MA_APIma_sound_configma_sound_config_init(void);/* Deprecated. Will be removed in version 0.12. Use ma_sound_config_2() instead. */
...
@@ -7494,6 +7531,7 @@ typedef struct
...
@@ -7494,6 +7531,7 @@ typedef struct
ma_uint32gainSmoothTimeInFrames;/* The number of frames to interpolate the gain of spatialized sounds across. If set to 0, will use gainSmoothTimeInMilliseconds. */
ma_uint32gainSmoothTimeInFrames;/* The number of frames to interpolate the gain of spatialized sounds across. If set to 0, will use gainSmoothTimeInMilliseconds. */
ma_uint32gainSmoothTimeInMilliseconds;/* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
ma_uint32gainSmoothTimeInMilliseconds;/* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
ma_uint32defaultVolumeSmoothTimeInPCMFrames;/* 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). */
ma_uint32defaultVolumeSmoothTimeInPCMFrames;/* 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). */
ma_uint32preMixStackSizeInBytes;/* 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. */
ma_allocation_callbacksallocationCallbacks;
ma_allocation_callbacksallocationCallbacks;
ma_bool32noAutoStart;/* 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(). */
ma_bool32noAutoStart;/* 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(). */
ma_bool32noDevice;/* When set to true, don't create a default device. ma_engine_read_pcm_frames() can be called manually to read data. */
ma_bool32noDevice;/* When set to true, don't create a default device. ma_engine_read_pcm_frames() can be called manually to read data. */
ma_node_graphnodeGraph;/* 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. */
ma_node_graphnodeGraph;/* 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. */
#if !defined(MA_NO_RESOURCE_MANAGER)
#if !defined(MA_NO_RESOURCE_MANAGER)
ma_resource_manager*pResourceManager;
ma_resource_manager*pResourceManager;
#endif
#endif
#if !defined(MA_NO_DEVICE_IO)
#if !defined(MA_NO_DEVICE_IO)
ma_device*pDevice;/* Optionally set via the config, otherwise allocated by the engine in ma_engine_init(). */
ma_device*pDevice;/* Optionally set via the config, otherwise allocated by the engine in ma_engine_init(). */
#endif
#endif
ma_log*pLog;
ma_log*pLog;
ma_uint32sampleRate;
ma_uint32sampleRate;
...
@@ -7522,10 +7560,10 @@ struct ma_engine
...
@@ -7522,10 +7560,10 @@ struct ma_engine
ma_allocation_callbacksallocationCallbacks;
ma_allocation_callbacksallocationCallbacks;
ma_bool8ownsResourceManager;
ma_bool8ownsResourceManager;
ma_bool8ownsDevice;
ma_bool8ownsDevice;
ma_spinlockinlinedSoundLock;/* For synchronizing access so the inlined sound list. */
ma_spinlockinlinedSoundLock;/* For synchronizing access to the inlined sound list. */
ma_sound_inlined*pInlinedSoundHead;/* The first inlined sound. Inlined sounds are tracked in a linked list. */
ma_sound_inlined*pInlinedSoundHead;/* The first inlined sound. Inlined sounds are tracked in a linked list. */
MA_ATOMIC(4,ma_uint32)inlinedSoundCount;/* The total number of allocated inlined sound objects. Used for debugging. */
MA_ATOMIC(4,ma_uint32)inlinedSoundCount;/* The total number of allocated inlined sound objects. Used for debugging. */
ma_uint32gainSmoothTimeInFrames;/* The number of frames to interpolate the gain of spatialized sounds across. */
ma_uint32gainSmoothTimeInFrames;/* The number of frames to interpolate the gain of spatialized sounds across. */