Add the remaining of the miniaudio API

This commit is contained in:
gingerBill
2021-09-17 14:09:45 +01:00
parent f38b7ebf42
commit 64f5ba6ba1
5 changed files with 385 additions and 7 deletions

165
vendor/miniaudio/decoding.odin vendored Normal file
View File

@@ -0,0 +1,165 @@
package miniaudio
import "core:c"
when ODIN_OS == "windows" { foreign import lib "../lib/miniaudio.lib" }
/************************************************************************************************************************************************************
Decoding
========
Decoders are independent of the main device API. Decoding APIs can be called freely inside the device's data callback, but they are not thread safe unless
you do your own synchronization.
************************************************************************************************************************************************************/
decoding_backend_config :: struct {
preferredFormat: format,
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
decoding_backend_config_init :: proc(preferredFormat: format) -> 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. */
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_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,
},
},
allocationCallbacks: allocation_callbacks,
encodingFormat: encoding_format,
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,
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,
data: struct #raw_union {
vfs: struct {
pVFS: ^vfs,
file: vfs_file,
},
memory: struct {
pData: [^]u8,
dataSize: c.size_t,
currentReadPos: c.size_t,
}, /* Only used for decoders that were opened against a block of memory. */
},
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
decoder_config_init :: proc(outputFormat: format, outputChannels, outputSampleRate: u32) -> decoder_config ---
decoder_config_init_default :: proc() -> decoder_config ---
decoder_init :: proc(onRead: decoder_read_proc, onSeek: decoder_seek_proc, pUserData: rawptr, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_memory :: proc(pData: rawptr, dataSize: c.size_t, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_vfs :: proc(pVFS: ^vfs, pFilePath: cstring, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_vfs_w :: proc(pVFS: ^vfs, pFilePath: [^]c.wchar_t, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_file :: proc(pFilePath: cstring, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
decoder_init_file_w :: proc(pFilePath: [^]c.wchar_t, pConfig: ^decoder_config, pDecoder: ^decoder) -> result ---
/*
Uninitializes a decoder.
*/
decoder_uninit :: proc(pDecoder: ^decoder) -> result ---
/*
Retrieves the current position of the read cursor in PCM frames.
*/
decoder_get_cursor_in_pcm_frames :: proc(pDecoder: ^decoder, pCursor: ^u64) -> result ---
/*
Retrieves the length of the decoder in PCM frames.
Do not call this on streams of an undefined length, such as internet radio.
If the length is unknown or an error occurs, 0 will be returned.
This will always return 0 for Vorbis decoders. This is due to a limitation with stb_vorbis in push mode which is what miniaudio
uses internally.
For MP3's, this will decode the entire file. Do not call this in time critical scenarios.
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 ---
/*
Retrieves the number of frames that can be read before reaching the end.
This calls `ma_decoder_get_length_in_pcm_frames()` so you need to be aware of the rules for that function, in
particular ensuring you do not call it on streams of an undefined length, such as internet radio.
If the total length of the decoder cannot be retrieved, such as with Vorbis decoders, `MA_NOT_IMPLEMENTED` will be
returned.
*/
decoder_get_available_frames :: proc(pDecoder: ^decoder, pAvailableFrames: ^u64) -> result ---
/*
Helper for opening and decoding a file into a heap allocated block of memory. Free the returned pointer with ma_free(). On input,
pConfig should be set to what you want. On output it will be set to what you got.
*/
decode_from_vfs :: proc(pVFS: ^vfs, pFilePath: cstring, pConfig: ^decoder_config, pFrameCountOut: ^u64, ppPCMFramesOut: ^rawptr) -> result ---
decode_file :: proc(pFilePath: cstring, pConfig: ^decoder_config, pFrameCountOut: ^u64, ppPCMFramesOut: ^rawptr) -> result ---
decode_memory :: proc(pData: rawptr, dataSize: c.size_t, pConfig: ^decoder_config, pFrameCountOut: ^u64, ppPCMFramesOut: ^rawptr) -> result ---
}

51
vendor/miniaudio/encoding.odin vendored Normal file
View File

@@ -0,0 +1,51 @@
package miniaudio
import "core:c"
when ODIN_OS == "windows" { foreign import lib "../lib/miniaudio.lib" }
/************************************************************************************************************************************************************
Encoding
========
Encoders do not perform any format conversion for you. If your target format does not support the format, and error will be returned.
************************************************************************************************************************************************************/
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_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_config :: struct {
resourceFormat: resource_format,
format: format,
channels: u32,
sampleRate: u32,
allocationCallbacks: allocation_callbacks,
}
encoder :: struct {
config: encoder_config,
onWrite: encoder_write_proc,
onSeek: encoder_seek_proc,
onInit: encoder_init_proc,
onUninit: encoder_uninit_proc,
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(). */
}
@(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_init :: proc(onWrite: encoder_write_proc, onSeek: encoder_seek_proc, pUserData: rawptr, 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 ---
}

84
vendor/miniaudio/generation.odin vendored Normal file
View File

@@ -0,0 +1,84 @@
package miniaudio
import "core:c"
when ODIN_OS == "windows" { foreign import lib "../lib/miniaudio.lib" }
waveform_type :: enum c.int {
sine,
square,
triangle,
sawtooth,
}
waveform_config :: struct {
format: format,
channels: u32,
sampleRate: u32,
type: waveform_type,
amplitude: f64,
frequency: f64,
}
waveform :: struct {
ds: data_source_base,
config: waveform_config,
advance: f64,
time: f64,
}
noise_type :: enum c. int {
white,
pink,
brownian,
}
noise_config :: struct {
format: format,
channels: u32,
type: noise_type,
seed: i32,
amplitude: f64,
duplicateChannels: b32,
}
noise :: struct {
ds: data_source_vtable,
config: noise_config,
lcg: lcg,
state: struct #raw_union {
pink: struct {
bin: [MAX_CHANNELS][16]f64,
accumulation: [MAX_CHANNELS]f64,
counter: [MAX_CHANNELS]u32,
},
brownian: struct {
accumulation: [MAX_CHANNELS]f64,
},
},
}
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
waveform_config_init :: proc(format: format, channels: u32, sampleRate: u32, type: waveform_type, amplitude: f64, frequency: f64) -> waveform_config ---
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_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 ---
waveform_set_type :: proc(pWaveform: ^waveform, type: waveform_type) -> result ---
waveform_set_sample_rate :: proc(pWaveform: ^waveform, sampleRate: u32) -> result ---
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 ---
}

View File

@@ -196,18 +196,18 @@ foreign lib {
audio_buffer_config :: struct {
format: format,
channels: u32,
sizeInFrames: u64,
pData: rawptr, /* If set to NULL, will allocate a block of memory for you. */
format: format,
channels: u32,
sizeInFrames: u64,
pData: rawptr, /* If set to NULL, will allocate a block of memory for you. */
allocationCallbacks: allocation_callbacks,
}
audio_buffer :: struct {
ref: audio_buffer_ref,
ref: audio_buffer_ref,
allocationCallbacks: allocation_callbacks,
ownsData: b32, /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
_pExtraData: [1]u8, /* For allocating a buffer with the memory located directly after the other memory of the structure. */
ownsData: b32, /* Used to control whether or not miniaudio owns the data buffer. If set to true, pData will be freed in ma_audio_buffer_uninit(). */
_pExtraData: [1]u8, /* For allocating a buffer with the memory located directly after the other memory of the structure. */
}
@(default_calling_convention="c", link_prefix="ma_")

78
vendor/miniaudio/vfs.odin vendored Normal file
View File

@@ -0,0 +1,78 @@
package miniaudio
import "core:c"
when ODIN_OS == "windows" { foreign import lib "../lib/miniaudio.lib" }
/************************************************************************************************************************************************************
VFS
===
The VFS object (virtual file system) is what's used to customize file access. This is useful in cases where stdio FILE* based APIs may not be entirely
appropriate for a given situation.
************************************************************************************************************************************************************/
vfs :: struct {}
vfs_file :: distinct handle
OPEN_MODE_READ :: 0x00000001
OPEN_MODE_WRITE :: 0x00000002
seek_origin :: enum c.int {
start,
current,
end, /* Not used by decoders. */
}
file_info :: struct {
sizeInBytes: u64,
}
vfs_callbacks :: struct {
onOpen: proc "c" (pVFS: ^vfs, pFilePath: cstring, openMode: u32, pFile: ^vfs_file) -> result,
onOpenW: proc "c" (pVFS: ^vfs, pFilePath: [^]c.wchar_t, openMode: u32, pFile: ^vfs_file) -> result,
onClose: proc "c" (pVFS: ^vfs, file: vfs_file) -> result,
onRead: proc "c" (pVFS: ^vfs, file: vfs_file, pDst: rawptr, sizeInBytes: c.size_t, pBytesRead: ^c.size_t) -> result,
onWrite: proc "c" (pVFS: ^vfs, file: vfs_file, pSrc: rawptr, sizeInBytes: c.size_t, pBytesWritten: ^c.size_t) -> result,
onSeek: proc "c" (pVFS: ^vfs, file: vfs_file, offset: i64, origin: seek_origin) -> result,
onTell: proc "c" (pVFS: ^vfs, file: vfs_file, pCursor: ^i64) -> result,
onInfo: proc "c" (pVFS: ^vfs, file: vfs_file, pInfo: ^file_info) -> result,
}
default_vfs :: struct {
cb: vfs_callbacks,
allocationCallbacks: allocation_callbacks, /* Only used for the wchar_t version of open() on non-Windows platforms. */
}
ma_read_proc :: proc "c" (pUserData: rawptr, pBufferOut: rawptr, bytesToRead: c.size_t, pBytesRead: ^c.size_t) -> result
ma_seek_proc :: proc "c" (pUserData: rawptr, offset: i64, origin: seek_origin) -> result
ma_tell_proc :: proc "c" (pUserData: rawptr, pCursor: ^i64) -> result
@(default_calling_convention="c", link_prefix="ma_")
foreign lib {
vfs_open :: proc(pVFS: ^vfs, pFilePath: cstring, openMode: u32, pFile: ^vfs_file) -> result ---
vfs_open_w :: proc(pVFS: ^vfs, pFilePath: [^]c.wchar_t, openMode: u32, pFile: ^vfs_file) -> result ---
vfs_close :: proc(pVFS: ^vfs, file: vfs_file) -> result ---
vfs_read :: proc(pVFS: ^vfs, file: vfs_file, pDst: rawptr, sizeInBytes: c.size_t, pBytesRead: ^c.size_t) -> result ---
vfs_write :: proc(pVFS: ^vfs, file: vfs_file, pSrc: rawptr, sizeInBytes: c.size_t, pBytesWritten: ^c.size_t) -> result ---
vfs_seek :: proc(pVFS: ^vfs, file: vfs_file, offset: i64, origin: seek_origin) -> result ---
vfs_tell :: proc(pVFS: ^vfs, file: vfs_file, pCursor: ^i64) -> result ---
vfs_info :: proc(pVFS: ^vfs, file: vfs_file, pInfo: ^file_info) -> result ---
vfs_open_and_read_file :: proc(pVFS: ^vfs, pFilePath: cstring, ppData: ^rawptr, pSize: ^c.size_t, pAllocationCallbacks: ^allocation_callbacks) -> result ---
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,
flac,
mp3,
vorbis,
}