use bit sets in miniaudio for flags

This commit is contained in:
wrapperup
2024-12-16 18:34:22 -05:00
parent 8b1c9b0ff5
commit c64f13a0eb
7 changed files with 90 additions and 61 deletions

View File

@@ -351,8 +351,13 @@ device_id :: struct #raw_union {
nullbackend: c.int, /* The null backend uses an integer for device IDs. */
}
data_format_flag :: enum c.int {
EXCLUSIVE_MODE = 1, /* If set, this is supported in exclusive mode. Otherwise not natively supported by exclusive mode. */
}
DATA_FORMAT_FLAG_EXCLUSIVE_MODE :: 1 << 1 /* If set, this is supported in exclusive mode. Otherwise not natively supported by exclusive mode. */
data_format_flags :: bit_set[data_format_flag; u32]
DATA_FORMAT_FLAG_EXCLUSIVE_MODE :: data_format_flags{.EXCLUSIVE_MODE}
MAX_DEVICE_NAME_LENGTH :: 255
@@ -364,10 +369,10 @@ device_info :: struct {
nativeDataFormatCount: u32,
nativeDataFormats: [/*len(format_count) * standard_sample_rate.rate_count * MAX_CHANNELS*/ 64]struct { /* Not sure how big to make this. There can be *many* permutations for virtual devices which can support anything. */
format: format, /* Sample format. If set to ma_format_unknown, all sample formats are supported. */
channels: u32, /* If set to 0, all channels are supported. */
sampleRate: u32, /* If set to 0, all sample rates are supported. */
flags: u32, /* A combination of MA_DATA_FORMAT_FLAG_* flags. */
format: format, /* Sample format. If set to ma_format_unknown, all sample formats are supported. */
channels: u32, /* If set to 0, all channels are supported. */
sampleRate: u32, /* If set to 0, all sample rates are supported. */
flags: data_format_flags, /* A combination of MA_DATA_FORMAT_FLAG_* flags. */
},
}

View File

@@ -11,20 +11,22 @@ Engine
************************************************************************************************************************************************************/
/* Sound flags. */
sound_flags :: enum c.int {
sound_flag :: enum c.int {
/* Resource manager flags. */
STREAM = 0x00000001, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM */
DECODE = 0x00000002, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE */
ASYNC = 0x00000004, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC */
WAIT_INIT = 0x00000008, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT */
UNKNOWN_LENGTH = 0x00000010, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH */
STREAM = 0, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_STREAM */
DECODE = 1, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_DECODE */
ASYNC = 2, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_ASYNC */
WAIT_INIT = 3, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_WAIT_INIT */
UNKNOWN_LENGTH = 4, /* MA_RESOURCE_MANAGER_DATA_SOURCE_FLAG_UNKNOWN_LENGTH */
/* ma_sound specific flags. */
NO_DEFAULT_ATTACHMENT = 0x00001000, /* Do not attach to the endpoint by default. Useful for when setting up nodes in a complex graph system. */
NO_PITCH = 0x00002000, /* Disable pitch shifting with ma_sound_set_pitch() and ma_sound_group_set_pitch(). This is an optimization. */
NO_SPATIALIZATION = 0x00004000, /* Disable spatialization. */
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_SPATIALIZATION = 14, /* Disable spatialization. */
}
sound_flags :: bit_set[sound_flag; u32]
ENGINE_MAX_LISTENERS :: 4
LISTENER_INDEX_CLOSEST :: 255
@@ -81,7 +83,7 @@ engine_node :: struct {
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
engine_node_config_init :: proc(pEngine: ^engine, type: engine_node_type, flags: u32) -> engine_node_config ---
engine_node_config_init :: proc(pEngine: ^engine, type: engine_node_type, flags: sound_flags) -> engine_node_config ---
engine_node_get_heap_size :: proc(pConfig: ^engine_node_config, pHeapSizeInBytes: ^c.size_t) -> result ---
engine_node_init_preallocated :: proc(pConfig: ^engine_node_config, pHeap: rawptr, pEngineNode: ^engine_node) -> result ---
@@ -96,17 +98,17 @@ SOUND_SOURCE_CHANNEL_COUNT :: 0xFFFFFFFF
sound_end_proc :: #type proc "c" (pUserData: rawptr, pSound: ^sound)
sound_config :: struct {
pFilePath: cstring, /* Set this to load from the resource manager. */
pFilePathW: [^]c.wchar_t, /* Set this to load from the resource manager. */
pDataSource: ^data_source, /* Set this to load from an existing data source. */
pInitialAttachment: ^node, /* If set, the sound will be attached to an input of this node. This can be set to a ma_sound. If set to NULL, the sound will be attached directly to the endpoint unless MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT is set in `flags`. */
initialAttachmentInputBusIndex: u32, /* The index of the input bus of pInitialAttachment to attach the sound to. */
channelsIn: u32, /* Ignored if using a data source as input (the data source's channel count will be used always). Otherwise, setting to 0 will cause the engine's channel count to be used. */
channelsOut: u32, /* Set this to 0 (default) to use the engine's channel count. Set to MA_SOUND_SOURCE_CHANNEL_COUNT to use the data source's channel count (only used if using a data source as input). */
pFilePath: cstring, /* Set this to load from the resource manager. */
pFilePathW: [^]c.wchar_t, /* Set this to load from the resource manager. */
pDataSource: ^data_source, /* Set this to load from an existing data source. */
pInitialAttachment: ^node, /* If set, the sound will be attached to an input of this node. This can be set to a ma_sound. If set to NULL, the sound will be attached directly to the endpoint unless MA_SOUND_FLAG_NO_DEFAULT_ATTACHMENT is set in `flags`. */
initialAttachmentInputBusIndex: u32, /* The index of the input bus of pInitialAttachment to attach the sound to. */
channelsIn: u32, /* Ignored if using a data source as input (the data source's channel count will be used always). Otherwise, setting to 0 will cause the engine's channel count to be used. */
channelsOut: u32, /* Set this to 0 (default) to use the engine's channel count. Set to MA_SOUND_SOURCE_CHANNEL_COUNT to use the data source's channel count (only used if using a data source as input). */
monoExpansionMode: mono_expansion_mode, /* Controls how the mono channel should be expanded to other channels when spatialization is disabled on a sound. */
flags: u32, /* A combination of MA_SOUND_FLAG_* flags. */
volumeSmoothTimeInPCMFrames: u32, /* The number of frames to smooth over volume changes. Defaults to 0 in which case no smoothing is used. */
initialSeekPointInPCMFrames: u64, /* Initializes the sound such that it's seeked to this location by default. */
flags: sound_flags, /* A combination of MA_SOUND_FLAG_* flags. */
volumeSmoothTimeInPCMFrames: u32, /* The number of frames to smooth over volume changes. Defaults to 0 in which case no smoothing is used. */
initialSeekPointInPCMFrames: u64, /* Initializes the sound such that it's seeked to this location by default. */
rangeBegInPCMFrames: u64,
rangeEndInPCMFrames: u64,
loopPointBegInPCMFrames: u64,
@@ -152,10 +154,10 @@ foreign lib {
sound_config_init :: proc() -> sound_config ---
sound_config_init2 :: proc(pEngine: ^engine) -> sound_config --- /* Will be renamed to sound_config_init() in version 0.12. */
sound_init_from_file :: proc(pEngine: ^engine, pFilePath: cstring, flags: u32, pGroup: ^sound_group, pDoneFence: ^fence, pSound: ^sound) -> result ---
sound_init_from_file_w :: proc(pEngine: ^engine, pFilePath: [^]c.wchar_t, flags: u32, pGroup: ^sound_group, pDoneFence: ^fence, pSound: ^sound) -> result ---
sound_init_copy :: proc(pEngine: ^engine, pExistingSound: ^sound, flags: u32, pGroup: ^sound_group, pSound: ^sound) -> result ---
sound_init_from_data_source :: proc(pEngine: ^engine, pDataSource: ^data_source, flags: u32, pGroup: ^sound_group, pSound: ^sound) -> result ---
sound_init_from_file :: proc(pEngine: ^engine, pFilePath: cstring, flags: sound_flags, pGroup: ^sound_group, pDoneFence: ^fence, pSound: ^sound) -> result ---
sound_init_from_file_w :: proc(pEngine: ^engine, pFilePath: [^]c.wchar_t, flags: sound_flags, pGroup: ^sound_group, pDoneFence: ^fence, pSound: ^sound) -> result ---
sound_init_copy :: proc(pEngine: ^engine, pExistingSound: ^sound, flags: sound_flags, pGroup: ^sound_group, pSound: ^sound) -> result ---
sound_init_from_data_source :: proc(pEngine: ^engine, pDataSource: ^data_source, flags: sound_flags, pGroup: ^sound_group, pSound: ^sound) -> result ---
sound_init_ex :: proc(pEngine: ^engine, pConfig: ^sound_config, pSound: ^sound) -> result ---
sound_uninit :: proc(pSound: ^sound) ---
sound_get_engine :: proc(pSound: ^sound) -> ^engine ---
@@ -243,7 +245,7 @@ foreign lib {
sound_group_config_init :: proc() -> sound_group_config ---
sound_group_config_init2 :: proc(pEngine: ^engine) -> sound_group_config ---
sound_group_init :: proc(pEngine: ^engine, flags: u32, pParentGroup, pGroup: ^sound_group) -> result ---
sound_group_init :: proc(pEngine: ^engine, flags: sound_flags, pParentGroup, pGroup: ^sound_group) -> result ---
sound_group_init_ex :: proc(pEngine: ^engine, pConfig: ^sound_group_config, pGroup: ^sound_group) -> result ---
sound_group_uninit :: proc(pGroup: ^sound_group) ---
sound_group_get_engine :: proc(pGroup: ^sound_group) -> ^engine ---

View File

@@ -108,7 +108,7 @@ job :: struct {
pDataBufferNode: rawptr /*ma_resource_manager_data_buffer_node**/,
pFilePath: cstring,
pFilePathW: [^]c.wchar_t,
flags: u32, /* Resource manager data source flags that were used when initializing the data buffer. */
flags: resource_manager_data_source_flags, /* Resource manager data source flags that were used when initializing the data buffer. */
pInitNotification: ^async_notification, /* Signalled when the data buffer has been initialized and the format/channels/rate can be retrieved. */
pDoneNotification: ^async_notification, /* Signalled when the data buffer has been fully decoded. Will be passed through to MA_JOB_TYPE_RESOURCE_MANAGER_PAGE_DATA_BUFFER_NODE when decoding. */
pInitFence: ^fence, /* Released when initialization of the decoder is complete. */
@@ -194,19 +194,21 @@ ma_job_queue_post(). ma_job_queue_next() will return MA_NO_DATA_AVAILABLE if not
This flag should always be used for platforms that do not support multithreading.
*/
job_queue_flags :: enum c.int {
NON_BLOCKING = 0x00000001,
job_queue_flag :: enum c.int {
NON_BLOCKING = 0,
}
job_queue_flags :: bit_set[job_queue_flag; u32]
job_queue_config :: struct {
flags: u32,
flags: job_queue_flags,
capacity: u32, /* The maximum number of jobs that can fit in the queue at a time. */
}
USE_EXPERIMENTAL_LOCK_FREE_JOB_QUEUE :: false
job_queue :: struct {
flags: u32, /* Flags passed in at initialization time. */
flags: job_queue_flags, /* Flags passed in at initialization time. */
capacity: u32, /* The maximum number of jobs that can fit in the queue at a time. Set by the config. */
head: u64, /*atomic*/ /* The first item in the list. Required for removing from the top of the list. */
tail: u64, /*atomic*/ /* The last item in the list. Required for appending to the end of the list. */
@@ -222,7 +224,7 @@ job_queue :: struct {
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
job_queue_config_init :: proc(flags, capacity: u32) -> job_queue_config ---
job_queue_config_init :: proc(flags: job_queue_flags, capacity: u32) -> job_queue_config ---
job_queue_get_heap_size :: proc(pConfig: ^job_queue_config, pHeapSizeInBytes: ^c.size_t) -> result ---
job_queue_init_preallocated :: proc(pConfig: ^job_queue_config, pHeap: rawptr, pQueue: ^job_queue) -> result ---

View File

@@ -22,14 +22,16 @@ NODE_BUS_COUNT_UNKNOWN :: 255
node :: struct {}
/* Node flags. */
node_flags :: enum c.int {
PASSTHROUGH = 0x00000001,
CONTINUOUS_PROCESSING = 0x00000002,
ALLOW_NULL_INPUT = 0x00000004,
DIFFERENT_PROCESSING_RATES = 0x00000008,
SILENT_OUTPUT = 0x00000010,
node_flag :: enum c.int {
PASSTHROUGH = 0,
CONTINUOUS_PROCESSING = 1,
ALLOW_NULL_INPUT = 2,
DIFFERENT_PROCESSING_RATES = 3,
SILENT_OUTPUT = 4,
}
node_flags :: bit_set[node_flag; u32]
/* The playback state of a node. Either started or stopped. */
node_state :: enum c.int {
started = 0,
@@ -75,7 +77,7 @@ node_vtable :: struct {
Flags describing characteristics of the node. This is currently just a placeholder for some
ideas for later on.
*/
flags: u32,
flags: node_flags,
}
node_config :: struct {
@@ -87,6 +89,12 @@ node_config :: struct {
pOutputChannels: ^u32, /* The number of elements are determined by the output bus count as determined by the vtable, or `outputBusCount` if the vtable specifies `MA_NODE_BUS_COUNT_UNKNOWN`. */
}
node_output_bus_flag :: enum c.int {
HAS_READ = 0, /* 0x01 */
}
node_output_bus_flags :: bit_set[node_output_bus_flag; u32]
/*
A node has multiple output buses. An output bus is attached to an input bus as an item in a linked
list. Think of the input bus as a linked list, with the output bus being an item in that list.
@@ -99,7 +107,7 @@ node_output_bus :: struct {
/* Mutable via multiple threads. Must be used atomically. The weird ordering here is for packing reasons. */
inputNodeInputBusIndex: u8, /* The index of the input bus on the input. Required for detaching. Will only be used in the spinlock so does not need to be atomic. */
flags: u32, /*atomic*/ /* Some state flags for tracking the read state of the output buffer. A combination of MA_NODE_OUTPUT_BUS_FLAG_*. */
flags: node_output_bus_flags, /*atomic*/ /* Some state flags for tracking the read state of the output buffer. A combination of MA_NODE_OUTPUT_BUS_FLAG_*. */
refCount: u32, /*atomic*/ /* Reference count for some thread-safety when detaching. */
isAttached: b32, /*atomic*/ /* This is used to prevent iteration of nodes that are in the middle of being detached. Used for thread safety. */
lock: spinlock, /*atomic*/ /* Unfortunate lock, but significantly simplifies the implementation. Required for thread-safe attaching and detaching. */

View File

@@ -10,14 +10,16 @@ Resource Manager
************************************************************************************************************************************************************/
resource_manager_data_source_flags :: enum c.int {
STREAM = 0x00000001, /* When set, does not load the entire data source in memory. Disk I/O will happen on job threads. */
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. */
ASYNC = 0x00000004, /* When set, the resource manager will load the data source asynchronously. */
WAIT_INIT = 0x00000008, /* When set, waits for initialization of the underlying data source before returning from ma_resource_manager_data_source_init(). */
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. */
resource_manager_data_source_flag :: enum c.int {
STREAM = 0, /* When set, does not load the entire data source in memory. Disk I/O will happen on job threads. */
DECODE = 1, /* 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. */
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(). */
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. */
}
resource_manager_data_source_flags :: bit_set[resource_manager_data_source_flag; u32]
/*
Pipeline notifications used by the resource manager. Made up of both an async notification and a fence, both of which are optional.
*/
@@ -58,7 +60,7 @@ resource_manager_job_queue_next :: job_queue_next
/* Maximum job thread count will be restricted to this, but this may be removed later and replaced with a heap allocation thereby removing any limitation. */
RESOURCE_MANAGER_MAX_JOB_THREAD_COUNT :: 64
resource_manager_flags :: enum c.int {
resource_manager_flag :: enum c.int {
/* Indicates ma_resource_manager_next_job() should not block. Only valid when the job thread count is 0. */
NON_BLOCKING = 0x00000001,
@@ -66,6 +68,8 @@ resource_manager_flags :: enum c.int {
NO_THREADING = 0x00000002,
}
resource_manager_flags :: bit_set[resource_manager_flag; u32]
resource_manager_data_source_config :: struct {
pFilePath: cstring,
pFilePathW: [^]c.wchar_t,
@@ -126,7 +130,7 @@ resource_manager_data_buffer :: struct {
ds: data_source_base, /* Base data source. A data buffer is a data source. */
pResourceManager: ^resource_manager, /* A pointer to the resource manager that owns this buffer. */
pNode: ^resource_manager_data_buffer_node, /* The data node. This is reference counted and is what supplies the data. */
flags: u32, /* The flags that were passed used to initialize the buffer. */
flags: resource_manager_flags, /* The flags that were passed used to initialize the buffer. */
executionCounter: u32, /*atomic*/ /* For allocating execution orders for jobs. */
executionPointer: u32, /*atomic*/ /* For managing the order of execution for asynchronous jobs relating to this object. Incremented as jobs complete processing. */
seekTargetInPCMFrames: u64, /* Only updated by the public API. Never written nor read from the job thread. */

View File

@@ -119,7 +119,13 @@ offset_pcm_frames_const_ptr_f32 :: #force_inline proc "c" (p: [^]f32, offsetInFr
data_source :: struct {}
DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT :: 0x00000001
data_source_flag :: enum c.int {
SELF_MANAGED_RANGE_AND_LOOP_POINT = 0,
}
data_source_flags :: bit_set[data_source_flag; u32]
DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT :: data_source_flags{.SELF_MANAGED_RANGE_AND_LOOP_POINT}
data_source_vtable :: struct {
onRead: proc "c" (pDataSource: ^data_source, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result,
@@ -128,7 +134,7 @@ data_source_vtable :: struct {
onGetCursor: proc "c" (pDataSource: ^data_source, pCursor: ^u64) -> result,
onGetLength: proc "c" (pDataSource: ^data_source, pLength: ^u64) -> result,
onSetLooping: proc "c" (pDataSource: ^data_source, isLooping: b32) -> result,
flags: u32,
flags: data_source_flags,
}
data_source_get_next_proc :: proc "c" (pDataSource: ^data_source) -> ^data_source

View File

@@ -16,11 +16,13 @@ appropriate for a given situation.
vfs :: struct {}
vfs_file :: distinct handle
open_mode_flags :: enum c.int {
READ = 0x00000001,
WRITE = 0x00000002,
open_mode_flag :: enum c.int {
READ = 0,
WRITE = 1,
}
open_mode_flags :: bit_set[open_mode_flag; u32]
seek_origin :: enum c.int {
start,
current,
@@ -32,8 +34,8 @@ file_info :: struct {
}
vfs_callbacks :: struct {
onOpen: proc "c" (pVFS: ^vfs, pFilePath: cstring, openMode: u32, pFile: ^vfs_file) -> result,
onOpenW: proc "c" (pVFS: ^vfs, pFilePath: [^]c.wchar_t, openMode: u32, pFile: ^vfs_file) -> result,
onOpen: proc "c" (pVFS: ^vfs, pFilePath: cstring, openMode: open_mode_flags, pFile: ^vfs_file) -> result,
onOpenW: proc "c" (pVFS: ^vfs, pFilePath: [^]c.wchar_t, openMode: open_mode_flags, pFile: ^vfs_file) -> result,
onClose: proc "c" (pVFS: ^vfs, file: vfs_file) -> result,
onRead: proc "c" (pVFS: ^vfs, file: vfs_file, pDst: rawptr, sizeInBytes: c.size_t, pBytesRead: ^c.size_t) -> result,
onWrite: proc "c" (pVFS: ^vfs, file: vfs_file, pSrc: rawptr, sizeInBytes: c.size_t, pBytesWritten: ^c.size_t) -> result,
@@ -54,8 +56,8 @@ ma_tell_proc :: proc "c" (pUserData: rawptr, pCursor: ^i64) -> result
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
vfs_open :: proc(pVFS: ^vfs, pFilePath: cstring, openMode: u32, pFile: ^vfs_file) -> result ---
vfs_open_w :: proc(pVFS: ^vfs, pFilePath: [^]c.wchar_t, openMode: u32, pFile: ^vfs_file) -> result ---
vfs_open :: proc(pVFS: ^vfs, pFilePath: cstring, openMode: open_mode_flags, pFile: ^vfs_file) -> result ---
vfs_open_w :: proc(pVFS: ^vfs, pFilePath: [^]c.wchar_t, openMode: open_mode_flags, pFile: ^vfs_file) -> result ---
vfs_close :: proc(pVFS: ^vfs, file: vfs_file) -> result ---
vfs_read :: proc(pVFS: ^vfs, file: vfs_file, pDst: rawptr, sizeInBytes: c.size_t, pBytesRead: ^c.size_t) -> result ---
vfs_write :: proc(pVFS: ^vfs, file: vfs_file, pSrc: rawptr, sizeInBytes: c.size_t, pBytesWritten: ^c.size_t) -> result ---