mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-08 19:44:20 +00:00
Merge branch 'master' of https://github.com/odin-lang/Odin
This commit is contained in:
@@ -1276,7 +1276,7 @@ preprocess_internal :: proc(cpp: ^Preprocessor, tok: ^Token) -> ^Token {
|
||||
if start.file != nil {
|
||||
dir = filepath.dir(start.file.name)
|
||||
}
|
||||
path := filepath.join(dir, filename)
|
||||
path := filepath.join({dir, filename})
|
||||
if os.exists(path) {
|
||||
tok = include_file(cpp, tok, path, start.next.next)
|
||||
continue
|
||||
|
||||
@@ -211,19 +211,19 @@ _signbitf :: #force_inline proc(x: float) -> int {
|
||||
return int(transmute(uint32_t)x >> 31)
|
||||
}
|
||||
|
||||
isfinite :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
isfinite :: #force_inline proc(x: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return fpclassify(x) == FP_INFINITE
|
||||
}
|
||||
|
||||
isinf :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
isinf :: #force_inline proc(x: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return fpclassify(x) > FP_INFINITE
|
||||
}
|
||||
|
||||
isnan :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
isnan :: #force_inline proc(x: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return fpclassify(x) == FP_NAN
|
||||
}
|
||||
|
||||
isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
isnormal :: #force_inline proc(x: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return fpclassify(x) == FP_NORMAL
|
||||
}
|
||||
|
||||
@@ -231,27 +231,27 @@ isnormal :: #force_inline proc(x: $T) where intrinsics.type_is_float(T) {
|
||||
// implemented as the relational comparisons, as that would produce an invalid
|
||||
// "sticky" state that propagates and affects maths results. These need
|
||||
// to be implemented natively in Odin assuming isunordered to prevent that.
|
||||
isgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
isgreater :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x > y
|
||||
}
|
||||
|
||||
isgreaterequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
isgreaterequal :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x >= y
|
||||
}
|
||||
|
||||
isless :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
isless :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x < y
|
||||
}
|
||||
|
||||
islessequal :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
islessequal :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x <= y
|
||||
}
|
||||
|
||||
islessgreater :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
islessgreater :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
return !isunordered(x, y) && x <= y
|
||||
}
|
||||
|
||||
isunordered :: #force_inline proc(x, y: $T) where intrinsics.type_is_float(T) {
|
||||
isunordered :: #force_inline proc(x, y: $T) -> bool where intrinsics.type_is_float(T) {
|
||||
if isnan(x) {
|
||||
// Force evaluation of y to propagate exceptions for ordering semantics.
|
||||
// To ensure correct semantics of IEEE 754 this cannot be compiled away.
|
||||
|
||||
@@ -389,7 +389,8 @@ change_directory :: proc(path: string) -> Errno {
|
||||
return Errno(win32.SetCurrentDirectoryW(wpath))
|
||||
}
|
||||
|
||||
make_directory :: proc(path: string, mode: u32) -> Errno {
|
||||
make_directory :: proc(path: string, mode: u32 = 0) -> Errno {
|
||||
// Mode is unused on Windows, but is needed on *nix
|
||||
wpath := win32.utf8_to_wstring(path, context.temp_allocator)
|
||||
return Errno(win32.CreateDirectoryW(wpath, nil))
|
||||
}
|
||||
|
||||
@@ -305,7 +305,7 @@ _glob :: proc(dir, pattern: string, matches: ^[dynamic]string, allocator := cont
|
||||
n := fi.name
|
||||
matched := match(pattern, n) or_return
|
||||
if matched {
|
||||
append(&m, join(dir, n))
|
||||
append(&m, join({dir, n}))
|
||||
}
|
||||
}
|
||||
return
|
||||
|
||||
@@ -38,7 +38,7 @@ abs :: proc(path: string, allocator := context.allocator) -> (string, bool) {
|
||||
return path_str, true
|
||||
}
|
||||
|
||||
join :: proc(elems: ..string, allocator := context.allocator) -> string {
|
||||
join :: proc(elems: []string, allocator := context.allocator) -> string {
|
||||
for e, i in elems {
|
||||
if e != "" {
|
||||
p := strings.join(elems[i:], SEPARATOR_STRING, context.temp_allocator)
|
||||
|
||||
@@ -88,7 +88,7 @@ abs :: proc(path: string, allocator := context.allocator) -> (string, bool) {
|
||||
}
|
||||
|
||||
|
||||
join :: proc(elems: ..string, allocator := context.allocator) -> string {
|
||||
join :: proc(elems: []string, allocator := context.allocator) -> string {
|
||||
for e, i in elems {
|
||||
if e != "" {
|
||||
return join_non_empty(elems[i:], allocator)
|
||||
|
||||
107
vendor/miniaudio/common.odin
vendored
107
vendor/miniaudio/common.odin
vendored
@@ -13,13 +13,15 @@ when ODIN_OS == .Windows {
|
||||
handle :: distinct rawptr
|
||||
|
||||
|
||||
/* SIMD alignment in bytes. Currently set to 64 bytes in preparation for future AVX-512 optimizations. */
|
||||
SIMD_ALIGNMENT :: 64
|
||||
/* SIMD alignment in bytes. Currently set to 32 bytes in preparation for future AVX optimizations. */
|
||||
SIMD_ALIGNMENT :: 32
|
||||
|
||||
LOG_LEVEL_DEBUG :: 4
|
||||
LOG_LEVEL_INFO :: 3
|
||||
LOG_LEVEL_WARNING :: 2
|
||||
LOG_LEVEL_ERROR :: 1
|
||||
log_level :: enum c.int {
|
||||
LOG_LEVEL_DEBUG = 4,
|
||||
LOG_LEVEL_INFO = 3,
|
||||
LOG_LEVEL_WARNING = 2,
|
||||
LOG_LEVEL_ERROR = 1,
|
||||
}
|
||||
|
||||
|
||||
channel :: enum u8 {
|
||||
@@ -158,13 +160,13 @@ result :: enum c.int {
|
||||
FAILED_TO_STOP_BACKEND_DEVICE = -303,
|
||||
}
|
||||
|
||||
|
||||
MIN_CHANNELS :: 1
|
||||
MAX_CHANNELS :: 32
|
||||
MAX_CHANNELS :: 254
|
||||
|
||||
MAX_FILTER_ORDER :: 8
|
||||
|
||||
|
||||
|
||||
stream_format :: enum c.int {
|
||||
pcm = 0,
|
||||
}
|
||||
@@ -175,9 +177,9 @@ stream_layout :: enum c.int {
|
||||
}
|
||||
|
||||
dither_mode :: enum c.int {
|
||||
none = 0,
|
||||
rectangle,
|
||||
triangle,
|
||||
none = 0,
|
||||
rectangle,
|
||||
triangle,
|
||||
}
|
||||
|
||||
format :: enum c.int {
|
||||
@@ -224,7 +226,6 @@ channel_mix_mode :: enum c.int {
|
||||
rectangular = 0, /* Simple averaging based on the plane(s) the channel is sitting on. */
|
||||
simple, /* Drop excess channels; zeroed out extra channels. */
|
||||
custom_weights, /* Use custom weights specified in ma_channel_router_config. */
|
||||
planar_blend = rectangular,
|
||||
default = rectangular,
|
||||
}
|
||||
|
||||
@@ -257,6 +258,10 @@ lcg :: struct {
|
||||
state: i32,
|
||||
}
|
||||
|
||||
|
||||
/* Spinlocks are 32-bit for compatibility reasons. */
|
||||
spinlock :: distinct u32
|
||||
|
||||
NO_THREADING :: false
|
||||
|
||||
when !NO_THREADING {
|
||||
@@ -272,8 +277,6 @@ thread_priority :: enum c.int {
|
||||
default = 0,
|
||||
}
|
||||
|
||||
/* Spinlocks are 32-bit for compatibility reasons. */
|
||||
spinlock :: distinct u32
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
thread :: distinct rawptr
|
||||
@@ -297,69 +300,6 @@ when ODIN_OS == .Windows {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
/*
|
||||
Locks a spinlock.
|
||||
*/
|
||||
spinlock_lock :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
|
||||
|
||||
/*
|
||||
Locks a spinlock, but does not yield() when looping.
|
||||
*/
|
||||
spinlock_lock_noyield :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
|
||||
|
||||
/*
|
||||
Unlocks a spinlock.
|
||||
*/
|
||||
spinlock_unlock :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
|
||||
|
||||
|
||||
/*
|
||||
Creates a mutex.
|
||||
|
||||
A mutex must be created from a valid context. A mutex is initially unlocked.
|
||||
*/
|
||||
mutex_init :: proc(pMutex: ^mutex) -> result ---
|
||||
|
||||
/*
|
||||
Deletes a mutex.
|
||||
*/
|
||||
mutex_uninit :: proc(pMutex: ^mutex) ---
|
||||
|
||||
/*
|
||||
Locks a mutex with an infinite timeout.
|
||||
*/
|
||||
mutex_lock :: proc(pMutex: ^mutex) ---
|
||||
|
||||
/*
|
||||
Unlocks a mutex.
|
||||
*/
|
||||
mutex_unlock :: proc(pMutex: ^mutex) ---
|
||||
|
||||
|
||||
/*
|
||||
Initializes an auto-reset event.
|
||||
*/
|
||||
event_init :: proc(pEvent: ^event) -> result ---
|
||||
|
||||
/*
|
||||
Uninitializes an auto-reset event.
|
||||
*/
|
||||
event_uninit :: proc(pEvent: ^event) ---
|
||||
|
||||
/*
|
||||
Waits for the specified auto-reset event to become signalled.
|
||||
*/
|
||||
event_wait :: proc(pEvent: ^event) -> result ---
|
||||
|
||||
/*
|
||||
Signals the specified auto-reset event.
|
||||
*/
|
||||
event_signal :: proc(pEvent: ^event) -> result ---
|
||||
}
|
||||
|
||||
} /* NO_THREADING */
|
||||
|
||||
|
||||
@@ -385,17 +325,22 @@ foreign lib {
|
||||
result_description :: proc(result: result) -> cstring ---
|
||||
|
||||
/*
|
||||
malloc(). Calls MA_MALLOC().
|
||||
malloc()
|
||||
*/
|
||||
malloc :: proc(sz: c.size_t, pAllocationCallbacks: ^allocation_callbacks) -> rawptr ---
|
||||
|
||||
/*
|
||||
realloc(). Calls MA_REALLOC().
|
||||
calloc()
|
||||
*/
|
||||
calloc :: proc(sz: c.size_t, pAllocationCallbacks: ^allocation_callbacks) -> rawptr ---
|
||||
|
||||
/*
|
||||
realloc()
|
||||
*/
|
||||
realloc :: proc(p: rawptr, sz: c.size_t, pAllocationCallbacks: ^allocation_callbacks) -> rawptr ---
|
||||
|
||||
/*
|
||||
free(). Calls MA_FREE().
|
||||
free()
|
||||
*/
|
||||
free :: proc(p: rawptr, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
|
||||
@@ -417,7 +362,7 @@ foreign lib {
|
||||
/*
|
||||
Blends two frames in floating point format.
|
||||
*/
|
||||
blend_f32 :: proc(pOut, pInA, pInB: ^f32, factor: f32, channels: u32) ---
|
||||
blend_f32 :: proc(pOut, pInA, pInB: [^]f32, factor: f32, channels: u32) ---
|
||||
|
||||
/*
|
||||
Retrieves the size of a sample in bytes for the given format.
|
||||
|
||||
291
vendor/miniaudio/data_conversion.odin
vendored
291
vendor/miniaudio/data_conversion.odin
vendored
@@ -36,77 +36,106 @@ linear_resampler_config :: struct {
|
||||
}
|
||||
|
||||
linear_resampler :: struct {
|
||||
config: linear_resampler_config,
|
||||
config: linear_resampler_config,
|
||||
inAdvanceInt: u32,
|
||||
inAdvanceFrac: u32,
|
||||
inTimeInt: u32,
|
||||
inTimeFrac: u32,
|
||||
x0: struct #raw_union {
|
||||
f32: [MAX_CHANNELS]f32,
|
||||
s16: [MAX_CHANNELS]i16,
|
||||
f32: [^]f32,
|
||||
s16: [^]i16,
|
||||
}, /* The previous input frame. */
|
||||
x1: struct #raw_union {
|
||||
f32: [MAX_CHANNELS]f32,
|
||||
s16: [MAX_CHANNELS]i16,
|
||||
f32: [^]f32,
|
||||
s16: [^]i16,
|
||||
}, /* The next input frame. */
|
||||
lpf: lpf,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
resampling_backend :: struct {}
|
||||
resampling_backend_vtable :: struct {
|
||||
onGetHeapSize: proc "c" (pUserData: rawptr, pConfig: ^resampler_config, pHeapSizeInBytes: ^c.size_t) -> result,
|
||||
onInit: proc "c" (pUserData: rawptr, pConfig: ^resampler_config, pHeap: rawptr, ppBackend: ^^resampling_backend) -> result,
|
||||
onUninit: proc "c" (pUserData: rawptr, pBackend: ^resampling_backend, pAllocationCallbacks: ^allocation_callbacks),
|
||||
onProcess: proc "c" (pUserData: rawptr, pBackend: ^resampling_backend, pFramesIn: rawptr, pFrameCountIn: ^u64, pFramesOut: rawptr, pFrameCountOut: ^u64) -> result,
|
||||
onSetRate: proc "c" (pUserData: rawptr, pBackend: ^resampling_backend, sampleRateIn: u32, sampleRateOut: u32) -> result, /* Optional. Rate changes will be disabled. */
|
||||
onGetInputLatency: proc "c" (pUserData: rawptr, pBackend: ^resampling_backend) -> u64, /* Optional. Latency will be reported as 0. */
|
||||
onGetOutputLatency: proc "c" (pUserData: rawptr, pBackend: ^resampling_backend) -> u64, /* Optional. Latency will be reported as 0. */
|
||||
onGetRequiredInputFrameCount: proc "c" (pUserData: rawptr, pBackend: ^resampling_backend, outputFrameCount: u64, pInputFrameCount: ^u64) -> result, /* Optional. Latency mitigation will be disabled. */
|
||||
onGetExpectedOutputFrameCount: proc "c" (pUserData: rawptr, pBackend: ^resampling_backend, inputFrameCount: u64, pOutputFrameCount: ^u64) -> result, /* Optional. Latency mitigation will be disabled. */
|
||||
onReset: proc "c" (pUserData: rawptr, pBackend: ^resampling_backend) -> result,
|
||||
}
|
||||
|
||||
resample_algorithm :: enum {
|
||||
linear = 0, /* Fastest, lowest quality. Optional low-pass filtering. Default. */
|
||||
speex,
|
||||
custom,
|
||||
}
|
||||
|
||||
resampler_config :: struct {
|
||||
format: format, /* Must be either ma_format_f32 or ma_format_s16. */
|
||||
channels: u32,
|
||||
sampleRateIn: u32,
|
||||
sampleRateOut: u32,
|
||||
algorithm: resample_algorithm,
|
||||
format: format, /* Must be either ma_format_f32 or ma_format_s16. */
|
||||
channels: u32,
|
||||
sampleRateIn: u32,
|
||||
sampleRateOut: u32,
|
||||
algorithm: resample_algorithm, /* When set to ma_resample_algorithm_custom, pBackendVTable will be used. */
|
||||
pBackendVTable: ^resampling_backend_vtable,
|
||||
pBackendUserData: rawptr,
|
||||
linear: struct {
|
||||
lpfOrder: u32,
|
||||
lpfNyquistFactor: f64,
|
||||
},
|
||||
speex: struct {
|
||||
quality: c.int, /* 0 to 10. Defaults to 3. */
|
||||
},
|
||||
}
|
||||
|
||||
resampler :: struct {
|
||||
config: resampler_config,
|
||||
pBackend: ^resampling_backend,
|
||||
pBackendVTable: ^resampling_backend_vtable,
|
||||
pBackendUserData: rawptr,
|
||||
format: format,
|
||||
channels: u32,
|
||||
sampleRateIn: u32,
|
||||
sampleRateOut: u32,
|
||||
state: struct #raw_union {
|
||||
linear: linear_resampler,
|
||||
speex: struct {
|
||||
pSpeexResamplerState: rawptr, /* SpeexResamplerState* */
|
||||
},
|
||||
},
|
||||
}, /* State for stock resamplers so we can avoid a malloc. For stock resamplers, pBackend will point here. */
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
linear_resampler_config_init :: proc(format: format, channels: u32, sampleRateIn, sampleRateOut: u32) -> linear_resampler_config ---
|
||||
|
||||
linear_resampler_init :: proc(pConfig: ^linear_resampler_config, pResampler: ^linear_resampler) -> result ---
|
||||
linear_resampler_uninit :: proc(pResampler: ^linear_resampler) ---
|
||||
linear_resampler_get_heap_size :: proc(pConfig: ^linear_resampler_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
linear_resampler_init_preallocated :: proc(pConfig: ^linear_resampler_config, pHeap: rawptr, pResampler: ^linear_resampler) -> result ---
|
||||
linear_resampler_init :: proc(pConfig: ^linear_resampler_config, pAllocationCallbacks: ^allocation_callbacks, pResampler: ^linear_resampler) -> result ---
|
||||
linear_resampler_uninit :: proc(pResampler: ^linear_resampler, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
linear_resampler_process_pcm_frames :: proc(pResampler: ^linear_resampler, pFramesIn: rawptr, pFrameCountIn: ^u64, pFramesOut: rawptr, pFrameCountOut: ^u64) -> result ---
|
||||
linear_resampler_set_rate :: proc(pResampler: ^linear_resampler, sampleRateIn, sampleRateOut: u32) -> result ---
|
||||
linear_resampler_set_rate_ratio :: proc(pResampler: ^linear_resampler, ratioInOut: f32) -> result ---
|
||||
linear_resampler_get_required_input_frame_count :: proc(pResampler: ^linear_resampler, outputFrameCount: u64) -> u64 ---
|
||||
linear_resampler_get_expected_output_frame_count :: proc(pResampler: ^linear_resampler, inputFrameCount: u64) -> u64 ---
|
||||
linear_resampler_get_input_latency :: proc(pResampler: ^linear_resampler) -> u64 ---
|
||||
linear_resampler_get_output_latency :: proc(pResampler: ^linear_resampler) -> u64 ---
|
||||
linear_resampler_get_required_input_frame_count :: proc(pResampler: ^linear_resampler, outputFrameCount: u64, pInputFrameCount: ^u64) -> result ---
|
||||
linear_resampler_get_expected_output_frame_count :: proc(pResampler: ^linear_resampler, inputFrameCount: u64, pOutputFrameCount: ^u64) -> result ---
|
||||
linear_resampler_reset :: proc(pResampler: ^linear_resampler) -> result ---
|
||||
|
||||
resampler_config_init :: proc(format: format, channels: u32, sampleRateIn, sampleRateOut: u32, algorithm: resample_algorithm) -> resampler_config ---
|
||||
|
||||
resampler_get_heap_size :: proc(pConfig: ^resampler_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
resampler_init_preallocated :: proc(pConfig: ^resampler_config, pHeap: rawptr, pResampler: ^resampler) -> result ---
|
||||
|
||||
/*
|
||||
Initializes a new resampler object from a config.
|
||||
*/
|
||||
resampler_init :: proc(pConfig: ^resampler_config, pResampler: ^resampler) -> result ---
|
||||
resampler_init :: proc(pConfig: ^resampler_config, pAllocationCallbacks: ^allocation_callbacks, pResampler: ^resampler) -> result ---
|
||||
|
||||
/*
|
||||
Uninitializes a resampler.
|
||||
*/
|
||||
resampler_uninit :: proc(pResampler: ^resampler) ---
|
||||
resampler_uninit :: proc(pResampler: ^resampler, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
|
||||
/*
|
||||
Converts the given input data.
|
||||
@@ -145,23 +174,6 @@ foreign lib {
|
||||
*/
|
||||
resampler_set_rate_ratio :: proc(pResampler: ^resampler, ratio: f32) -> result ---
|
||||
|
||||
|
||||
/*
|
||||
Calculates the number of whole input frames that would need to be read from the client in order to output the specified
|
||||
number of output frames.
|
||||
|
||||
The returned value does not include cached input frames. It only returns the number of extra frames that would need to be
|
||||
read from the input buffer in order to output the specified number of output frames.
|
||||
*/
|
||||
resampler_get_required_input_frame_count :: proc(pResampler: ^resampler, outputFrameCount: u64) -> u64 ---
|
||||
|
||||
/*
|
||||
Calculates the number of whole output frames that would be output after fully reading and consuming the specified number of
|
||||
input frames.
|
||||
*/
|
||||
resampler_get_expected_output_frame_count :: proc(pResampler: ^resampler, inputFrameCount: u64) -> u64 ---
|
||||
|
||||
|
||||
/*
|
||||
Retrieves the latency introduced by the resampler in input frames.
|
||||
*/
|
||||
@@ -171,6 +183,26 @@ foreign lib {
|
||||
Retrieves the latency introduced by the resampler in output frames.
|
||||
*/
|
||||
resampler_get_output_latency :: proc(pResampler: ^resampler) -> u64 ---
|
||||
|
||||
/*
|
||||
Calculates the number of whole input frames that would need to be read from the client in order to output the specified
|
||||
number of output frames.
|
||||
|
||||
The returned value does not include cached input frames. It only returns the number of extra frames that would need to be
|
||||
read from the input buffer in order to output the specified number of output frames.
|
||||
*/
|
||||
resampler_get_required_input_frame_count :: proc(pResampler: ^resampler, outputFrameCount: u64, pInputFrameCount: ^u64) -> result ---
|
||||
|
||||
/*
|
||||
Calculates the number of whole output frames that would be output after fully reading and consuming the specified number of
|
||||
input frames.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
resampler_reset :: proc(pResampler: ^resampler) -> result ---
|
||||
}
|
||||
|
||||
|
||||
@@ -179,42 +211,63 @@ foreign lib {
|
||||
Channel Conversion
|
||||
|
||||
**************************************************************************************************************************************************************/
|
||||
channel_conversion_path :: enum c.int {
|
||||
unknown,
|
||||
passthrough,
|
||||
mono_out, /* Converting to mono. */
|
||||
mono_in, /* Converting from mono. */
|
||||
shuffle, /* Simple shuffle. Will use this when all channels are present in both input and output channel maps, but just in a different order. */
|
||||
weights, /* Blended based on weights. */
|
||||
}
|
||||
|
||||
mono_expansion_mode :: enum c.int {
|
||||
duplicate = 0, /* The default. */
|
||||
average, /* Average the mono channel across all channels. */
|
||||
stereo_only, /* Duplicate to the left and right channels only and ignore the others. */
|
||||
default = duplicate,
|
||||
}
|
||||
|
||||
channel_converter_config :: struct {
|
||||
format: format,
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
channelMapIn: [MAX_CHANNELS]channel,
|
||||
channelMapOut: [MAX_CHANNELS]channel,
|
||||
mixingMode: channel_mix_mode,
|
||||
weights: [MAX_CHANNELS][MAX_CHANNELS]f32, /* [in][out]. Only used when mixingMode is set to ma_channel_mix_mode_custom_weights. */
|
||||
format: format,
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
pChannelMapIn: [^]channel,
|
||||
pChannelMapOut: [^]channel,
|
||||
mixingMode: channel_mix_mode,
|
||||
ppWeights: ^[^]f32, /* [in][out]. Only used when mixingMode is set to ma_channel_mix_mode_custom_weights. */
|
||||
}
|
||||
|
||||
channel_converter :: struct {
|
||||
format: format,
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
channelMapIn: [MAX_CHANNELS]channel,
|
||||
channelMapOut: [MAX_CHANNELS]channel,
|
||||
mixingMode: channel_mix_mode,
|
||||
weights: struct #raw_union {
|
||||
f32: [MAX_CHANNELS][MAX_CHANNELS]f32,
|
||||
s16: [MAX_CHANNELS][MAX_CHANNELS]i32,
|
||||
format: format,
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
mixingMode: channel_mix_mode,
|
||||
conversionPath: channel_conversion_path,
|
||||
pChannelMapIn: [^]channel,
|
||||
pChannelMapOut: [^]channel,
|
||||
pShuffleTable: [^]u8,
|
||||
weights: struct #raw_union { /* [in][out] */
|
||||
f32: ^[^]f32,
|
||||
s16: ^[^]i32,
|
||||
},
|
||||
isPassthrough: b8,
|
||||
isSimpleShuffle: b8,
|
||||
isSimpleMonoExpansion: b8,
|
||||
isStereoToMono: b8,
|
||||
shuffleTable: [MAX_CHANNELS]u8,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
channel_converter_config_init :: proc(format: format, channelsIn: u32, pChannelMapIn: ^channel, channelsOut: u32, pChannelMapOut: ^channel, mixingMode: channel_mix_mode) -> channel_converter_config ---
|
||||
channel_converter_config_init :: proc(format: format, channelsIn: u32, pChannelMapIn: [^]channel, channelsOut: u32, pChannelMapOut: [^]channel, mixingMode: channel_mix_mode) -> channel_converter_config ---
|
||||
|
||||
channel_converter_init :: proc(pConfig: ^channel_converter_config, pConverter: ^channel_converter) -> result ---
|
||||
channel_converter_uninit :: proc(pConverter: ^channel_converter) ---
|
||||
channel_converter_process_pcm_frames :: proc(pConverter: ^channel_converter, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
channel_converter_get_heap_size :: proc(pConfig: ^channel_converter_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
channel_converter_init_preallocated :: proc(pConfig: ^channel_converter_config, pHeap: rawptr, pConverter: ^channel_converter) -> result ---
|
||||
channel_converter_init :: proc(pConfig: ^channel_converter_config, pAllocationCallbacks: ^allocation_callbacks, pConverter: ^channel_converter) -> result ---
|
||||
channel_converter_uninit :: proc(pConverter: ^channel_converter, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
channel_converter_process_pcm_frames :: proc(pConverter: ^channel_converter, pFramesOut, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
channel_converter_get_input_channel_map :: proc(pConverter: ^channel_converter, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
|
||||
channel_converter_get_output_channel_map :: proc(pConverter: ^channel_converter, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
|
||||
}
|
||||
|
||||
|
||||
@@ -224,32 +277,39 @@ Data Conversion
|
||||
|
||||
**************************************************************************************************************************************************************/
|
||||
data_converter_config :: struct {
|
||||
formatIn: format,
|
||||
formatOut: format,
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
sampleRateIn: u32,
|
||||
sampleRateOut: u32,
|
||||
channelMapIn: [MAX_CHANNELS]channel,
|
||||
channelMapOut: [MAX_CHANNELS]channel,
|
||||
ditherMode: dither_mode,
|
||||
channelMixMode: channel_mix_mode,
|
||||
channelWeights: [MAX_CHANNELS][MAX_CHANNELS]f32, /* [in][out]. Only used when channelMixMode is set to ma_channel_mix_mode_custom_weights. */
|
||||
resampling: struct {
|
||||
algorithm: resample_algorithm,
|
||||
allowDynamicSampleRate: b32,
|
||||
linear: struct {
|
||||
lpfOrderL: u32,
|
||||
lpfNyquistFactor: f64,
|
||||
},
|
||||
speex: struct {
|
||||
quality: c.int,
|
||||
},
|
||||
},
|
||||
formatIn: format,
|
||||
formatOut: format,
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
sampleRateIn: u32,
|
||||
sampleRateOut: u32,
|
||||
pChannelMapIn: [^]channel,
|
||||
pChannelMapOut: [^]channel,
|
||||
ditherMode: dither_mode,
|
||||
channelMixMode: channel_mix_mode,
|
||||
ppChannelWeights: ^[^]f32, /* [in][out]. Only used when channelMixMode is set to ma_channel_mix_mode_custom_weights. */
|
||||
allowDynamicSampleRate: b32,
|
||||
resampling: resampler_config,
|
||||
}
|
||||
|
||||
data_converter_execution_path :: enum c.int {
|
||||
passthrough, /* No conversion. */
|
||||
format_only, /* Only format conversion. */
|
||||
channels_only, /* Only channel conversion. */
|
||||
resample_only, /* Only resampling. */
|
||||
resample_first, /* All conversions, but resample as the first step. */
|
||||
channels_first, /* All conversions, but channels as the first step. */
|
||||
}
|
||||
|
||||
data_converter :: struct {
|
||||
config: data_converter_config,
|
||||
formatIn: format,
|
||||
formatOut: format,
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
sampleRateIn: u32,
|
||||
sampleRateOut: u32,
|
||||
ditherMode: dither_mode,
|
||||
executionPath: data_converter_execution_path, /* The execution path the data converter will follow when processing. */
|
||||
channelConverter: channel_converter,
|
||||
resampler: resampler,
|
||||
hasPreFormatConversion: b8,
|
||||
@@ -257,6 +317,10 @@ data_converter :: struct {
|
||||
hasChannelConverter: b8,
|
||||
hasResampler: b8,
|
||||
isPassthrough: b8,
|
||||
|
||||
/* Memory management. */
|
||||
_ownsHeap: b8,
|
||||
_pHeap: rawptr,
|
||||
}
|
||||
|
||||
|
||||
@@ -265,15 +329,20 @@ foreign lib {
|
||||
data_converter_config_init_default :: proc() -> data_converter_config ---
|
||||
data_converter_config_init :: proc(formatIn, formatOut: format, channelsIn, channelsOut: u32, sampleRateIn, sampleRateOut: u32) -> data_converter_config ---
|
||||
|
||||
data_converter_init :: proc(pConfig: ^data_converter_config, pConverter: ^data_converter) -> result ---
|
||||
data_converter_uninit :: proc(pConverter: ^data_converter) ---
|
||||
data_converter_get_heap_size :: proc(pConfig: ^data_converter_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
data_converter_init_preallocated :: proc(pConfig: ^data_converter_config, pHeap: rawptr, pConverter: ^data_converter) -> result ---
|
||||
data_converter_init :: proc(pConfig: ^data_converter_config, pAllocationCallbacks: ^allocation_callbacks, pConverter: ^data_converter) -> result ---
|
||||
data_converter_uninit :: proc(pConverter: ^data_converter, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
data_converter_process_pcm_frames :: proc(pConverter: ^data_converter, pFramesIn: rawptr, pFrameCountIn: ^u64, pFramesOut: rawptr, pFrameCountOut: ^u64) -> result ---
|
||||
data_converter_set_rate :: proc(pConverter: ^data_converter, sampleRateIn, sampleRateOut: u32) -> result ---
|
||||
data_converter_set_rate_ratio :: proc(pConverter: ^data_converter, ratioInOut: f32) -> result ---
|
||||
data_converter_get_required_input_frame_count :: proc(pConverter: ^data_converter, outputFrameCount: u64) -> u64 ---
|
||||
data_converter_get_expected_output_frame_count :: proc(pConverter: ^data_converter, inputFrameCount: u64) -> u64 ---
|
||||
data_converter_get_input_latency :: proc(pConverter: ^data_converter) -> u64 ---
|
||||
data_converter_get_output_latency :: proc(pConverter: ^data_converter) -> u64 ---
|
||||
data_converter_get_required_input_frame_count :: proc(pConverter: ^data_converter, outputFrameCount: u64, pInputFrameCount: ^u64) -> result ---
|
||||
data_converter_get_expected_output_frame_count :: proc(pConverter: ^data_converter, inputFrameCount: u64, pOutputFrameCount: ^u64) -> result ---
|
||||
data_converter_get_input_channel_map :: proc(pConverter: ^data_converter, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
|
||||
data_converter_get_output_channel_map :: proc(pConverter: ^data_converter, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
|
||||
data_converter_reset :: proc(pConverter: ^data_converter) -> result ---
|
||||
}
|
||||
|
||||
/************************************************************************************************************************************************************
|
||||
@@ -332,43 +401,40 @@ CHANNEL_INDEX_NULL :: 255
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
/* Retrieves the channel position of the specified channel based on miniaudio's default channel map. */
|
||||
channel_map_get_default_channel :: proc(channelCount: u32, channelIndex: u32) -> channel ---
|
||||
|
||||
/*
|
||||
Retrieves the channel position of the specified channel in the given channel map.
|
||||
|
||||
The pChannelMap parameter can be null, in which case miniaudio's default channel map will be assumed.
|
||||
*/
|
||||
channel_map_get_channel :: proc(pChannelMap: ^channel, channelCount: u32, channelIndex: u32) -> channel ---
|
||||
channel_map_get_channel :: proc(pChannelMap: [^]channel, channelCount: u32, channelIndex: u32) -> channel ---
|
||||
|
||||
/*
|
||||
Initializes a blank channel map.
|
||||
|
||||
When a blank channel map is specified anywhere it indicates that the native channel map should be used.
|
||||
*/
|
||||
channel_map_init_blank :: proc(channels: u32, pChannelMap: ^channel) ---
|
||||
channel_map_init_blank :: proc(pChannelMap: [^]channel, channels: u32) ---
|
||||
|
||||
/*
|
||||
Helper for retrieving a standard channel map.
|
||||
|
||||
The output channel map buffer must have a capacity of at least `channels`.
|
||||
The output channel map buffer must have a capacity of at least `channelMapCap`.
|
||||
*/
|
||||
get_standard_channel_map :: proc(standardChannelMap: standard_channel_map, channels: u32, pChannelMap: ^channel) ---
|
||||
channel_map_init_standard :: proc(standardChannelMap: standard_channel_map, pChannelMap: [^]channel, channelMapCap: c.size_t, channels: u32) ---
|
||||
|
||||
/*
|
||||
Copies a channel map.
|
||||
|
||||
Both input and output channel map buffers must have a capacity of at at least `channels`.
|
||||
*/
|
||||
channel_map_copy :: proc(pOut: ^channel, pIn: ^channel, channels: u32) ---
|
||||
channel_map_copy :: proc(pOut: [^]channel, pIn: [^]channel, channels: u32) ---
|
||||
|
||||
/*
|
||||
Copies a channel map if one is specified, otherwise copies the default channel map.
|
||||
|
||||
The output buffer must have a capacity of at least `channels`. If not NULL, the input channel map must also have a capacity of at least `channels`.
|
||||
*/
|
||||
channel_map_copy_or_default :: proc(pOut: ^channel, pIn: ^channel, channels: u32) ---
|
||||
channel_map_copy_or_default :: proc(pOut: [^]channel, channelMapCapOut: c.size_t, pIn: [^]channel, channels: u32) ---
|
||||
|
||||
|
||||
/*
|
||||
@@ -378,12 +444,12 @@ foreign lib {
|
||||
is usually treated as a passthrough.
|
||||
|
||||
Invalid channel maps:
|
||||
- A channel map with no channels
|
||||
- A channel map with more than one channel and a mono channel
|
||||
- A channel map with no channels
|
||||
- A channel map with more than one channel and a mono channel
|
||||
|
||||
The channel map buffer must have a capacity of at least `channels`.
|
||||
*/
|
||||
channel_map_valid :: proc(channels: u32, pChannelMap: ^channel) -> b32 ---
|
||||
channel_map_is_valid :: proc(pChannelMap: [^]channel, channels: u32) -> b32 ---
|
||||
|
||||
/*
|
||||
Helper for comparing two channel maps for equality.
|
||||
@@ -392,23 +458,24 @@ foreign lib {
|
||||
|
||||
Both channels map buffers must have a capacity of at least `channels`.
|
||||
*/
|
||||
channel_map_equal :: proc(channels: u32, pChannelMapA, pChannelMapB: ^channel) -> b32 ---
|
||||
channel_map_is_equal :: proc(pChannelMapA, pChannelMapB: [^]channel, channels: u32) -> b32 ---
|
||||
|
||||
/*
|
||||
Helper for determining if a channel map is blank (all channels set to MA_CHANNEL_NONE).
|
||||
|
||||
The channel map buffer must have a capacity of at least `channels`.
|
||||
*/
|
||||
channel_map_blank :: proc(channels: u32, pChannelMap: ^channel) -> b32 ---
|
||||
channel_map_is_blank :: proc(pChannelMap: [^]channel, channels: u32) -> b32 ---
|
||||
|
||||
/*
|
||||
Helper for determining whether or not a channel is present in the given channel map.
|
||||
|
||||
The channel map buffer must have a capacity of at least `channels`.
|
||||
*/
|
||||
channel_map_contains_channel_position :: proc(channels: u32, pChannelMap: ^channel, channelPosition: channel) -> b32 ---
|
||||
channel_map_contains_channel_position :: proc(channels: u32, pChannelMap: [^]channel, channelPosition: channel) -> b32 ---
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************************************************************************************************
|
||||
|
||||
Conversion Helpers
|
||||
@@ -461,9 +528,9 @@ foreign lib {
|
||||
rb_uninit :: proc(pRB: ^rb) ---
|
||||
rb_reset :: proc(pRB: ^rb) ---
|
||||
rb_acquire_read :: proc(pRB: ^rb, pSizeInBytes: ^c.size_t, ppBufferOut: ^rawptr) -> result ---
|
||||
rb_commit_read :: proc(pRB: ^rb, sizeInBytes: c.size_t, pBufferOut: rawptr) -> result ---
|
||||
rb_commit_read :: proc(pRB: ^rb, sizeInBytes: c.size_t) -> result ---
|
||||
rb_acquire_write :: proc(pRB: ^rb, pSizeInBytes: ^c.size_t, ppBufferOut: ^rawptr) -> result ---
|
||||
rb_commit_write :: proc(pRB: ^rb, sizeInBytes: c.size_t, pBufferOut: rawptr) -> result ---
|
||||
rb_commit_write :: proc(pRB: ^rb, sizeInBytes: c.size_t) -> result ---
|
||||
rb_seek_read :: proc(pRB: ^rb, offsetInBytes: c.size_t) -> result ---
|
||||
rb_seek_write :: proc(pRB: ^rb, offsetInBytes: c.size_t) -> result ---
|
||||
rb_pointer_distance :: proc(pRB: ^rb) -> i32 --- /* Returns the distance between the write pointer and the read pointer. Should never be negative for a correct program. Will return the number of bytes that can be read before the read pointer hits the write pointer. */
|
||||
|
||||
102
vendor/miniaudio/decoding.odin
vendored
102
vendor/miniaudio/decoding.odin
vendored
@@ -22,68 +22,63 @@ you do your own synchronization.
|
||||
|
||||
decoding_backend_config :: struct {
|
||||
preferredFormat: format,
|
||||
seekPointCount: u32, /* Set to > 0 to generate a seektable if the decoding backend supports it. */
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
decoding_backend_config_init :: proc(preferredFormat: format) -> decoding_backend_config ---
|
||||
decoding_backend_config_init :: proc(preferredFormat: format, seekPointCount: u32) -> decoding_backend_config ---
|
||||
}
|
||||
|
||||
|
||||
decoding_backend_vtable :: struct {
|
||||
onInit: proc "c" (pUserData: rawptr, onRead: decoder_read_proc, onSeek: decoder_seek_proc, onTell: decoder_tell_proc, pReadSeekTellUserData: rawptr, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result,
|
||||
onInitFile: proc "c" (pUserData: rawptr, pFilePath: cstring, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result, /* Optional. */
|
||||
onInitFile: proc "c" (pUserData: rawptr, pFilePath: cstring, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result, /* Optional. */
|
||||
onInitFileW: proc "c" (pUserData: rawptr, pFilePath: [^]c.wchar_t, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result, /* Optional. */
|
||||
onInitMemory: proc "c" (pUserData: rawptr, pData: rawptr, dataSize: c.size_t, pConfig: ^decoding_backend_config, pAllocationCallbacks: ^allocation_callbacks, ppBackend: ^^data_source) -> result, /* Optional. */
|
||||
onUninit: proc "c" (pUserData: rawptr, pBackend: ^data_source, pAllocationCallbacks: ^allocation_callbacks),
|
||||
onGetChannelMap: proc "c" (pUserData: rawptr, pBackend: ^data_source, pChannelMap: ^channel, channelMapCap: c.size_t) -> result,
|
||||
}
|
||||
|
||||
|
||||
/* TODO: Convert read and seek to be consistent with the VFS API (ma_result return value, bytes read moved to an output parameter). */
|
||||
decoder_read_proc :: proc "c" (pDecoder: ^decoder, pBufferOut: rawptr, bytesToRead: c.size_t) -> c.size_t /* Returns the number of bytes read. */
|
||||
decoder_seek_proc :: proc "c" (pDecoder: ^decoder, byteOffset: i64, origin: seek_origin) -> b32
|
||||
decoder_read_proc :: proc "c" (pDecoder: ^decoder, pBufferOut: rawptr, bytesToRead: c.size_t, pBytesRead: ^c.size_t) -> result /* Returns the number of bytes read. */
|
||||
decoder_seek_proc :: proc "c" (pDecoder: ^decoder, byteOffset: i64, origin: seek_origin) -> result
|
||||
decoder_tell_proc :: proc "c" (pDecoder: ^decoder, pCursor: ^i64) -> result
|
||||
|
||||
decoder_config :: struct {
|
||||
format: format, /* Set to 0 or ma_format_unknown to use the stream's internal format. */
|
||||
channels: u32, /* Set to 0 to use the stream's internal channels. */
|
||||
sampleRate: u32, /* Set to 0 to use the stream's internal sample rate. */
|
||||
channelMap: [MAX_CHANNELS]channel,
|
||||
channelMixMode: channel_mix_mode,
|
||||
ditherMode: dither_mode,
|
||||
resampling: struct {
|
||||
algorithm: resample_algorithm,
|
||||
linear: struct {
|
||||
lpfOrder: u32,
|
||||
},
|
||||
speex: struct {
|
||||
quality: c.int,
|
||||
},
|
||||
},
|
||||
format: format, /* Set to 0 or ma_format_unknown to use the stream's internal format. */
|
||||
channels: u32, /* Set to 0 to use the stream's internal channels. */
|
||||
sampleRate: u32, /* Set to 0 to use the stream's internal sample rate. */
|
||||
channelMap: [^]channel,
|
||||
channelMixMode: channel_mix_mode,
|
||||
ditherMode: dither_mode,
|
||||
resampling: resampler_config,
|
||||
allocationCallbacks: allocation_callbacks,
|
||||
encodingFormat: encoding_format,
|
||||
ppCustomBackendVTables: ^^decoding_backend_vtable,
|
||||
seekPointCount: u32, /* When set to > 0, specifies the number of seek points to use for the generation of a seek table. Not all decoding backends support this. */
|
||||
ppCustomBackendVTables: ^[^]decoding_backend_vtable,
|
||||
customBackendCount: u32,
|
||||
pCustomBackendUserData: rawptr,
|
||||
}
|
||||
|
||||
decoder :: struct {
|
||||
ds: data_source_base,
|
||||
pBackend: ^data_source, /* The decoding backend we'll be pulling data from. */
|
||||
pBackendVTable: ^^decoding_backend_vtable, /* The vtable for the decoding backend. This needs to be stored so we can access the onUninit() callback. */
|
||||
pBackendUserData: rawptr,
|
||||
onRead: decoder_read_proc,
|
||||
onSeek: decoder_seek_proc,
|
||||
onTell: decoder_tell_proc,
|
||||
pUserData: rawptr,
|
||||
ds: data_source_base,
|
||||
pBackend: ^data_source, /* The decoding backend we'll be pulling data from. */
|
||||
pBackendVTable: ^decoding_backend_vtable, /* The vtable for the decoding backend. This needs to be stored so we can access the onUninit() callback. */
|
||||
pBackendUserData: rawptr,
|
||||
onRead: decoder_read_proc,
|
||||
onSeek: decoder_seek_proc,
|
||||
onTell: decoder_tell_proc,
|
||||
pUserData: rawptr,
|
||||
readPointerInPCMFrames: u64, /* In output sample rate. Used for keeping track of how many frames are available for decoding. */
|
||||
outputFormat: format,
|
||||
outputChannels: u32,
|
||||
outputSampleRate: u32,
|
||||
outputChannelMap: [MAX_CHANNELS]channel,
|
||||
converter: data_converter, /* <-- Data conversion is achieved by running frames through this. */
|
||||
allocationCallbacks: allocation_callbacks,
|
||||
outputFormat: format,
|
||||
outputChannels: u32,
|
||||
outputSampleRate: u32,
|
||||
converter: data_converter, /* <-- Data conversion is achieved by running frames through this. */
|
||||
pInputCache: rawptr, /* In input format. Can be null if it's not needed. */
|
||||
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. */
|
||||
inputCacheRemaining: u64, /* The number of valid frames remaining in the cahce. */
|
||||
allocationCallbacks: allocation_callbacks,
|
||||
data: struct #raw_union {
|
||||
vfs: struct {
|
||||
pVFS: ^vfs,
|
||||
@@ -114,6 +109,25 @@ foreign lib {
|
||||
*/
|
||||
decoder_uninit :: proc(pDecoder: ^decoder) -> result ---
|
||||
|
||||
/*
|
||||
Reads PCM frames from the given decoder.
|
||||
|
||||
This is not thread safe without your own synchronization.
|
||||
*/
|
||||
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.
|
||||
|
||||
This is not thread safe without your own synchronization.
|
||||
*/
|
||||
decoder_seek_to_pcm_frame :: proc(pDecoder: ^decoder, frameIndex: u64) -> result ---
|
||||
|
||||
/*
|
||||
Retrieves the decoder's output data format.
|
||||
*/
|
||||
decoder_get_data_format :: proc(pDecoder: ^decoder, pFormat: ^format, pChannels, pSampleRate: ^u32, pChannelMap: ^channel, channelMapCap: c.size_t) -> result ---
|
||||
|
||||
/*
|
||||
Retrieves the current position of the read cursor in PCM frames.
|
||||
*/
|
||||
@@ -133,21 +147,7 @@ foreign lib {
|
||||
|
||||
This function is not thread safe without your own synchronization.
|
||||
*/
|
||||
decoder_get_length_in_pcm_frames :: proc(pDecoder: ^decoder) -> u64 ---
|
||||
|
||||
/*
|
||||
Reads PCM frames from the given decoder.
|
||||
|
||||
This is not thread safe without your own synchronization.
|
||||
*/
|
||||
decoder_read_pcm_frames :: proc(pDecoder: ^decoder, pFramesOut: rawptr, frameCount: u64) -> u64 ---
|
||||
|
||||
/*
|
||||
Seeks to a PCM frame based on it's absolute index.
|
||||
|
||||
This is not thread safe without your own synchronization.
|
||||
*/
|
||||
decoder_seek_to_pcm_frame :: proc(pDecoder: ^decoder, frameIndex: u64) -> result ---
|
||||
decoder_get_length_in_pcm_frames :: proc(pDecoder: ^decoder, pLength: ^u64) -> result ---
|
||||
|
||||
/*
|
||||
Retrieves the number of frames that can be read before reaching the end.
|
||||
|
||||
786
vendor/miniaudio/device_io_procs.odin
vendored
786
vendor/miniaudio/device_io_procs.odin
vendored
File diff suppressed because it is too large
Load Diff
365
vendor/miniaudio/device_io_types.odin
vendored
365
vendor/miniaudio/device_io_types.odin
vendored
@@ -18,12 +18,13 @@ SUPPORT_WEBAUDIO :: false // ODIN_OS == .Emscripten
|
||||
SUPPORT_CUSTOM :: true
|
||||
SUPPORT_NULL :: true // ODIN_OS != .Emscripten
|
||||
|
||||
STATE_UNINITIALIZED :: 0
|
||||
STATE_STOPPED :: 1 /* The device's default state after initialization. */
|
||||
STATE_STARTED :: 2 /* The device is started and is requesting and/or delivering audio data. */
|
||||
STATE_STARTING :: 3 /* Transitioning from a stopped state to started. */
|
||||
STATE_STOPPING :: 4 /* Transitioning from a started state to stopped. */
|
||||
|
||||
device_state :: enum c.int {
|
||||
uninitialized = 0,
|
||||
stopped = 1, /* The device's default state after initialization. */
|
||||
started = 2, /* The device is started and is requesting and/or delivering audio data. */
|
||||
starting = 3, /* Transitioning from a stopped state to started. */
|
||||
stopping = 4, /* Transitioning from a started state to stopped. */
|
||||
}
|
||||
|
||||
|
||||
when SUPPORT_WASAPI {
|
||||
@@ -56,6 +57,96 @@ backend :: enum c.int {
|
||||
BACKEND_COUNT :: len(backend)
|
||||
|
||||
|
||||
/*
|
||||
Device job thread. This is used by backends that require asynchronous processing of certain
|
||||
operations. It is not used by all backends.
|
||||
|
||||
The device job thread is made up of a thread and a job queue. You can post a job to the thread with
|
||||
ma_device_job_thread_post(). The thread will do the processing of the job.
|
||||
*/
|
||||
device_job_thread_config :: struct {
|
||||
noThread: b32, /* Set this to true if you want to process jobs yourself. */
|
||||
jobQueueCapacity: u32,
|
||||
jobQueueFlags: u32,
|
||||
}
|
||||
|
||||
device_job_thread :: struct {
|
||||
thread: thread,
|
||||
jobQueue: job_queue,
|
||||
_hasThread: b32,
|
||||
}
|
||||
|
||||
|
||||
/* Device notification types. */
|
||||
device_notification_type :: enum c.int {
|
||||
started,
|
||||
stopped,
|
||||
rerouted,
|
||||
interruption_began,
|
||||
interruption_ended,
|
||||
}
|
||||
|
||||
device_notification :: struct {
|
||||
pDevice: ^device,
|
||||
type: device_notification_type,
|
||||
data: struct #raw_union {
|
||||
started: struct {
|
||||
_unused: c.int,
|
||||
},
|
||||
stopped: struct {
|
||||
_unused: c.int,
|
||||
},
|
||||
rerouted: struct {
|
||||
_unused: c.int,
|
||||
},
|
||||
interruption: struct {
|
||||
_unused: c.int,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/*
|
||||
The notification callback for when the application should be notified of a change to the device.
|
||||
|
||||
This callback is used for notifying the application of changes such as when the device has started,
|
||||
stopped, rerouted or an interruption has occurred. Note that not all backends will post all
|
||||
notification types. For example, some backends will perform automatic stream routing without any
|
||||
kind of notification to the host program which means miniaudio will never know about it and will
|
||||
never be able to fire the rerouted notification. You should keep this in mind when designing your
|
||||
program.
|
||||
|
||||
The stopped notification will *not* get fired when a device is rerouted.
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
pNotification (in)
|
||||
A pointer to a structure containing information about the event. Use the `pDevice` member of
|
||||
this object to retrieve the relevant device. The `type` member can be used to discriminate
|
||||
against each of the notification types.
|
||||
|
||||
|
||||
Remarks
|
||||
-------
|
||||
Do not restart or uninitialize the device from the callback.
|
||||
|
||||
Not all notifications will be triggered by all backends, however the started and stopped events
|
||||
should be reliable for all backends. Some backends do not have a good way to detect device
|
||||
stoppages due to unplugging the device which may result in the stopped callback not getting
|
||||
fired. This has been observed with at least one BSD variant.
|
||||
|
||||
The rerouted notification is fired *after* the reroute has occurred. The stopped notification will
|
||||
*not* get fired when a device is rerouted. The following backends are known to do automatic stream
|
||||
rerouting, but do not have a way to be notified of the change:
|
||||
|
||||
* DirectSound
|
||||
|
||||
The interruption notifications are used on mobile platforms for detecting when audio is interrupted
|
||||
due to things like an incoming phone call. Currently this is only implemented on iOS. None of the
|
||||
Android backends will report this notification.
|
||||
*/
|
||||
device_notification_proc :: proc "c" (pNotification: ^device_notification)
|
||||
|
||||
/*
|
||||
The callback for processing audio data from the device.
|
||||
|
||||
@@ -96,9 +187,11 @@ callback. The following APIs cannot be called from inside the callback:
|
||||
|
||||
The proper way to stop the device is to call `ma_device_stop()` from a different thread, normally the main application thread.
|
||||
*/
|
||||
device_callback_proc :: proc "c" (pDevice: ^device, pOutput: rawptr, pInput: rawptr, frameCount: u32)
|
||||
device_data_proc :: proc "c" (pDevice: ^device, pOutput, pInput: rawptr, frameCount: u32)
|
||||
|
||||
/*
|
||||
DEPRECATED. Use ma_device_notification_proc instead.
|
||||
|
||||
The callback for when the device has been stopped.
|
||||
|
||||
This will be called when the device is stopped explicitly with `ma_device_stop()` and also called implicitly when the device is stopped through external forces
|
||||
@@ -108,48 +201,15 @@ such as being unplugged or an internal error occuring.
|
||||
Parameters
|
||||
----------
|
||||
pDevice (in)
|
||||
A pointer to the device that has just stopped.
|
||||
A pointer to the device that has just stopped.
|
||||
|
||||
|
||||
Remarks
|
||||
-------
|
||||
Do not restart or uninitialize the device from the callback.
|
||||
*/
|
||||
stop_proc :: proc "c" (pDevice: ^device)
|
||||
stop_proc :: proc "c" (pDevice: ^device) /* DEPRECATED. Use ma_device_notification_proc instead. */
|
||||
|
||||
/*
|
||||
The callback for handling log messages.
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
pContext (in)
|
||||
A pointer to the context the log message originated from.
|
||||
|
||||
pDevice (in)
|
||||
A pointer to the device the log message originate from, if any. This can be null, in which case the message came from the context.
|
||||
|
||||
logLevel (in)
|
||||
The log level. This can be one of the following:
|
||||
|
||||
+----------------------+
|
||||
| Log Level |
|
||||
+----------------------+
|
||||
| MA_LOG_LEVEL_DEBUG |
|
||||
| MA_LOG_LEVEL_INFO |
|
||||
| MA_LOG_LEVEL_WARNING |
|
||||
| MA_LOG_LEVEL_ERROR |
|
||||
+----------------------+
|
||||
|
||||
message (in)
|
||||
The log message.
|
||||
|
||||
|
||||
Remarks
|
||||
-------
|
||||
Do not modify the state of the device from inside the callback.
|
||||
*/
|
||||
log_proc :: proc "c" (pContext: context_type, pDevice: ^device, logLevel: u32, message: cstring)
|
||||
|
||||
device_type :: enum c.int {
|
||||
playback = 1,
|
||||
@@ -279,29 +339,14 @@ device_id :: struct #raw_union {
|
||||
|
||||
DATA_FORMAT_FLAG_EXCLUSIVE_MODE :: 1 << 1 /* If set, this is supported in exclusive mode. Otherwise not natively supported by exclusive mode. */
|
||||
|
||||
MAX_DEVICE_NAME_LENGTH :: 255
|
||||
|
||||
device_info :: struct {
|
||||
/* Basic info. This is the only information guaranteed to be filled in during device enumeration. */
|
||||
id: device_id,
|
||||
name: [256]byte,
|
||||
name: [MAX_DEVICE_NAME_LENGTH + 1]c.char, /* +1 for null terminator. */
|
||||
isDefault: b32,
|
||||
|
||||
/*
|
||||
Detailed info. As much of this is filled as possible with ma_context_get_device_info(). Note that you are allowed to initialize
|
||||
a device with settings outside of this range, but it just means the data will be converted using miniaudio's data conversion
|
||||
pipeline before sending the data to/from the device. Most programs will need to not worry about these values, but it's provided
|
||||
here mainly for informational purposes or in the rare case that someone might find it useful.
|
||||
|
||||
These will be set to 0 when returned by ma_context_enumerate_devices() or ma_context_get_devices().
|
||||
*/
|
||||
formatCount: u32,
|
||||
formats: [format]format,
|
||||
minChannels: u32,
|
||||
maxChannels: u32,
|
||||
minSampleRate: u32,
|
||||
maxSampleRate: u32,
|
||||
|
||||
|
||||
/* Experimental. Don't use these right now. */
|
||||
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. */
|
||||
@@ -312,31 +357,26 @@ device_info :: struct {
|
||||
}
|
||||
|
||||
device_config :: struct {
|
||||
deviceType: device_type,
|
||||
sampleRate: u32,
|
||||
periodSizeInFrames: u32,
|
||||
periodSizeInMilliseconds: u32,
|
||||
periods: u32,
|
||||
performanceProfile: performance_profile,
|
||||
noPreZeroedOutputBuffer: b8, /* When set to true, the contents of the output buffer passed into the data callback will be left undefined rather than initialized to zero. */
|
||||
noClip: b8, /* When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. Only applies when the playback sample format is f32. */
|
||||
dataCallback: device_callback_proc,
|
||||
stopCallback: stop_proc,
|
||||
pUserData: rawptr,
|
||||
resampling: struct {
|
||||
algorithm: resample_algorithm,
|
||||
linear: struct {
|
||||
lpfOrder: u32,
|
||||
},
|
||||
speex: struct {
|
||||
quality: c.int,
|
||||
},
|
||||
},
|
||||
deviceType: device_type,
|
||||
sampleRate: u32,
|
||||
periodSizeInFrames: u32,
|
||||
periodSizeInMilliseconds: u32,
|
||||
periods: u32,
|
||||
performanceProfile: performance_profile,
|
||||
noPreSilencedOutputBuffer: b8, /* When set to true, the contents of the output buffer passed into the data callback will be left undefined rather than initialized to zero. */
|
||||
noClip: b8, /* When set to true, the contents of the output buffer passed into the data callback will be clipped after returning. Only applies when the playback sample format is f32. */
|
||||
noDisableDenormals: b8, /* Do not disable denormals when firing the data callback. */
|
||||
noFixedSizedCallback: b8, /* Disables strict fixed-sized data callbacks. Setting this to true will result in the period size being treated only as a hint to the backend. This is an optimization for those who don't need fixed sized callbacks. */
|
||||
dataCallback: device_data_proc,
|
||||
notificationCallback: device_notification_proc,
|
||||
stopCallback: stop_proc,
|
||||
pUserData: rawptr,
|
||||
resampling: resampler_config,
|
||||
playback: struct {
|
||||
pDeviceID: ^device_id,
|
||||
format: format,
|
||||
channels: u32,
|
||||
channelMap: [MAX_CHANNELS]channel,
|
||||
channelMap: [^]channel,
|
||||
channelMixMode: channel_mix_mode,
|
||||
shareMode: share_mode,
|
||||
},
|
||||
@@ -344,7 +384,7 @@ device_config :: struct {
|
||||
pDeviceID: ^device_id,
|
||||
format: format,
|
||||
channels: u32,
|
||||
channelMap: [MAX_CHANNELS]channel,
|
||||
channelMap: [^]channel,
|
||||
channelMixMode: channel_mix_mode,
|
||||
shareMode: share_mode,
|
||||
},
|
||||
@@ -373,9 +413,10 @@ device_config :: struct {
|
||||
recordingPreset: opensl_recording_preset,
|
||||
},
|
||||
aaudio: struct {
|
||||
usage: aaudio_usage,
|
||||
contentType: aaudio_content_type,
|
||||
inputPreset: aaudio_input_preset,
|
||||
usage: aaudio_usage,
|
||||
contentType: aaudio_content_type,
|
||||
inputPreset: aaudio_input_preset,
|
||||
noAutoStartAfterReroute: b32,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -425,14 +466,14 @@ to many devices. A device is created from a context.
|
||||
The general flow goes like this:
|
||||
|
||||
1) A context is created with `onContextInit()`
|
||||
1a) Available devices can be enumerated with `onContextEnumerateDevices()` if required.
|
||||
1b) Detailed information about a device can be queried with `onContextGetDeviceInfo()` if required.
|
||||
1a) Available devices can be enumerated with `onContextEnumerateDevices()` if required.
|
||||
1b) Detailed information about a device can be queried with `onContextGetDeviceInfo()` if required.
|
||||
2) A device is created from the context that was created in the first step using `onDeviceInit()`, and optionally a device ID that was
|
||||
selected from device enumeration via `onContextEnumerateDevices()`.
|
||||
selected from device enumeration via `onContextEnumerateDevices()`.
|
||||
3) A device is started or stopped with `onDeviceStart()` / `onDeviceStop()`
|
||||
4) Data is delivered to and from the device by the backend. This is always done based on the native format returned by the prior call
|
||||
to `onDeviceInit()`. Conversion between the device's native format and the format requested by the application will be handled by
|
||||
miniaudio internally.
|
||||
to `onDeviceInit()`. Conversion between the device's native format and the format requested by the application will be handled by
|
||||
miniaudio internally.
|
||||
|
||||
Initialization of the context is quite simple. You need to do any necessary initialization of internal objects and then output the
|
||||
callbacks defined in this structure.
|
||||
@@ -440,7 +481,7 @@ callbacks defined in this structure.
|
||||
Once the context has been initialized you can initialize a device. Before doing so, however, the application may want to know which
|
||||
physical devices are available. This is where `onContextEnumerateDevices()` comes in. This is fairly simple. For each device, fire the
|
||||
given callback with, at a minimum, the basic information filled out in `ma_device_info`. When the callback returns `MA_FALSE`, enumeration
|
||||
needs to stop and the `onContextEnumerateDevices()` function return with a success code.
|
||||
needs to stop and the `onContextEnumerateDevices()` function returns with a success code.
|
||||
|
||||
Detailed device information can be retrieved from a device ID using `onContextGetDeviceInfo()`. This takes as input the device type and ID,
|
||||
and on output returns detailed information about the device in `ma_device_info`. The `onContextGetDeviceInfo()` callback must handle the
|
||||
@@ -455,7 +496,7 @@ internally by miniaudio.
|
||||
|
||||
On input, if the sample format is set to `ma_format_unknown`, the backend is free to use whatever sample format it desires, so long as it's
|
||||
supported by miniaudio. When the channel count is set to 0, the backend should use the device's native channel count. The same applies for
|
||||
sample rate. For the channel map, the default should be used when `ma_channel_map_blank()` returns true (all channels set to
|
||||
sample rate. For the channel map, the default should be used when `ma_channel_map_is_blank()` returns true (all channels set to
|
||||
`MA_CHANNEL_NONE`). On input, the `periodSizeInFrames` or `periodSizeInMilliseconds` option should always be set. The backend should
|
||||
inspect both of these variables. If `periodSizeInFrames` is set, it should take priority, otherwise it needs to be derived from the period
|
||||
size in milliseconds (`periodSizeInMilliseconds`) and the sample rate, keeping in mind that the sample rate may be 0, in which case the
|
||||
@@ -474,14 +515,17 @@ This allows miniaudio to then process any necessary data conversion and then pas
|
||||
If the backend requires absolute flexibility with it's 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.
|
||||
|
||||
The audio thread should run data delivery logic in a loop while `ma_device_get_state() == MA_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
|
||||
encounted. Do not start or stop the device here. That will be handled from outside the `onDeviceDataLoop()` callback.
|
||||
|
||||
The invocation of the `onDeviceDataLoop()` callback will be handled by miniaudio. When you start the device, miniaudio will fire this
|
||||
callback. When the device is stopped, the `ma_device_get_state() == MA_STATE_STARTED` condition will fail and the loop will be terminated
|
||||
callback. When the device is stopped, the `ma_device_get_state() == ma_device_state_started` condition will fail and the loop will be terminated
|
||||
which will then fall through to the part that stops the device. For an example on how to implement the `onDeviceDataLoop()` callback,
|
||||
look at `ma_device_audio_thread__default_read_write()`. Implement the `onDeviceDataLoopWakeup()` callback if you need a mechanism to
|
||||
wake up the audio thread.
|
||||
|
||||
If the backend supports an optimized retrieval of device information from an initialized `ma_device` object, it should implement the
|
||||
`onDeviceGetInfo()` callback. This is optional, in which case it will fall back to `onContextGetDeviceInfo()` which is less efficient.
|
||||
*/
|
||||
backend_callbacks :: struct {
|
||||
onContextInit: proc "c" (pContext: ^context_type, pConfig: ^context_config, pCallbacks: ^backend_callbacks) -> result,
|
||||
@@ -496,10 +540,10 @@ backend_callbacks :: struct {
|
||||
onDeviceWrite: proc "c" (pDevice: ^device, pFrames: rawptr, frameCount: u32, pFramesWritten: ^u32) -> result,
|
||||
onDeviceDataLoop: proc "c" (pDevice: ^device) -> result,
|
||||
onDeviceDataLoopWakeup: proc "c" (pDevice: ^device) -> result,
|
||||
onDeviceGetInfo: proc "c" (pDevice: ^device, type: device_type, pDeviceInfo: ^device_info) -> result,
|
||||
}
|
||||
|
||||
context_config :: struct {
|
||||
logCallback: log_proc, /* Legacy logging callback. Will be removed in version 0.11. */
|
||||
pLog: ^log,
|
||||
threadPriority: thread_priority,
|
||||
threadStackSize: c.size_t,
|
||||
@@ -538,7 +582,7 @@ context_command__wasapi :: struct {
|
||||
deviceType: device_type,
|
||||
pAudioClient: rawptr,
|
||||
ppAudioClientService: ^rawptr,
|
||||
pResult: ^rawptr, /* The result from creating the audio client service. */
|
||||
pResult: ^result, /* The result from creating the audio client service. */
|
||||
},
|
||||
releaseAudioClient: struct {
|
||||
pDevice: ^device,
|
||||
@@ -548,21 +592,20 @@ context_command__wasapi :: struct {
|
||||
}
|
||||
|
||||
context_type :: struct {
|
||||
callbacks: backend_callbacks,
|
||||
backend: backend, /* DirectSound, ALSA, etc. */
|
||||
pLog: ^log,
|
||||
log: log, /* Only used if the log is owned by the context. The pLog member will be set to &log in this case. */
|
||||
logCallback: log_proc, /* Legacy callback. Will be removed in version 0.11. */
|
||||
threadPriority: thread_priority,
|
||||
threadStackSize: c.size_t,
|
||||
pUserData: rawptr,
|
||||
allocationCallbacks: allocation_callbacks,
|
||||
deviceEnumLock: mutex, /* Used to make ma_context_get_devices() thread safe. */
|
||||
deviceInfoLock: mutex, /* Used to make ma_context_get_device_info() thread safe. */
|
||||
deviceInfoCapacity: u32, /* Total capacity of pDeviceInfos. */
|
||||
callbacks: backend_callbacks,
|
||||
backend: backend, /* DirectSound, ALSA, etc. */
|
||||
pLog: ^log,
|
||||
log: log, /* Only used if the log is owned by the context. The pLog member will be set to &log in this case. */
|
||||
threadPriority: thread_priority,
|
||||
threadStackSize: c.size_t,
|
||||
pUserData: rawptr,
|
||||
allocationCallbacks: allocation_callbacks,
|
||||
deviceEnumLock: mutex, /* Used to make ma_context_get_devices() thread safe. */
|
||||
deviceInfoLock: mutex, /* Used to make ma_context_get_device_info() thread safe. */
|
||||
deviceInfoCapacity: u32, /* Total capacity of pDeviceInfos. */
|
||||
playbackDeviceInfoCount: u32,
|
||||
captureDeviceInfoCount: u32,
|
||||
pDeviceInfos: [^]device_info, /* Playback devices first, then capture. */
|
||||
captureDeviceInfoCount: u32,
|
||||
pDeviceInfos: [^]device_info, /* Playback devices first, then capture. */
|
||||
|
||||
using _: struct #raw_union {
|
||||
wasapi: (struct {
|
||||
@@ -575,7 +618,7 @@ context_type :: struct {
|
||||
} when SUPPORT_WASAPI else struct {}),
|
||||
|
||||
dsound: (struct {
|
||||
DSoundDLL: handle,
|
||||
hDSoundDLL: handle,
|
||||
DirectSoundCreate: proc "system" (),
|
||||
DirectSoundEnumerateA: proc "system" (),
|
||||
DirectSoundCaptureCreate: proc "system" (),
|
||||
@@ -741,6 +784,8 @@ context_type :: struct {
|
||||
|
||||
/*pa_mainloop**/ pMainLoop: rawptr,
|
||||
/*pa_context**/ pPulseContext: rawptr,
|
||||
pApplicationName: cstring, /* Set when the context is initialized. Used by devices for their local pa_context objects. */
|
||||
pServerName: cstring, /* Set when the context is initialized. Used by devices for their local pa_context objects. */
|
||||
} when SUPPORT_PULSEAUDIO else struct {}),
|
||||
|
||||
jack: (struct {
|
||||
@@ -762,7 +807,7 @@ context_type :: struct {
|
||||
jack_port_get_buffer: proc "system" (),
|
||||
jack_free: proc "system" (),
|
||||
|
||||
pClientName: [^]c.char,
|
||||
pClientName: cstring,
|
||||
tryStartServer: b32,
|
||||
} when SUPPORT_JACK else struct {}),
|
||||
|
||||
@@ -817,7 +862,7 @@ context_type :: struct {
|
||||
} when SUPPORT_SNDIO else struct {}),
|
||||
|
||||
audio4: (struct {
|
||||
_unused: cint,
|
||||
_unused: c.int,
|
||||
} when SUPPORT_AUDIO4 else struct {}),
|
||||
|
||||
oss: (struct {
|
||||
@@ -855,6 +900,7 @@ context_type :: struct {
|
||||
AAudioStream_getFramesPerBurst: proc "system" (),
|
||||
AAudioStream_requestStart: proc "system" (),
|
||||
AAudioStream_requestStop: proc "system" (),
|
||||
jobThread: device_job_thread, /* For processing operations outside of the error callback, specifically device disconnections and rerouting. */
|
||||
} when SUPPORT_AAUDIO else struct {}),
|
||||
|
||||
opensl: (struct {
|
||||
@@ -921,37 +967,40 @@ context_type :: struct {
|
||||
}
|
||||
|
||||
device :: struct {
|
||||
pContext: ^context_type,
|
||||
type: device_type,
|
||||
sampleRate: u32,
|
||||
state: u32, /*atomic*/ /* The state of the device is variable and can change at any time on any thread. Must be used atomically. */
|
||||
onData: device_callback_proc, /* Set once at initialization time and should not be changed after. */
|
||||
onStop: stop_proc, /* Set once at initialization time and should not be changed after. */
|
||||
pUserData: rawptr, /* Application defined data. */
|
||||
startStopLock: mutex,
|
||||
wakeupEvent: event,
|
||||
startEvent: event,
|
||||
stopEvent: event,
|
||||
device_thread: thread,
|
||||
workResult: result, /* This is set by the worker thread after it's finished doing a job. */
|
||||
isOwnerOfContext: b8, /* When set to true, uninitializing the device will also uninitialize the context. Set to true when NULL is passed into ma_device_init(). */
|
||||
noPreZeroedOutputBuffer: b8,
|
||||
noClip: b8,
|
||||
masterVolumeFactor: f32, /*atomic*/ /* Linear 0..1. Can be read and written simultaneously by different threads. Must be used atomically. */
|
||||
duplexRB: duplex_rb, /* Intermediary buffer for duplex device on asynchronous backends. */
|
||||
pContext: ^context_type,
|
||||
type: device_type,
|
||||
sampleRate: u32,
|
||||
state: u32, /*atomic*/ /* The state of the device is variable and can change at any time on any thread. Must be used atomically. */
|
||||
onData: device_data_proc, /* Set once at initialization time and should not be changed after. */
|
||||
onNotification: device_notification_proc, /* Set once at initialization time and should not be changed after. */
|
||||
onStop: stop_proc, /* DEPRECATED. Use the notification callback instead. Set once at initialization time and should not be changed after. */
|
||||
pUserData: rawptr, /* Application defined data. */
|
||||
startStopLock: mutex,
|
||||
wakeupEvent: event,
|
||||
startEvent: event,
|
||||
stopEvent: event,
|
||||
device_thread: thread,
|
||||
workResult: result, /* This is set by the worker thread after it's finished doing a job. */
|
||||
isOwnerOfContext: b8, /* When set to true, uninitializing the device will also uninitialize the context. Set to true when NULL is passed into ma_device_init(). */
|
||||
noPreSilencedOutputBuffer: b8,
|
||||
noClip: b8,
|
||||
noDisableDenormals: b8,
|
||||
noFixedSizedCallback: b8,
|
||||
masterVolumeFactor: f32, /*atomic*/ /* Linear 0..1. Can be read and written simultaneously by different threads. Must be used atomically. */
|
||||
duplexRB: duplex_rb, /* Intermediary buffer for duplex device on asynchronous backends. */
|
||||
resampling: struct {
|
||||
algorithm: resample_algorithm,
|
||||
algorithm: resample_algorithm,
|
||||
pBackendVTable: ^resampling_backend_vtable,
|
||||
pBackendUserData: rawptr,
|
||||
linear: struct {
|
||||
lpfOrder: u32,
|
||||
},
|
||||
speex: struct {
|
||||
quality: c.int,
|
||||
},
|
||||
},
|
||||
playback: struct {
|
||||
id: device_id, /* If using an explicit device, will be set to a copy of the ID used for initialization. Otherwise cleared to 0. */
|
||||
name: [256]byte, /* Maybe temporary. Likely to be replaced with a query API. */
|
||||
shareMode: share_mode, /* Set to whatever was passed in when the device was initialized. */
|
||||
pID: ^device_id, /* Set to NULL if using default ID, otherwise set to the address of "id". */
|
||||
id: device_id, /* If using an explicit device, will be set to a copy of the ID used for initialization. Otherwise cleared to 0. */
|
||||
name: [MAX_DEVICE_NAME_LENGTH + 1]c.char, /* Maybe temporary. Likely to be replaced with a query API. */
|
||||
shareMode: share_mode, /* Set to whatever was passed in when the device was initialized. */
|
||||
playback_format: format,
|
||||
channels: u32,
|
||||
channelMap: [MAX_CHANNELS]channel,
|
||||
@@ -963,11 +1012,19 @@ device :: struct {
|
||||
internalPeriods: u32,
|
||||
channelMixMode: channel_mix_mode,
|
||||
converter: data_converter,
|
||||
pIntermediaryBuffer: rawptr, /* For implementing fixed sized buffer callbacks. Will be null if using variable sized callbacks. */
|
||||
intermediaryBufferCap: u32,
|
||||
intermediaryBufferLen: u32, /* How many valid frames are sitting in the intermediary buffer. */
|
||||
pInputCache: rawptr, /* In external format. Can be null. */
|
||||
inputCacheCap: u64,
|
||||
inputCacheConsumed: u64,
|
||||
inputCacheRemaining: u64,
|
||||
},
|
||||
capture: struct {
|
||||
id: device_id, /* If using an explicit device, will be set to a copy of the ID used for initialization. Otherwise cleared to 0. */
|
||||
name: [256]byte, /* Maybe temporary. Likely to be replaced with a query API. */
|
||||
shareMode: share_mode, /* Set to whatever was passed in when the device was initialized. */
|
||||
pID: ^device_id, /* Set to NULL if using default ID, otherwise set to the address of "id". */
|
||||
id: device_id, /* If using an explicit device, will be set to a copy of the ID used for initialization. Otherwise cleared to 0. */
|
||||
name: [MAX_DEVICE_NAME_LENGTH + 1]c.char, /* Maybe temporary. Likely to be replaced with a query API. */
|
||||
shareMode: share_mode, /* Set to whatever was passed in when the device was initialized. */
|
||||
capture_format: format,
|
||||
channels: u32,
|
||||
channelMap: [MAX_CHANNELS]channel,
|
||||
@@ -979,6 +1036,9 @@ device :: struct {
|
||||
internalPeriods: u32,
|
||||
channelMixMode: channel_mix_mode,
|
||||
converter: data_converter,
|
||||
pIntermediaryBuffer: rawptr, /* For implementing fixed sized buffer callbacks. Will be null if using variable sized callbacks. */
|
||||
intermediaryBufferCap: u32,
|
||||
intermediaryBufferLen: u32, /* How many valid frames are sitting in the intermediary buffer. */
|
||||
},
|
||||
|
||||
using _: struct #raw_union {
|
||||
@@ -991,7 +1051,7 @@ device :: struct {
|
||||
notificationClient: IMMNotificationClient,
|
||||
/*HANDLE*/ hEventPlayback: handle, /* Auto reset. Initialized to signaled. */
|
||||
/*HANDLE*/ hEventCapture: handle, /* Auto reset. Initialized to unsignaled. */
|
||||
actualPeriodSizeInFramesPlayback: u32, /* Value from GetBufferSize(). internalPeriodSizeInFrames is not set to the _actual_ buffer size when low-latency shared mode is being used due to the way the IAudioClient3 API works. */
|
||||
actualPeriodSizeInFramesPlayback: u32, /* Value from GetBufferSize(). internalPeriodSizeInFrames is not set to the _actual_ buffer size when low-latency shared mode is being used due to the way the IAudioClient3 API works. */
|
||||
actualPeriodSizeInFramesCapture: u32,
|
||||
originalPeriodSizeInFrames: u32,
|
||||
originalPeriodSizeInMilliseconds: u32,
|
||||
@@ -999,8 +1059,14 @@ device :: struct {
|
||||
originalPerformanceProfile: performance_profile,
|
||||
periodSizeInFramesPlayback: u32,
|
||||
periodSizeInFramesCapture: u32,
|
||||
isStartedCapture: b32, /*atomic*/ /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
|
||||
isStartedPlayback: b32, /*atomic*/ /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
|
||||
pMappedBufferCapture: rawptr,
|
||||
mappedBufferCaptureCap: u32,
|
||||
mappedBufferCaptureLen: u32,
|
||||
pMappedBufferPlayback: rawptr,
|
||||
mappedBufferPlaybackCap: u32,
|
||||
mappedBufferPlaybackLen: u32,
|
||||
isStartedCapture: b32, /*atomic*/ /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
|
||||
isStartedPlayback: b32, /*atomic*/ /* Can be read and written simultaneously across different threads. Must be used atomically, and must be 32-bit. */
|
||||
noAutoConvertSRC: b8, /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM. */
|
||||
noDefaultQualitySRC: b8, /* When set to true, disables the use of AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY. */
|
||||
noHardwareOffloading: b8,
|
||||
@@ -1049,14 +1115,16 @@ device :: struct {
|
||||
} when SUPPORT_ALSA else struct {}),
|
||||
|
||||
pulse: (struct {
|
||||
/*pa_mainloop**/ pMainLoop: rawptr,
|
||||
/*pa_context**/ pPulseContext: rawptr,
|
||||
/*pa_stream**/ pStreamPlayback: rawptr,
|
||||
/*pa_stream**/ pStreamCapture: rawptr,
|
||||
} when SUPPORT_PULSEAUDIO else struct {}),
|
||||
|
||||
jack: (struct {
|
||||
/*jack_client_t**/ pClient: rawptr,
|
||||
/*jack_port_t**/ pPortsPlayback: [MAX_CHANNELS]rawptr,
|
||||
/*jack_port_t**/ pPortsCapture: [MAX_CHANNELS]rawptr,
|
||||
/*jack_port_t**/ pPortsPlayback: [^]rawptr,
|
||||
/*jack_port_t**/ pPortsCapture: [^]rawptr,
|
||||
pIntermediaryBufferPlayback: [^]f32, /* Typed as a float because JACK is always floating point. */
|
||||
pIntermediaryBufferCapture: [^]f32,
|
||||
} when SUPPORT_JACK else struct {}),
|
||||
@@ -1079,6 +1147,7 @@ device :: struct {
|
||||
isSwitchingCaptureDevice: b32, /* <-- Set to true when the default device has changed and miniaudio is in the process of switching. */
|
||||
pRouteChangeHandler: rawptr, /* Only used on mobile platforms. Obj-C object for handling route changes. */
|
||||
} when SUPPORT_COREAUDIO else struct {}),
|
||||
|
||||
sndio: (struct {
|
||||
handlePlayback: rawptr,
|
||||
handleCapture: rawptr,
|
||||
@@ -1099,6 +1168,10 @@ device :: struct {
|
||||
aaudio: (struct {
|
||||
/*AAudioStream**/ pStreamPlayback: rawptr,
|
||||
/*AAudioStream**/ pStreamCapture: rawptr,
|
||||
usage: aaudio_usage,
|
||||
contentType: aaudio_content_type,
|
||||
inputPreset: aaudio_input_preset,
|
||||
noAutoStartAfterReroute: b32,
|
||||
} when SUPPORT_AAUDIO else struct {}),
|
||||
|
||||
opensl: (struct {
|
||||
|
||||
2955
vendor/miniaudio/doc.odin
vendored
2955
vendor/miniaudio/doc.odin
vendored
File diff suppressed because it is too large
Load Diff
300
vendor/miniaudio/effects.odin
vendored
Normal file
300
vendor/miniaudio/effects.odin
vendored
Normal file
@@ -0,0 +1,300 @@
|
||||
package miniaudio
|
||||
|
||||
import c "core:c/libc"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import lib "lib/miniaudio.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "lib/miniaudio.a"
|
||||
} else {
|
||||
foreign import lib "system:miniaudio"
|
||||
}
|
||||
|
||||
/*
|
||||
Delay
|
||||
*/
|
||||
delay_config :: struct {
|
||||
channels: u32,
|
||||
sampleRate: u32,
|
||||
delayInFrames: u32,
|
||||
delayStart: b32, /* Set to true to delay the start of the output; false otherwise. */
|
||||
wet: f32, /* 0..1. Default = 1. */
|
||||
dry: f32, /* 0..1. Default = 1. */
|
||||
decay: f32, /* 0..1. Default = 0 (no feedback). Feedback decay. Use this for echo. */
|
||||
}
|
||||
|
||||
delay :: struct {
|
||||
config: delay_config,
|
||||
cursor: u32, /* Feedback is written to this cursor. Always equal or in front of the read cursor. */
|
||||
bufferSizeInFrames: u32, /* The maximum of config.startDelayInFrames and config.feedbackDelayInFrames. */
|
||||
pBuffer: [^]f32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
delay_config_init :: proc(channels, sampleRate, delayInFrames: u32, decay: f32) -> delay_config ---
|
||||
|
||||
delay_init :: proc(pConfig: ^delay_config, pAllocationCallbacks: ^allocation_callbacks, pDelay: ^delay) -> result ---
|
||||
delay_uninit :: proc(pDelay: ^delay, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
delay_process_pcm_frames :: proc(pDelay: ^delay, pFramesOut, pFramesIn: rawptr, frameCount: u32) -> result ---
|
||||
delay_set_wet :: proc(pDelay: ^delay, value: f32) ---
|
||||
delay_get_wet :: proc(pDelay: ^delay) -> f32 ---
|
||||
delay_set_dry :: proc(pDelay: ^delay, value: f32) ---
|
||||
delay_get_dry :: proc(pDelay: ^delay) -> f32 ---
|
||||
delay_set_decay :: proc(pDelay: ^delay, value: f32) ---
|
||||
delay_get_decay :: proc(pDelay: ^delay) -> f32 ---
|
||||
}
|
||||
|
||||
|
||||
/* Gainer for smooth volume changes. */
|
||||
gainer_config :: struct {
|
||||
channels: u32,
|
||||
smoothTimeInFrames: u32,
|
||||
}
|
||||
|
||||
gainer :: struct {
|
||||
config: gainer_config,
|
||||
t: u32,
|
||||
pOldGains: [^]f32,
|
||||
pNewGains: [^]f32,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
gainer_config_init :: proc(channels, smoothTimeInFrames: u32) -> gainer_config ---
|
||||
|
||||
gainer_get_heap_size :: proc(pConfig: ^gainer_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
gainer_init_preallocated :: proc(pConfig: ^gainer_config, pHeap: rawptr, pGainer: ^gainer) -> result ---
|
||||
gainer_init :: proc(pConfig: ^gainer_config, pAllocationCallbacks: ^allocation_callbacks, pGainer: ^gainer) -> result ---
|
||||
gainer_uninit :: proc(pGainer: ^gainer, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
gainer_process_pcm_frames :: proc(pGainer: ^gainer, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
gainer_set_gain :: proc(pGainer: ^gainer, newGain: f32) -> result ---
|
||||
gainer_set_gains :: proc(pGainer: ^gainer, pNewGains: [^]f32) -> result ---
|
||||
}
|
||||
|
||||
|
||||
/* Stereo panner. */
|
||||
pan_mode :: enum c.int {
|
||||
balance = 0, /* Does not blend one side with the other. Technically just a balance. Compatible with other popular audio engines and therefore the default. */
|
||||
pan, /* A true pan. The sound from one side will "move" to the other side and blend with it. */
|
||||
}
|
||||
|
||||
panner_config :: struct {
|
||||
format: format,
|
||||
channels: u32,
|
||||
mode: pan_mode,
|
||||
pan: f32,
|
||||
}
|
||||
|
||||
panner :: struct {
|
||||
format: format,
|
||||
channels: u32,
|
||||
mode: pan_mode,
|
||||
pan: f32, /* -1..1 where 0 is no pan, -1 is left side, +1 is right side. Defaults to 0. */
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
panner_config_init :: proc(format: format, channels: u32) -> panner_config ---
|
||||
|
||||
panner_init :: proc(pConfig: ^panner_config, pPanner: ^panner) -> result ---
|
||||
panner_process_pcm_frames :: proc(pPanner: ^panner, pFramesOut, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
panner_set_mode :: proc(pPanner: ^panner, mode: pan_mode) ---
|
||||
panner_get_mode :: proc(pPanner: ^panner) -> pan_mode ---
|
||||
panner_set_pan :: proc(pPanner: ^panner, pan: f32) ---
|
||||
panner_get_pan :: proc(pPanner: ^panner) -> f32 ---
|
||||
}
|
||||
|
||||
|
||||
/* Fader. */
|
||||
fader_config :: struct {
|
||||
format: format,
|
||||
channels: u32,
|
||||
sampleRate: u32,
|
||||
}
|
||||
|
||||
fader :: struct {
|
||||
config: fader_config,
|
||||
volumeBeg: f32, /* If volumeBeg and volumeEnd is equal to 1, no fading happens (ma_fader_process_pcm_frames() will run as a passthrough). */
|
||||
volumeEnd: f32,
|
||||
lengthInFrames: u64, /* The total length of the fade. */
|
||||
cursorInFrames: u64, /* The current time in frames. Incremented by ma_fader_process_pcm_frames(). */
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
fader_config_init :: proc(format: format, channels, sampleRate: u32) -> fader_config ---
|
||||
|
||||
fader_init :: proc(pConfig: ^fader_config, pFader: ^fader) -> result ---
|
||||
fader_process_pcm_frames :: proc(pFader: ^fader, pFramesOut, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
fader_get_data_format :: proc(pFader: ^fader, pFormat: ^format, pChannels, pSampleRate: ^u32) ---
|
||||
fader_set_fade :: proc(pFader: ^fader, volumeBeg, volumeEnd: f32, lengthInFrames: u64) ---
|
||||
fader_get_current_volume :: proc(pFader: ^fader) -> f32 ---
|
||||
}
|
||||
|
||||
|
||||
/* Spatializer. */
|
||||
vec3f :: struct {
|
||||
x: f32,
|
||||
y: f32,
|
||||
z: f32,
|
||||
}
|
||||
|
||||
attenuation_model :: enum c.int {
|
||||
none, /* No distance attenuation and no spatialization. */
|
||||
inverse, /* Equivalent to OpenAL's AL_INVERSE_DISTANCE_CLAMPED. */
|
||||
linear, /* Linear attenuation. Equivalent to OpenAL's AL_LINEAR_DISTANCE_CLAMPED. */
|
||||
exponential, /* Exponential attenuation. Equivalent to OpenAL's AL_EXPONENT_DISTANCE_CLAMPED. */
|
||||
}
|
||||
|
||||
positioning :: enum c.int {
|
||||
absolute,
|
||||
relative,
|
||||
}
|
||||
|
||||
handedness :: enum c.int {
|
||||
right,
|
||||
left,
|
||||
}
|
||||
|
||||
spatializer_listener_config :: struct {
|
||||
channelsOut: u32,
|
||||
pChannelMapOut: [^]channel,
|
||||
handedness: handedness, /* Defaults to right. Forward is -1 on the Z axis. In a left handed system, forward is +1 on the Z axis. */
|
||||
coneInnerAngleInRadians: f32,
|
||||
coneOuterAngleInRadians: f32,
|
||||
coneOuterGain: f32,
|
||||
speedOfSound: f32,
|
||||
worldUp: vec3f,
|
||||
}
|
||||
|
||||
spatializer_listener :: struct {
|
||||
config: spatializer_listener_config,
|
||||
position: vec3f, /* The absolute position of the listener. */
|
||||
direction: vec3f, /* The direction the listener is facing. The world up vector is config.worldUp. */
|
||||
velocity: vec3f,
|
||||
isEnabled: b32,
|
||||
|
||||
/* Memory management. */
|
||||
_ownsHeap: b32,
|
||||
_pHeap: rawptr,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
spatializer_listener_config_init :: proc(channelsOut: u32) -> spatializer_listener_config ---
|
||||
|
||||
spatializer_listener_get_heap_size :: proc(pConfig: ^spatializer_listener_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
spatializer_listener_init_preallocated :: proc(pConfig: ^spatializer_listener_config, pHeap: rawptr, pListener: ^spatializer_listener) -> result ---
|
||||
spatializer_listener_init :: proc(pConfig: ^spatializer_listener_config, pAllocationCallbacks: ^allocation_callbacks, pListener: ^spatializer_listener) -> result ---
|
||||
spatializer_listener_uninit :: proc(pListener: ^spatializer_listener, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
spatializer_listener_get_channel_map :: proc(pListener: ^spatializer_listener) -> ^channel ---
|
||||
spatializer_listener_set_cone :: proc(pListener: ^spatializer_listener, innerAngleInRadians, outerAngleInRadians, outerGain: f32) ---
|
||||
spatializer_listener_get_cone :: proc(pListener: ^spatializer_listener, pInnerAngleInRadians, pOuterAngleInRadians, pOuterGain: ^f32) ---
|
||||
spatializer_listener_set_position :: proc(pListener: ^spatializer_listener, x, y, z: f32) ---
|
||||
spatializer_listener_get_position :: proc(pListener: ^spatializer_listener) -> vec3f ---
|
||||
spatializer_listener_set_direction :: proc(pListener: ^spatializer_listener, x, y, z: f32) ---
|
||||
spatializer_listener_get_direction :: proc(pListener: ^spatializer_listener) -> vec3f ---
|
||||
spatializer_listener_set_velocity :: proc(pListener: ^spatializer_listener, x, y, z: f32) ---
|
||||
spatializer_listener_get_velocity :: proc(pListener: ^spatializer_listener) -> vec3f ---
|
||||
spatializer_listener_set_speed_of_sound :: proc(pListener: ^spatializer_listener, speedOfSound: f32) ---
|
||||
spatializer_listener_get_speed_of_sound :: proc(pListener: ^spatializer_listener) -> f32 ---
|
||||
spatializer_listener_set_world_up :: proc(pListener: ^spatializer_listener, x, y, z: f32) ---
|
||||
spatializer_listener_get_world_up :: proc(pListener: ^spatializer_listener) -> vec3f ---
|
||||
spatializer_listener_set_enabled :: proc(pListener: ^spatializer_listener, isEnabled: b32) ---
|
||||
spatializer_listener_is_enabled :: proc(pListener: ^spatializer_listener) -> b32 ---
|
||||
}
|
||||
|
||||
spatializer_config :: struct {
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
pChannelMapIn: [^]channel,
|
||||
attenuationModel: attenuation_model,
|
||||
positioning: positioning,
|
||||
handedness: handedness, /* Defaults to right. Forward is -1 on the Z axis. In a left handed system, forward is +1 on the Z axis. */
|
||||
minGain: f32,
|
||||
maxGain: f32,
|
||||
minDistance: f32,
|
||||
maxDistance: f32,
|
||||
rolloff: f32,
|
||||
coneInnerAngleInRadians: f32,
|
||||
coneOuterAngleInRadians: f32,
|
||||
coneOuterGain: f32,
|
||||
dopplerFactor: f32, /* Set to 0 to disable doppler effect. */
|
||||
directionalAttenuationFactor: f32, /* Set to 0 to disable directional attenuation. */
|
||||
gainSmoothTimeInFrames: u32, /* When the gain of a channel changes during spatialization, the transition will be linearly interpolated over this number of frames. */
|
||||
}
|
||||
|
||||
spatializer :: struct {
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
pChannelMapIn: [^]channel,
|
||||
attenuationModel: attenuation_model,
|
||||
positioning: positioning,
|
||||
handedness: handedness, /* Defaults to right. Forward is -1 on the Z axis. In a left handed system, forward is +1 on the Z axis. */
|
||||
minGain: f32,
|
||||
maxGain: f32,
|
||||
minDistance: f32,
|
||||
maxDistance: f32,
|
||||
rolloff: f32,
|
||||
coneInnerAngleInRadians: f32,
|
||||
coneOuterAngleInRadians: f32,
|
||||
coneOuterGain: f32,
|
||||
dopplerFactor: f32, /* Set to 0 to disable doppler effect. */
|
||||
directionalAttenuationFactor: f32, /* Set to 0 to disable directional attenuation. */
|
||||
gainSmoothTimeInFrames: u32, /* When the gain of a channel changes during spatialization, the transition will be linearly interpolated over this number of frames. */
|
||||
position: vec3f,
|
||||
direction: vec3f,
|
||||
velocity: vec3f, /* For doppler effect. */
|
||||
dopplerPitch: f32, /* Will be updated by ma_spatializer_process_pcm_frames() and can be used by higher level functions to apply a pitch shift for doppler effect. */
|
||||
gainer: gainer, /* For smooth gain transitions. */
|
||||
pNewChannelGainsOut: [^]f32, /* An offset of _pHeap. Used by ma_spatializer_process_pcm_frames() to store new channel gains. The number of elements in this array is equal to config.channelsOut. */
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
spatializer_config_init :: proc(channelsIn, channelsOut: u32) -> spatializer_config ---
|
||||
|
||||
spatializer_get_heap_size :: proc(pConfig: ^spatializer_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
spatializer_init_preallocated :: proc(pConfig: ^spatializer_config, pHeap: rawptr, pSpatializer: ^spatializer) -> result ---
|
||||
spatializer_init :: proc(pConfig: ^spatializer_config, pAllocationCallbacks: ^allocation_callbacks, pSpatializer: ^spatializer) -> result ---
|
||||
spatializer_uninit :: proc(pSpatializer: ^spatializer, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
spatializer_process_pcm_frames :: proc(pSpatializer: ^spatializer, pListener: ^spatializer_listener, pFramesOut, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
spatializer_get_input_channels :: proc(pSpatializer: ^spatializer) -> u32 ---
|
||||
spatializer_get_output_channels :: proc(pSpatializer: ^spatializer) -> u32 ---
|
||||
spatializer_set_attenuation_model :: proc(pSpatializer: ^spatializer, attenuationModel: attenuation_model) ---
|
||||
spatializer_get_attenuation_model :: proc(pSpatializer: ^spatializer) -> attenuation_model ---
|
||||
spatializer_set_positioning :: proc(pSpatializer: ^spatializer, positioning: positioning) ---
|
||||
spatializer_get_positioning :: proc(pSpatializer: ^spatializer) -> positioning ---
|
||||
spatializer_set_rolloff :: proc(pSpatializer: ^spatializer, rolloff: f32) ---
|
||||
spatializer_get_rolloff :: proc(pSpatializer: ^spatializer) -> f32 ---
|
||||
spatializer_set_min_gain :: proc(pSpatializer: ^spatializer, minGain: f32) ---
|
||||
spatializer_get_min_gain :: proc(pSpatializer: ^spatializer) -> f32 ---
|
||||
spatializer_set_max_gain :: proc(pSpatializer: ^spatializer, maxGain: f32) ---
|
||||
spatializer_get_max_gain :: proc(pSpatializer: ^spatializer) -> f32 ---
|
||||
spatializer_set_min_distance :: proc(pSpatializer: ^spatializer, minDistance: f32) ---
|
||||
spatializer_get_min_distance :: proc(pSpatializer: ^spatializer) -> f32 ---
|
||||
spatializer_set_max_distance :: proc(pSpatializer: ^spatializer, maxDistance: f32) ---
|
||||
spatializer_get_max_distance :: proc(pSpatializer: ^spatializer) -> f32 ---
|
||||
spatializer_set_cone :: proc(pSpatializer: ^spatializer, innerAngleInRadians, outerAngleInRadians, outerGain: f32) ---
|
||||
spatializer_get_cone :: proc(pSpatializer: ^spatializer, pInnerAngleInRadians, pOuterAngleInRadians, pOuterGain: ^f32) ---
|
||||
spatializer_set_doppler_factor :: proc(pSpatializer: ^spatializer, dopplerFactor: f32) ---
|
||||
spatializer_get_doppler_factor :: proc(pSpatializer: ^spatializer) -> f32 ---
|
||||
spatializer_set_directional_attenuation_factor :: proc(pSpatializer: ^spatializer, directionalAttenuationFactor: f32) ---
|
||||
spatializer_get_directional_attenuation_factor :: proc(pSpatializer: ^spatializer) -> f32 ---
|
||||
spatializer_set_position :: proc(pSpatializer: ^spatializer, x, y, z: f32) ---
|
||||
spatializer_get_position :: proc(pSpatializer: ^spatializer) -> vec3f ---
|
||||
spatializer_set_direction :: proc(pSpatializer: ^spatializer, x, y, z: f32) ---
|
||||
spatializer_get_direction :: proc(pSpatializer: ^spatializer) -> vec3f ---
|
||||
spatializer_set_velocity :: proc(pSpatializer: ^spatializer, x, y, z: f32) ---
|
||||
spatializer_get_velocity :: proc(pSpatializer: ^spatializer) -> vec3f ---
|
||||
spatializer_get_relative_position_and_direction :: proc(pSpatializer: ^spatializer, pListener: ^spatializer_listener, pRelativePos, pRelativeDir: ^vec3f) ---
|
||||
}
|
||||
23
vendor/miniaudio/encoding.odin
vendored
23
vendor/miniaudio/encoding.odin
vendored
@@ -19,14 +19,14 @@ Encoders do not perform any format conversion for you. If your target format doe
|
||||
|
||||
************************************************************************************************************************************************************/
|
||||
|
||||
encoder_write_proc :: proc "c" (pEncoder: ^encoder, pBufferIn: rawptr, bytesToWrite: c.size_t) -> c.size_t /* Returns the number of bytes written. */
|
||||
encoder_seek_proc :: proc "c" (pEncoder: ^encoder, byteOffset: c.int, origin: seek_origin) -> b32
|
||||
encoder_write_proc :: proc "c" (pEncoder: ^encoder, pBufferIn: rawptr, bytesToWrite: c.size_t, pBytesWritten: ^c.size_t) -> result
|
||||
encoder_seek_proc :: proc "c" (pEncoder: ^encoder, offset: i64, origin: seek_origin) -> result
|
||||
encoder_init_proc :: proc "c" (pEncoder: ^encoder) -> result
|
||||
encoder_uninit_proc :: proc "c" (pEncoder: ^encoder)
|
||||
encoder_write_pcm_frames_proc :: proc "c" (pEncoder: ^encoder, pFramesIn: rawptr, frameCount: u64) -> u64
|
||||
encoder_uninit_proc :: proc "c" (pEncoder: ^encoder)
|
||||
encoder_write_pcm_frames_proc :: proc "c" (pEncoder: ^encoder, pFramesIn: rawptr, frameCount: u64, pFramesWritten: ^u64) -> result
|
||||
|
||||
encoder_config :: struct {
|
||||
resourceFormat: resource_format,
|
||||
encodingFormat: encoding_format,
|
||||
format: format,
|
||||
channels: u32,
|
||||
sampleRate: u32,
|
||||
@@ -42,16 +42,23 @@ encoder :: struct {
|
||||
onWritePCMFrames: encoder_write_pcm_frames_proc,
|
||||
pUserData: rawptr,
|
||||
pInternalEncoder: rawptr, /* <-- The drwav/drflac/stb_vorbis/etc. objects. */
|
||||
pFile: rawptr, /* FILE*. Only used when initialized with ma_encoder_init_file(). */
|
||||
data: struct #raw_union {
|
||||
vfs: struct {
|
||||
pVFS: ^vfs,
|
||||
file: vfs_file,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
encoder_config_init :: proc(resourceFormat: resource_format, format: format, channels: u32, sampleRate: u32) -> encoder_config ---
|
||||
encoder_config_init :: proc(encodingFormat: encoding_format, format: format, channels: u32, sampleRate: u32) -> encoder_config ---
|
||||
|
||||
encoder_init :: proc(onWrite: encoder_write_proc, onSeek: encoder_seek_proc, pUserData: rawptr, pConfig: ^encoder_config, pEncoder: ^encoder) -> result ---
|
||||
encoder_init_vfs :: proc(pVFS: ^vfs, pFilePath: cstring, pConfig: ^encoder_config, pEncoder: ^encoder) -> result ---
|
||||
encoder_init_vfs_w :: proc(pVFS: ^vfs, pFilePath: [^]c.wchar_t, pConfig: ^encoder_config, pEncoder: ^encoder) -> result ---
|
||||
encoder_init_file :: proc(pFilePath: cstring, pConfig: ^encoder_config, pEncoder: ^encoder) -> result ---
|
||||
encoder_init_file_w :: proc(pFilePath: [^]c.wchar_t, pConfig: ^encoder_config, pEncoder: ^encoder) -> result ---
|
||||
encoder_uninit :: proc(pEncoder: ^encoder) ---
|
||||
encoder_write_pcm_frames :: proc(pEncoder: ^encoder, FramesIn: rawptr, frameCount: u64) -> u64 ---
|
||||
encoder_write_pcm_frames :: proc(pEncoder: ^encoder, FramesIn: rawptr, frameCount: u64, pFramesWritten: ^u64) -> result ---
|
||||
}
|
||||
|
||||
341
vendor/miniaudio/engine.odin
vendored
Normal file
341
vendor/miniaudio/engine.odin
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
package miniaudio
|
||||
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import lib "lib/miniaudio.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "lib/miniaudio.a"
|
||||
} else {
|
||||
foreign import lib "system:miniaudio"
|
||||
}
|
||||
|
||||
/************************************************************************************************************************************************************
|
||||
|
||||
Engine
|
||||
|
||||
************************************************************************************************************************************************************/
|
||||
|
||||
/* Sound flags. */
|
||||
sound_flags :: enum c.int {
|
||||
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 */
|
||||
NO_DEFAULT_ATTACHMENT = 0x00000010, /* Do not attach to the endpoint by default. Useful for when setting up nodes in a complex graph system. */
|
||||
NO_PITCH = 0x00000020, /* Disable pitch shifting with ma_sound_set_pitch() and ma_sound_group_set_pitch(). This is an optimization. */
|
||||
NO_SPATIALIZATION = 0x00000040, /* Disable spatialization. */
|
||||
}
|
||||
|
||||
ENGINE_MAX_LISTENERS :: 4
|
||||
|
||||
LISTENER_INDEX_CLOSEST :: 255
|
||||
|
||||
engine_node_type :: enum c.int {
|
||||
sound,
|
||||
group,
|
||||
}
|
||||
|
||||
engine_node_config :: struct {
|
||||
pEngine: ^engine,
|
||||
type: engine_node_type,
|
||||
channelsIn: u32,
|
||||
channelsOut: u32,
|
||||
sampleRate: u32, /* Only used when the type is set to ma_engine_node_type_sound. */
|
||||
isPitchDisabled: b8, /* Pitching can be explicitly disable with MA_SOUND_FLAG_NO_PITCH to optimize processing. */
|
||||
isSpatializationDisabled: b8, /* Spatialization can be explicitly disabled with MA_SOUND_FLAG_NO_SPATIALIZATION. */
|
||||
pinnedListenerIndex: u8, /* The index of the listener this node should always use for spatialization. If set to MA_LISTENER_INDEX_CLOSEST the engine will use the closest listener. */
|
||||
}
|
||||
|
||||
/* Base node object for both ma_sound and ma_sound_group. */
|
||||
engine_node :: struct {
|
||||
baseNode: node_base, /* Must be the first member for compatiblity with the ma_node API. */
|
||||
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. */
|
||||
fader: fader,
|
||||
resampler: linear_resampler, /* For pitch shift. */
|
||||
spatializer: spatializer,
|
||||
panner: panner,
|
||||
pitch: f32, /*atomic*/
|
||||
oldPitch: f32, /* For determining whether or not the resampler needs to be updated to reflect the new pitch. The resampler will be updated on the mixing thread. */
|
||||
oldDopplerPitch: f32, /* For determining whether or not the resampler needs to be updated to take a new doppler pitch into account. */
|
||||
isPitchDisabled: b32, /*atomic*/ /* When set to true, pitching will be disabled which will allow the resampler to be bypassed to save some computation. */
|
||||
isSpatializationDisabled: b32, /*atomic*/ /* Set to false by default. When set to false, will not have spatialisation applied. */
|
||||
pinnedListenerIndex: u32, /*atomic*/ /* The index of the listener this node should always use for spatialization. If set to MA_LISTENER_INDEX_CLOSEST the engine will use the closest listener. */
|
||||
|
||||
/* Memory management. */
|
||||
_ownsHeap: b8,
|
||||
_pHeap: rawptr,
|
||||
}
|
||||
|
||||
@(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_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 ---
|
||||
engine_node_init :: proc(pConfig: ^engine_node_config, pAllocationCallbacks: ^allocation_callbacks, pEngineNode: ^engine_node) -> result ---
|
||||
engine_node_uninit :: proc(pEngineNode: ^engine_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
SOUND_SOURCE_CHANNEL_COUNT :: 0xFFFFFFFF
|
||||
|
||||
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). */
|
||||
flags: u32, /* A combination of MA_SOUND_FLAG_* flags. */
|
||||
initialSeekPointInPCMFrames: u64, /* Initializes the sound such that it's seeked to this location by default. */
|
||||
rangeBegInPCMFrames: u64,
|
||||
rangeEndInPCMFrames: u64,
|
||||
loopPointBegInPCMFrames: u64,
|
||||
loopPointEndInPCMFrames: u64,
|
||||
isLooping: b32,
|
||||
pDoneFence: ^fence, /* Released when the resource manager has finished decoding the entire sound. Not used with streams. */
|
||||
}
|
||||
|
||||
sound :: struct {
|
||||
engineNode: engine_node, /* Must be the first member for compatibility with the ma_node API. */
|
||||
pDataSource: ^data_source,
|
||||
seekTarget: u64, /*atomic*/ /* The PCM frame index to seek to in the mixing thread. Set to (~(ma_uint64)0) to not perform any seeking. */
|
||||
atEnd: b32, /*atomic*/
|
||||
ownsDataSource: b8,
|
||||
|
||||
/*
|
||||
We're declaring a resource manager data source object here to save us a malloc when loading a
|
||||
sound via the resource manager, which I *think* will be the most common scenario.
|
||||
*/
|
||||
pResourceManagerDataSource: ^resource_manager_data_source,
|
||||
}
|
||||
|
||||
/* Structure specifically for sounds played with ma_engine_play_sound(). Making this a separate structure to reduce overhead. */
|
||||
sound_inlined :: struct {
|
||||
sound: sound,
|
||||
pNext: ^sound_inlined,
|
||||
pPrev: ^sound_inlined,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
sound_config_init :: proc() -> sound_config ---
|
||||
|
||||
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_ex :: proc(pEngine: ^engine, pConfig: ^sound_config, pSound: ^sound) -> result ---
|
||||
sound_uninit :: proc(pSound: ^sound) ---
|
||||
sound_get_engine :: proc(pSound: ^sound) -> ^engine ---
|
||||
sound_get_data_source :: proc(pSound: ^sound) -> ^data_source ---
|
||||
sound_start :: proc(pSound: ^sound) -> result ---
|
||||
sound_stop :: proc(pSound: ^sound) -> result ---
|
||||
sound_set_volume :: proc(pSound: ^sound, volume: f32) ---
|
||||
sound_get_volume :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_pan :: proc(pSound: ^sound, pan: f32) ---
|
||||
sound_get_pan :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_pan_mode :: proc(pSound: ^sound, panMode: pan_mode) ---
|
||||
sound_get_pan_mode :: proc(pSound: ^sound) -> pan_mode ---
|
||||
sound_set_pitch :: proc(pSound: ^sound, pitch: f32) ---
|
||||
sound_get_pitch :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_spatialization_enabled :: proc(pSound: ^sound, enabled: b32) ---
|
||||
sound_is_spatialization_enabled :: proc(pSound: ^sound) -> b32 ---
|
||||
sound_set_pinned_listener_index :: proc(pSound: ^sound, listenerIndex: u32) ---
|
||||
sound_get_pinned_listener_index :: proc(pSound: ^sound) -> u32 ---
|
||||
sound_get_listener_index :: proc(pSound: ^sound) -> u32 ---
|
||||
sound_get_direction_to_listener :: proc(pSound: ^sound) -> vec3f ---
|
||||
sound_set_position :: proc(pSound: ^sound, x, y, z: f32) ---
|
||||
sound_get_position :: proc(pSound: ^sound) -> vec3f ---
|
||||
sound_set_direction :: proc(pSound: ^sound, x, y, z: f32) ---
|
||||
sound_get_direction :: proc(pSound: ^sound) -> vec3f ---
|
||||
sound_set_velocity :: proc(pSound: ^sound, x, y, z: f32) ---
|
||||
sound_get_velocity :: proc(pSound: ^sound) -> vec3f ---
|
||||
sound_set_attenuation_model :: proc(pSound: ^sound, attenuationModel: attenuation_model) ---
|
||||
sound_get_attenuation_model :: proc(pSound: ^sound) -> attenuation_model ---
|
||||
sound_set_positioning :: proc(pSound: ^sound, positioning: positioning) ---
|
||||
sound_get_positioning :: proc(pSound: ^sound) -> positioning ---
|
||||
sound_set_rolloff :: proc(pSound: ^sound, rolloff: f32) ---
|
||||
sound_get_rolloff :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_min_gain :: proc(pSound: ^sound, minGain: f32) ---
|
||||
sound_get_min_gain :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_max_gain :: proc(pSound: ^sound, maxGain: f32) ---
|
||||
sound_get_max_gain :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_min_distance :: proc(pSound: ^sound, minDistance: f32) ---
|
||||
sound_get_min_distance :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_max_distance :: proc(pSound: ^sound, maxDistance: f32) ---
|
||||
sound_get_max_distance :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_cone :: proc(pSound: ^sound, innerAngleInRadians, outerAngleInRadians, outerGain: f32) ---
|
||||
sound_get_cone :: proc(pSound: ^sound, pInnerAngleInRadians, pOuterAngleInRadians, pOuterGain: ^f32) ---
|
||||
sound_set_doppler_factor :: proc(pSound: ^sound, dopplerFactor: f32) ---
|
||||
sound_get_doppler_factor :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_directional_attenuation_factor :: proc(pSound: ^sound, directionalAttenuationFactor: f32) ---
|
||||
sound_get_directional_attenuation_factor :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_fade_in_pcm_frames :: proc(pSound: ^sound, volumeBeg, volumeEnd: f32, fadeLengthInFrames: u64) ---
|
||||
sound_set_fade_in_milliseconds :: proc(pSound: ^sound, volumeBeg, volumeEnd: f32, fadeLengthInMilliseconds: u64) ---
|
||||
sound_get_current_fade_volume :: proc(pSound: ^sound) -> f32 ---
|
||||
sound_set_start_time_in_pcm_frames :: proc(pSound: ^sound, absoluteGlobalTimeInFrames: u64) ---
|
||||
sound_set_start_time_in_milliseconds :: proc(pSound: ^sound, absoluteGlobalTimeInMilliseconds: u64) ---
|
||||
sound_set_stop_time_in_pcm_frames :: proc(pSound: ^sound, absoluteGlobalTimeInFrames: u64) ---
|
||||
sound_set_stop_time_in_milliseconds :: proc(pSound: ^sound, absoluteGlobalTimeInMilliseconds: u64) ---
|
||||
sound_is_playing :: proc(pSound: ^sound) -> b32 ---
|
||||
sound_get_time_in_pcm_frames :: proc(pSound: ^sound) -> u64 ---
|
||||
sound_set_looping :: proc(pSound: ^sound, isLooping: b32) ---
|
||||
sound_is_looping :: 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_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_length_in_pcm_frames :: proc(pSound: ^sound, pLength: ^u64) -> result ---
|
||||
sound_get_cursor_in_seconds :: proc(pSound: ^sound, pCursor: ^f32) -> result ---
|
||||
sound_get_length_in_seconds :: proc(pSound: ^sound, pLength: ^f32) -> result ---
|
||||
}
|
||||
|
||||
|
||||
/* A sound group is just a sound. */
|
||||
sound_group_config :: distinct sound_config
|
||||
sound_group :: distinct sound
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
sound_group_config_init :: proc() -> sound_group_config ---
|
||||
|
||||
sound_group_init :: proc(pEngine: ^engine, flags: u32, 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 ---
|
||||
sound_group_start :: proc(pGroup: ^sound_group) -> result ---
|
||||
sound_group_stop :: proc(pGroup: ^sound_group) -> result ---
|
||||
sound_group_set_volume :: proc(pGroup: ^sound_group, volume: f32) ---
|
||||
sound_group_get_volume :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_pan :: proc(pGroup: ^sound_group, pan: f32) ---
|
||||
sound_group_get_pan :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_pan_mode :: proc(pGroup: ^sound_group, panMode: pan_mode) ---
|
||||
sound_group_get_pan_mode :: proc(pGroup: ^sound_group) -> pan_mode ---
|
||||
sound_group_set_pitch :: proc(pGroup: ^sound_group, pitch: f32) ---
|
||||
sound_group_get_pitch :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_spatialization_enabled :: proc(pGroup: ^sound_group, enabled: b32) ---
|
||||
sound_group_is_spatialization_enabled :: proc(pGroup: ^sound_group) -> b32 ---
|
||||
sound_group_set_pinned_listener_index :: proc(pGroup: ^sound_group, listenerIndex: u32) ---
|
||||
sound_group_get_pinned_listener_index :: proc(pGroup: ^sound_group) -> u32 ---
|
||||
sound_group_get_listener_index :: proc(pGroup: ^sound_group) -> u32 ---
|
||||
sound_group_get_direction_to_listener :: proc(pGroup: ^sound_group) -> vec3f ---
|
||||
sound_group_set_position :: proc(pGroup: ^sound_group, x, y, z: f32) ---
|
||||
sound_group_get_position :: proc(pGroup: ^sound_group) -> vec3f ---
|
||||
sound_group_set_direction :: proc(pGroup: ^sound_group, x, y, z: f32) ---
|
||||
sound_group_get_direction :: proc(pGroup: ^sound_group) -> vec3f ---
|
||||
sound_group_set_velocity :: proc(pGroup: ^sound_group, x, y, z: f32) ---
|
||||
sound_group_get_velocity :: proc(pGroup: ^sound_group) -> vec3f ---
|
||||
sound_group_set_attenuation_model :: proc(pGroup: ^sound_group, attenuationModel: attenuation_model) ---
|
||||
sound_group_get_attenuation_model :: proc(pGroup: ^sound_group) -> attenuation_model ---
|
||||
sound_group_set_positioning :: proc(pGroup: ^sound_group, positioning: positioning) ---
|
||||
sound_group_get_positioning :: proc(pGroup: ^sound_group) -> positioning ---
|
||||
sound_group_set_rolloff :: proc(pGroup: ^sound_group, rolloff: f32) ---
|
||||
sound_group_get_rolloff :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_min_gain :: proc(pGroup: ^sound_group, minGain: f32) ---
|
||||
sound_group_get_min_gain :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_max_gain :: proc(pGroup: ^sound_group, maxGain: f32) ---
|
||||
sound_group_get_max_gain :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_min_distance :: proc(pGroup: ^sound_group, minDistance: f32) ---
|
||||
sound_group_get_min_distance :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_max_distance :: proc(pGroup: ^sound_group, maxDistance: f32) ---
|
||||
sound_group_get_max_distance :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_cone :: proc(pGroup: ^sound_group, innerAngleInRadians, outerAngleInRadians, outerGain: f32) ---
|
||||
sound_group_get_cone :: proc(pGroup: ^sound_group, pInnerAngleInRadians, pOuterAngleInRadians, pOuterGain: ^f32) ---
|
||||
sound_group_set_doppler_factor :: proc(pGroup: ^sound_group, dopplerFactor: f32) ---
|
||||
sound_group_get_doppler_factor :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_directional_attenuation_factor :: proc(pGroup: ^sound_group, directionalAttenuationFactor: f32) ---
|
||||
sound_group_get_directional_attenuation_factor :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_fade_in_pcm_frames :: proc(pGroup: ^sound_group, volumeBeg, volumeEnd: f32, fadeLengthInFrames: u64) ---
|
||||
sound_group_set_fade_in_milliseconds :: proc(pGroup: ^sound_group, volumeBeg, volumeEnd: f32, fadeLengthInMilliseconds: u64) ---
|
||||
sound_group_get_current_fade_volume :: proc(pGroup: ^sound_group) -> f32 ---
|
||||
sound_group_set_start_time_in_pcm_frames :: proc(pGroup: ^sound_group, absoluteGlobalTimeInFrames: u64) ---
|
||||
sound_group_set_start_time_in_milliseconds :: proc(pGroup: ^sound_group, absoluteGlobalTimeInMilliseconds: u64) ---
|
||||
sound_group_set_stop_time_in_pcm_frames :: proc(pGroup: ^sound_group, absoluteGlobalTimeInFrames: u64) ---
|
||||
sound_group_set_stop_time_in_milliseconds :: proc(pGroup: ^sound_group, absoluteGlobalTimeInMilliseconds: u64) ---
|
||||
sound_group_is_playing :: proc(pGroup: ^sound_group) -> b32 ---
|
||||
sound_group_get_time_in_pcm_frames :: proc(pGroup: ^sound_group) -> u64 ---
|
||||
}
|
||||
|
||||
|
||||
engine_config :: struct {
|
||||
pResourceManager: ^resource_manager, /* Can be null in which case a resource manager will be created for you. */
|
||||
pContext: ^context_type,
|
||||
pDevice: ^device, /* If set, the caller is responsible for calling ma_engine_data_callback() in the device's data callback. */
|
||||
pPlaybackDeviceID: ^device_id, /* The ID of the playback device to use with the default listener. */
|
||||
pLog: ^log, /* When set to NULL, will use the context's log. */
|
||||
listenerCount: u32, /* Must be between 1 and MA_ENGINE_MAX_LISTENERS. */
|
||||
channels: u32, /* The number of channels to use when mixing and spatializing. When set to 0, will use the native channel count of the device. */
|
||||
sampleRate: u32, /* The sample rate. When set to 0 will use the native channel count of the device. */
|
||||
periodSizeInFrames: u32, /* If set to something other than 0, updates will always be exactly this size. The underlying device may be a different size, but from the perspective of the mixer that won't matter.*/
|
||||
periodSizeInMilliseconds: u32, /* Used if periodSizeInFrames is unset. */
|
||||
gainSmoothTimeInFrames: u32, /* The number of frames to interpolate the gain of spatialized sounds across. If set to 0, will use gainSmoothTimeInMilliseconds. */
|
||||
gainSmoothTimeInMilliseconds: u32, /* When set to 0, gainSmoothTimeInFrames will be used. If both are set to 0, a default value will be used. */
|
||||
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(). */
|
||||
noDevice: b32, /* When set to true, don't create a default device. ma_engine_read_pcm_frames() can be called manually to read data. */
|
||||
monoExpansionMode: mono_expansion_mode, /* Controls how the mono channel should be expanded to other channels when spatialization is disabled on a sound. */
|
||||
pResourceManagerVFS: ^vfs, /* A pointer to a pre-allocated VFS object to use with the resource manager. This is ignored if pResourceManager is not NULL. */
|
||||
}
|
||||
|
||||
engine :: struct {
|
||||
nodeGraph: node_graph, /* 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. */
|
||||
pResourceManager: ^resource_manager,
|
||||
pDevice: ^device, /* Optionally set via the config, otherwise allocated by the engine in ma_engine_init(). */
|
||||
pLog: ^log,
|
||||
sampleRate: u32,
|
||||
listenerCount: u32,
|
||||
listeners: [ENGINE_MAX_LISTENERS]spatializer_listener,
|
||||
allocationCallbacks: allocation_callbacks,
|
||||
ownsResourceManager: b8,
|
||||
ownsDevice: b8,
|
||||
inlinedSoundLock: spinlock, /* For synchronizing access so the inlined sound 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. */
|
||||
gainSmoothTimeInFrames: u32, /* The number of frames to interpolate the gain of spatialized sounds across. */
|
||||
monoExpansionMode: mono_expansion_mode,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
engine_config_init :: proc() -> engine_config ---
|
||||
|
||||
engine_init :: proc(pConfig: ^engine_config, pEngine: ^engine) -> result ---
|
||||
engine_uninit :: proc(pEngine: ^engine) ---
|
||||
engine_read_pcm_frames :: proc(pEngine: ^engine, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
|
||||
engine_get_node_graph :: proc(pEngine: ^engine) -> ^node_graph ---
|
||||
engine_get_resource_manager :: proc(pEngine: ^engine) -> ^resource_manager ---
|
||||
engine_get_device :: proc(pEngine: ^engine) -> ^device ---
|
||||
engine_get_log :: proc(pEngine: ^engine) -> ^log ---
|
||||
engine_get_endpoint :: proc(pEngine: ^engine) -> ^node ---
|
||||
engine_get_time :: proc(pEngine: ^engine) -> u64 ---
|
||||
engine_set_time :: proc(pEngine: ^engine, globalTime: u64) -> result ---
|
||||
engine_get_channels :: proc(pEngine: ^engine) -> u32 ---
|
||||
engine_get_sample_rate :: proc(pEngine: ^engine) -> u32 ---
|
||||
|
||||
engine_start :: proc(pEngine: ^engine) -> result ---
|
||||
engine_stop :: proc(pEngine: ^engine) -> result ---
|
||||
engine_set_volume :: proc(pEngine: ^engine, volume: f32) -> result ---
|
||||
engine_set_gain_db :: proc(pEngine: ^engine, gainDB: f32) -> result ---
|
||||
|
||||
engine_get_listener_count :: proc(pEngine: ^engine) -> u32 ---
|
||||
engine_find_closest_listener :: proc(pEngine: ^engine, absolutePosX, absolutePosY, absolutePosZ: f32) -> u32 ---
|
||||
engine_listener_set_position :: proc(pEngine: ^engine, listenerIndex: u32, x, y, z: f32) ---
|
||||
engine_listener_get_position :: proc(pEngine: ^engine, listenerIndex: u32) -> vec3f ---
|
||||
engine_listener_set_direction :: proc(pEngine: ^engine, listenerIndex: u32, x, y, z: f32) ---
|
||||
engine_listener_get_direction :: proc(pEngine: ^engine, listenerIndex: u32) -> vec3f ---
|
||||
engine_listener_set_velocity :: proc(pEngine: ^engine, listenerIndex: u32, x, y, z: f32) ---
|
||||
engine_listener_get_velocity :: proc(pEngine: ^engine, listenerIndex: u32) -> vec3f ---
|
||||
engine_listener_set_cone :: proc(pEngine: ^engine, listenerIndex: u32, innerAngleInRadians, outerAngleInRadians, outerGain: f32) ---
|
||||
engine_listener_get_cone :: proc(pEngine: ^engine, listenerIndex: u32, pInnerAngleInRadians, pOuterAngleInRadians, pOuterGain: ^f32) ---
|
||||
engine_listener_set_world_up :: proc(pEngine: ^engine, listenerIndex: u32, x, y, z: f32) ---
|
||||
engine_listener_get_world_up :: proc(pEngine: ^engine, listenerIndex: u32) -> vec3f ---
|
||||
engine_listener_set_enabled :: proc(pEngine: ^engine, listenerIndex: u32, isEnabled: b32) ---
|
||||
engine_listener_is_enabled :: proc(pEngine: ^engine, listenerIndex: u32) -> b32 ---
|
||||
|
||||
engine_play_sound_ex :: proc(pEngine: ^engine, pFilePath: cstring, pNode: ^node, nodeInputBusIndex: u32) -> result ---
|
||||
engine_play_sound :: proc(pEngine: ^engine, pFilePath: cstring, pGroup: ^sound_group) -> result --- /* Fire and forget. */
|
||||
}
|
||||
129
vendor/miniaudio/filtering.odin
vendored
129
vendor/miniaudio/filtering.odin
vendored
@@ -1,5 +1,7 @@
|
||||
package miniaudio
|
||||
|
||||
import c "core:c/libc"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import lib "lib/miniaudio.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
@@ -19,14 +21,14 @@ biquad_coefficient :: struct #raw_union {
|
||||
}
|
||||
|
||||
biquad_config :: struct {
|
||||
format: format,
|
||||
format: format,
|
||||
channels: u32,
|
||||
b0: f64,
|
||||
b1: f64,
|
||||
b2: f64,
|
||||
a0: f64,
|
||||
a1: f64,
|
||||
a2: f64,
|
||||
b0: f64,
|
||||
b1: f64,
|
||||
b2: f64,
|
||||
a0: f64,
|
||||
a1: f64,
|
||||
a2: f64,
|
||||
}
|
||||
|
||||
biquad :: struct {
|
||||
@@ -37,17 +39,25 @@ biquad :: struct {
|
||||
b2: biquad_coefficient,
|
||||
a1: biquad_coefficient,
|
||||
a2: biquad_coefficient,
|
||||
r1: [MAX_CHANNELS]biquad_coefficient,
|
||||
r2: [MAX_CHANNELS]biquad_coefficient,
|
||||
pR1: ^biquad_coefficient,
|
||||
pR2: ^biquad_coefficient,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
biquad_config_init :: proc(format: format, channels: u32, b0, b1, b2, a0, a1, a2: f64) -> biquad_config ---
|
||||
|
||||
biquad_init :: proc(pConfig: ^biquad_config, pBQ: ^biquad) -> result ---
|
||||
biquad_get_heap_size :: proc(pConfig: ^biquad_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
biquad_init_preallocated :: proc(pConfig: ^biquad_config, pHeap: rawptr, pBQ: ^biquad) -> result ---
|
||||
biquad_init :: proc(pConfig: ^biquad_config, pAllocationCallbacks: ^allocation_callbacks, pBQ: ^biquad) -> result ---
|
||||
biquad_uninit :: proc(pBQ: ^biquad, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
biquad_reinit :: proc(pConfig: ^biquad_config, pBQ: ^biquad) -> result ---
|
||||
biquad_process_pcm_frames :: proc(pBQ: ^biquad, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
biquad_clear_cache :: proc(pBQ: ^biquad) -> result ---
|
||||
biquad_process_pcm_frames :: proc(pBQ: ^biquad, pFramesOut, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
biquad_get_latency :: proc(pBQ: ^biquad) -> u32 ---
|
||||
}
|
||||
|
||||
@@ -70,7 +80,11 @@ lpf1 :: struct {
|
||||
format: format,
|
||||
channels: u32,
|
||||
a: biquad_coefficient,
|
||||
r1: [MAX_CHANNELS]biquad_coefficient,
|
||||
pR1: ^biquad_coefficient,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
lpf2 :: struct {
|
||||
@@ -91,8 +105,12 @@ lpf :: struct {
|
||||
sampleRate: u32,
|
||||
lpf1Count: u32,
|
||||
lpf2Count: u32,
|
||||
lpf1: [1]lpf1,
|
||||
lpf2: [MAX_FILTER_ORDER/2]lpf2,
|
||||
pLPF1: ^lpf1,
|
||||
pLPF2: ^lpf2,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
|
||||
@@ -101,20 +119,32 @@ foreign lib {
|
||||
lpf1_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64) -> lpf1_config ---
|
||||
lpf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency, q: f64) -> lpf2_config ---
|
||||
|
||||
lpf1_init :: proc(pConfig: ^lpf1_config, pLPF: ^lpf1) -> result ---
|
||||
lpf1_get_heap_size :: proc(pConfig: ^lpf1_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
lpf1_init_preallocated :: proc(pConfig: ^lpf1_config, pHeap: rawptr, pLPF: ^lpf1) -> result ---
|
||||
lpf1_init :: proc(pConfig: ^lpf1_config, pAllocationCallbacks: ^allocation_callbacks, pLPF: ^lpf1) -> result ---
|
||||
lpf1_uninit :: proc(pLPF: ^lpf1, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
lpf1_reinit :: proc(pConfig: ^lpf1_config, pLPF: ^lpf1) -> result ---
|
||||
lpf1_clear_cache :: proc(pLPF: ^lpf1) -> result ---
|
||||
lpf1_process_pcm_frames :: proc(pLPF: ^lpf1, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
lpf1_get_latency :: proc(pLPF: ^lpf1) -> u32 ---
|
||||
|
||||
lpf2_init :: proc(pConfig: ^lpf2_config, pLPF: ^lpf2) -> result ---
|
||||
lpf2_get_heap_size :: proc(pConfig: ^lpf2_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
lpf2_init_preallocated :: proc(pConfig: ^lpf2_config, pHeap: rawptr, pHPF: ^lpf2) -> result ---
|
||||
lpf2_init :: proc(pConfig: ^lpf2_config, pAllocationCallbacks: ^allocation_callbacks, pLPF: ^lpf2) -> result ---
|
||||
lpf2_uninit :: proc(pLPF: ^lpf2, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
lpf2_reinit :: proc(pConfig: ^lpf2_config, pLPF: ^lpf2) -> result ---
|
||||
lpf2_clear_cache :: proc(pLPF: ^lpf2) -> result ---
|
||||
lpf2_process_pcm_frames :: proc(pLPF: ^lpf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
lpf2_get_latency :: proc(pLPF: ^lpf2) -> u32 ---
|
||||
|
||||
lpf_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64, order: u32) -> lpf_config ---
|
||||
|
||||
lpf_init :: proc(pConfig: ^lpf_config, pLPF: ^lpf) -> result ---
|
||||
lpf_get_heap_size :: proc(pConfig: ^lpf_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
lpf_init_preallocated :: proc(pConfig: ^lpf_config, pHeap: rawptr, pLPF: ^lpf) -> result ---
|
||||
lpf_init :: proc(pConfig: ^lpf_config, pAllocationCallbacks: ^allocation_callbacks, pLPF: ^lpf) -> result ---
|
||||
lpf_uninit :: proc(pLPF: ^lpf, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
lpf_reinit :: proc(pConfig: ^lpf_config, pLPF: ^lpf) -> result ---
|
||||
lpf_clear_cache :: proc(pLPF: ^lpf) -> result ---
|
||||
lpf_process_pcm_frames :: proc(pLPF: ^lpf, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
lpf_get_latency :: proc(pLPF: ^lpf) -> u32 ---
|
||||
}
|
||||
@@ -138,7 +168,11 @@ hpf1 :: struct {
|
||||
format: format,
|
||||
channels: u32,
|
||||
a: biquad_coefficient,
|
||||
r1: [MAX_CHANNELS]biquad_coefficient,
|
||||
pR1: ^biquad_coefficient,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
hpf2 :: struct {
|
||||
@@ -159,8 +193,12 @@ hpf :: struct {
|
||||
sampleRate: u32,
|
||||
hpf1Count: u32,
|
||||
hpf2Count: u32,
|
||||
hpf1: [1]hpf1,
|
||||
hpf2: [MAX_FILTER_ORDER/2]hpf2,
|
||||
pHPF1: ^hpf1,
|
||||
pHPF2: ^hpf2,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
|
||||
@@ -169,19 +207,28 @@ foreign lib {
|
||||
hpf1_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64) -> hpf1_config ---
|
||||
hpf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency, q: f64) -> hpf2_config ---
|
||||
|
||||
hpf1_init :: proc(pConfig: ^hpf1_config, pHPF: ^hpf1) -> result ---
|
||||
hpf1_get_heap_size :: proc(pConfig: ^hpf1_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
hpf1_init_preallocated :: proc(pConfig: ^hpf1_config, pHeap: rawptr, pLPF: ^hpf1) -> result ---
|
||||
hpf1_init :: proc(pConfig: ^hpf1_config, pAllocationCallbacks: ^allocation_callbacks, pHPF: ^hpf1) -> result ---
|
||||
hpf1_uninit :: proc(pHPF: ^hpf1, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
hpf1_reinit :: proc(pConfig: ^hpf1_config, pHPF: ^hpf1) -> result ---
|
||||
hpf1_process_pcm_frames :: proc(pHPF: ^hpf1, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
hpf1_get_latency :: proc(pHPF: ^hpf1) -> u32 ---
|
||||
|
||||
hpf2_init :: proc(pConfig: ^hpf2_config, pHPF: ^hpf2) -> result ---
|
||||
hpf2_get_heap_size :: proc(pConfig: ^hpf2_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
hpf2_init_preallocated :: proc(pConfig: ^hpf2_config, pHeap: rawptr, pHPF: ^hpf2) -> result ---
|
||||
hpf2_init :: proc(pConfig: ^hpf2_config, pAllocationCallbacks: ^allocation_callbacks, pHPF: ^hpf2) -> result ---
|
||||
hpf2_uninit :: proc(pHPF: ^hpf2, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
hpf2_reinit :: proc(pConfig: ^hpf2_config, pHPF: ^hpf2) -> result ---
|
||||
hpf2_process_pcm_frames :: proc(pHPF: ^hpf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
hpf2_get_latency :: proc(pHPF: ^hpf2) -> u32 ---
|
||||
|
||||
hpf_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64, order: u32) -> hpf_config ---
|
||||
|
||||
hpf_init :: proc(pConfig: ^hpf_config, pHPF: ^hpf) -> result ---
|
||||
hpf_get_heap_size :: proc(pConfig: ^hpf_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
hpf_init_preallocated :: proc(pConfig: ^hpf_config, pHeap: rawptr, pLPF: ^hpf) -> result ---
|
||||
hpf_init :: proc(pConfig: ^hpf_config, pAllocationCallbacks: ^allocation_callbacks, pHPF: ^hpf) -> result ---
|
||||
hpf_uninit :: proc(pHPF: ^hpf, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
hpf_reinit :: proc(pConfig: ^hpf_config, pHPF: ^hpf) -> result ---
|
||||
hpf_process_pcm_frames :: proc(pHPF: ^hpf, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
hpf_get_latency :: proc(pHPF: ^hpf) -> u32 ---
|
||||
@@ -217,21 +264,31 @@ bpf :: struct {
|
||||
format: format,
|
||||
channels: u32,
|
||||
bpf2Count: u32,
|
||||
bpf2: [MAX_FILTER_ORDER/2]bpf2,
|
||||
pBPF2: ^bpf2,
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
bpf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64, q: f64) -> bpf2_config ---
|
||||
|
||||
bpf2_init :: proc(pConfig: ^bpf2_config, pBPF: ^bpf2) -> result ---
|
||||
bpf2_get_heap_size :: proc(pConfig: ^bpf2_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
bpf2_init_preallocated :: proc(pConfig: ^bpf2_config, pHeap: rawptr, pBPF: ^bpf2) -> result ---
|
||||
bpf2_init :: proc(pConfig: ^bpf2_config, pAllocationCallbacks: ^allocation_callbacks, pBPF: ^bpf2) -> result ---
|
||||
bpf2_uninit :: proc(pBPF: ^bpf2, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
bpf2_reinit :: proc(pConfig: ^bpf2_config, pBPF: ^bpf2) -> result ---
|
||||
bpf2_process_pcm_frames :: proc(pBPF: ^bpf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
bpf2_get_latency :: proc(pBPF: ^bpf2) -> u32 ---
|
||||
|
||||
bpf_config_init :: proc(format: format, channels: u32, sampleRate: u32, cutoffFrequency: f64, order: u32) -> bpf_config ---
|
||||
|
||||
bpf_init :: proc(pConfig: ^bpf_config, pBPF: ^bpf) -> result ---
|
||||
bpf_get_heap_size :: proc(pConfig: ^bpf_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
bpf_init_preallocated :: proc(pConfig: ^bpf_config, pHeap: rawptr, pBPF: ^bpf) -> result ---
|
||||
bpf_init :: proc(pConfig: ^bpf_config, pAllocationCallbacks: ^allocation_callbacks, pBPF: ^bpf) -> result ---
|
||||
bpf_uninit :: proc(pBPF: ^bpf, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
bpf_reinit :: proc(pConfig: ^bpf_config, pBPF: ^bpf) -> result ---
|
||||
bpf_process_pcm_frames :: proc(pBPF: ^bpf, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
bpf_get_latency :: proc(pBPF: ^bpf) -> u32 ---
|
||||
@@ -260,7 +317,10 @@ notch2 :: struct {
|
||||
foreign lib {
|
||||
notch2_config_init :: proc(format: format, channels: u32, sampleRate: u32, q: f64, frequency: f64) -> notch2_config ---
|
||||
|
||||
notch2_init :: proc(pConfig: ^notch2_config, pFilter: ^notch2) -> result ---
|
||||
notch2_get_heap_size :: proc(pConfig: ^notch2_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
notch2_init_preallocated :: proc(pConfig: ^notch2_config, pHeap: rawptr, pFilter: ^notch2) -> result ---
|
||||
notch2_init :: proc(pConfig: ^notch2_config, pAllocationCallbacks: ^allocation_callbacks, pFilter: ^notch2) -> result ---
|
||||
notch2_uninit :: proc(pFilter: ^notch2, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
notch2_reinit :: proc(pConfig: ^notch2_config, pFilter: ^notch2) -> result ---
|
||||
notch2_process_pcm_frames :: proc(pFilter: ^notch2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
notch2_get_latency :: proc(pFilter: ^notch2) -> u32 ---
|
||||
@@ -290,7 +350,10 @@ peak2 :: struct {
|
||||
foreign lib {
|
||||
peak2_config_init :: proc(format: format, channels: u32, sampleRate: u32, gainDB, q, frequency: f64) -> peak2_config ---
|
||||
|
||||
peak2_init :: proc(pConfig: ^peak2_config, pFilter: ^peak2) -> result ---
|
||||
peak2_get_heap_size :: proc(pConfig: ^peak2_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
peak2_init_preallocated :: proc(pConfig: ^peak2_config, pHeap: rawptr, pFilter: ^peak2) -> result ---
|
||||
peak2_init :: proc(pConfig: ^peak2_config, pAllocationCallbacks: ^allocation_callbacks, pFilter: ^peak2) -> result ---
|
||||
peak2_uninit :: proc(pFilter: ^peak2, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
peak2_reinit :: proc(pConfig: ^peak2_config, pFilter: ^peak2) -> result ---
|
||||
peak2_process_pcm_frames :: proc(pFilter: ^peak2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
peak2_get_latency :: proc(pFilter: ^peak2) -> u32 ---
|
||||
@@ -320,7 +383,10 @@ loshelf2 :: struct {
|
||||
foreign lib {
|
||||
loshelf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, gainDB, shelfSlope, frequency: f64) -> loshelf2_config ---
|
||||
|
||||
loshelf2_init :: proc(pConfig: ^loshelf2_config, pFilter: ^loshelf2) -> result ---
|
||||
loshelf2_get_heap_size :: proc(pConfig: ^loshelf2_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
loshelf2_init_preallocated :: proc(pConfig: ^loshelf2_config, pHeap: rawptr, pFilter: ^loshelf2) -> result ---
|
||||
loshelf2_init :: proc(pConfig: ^loshelf2_config, pAllocationCallbacks: ^allocation_callbacks, pFilter: ^loshelf2) -> result ---
|
||||
loshelf2_uninit :: proc(pFilter: ^loshelf2, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
loshelf2_reinit :: proc(pConfig: ^loshelf2_config, pFilter: ^loshelf2) -> result ---
|
||||
loshelf2_process_pcm_frames :: proc(pFilter: ^loshelf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
loshelf2_get_latency :: proc(pFilter: ^loshelf2) -> u32 ---
|
||||
@@ -350,7 +416,10 @@ hishelf2 :: struct {
|
||||
foreign lib {
|
||||
hishelf2_config_init :: proc(format: format, channels: u32, sampleRate: u32, gainDB, shelfSlope, frequency: f64) -> hishelf2_config ---
|
||||
|
||||
hishelf2_init :: proc(pConfig: ^hishelf2_config, pFilter: ^hishelf2) -> result ---
|
||||
hishelf2_get_heap_size :: proc(pConfig: ^hishelf2_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
hishelf2_init_preallocated :: proc(pConfig: ^hishelf2_config, pHeap: rawptr, pFilter: ^hishelf2) -> result ---
|
||||
hishelf2_init :: proc(pConfig: ^hishelf2_config, pAllocationCallbacks: ^allocation_callbacks, pFilter: ^hishelf2) -> result ---
|
||||
hishelf2_uninit :: proc(pFilter: ^hishelf2, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
hishelf2_reinit :: proc(pConfig: ^hishelf2_config, pFilter: ^hishelf2) -> result ---
|
||||
hishelf2_process_pcm_frames :: proc(pFilter: ^hishelf2, pFramesOut: rawptr, pFramesIn: rawptr, frameCount: u64) -> result ---
|
||||
hishelf2_get_latency :: proc(pFilter: ^hishelf2) -> u32 ---
|
||||
|
||||
28
vendor/miniaudio/generation.odin
vendored
28
vendor/miniaudio/generation.odin
vendored
@@ -56,14 +56,18 @@ noise :: struct {
|
||||
lcg: lcg,
|
||||
state: struct #raw_union {
|
||||
pink: struct {
|
||||
bin: [MAX_CHANNELS][16]f64,
|
||||
accumulation: [MAX_CHANNELS]f64,
|
||||
counter: [MAX_CHANNELS]u32,
|
||||
bin: ^[^]f64,
|
||||
accumulation: [^]f64,
|
||||
counter: [^]u32,
|
||||
},
|
||||
brownian: struct {
|
||||
accumulation: [MAX_CHANNELS]f64,
|
||||
accumulation: [^]f64,
|
||||
},
|
||||
},
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
@@ -72,7 +76,7 @@ foreign lib {
|
||||
|
||||
waveform_init :: proc(pConfig: ^waveform_config, pWaveform: ^waveform) -> result ---
|
||||
waveform_uninit :: proc(pWaveform: ^waveform) ---
|
||||
waveform_read_pcm_frames :: proc(pWaveform: ^waveform, pFramesOut: rawptr, frameCount: u64) -> u64 ---
|
||||
waveform_read_pcm_frames :: proc(pWaveform: ^waveform, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
|
||||
waveform_seek_to_pcm_frame :: proc(pWaveform: ^waveform, frameIndex: u64) -> result ---
|
||||
waveform_set_amplitude :: proc(pWaveform: ^waveform, amplitude: f64) -> result ---
|
||||
waveform_set_frequency :: proc(pWaveform: ^waveform, frequency: f64) -> result ---
|
||||
@@ -81,10 +85,12 @@ foreign lib {
|
||||
|
||||
noise_config_init :: proc(format: format, channels: u32, type: noise_type, seed: i32, amplitude: f64) -> noise_config ---
|
||||
|
||||
noise_init :: proc(pConfig: ^noise_config, pNoise: ^noise) -> result ---
|
||||
noise_uninit :: proc(pNoise: ^noise) ---
|
||||
noise_read_pcm_frames :: proc(pNoise: ^noise, pFramesOut: rawptr, frameCount: u64) -> u64 ---
|
||||
noise_set_amplitude :: proc(pNoise: ^noise, amplitude: f64) -> result ---
|
||||
noise_set_seed :: proc(pNoise: ^noise, seed: i32) -> result ---
|
||||
noise_set_type :: proc(pNoise: ^noise, type: noise_type) -> result ---
|
||||
noise_get_heap_size :: proc(pConfig: ^noise_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
noise_init_preallocated :: proc(pConfig: ^noise_config, pHeap: rawptr, pNoise: ^noise) -> result ---
|
||||
noise_init :: proc(pConfig: ^noise_config, pAllocationCallbacks: ^allocation_callbacks, pNoise: ^noise) -> result ---
|
||||
noise_uninit :: proc(pNoise: ^noise, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
noise_read_pcm_frames :: proc(pNoise: ^noise, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
|
||||
noise_set_amplitude :: proc(pNoise: ^noise, amplitude: f64) -> result ---
|
||||
noise_set_seed :: proc(pNoise: ^noise, seed: i32) -> result ---
|
||||
noise_set_type :: proc(pNoise: ^noise, type: noise_type) -> result ---
|
||||
}
|
||||
|
||||
239
vendor/miniaudio/job_queue.odin
vendored
Normal file
239
vendor/miniaudio/job_queue.odin
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
package miniaudio
|
||||
|
||||
import c "core:c/libc"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import lib "lib/miniaudio.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "lib/miniaudio.a"
|
||||
} else {
|
||||
foreign import lib "system:miniaudio"
|
||||
}
|
||||
|
||||
/*
|
||||
Slot Allocator
|
||||
--------------
|
||||
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
|
||||
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.
|
||||
|
||||
The slot index is stored in the low 32 bits. The reference counter is stored in the high 32 bits:
|
||||
|
||||
+-----------------+-----------------+
|
||||
| 32 Bits | 32 Bits |
|
||||
+-----------------+-----------------+
|
||||
| Reference Count | Slot Index |
|
||||
+-----------------+-----------------+
|
||||
*/
|
||||
slot_allocator_config :: struct {
|
||||
capacity: u32, /* The number of slots to make available. */
|
||||
}
|
||||
|
||||
slot_allocator_group :: struct {
|
||||
bitfield: u32, /*atomic*/ /* Must be used atomically because the allocation and freeing routines need to make copies of this which must never be optimized away by the compiler. */
|
||||
}
|
||||
|
||||
slot_allocator :: struct {
|
||||
pGroups: [^]slot_allocator_group, /* Slots are grouped in chunks of 32. */
|
||||
pSlots: [^]u32, /* 32 bits for reference counting for ABA mitigation. */
|
||||
count: u32, /* Allocation count. */
|
||||
capacity: u32,
|
||||
|
||||
/* Memory management. */
|
||||
_ownsHeap: b32,
|
||||
_pHeap: rawptr,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
slot_allocator_config_init :: proc(capacity: u32) -> slot_allocator_config ---
|
||||
|
||||
slot_allocator_get_heap_size :: proc(pConfig: ^slot_allocator_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
slot_allocator_init_preallocated :: proc(pConfig: ^slot_allocator_config, pHeap: rawptr, pAllocator: ^slot_allocator) -> result ---
|
||||
slot_allocator_init :: proc(pConfig: ^slot_allocator_config, pAllocationCallbacks: ^allocation_callbacks, pAllocator: ^slot_allocator) -> result ---
|
||||
slot_allocator_uninit :: proc(pAllocator: ^slot_allocator, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
slot_allocator_alloc :: proc(pAllocator: ^slot_allocator, pSlot: ^u64) -> result ---
|
||||
slot_allocator_free :: proc(pAllocator: ^slot_allocator, slot: u64) -> result ---
|
||||
}
|
||||
|
||||
/*
|
||||
Callback for processing a job. Each job type will have their own processing callback which will be
|
||||
called by ma_job_process().
|
||||
*/
|
||||
job_proc :: proc "c" (pJob: ^job)
|
||||
|
||||
/* When a job type is added here an callback needs to be added go "g_jobVTable" in the implementation section. */
|
||||
job_type :: enum c.int {
|
||||
/* Miscellaneous. */
|
||||
QUIT = 0,
|
||||
CUSTOM,
|
||||
|
||||
/* Resource Manager. */
|
||||
RESOURCE_MANAGER_LOAD_DATA_BUFFER_NODE,
|
||||
RESOURCE_MANAGER_FREE_DATA_BUFFER_NODE,
|
||||
RESOURCE_MANAGER_PAGE_DATA_BUFFER_NODE,
|
||||
RESOURCE_MANAGER_LOAD_DATA_BUFFER,
|
||||
RESOURCE_MANAGER_FREE_DATA_BUFFER,
|
||||
RESOURCE_MANAGER_LOAD_DATA_STREAM,
|
||||
RESOURCE_MANAGER_FREE_DATA_STREAM,
|
||||
RESOURCE_MANAGER_PAGE_DATA_STREAM,
|
||||
RESOURCE_MANAGER_SEEK_DATA_STREAM,
|
||||
|
||||
/* Device. */
|
||||
DEVICE_AAUDIO_REROUTE,
|
||||
|
||||
/* Count. Must always be last. */
|
||||
COUNT,
|
||||
}
|
||||
|
||||
job :: struct {
|
||||
toc: struct #raw_union { /* 8 bytes. We encode the job code into the slot allocation data to save space. */
|
||||
breakup: struct {
|
||||
code: u16, /* Job type. */
|
||||
slot: u16, /* Index into a ma_slot_allocator. */
|
||||
refcount: u32,
|
||||
},
|
||||
allocation: u64,
|
||||
},
|
||||
next: u64, /*atomic*/ /* refcount + slot for the next item. Does not include the job code. */
|
||||
order: u32, /* Execution order. Used to create a data dependency and ensure a job is executed in order. Usage is contextual depending on the job type. */
|
||||
|
||||
data: struct #raw_union {
|
||||
/* Miscellaneous. */
|
||||
custom: struct {
|
||||
proc_: job_proc,
|
||||
data0: uintptr,
|
||||
data1: uintptr,
|
||||
},
|
||||
|
||||
/* Resource Manager */
|
||||
resourceManager: struct #raw_union {
|
||||
loadDataBufferNode: struct {
|
||||
pResourceManager: rawptr /*ma_resource_manager**/,
|
||||
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. */
|
||||
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. */
|
||||
pDoneFence: ^fence, /* Released if initialization of the decoder fails. Passed through to PAGE_DATA_BUFFER_NODE untouched if init is successful. */
|
||||
},
|
||||
freeDataBufferNode: struct {
|
||||
pResourceManager: rawptr /*ma_resource_manager**/,
|
||||
pDataBufferNode: rawptr /*ma_resource_manager_data_buffer_node**/,
|
||||
pDoneNotification: ^async_notification,
|
||||
pDoneFence: ^fence,
|
||||
},
|
||||
pageDataBufferNode: struct {
|
||||
pResourceManager: rawptr /*ma_resource_manager**/,
|
||||
pDataBufferNode: rawptr /*ma_resource_manager_data_buffer_node**/,
|
||||
pDecoder: rawptr /*ma_decoder**/,
|
||||
pDoneNotification: ^async_notification, /* Signalled when the data buffer has been fully decoded. */
|
||||
pDoneFence: ^fence, /* Passed through from LOAD_DATA_BUFFER_NODE and released when the data buffer completes decoding or an error occurs. */
|
||||
},
|
||||
|
||||
loadDataBuffer: struct {
|
||||
pDataBuffer: rawptr /*ma_resource_manager_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. */
|
||||
pInitFence: ^fence, /* Released when the data buffer has been initialized and the format/channels/rate can be retrieved. */
|
||||
pDoneFence: ^fence, /* Released when the data buffer has been fully decoded. */
|
||||
rangeBegInPCMFrames: u64,
|
||||
rangeEndInPCMFrames: u64,
|
||||
loopPointBegInPCMFrames: u64,
|
||||
loopPointEndInPCMFrames: u64,
|
||||
isLooping: u32,
|
||||
},
|
||||
freeDataBuffer: struct {
|
||||
pDataBuffer: rawptr /*ma_resource_manager_data_buffer**/,
|
||||
pDoneNotification: ^async_notification,
|
||||
pDoneFence: ^fence,
|
||||
},
|
||||
|
||||
loadDataStream: struct {
|
||||
pDataStream: rawptr /*ma_resource_manager_data_stream**/,
|
||||
pFilePath: cstring, /* Allocated when the job is posted, freed by the job thread after loading. */
|
||||
pFilePathW: [^]c.wchar_t, /* ^ As above ^. Only used if pFilePath is NULL. */
|
||||
initialSeekPoint: u64,
|
||||
pInitNotification: ^async_notification, /* Signalled after the first two pages have been decoded and frames can be read from the stream. */
|
||||
pInitFence: ^fence,
|
||||
},
|
||||
freeDataStream: struct {
|
||||
pDataStream: rawptr /*ma_resource_manager_data_stream**/,
|
||||
pDoneNotification: ^async_notification,
|
||||
pDoneFence: ^fence,
|
||||
},
|
||||
pageDataStream: struct {
|
||||
pDataStream: rawptr /*ma_resource_manager_data_stream**/,
|
||||
pageIndex: u32, /* The index of the page to decode into. */
|
||||
},
|
||||
seekDataStream: struct {
|
||||
pDataStream: rawptr /*ma_resource_manager_data_stream**/,
|
||||
frameIndex: u64,
|
||||
},
|
||||
},
|
||||
|
||||
/* Device. */
|
||||
device: struct #raw_union {
|
||||
aaudio: struct #raw_union {
|
||||
reroute: struct {
|
||||
pDevice: rawptr /*ma_device**/,
|
||||
deviceType: u32 /*ma_device_type*/,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
job_init :: proc(code: u16) -> job ---
|
||||
job_process :: proc(pJob: ^job) -> result ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
When set, ma_job_queue_next() will not wait and no semaphore will be signaled in
|
||||
ma_job_queue_post(). ma_job_queue_next() will return MA_NO_DATA_AVAILABLE if nothing is available.
|
||||
|
||||
This flag should always be used for platforms that do not support multithreading.
|
||||
*/
|
||||
job_queue_flags :: enum c.int {
|
||||
NON_BLOCKING = 0x00000001,
|
||||
}
|
||||
|
||||
job_queue_config :: struct {
|
||||
flags: u32,
|
||||
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. */
|
||||
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. */
|
||||
sem: (struct {} when NO_THREADING else semaphore), /* Only used when MA_JOB_QUEUE_FLAG_NON_BLOCKING is unset. */
|
||||
allocator: slot_allocator,
|
||||
pJobs: [^]job,
|
||||
lock: (struct {} when USE_EXPERIMENTAL_LOCK_FREE_JOB_QUEUE else spinlock),
|
||||
|
||||
/* Memory management. */
|
||||
_pHeap: rawptr,
|
||||
_ownsHeap: b32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
job_queue_config_init :: proc(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 ---
|
||||
job_queue_init :: proc(pConfig: ^job_queue_config, pAllocationCallbacks: ^allocation_callbacks, pQueue: ^job_queue) -> result ---
|
||||
job_queue_uninit :: proc(pQueue: ^job_queue, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
job_queue_post :: proc(pQueue: ^job_queue, pJob: ^job) -> result ---
|
||||
job_queue_next :: proc(pQueue: ^job_queue, pJob: ^job) -> result --- /* Returns MA_CANCELLED if the next job is a quit job. */
|
||||
}
|
||||
BIN
vendor/miniaudio/lib/miniaudio.lib
vendored
BIN
vendor/miniaudio/lib/miniaudio.lib
vendored
Binary file not shown.
30
vendor/miniaudio/logging.odin
vendored
30
vendor/miniaudio/logging.odin
vendored
@@ -12,6 +12,36 @@ when ODIN_OS == .Windows {
|
||||
|
||||
MAX_LOG_CALLBACKS :: 4
|
||||
|
||||
|
||||
/*
|
||||
The callback for handling log messages.
|
||||
|
||||
|
||||
Parameters
|
||||
----------
|
||||
pUserData (in)
|
||||
The user data pointer that was passed into ma_log_register_callback().
|
||||
|
||||
logLevel (in)
|
||||
The log level. This can be one of the following:
|
||||
|
||||
+----------------------+
|
||||
| Log Level |
|
||||
+----------------------+
|
||||
| MA_LOG_LEVEL_DEBUG |
|
||||
| MA_LOG_LEVEL_INFO |
|
||||
| MA_LOG_LEVEL_WARNING |
|
||||
| MA_LOG_LEVEL_ERROR |
|
||||
+----------------------+
|
||||
|
||||
pMessage (in)
|
||||
The log message.
|
||||
|
||||
|
||||
Remarks
|
||||
-------
|
||||
Do not modify the state of the device from inside the callback.
|
||||
*/
|
||||
log_callback_proc :: proc "c" (pUserData: rawptr, level: u32, pMessage: cstring)
|
||||
|
||||
log_callback :: struct {
|
||||
|
||||
469
vendor/miniaudio/node_graph.odin
vendored
Normal file
469
vendor/miniaudio/node_graph.odin
vendored
Normal file
@@ -0,0 +1,469 @@
|
||||
package miniaudio
|
||||
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import lib "lib/miniaudio.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "lib/miniaudio.a"
|
||||
} else {
|
||||
foreign import lib "system:miniaudio"
|
||||
}
|
||||
|
||||
/************************************************************************************************************************************************************
|
||||
|
||||
Node Graph
|
||||
|
||||
************************************************************************************************************************************************************/
|
||||
|
||||
/* Must never exceed 254. */
|
||||
MAX_NODE_BUS_COUNT :: 254
|
||||
|
||||
/* Used internally by miniaudio for memory management. Must never exceed MA_MAX_NODE_BUS_COUNT. */
|
||||
MAX_NODE_LOCAL_BUS_COUNT :: 2
|
||||
|
||||
/* Use this when the bus count is determined by the node instance rather than the vtable. */
|
||||
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,
|
||||
}
|
||||
|
||||
/* The playback state of a node. Either started or stopped. */
|
||||
node_state :: enum c.int {
|
||||
started = 0,
|
||||
stopped = 1,
|
||||
}
|
||||
|
||||
node_vtable :: struct {
|
||||
/*
|
||||
Extended processing callback. This callback is used for effects that process input and output
|
||||
at different rates (i.e. they perform resampling). This is similar to the simple version, only
|
||||
they take two seperate frame counts: one for input, and one for output.
|
||||
|
||||
On input, `pFrameCountOut` is equal to the capacity of the output buffer for each bus, whereas
|
||||
`pFrameCountIn` will be equal to the number of PCM frames in each of the buffers in `ppFramesIn`.
|
||||
|
||||
On output, set `pFrameCountOut` to the number of PCM frames that were actually output and set
|
||||
`pFrameCountIn` to the number of input frames that were consumed.
|
||||
*/
|
||||
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
|
||||
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
|
||||
small reduction in latency as it allows miniaudio to calculate the exact number of input frames
|
||||
to read at a time instead of having to estimate.
|
||||
*/
|
||||
onGetRequiredInputFrameCount: proc "c" (pNode: ^node, outputFrameCount: u32, pInputFrameCount: ^u32) -> result,
|
||||
|
||||
/*
|
||||
The number of input buses. This is how many sub-buffers will be contained in the `ppFramesIn`
|
||||
parameters of the callbacks above.
|
||||
*/
|
||||
inputBusCount: u8,
|
||||
|
||||
/*
|
||||
The number of output buses. This is how many sub-buffers will be contained in the `ppFramesOut`
|
||||
parameters of the callbacks above.
|
||||
*/
|
||||
outputBusCount: u8,
|
||||
|
||||
/*
|
||||
Flags describing characteristics of the node. This is currently just a placeholder for some
|
||||
ideas for later on.
|
||||
*/
|
||||
flags: u32,
|
||||
}
|
||||
|
||||
node_config :: struct {
|
||||
vtable: ^node_vtable, /* Should never be null. Initialization of the node will fail if so. */
|
||||
initialState: node_state, /* Defaults to ma_node_state_started. */
|
||||
inputBusCount: u32, /* Only used if the vtable specifies an input bus count of `MA_NODE_BUS_COUNT_UNKNOWN`, otherwise must be set to `MA_NODE_BUS_COUNT_UNKNOWN` (default). */
|
||||
outputBusCount: u32, /* Only used if the vtable specifies an output bus count of `MA_NODE_BUS_COUNT_UNKNOWN`, otherwise be set to `MA_NODE_BUS_COUNT_UNKNOWN` (default). */
|
||||
pInputChannels: ^u32, /* The number of elements are determined by the input bus count as determined by the vtable, or `inputBusCount` if the vtable specifies `MA_NODE_BUS_COUNT_UNKNOWN`. */
|
||||
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`. */
|
||||
}
|
||||
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
node_output_bus :: struct {
|
||||
/* Immutable. */
|
||||
pNode: ^node, /* The node that owns this output bus. The input node. Will be null for dummy head and tail nodes. */
|
||||
outputBusIndex: u8, /* The index of the output bus on pNode that this output bus represents. */
|
||||
channels: u8, /* The number of channels in the audio stream for this bus. */
|
||||
|
||||
/* Mutable via multiple threads. Must be used atomically. The weird ordering here is for packing reasons. */
|
||||
inputNodeInputBusIndex: u8, /*atomic*/ /* The index of the input bus on the input. Required for detaching. */
|
||||
flags: u32, /*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. */
|
||||
volume: f32, /*atomic*/ /* Linear. */
|
||||
pNext: ^node_output_bus, /*atomic*/ /* If null, it's the tail node or detached. */
|
||||
pPrev: ^node_output_bus, /*atomic*/ /* If null, it's the head node or detached. */
|
||||
pInputNode: ^node, /*atomic*/ /* The node that this output bus is attached to. Required for detaching. */
|
||||
}
|
||||
|
||||
/*
|
||||
A node has multiple input buses. The output buses of a node are connecting to the input busses of
|
||||
another. An input bus is essentially just a linked list of output buses.
|
||||
*/
|
||||
node_input_bus :: struct {
|
||||
/* Mutable via multiple threads. */
|
||||
head: node_output_bus, /* Dummy head node for simplifying some lock-free thread-safety stuff. */
|
||||
nextCounter: u32, /*atomic*/ /* This is used to determine whether or not the input bus is finding the next node in the list. Used for thread safety when detaching output buses. */
|
||||
lock: spinlock, /*atomic*/ /* Unfortunate lock, but significantly simplifies the implementation. Required for thread-safe attaching and detaching. */
|
||||
|
||||
/* Set once at startup. */
|
||||
channels: u8, /* The number of channels in the audio stream for this bus. */
|
||||
}
|
||||
|
||||
|
||||
node_base :: struct {
|
||||
/* These variables are set once at startup. */
|
||||
pNodeGraph: ^node_graph, /* The graph this node belongs to. */
|
||||
vtable: ^node_vtable,
|
||||
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. */
|
||||
|
||||
/* These variables are read and written only from the audio thread. */
|
||||
cachedFrameCountOut: u16,
|
||||
cachedFrameCountIn: u16,
|
||||
consumedFrameCountIn: u16,
|
||||
|
||||
/* These variables are read and written between different threads. */
|
||||
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. */
|
||||
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. */
|
||||
_inputBuses: [MAX_NODE_LOCAL_BUS_COUNT]node_input_bus,
|
||||
_outputBuses: [MAX_NODE_LOCAL_BUS_COUNT]node_output_bus,
|
||||
_pHeap: rawptr, /* A heap allocation for internal use only. pInputBuses and/or pOutputBuses will point to this if the bus count exceeds MA_MAX_NODE_LOCAL_BUS_COUNT. */
|
||||
_ownsHeap: b32, /* If set to true, the node owns the heap allocation and _pHeap will be freed in ma_node_uninit(). */
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
node_config_init :: proc() -> node_config ---
|
||||
|
||||
node_get_heap_size :: proc(pNodeGraph: ^node_graph, pConfig: ^node_config, pHeapSizeInBytes: ^c.size_t) -> result ---
|
||||
node_init_preallocated :: proc(pNodeGraph: ^node_graph, pConfig: ^node_config, pHeap: rawptr, pNode: ^node) -> result ---
|
||||
node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^node) -> result ---
|
||||
node_uninit :: proc(pNode: ^node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
node_get_node_graph :: proc(pNode: ^node) -> ^node_graph ---
|
||||
node_get_input_bus_count :: proc(pNode: ^node) -> u32 ---
|
||||
node_get_output_bus_count :: proc(pNode: ^node) -> u32 ---
|
||||
node_get_input_channels :: proc(pNode: ^node, inputBusIndex: u32) -> u32 ---
|
||||
node_get_output_channels :: proc(pNode: ^node, outputBusIndex: u32) -> u32 ---
|
||||
node_attach_output_bus :: proc(pNode: ^node, outputBusIndex: u32, pOtherNode: ^node, otherNodeInputBusIndex: u32) -> result ---
|
||||
node_detach_output_bus :: proc(pNode: ^node, outputBusIndex: u32) -> result ---
|
||||
node_detach_all_output_buses :: proc(pNode: ^node) -> result ---
|
||||
node_set_output_bus_volume :: proc(pNode: ^node, outputBusIndex: u32, volume: f32) -> result ---
|
||||
node_get_output_bus_volume :: proc(pNode: ^node, outputBusIndex: u32) -> f32 ---
|
||||
node_set_state :: proc(pNode: ^node, state: node_state) -> result ---
|
||||
node_get_state :: proc(pNode: ^node) -> node_state ---
|
||||
node_set_state_time :: proc(pNode: ^node, state: node_state, globalTime: u64) -> result ---
|
||||
node_get_state_time :: proc(pNode: ^node, state: node_state) -> u64 ---
|
||||
node_get_state_by_time :: proc(pNode: ^node, globalTime: u64) -> node_state ---
|
||||
node_get_state_by_time_range :: proc(pNode: ^node, globalTimeBeg: u64, globalTimeEnd: u64) -> node_state ---
|
||||
node_get_time :: proc(pNode: ^node) -> u64 ---
|
||||
node_set_time :: proc(pNode: ^node, localTime: u64) -> result ---
|
||||
}
|
||||
|
||||
node_graph_config :: struct {
|
||||
channels: u32,
|
||||
nodeCacheCapInFrames: u16,
|
||||
}
|
||||
|
||||
node_graph :: struct {
|
||||
/* 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. */
|
||||
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,
|
||||
|
||||
/* Read and written by multiple threads. */
|
||||
isReading: b32, /*atomic*/
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
node_graph_config_init :: proc(channels: u32) -> node_graph_config ---
|
||||
|
||||
node_graph_init :: proc(pConfig: ^node_graph_config, pAllocationCallbacks: ^allocation_callbacks, pNodeGraph: ^node_graph) -> result ---
|
||||
node_graph_uninit :: proc(pNodeGraph: ^node_graph, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
node_graph_get_endpoint :: proc(pNodeGraph: ^node_graph) -> ^node ---
|
||||
node_graph_read_pcm_frames :: proc(pNodeGraph: ^node_graph, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
|
||||
node_graph_get_channels :: proc(pNodeGraph: ^node_graph) -> u32 ---
|
||||
node_graph_get_time :: proc(pNodeGraph: ^node_graph) -> u64 ---
|
||||
node_graph_set_time :: proc(pNodeGraph: ^node_graph, globalTime: u64) -> result ---
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Data source node. 0 input buses, 1 output bus. Used for reading from a data source. */
|
||||
data_source_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
pDataSource: ^data_source,
|
||||
}
|
||||
|
||||
data_source_node :: struct {
|
||||
base: node_base,
|
||||
pDataSource: ^data_source,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
data_source_node_config_init :: proc(pDataSource: ^data_source) -> data_source_node_config ---
|
||||
|
||||
data_source_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^data_source_node_config, pAllocationCallbacks: ^allocation_callbacks, pDataSourceNode: ^data_source_node) -> result ---
|
||||
data_source_node_uninit :: proc(pDataSourceNode: ^data_source_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
data_source_node_set_looping :: proc(pDataSourceNode: ^data_source_node, isLooping: b32) -> result ---
|
||||
data_source_node_is_looping :: proc(pDataSourceNode: ^data_source_node) -> b32 ---
|
||||
}
|
||||
|
||||
|
||||
/* Splitter Node. 1 input, 2 outputs. Used for splitting/copying a stream so it can be as input into two separate output nodes. */
|
||||
splitter_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
channels: u32,
|
||||
}
|
||||
|
||||
splitter_node :: struct {
|
||||
base: node_base,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
splitter_node_config_init :: proc(channels: u32) -> splitter_node_config ---
|
||||
|
||||
splitter_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^splitter_node_config, pAllocationCallbacks: ^allocation_callbacks, pSplitterNode: ^splitter_node) -> result ---
|
||||
splitter_node_uninit :: proc(pSplitterNode: ^splitter_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Biquad Node
|
||||
*/
|
||||
biquad_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
biquad: biquad_config,
|
||||
}
|
||||
|
||||
biquad_node :: struct {
|
||||
baseNode: node_base,
|
||||
biquad: biquad,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
biquad_node_config_init :: proc(channels: u32, b0, b1, b2, a0, a1, a2: f32) -> biquad_node_config ---
|
||||
|
||||
biquad_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^biquad_node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^biquad_node) -> result ---
|
||||
biquad_node_reinit :: proc(pConfig: ^biquad_config, pNode: ^biquad_node) -> result ---
|
||||
biquad_node_uninit :: proc(pNode: ^biquad_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Low Pass Filter Node
|
||||
*/
|
||||
lpf_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
lpf: lpf_config,
|
||||
}
|
||||
|
||||
lpf_node :: struct {
|
||||
baseNode: node_base,
|
||||
lpf: lpf,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
lpf_node_config_init :: proc(channels, sampleRate: u32, cutoffFrequency: f64, order: u32) -> lpf_node_config ---
|
||||
|
||||
lpf_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^lpf_node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^lpf_node) -> result ---
|
||||
lpf_node_reinit :: proc(pConfig: ^lpf_config, pNode: ^lpf_node) -> result ---
|
||||
lpf_node_uninit :: proc(pNode: ^lpf_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
High Pass Filter Node
|
||||
*/
|
||||
hpf_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
hpf: hpf_config,
|
||||
}
|
||||
|
||||
hpf_node :: struct {
|
||||
baseNode: node_base,
|
||||
hpf: hpf,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
hpf_node_config_init :: proc(channels, sampleRate: u32, cutoffFrequency: f64, order: u32) -> hpf_node_config ---
|
||||
|
||||
hpf_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^hpf_node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^hpf_node) -> result ---
|
||||
hpf_node_reinit :: proc(pConfig: ^hpf_config, pNode: ^hpf_node) -> result ---
|
||||
hpf_node_uninit :: proc(pNode: ^hpf_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Band Pass Filter Node
|
||||
*/
|
||||
bpf_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
bpf: bpf_config,
|
||||
}
|
||||
|
||||
bpf_node :: struct {
|
||||
baseNode: node_base,
|
||||
bpf: bpf,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
bpf_node_config_init :: proc(channels, sampleRate: u32, cutoffFrequency: f64, order: u32) -> bpf_node_config ---
|
||||
|
||||
bpf_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^bpf_node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^bpf_node) -> result ---
|
||||
bpf_node_reinit :: proc(pConfig: ^bpf_config, pNode: ^bpf_node) -> result ---
|
||||
bpf_node_uninit :: proc(pNode: ^bpf_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Notching Filter Node
|
||||
*/
|
||||
notch_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
notch: notch_config,
|
||||
}
|
||||
|
||||
notch_node :: struct {
|
||||
baseNode: node_base,
|
||||
notch: notch2,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
notch_node_config_init :: proc(channels, sampleRate: u32, q, frequency: f64) -> notch_node_config ---
|
||||
|
||||
notch_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^notch_node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^notch_node) -> result ---
|
||||
notch_node_reinit :: proc(pConfig: ^notch_config, pNode: ^notch_node) -> result ---
|
||||
notch_node_uninit :: proc(pNode: ^notch_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Peaking Filter Node
|
||||
*/
|
||||
peak_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
peak: peak_config,
|
||||
}
|
||||
|
||||
peak_node :: struct {
|
||||
baseNode: node_base,
|
||||
peak: peak2,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
peak_node_config_init :: proc(channels, sampleRate: u32, gainDB, q, frequency: f64) -> peak_node_config ---
|
||||
|
||||
peak_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^peak_node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^peak_node) -> result ---
|
||||
peak_node_reinit :: proc(pConfig: ^peak_config, pNode: ^peak_node) -> result ---
|
||||
peak_node_uninit :: proc(pNode: ^peak_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Low Shelf Filter Node
|
||||
*/
|
||||
loshelf_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
loshelf: loshelf_config,
|
||||
}
|
||||
|
||||
loshelf_node :: struct {
|
||||
baseNode: node_base,
|
||||
loshelf: loshelf2,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
loshelf_node_config_init :: proc(channels, sampleRate: u32, gainDB, q, frequency: f64) -> loshelf_node_config ---
|
||||
|
||||
loshelf_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^loshelf_node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^loshelf_node) -> result ---
|
||||
loshelf_node_reinit :: proc(pConfig: ^loshelf_config, pNode: ^loshelf_node) -> result ---
|
||||
loshelf_node_uninit :: proc(pNode: ^loshelf_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
High Shelf Filter Node
|
||||
*/
|
||||
hishelf_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
hishelf: hishelf_config,
|
||||
}
|
||||
|
||||
hishelf_node :: struct {
|
||||
baseNode: node_base,
|
||||
hishelf: hishelf2,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
hishelf_node_config_init :: proc(channels, sampleRate: u32, gainDB, q, frequency: f64) -> hishelf_node_config ---
|
||||
|
||||
hishelf_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^hishelf_node_config, pAllocationCallbacks: ^allocation_callbacks, pNode: ^hishelf_node) -> result ---
|
||||
hishelf_node_reinit :: proc(pConfig: ^hishelf_config, pNode: ^hishelf_node) -> result ---
|
||||
hishelf_node_uninit :: proc(pNode: ^hishelf_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Delay Filter Node
|
||||
*/
|
||||
delay_node_config :: struct {
|
||||
nodeConfig: node_config,
|
||||
delay: delay_config,
|
||||
}
|
||||
|
||||
delay_node :: struct {
|
||||
baseNode: node_base,
|
||||
delay: delay,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
delay_node_config_init :: proc(channels, sampleRate, delayInFrames: u32, decay: f32) -> delay_node_config ---
|
||||
|
||||
delay_node_init :: proc(pNodeGraph: ^node_graph, pConfig: ^delay_node_config, pAllocationCallbacks: ^allocation_callbacks, pDelayNode: ^delay_node) -> result ---
|
||||
delay_node_uninit :: proc(pDelayNode: ^delay_node, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
delay_node_set_wet :: proc(pDelayNode: ^delay_node, value: f32) ---
|
||||
delay_node_get_wet :: proc(pDelayNode: ^delay_node) -> f32 ---
|
||||
delay_node_set_dry :: proc(pDelayNode: ^delay_node, value: f32) ---
|
||||
delay_node_get_dry :: proc(pDelayNode: ^delay_node) -> f32 ---
|
||||
delay_node_set_decay :: proc(pDelayNode: ^delay_node, value: f32) ---
|
||||
delay_node_get_decay :: proc(pDelayNode: ^delay_node) -> f32 ---
|
||||
}
|
||||
288
vendor/miniaudio/resource_manager.odin
vendored
Normal file
288
vendor/miniaudio/resource_manager.odin
vendored
Normal file
@@ -0,0 +1,288 @@
|
||||
package miniaudio
|
||||
|
||||
import "core:c"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import lib "lib/miniaudio.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "lib/miniaudio.a"
|
||||
} else {
|
||||
foreign import lib "system:miniaudio"
|
||||
}
|
||||
|
||||
/************************************************************************************************************************************************************
|
||||
|
||||
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. */
|
||||
}
|
||||
|
||||
/*
|
||||
Pipeline notifications used by the resource manager. Made up of both an async notification and a fence, both of which are optional.
|
||||
*/
|
||||
resource_manager_pipeline_stage_notification :: struct {
|
||||
pNotification: ^async_notification,
|
||||
pFence: ^fence,
|
||||
}
|
||||
|
||||
resource_manager_pipeline_notifications :: struct {
|
||||
init: resource_manager_pipeline_stage_notification, /* Initialization of the decoder. */
|
||||
done: resource_manager_pipeline_stage_notification, /* Decoding fully completed. */
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
resource_manager_pipeline_notifications_init :: proc() -> resource_manager_pipeline_notifications ---
|
||||
}
|
||||
|
||||
|
||||
/* BEGIN BACKWARDS COMPATIBILITY */
|
||||
/* TODO: Remove this block in version 0.12. */
|
||||
resource_manager_job :: job
|
||||
resource_manager_job_init :: job_init
|
||||
JOB_TYPE_RESOURCE_MANAGER_QUEUE_FLAG_NON_BLOCKING :: job_queue_flags.NON_BLOCKING
|
||||
resource_manager_job_queue_config :: job_queue_config
|
||||
resource_manager_job_queue_config_init :: job_queue_config_init
|
||||
resource_manager_job_queue :: job_queue
|
||||
resource_manager_job_queue_get_heap_size :: job_queue_get_heap_size
|
||||
resource_manager_job_queue_init_preallocated :: job_queue_init_preallocated
|
||||
resource_manager_job_queue_init :: job_queue_init
|
||||
resource_manager_job_queue_uninit :: job_queue_uninit
|
||||
resource_manager_job_queue_post :: job_queue_post
|
||||
resource_manager_job_queue_next :: job_queue_next
|
||||
/* END BACKWARDS COMPATIBILITY */
|
||||
|
||||
|
||||
|
||||
/* 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 {
|
||||
/* Indicates ma_resource_manager_next_job() should not block. Only valid when the job thread count is 0. */
|
||||
NON_BLOCKING = 0x00000001,
|
||||
|
||||
/* Disables any kind of multithreading. Implicitly enables MA_RESOURCE_MANAGER_FLAG_NON_BLOCKING. */
|
||||
NO_THREADING = 0x00000002,
|
||||
}
|
||||
|
||||
resource_manager_data_source_config :: struct {
|
||||
pFilePath: cstring,
|
||||
pFilePathW: [^]c.wchar_t,
|
||||
pNotifications: ^resource_manager_pipeline_notifications,
|
||||
initialSeekPointInPCMFrames: u64,
|
||||
rangeBegInPCMFrames: u64,
|
||||
rangeEndInPCMFrames: u64,
|
||||
loopPointBegInPCMFrames: u64,
|
||||
loopPointEndInPCMFrames: u64,
|
||||
isLooping: b32,
|
||||
flags: u32,
|
||||
}
|
||||
|
||||
resource_manager_data_supply_type :: enum c.int {
|
||||
unknown = 0, /* Used for determining whether or the data supply has been initialized. */
|
||||
encoded, /* Data supply is an encoded buffer. Connector is ma_decoder. */
|
||||
decoded, /* Data supply is a decoded buffer. Connector is ma_audio_buffer. */
|
||||
decoded_paged, /* Data supply is a linked list of decoded buffers. Connector is ma_paged_audio_buffer. */
|
||||
}
|
||||
|
||||
resource_manager_data_supply :: struct {
|
||||
type: resource_manager_data_supply_type, /*atomic*/ /* Read and written from different threads so needs to be accessed atomically. */
|
||||
backend: struct #raw_union {
|
||||
encoded: struct {
|
||||
pData: rawptr,
|
||||
sizeInBytes: c.size_t,
|
||||
},
|
||||
decoded: struct {
|
||||
pData: rawptr,
|
||||
totalFrameCount: u64,
|
||||
decodedFrameCount: u64,
|
||||
format: format,
|
||||
channels: u32,
|
||||
sampleRate: u32,
|
||||
},
|
||||
decodedPaged: struct {
|
||||
data: paged_audio_buffer_data,
|
||||
decodedFrameCount: u64,
|
||||
sampleRate: u32,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
resource_manager_data_buffer_node :: struct {
|
||||
hashedName32: u32, /* The hashed name. This is the key. */
|
||||
refCount: u32,
|
||||
result: result, /*atomic*/ /* Result from asynchronous loading. When loading set to MA_BUSY. When fully loaded set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. */
|
||||
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. */
|
||||
isDataOwnedByResourceManager: b32, /* Set to true when the underlying data buffer was allocated the resource manager. Set to false if it is owned by the application (via ma_resource_manager_register_*()). */
|
||||
data: resource_manager_data_supply,
|
||||
pParent: ^resource_manager_data_buffer_node,
|
||||
pChildLo: ^resource_manager_data_buffer_node,
|
||||
pChildHi: ^resource_manager_data_buffer_node,
|
||||
}
|
||||
|
||||
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. */
|
||||
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. */
|
||||
seekToCursorOnNextRead: b32, /* On the next read we need to seek to the frame cursor. */
|
||||
result: result, /*atomic*/ /* Keeps track of a result of decoding. Set to MA_BUSY while the buffer is still loading. Set to MA_SUCCESS when loading is finished successfully. Otherwise set to some other code. */
|
||||
isLooping: b32, /*atomic*/ /* Can be read and written by different threads at the same time. Must be used atomically. */
|
||||
isConnectorInitialized: b32, /* Used for asynchronous loading to ensure we don't try to initialize the connector multiple times while waiting for the node to fully load. */
|
||||
connector: struct #raw_union {
|
||||
decoder: decoder, /* Supply type is ma_resource_manager_data_supply_type_encoded */
|
||||
buffer: audio_buffer, /* Supply type is ma_resource_manager_data_supply_type_decoded */
|
||||
pagedBuffer: paged_audio_buffer, /* Supply type is ma_resource_manager_data_supply_type_decoded_paged */
|
||||
}, /* Connects this object to the node's data supply. */
|
||||
}
|
||||
|
||||
resource_manager_data_stream :: struct {
|
||||
ds: data_source_base, /* Base data source. A data stream is a data source. */
|
||||
pResourceManager: ^resource_manager, /* A pointer to the resource manager that owns this data stream. */
|
||||
flags: u32, /* The flags that were passed used to initialize the stream. */
|
||||
decoder: decoder, /* Used for filling pages with data. This is only ever accessed by the job thread. The public API should never touch this. */
|
||||
isDecoderInitialized: b32, /* Required for determining whether or not the decoder should be uninitialized in MA_JOB_TYPE_RESOURCE_MANAGER_FREE_DATA_STREAM. */
|
||||
totalLengthInPCMFrames: u64, /* This is calculated when first loaded by the MA_JOB_TYPE_RESOURCE_MANAGER_LOAD_DATA_STREAM. */
|
||||
relativeCursor: u32, /* The playback cursor, relative to the current page. Only ever accessed by the public API. Never accessed by the job thread. */
|
||||
absoluteCursor: u64, /*atomic*/ /* The playback cursor, in absolute position starting from the start of the file. */
|
||||
currentPageIndex: u32, /* Toggles between 0 and 1. Index 0 is the first half of pPageData. Index 1 is the second half. Only ever accessed by the public API. Never accessed by the job thread. */
|
||||
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. */
|
||||
|
||||
/* Written by the public API, read by the job thread. */
|
||||
isLooping: b32, /*atomic*/ /* Whether or not the stream is looping. It's important to set the looping flag at the data stream level for smooth loop transitions. */
|
||||
|
||||
/* Written by the job thread, read by the public API. */
|
||||
pPageData: rawptr, /* Buffer containing the decoded data of each page. Allocated once at initialization time. */
|
||||
pageFrameCount: [2]u32, /*atomic*/ /* The number of valid PCM frames in each page. Used to determine the last valid frame. */
|
||||
|
||||
/* Written and read by both the public API and the job thread. These must be atomic. */
|
||||
result: result, /*atomic*/ /* Result from asynchronous loading. When loading set to MA_BUSY. When initialized set to MA_SUCCESS. When deleting set to MA_UNAVAILABLE. If an error occurs when loading, set to an error code. */
|
||||
isDecoderAtEnd: b32, /*atomic*/ /* Whether or not the decoder has reached the end. */
|
||||
isPageValid: [2]b32, /*atomic*/ /* Booleans to indicate whether or not a page is valid. Set to false by the public API, set to true by the job thread. Set to false as the pages are consumed, true when they are filled. */
|
||||
seekCounter: b32, /*atomic*/ /* When 0, no seeking is being performed. When > 0, a seek is being performed and reading should be delayed with MA_BUSY. */
|
||||
}
|
||||
|
||||
resource_manager_data_source :: struct {
|
||||
backend: struct #raw_union {
|
||||
buffer: resource_manager_data_buffer,
|
||||
stream: resource_manager_data_stream,
|
||||
}, /* Must be the first item because we need the first item to be the data source callbacks for the buffer or stream. */
|
||||
|
||||
flags: u32, /* The flags that were passed in to ma_resource_manager_data_source_init(). */
|
||||
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. */
|
||||
}
|
||||
|
||||
resource_manager_config :: struct {
|
||||
allocationCallbacks: allocation_callbacks,
|
||||
pLog: ^log,
|
||||
decodedFormat: format, /* The decoded format to use. Set to ma_format_unknown (default) to use the file's native format. */
|
||||
decodedChannels: u32, /* The decoded channel count to use. Set to 0 (default) to use the file's native channel count. */
|
||||
decodedSampleRate: u32, /* the decoded sample rate to use. Set to 0 (default) to use the file's native sample rate. */
|
||||
jobThreadCount: u32, /* Set to 0 if you want to self-manage your job threads. Defaults to 1. */
|
||||
jobQueueCapacity: u32, /* The maximum number of jobs that can fit in the queue at a time. Defaults to MA_JOB_TYPE_RESOURCE_MANAGER_QUEUE_CAPACITY. Cannot be zero. */
|
||||
flags: u32,
|
||||
pVFS: ^vfs, /* Can be NULL in which case defaults will be used. */
|
||||
ppCustomDecodingBackendVTables: ^[^]decoding_backend_vtable,
|
||||
customDecodingBackendCount: u32,
|
||||
pCustomDecodingBackendUserData: rawptr,
|
||||
}
|
||||
|
||||
resource_manager :: struct {
|
||||
config: resource_manager_config,
|
||||
pRootDataBufferNode: ^resource_manager_data_buffer_node, /* The root buffer in the binary tree. */
|
||||
dataBufferBSTLock: (struct {} when NO_THREADING else mutex), /* For synchronizing access to the data buffer binary tree. */
|
||||
jobThreads: (struct {} when NO_THREADING else [RESOURCE_MANAGER_MAX_JOB_THREAD_COUNT]thread), /* The threads for executing jobs. */
|
||||
jobQueue: job_queue, /* Multi-consumer, multi-producer job queue for managing jobs for asynchronous decoding and streaming. */
|
||||
defaultVFS: default_vfs, /* Only used if a custom VFS is not specified. */
|
||||
log: log, /* Only used if no log was specified in the config. */
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
resource_manager_data_source_config_init :: proc() -> resource_manager_data_source_config ---
|
||||
resource_manager_config_init :: proc() -> resource_manager_config ---
|
||||
|
||||
/* Init. */
|
||||
resource_manager_init :: proc(pConfig: ^resource_manager_config, pResourceManager: ^resource_manager) -> result ---
|
||||
resource_manager_uninit :: proc(pResourceManager: ^resource_manager) ---
|
||||
resource_manager_get_log :: proc(pResourceManager: ^resource_manager) -> ^log ---
|
||||
|
||||
/* Registration. */
|
||||
resource_manager_register_file :: proc(pResourceManager: ^resource_manager, pFilePath: cstring, flags: u32) -> result ---
|
||||
resource_manager_register_file_w :: proc(pResourceManager: ^resource_manager, pFilePath: [^]c.wchar_t, flags: u32) -> result ---
|
||||
resource_manager_register_decoded_data :: proc(pResourceManager: ^resource_manager, pName: cstring, pData: rawptr, frameCount: u64, format: format, channels: u32, sampleRate: u32) -> result --- /* Does not copy. Increments the reference count if already exists and returns MA_SUCCESS. */
|
||||
resource_manager_register_decoded_data_w :: proc(pResourceManager: ^resource_manager, pName: [^]c.wchar_t, pData: rawptr, frameCount: u64, format: format, channels: u32, sampleRate: u32) -> result ---
|
||||
resource_manager_register_encoded_data :: proc(pResourceManager: ^resource_manager, pName: cstring, pData: rawptr, sizeInBytes: c.size_t) -> result --- /* Does not copy. Increments the reference count if already exists and returns MA_SUCCESS. */
|
||||
resource_manager_register_encoded_data_w :: proc(pResourceManager: ^resource_manager, pName: [^]c.wchar_t, pData: rawptr, sizeInBytes: c.size_t) -> result ---
|
||||
resource_manager_unregister_file :: proc(pResourceManager: ^resource_manager, pFilePath: cstring) -> result ---
|
||||
resource_manager_unregister_file_w :: proc(pResourceManager: ^resource_manager, pFilePath: [^]c.wchar_t) -> result ---
|
||||
resource_manager_unregister_data :: proc(pResourceManager: ^resource_manager, pName: cstring) -> result ---
|
||||
resource_manager_unregister_data_w :: proc(pResourceManager: ^resource_manager, pName: [^]c.wchar_t) -> result ---
|
||||
|
||||
/* Data Buffers. */
|
||||
resource_manager_data_buffer_init_ex :: proc(pResourceManager: ^resource_manager, pConfig: ^resource_manager_data_source_config, pDataBuffer: ^resource_manager_data_buffer) -> result ---
|
||||
resource_manager_data_buffer_init :: proc(pResourceManager: ^resource_manager, pFilePath: cstring, flags: u32, pNotifications: ^resource_manager_pipeline_notifications, pDataBuffer: ^resource_manager_data_buffer) -> result ---
|
||||
resource_manager_data_buffer_init_w :: proc(pResourceManager: ^resource_manager, pFilePath: [^]c.wchar_t, flags: u32, pNotifications: ^resource_manager_pipeline_notifications, pDataBuffer: ^resource_manager_data_buffer) -> result ---
|
||||
resource_manager_data_buffer_init_copy :: proc(pResourceManager: ^resource_manager, pExistingDataBuffer, pDataBuffer: ^resource_manager_data_buffer) -> result ---
|
||||
resource_manager_data_buffer_uninit :: proc(pDataBuffer: ^resource_manager_data_buffer) -> result ---
|
||||
resource_manager_data_buffer_read_pcm_frames :: proc(pDataBuffer: ^resource_manager_data_buffer, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
|
||||
resource_manager_data_buffer_seek_to_pcm_frame :: proc(pDataBuffer: ^resource_manager_data_buffer, frameIndex: u64) -> result ---
|
||||
resource_manager_data_buffer_get_data_format :: proc(pDataBuffer: ^resource_manager_data_buffer, pFormat: ^format, pChannels: ^u32, pSampleRate: ^u32, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
|
||||
resource_manager_data_buffer_get_cursor_in_pcm_frames :: proc(pDataBuffer: ^resource_manager_data_buffer, pCursor: ^u64) -> result ---
|
||||
resource_manager_data_buffer_get_length_in_pcm_frames :: proc(pDataBuffer: ^resource_manager_data_buffer, pLength: ^u64) -> result ---
|
||||
resource_manager_data_buffer_result :: proc(pDataBuffer: ^resource_manager_data_buffer) -> result ---
|
||||
resource_manager_data_buffer_set_looping :: proc(pDataBuffer: ^resource_manager_data_buffer, isLooping: b32) -> result ---
|
||||
resource_manager_data_buffer_is_looping :: proc(pDataBuffer: ^resource_manager_data_buffer) -> b32 ---
|
||||
resource_manager_data_buffer_get_available_frames :: proc(pDataBuffer: ^resource_manager_data_buffer, pAvailableFrames: ^u64) -> result ---
|
||||
|
||||
/* Data Streams. */
|
||||
resource_manager_data_stream_init_ex :: proc(pResourceManager: ^resource_manager, pConfig: ^resource_manager_data_source_config, pDataStream: ^resource_manager_data_stream) -> result ---
|
||||
resource_manager_data_stream_init :: proc(pResourceManager: ^resource_manager, pFilePath: cstring, flags: u32, pNotifications: ^resource_manager_pipeline_notifications, pDataStream: ^resource_manager_data_stream) -> result ---
|
||||
resource_manager_data_stream_init_w :: proc(pResourceManager: ^resource_manager, pFilePath: [^]c.wchar_t, flags: u32, pNotifications: ^resource_manager_pipeline_notifications, pDataStream: ^resource_manager_data_stream) -> result ---
|
||||
resource_manager_data_stream_uninit :: proc(pDataStream: ^resource_manager_data_stream) -> result ---
|
||||
resource_manager_data_stream_read_pcm_frames :: proc(pDataStream: ^resource_manager_data_stream, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
|
||||
resource_manager_data_stream_seek_to_pcm_frame :: proc(pDataStream: ^resource_manager_data_stream, frameIndex: u64) -> result ---
|
||||
resource_manager_data_stream_get_data_format :: proc(pDataStream: ^resource_manager_data_stream, pFormat: ^format, pChannels, pSampleRate: ^u32, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
|
||||
resource_manager_data_stream_get_cursor_in_pcm_frames :: proc(pDataStream: ^resource_manager_data_stream, pCursor: ^u64) -> result ---
|
||||
resource_manager_data_stream_get_length_in_pcm_frames :: proc(pDataStream: ^resource_manager_data_stream, pLength: ^u64) -> result ---
|
||||
resource_manager_data_stream_result :: proc(pDataStream: ^resource_manager_data_stream) -> result ---
|
||||
resource_manager_data_stream_set_looping :: proc(pDataStream: ^resource_manager_data_stream, isLooping: b32) -> result ---
|
||||
resource_manager_data_stream_is_looping :: proc(pDataStream: ^resource_manager_data_stream) -> b32 ---
|
||||
resource_manager_data_stream_get_available_frames :: proc(pDataStream: ^resource_manager_data_stream, pAvailableFrames: ^u64) -> result ---
|
||||
|
||||
/* Data Sources. */
|
||||
resource_manager_data_source_init_ex :: proc(pResourceManager: ^resource_manager, pConfig: ^resource_manager_data_source_config, pDataSource: ^resource_manager_data_source) -> result ---
|
||||
resource_manager_data_source_init :: proc(pResourceManager: ^resource_manager, pName: cstring, flags: u32, pNotifications: ^resource_manager_pipeline_notifications, pDataSource: ^resource_manager_data_source) -> result ---
|
||||
resource_manager_data_source_init_w :: proc(pResourceManager: ^resource_manager, pName: [^]c.wchar_t, flags: u32, pNotifications: ^resource_manager_pipeline_notifications, pDataSource: ^resource_manager_data_source) -> result ---
|
||||
resource_manager_data_source_init_copy :: proc(pResourceManager: ^resource_manager, pExistingDataSource, pDataSource: ^resource_manager_data_source) -> result ---
|
||||
resource_manager_data_source_uninit :: proc(pDataSource: ^resource_manager_data_source) -> result ---
|
||||
resource_manager_data_source_read_pcm_frames :: proc(pDataSource: ^resource_manager_data_source, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result ---
|
||||
resource_manager_data_source_seek_to_pcm_frame :: proc(pDataSource: ^resource_manager_data_source, frameIndex: u64) -> result ---
|
||||
resource_manager_data_source_get_data_format :: proc(pDataSource: ^resource_manager_data_source, pFormat: ^format, pChannels, pSampleRate: ^u32, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result ---
|
||||
resource_manager_data_source_get_cursor_in_pcm_frames :: proc(pDataSource: ^resource_manager_data_source, pCursor: ^u64) -> result ---
|
||||
resource_manager_data_source_get_length_in_pcm_frames :: proc(pDataSource: ^resource_manager_data_source, pLength: ^u64) -> result ---
|
||||
resource_manager_data_source_result :: proc(pDataSource: ^resource_manager_data_source) -> result ---
|
||||
resource_manager_data_source_set_looping :: proc(pDataSource: ^resource_manager_data_source, isLooping: b32) -> result ---
|
||||
resource_manager_data_source_is_looping :: proc(pDataSource: ^resource_manager_data_source) -> b32 ---
|
||||
resource_manager_data_source_get_available_frames :: proc(pDataSource: ^resource_manager_data_source, pAvailableFrames: ^u64) -> result ---
|
||||
|
||||
/* Job management. */
|
||||
resource_manager_post_job :: proc(pResourceManager: ^resource_manager, pJob: ^job) -> result ---
|
||||
resource_manager_post_job_quit :: proc(pResourceManager: ^resource_manager) -> result --- /* Helper for posting a quit job. */
|
||||
resource_manager_next_job :: proc(pResourceManager: ^resource_manager, pJob: ^job) -> result ---
|
||||
resource_manager_process_job :: proc(pResourceManager: ^resource_manager, pJob: ^job) -> result --- /* DEPRECATED. Use ma_job_process(). Will be removed in version 0.12. */
|
||||
resource_manager_process_next_job :: proc(pResourceManager: ^resource_manager) -> result --- /* Returns MA_CANCELLED if a MA_JOB_TYPE_QUIT job is found. In non-blocking mode, returns MA_NO_DATA_AVAILABLE if no jobs are available. */
|
||||
}
|
||||
34632
vendor/miniaudio/src/miniaudio.h
vendored
34632
vendor/miniaudio/src/miniaudio.h
vendored
File diff suppressed because it is too large
Load Diff
152
vendor/miniaudio/synchronization.odin
vendored
Normal file
152
vendor/miniaudio/synchronization.odin
vendored
Normal file
@@ -0,0 +1,152 @@
|
||||
package miniaudio
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import lib "lib/miniaudio.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
foreign import lib "lib/miniaudio.a"
|
||||
} else {
|
||||
foreign import lib "system:miniaudio"
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
/*
|
||||
Locks a spinlock.
|
||||
*/
|
||||
spinlock_lock :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
|
||||
|
||||
/*
|
||||
Locks a spinlock, but does not yield() when looping.
|
||||
*/
|
||||
spinlock_lock_noyield :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
|
||||
|
||||
/*
|
||||
Unlocks a spinlock.
|
||||
*/
|
||||
spinlock_unlock :: proc(/*volatile*/ pSpinlock: ^spinlock) -> result ---
|
||||
|
||||
when NO_THREADING {
|
||||
/*
|
||||
Creates a mutex.
|
||||
|
||||
A mutex must be created from a valid context. A mutex is initially unlocked.
|
||||
*/
|
||||
mutex_init :: proc(pMutex: ^mutex) -> result ---
|
||||
|
||||
/*
|
||||
Deletes a mutex.
|
||||
*/
|
||||
mutex_uninit :: proc(pMutex: ^mutex) ---
|
||||
|
||||
/*
|
||||
Locks a mutex with an infinite timeout.
|
||||
*/
|
||||
mutex_lock :: proc(pMutex: ^mutex) ---
|
||||
|
||||
/*
|
||||
Unlocks a mutex.
|
||||
*/
|
||||
mutex_unlock :: proc(pMutex: ^mutex) ---
|
||||
|
||||
|
||||
/*
|
||||
Initializes an auto-reset event.
|
||||
*/
|
||||
event_init :: proc(pEvent: ^event) -> result ---
|
||||
|
||||
/*
|
||||
Uninitializes an auto-reset event.
|
||||
*/
|
||||
event_uninit :: proc(pEvent: ^event) ---
|
||||
|
||||
/*
|
||||
Waits for the specified auto-reset event to become signalled.
|
||||
*/
|
||||
event_wait :: proc(pEvent: ^event) -> result ---
|
||||
|
||||
/*
|
||||
Signals the specified auto-reset event.
|
||||
*/
|
||||
event_signal :: proc(pEvent: ^event) -> result ---
|
||||
} /* NO_THREADING */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
Fence
|
||||
=====
|
||||
This locks while the counter is larger than 0. Counter can be incremented and decremented by any
|
||||
thread, but care needs to be taken when waiting. It is possible for one thread to acquire the
|
||||
fence just as another thread returns from ma_fence_wait().
|
||||
|
||||
The idea behind a fence is to allow you to wait for a group of operations to complete. When an
|
||||
operation starts, the counter is incremented which locks the fence. When the operation completes,
|
||||
the fence will be released which decrements the counter. ma_fence_wait() will block until the
|
||||
counter hits zero.
|
||||
|
||||
If threading is disabled, ma_fence_wait() will spin on the counter.
|
||||
*/
|
||||
fence :: struct {
|
||||
e: (struct {} when NO_THREADING else event),
|
||||
counter: (u32 when NO_THREADING else struct {}),
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
fence_init :: proc(pFence: ^fence) -> result ---
|
||||
fence_uninit :: proc(pFence: ^fence) ---
|
||||
fence_acquire :: proc(pFence: ^fence) -> result --- /* Increment counter. */
|
||||
fence_release :: proc(pFence: ^fence) -> result --- /* Decrement counter. */
|
||||
fence_wait :: proc(pFence: ^fence) -> result --- /* Wait for counter to reach 0. */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Notification callback for asynchronous operations.
|
||||
*/
|
||||
async_notification :: struct {}
|
||||
|
||||
async_notification_callbacks :: struct {
|
||||
onSignal: proc "c" (pNotification: ^async_notification),
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
async_notification_signal :: proc(pNotification: ^async_notification) -> result ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Simple polling notification.
|
||||
|
||||
This just sets a variable when the notification has been signalled which is then polled with ma_async_notification_poll_is_signalled()
|
||||
*/
|
||||
async_notification_poll :: struct {
|
||||
cb: async_notification_callbacks,
|
||||
signalled: b32,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
async_notification_poll_init :: proc(pNotificationPoll: ^async_notification_poll) -> result ---
|
||||
async_notification_poll_is_signalled :: proc(pNotificationPoll: ^async_notification_poll) -> b32 ---
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Event Notification
|
||||
|
||||
This uses an ma_event. If threading is disabled (MA_NO_THREADING), initialization will fail.
|
||||
*/
|
||||
async_notification_event :: struct {
|
||||
cb: async_notification_callbacks,
|
||||
e: (struct {} when NO_THREADING else event),
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
async_notification_event_init :: proc(pNotificationEvent: ^async_notification_event) -> result ---
|
||||
async_notification_event_uninit :: proc(pNotificationEvent: ^async_notification_event) -> result ---
|
||||
async_notification_event_wait :: proc(pNotificationEvent: ^async_notification_event) -> result ---
|
||||
async_notification_event_signal :: proc(pNotificationEvent: ^async_notification_event) -> result ---
|
||||
}
|
||||
175
vendor/miniaudio/utilities.odin
vendored
175
vendor/miniaudio/utilities.odin
vendored
@@ -1,5 +1,7 @@
|
||||
package miniaudio
|
||||
|
||||
import c "core:c/libc"
|
||||
|
||||
when ODIN_OS == .Windows {
|
||||
foreign import lib "lib/miniaudio.lib"
|
||||
} else when ODIN_OS == .Linux {
|
||||
@@ -10,13 +12,6 @@ when ODIN_OS == .Windows {
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
/*
|
||||
Adjust buffer size based on a scaling factor.
|
||||
|
||||
This just multiplies the base size by the scaling factor, making sure it's a size of at least 1.
|
||||
*/
|
||||
scale_buffer_size :: proc(baseBufferSize: u32, scale: f32) -> u32 ---
|
||||
|
||||
/*
|
||||
Calculates a buffer size in milliseconds from the specified number of frames and sample rate.
|
||||
*/
|
||||
@@ -51,9 +46,14 @@ foreign lib {
|
||||
|
||||
|
||||
/*
|
||||
Clips f32 samples.
|
||||
Clips samples.
|
||||
*/
|
||||
clip_samples_f32 :: proc(p: [^]f32, sampleCount: u64) ---
|
||||
clip_samples_u8 :: proc(pDst: [^]u8, pSrc: [^]i16, count: u64) ---
|
||||
clip_samples_s16 :: proc(pDst: [^]i16, pSrc: [^]i32, count: u64) ---
|
||||
clip_samples_s24 :: proc(pDst: [^]u8, pSrc: [^]i64, count: u64) ---
|
||||
clip_samples_s32 :: proc(pDst: [^]i32, pSrc: [^]i64, count: u64) ---
|
||||
clip_samples_f32 :: proc(pDst, pSrc: [^]f32, count: u64) ---
|
||||
clip_pcm_frames :: proc(pDst, pSrc: rawptr, frameCount: u64, format: format, channels: u32) ---
|
||||
|
||||
/*
|
||||
Helper for applying a volume factor to samples.
|
||||
@@ -86,20 +86,26 @@ foreign lib {
|
||||
apply_volume_factor_pcm_frames_f32 :: proc(pFrames: [^]f32, frameCount: u64, channels: u32, factor: f32) ---
|
||||
apply_volume_factor_pcm_frames :: proc(pFrames: rawptr, frameCount: u64, format: format, channels: u32, factor: f32) ---
|
||||
|
||||
copy_and_apply_volume_factor_per_channel_f32 :: proc(pFramesOut, pFramesIn: [^]f32, frameCount: u64, channels: u32, pChannelGains: [^]f32) ---
|
||||
|
||||
|
||||
ma_copy_and_apply_volume_and_clip_samples_u8 :: proc(pDst: [^]u8, pSrc: [^]i16, count: u64, volume: f32) ---
|
||||
ma_copy_and_apply_volume_and_clip_samples_s16 :: proc(pDst: [^]i16, pSrc: [^]i32, count: u64, volume: f32) ---
|
||||
ma_copy_and_apply_volume_and_clip_samples_s24 :: proc(pDst: [^]u8, pSrc: [^]i64, count: u64, volume: f32) ---
|
||||
ma_copy_and_apply_volume_and_clip_samples_s32 :: proc(pDst: [^]i32, pSrc: [^]i64, count: u64, volume: f32) ---
|
||||
ma_copy_and_apply_volume_and_clip_samples_f32 :: proc(pDst, pSrc: [^]f32, count: u64, volume: f32) ---
|
||||
ma_copy_and_apply_volume_and_clip_pcm_frames :: proc(pDst, pSrc: rawptr, frameCount: u64, format: format, channels: u32, volume: f32) ---
|
||||
|
||||
|
||||
/*
|
||||
Helper for converting a linear factor to gain in decibels.
|
||||
*/
|
||||
factor_to_gain_db :: proc(factor: f32) -> f32 ---
|
||||
volume_linear_to_db :: proc(factor: f32) -> f32 ---
|
||||
|
||||
/*
|
||||
Helper for converting gain in decibels to a linear factor.
|
||||
*/
|
||||
gain_db_to_factor :: proc(gain: f32) -> f32 ---
|
||||
}
|
||||
|
||||
zero_pcm_frames :: #force_inline proc "c" (p: rawptr, frameCount: u64, format: format, channels: u32) {
|
||||
silence_pcm_frames(p, frameCount, format, channels)
|
||||
volume_db_to_linear :: proc(gain: f32) -> f32 ---
|
||||
}
|
||||
|
||||
offset_pcm_frames_ptr_f32 :: #force_inline proc "c" (p: [^]f32, offsetInFrames: u64, channels: u32) -> [^]f32 {
|
||||
@@ -109,23 +115,20 @@ offset_pcm_frames_const_ptr_f32 :: #force_inline proc "c" (p: [^]f32, offsetInFr
|
||||
return cast([^]f32)offset_pcm_frames_ptr(p, offsetInFrames, .f32, channels)
|
||||
}
|
||||
|
||||
clip_pcm_frames_f32 :: #force_inline proc "c" (p: [^]f32, frameCount: u64, channels: u32) {
|
||||
clip_samples_f32(p, frameCount*u64(channels))
|
||||
}
|
||||
|
||||
|
||||
data_source :: struct {}
|
||||
|
||||
DATA_SOURCE_SELF_MANAGED_RANGE_AND_LOOP_POINT :: 0x00000001
|
||||
|
||||
data_source_vtable :: struct {
|
||||
onRead: proc "c" (pDataSource: ^data_source, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result,
|
||||
onSeek: proc "c" (pDataSource: ^data_source, frameIndex: u64) -> result,
|
||||
onMap: proc "c" (pDataSource: ^data_source, ppFramesOut: ^rawptr, pFrameCount: ^u64) -> result, /* Returns MA_AT_END if the end has been reached. This should be considered successful. */
|
||||
onUnmap: proc "c" (pDataSource: ^data_source, frameCount: u64) -> result,
|
||||
onGetDataFormat: proc "c" (pDataSource: ^data_source, pFormat: ^format, pChannels: ^u32, pSampleRate: ^u32) -> result,
|
||||
onGetDataFormat: proc "c" (pDataSource: ^data_source, pFormat: ^format, pChannels: ^u32, pSampleRate: ^u32, pChannelMap: [^]channel, channelMapCap: c.size_t) -> result,
|
||||
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,
|
||||
}
|
||||
data_source_callbacks :: data_source_vtable /* TODO: Remove ma_data_source_callbacks in version 0.11. */
|
||||
|
||||
data_source_get_next_proc :: proc "c" (pDataSource: ^data_source) -> ^data_source
|
||||
|
||||
@@ -134,45 +137,43 @@ data_source_config :: struct {
|
||||
}
|
||||
|
||||
data_source_base :: struct {
|
||||
cb: data_source_callbacks, /* TODO: Remove this. */
|
||||
|
||||
/* Variables below are placeholder and not yet used. */
|
||||
vtable: ^data_source_vtable,
|
||||
rangeBegInFrames: u64,
|
||||
rangeEndInFrames: u64, /* Set to -1 for unranged (default). */
|
||||
loopBegInFrames: u64, /* Relative to rangeBegInFrames. */
|
||||
loopEndInFrames: u64, /* Relative to rangeBegInFrames. Set to -1 for the end of the range. */
|
||||
pCurrent: ^data_source, /* When non-NULL, the data source being initialized will act as a proxy and will route all operations to pCurrent. Used in conjunction with pNext/onGetNext for seamless chaining. */
|
||||
pNext: ^data_source, /* When set to NULL, onGetNext will be used. */
|
||||
onGetNext: ^data_source_get_next_proc, /* Will be used when pNext is NULL. If both are NULL, no next will be used. */
|
||||
rangeEndInFrames: u64, /* Set to -1 for unranged (default). */
|
||||
loopBegInFrames: u64, /* Relative to rangeBegInFrames. */
|
||||
loopEndInFrames: u64, /* Relative to rangeBegInFrames. Set to -1 for the end of the range. */
|
||||
pCurrent: ^data_source, /* When non-NULL, the data source being initialized will act as a proxy and will route all operations to pCurrent. Used in conjunction with pNext/onGetNext for seamless chaining. */
|
||||
pNext: ^data_source, /* When set to NULL, onGetNext will be used. */
|
||||
onGetNext: data_source_get_next_proc, /* Will be used when pNext is NULL. If both are NULL, no next will be used. */
|
||||
isLooping: b32, /*atomic*/
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
ma_data_source_config_init :: proc() -> data_source_config ---
|
||||
data_source_config_init :: proc() -> data_source_config ---
|
||||
|
||||
data_source_init :: proc(pConfig: ^data_source_config, pDataSource: ^data_source) -> result ---
|
||||
data_source_uninit :: proc(pDataSource: ^data_source) ---
|
||||
data_source_read_pcm_frames :: proc(pDataSource: ^data_source, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64, loop: b32) -> 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, loop: b32) -> 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_map :: proc(pDataSource: ^data_source, ppFramesOut: ^rawptr, pFrameCount: ^u64) -> result --- /* Returns MA_NOT_IMPLEMENTED if mapping is not supported. */
|
||||
data_source_unmap :: proc(pDataSource: ^data_source, frameCount: u64) -> result --- /* Returns MA_AT_END if the end has been reached. */
|
||||
data_source_get_data_format :: proc(pDataSource: ^data_source, pFormat: ^format, pChannels: ^u32, pSampleRate: ^u32) -> 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. */
|
||||
// #if defined(MA_EXPERIMENTAL__DATA_LOOPING_AND_CHAINING)
|
||||
// MA_API ma_result ma_data_source_set_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 rangeBegInFrames, ma_uint64 rangeEndInFrames);
|
||||
// MA_API void ma_data_source_get_range_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pRangeBegInFrames, ma_uint64* pRangeEndInFrames);
|
||||
// MA_API ma_result ma_data_source_set_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64 loopBegInFrames, ma_uint64 loopEndInFrames);
|
||||
// MA_API void ma_data_source_get_loop_point_in_pcm_frames(ma_data_source* pDataSource, ma_uint64* pLoopBegInFrames, ma_uint64* pLoopEndInFrames);
|
||||
// MA_API ma_result ma_data_source_set_current(ma_data_source* pDataSource, ma_data_source* pCurrentDataSource);
|
||||
// MA_API ma_data_source* ma_data_source_get_current(ma_data_source* pDataSource);
|
||||
// MA_API ma_result ma_data_source_set_next(ma_data_source* pDataSource, ma_data_source* pNextDataSource);
|
||||
// MA_API ma_data_source* ma_data_source_get_next(ma_data_source* pDataSource);
|
||||
// MA_API ma_result ma_data_source_set_next_callback(ma_data_source* pDataSource, ma_data_source_get_next_proc onGetNext);
|
||||
// MA_API ma_data_source_get_next_proc ma_data_source_get_next_callback(ma_data_source* pDataSource);
|
||||
// #endif
|
||||
data_source_init :: proc(pConfig: ^data_source_config, pDataSource: ^data_source) -> result ---
|
||||
data_source_uninit :: proc(pDataSource: ^data_source) ---
|
||||
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_to_pcm_frame :: proc(pDataSource: ^data_source, frameIndex: u64) -> 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_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_cursor_in_seconds :: proc(pDataSource: ^data_source, pCursor: ^f32) -> result ---
|
||||
data_source_get_length_in_seconds :: proc(pDataSource: ^data_source, pLength: ^f32) -> result ---
|
||||
data_source_set_looping :: proc(pDataSource: ^data_source, isLooping: b32) -> result ---
|
||||
data_source_is_looping :: proc(pDataSource: ^data_source) -> b32 ---
|
||||
data_source_set_range_in_pcm_frames :: proc(pDataSource: ^data_source, rangeBegInFrames: u64, rangeEndInFrames: u64) -> result ---
|
||||
data_source_get_range_in_pcm_frames :: proc(pDataSource: ^data_source, pRangeBegInFrames: ^u64, pRangeEndInFrames: ^u64) ---
|
||||
data_source_set_loop_point_in_pcm_frames :: proc(pDataSource: ^data_source, loopBegInFrames: u64, loopEndInFrames: u64) -> result ---
|
||||
data_source_get_loop_point_in_pcm_frames :: proc(pDataSource: ^data_source, pLoopBegInFrames: ^u64, pLoopEndInFrames: ^u64) ---
|
||||
data_source_set_current :: proc(pDataSource: ^data_source, pCurrentDataSource: ^data_source) -> result ---
|
||||
data_source_get_current :: proc(pDataSource: ^data_source) -> ^data_source ---
|
||||
data_source_set_next :: proc(pDataSource: ^data_source, pNextDataSource: ^data_source) -> result ---
|
||||
data_source_get_next :: proc(pDataSource: ^data_source) -> ^data_source ---
|
||||
data_source_set_next_callback :: proc(pDataSource: ^data_source, onGetNext: ^data_source_get_next_proc) -> result ---
|
||||
data_source_get_next_callback :: proc(pDataSource: ^data_source) -> ^data_source_get_next_proc ---
|
||||
}
|
||||
|
||||
|
||||
@@ -180,6 +181,7 @@ audio_buffer_ref :: struct {
|
||||
ds: data_source_base,
|
||||
format: format,
|
||||
channels: u32,
|
||||
sampleRate: u32,
|
||||
cursor: u64,
|
||||
sizeInFrames: u64,
|
||||
pData: rawptr,
|
||||
@@ -204,6 +206,7 @@ foreign lib {
|
||||
audio_buffer_config :: struct {
|
||||
format: format,
|
||||
channels: u32,
|
||||
sampleRate: u32,
|
||||
sizeInFrames: u64,
|
||||
pData: rawptr, /* If set to NULL, will allocate a block of memory for you. */
|
||||
allocationCallbacks: allocation_callbacks,
|
||||
@@ -234,3 +237,65 @@ foreign lib {
|
||||
audio_buffer_get_length_in_pcm_frames :: proc(pAudioBuffer: ^audio_buffer, pLength: ^u64) -> result ---
|
||||
audio_buffer_get_available_frames :: proc(pAudioBuffer: ^audio_buffer, pAvailableFrames: ^u64) -> result ---
|
||||
}
|
||||
|
||||
/*
|
||||
Paged Audio Buffer
|
||||
==================
|
||||
A paged audio buffer is made up of a linked list of pages. It's expandable, but not shrinkable. It
|
||||
can be used for cases where audio data is streamed in asynchronously while allowing data to be read
|
||||
at the same time.
|
||||
|
||||
This is lock-free, but not 100% thread safe. You can append a page and read from the buffer across
|
||||
simultaneously across different threads, however only one thread at a time can append, and only one
|
||||
thread at a time can read and seek.
|
||||
*/
|
||||
paged_audio_buffer_page :: struct {
|
||||
pNext: ^paged_audio_buffer_page, /*atomic*/
|
||||
sizeInFrames: u64,
|
||||
pAudioData: [1]u8,
|
||||
}
|
||||
|
||||
paged_audio_buffer_data :: struct {
|
||||
format: format,
|
||||
channels: u32,
|
||||
head: paged_audio_buffer_page, /* Dummy head for the lock-free algorithm. Always has a size of 0. */
|
||||
pTail: ^paged_audio_buffer_page, /*atomic*/ /* Never null. Initially set to &head. */
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
paged_audio_buffer_data_init :: proc(format: format, channels: u32, pData: ^paged_audio_buffer_data) -> result ---
|
||||
paged_audio_buffer_data_uninit :: proc(pData: ^paged_audio_buffer_data, pAllocationCallbacks: ^allocation_callbacks) ---
|
||||
paged_audio_buffer_data_get_head :: proc(pData: ^paged_audio_buffer_data) -> ^paged_audio_buffer_page ---
|
||||
paged_audio_buffer_data_get_tail :: proc(pData: ^paged_audio_buffer_data) -> ^paged_audio_buffer_page ---
|
||||
paged_audio_buffer_data_get_length_in_pcm_frames :: proc(pData: ^paged_audio_buffer_data, pLength: ^u64) -> result ---
|
||||
paged_audio_buffer_data_allocate_page :: proc(pData: ^paged_audio_buffer_data, pageSizeInFrames: u64, pInitialData: rawptr, pAllocationCallbacks: ^allocation_callbacks, ppPage: ^^paged_audio_buffer_page) -> result ---
|
||||
paged_audio_buffer_data_free_page :: proc(pData: ^paged_audio_buffer_data, pPage: ^paged_audio_buffer_page, pAllocationCallbacks: ^allocation_callbacks) -> result ---
|
||||
paged_audio_buffer_data_append_page :: proc(pData: ^paged_audio_buffer_data, pPage: ^paged_audio_buffer_page) -> result ---
|
||||
paged_audio_buffer_data_allocate_and_append_page :: proc(pData: ^paged_audio_buffer_data, pageSizeInFrames: u32, pInitialData: rawptr, pAllocationCallbacks: ^allocation_callbacks) -> result ---
|
||||
}
|
||||
|
||||
|
||||
paged_audio_buffer_config :: struct {
|
||||
pData: ^paged_audio_buffer_data, /* Must not be null. */
|
||||
}
|
||||
|
||||
paged_audio_buffer :: struct {
|
||||
ds: data_source_base,
|
||||
pData: ^paged_audio_buffer_data, /* Audio data is read from here. Cannot be null. */
|
||||
pCurrent: ^paged_audio_buffer_page,
|
||||
relativeCursor: u64, /* Relative to the current page. */
|
||||
absoluteCursor: u64,
|
||||
}
|
||||
|
||||
@(default_calling_convention="c", link_prefix="ma_")
|
||||
foreign lib {
|
||||
paged_audio_buffer_config_init :: proc(pData: ^paged_audio_buffer_data) -> paged_audio_buffer_config ---
|
||||
|
||||
paged_audio_buffer_init :: proc(pConfig: ^paged_audio_buffer_config, pPagedAudioBuffer: ^paged_audio_buffer) -> result ---
|
||||
paged_audio_buffer_uninit :: proc(pPagedAudioBuffer: ^paged_audio_buffer) ---
|
||||
paged_audio_buffer_read_pcm_frames :: proc(pPagedAudioBuffer: ^paged_audio_buffer, pFramesOut: rawptr, frameCount: u64, pFramesRead: ^u64) -> result --- /* Returns MA_AT_END if no more pages available. */
|
||||
paged_audio_buffer_seek_to_pcm_frame :: proc(pPagedAudioBuffer: ^paged_audio_buffer, frameIndex: u64) -> result ---
|
||||
paged_audio_buffer_get_cursor_in_pcm_frames :: proc(pPagedAudioBuffer: ^paged_audio_buffer, pCursor: ^u64) -> result ---
|
||||
paged_audio_buffer_get_length_in_pcm_frames :: proc(pPagedAudioBuffer: ^paged_audio_buffer, pLength: ^u64) -> result ---
|
||||
}
|
||||
|
||||
10
vendor/miniaudio/vfs.odin
vendored
10
vendor/miniaudio/vfs.odin
vendored
@@ -22,8 +22,10 @@ appropriate for a given situation.
|
||||
vfs :: struct {}
|
||||
vfs_file :: distinct handle
|
||||
|
||||
OPEN_MODE_READ :: 0x00000001
|
||||
OPEN_MODE_WRITE :: 0x00000002
|
||||
open_mode_flags :: enum c.int {
|
||||
READ = 0x00000001,
|
||||
WRITE = 0x00000002,
|
||||
}
|
||||
|
||||
seek_origin :: enum c.int {
|
||||
start,
|
||||
@@ -71,10 +73,6 @@ foreign lib {
|
||||
default_vfs_init :: proc(pVFS: ^default_vfs, pAllocationCallbacks: ^allocation_callbacks) -> result ---
|
||||
}
|
||||
|
||||
resource_format :: enum c.int {
|
||||
wav,
|
||||
}
|
||||
|
||||
encoding_format :: enum c.int {
|
||||
unknown = 0,
|
||||
wav,
|
||||
|
||||
Reference in New Issue
Block a user