diff --git a/vendor/miniaudio/decoding.odin b/vendor/miniaudio/decoding.odin new file mode 100644 index 000000000..916d55172 --- /dev/null +++ b/vendor/miniaudio/decoding.odin @@ -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 --- +} \ No newline at end of file diff --git a/vendor/miniaudio/encoding.odin b/vendor/miniaudio/encoding.odin new file mode 100644 index 000000000..c2cdd7a24 --- /dev/null +++ b/vendor/miniaudio/encoding.odin @@ -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 --- +} \ No newline at end of file diff --git a/vendor/miniaudio/generation.odin b/vendor/miniaudio/generation.odin new file mode 100644 index 000000000..ecf7c60cd --- /dev/null +++ b/vendor/miniaudio/generation.odin @@ -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 --- +} \ No newline at end of file diff --git a/vendor/miniaudio/utilities.odin b/vendor/miniaudio/utilities.odin index f7b485adc..2eeb137e5 100644 --- a/vendor/miniaudio/utilities.odin +++ b/vendor/miniaudio/utilities.odin @@ -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_") diff --git a/vendor/miniaudio/vfs.odin b/vendor/miniaudio/vfs.odin new file mode 100644 index 000000000..e42468224 --- /dev/null +++ b/vendor/miniaudio/vfs.odin @@ -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, +}