From 7634cbeb224a064868084639aa557be0f521743e Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 8 Aug 2018 18:26:05 +0200 Subject: [PATCH] Updated mini_al Corrected issue with sound playing (pop sound at the end) --- release/include/raylib.h | 8 +- release/libs/win32/mingw32/libraylib.a | Bin 1237446 -> 1239504 bytes src/external/mini_al.c | 6 +- src/external/mini_al.h | 3762 +++++++++++++++++------- 4 files changed, 2780 insertions(+), 996 deletions(-) diff --git a/release/include/raylib.h b/release/include/raylib.h index a8e399da1..8d1389f73 100644 --- a/release/include/raylib.h +++ b/release/include/raylib.h @@ -71,6 +71,8 @@ #ifndef RAYLIB_H #define RAYLIB_H +#include // Required for: va_list - Only used by TraceLogCallback + #if defined(_WIN32) && defined(BUILD_LIBTYPE_SHARED) #define RLAPI __declspec(dllexport) // We are building raylib as a Win32 shared library (.dll) #elif defined(_WIN32) && defined(USE_LIBTYPE_SHARED) @@ -727,6 +729,9 @@ typedef enum { HMD_SONY_PSVR } VrDeviceType; +// Callbacks to be implemented by users +typedef void (*TraceLogCallback)(int msgType, const char *text, va_list args); + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -779,7 +784,7 @@ RLAPI Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Returns a r RLAPI Vector2 GetWorldToScreen(Vector3 position, Camera camera); // Returns the screen space position for a 3d world space position RLAPI Matrix GetCameraMatrix(Camera camera); // Returns camera transform matrix (view matrix) -// Timing-related functions +// timing-related functions RLAPI void SetTargetFPS(int fps); // Set target FPS (maximum) RLAPI int GetFPS(void); // Returns current FPS RLAPI float GetFrameTime(void); // Returns time in seconds for last frame drawn @@ -796,6 +801,7 @@ RLAPI Color Fade(Color color, float alpha); // Color fade- RLAPI void ShowLogo(void); // Activate raylib logo at startup (can be done with flags) RLAPI void SetConfigFlags(unsigned char flags); // Setup window configuration flags (view FLAGS) RLAPI void SetTraceLog(unsigned char types); // Enable trace log message types (bit flags based) +RLAPI void SetTraceLogCallback(TraceLogCallback callback); // Set a trace log callback to enable custom logging bypassing raylib's one RLAPI void TraceLog(int logType, const char *text, ...); // Show trace log messages (LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_DEBUG) RLAPI void TakeScreenshot(const char *fileName); // Takes a screenshot of current screen (saved a .png) RLAPI int GetRandomValue(int min, int max); // Returns a random value between min and max (both included) diff --git a/release/libs/win32/mingw32/libraylib.a b/release/libs/win32/mingw32/libraylib.a index c27c819e30eda1abd3ba8a2beaff6bb0cb6757d9..5c64af95a4bf922fee3ff4c59270c4ffa913e530 100644 GIT binary patch delta 213193 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

>F6#o94S>sr!evw8vW0Njnco>yp!@2$f53L# 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 delta 208002 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

~88ygb?!_8B#S?=DrdFu8{{`Sp`3=B6< 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 // For size_t. #ifndef MAL_HAS_STDINT @@ -479,122 +416,6 @@ typedef mal_uint16 wchar_t; #endif -// Thread priorties should be ordered such that the default priority of the worker thread is 0. -typedef enum -{ - mal_thread_priority_idle = -5, - mal_thread_priority_lowest = -4, - mal_thread_priority_low = -3, - mal_thread_priority_normal = -2, - mal_thread_priority_high = -1, - mal_thread_priority_highest = 0, - mal_thread_priority_realtime = 1, - mal_thread_priority_default = 0 -} mal_thread_priority; - -typedef struct -{ - mal_context* pContext; - - union - { -#ifdef MAL_WIN32 - struct - { - /*HANDLE*/ mal_handle hThread; - } win32; -#endif -#ifdef MAL_POSIX - struct - { - pthread_t thread; - } posix; -#endif - - int _unused; - }; -} mal_thread; - -typedef struct -{ - mal_context* pContext; - - union - { -#ifdef MAL_WIN32 - struct - { - /*HANDLE*/ mal_handle hMutex; - } win32; -#endif -#ifdef MAL_POSIX - struct - { - pthread_mutex_t mutex; - } posix; -#endif - - int _unused; - }; -} mal_mutex; - -typedef struct -{ - mal_context* pContext; - - union - { -#ifdef MAL_WIN32 - struct - { - /*HANDLE*/ mal_handle hEvent; - } win32; -#endif -#ifdef MAL_POSIX - struct - { - pthread_mutex_t mutex; - pthread_cond_t condition; - mal_uint32 value; - } posix; -#endif - - int _unused; - }; -} mal_event; - - -#define MAL_MAX_PERIODS_DSOUND 4 -#define MAL_MAX_PERIODS_OPENAL 4 - -// Standard sample rates. -#define MAL_SAMPLE_RATE_8000 8000 -#define MAL_SAMPLE_RATE_11025 11025 -#define MAL_SAMPLE_RATE_16000 16000 -#define MAL_SAMPLE_RATE_22050 22050 -#define MAL_SAMPLE_RATE_24000 24000 -#define MAL_SAMPLE_RATE_32000 32000 -#define MAL_SAMPLE_RATE_44100 44100 -#define MAL_SAMPLE_RATE_48000 48000 -#define MAL_SAMPLE_RATE_88200 88200 -#define MAL_SAMPLE_RATE_96000 96000 -#define MAL_SAMPLE_RATE_176400 176400 -#define MAL_SAMPLE_RATE_192000 192000 -#define MAL_SAMPLE_RATE_352800 352800 -#define MAL_SAMPLE_RATE_384000 384000 - -#define MAL_MIN_PCM_SAMPLE_SIZE_IN_BYTES 1 // For simplicity, mini_al does not support PCM samples that are not byte aligned. -#define MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES 8 -#define MAL_MIN_CHANNELS 1 -#define MAL_MAX_CHANNELS 32 -#define MAL_MIN_SAMPLE_RATE MAL_SAMPLE_RATE_8000 -#define MAL_MAX_SAMPLE_RATE MAL_SAMPLE_RATE_384000 -#define MAL_SRC_SINC_MIN_WINDOW_WIDTH 2 -#define MAL_SRC_SINC_MAX_WINDOW_WIDTH 32 -#define MAL_SRC_SINC_DEFAULT_WINDOW_WIDTH 16 -#define MAL_SRC_SINC_LOOKUP_TABLE_RESOLUTION 8 -#define MAL_SRC_INPUT_BUFFER_SIZE_IN_SAMPLES 256 - typedef mal_uint8 mal_channel; #define MAL_CHANNEL_NONE 0 #define MAL_CHANNEL_MONO 1 @@ -688,38 +509,33 @@ typedef int mal_result; #define MAL_ACCESS_DENIED -32 #define MAL_TOO_LARGE -33 -typedef void (* mal_log_proc) (mal_context* pContext, mal_device* pDevice, const char* message); -typedef void (* mal_recv_proc)(mal_device* pDevice, mal_uint32 frameCount, const void* pSamples); -typedef mal_uint32 (* mal_send_proc)(mal_device* pDevice, mal_uint32 frameCount, void* pSamples); -typedef void (* mal_stop_proc)(mal_device* pDevice); +// Standard sample rates. +#define MAL_SAMPLE_RATE_8000 8000 +#define MAL_SAMPLE_RATE_11025 11025 +#define MAL_SAMPLE_RATE_16000 16000 +#define MAL_SAMPLE_RATE_22050 22050 +#define MAL_SAMPLE_RATE_24000 24000 +#define MAL_SAMPLE_RATE_32000 32000 +#define MAL_SAMPLE_RATE_44100 44100 +#define MAL_SAMPLE_RATE_48000 48000 +#define MAL_SAMPLE_RATE_88200 88200 +#define MAL_SAMPLE_RATE_96000 96000 +#define MAL_SAMPLE_RATE_176400 176400 +#define MAL_SAMPLE_RATE_192000 192000 +#define MAL_SAMPLE_RATE_352800 352800 +#define MAL_SAMPLE_RATE_384000 384000 -typedef enum -{ - mal_backend_null, - mal_backend_wasapi, - mal_backend_dsound, - mal_backend_winmm, - mal_backend_alsa, - mal_backend_pulseaudio, - mal_backend_jack, - mal_backend_coreaudio, - mal_backend_oss, - mal_backend_opensl, - mal_backend_openal, - mal_backend_sdl -} mal_backend; - -typedef enum -{ - mal_device_type_playback, - mal_device_type_capture -} mal_device_type; - -typedef enum -{ - mal_share_mode_shared = 0, - mal_share_mode_exclusive, -} mal_share_mode; +#define MAL_MIN_PCM_SAMPLE_SIZE_IN_BYTES 1 // For simplicity, mini_al does not support PCM samples that are not byte aligned. +#define MAL_MAX_PCM_SAMPLE_SIZE_IN_BYTES 8 +#define MAL_MIN_CHANNELS 1 +#define MAL_MAX_CHANNELS 32 +#define MAL_MIN_SAMPLE_RATE MAL_SAMPLE_RATE_8000 +#define MAL_MAX_SAMPLE_RATE MAL_SAMPLE_RATE_384000 +#define MAL_SRC_SINC_MIN_WINDOW_WIDTH 2 +#define MAL_SRC_SINC_MAX_WINDOW_WIDTH 32 +#define MAL_SRC_SINC_DEFAULT_WINDOW_WIDTH 32 +#define MAL_SRC_SINC_LOOKUP_TABLE_RESOLUTION 8 +#define MAL_SRC_INPUT_BUFFER_SIZE_IN_SAMPLES 256 typedef enum { @@ -766,6 +582,7 @@ typedef enum mal_standard_channel_map_rfc3551, // Based off AIFF. mal_standard_channel_map_flac, mal_standard_channel_map_vorbis, + mal_standard_channel_map_sndio, // www.sndio.org/tips.html mal_standard_channel_map_default = mal_standard_channel_map_microsoft } mal_standard_channel_map; @@ -775,72 +592,6 @@ typedef enum mal_performance_profile_conservative } mal_performance_profile; -typedef union -{ -#ifdef MAL_SUPPORT_WASAPI - wchar_t wasapi[64]; // WASAPI uses a wchar_t string for identification. -#endif -#ifdef MAL_SUPPORT_DSOUND - mal_uint8 dsound[16]; // DirectSound uses a GUID for identification. -#endif -#ifdef MAL_SUPPORT_WINMM - /*UINT_PTR*/ mal_uint32 winmm; // When creating a device, WinMM expects a Win32 UINT_PTR for device identification. In practice it's actually just a UINT. -#endif -#ifdef MAL_SUPPORT_ALSA - char alsa[256]; // ALSA uses a name string for identification. -#endif -#ifdef MAL_SUPPORT_PULSEAUDIO - char pulse[256]; // PulseAudio uses a name string for identification. -#endif -#ifdef MAL_SUPPORT_JACK - int jack; // JACK always uses default devices. -#endif -#ifdef MAL_SUPPORT_COREAUDIO - char coreaudio[256]; // Core Audio uses a string for identification. -#endif -#ifdef MAL_SUPPORT_OSS - char oss[64]; // "dev/dsp0", etc. "dev/dsp" for the default device. -#endif -#ifdef MAL_SUPPORT_OPENSL - mal_uint32 opensl; // OpenSL|ES uses a 32-bit unsigned integer for identification. -#endif -#ifdef MAL_SUPPORT_OPENAL - char openal[256]; // OpenAL seems to use human-readable device names as the ID. -#endif -#ifdef MAL_SUPPORT_SDL - int sdl; // SDL devices are identified with an index. -#endif -#ifdef MAL_SUPPORT_NULL - int nullbackend; // The null backend uses an integer for device IDs. -#endif -} mal_device_id; - -typedef struct -{ - // Basic info. This is the only information guaranteed to be filled in during device enumeration. - mal_device_id id; - char name[256]; - - // Detailed info. As much of this is filled as possible with mal_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 mini_al'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 mal_context_enumerate_devices() or mal_context_get_devices(). - mal_uint32 formatCount; - mal_format formats[mal_format_count]; - mal_uint32 minChannels; - mal_uint32 maxChannels; - mal_uint32 minSampleRate; - mal_uint32 maxSampleRate; -} mal_device_info; - -typedef struct -{ - mal_int64 counter; -} mal_timer; - - typedef struct mal_format_converter mal_format_converter; typedef mal_uint32 (* mal_format_converter_read_proc) (mal_format_converter* pConverter, mal_uint32 frameCount, void* pFramesOut, void* pUserData); @@ -929,6 +680,12 @@ typedef enum mal_src_sinc_window_function_default = mal_src_sinc_window_function_hann } mal_src_sinc_window_function; +typedef struct +{ + mal_src_sinc_window_function windowFunction; + mal_uint32 windowWidth; +} mal_src_config_sinc; + typedef struct { mal_uint32 sampleRateIn; @@ -944,11 +701,7 @@ typedef struct void* pUserData; union { - struct - { - mal_src_sinc_window_function windowFunction; - mal_uint32 windowWidth; - } sinc; + mal_src_config_sinc sinc; }; } mal_src_config; @@ -1007,11 +760,7 @@ typedef struct void* pUserData; union { - struct - { - mal_src_sinc_window_function windowFunction; - mal_uint32 windowWidth; - } sinc; + mal_src_config_sinc sinc; }; } mal_dsp_config; @@ -1033,6 +782,637 @@ MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_dsp }; +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DATA CONVERSION +// =============== +// +// This section contains the APIs for data conversion. You will find everything here for channel mapping, sample format conversion, resampling, etc. +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Channel Maps +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Helper for retrieving a standard channel map. +void mal_get_standard_channel_map(mal_standard_channel_map standardChannelMap, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS]); + +// Copies a channel map. +void mal_channel_map_copy(mal_channel* pOut, const mal_channel* pIn, mal_uint32 channels); + + +// Determines whether or not a channel map is valid. +// +// A blank channel map is valid (all channels set to MAL_CHANNEL_NONE). The way a blank channel map is handled is context specific, but +// 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 +mal_bool32 mal_channel_map_valid(mal_uint32 channels, const mal_channel channelMap[MAL_MAX_CHANNELS]); + +// Helper for comparing two channel maps for equality. +// +// This assumes the channel count is the same between the two. +mal_bool32 mal_channel_map_equal(mal_uint32 channels, const mal_channel channelMapA[MAL_MAX_CHANNELS], const mal_channel channelMapB[MAL_MAX_CHANNELS]); + +// Helper for determining if a channel map is blank (all channels set to MAL_CHANNEL_NONE). +mal_bool32 mal_channel_map_blank(mal_uint32 channels, const mal_channel channelMap[MAL_MAX_CHANNELS]); + +// Helper for determining whether or not a channel is present in the given channel map. +mal_bool32 mal_channel_map_contains_channel_position(mal_uint32 channels, const mal_channel channelMap[MAL_MAX_CHANNELS], mal_channel channelPosition); + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Format Conversion +// ================= +// The format converter serves two purposes: +// 1) Conversion between data formats (u8 to f32, etc.) +// 2) Interleaving and deinterleaving +// +// When initializing a converter, you specify the input and output formats (u8, s16, etc.) and read callbacks. There are two read callbacks - one for +// interleaved input data (onRead) and another for deinterleaved input data (onReadDeinterleaved). You implement whichever is most convenient for you. You +// can implement both, but it's not recommended as it just introduces unnecessary complexity. +// +// To read data as interleaved samples, use mal_format_converter_read(). Otherwise use mal_format_converter_read_deinterleaved(). +// +// Dithering +// --------- +// The format converter also supports dithering. Dithering can be set using ditherMode variable in the config, like so. +// +// pConfig->ditherMode = mal_dither_mode_rectangle; +// +// The different dithering modes include the following, in order of efficiency: +// - None: mal_dither_mode_none +// - Rectangle: mal_dither_mode_rectangle +// - Triangle: mal_dither_mode_triangle +// +// Note that even if the dither mode is set to something other than mal_dither_mode_none, it will be ignored for conversions where dithering is not needed. +// Dithering is available for the following conversions: +// - s16 -> u8 +// - s24 -> u8 +// - s32 -> u8 +// - f32 -> u8 +// - s24 -> s16 +// - s32 -> s16 +// - f32 -> s16 +// +// Note that it is not an error to pass something other than mal_dither_mode_none for conversions where dither is not used. It will just be ignored. +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Initializes a format converter. +mal_result mal_format_converter_init(const mal_format_converter_config* pConfig, mal_format_converter* pConverter); + +// Reads data from the format converter as interleaved channels. +mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint64 frameCount, void* pFramesOut, void* pUserData); + +// Reads data from the format converter as deinterleaved channels. +mal_uint64 mal_format_converter_read_deinterleaved(mal_format_converter* pConverter, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData); + + +// Helper for initializing a format converter config. +mal_format_converter_config mal_format_converter_config_init_new(void); +mal_format_converter_config mal_format_converter_config_init(mal_format formatIn, mal_format formatOut, mal_uint32 channels, mal_format_converter_read_proc onRead, void* pUserData); +mal_format_converter_config mal_format_converter_config_init_deinterleaved(mal_format formatIn, mal_format formatOut, mal_uint32 channels, mal_format_converter_read_deinterleaved_proc onReadDeinterleaved, void* pUserData); + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Channel Routing +// =============== +// There are two main things you can do with the channel router: +// 1) Rearrange channels +// 2) Convert from one channel count to another +// +// Channel Rearrangement +// --------------------- +// A simple example of channel rearrangement may be swapping the left and right channels in a stereo stream. To do this you just pass in the same channel +// count for both the input and output with channel maps that contain the same channels (in a different order). +// +// Channel Conversion +// ------------------ +// The channel router can also convert from one channel count to another, such as converting a 5.1 stream to stero. When changing the channel count, the +// router will first perform a 1:1 mapping of channel positions that are present in both the input and output channel maps. The second thing it will do +// is distribute the input mono channel (if any) across all output channels, excluding any None and LFE channels. If there is an output mono channel, all +// input channels will be averaged, excluding any None and LFE channels. +// +// The last case to consider is when a channel position in the input channel map is not present in the output channel map, and vice versa. In this case the +// channel router will perform a blend of other related channels to produce an audible channel. There are several blending modes. +// 1) Simple +// Unmatched channels are silenced. +// 2) Planar Blending +// Channels are blended based on a set of planes that each speaker emits audio from. +// +// Planar Blending +// --------------- +// In this mode, channel positions are associated with a set of planes where the channel conceptually emits audio from. An example is the front/left speaker. +// This speaker is positioned to the front of the listener, so you can think of it as emitting audio from the front plane. It is also positioned to the left +// of the listener so you can think of it as also emitting audio from the left plane. Now consider the (unrealistic) situation where the input channel map +// contains only the front/left channel position, but the output channel map contains both the front/left and front/center channel. When deciding on the audio +// data to send to the front/center speaker (which has no 1:1 mapping with an input channel) we need to use some logic based on our available input channel +// positions. +// +// As mentioned earlier, our front/left speaker is, conceptually speaking, emitting audio from the front _and_ the left planes. Similarly, the front/center +// speaker is emitting audio from _only_ the front plane. What these two channels have in common is that they are both emitting audio from the front plane. +// Thus, it makes sense that the front/center speaker should receive some contribution from the front/left channel. How much contribution depends on their +// planar relationship (thus the name of this blending technique). +// +// Because the front/left channel is emitting audio from two planes (front and left), you can think of it as though it's willing to dedicate 50% of it's total +// volume to each of it's planes (a channel position emitting from 1 plane would be willing to given 100% of it's total volume to that plane, and a channel +// position emitting from 3 planes would be willing to given 33% of it's total volume to each plane). Similarly, the front/center speaker is emitting audio +// from only one plane so you can think of it as though it's willing to _take_ 100% of it's volume from front plane emissions. Now, since the front/left +// channel is willing to _give_ 50% of it's total volume to the front plane, and the front/center speaker is willing to _take_ 100% of it's total volume +// from the front, you can imagine that 50% of the front/left speaker will be given to the front/center speaker. +// +// Usage +// ----- +// To use the channel router you need to specify three things: +// 1) The input channel count and channel map +// 2) The output channel count and channel map +// 3) The mixing mode to use in the case where a 1:1 mapping is unavailable +// +// Note that input and output data is always deinterleaved 32-bit floating point. +// +// Initialize the channel router with mal_channel_router_init(). You will need to pass in a config object which specifies the input and output configuration, +// mixing mode and a callback for sending data to the router. This callback will be called when input data needs to be sent to the router for processing. +// +// Read data from the channel router with mal_channel_router_read_deinterleaved(). Output data is always 32-bit floating point. +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Initializes a channel router where it is assumed that the input data is non-interleaved. +mal_result mal_channel_router_init(const mal_channel_router_config* pConfig, mal_channel_router* pRouter); + +// Reads data from the channel router as deinterleaved channels. +mal_uint64 mal_channel_router_read_deinterleaved(mal_channel_router* pRouter, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData); + +// Helper for initializing a channel router config. +mal_channel_router_config mal_channel_router_config_init(mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], mal_channel_mix_mode mixingMode, mal_channel_router_read_deinterleaved_proc onRead, void* pUserData); + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Sample Rate Conversion +// ====================== +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Initializes a sample rate conversion object. +mal_result mal_src_init(const mal_src_config* pConfig, mal_src* pSRC); + +// Dynamically adjusts the input sample rate. +// +// DEPRECATED. Use mal_src_set_sample_rate() instead. +mal_result mal_src_set_input_sample_rate(mal_src* pSRC, mal_uint32 sampleRateIn); + +// Dynamically adjusts the output sample rate. +// +// This is useful for dynamically adjust pitch. Keep in mind, however, that this will speed up or slow down the sound. If this +// is not acceptable you will need to use your own algorithm. +// +// DEPRECATED. Use mal_src_set_sample_rate() instead. +mal_result mal_src_set_output_sample_rate(mal_src* pSRC, mal_uint32 sampleRateOut); + +// Dynamically adjusts the sample rate. +// +// This is useful for dynamically adjust pitch. Keep in mind, however, that this will speed up or slow down the sound. If this +// is not acceptable you will need to use your own algorithm. +mal_result mal_src_set_sample_rate(mal_src* pSRC, mal_uint32 sampleRateIn, mal_uint32 sampleRateOut); + +// Reads a number of frames. +// +// Returns the number of frames actually read. +mal_uint64 mal_src_read_deinterleaved(mal_src* pSRC, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData); + + +// Helper for creating a sample rate conversion config. +mal_src_config mal_src_config_init_new(void); +mal_src_config mal_src_config_init(mal_uint32 sampleRateIn, mal_uint32 sampleRateOut, mal_uint32 channels, mal_src_read_deinterleaved_proc onReadDeinterleaved, void* pUserData); + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DSP +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// Initializes a DSP object. +mal_result mal_dsp_init(const mal_dsp_config* pConfig, mal_dsp* pDSP); + +// Dynamically adjusts the input sample rate. +// +// This will fail is the DSP was not initialized with allowDynamicSampleRate. +// +// DEPRECATED. Use mal_dsp_set_sample_rate() instead. +mal_result mal_dsp_set_input_sample_rate(mal_dsp* pDSP, mal_uint32 sampleRateOut); + +// Dynamically adjusts the output sample rate. +// +// This is useful for dynamically adjust pitch. Keep in mind, however, that this will speed up or slow down the sound. If this +// is not acceptable you will need to use your own algorithm. +// +// This will fail is the DSP was not initialized with allowDynamicSampleRate. +// +// DEPRECATED. Use mal_dsp_set_sample_rate() instead. +mal_result mal_dsp_set_output_sample_rate(mal_dsp* pDSP, mal_uint32 sampleRateOut); + +// Dynamically adjusts the output sample rate. +// +// This is useful for dynamically adjust pitch. Keep in mind, however, that this will speed up or slow down the sound. If this +// is not acceptable you will need to use your own algorithm. +// +// This will fail is the DSP was not initialized with allowDynamicSampleRate. +mal_result mal_dsp_set_sample_rate(mal_dsp* pDSP, mal_uint32 sampleRateIn, mal_uint32 sampleRateOut); + + +// Reads a number of frames and runs them through the DSP processor. +mal_uint64 mal_dsp_read(mal_dsp* pDSP, mal_uint64 frameCount, void* pFramesOut, void* pUserData); + +// Helper for initializing a mal_dsp_config object. +mal_dsp_config mal_dsp_config_init_new(void); +mal_dsp_config mal_dsp_config_init(mal_format formatIn, mal_uint32 channelsIn, mal_uint32 sampleRateIn, mal_format formatOut, mal_uint32 channelsOut, mal_uint32 sampleRateOut, mal_dsp_read_proc onRead, void* pUserData); +mal_dsp_config mal_dsp_config_init_ex(mal_format formatIn, mal_uint32 channelsIn, mal_uint32 sampleRateIn, mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_format formatOut, mal_uint32 channelsOut, mal_uint32 sampleRateOut, mal_channel channelMapOut[MAL_MAX_CHANNELS], mal_dsp_read_proc onRead, void* pUserData); + + +// High-level helper for doing a full format conversion in one go. Returns the number of output frames. Call this with pOut set to NULL to +// determine the required size of the output buffer. +// +// A return value of 0 indicates an error. +// +// This function is useful for one-off bulk conversions, but if you're streaming data you should use the DSP APIs instead. +mal_uint64 mal_convert_frames(void* pOut, mal_format formatOut, mal_uint32 channelsOut, mal_uint32 sampleRateOut, const void* pIn, mal_format formatIn, mal_uint32 channelsIn, mal_uint32 sampleRateIn, mal_uint64 frameCountIn); +mal_uint64 mal_convert_frames_ex(void* pOut, mal_format formatOut, mal_uint32 channelsOut, mal_uint32 sampleRateOut, mal_channel channelMapOut[MAL_MAX_CHANNELS], const void* pIn, mal_format formatIn, mal_uint32 channelsIn, mal_uint32 sampleRateIn, mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint64 frameCountIn); + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Miscellaneous Helpers +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// malloc(). Calls MAL_MALLOC(). +void* mal_malloc(size_t sz); + +// realloc(). Calls MAL_REALLOC(). +void* mal_realloc(void* p, size_t sz); + +// free(). Calls MAL_FREE(). +void mal_free(void* p); + +// Performs an aligned malloc, with the assumption that the alignment is a power of 2. +void* mal_aligned_malloc(size_t sz, size_t alignment); + +// Free's an aligned malloc'd buffer. +void mal_aligned_free(void* p); + +// Retrieves a friendly name for a format. +const char* mal_get_format_name(mal_format format); + +// Blends two frames in floating point format. +void mal_blend_f32(float* pOut, float* pInA, float* pInB, float factor, mal_uint32 channels); + +// Retrieves the size of a sample in bytes for the given format. +// +// This API is efficient and is implemented using a lookup table. +// +// Thread Safety: SAFE +// This is API is pure. +mal_uint32 mal_get_bytes_per_sample(mal_format format); +static MAL_INLINE mal_uint32 mal_get_bytes_per_frame(mal_format format, mal_uint32 channels) { return mal_get_bytes_per_sample(format) * channels; } + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Format Conversion +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +void mal_pcm_u8_to_s16(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_u8_to_s24(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_u8_to_s32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_u8_to_f32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s16_to_u8(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s16_to_s24(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s16_to_s32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s16_to_f32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s24_to_u8(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s24_to_s16(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s24_to_s32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s24_to_f32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s32_to_u8(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s32_to_s16(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s32_to_s24(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_s32_to_f32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_f32_to_u8(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_f32_to_s16(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_f32_to_s24(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_f32_to_s32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); +void mal_pcm_convert(void* pOut, mal_format formatOut, const void* pIn, mal_format formatIn, mal_uint64 sampleCount, mal_dither_mode ditherMode); + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DEVICE I/O +// ========== +// +// This section contains the APIs for device playback and capture. Here is where you'll find mal_device_init(), etc. +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#ifndef MAL_NO_DEVICE_IO +// Some backends are only supported on certain platforms. +#if defined(MAL_WIN32) + #define MAL_SUPPORT_WASAPI + #if defined(MAL_WIN32_DESKTOP) // DirectSound and WinMM backends are only supported on desktop's. + #define MAL_SUPPORT_DSOUND + #define MAL_SUPPORT_WINMM + #define MAL_SUPPORT_JACK // JACK is technically supported on Windows, but I don't know how many people use it in practice... + #endif +#endif +#if defined(MAL_UNIX) + #if defined(MAL_LINUX) + #if !defined(MAL_ANDROID) // ALSA is not supported on Android. + #define MAL_SUPPORT_ALSA + #endif + #endif + #if !defined(MAL_BSD) && !defined(MAL_ANDROID) && !defined(MAL_EMSCRIPTEN) + #define MAL_SUPPORT_PULSEAUDIO + #define MAL_SUPPORT_JACK + #endif + #if defined(MAL_ANDROID) + #define MAL_SUPPORT_OPENSL + #endif + #if defined(__OpenBSD__) // <-- Change this to "#if defined(MAL_BSD)" to enable sndio on all BSD flavors. + #define MAL_SUPPORT_SNDIO // sndio is only supported on OpenBSD for now. May be expanded later if there's demand. + #endif + #if defined(__NetBSD__) + #define MAL_SUPPORT_AUDIOIO // Only support audioio on platforms with known support. + #endif + #if defined(__FreeBSD__) || defined(__DragonFly__) + #define MAL_SUPPORT_OSS // Only support OSS on specific platforms with known support. + #endif +#endif +#if defined(MAL_APPLE) + #define MAL_SUPPORT_COREAUDIO +#endif + +#define MAL_SUPPORT_SDL // All platforms support SDL. + +// Explicitly disable OpenAL and Null backends for Emscripten because they both use a background thread which is not properly supported right now. +#if !defined(MAL_EMSCRIPTEN) +#define MAL_SUPPORT_OPENAL +#define MAL_SUPPORT_NULL // All platforms support the null backend. +#endif + + +#if !defined(MAL_NO_WASAPI) && defined(MAL_SUPPORT_WASAPI) + #define MAL_ENABLE_WASAPI +#endif +#if !defined(MAL_NO_DSOUND) && defined(MAL_SUPPORT_DSOUND) + #define MAL_ENABLE_DSOUND +#endif +#if !defined(MAL_NO_WINMM) && defined(MAL_SUPPORT_WINMM) + #define MAL_ENABLE_WINMM +#endif +#if !defined(MAL_NO_ALSA) && defined(MAL_SUPPORT_ALSA) + #define MAL_ENABLE_ALSA +#endif +#if !defined(MAL_NO_PULSEAUDIO) && defined(MAL_SUPPORT_PULSEAUDIO) + #define MAL_ENABLE_PULSEAUDIO +#endif +#if !defined(MAL_NO_JACK) && defined(MAL_SUPPORT_JACK) + #define MAL_ENABLE_JACK +#endif +#if !defined(MAL_NO_COREAUDIO) && defined(MAL_SUPPORT_COREAUDIO) + #define MAL_ENABLE_COREAUDIO +#endif +#if !defined(MAL_NO_SNDIO) && defined(MAL_SUPPORT_SNDIO) + #define MAL_ENABLE_SNDIO +#endif +#if !defined(MAL_NO_AUDIOIO) && defined(MAL_SUPPORT_AUDIOIO) + #define MAL_ENABLE_AUDIOIO +#endif +#if !defined(MAL_NO_OSS) && defined(MAL_SUPPORT_OSS) + #define MAL_ENABLE_OSS +#endif +#if !defined(MAL_NO_OPENSL) && defined(MAL_SUPPORT_OPENSL) + #define MAL_ENABLE_OPENSL +#endif +#if !defined(MAL_NO_OPENAL) && defined(MAL_SUPPORT_OPENAL) + #define MAL_ENABLE_OPENAL +#endif +#if !defined(MAL_NO_SDL) && defined(MAL_SUPPORT_SDL) + #define MAL_ENABLE_SDL +#endif +#if !defined(MAL_NO_NULL) && defined(MAL_SUPPORT_NULL) + #define MAL_ENABLE_NULL +#endif + + +typedef enum +{ + mal_backend_null, + mal_backend_wasapi, + mal_backend_dsound, + mal_backend_winmm, + mal_backend_alsa, + mal_backend_pulseaudio, + mal_backend_jack, + mal_backend_coreaudio, + mal_backend_sndio, + mal_backend_audioio, + mal_backend_oss, + mal_backend_opensl, + mal_backend_openal, + mal_backend_sdl +} mal_backend; + +// Thread priorties should be ordered such that the default priority of the worker thread is 0. +typedef enum +{ + mal_thread_priority_idle = -5, + mal_thread_priority_lowest = -4, + mal_thread_priority_low = -3, + mal_thread_priority_normal = -2, + mal_thread_priority_high = -1, + mal_thread_priority_highest = 0, + mal_thread_priority_realtime = 1, + mal_thread_priority_default = 0 +} mal_thread_priority; + +typedef struct +{ + mal_context* pContext; + + union + { +#ifdef MAL_WIN32 + struct + { + /*HANDLE*/ mal_handle hThread; + } win32; +#endif +#ifdef MAL_POSIX + struct + { + pthread_t thread; + } posix; +#endif + + int _unused; + }; +} mal_thread; + +typedef struct +{ + mal_context* pContext; + + union + { +#ifdef MAL_WIN32 + struct + { + /*HANDLE*/ mal_handle hMutex; + } win32; +#endif +#ifdef MAL_POSIX + struct + { + pthread_mutex_t mutex; + } posix; +#endif + + int _unused; + }; +} mal_mutex; + +typedef struct +{ + mal_context* pContext; + + union + { +#ifdef MAL_WIN32 + struct + { + /*HANDLE*/ mal_handle hEvent; + } win32; +#endif +#ifdef MAL_POSIX + struct + { + pthread_mutex_t mutex; + pthread_cond_t condition; + mal_uint32 value; + } posix; +#endif + + int _unused; + }; +} mal_event; + + +#define MAL_MAX_PERIODS_DSOUND 4 +#define MAL_MAX_PERIODS_OPENAL 4 + +typedef void (* mal_log_proc) (mal_context* pContext, mal_device* pDevice, const char* message); +typedef void (* mal_recv_proc)(mal_device* pDevice, mal_uint32 frameCount, const void* pSamples); +typedef mal_uint32 (* mal_send_proc)(mal_device* pDevice, mal_uint32 frameCount, void* pSamples); +typedef void (* mal_stop_proc)(mal_device* pDevice); + +typedef enum +{ + mal_device_type_playback, + mal_device_type_capture +} mal_device_type; + +typedef enum +{ + mal_share_mode_shared = 0, + mal_share_mode_exclusive, +} mal_share_mode; + +typedef union +{ +#ifdef MAL_SUPPORT_WASAPI + wchar_t wasapi[64]; // WASAPI uses a wchar_t string for identification. +#endif +#ifdef MAL_SUPPORT_DSOUND + mal_uint8 dsound[16]; // DirectSound uses a GUID for identification. +#endif +#ifdef MAL_SUPPORT_WINMM + /*UINT_PTR*/ mal_uint32 winmm; // When creating a device, WinMM expects a Win32 UINT_PTR for device identification. In practice it's actually just a UINT. +#endif +#ifdef MAL_SUPPORT_ALSA + char alsa[256]; // ALSA uses a name string for identification. +#endif +#ifdef MAL_SUPPORT_PULSEAUDIO + char pulse[256]; // PulseAudio uses a name string for identification. +#endif +#ifdef MAL_SUPPORT_JACK + int jack; // JACK always uses default devices. +#endif +#ifdef MAL_SUPPORT_COREAUDIO + char coreaudio[256]; // Core Audio uses a string for identification. +#endif +#ifdef MAL_SUPPORT_SNDIO + char sndio[256]; // "snd/0", etc. +#endif +#ifdef MAL_SUPPORT_AUDIOIO + char audioio[256]; // "/dev/audio", etc. +#endif +#ifdef MAL_SUPPORT_OSS + char oss[64]; // "dev/dsp0", etc. "dev/dsp" for the default device. +#endif +#ifdef MAL_SUPPORT_OPENSL + mal_uint32 opensl; // OpenSL|ES uses a 32-bit unsigned integer for identification. +#endif +#ifdef MAL_SUPPORT_OPENAL + char openal[256]; // OpenAL seems to use human-readable device names as the ID. +#endif +#ifdef MAL_SUPPORT_SDL + int sdl; // SDL devices are identified with an index. +#endif +#ifdef MAL_SUPPORT_NULL + int nullbackend; // The null backend uses an integer for device IDs. +#endif +} mal_device_id; + +typedef struct +{ + // Basic info. This is the only information guaranteed to be filled in during device enumeration. + mal_device_id id; + char name[256]; + + // Detailed info. As much of this is filled as possible with mal_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 mini_al'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 mal_context_enumerate_devices() or mal_context_get_devices(). + mal_uint32 formatCount; + mal_format formats[mal_format_count]; + mal_uint32 minChannels; + mal_uint32 maxChannels; + mal_uint32 minSampleRate; + mal_uint32 maxSampleRate; +} mal_device_info; + +typedef struct +{ + mal_int64 counter; +} mal_timer; + typedef struct { mal_format format; @@ -1299,6 +1679,35 @@ struct mal_context mal_proc AudioUnitRender; } coreaudio; #endif +#ifdef MAL_SUPPORT_SNDIO + struct + { + mal_handle sndioSO; + mal_proc sio_open; + mal_proc sio_close; + mal_proc sio_setpar; + mal_proc sio_getpar; + mal_proc sio_getcap; + mal_proc sio_start; + mal_proc sio_stop; + mal_proc sio_read; + mal_proc sio_write; + mal_proc sio_onmove; + mal_proc sio_nfds; + mal_proc sio_pollfd; + mal_proc sio_revents; + mal_proc sio_eof; + mal_proc sio_setvol; + mal_proc sio_onvol; + mal_proc sio_initpar; + } sndio; +#endif +#ifdef MAL_SUPPORT_AUDIOIO + struct + { + int _unused; + } audioio; +#endif #ifdef MAL_SUPPORT_OSS struct { @@ -1591,6 +2000,24 @@ MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_device /*AudioBufferList**/ mal_ptr pAudioBufferList; // Only used for input devices. } coreaudio; #endif +#ifdef MAL_SUPPORT_SNDIO + struct + { + mal_ptr handle; + mal_uint32 fragmentSizeInFrames; + mal_bool32 breakFromMainLoop; + void* pIntermediaryBuffer; + } sndio; +#endif +#ifdef MAL_SUPPORT_AUDIOIO + struct + { + int fd; + mal_uint32 fragmentSizeInFrames; + mal_bool32 breakFromMainLoop; + void* pIntermediaryBuffer; + } audioio; +#endif #ifdef MAL_SUPPORT_OSS struct { @@ -1663,7 +2090,9 @@ MAL_ALIGNED_STRUCT(MAL_SIMD_ALIGNMENT) mal_device // - WASAPI // - DirectSound // - WinMM -// - Core Audio (macOS, iOS) +// - Core Audio (Apple) +// - sndio +// - audioio // - OSS // - PulseAudio // - ALSA @@ -1941,15 +2370,6 @@ mal_bool32 mal_device_is_started(mal_device* pDevice); // This is calculated from constant values which are set at initialization time and never change. mal_uint32 mal_device_get_buffer_size_in_bytes(mal_device* pDevice); -// Retrieves the size of a sample in bytes for the given format. -// -// This API is efficient and is implemented using a lookup table. -// -// Thread Safety: SAFE -// This is API is pure. -mal_uint32 mal_get_bytes_per_sample(mal_format format); -static MAL_INLINE mal_uint32 mal_get_bytes_per_frame(mal_format format, mal_uint32 channels) { return mal_get_bytes_per_sample(format) * channels; } - // Helper function for initializing a mal_context_config object. mal_context_config mal_context_config_init(mal_log_proc onLog); @@ -2044,236 +2464,6 @@ static MAL_INLINE mal_device_config mal_device_config_init_playback_ex(mal_forma static MAL_INLINE mal_device_config mal_device_config_init_playback(mal_format format, mal_uint32 channels, mal_uint32 sampleRate, mal_send_proc onSendCallback) { return mal_device_config_init_playback_ex(format, channels, sampleRate, NULL, onSendCallback); } -// Helper for retrieving a standard channel map. -void mal_get_standard_channel_map(mal_standard_channel_map standardChannelMap, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS]); - -// Copies a channel map. -void mal_channel_map_copy(mal_channel* pOut, const mal_channel* pIn, mal_uint32 channels); - - -// Determines whether or not a channel map is valid. -// -// A blank channel map is valid (all channels set to MAL_CHANNEL_NONE). The way a blank channel map is handled is context specific, but -// 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 -mal_bool32 mal_channel_map_valid(mal_uint32 channels, const mal_channel channelMap[MAL_MAX_CHANNELS]); - -// Helper for comparing two channel maps for equality. -// -// This assumes the channel count is the same between the two. -mal_bool32 mal_channel_map_equal(mal_uint32 channels, const mal_channel channelMapA[MAL_MAX_CHANNELS], const mal_channel channelMapB[MAL_MAX_CHANNELS]); - -// Helper for determining if a channel map is blank (all channels set to MAL_CHANNEL_NONE). -mal_bool32 mal_channel_map_blank(mal_uint32 channels, const mal_channel channelMap[MAL_MAX_CHANNELS]); - -// Helper for determining whether or not a channel is present in the given channel map. -mal_bool32 mal_channel_map_contains_channel_position(mal_uint32 channels, const mal_channel channelMap[MAL_MAX_CHANNELS], mal_channel channelPosition); - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Format Conversion -// ================= -// The format converter serves two purposes: -// 1) Conversion between data formats (u8 to f32, etc.) -// 2) Interleaving and deinterleaving -// -// When initializing a converter, you specify the input and output formats (u8, s16, etc.) and read callbacks. There are two read callbacks - one for -// interleaved input data (onRead) and another for deinterleaved input data (onReadDeinterleaved). You implement whichever is most convenient for you. You -// can implement both, but it's not recommended as it just introduces unnecessary complexity. -// -// To read data as interleaved samples, use mal_format_converter_read(). Otherwise use mal_format_converter_read_deinterleaved(). -// -// Dithering -// --------- -// The format converter also supports dithering. Dithering can be set using ditherMode variable in the config, like so. -// -// pConfig->ditherMode = mal_dither_mode_rectangle; -// -// The different dithering modes include the following, in order of efficiency: -// - None: mal_dither_mode_none -// - Rectangle: mal_dither_mode_rectangle -// - Triangle: mal_dither_mode_triangle -// -// Note that even if the dither mode is set to something other than mal_dither_mode_none, it will be ignored for conversions where dithering is not needed. -// Dithering is available for the following conversions: -// - s16 -> u8 -// - s24 -> u8 -// - s32 -> u8 -// - f32 -> u8 -// - s24 -> s16 -// - s32 -> s16 -// - f32 -> s16 -// -// Note that it is not an error to pass something other than mal_dither_mode_none for conversions where dither is not used. It will just be ignored. -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// Initializes a format converter. -mal_result mal_format_converter_init(const mal_format_converter_config* pConfig, mal_format_converter* pConverter); - -// Reads data from the format converter as interleaved channels. -mal_uint64 mal_format_converter_read(mal_format_converter* pConverter, mal_uint64 frameCount, void* pFramesOut, void* pUserData); - -// Reads data from the format converter as deinterleaved channels. -mal_uint64 mal_format_converter_read_deinterleaved(mal_format_converter* pConverter, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData); - - -// Helper for initializing a format converter config. -mal_format_converter_config mal_format_converter_config_init_new(void); -mal_format_converter_config mal_format_converter_config_init(mal_format formatIn, mal_format formatOut, mal_uint32 channels, mal_format_converter_read_proc onRead, void* pUserData); -mal_format_converter_config mal_format_converter_config_init_deinterleaved(mal_format formatIn, mal_format formatOut, mal_uint32 channels, mal_format_converter_read_deinterleaved_proc onReadDeinterleaved, void* pUserData); - - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Channel Routing -// =============== -// There are two main things you can do with the channel router: -// 1) Rearrange channels -// 2) Convert from one channel count to another -// -// Channel Rearrangement -// --------------------- -// A simple example of channel rearrangement may be swapping the left and right channels in a stereo stream. To do this you just pass in the same channel -// count for both the input and output with channel maps that contain the same channels (in a different order). -// -// Channel Conversion -// ------------------ -// The channel router can also convert from one channel count to another, such as converting a 5.1 stream to stero. When changing the channel count, the -// router will first perform a 1:1 mapping of channel positions that are present in both the input and output channel maps. The second thing it will do -// is distribute the input mono channel (if any) across all output channels, excluding any None and LFE channels. If there is an output mono channel, all -// input channels will be averaged, excluding any None and LFE channels. -// -// The last case to consider is when a channel position in the input channel map is not present in the output channel map, and vice versa. In this case the -// channel router will perform a blend of other related channels to produce an audible channel. There are several blending modes. -// 1) Simple -// Unmatched channels are silenced. -// 2) Planar Blending -// Channels are blended based on a set of planes that each speaker emits audio from. -// -// Planar Blending -// --------------- -// In this mode, channel positions are associated with a set of planes where the channel conceptually emits audio from. An example is the front/left speaker. -// This speaker is positioned to the front of the listener, so you can think of it as emitting audio from the front plane. It is also positioned to the left -// of the listener so you can think of it as also emitting audio from the left plane. Now consider the (unrealistic) situation where the input channel map -// contains only the front/left channel position, but the output channel map contains both the front/left and front/center channel. When deciding on the audio -// data to send to the front/center speaker (which has no 1:1 mapping with an input channel) we need to use some logic based on our available input channel -// positions. -// -// As mentioned earlier, our front/left speaker is, conceptually speaking, emitting audio from the front _and_ the left planes. Similarly, the front/center -// speaker is emitting audio from _only_ the front plane. What these two channels have in common is that they are both emitting audio from the front plane. -// Thus, it makes sense that the front/center speaker should receive some contribution from the front/left channel. How much contribution depends on their -// planar relationship (thus the name of this blending technique). -// -// Because the front/left channel is emitting audio from two planes (front and left), you can think of it as though it's willing to dedicate 50% of it's total -// volume to each of it's planes (a channel position emitting from 1 plane would be willing to given 100% of it's total volume to that plane, and a channel -// position emitting from 3 planes would be willing to given 33% of it's total volume to each plane). Similarly, the front/center speaker is emitting audio -// from only one plane so you can think of it as though it's willing to _take_ 100% of it's volume from front plane emissions. Now, since the front/left -// channel is willing to _give_ 50% of it's total volume to the front plane, and the front/center speaker is willing to _take_ 100% of it's total volume -// from the front, you can imagine that 50% of the front/left speaker will be given to the front/center speaker. -// -// Usage -// ----- -// To use the channel router you need to specify three things: -// 1) The input channel count and channel map -// 2) The output channel count and channel map -// 3) The mixing mode to use in the case where a 1:1 mapping is unavailable -// -// Note that input and output data is always deinterleaved 32-bit floating point. -// -// Initialize the channel router with mal_channel_router_init(). You will need to pass in a config object which specifies the input and output configuration, -// mixing mode and a callback for sending data to the router. This callback will be called when input data needs to be sent to the router for processing. -// -// Read data from the channel router with mal_channel_router_read_deinterleaved(). Output data is always 32-bit floating point. -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// Initializes a channel router where it is assumed that the input data is non-interleaved. -mal_result mal_channel_router_init(const mal_channel_router_config* pConfig, mal_channel_router* pRouter); - -// Reads data from the channel router as deinterleaved channels. -mal_uint64 mal_channel_router_read_deinterleaved(mal_channel_router* pRouter, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData); - -// Helper for initializing a channel router config. -mal_channel_router_config mal_channel_router_config_init(mal_uint32 channelsIn, const mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint32 channelsOut, const mal_channel channelMapOut[MAL_MAX_CHANNELS], mal_channel_mix_mode mixingMode, mal_channel_router_read_deinterleaved_proc onRead, void* pUserData); - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Sample Rate Conversion -// ====================== -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// Initializes a sample rate conversion object. -mal_result mal_src_init(const mal_src_config* pConfig, mal_src* pSRC); - -// Dynamically adjusts the input sample rate. -mal_result mal_src_set_input_sample_rate(mal_src* pSRC, mal_uint32 sampleRateIn); - -// Dynamically adjusts the output sample rate. -// -// This is useful for dynamically adjust pitch. Keep in mind, however, that this will speed up or slow down the sound. If this -// is not acceptable you will need to use your own algorithm. -mal_result mal_src_set_output_sample_rate(mal_src* pSRC, mal_uint32 sampleRateOut); - -// Reads a number of frames. -// -// Returns the number of frames actually read. -mal_uint64 mal_src_read_deinterleaved(mal_src* pSRC, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData); - - -// Helper for creating a sample rate conversion config. -mal_src_config mal_src_config_init_new(void); -mal_src_config mal_src_config_init(mal_uint32 sampleRateIn, mal_uint32 sampleRateOut, mal_uint32 channels, mal_src_read_deinterleaved_proc onReadDeinterleaved, void* pUserData); - - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// DSP -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// Initializes a DSP object. -mal_result mal_dsp_init(const mal_dsp_config* pConfig, mal_dsp* pDSP); - -// Dynamically adjusts the input sample rate. -// -// This will fail is the DSP was not initialized with allowDynamicSampleRate. -mal_result mal_dsp_set_input_sample_rate(mal_dsp* pDSP, mal_uint32 sampleRateOut); - -// Dynamically adjusts the output sample rate. -// -// This is useful for dynamically adjust pitch. Keep in mind, however, that this will speed up or slow down the sound. If this -// is not acceptable you will need to use your own algorithm. -// -// This will fail is the DSP was not initialized with allowDynamicSampleRate. -mal_result mal_dsp_set_output_sample_rate(mal_dsp* pDSP, mal_uint32 sampleRateOut); - -// Reads a number of frames and runs them through the DSP processor. -mal_uint64 mal_dsp_read(mal_dsp* pDSP, mal_uint64 frameCount, void* pFramesOut, void* pUserData); - -// Helper for initializing a mal_dsp_config object. -mal_dsp_config mal_dsp_config_init_new(void); -mal_dsp_config mal_dsp_config_init(mal_format formatIn, mal_uint32 channelsIn, mal_uint32 sampleRateIn, mal_format formatOut, mal_uint32 channelsOut, mal_uint32 sampleRateOut, mal_dsp_read_proc onRead, void* pUserData); -mal_dsp_config mal_dsp_config_init_ex(mal_format formatIn, mal_uint32 channelsIn, mal_uint32 sampleRateIn, mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_format formatOut, mal_uint32 channelsOut, mal_uint32 sampleRateOut, mal_channel channelMapOut[MAL_MAX_CHANNELS], mal_dsp_read_proc onRead, void* pUserData); - - -// High-level helper for doing a full format conversion in one go. Returns the number of output frames. Call this with pOut set to NULL to -// determine the required size of the output buffer. -// -// A return value of 0 indicates an error. -// -// This function is useful for one-off bulk conversions, but if you're streaming data you should use the DSP APIs instead. -mal_uint64 mal_convert_frames(void* pOut, mal_format formatOut, mal_uint32 channelsOut, mal_uint32 sampleRateOut, const void* pIn, mal_format formatIn, mal_uint32 channelsIn, mal_uint32 sampleRateIn, mal_uint64 frameCountIn); -mal_uint64 mal_convert_frames_ex(void* pOut, mal_format formatOut, mal_uint32 channelsOut, mal_uint32 sampleRateOut, mal_channel channelMapOut[MAL_MAX_CHANNELS], const void* pIn, mal_format formatIn, mal_uint32 channelsIn, mal_uint32 sampleRateIn, mal_channel channelMapIn[MAL_MAX_CHANNELS], mal_uint64 frameCountIn); - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -2296,37 +2486,9 @@ void mal_mutex_lock(mal_mutex* pMutex); void mal_mutex_unlock(mal_mutex* pMutex); - -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Miscellaneous Helpers -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// malloc(). Calls MAL_MALLOC(). -void* mal_malloc(size_t sz); - -// realloc(). Calls MAL_REALLOC(). -void* mal_realloc(void* p, size_t sz); - -// free(). Calls MAL_FREE(). -void mal_free(void* p); - -// Performs an aligned malloc, with the assumption that the alignment is a power of 2. -void* mal_aligned_malloc(size_t sz, size_t alignment); - -// Free's an aligned malloc'd buffer. -void mal_aligned_free(void* p); - // Retrieves a friendly name for a backend. const char* mal_get_backend_name(mal_backend backend); -// Retrieves a friendly name for a format. -const char* mal_get_format_name(mal_format format); - -// Blends two frames in floating point format. -void mal_blend_f32(float* pOut, float* pInA, float* pInB, float factor, mal_uint32 channels); - // Calculates a scaling factor relative to speed of the system. // // This could be useful for dynamically determining the size of a device's internal buffer based on the speed of the system. @@ -2342,35 +2504,9 @@ mal_uint32 mal_scale_buffer_size(mal_uint32 baseBufferSize, float scale); // Calculates a buffer size in frames for the specified performance profile and scale factor. mal_uint32 mal_calculate_default_buffer_size_in_frames(mal_performance_profile performanceProfile, mal_uint32 sampleRate, float scale); +#endif // MAL_NO_DEVICE_IO -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Format Conversion -// -////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void mal_pcm_u8_to_s16(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_u8_to_s24(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_u8_to_s32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_u8_to_f32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s16_to_u8(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s16_to_s24(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s16_to_s32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s16_to_f32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s24_to_u8(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s24_to_s16(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s24_to_s32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s24_to_f32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s32_to_u8(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s32_to_s16(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s32_to_s24(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_s32_to_f32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_f32_to_u8(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_f32_to_s16(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_f32_to_s24(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_f32_to_s32(void* pOut, const void* pIn, mal_uint64 count, mal_dither_mode ditherMode); -void mal_pcm_convert(void* pOut, mal_format formatOut, const void* pIn, mal_format formatIn, mal_uint64 sampleCount, mal_dither_mode ditherMode); - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -2395,10 +2531,17 @@ typedef mal_result (* mal_decoder_uninit_proc) (mal_decoder* pDecoder); typedef struct { - mal_format format; // Set to 0 or mal_format_unknown to use the stream's internal format. - mal_uint32 channels; // Set to 0 to use the stream's internal channels. - mal_uint32 sampleRate; // Set to 0 to use the stream's internal sample rate. + mal_format format; // Set to 0 or mal_format_unknown to use the stream's internal format. + mal_uint32 channels; // Set to 0 to use the stream's internal channels. + mal_uint32 sampleRate; // Set to 0 to use the stream's internal sample rate. mal_channel channelMap[MAL_MAX_CHANNELS]; + mal_channel_mix_mode channelMixMode; + mal_dither_mode ditherMode; + mal_src_algorithm srcAlgorithm; + union + { + mal_src_config_sinc sinc; + } src; } mal_decoder_config; struct mal_decoder @@ -2660,9 +2803,23 @@ mal_uint64 mal_sine_wave_read(mal_sine_wave* pSignWave, mal_uint64 count, float* #elif (defined(__GNUC__) || defined(__clang__)) && !defined(MAL_ANDROID) static MAL_INLINE void mal_cpuid(int info[4], int fid) { - __asm__ __volatile__ ( - "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0) - ); + // It looks like the -fPIC option uses the ebx register which GCC complains about. We can work around this by just using a different register, the + // specific register of which I'm letting the compiler decide on. The "k" prefix is used to specify a 32-bit register. The {...} syntax is for + // supporting different assembly dialects. + // + // What's basically happening is that we're saving and restoring the ebx register manually. + #if defined(DRFLAC_X86) && defined(__PIC__) + __asm__ __volatile__ ( + "xchg{l} {%%}ebx, %k1;" + "cpuid;" + "xchg{l} {%%}ebx, %k1;" + : "=a"(info[0]), "=&r"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0) + ); + #else + __asm__ __volatile__ ( + "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(fid), "c"(0) + ); + #endif } static MAL_INLINE unsigned long long mal_xgetbv(int reg) @@ -2834,6 +2991,23 @@ static MAL_INLINE mal_bool32 mal_has_neon() } +static MAL_INLINE mal_bool32 mal_is_little_endian() +{ +#if defined(MAL_X86) || defined(MAL_X64) + return MAL_TRUE; +#else + int n = 1; + return (*(char*)&n) == 1; +#endif +} + +static MAL_INLINE mal_bool32 mal_is_big_endian() +{ + return !mal_is_little_endian(); +} + + + #ifndef MAL_PI #define MAL_PI 3.14159265358979323846264f #endif @@ -2847,136 +3021,6 @@ static MAL_INLINE mal_bool32 mal_has_neon() #define MAL_TAU_D 6.28318530717958647693 #endif -// Unfortunately using runtime linking for pthreads causes problems. This has occurred for me when testing on FreeBSD. When -// using runtime linking, deadlocks can occur (for me it happens when loading data from fread()). It turns out that doing -// compile-time linking fixes this. I'm not sure why this happens, but the safest way I can think of to fix this is to simply -// disable runtime linking by default. To enable runtime linking, #define this before the implementation of this file. I am -// not officially supporting this, but I'm leaving it here in case it's useful for somebody, somewhere. -//#define MAL_USE_RUNTIME_LINKING_FOR_PTHREAD - -// Disable run-time linking on certain backends. -#ifndef MAL_NO_RUNTIME_LINKING - #if defined(MAL_ANDROID) || defined(MAL_EMSCRIPTEN) - #define MAL_NO_RUNTIME_LINKING - #endif -#endif - -// Check if we have the necessary development packages for each backend at the top so we can use this to determine whether or not -// certain unused functions and variables can be excluded from the build to avoid warnings. -#ifdef MAL_ENABLE_WASAPI - #define MAL_HAS_WASAPI // Every compiler should support WASAPI -#endif -#ifdef MAL_ENABLE_DSOUND - #define MAL_HAS_DSOUND // Every compiler should support DirectSound. -#endif -#ifdef MAL_ENABLE_WINMM - #define MAL_HAS_WINMM // Every compiler I'm aware of supports WinMM. -#endif -#ifdef MAL_ENABLE_ALSA - #define MAL_HAS_ALSA - #ifdef MAL_NO_RUNTIME_LINKING - #ifdef __has_include - #if !__has_include() - #undef MAL_HAS_ALSA - #endif - #endif - #endif -#endif -#ifdef MAL_ENABLE_PULSEAUDIO - #define MAL_HAS_PULSEAUDIO // Development packages are unnecessary for PulseAudio. - #ifdef MAL_NO_RUNTIME_LINKING - #ifdef __has_include - #if !__has_include() - #undef MAL_HAS_PULSEAUDIO - #endif - #endif - #endif -#endif -#ifdef MAL_ENABLE_JACK - #define MAL_HAS_JACK - #ifdef MAL_NO_RUNTIME_LINKING - #ifdef __has_include - #if !__has_include() - #undef MAL_HAS_JACK - #endif - #endif - #endif -#endif -#ifdef MAL_ENABLE_COREAUDIO - #define MAL_HAS_COREAUDIO -#endif -#ifdef MAL_ENABLE_OSS - #define MAL_HAS_OSS // OSS is the only supported backend for Unix and BSD, so it must be present else this library is useless. -#endif -#ifdef MAL_ENABLE_OPENSL - #define MAL_HAS_OPENSL // OpenSL is the only supported backend for Android. It must be present. -#endif -#ifdef MAL_ENABLE_OPENAL - #define MAL_HAS_OPENAL - #ifdef MAL_NO_RUNTIME_LINKING - #ifdef __has_include - #if !__has_include() - #undef MAL_HAS_OPENAL - #endif - #endif - #endif -#endif -#ifdef MAL_ENABLE_SDL - #define MAL_HAS_SDL - - // SDL headers are necessary if using compile-time linking. - #ifdef MAL_NO_RUNTIME_LINKING - #ifdef __has_include - #ifdef MAL_EMSCRIPTEN - #if !__has_include() - #undef MAL_HAS_SDL - #endif - #else - #if !__has_include() - #undef MAL_HAS_SDL - #endif - #endif - #endif - #endif -#endif -#ifdef MAL_ENABLE_NULL - #define MAL_HAS_NULL // Everything supports the null backend. -#endif - - -#ifdef MAL_WIN32 - #define MAL_THREADCALL WINAPI - typedef unsigned long mal_thread_result; -#else - #define MAL_THREADCALL - typedef void* mal_thread_result; -#endif -typedef mal_thread_result (MAL_THREADCALL * mal_thread_entry_proc)(void* pData); - -#ifdef MAL_WIN32 -typedef HRESULT (WINAPI * MAL_PFN_CoInitializeEx)(LPVOID pvReserved, DWORD dwCoInit); -typedef void (WINAPI * MAL_PFN_CoUninitialize)(); -typedef HRESULT (WINAPI * MAL_PFN_CoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv); -typedef void (WINAPI * MAL_PFN_CoTaskMemFree)(LPVOID pv); -typedef HRESULT (WINAPI * MAL_PFN_PropVariantClear)(PROPVARIANT *pvar); -typedef int (WINAPI * MAL_PFN_StringFromGUID2)(const GUID* const rguid, LPOLESTR lpsz, int cchMax); - -typedef HWND (WINAPI * MAL_PFN_GetForegroundWindow)(); -typedef HWND (WINAPI * MAL_PFN_GetDesktopWindow)(); - -// Microsoft documents these APIs as returning LSTATUS, but the Win32 API shipping with some compilers do not define it. It's just a LONG. -typedef LONG (WINAPI * MAL_PFN_RegOpenKeyExA)(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); -typedef LONG (WINAPI * MAL_PFN_RegCloseKey)(HKEY hKey); -typedef LONG (WINAPI * MAL_PFN_RegQueryValueExA)(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); -#endif - - -#define MAL_STATE_UNINITIALIZED 0 -#define MAL_STATE_STOPPED 1 // The device's default state after initialization. -#define MAL_STATE_STARTED 2 // The worker thread is in it's main loop waiting for the driver to request or deliver audio data. -#define MAL_STATE_STARTING 3 // Transitioning from a stopped state to started. -#define MAL_STATE_STOPPING 4 // Transitioning from a started state to stopped. - // The default format when mal_format_unknown (0) is requested when initializing a device. #ifndef MAL_DEFAULT_FORMAT @@ -3032,8 +3076,8 @@ mal_uint32 g_malStandardSampleRatePriorities[] = { }; mal_format g_malFormatPriorities[] = { - mal_format_f32, // Most common - mal_format_s16, + mal_format_s16, // Most common + mal_format_f32, //mal_format_s24_32, // Clean alignment mal_format_s32, @@ -3043,8 +3087,7 @@ mal_format g_malFormatPriorities[] = { mal_format_u8 // Low quality }; -#define MAL_DEFAULT_PLAYBACK_DEVICE_NAME "Default Playback Device" -#define MAL_DEFAULT_CAPTURE_DEVICE_NAME "Default Capture Device" + /////////////////////////////////////////////////////////////////////////////// // @@ -3569,6 +3612,207 @@ void mal_split_buffer(void* pBuffer, size_t bufferSize, size_t splitCount, size_ #endif +mal_uint32 mal_get_standard_sample_rate_priority_index(mal_uint32 sampleRate) // Lower = higher priority +{ + for (mal_uint32 i = 0; i < mal_countof(g_malStandardSampleRatePriorities); ++i) { + if (g_malStandardSampleRatePriorities[i] == sampleRate) { + return i; + } + } + + return (mal_uint32)-1; +} + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// DEVICE I/O +// ========== +// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#ifndef MAL_NO_DEVICE_IO +// Unfortunately using runtime linking for pthreads causes problems. This has occurred for me when testing on FreeBSD. When +// using runtime linking, deadlocks can occur (for me it happens when loading data from fread()). It turns out that doing +// compile-time linking fixes this. I'm not sure why this happens, but the safest way I can think of to fix this is to simply +// disable runtime linking by default. To enable runtime linking, #define this before the implementation of this file. I am +// not officially supporting this, but I'm leaving it here in case it's useful for somebody, somewhere. +//#define MAL_USE_RUNTIME_LINKING_FOR_PTHREAD + +// Disable run-time linking on certain backends. +#ifndef MAL_NO_RUNTIME_LINKING + #if defined(MAL_ANDROID) || defined(MAL_EMSCRIPTEN) + #define MAL_NO_RUNTIME_LINKING + #endif +#endif + +// Check if we have the necessary development packages for each backend at the top so we can use this to determine whether or not +// certain unused functions and variables can be excluded from the build to avoid warnings. +#ifdef MAL_ENABLE_WASAPI + #define MAL_HAS_WASAPI // Every compiler should support WASAPI +#endif +#ifdef MAL_ENABLE_DSOUND + #define MAL_HAS_DSOUND // Every compiler should support DirectSound. +#endif +#ifdef MAL_ENABLE_WINMM + #define MAL_HAS_WINMM // Every compiler I'm aware of supports WinMM. +#endif +#ifdef MAL_ENABLE_ALSA + #define MAL_HAS_ALSA + #ifdef MAL_NO_RUNTIME_LINKING + #ifdef __has_include + #if !__has_include() + #undef MAL_HAS_ALSA + #endif + #endif + #endif +#endif +#ifdef MAL_ENABLE_PULSEAUDIO + #define MAL_HAS_PULSEAUDIO // Development packages are unnecessary for PulseAudio. + #ifdef MAL_NO_RUNTIME_LINKING + #ifdef __has_include + #if !__has_include() + #undef MAL_HAS_PULSEAUDIO + #endif + #endif + #endif +#endif +#ifdef MAL_ENABLE_JACK + #define MAL_HAS_JACK + #ifdef MAL_NO_RUNTIME_LINKING + #ifdef __has_include + #if !__has_include() + #undef MAL_HAS_JACK + #endif + #endif + #endif +#endif +#ifdef MAL_ENABLE_COREAUDIO + #define MAL_HAS_COREAUDIO +#endif +#ifdef MAL_ENABLE_SNDIO + #define MAL_HAS_SNDIO +#endif +#ifdef MAL_ENABLE_AUDIOIO + #define MAL_HAS_AUDIOIO // When enabled, always assume audioio is available. +#endif +#ifdef MAL_ENABLE_OSS + #define MAL_HAS_OSS // OSS is the only supported backend for Unix and BSD, so it must be present else this library is useless. +#endif +#ifdef MAL_ENABLE_OPENSL + #define MAL_HAS_OPENSL // OpenSL is the only supported backend for Android. It must be present. +#endif +#ifdef MAL_ENABLE_OPENAL + #define MAL_HAS_OPENAL + #ifdef MAL_NO_RUNTIME_LINKING + #ifdef __has_include + #if !__has_include() + #undef MAL_HAS_OPENAL + #endif + #endif + #endif +#endif +#ifdef MAL_ENABLE_SDL + #define MAL_HAS_SDL + + // SDL headers are necessary if using compile-time linking. + #ifdef MAL_NO_RUNTIME_LINKING + #ifdef __has_include + #ifdef MAL_EMSCRIPTEN + #if !__has_include() + #undef MAL_HAS_SDL + #endif + #else + #if !__has_include() + #undef MAL_HAS_SDL + #endif + #endif + #endif + #endif +#endif +#ifdef MAL_ENABLE_NULL + #define MAL_HAS_NULL // Everything supports the null backend. +#endif + +const mal_backend g_malDefaultBackends[] = { + mal_backend_wasapi, + mal_backend_dsound, + mal_backend_winmm, + mal_backend_coreaudio, + mal_backend_sndio, + mal_backend_audioio, + mal_backend_oss, + mal_backend_pulseaudio, + mal_backend_alsa, + mal_backend_jack, + mal_backend_opensl, + mal_backend_openal, + mal_backend_sdl, + mal_backend_null +}; + +const char* mal_get_backend_name(mal_backend backend) +{ + switch (backend) + { + case mal_backend_null: return "Null"; + case mal_backend_wasapi: return "WASAPI"; + case mal_backend_dsound: return "DirectSound"; + case mal_backend_winmm: return "WinMM"; + case mal_backend_alsa: return "ALSA"; + case mal_backend_pulseaudio: return "PulseAudio"; + case mal_backend_jack: return "JACK"; + case mal_backend_coreaudio: return "Core Audio"; + case mal_backend_sndio: return "sndio"; + case mal_backend_audioio: return "audioio"; + case mal_backend_oss: return "OSS"; + case mal_backend_opensl: return "OpenSL|ES"; + case mal_backend_openal: return "OpenAL"; + case mal_backend_sdl: return "SDL"; + default: return "Unknown"; + } +} + + + +#ifdef MAL_WIN32 + #define MAL_THREADCALL WINAPI + typedef unsigned long mal_thread_result; +#else + #define MAL_THREADCALL + typedef void* mal_thread_result; +#endif +typedef mal_thread_result (MAL_THREADCALL * mal_thread_entry_proc)(void* pData); + +#ifdef MAL_WIN32 +typedef HRESULT (WINAPI * MAL_PFN_CoInitializeEx)(LPVOID pvReserved, DWORD dwCoInit); +typedef void (WINAPI * MAL_PFN_CoUninitialize)(); +typedef HRESULT (WINAPI * MAL_PFN_CoCreateInstance)(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv); +typedef void (WINAPI * MAL_PFN_CoTaskMemFree)(LPVOID pv); +typedef HRESULT (WINAPI * MAL_PFN_PropVariantClear)(PROPVARIANT *pvar); +typedef int (WINAPI * MAL_PFN_StringFromGUID2)(const GUID* const rguid, LPOLESTR lpsz, int cchMax); + +typedef HWND (WINAPI * MAL_PFN_GetForegroundWindow)(); +typedef HWND (WINAPI * MAL_PFN_GetDesktopWindow)(); + +// Microsoft documents these APIs as returning LSTATUS, but the Win32 API shipping with some compilers do not define it. It's just a LONG. +typedef LONG (WINAPI * MAL_PFN_RegOpenKeyExA)(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); +typedef LONG (WINAPI * MAL_PFN_RegCloseKey)(HKEY hKey); +typedef LONG (WINAPI * MAL_PFN_RegQueryValueExA)(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData); +#endif + + +#define MAL_STATE_UNINITIALIZED 0 +#define MAL_STATE_STOPPED 1 // The device's default state after initialization. +#define MAL_STATE_STARTED 2 // The worker thread is in it's main loop waiting for the driver to request or deliver audio data. +#define MAL_STATE_STARTING 3 // Transitioning from a stopped state to started. +#define MAL_STATE_STOPPING 4 // Transitioning from a started state to stopped. + +#define MAL_DEFAULT_PLAYBACK_DEVICE_NAME "Default Playback Device" +#define MAL_DEFAULT_CAPTURE_DEVICE_NAME "Default Capture Device" + + /////////////////////////////////////////////////////////////////////////////// // // Timing @@ -4154,6 +4398,136 @@ mal_uint32 mal_get_closest_standard_sample_rate(mal_uint32 sampleRateIn) } +typedef struct +{ + mal_uint8* pInputFrames; + mal_uint32 framesRemaining; +} mal_calculate_cpu_speed_factor_data; + +mal_uint32 mal_calculate_cpu_speed_factor__on_read(mal_dsp* pDSP, mal_uint32 framesToRead, void* pFramesOut, void* pUserData) +{ + mal_calculate_cpu_speed_factor_data* pData = (mal_calculate_cpu_speed_factor_data*)pUserData; + mal_assert(pData != NULL); + + if (framesToRead > pData->framesRemaining) { + framesToRead = pData->framesRemaining; + } + + mal_copy_memory(pFramesOut, pData->pInputFrames, framesToRead*pDSP->formatConverterIn.config.channels * sizeof(*pData->pInputFrames)); + + pData->pInputFrames += framesToRead; + pData->framesRemaining -= framesToRead; + + return framesToRead; +} + +float mal_calculate_cpu_speed_factor() +{ + // Our profiling test is based on how quick it can process 1 second worth of samples through mini_al's data conversion pipeline. + + // This factor is multiplied with the profiling time. May need to fiddle with this to get an accurate value. + double f = 1000; + + // Experiment: Reduce the factor a little when debug mode is used to reduce a blowout. +#if !defined(NDEBUG) || defined(_DEBUG) + f /= 2; +#endif + + mal_uint32 sampleRateIn = 44100; + mal_uint32 sampleRateOut = 48000; + mal_uint32 channelsIn = 2; + mal_uint32 channelsOut = 6; + + // Using the heap here to avoid an unnecessary static memory allocation. Also too big for the stack. + mal_uint8* pInputFrames = NULL; + float* pOutputFrames = NULL; + + size_t inputDataSize = sampleRateIn * channelsIn * sizeof(*pInputFrames); + size_t outputDataSize = sampleRateOut * channelsOut * sizeof(*pOutputFrames); + + void* pData = mal_malloc(inputDataSize + outputDataSize); + if (pData == NULL) { + return 1; + } + + pInputFrames = (mal_uint8*)pData; + pOutputFrames = (float*)(pInputFrames + inputDataSize); + + + + + mal_calculate_cpu_speed_factor_data data; + data.pInputFrames = pInputFrames; + data.framesRemaining = sampleRateIn; + + mal_dsp_config config = mal_dsp_config_init(mal_format_u8, channelsIn, sampleRateIn, mal_format_f32, channelsOut, sampleRateOut, mal_calculate_cpu_speed_factor__on_read, &data); + + // Use linear sample rate conversion because it's the simplest and least likely to cause skewing as a result of tweaks to default + // configurations in the future. + config.srcAlgorithm = mal_src_algorithm_linear; + + // Experiment: Disable SIMD extensions when profiling just to try and keep things a bit more consistent. The idea is to get a general + // indication on the speed of the system, but SIMD is used more heavily in the DSP pipeline than in the general case which may make + // the results a little less realistic. + config.noSSE2 = MAL_TRUE; + config.noAVX2 = MAL_TRUE; + config.noAVX512 = MAL_TRUE; + config.noNEON = MAL_TRUE; + + mal_dsp dsp; + mal_result result = mal_dsp_init(&config, &dsp); + if (result != MAL_SUCCESS) { + mal_free(pData); + return 1; + } + + + int iterationCount = 2; + + mal_timer timer; + mal_timer_init(&timer); + double startTime = mal_timer_get_time_in_seconds(&timer); + { + for (int i = 0; i < iterationCount; ++i) { + mal_dsp_read(&dsp, sampleRateOut, pOutputFrames, &data); + data.pInputFrames = pInputFrames; + data.framesRemaining = sampleRateIn; + } + } + double executionTimeInSeconds = mal_timer_get_time_in_seconds(&timer) - startTime; + executionTimeInSeconds /= iterationCount; + + + mal_free(pData); + + // Guard against extreme blowouts. + return (float)mal_clamp(executionTimeInSeconds * f, 0.1, 100.0); +} + +mal_uint32 mal_scale_buffer_size(mal_uint32 baseBufferSize, float scale) +{ + return mal_max(1, (mal_uint32)(baseBufferSize*scale)); +} + +mal_uint32 mal_calculate_default_buffer_size_in_frames(mal_performance_profile performanceProfile, mal_uint32 sampleRate, float scale) +{ + mal_uint32 baseLatency; + if (performanceProfile == mal_performance_profile_low_latency) { + baseLatency = MAL_BASE_BUFFER_SIZE_IN_MILLISECONDS_LOW_LATENCY; + } else { + baseLatency = MAL_BASE_BUFFER_SIZE_IN_MILLISECONDS_CONSERVATIVE; + } + + mal_uint32 sampleRateMS = (sampleRate/1000); + + mal_uint32 minBufferSize = sampleRateMS * mal_min(baseLatency / 5, 1); // <-- Guard against multiply by zero. + mal_uint32 maxBufferSize = sampleRateMS * (baseLatency * 40); + + mal_uint32 bufferSize = mal_scale_buffer_size((sampleRate/1000) * baseLatency, scale); + return mal_clamp(bufferSize, minBufferSize, maxBufferSize); +} + + const char* mal_log_level_to_string(mal_uint32 logLevel) { switch (logLevel) @@ -6191,7 +6565,7 @@ mal_uint32 mal_device__get_available_frames__wasapi(mal_device* pDevice) { mal_assert(pDevice != NULL); -#if 1 +#if 0 if (pDevice->type == mal_device_type_playback) { mal_uint32 paddingFramesCount; HRESULT hr = mal_IAudioClient_GetCurrentPadding((mal_IAudioClient*)pDevice->wasapi.pAudioClient, &paddingFramesCount); @@ -6215,15 +6589,20 @@ mal_uint32 mal_device__get_available_frames__wasapi(mal_device* pDevice) } #else mal_uint32 paddingFramesCount; - HRESULT hr = mal_IAudioClient_GetCurrentPadding(pDevice->wasapi.pAudioClient, &paddingFramesCount); + HRESULT hr = mal_IAudioClient_GetCurrentPadding((mal_IAudioClient*)pDevice->wasapi.pAudioClient, &paddingFramesCount); if (FAILED(hr)) { return 0; } + // Slightly different rules for exclusive and shared modes. if (pDevice->exclusiveMode) { return paddingFramesCount; } else { - return pDevice->bufferSizeInFrames - paddingFramesCount; + if (pDevice->type == mal_device_type_playback) { + return pDevice->bufferSizeInFrames - paddingFramesCount; + } else { + return paddingFramesCount; + } } #endif } @@ -8843,16 +9222,6 @@ typedef size_t (* mal_snd_pcm_info_sizeof_proc) typedef const char* (* mal_snd_pcm_info_get_name_proc) (const mal_snd_pcm_info_t* info); typedef int (* mal_snd_config_update_free_global_proc) (); -mal_snd_pcm_format_t g_mal_ALSAFormats[] = { - MAL_SND_PCM_FORMAT_UNKNOWN, // mal_format_unknown - MAL_SND_PCM_FORMAT_U8, // mal_format_u8 - MAL_SND_PCM_FORMAT_S16_LE, // mal_format_s16 - MAL_SND_PCM_FORMAT_S24_3LE, // mal_format_s24 - //MAL_SND_PCM_FORMAT_S24_LE, // mal_format_s24_32 - MAL_SND_PCM_FORMAT_S32_LE, // mal_format_s32 - MAL_SND_PCM_FORMAT_FLOAT_LE // mal_format_f32 -}; - // This array specifies each of the common devices that can be used for both playback and capture. const char* g_malCommonDeviceNamesALSA[] = { "default", @@ -8900,20 +9269,52 @@ float mal_find_default_buffer_size_scale__alsa(const char* deviceName) mal_snd_pcm_format_t mal_convert_mal_format_to_alsa_format(mal_format format) { - return g_mal_ALSAFormats[format]; + mal_snd_pcm_format_t ALSAFormats[] = { + MAL_SND_PCM_FORMAT_UNKNOWN, // mal_format_unknown + MAL_SND_PCM_FORMAT_U8, // mal_format_u8 + MAL_SND_PCM_FORMAT_S16_LE, // mal_format_s16 + MAL_SND_PCM_FORMAT_S24_3LE, // mal_format_s24 + MAL_SND_PCM_FORMAT_S32_LE, // mal_format_s32 + MAL_SND_PCM_FORMAT_FLOAT_LE // mal_format_f32 + }; + + if (mal_is_big_endian()) { + ALSAFormats[0] = MAL_SND_PCM_FORMAT_UNKNOWN; + ALSAFormats[1] = MAL_SND_PCM_FORMAT_U8; + ALSAFormats[2] = MAL_SND_PCM_FORMAT_S16_BE; + ALSAFormats[3] = MAL_SND_PCM_FORMAT_S24_3BE; + ALSAFormats[4] = MAL_SND_PCM_FORMAT_S32_BE; + ALSAFormats[5] = MAL_SND_PCM_FORMAT_FLOAT_BE; + } + + + return ALSAFormats[format]; } mal_format mal_convert_alsa_format_to_mal_format(mal_snd_pcm_format_t formatALSA) { - switch (formatALSA) - { - case MAL_SND_PCM_FORMAT_U8: return mal_format_u8; - case MAL_SND_PCM_FORMAT_S16_LE: return mal_format_s16; - case MAL_SND_PCM_FORMAT_S24_3LE: return mal_format_s24; - //case MAL_SND_PCM_FORMAT_S24_LE: return mal_format_s24_32 - case MAL_SND_PCM_FORMAT_S32_LE: return mal_format_s32; - case MAL_SND_PCM_FORMAT_FLOAT_LE: return mal_format_f32; - default: return mal_format_unknown; + if (mal_is_little_endian()) { + switch (formatALSA) { + case MAL_SND_PCM_FORMAT_S16_LE: return mal_format_s16; + case MAL_SND_PCM_FORMAT_S24_3LE: return mal_format_s24; + case MAL_SND_PCM_FORMAT_S32_LE: return mal_format_s32; + case MAL_SND_PCM_FORMAT_FLOAT_LE: return mal_format_f32; + default: break; + } + } else { + switch (formatALSA) { + case MAL_SND_PCM_FORMAT_S16_BE: return mal_format_s16; + case MAL_SND_PCM_FORMAT_S24_3BE: return mal_format_s24; + case MAL_SND_PCM_FORMAT_S32_BE: return mal_format_s32; + case MAL_SND_PCM_FORMAT_FLOAT_BE: return mal_format_f32; + default: break; + } + } + + // Endian agnostic. + switch (formatALSA) { + case MAL_SND_PCM_FORMAT_U8: return mal_format_u8; + default: return mal_format_unknown; } } @@ -9933,11 +10334,19 @@ mal_result mal_device_init__alsa(mal_context* pContext, mal_device_type type, co MAL_SND_PCM_FORMAT_FLOAT_LE, // mal_format_f32 MAL_SND_PCM_FORMAT_S32_LE, // mal_format_s32 MAL_SND_PCM_FORMAT_S24_3LE, // mal_format_s24 - //MAL_SND_PCM_FORMAT_S24_LE, // mal_format_s24_32 MAL_SND_PCM_FORMAT_S16_LE, // mal_format_s16 MAL_SND_PCM_FORMAT_U8 // mal_format_u8 }; + if (mal_is_big_endian()) { + preferredFormatsALSA[0] = MAL_SND_PCM_FORMAT_FLOAT_BE; + preferredFormatsALSA[1] = MAL_SND_PCM_FORMAT_S32_BE; + preferredFormatsALSA[2] = MAL_SND_PCM_FORMAT_S24_3BE; + preferredFormatsALSA[3] = MAL_SND_PCM_FORMAT_S16_BE; + preferredFormatsALSA[4] = MAL_SND_PCM_FORMAT_U8; + } + + formatALSA = MAL_SND_PCM_FORMAT_UNKNOWN; for (size_t i = 0; i < (sizeof(preferredFormatsALSA) / sizeof(preferredFormatsALSA[0])); ++i) { if (((mal_snd_pcm_format_mask_test_proc)pContext->alsa.snd_pcm_format_mask_test)(pFormatMask, preferredFormatsALSA[i])) { @@ -10943,20 +11352,27 @@ mal_result mal_result_from_pulse(int result) #if 0 mal_pa_sample_format_t mal_format_to_pulse(mal_format format) { - switch (format) - { - case mal_format_u8: return MAL_PA_SAMPLE_U8; - case mal_format_s16: return MAL_PA_SAMPLE_S16LE; - //case mal_format_s16be: return MAL_PA_SAMPLE_S16BE; - case mal_format_s24: return MAL_PA_SAMPLE_S24LE; - //case mal_format_s24be: return MAL_PA_SAMPLE_S24BE; - //case mal_format_s24_32: return MAL_PA_SAMPLE_S24_32LE; - //case mal_format_s24_32be: return MAL_PA_SAMPLE_S24_32BE; - case mal_format_s32: return MAL_PA_SAMPLE_S32LE; - //case mal_format_s32be: return MAL_PA_SAMPLE_S32BE; - case mal_format_f32: return MAL_PA_SAMPLE_FLOAT32LE; - //case mal_format_f32be: return PA_SAMPLE_FLOAT32BE; + if (mal_is_little_endian()) { + switch (format) { + case mal_format_s16: return MAL_PA_SAMPLE_S16LE; + case mal_format_s24: return MAL_PA_SAMPLE_S24LE; + case mal_format_s32: return MAL_PA_SAMPLE_S32LE; + case mal_format_f32: return MAL_PA_SAMPLE_FLOAT32LE; + default: break; + } + } else { + switch (format) { + case mal_format_s16: return MAL_PA_SAMPLE_S16BE; + case mal_format_s24: return MAL_PA_SAMPLE_S24BE; + case mal_format_s32: return MAL_PA_SAMPLE_S32BE; + case mal_format_f32: return MAL_PA_SAMPLE_FLOAT32BE; + default: break; + } + } + // Endian agnostic. + switch (format) { + case mal_format_u8: return MAL_PA_SAMPLE_U8; default: return MAL_PA_SAMPLE_INVALID; } } @@ -10964,20 +11380,27 @@ mal_pa_sample_format_t mal_format_to_pulse(mal_format format) mal_format mal_format_from_pulse(mal_pa_sample_format_t format) { - switch (format) - { - case MAL_PA_SAMPLE_U8: return mal_format_u8; - case MAL_PA_SAMPLE_S16LE: return mal_format_s16; - //case MAL_PA_SAMPLE_S16BE: return mal_format_s16be; - case MAL_PA_SAMPLE_S24LE: return mal_format_s24; - //case MAL_PA_SAMPLE_S24BE: return mal_format_s24be; - //case MAL_PA_SAMPLE_S24_32LE: return mal_format_s24_32; - //case MAL_PA_SAMPLE_S24_32BE: return mal_format_s24_32be; - case MAL_PA_SAMPLE_S32LE: return mal_format_s32; - //case MAL_PA_SAMPLE_S32BE: return mal_format_s32be; - case MAL_PA_SAMPLE_FLOAT32LE: return mal_format_f32; - //case MAL_PA_SAMPLE_FLOAT32BE: return mal_format_f32be; + if (mal_is_little_endian()) { + switch (format) { + case MAL_PA_SAMPLE_S16LE: return mal_format_s16; + case MAL_PA_SAMPLE_S24LE: return mal_format_s24; + case MAL_PA_SAMPLE_S32LE: return mal_format_s32; + case MAL_PA_SAMPLE_FLOAT32LE: return mal_format_f32; + default: break; + } + } else { + switch (format) { + case MAL_PA_SAMPLE_S16BE: return mal_format_s16; + case MAL_PA_SAMPLE_S24BE: return mal_format_s24; + case MAL_PA_SAMPLE_S32BE: return mal_format_s32; + case MAL_PA_SAMPLE_FLOAT32BE: return mal_format_f32; + default: break; + } + } + // Endian agnostic. + switch (format) { + case MAL_PA_SAMPLE_U8: return mal_format_u8; default: return mal_format_unknown; } } @@ -12967,9 +13390,9 @@ mal_result mal_format_from_AudioStreamBasicDescription(const AudioStreamBasicDes if ((pDescription->mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) != 0) { return MAL_FORMAT_NOT_SUPPORTED; } - - // Big-endian formats are not currently supported, but will be added in a future version of mini_al. - if ((pDescription->mFormatFlags & kLinearPCMFormatFlagIsAlignedHigh) != 0) { + + // Only supporting native-endian. + if ((mal_is_little_endian() && (pDescription->mFormatFlags & kAudioFormatFlagIsBigEndian) != 0) || (mal_is_big_endian() && (pDescription->mFormatFlags & kAudioFormatFlagIsBigEndian) == 0)) { return MAL_FORMAT_NOT_SUPPORTED; } @@ -14565,6 +14988,1299 @@ mal_result mal_context_init__coreaudio(mal_context* pContext) +/////////////////////////////////////////////////////////////////////////////// +// +// sndio Backend +// +/////////////////////////////////////////////////////////////////////////////// +#ifdef MAL_HAS_SNDIO +#include +#include + +// Only supporting OpenBSD. This did not work very well at all on FreeBSD when I tried it. Not sure if this is due +// to mini_al's implementation or if it's some kind of system configuration issue, but basically the default device +// just doesn't emit any sound, or at times you'll hear tiny pieces. I will consider enabling this when there's +// demand for it or if I can get it tested and debugged more thoroughly. + +//#if defined(__NetBSD__) || defined(__OpenBSD__) +//#include +//#endif +//#if defined(__FreeBSD__) || defined(__DragonFly__) +//#include +//#endif + +#define MAL_SIO_DEVANY "default" +#define MAL_SIO_PLAY 1 +#define MAL_SIO_REC 2 +#define MAL_SIO_NENC 8 +#define MAL_SIO_NCHAN 8 +#define MAL_SIO_NRATE 16 +#define MAL_SIO_NCONF 4 + +struct mal_sio_hdl; // <-- Opaque + +struct mal_sio_par +{ + unsigned int bits; + unsigned int bps; + unsigned int sig; + unsigned int le; + unsigned int msb; + unsigned int rchan; + unsigned int pchan; + unsigned int rate; + unsigned int bufsz; + unsigned int xrun; + unsigned int round; + unsigned int appbufsz; + int __pad[3]; + unsigned int __magic; +}; + +struct mal_sio_enc +{ + unsigned int bits; + unsigned int bps; + unsigned int sig; + unsigned int le; + unsigned int msb; +}; + +struct mal_sio_conf +{ + unsigned int enc; + unsigned int rchan; + unsigned int pchan; + unsigned int rate; +}; + +struct mal_sio_cap +{ + struct mal_sio_enc enc[MAL_SIO_NENC]; + unsigned int rchan[MAL_SIO_NCHAN]; + unsigned int pchan[MAL_SIO_NCHAN]; + unsigned int rate[MAL_SIO_NRATE]; + int __pad[7]; + unsigned int nconf; + struct mal_sio_conf confs[MAL_SIO_NCONF]; +}; + +typedef struct mal_sio_hdl* (* mal_sio_open_proc) (const char*, unsigned int, int); +typedef void (* mal_sio_close_proc) (struct mal_sio_hdl*); +typedef int (* mal_sio_setpar_proc) (struct mal_sio_hdl*, struct mal_sio_par*); +typedef int (* mal_sio_getpar_proc) (struct mal_sio_hdl*, struct mal_sio_par*); +typedef int (* mal_sio_getcap_proc) (struct mal_sio_hdl*, struct mal_sio_cap*); +typedef size_t (* mal_sio_write_proc) (struct mal_sio_hdl*, const void*, size_t); +typedef size_t (* mal_sio_read_proc) (struct mal_sio_hdl*, void*, size_t); +typedef int (* mal_sio_start_proc) (struct mal_sio_hdl*); +typedef int (* mal_sio_stop_proc) (struct mal_sio_hdl*); +typedef int (* mal_sio_initpar_proc)(struct mal_sio_par*); + +mal_format mal_format_from_sio_enc__sndio(unsigned int bits, unsigned int bps, unsigned int sig, unsigned int le, unsigned int msb) +{ + // We only support native-endian right now. + if ((mal_is_little_endian() && le == 0) || (mal_is_big_endian() && le == 1)) { + return mal_format_unknown; + } + + if (bits == 8 && bps == 1 && sig == 0) { + return mal_format_u8; + } + if (bits == 16 && bps == 2 && sig == 1) { + return mal_format_s16; + } + if (bits == 24 && bps == 3 && sig == 1) { + return mal_format_s24; + } + if (bits == 24 && bps == 4 && sig == 1 && msb == 0) { + //return mal_format_s24_32; + } + if (bits == 32 && bps == 4 && sig == 1) { + return mal_format_s32; + } + + return mal_format_unknown; +} + +mal_format mal_find_best_format_from_sio_cap__sndio(struct mal_sio_cap* caps) +{ + mal_assert(caps != NULL); + + mal_format bestFormat = mal_format_unknown; + for (unsigned int iConfig = 0; iConfig < caps->nconf; iConfig += 1) { + for (unsigned int iEncoding = 0; iEncoding < MAL_SIO_NENC; iEncoding += 1) { + if ((caps->confs[iConfig].enc & (1UL << iEncoding)) == 0) { + continue; + } + + unsigned int bits = caps->enc[iEncoding].bits; + unsigned int bps = caps->enc[iEncoding].bps; + unsigned int sig = caps->enc[iEncoding].sig; + unsigned int le = caps->enc[iEncoding].le; + unsigned int msb = caps->enc[iEncoding].msb; + mal_format format = mal_format_from_sio_enc__sndio(bits, bps, sig, le, msb); + if (format == mal_format_unknown) { + continue; // Format not supported. + } + + if (bestFormat == mal_format_unknown) { + bestFormat = format; + } else { + if (mal_get_format_priority_index(bestFormat) > mal_get_format_priority_index(format)) { // <-- Lower = better. + bestFormat = format; + } + } + } + } + + return mal_format_unknown; +} + +mal_uint32 mal_find_best_channels_from_sio_cap__sndio(struct mal_sio_cap* caps, mal_device_type deviceType, mal_format requiredFormat) +{ + mal_assert(caps != NULL); + mal_assert(requiredFormat != mal_format_unknown); + + // Just pick whatever configuration has the most channels. + mal_uint32 maxChannels = 0; + for (unsigned int iConfig = 0; iConfig < caps->nconf; iConfig += 1) { + // The encoding should be of requiredFormat. + for (unsigned int iEncoding = 0; iEncoding < MAL_SIO_NENC; iEncoding += 1) { + if ((caps->confs[iConfig].enc & (1UL << iEncoding)) == 0) { + continue; + } + + unsigned int bits = caps->enc[iEncoding].bits; + unsigned int bps = caps->enc[iEncoding].bps; + unsigned int sig = caps->enc[iEncoding].sig; + unsigned int le = caps->enc[iEncoding].le; + unsigned int msb = caps->enc[iEncoding].msb; + mal_format format = mal_format_from_sio_enc__sndio(bits, bps, sig, le, msb); + if (format != requiredFormat) { + continue; + } + + // Getting here means the format is supported. Iterate over each channel count and grab the biggest one. + for (unsigned int iChannel = 0; iChannel < MAL_SIO_NCHAN; iChannel += 1) { + unsigned int chan = 0; + if (deviceType == mal_device_type_playback) { + chan = caps->confs[iConfig].pchan; + } else { + chan = caps->confs[iConfig].rchan; + } + + if ((chan & (1UL << iChannel)) == 0) { + continue; + } + + unsigned int channels; + if (deviceType == mal_device_type_playback) { + channels = caps->pchan[iChannel]; + } else { + channels = caps->rchan[iChannel]; + } + + if (maxChannels < channels) { + maxChannels = channels; + } + } + } + } + + return maxChannels; +} + +mal_uint32 mal_find_best_sample_rate_from_sio_cap__sndio(struct mal_sio_cap* caps, mal_device_type deviceType, mal_format requiredFormat, mal_uint32 requiredChannels) +{ + mal_assert(caps != NULL); + mal_assert(requiredFormat != mal_format_unknown); + mal_assert(requiredChannels > 0); + mal_assert(requiredChannels <= MAL_MAX_CHANNELS); + + mal_uint32 firstSampleRate = 0; // <-- If the device does not support a standard rate we'll fall back to the first one that's found. + + mal_uint32 bestSampleRate = 0; + for (unsigned int iConfig = 0; iConfig < caps->nconf; iConfig += 1) { + // The encoding should be of requiredFormat. + for (unsigned int iEncoding = 0; iEncoding < MAL_SIO_NENC; iEncoding += 1) { + if ((caps->confs[iConfig].enc & (1UL << iEncoding)) == 0) { + continue; + } + + unsigned int bits = caps->enc[iEncoding].bits; + unsigned int bps = caps->enc[iEncoding].bps; + unsigned int sig = caps->enc[iEncoding].sig; + unsigned int le = caps->enc[iEncoding].le; + unsigned int msb = caps->enc[iEncoding].msb; + mal_format format = mal_format_from_sio_enc__sndio(bits, bps, sig, le, msb); + if (format != requiredFormat) { + continue; + } + + // Getting here means the format is supported. Iterate over each channel count and grab the biggest one. + for (unsigned int iChannel = 0; iChannel < MAL_SIO_NCHAN; iChannel += 1) { + unsigned int chan = 0; + if (deviceType == mal_device_type_playback) { + chan = caps->confs[iConfig].pchan; + } else { + chan = caps->confs[iConfig].rchan; + } + + if ((chan & (1UL << iChannel)) == 0) { + continue; + } + + unsigned int channels; + if (deviceType == mal_device_type_playback) { + channels = caps->pchan[iChannel]; + } else { + channels = caps->rchan[iChannel]; + } + + if (channels != requiredChannels) { + continue; + } + + // Getting here means we have found a compatible encoding/channel pair. + for (unsigned int iRate = 0; iRate < MAL_SIO_NRATE; iRate += 1) { + mal_uint32 rate = (mal_uint32)caps->rate[iRate]; + + if (firstSampleRate == 0) { + firstSampleRate = rate; + } + + // Disregard this rate if it's not a standard one. + mal_uint32 ratePriority = mal_get_standard_sample_rate_priority_index(rate); + if (ratePriority == (mal_uint32)-1) { + continue; + } + + if (mal_get_standard_sample_rate_priority_index(bestSampleRate) > ratePriority) { // Lower = better. + bestSampleRate = rate; + } + } + } + } + } + + // If a standard sample rate was not found just fall back to the first one that was iterated. + if (bestSampleRate == 0) { + bestSampleRate = firstSampleRate; + } + + return bestSampleRate; +} + + +mal_bool32 mal_context_is_device_id_equal__sndio(mal_context* pContext, const mal_device_id* pID0, const mal_device_id* pID1) +{ + mal_assert(pContext != NULL); + mal_assert(pID0 != NULL); + mal_assert(pID1 != NULL); + (void)pContext; + + return mal_strcmp(pID0->sndio, pID1->sndio) == 0; +} + +mal_result mal_context_enumerate_devices__sndio(mal_context* pContext, mal_enum_devices_callback_proc callback, void* pUserData) +{ + mal_assert(pContext != NULL); + mal_assert(callback != NULL); + + // sndio doesn't seem to have a good device enumeration API, so I'm therefore only enumerating + // over default devices for now. + mal_bool32 isTerminating = MAL_FALSE; + struct mal_sio_hdl* handle; + + // Playback. + if (!isTerminating) { + handle = ((mal_sio_open_proc)pContext->sndio.sio_open)(MAL_SIO_DEVANY, MAL_SIO_PLAY, 0); + if (handle != NULL) { + // Supports playback. + mal_device_info deviceInfo; + mal_zero_object(&deviceInfo); + mal_strcpy_s(deviceInfo.id.sndio, sizeof(deviceInfo.id.sndio), MAL_SIO_DEVANY); + mal_strcpy_s(deviceInfo.name, sizeof(deviceInfo.name), MAL_DEFAULT_PLAYBACK_DEVICE_NAME); + + isTerminating = !callback(pContext, mal_device_type_playback, &deviceInfo, pUserData); + + ((mal_sio_close_proc)pContext->sndio.sio_close)(handle); + } + } + + // Capture. + if (!isTerminating) { + handle = ((mal_sio_open_proc)pContext->sndio.sio_open)(MAL_SIO_DEVANY, MAL_SIO_REC, 0); + if (handle != NULL) { + // Supports capture. + mal_device_info deviceInfo; + mal_zero_object(&deviceInfo); + mal_strcpy_s(deviceInfo.id.sndio, sizeof(deviceInfo.id.sndio), "default"); + mal_strcpy_s(deviceInfo.name, sizeof(deviceInfo.name), MAL_DEFAULT_CAPTURE_DEVICE_NAME); + + isTerminating = !callback(pContext, mal_device_type_capture, &deviceInfo, pUserData); + + ((mal_sio_close_proc)pContext->sndio.sio_close)(handle); + } + } + + return MAL_SUCCESS; +} + +mal_result mal_context_get_device_info__sndio(mal_context* pContext, mal_device_type deviceType, const mal_device_id* pDeviceID, mal_share_mode shareMode, mal_device_info* pDeviceInfo) +{ + mal_assert(pContext != NULL); + (void)shareMode; + + // We need to open the device before we can get information about it. + char devid[256]; + if (pDeviceID == NULL) { + mal_strcpy_s(devid, sizeof(devid), MAL_SIO_DEVANY); + mal_strcpy_s(pDeviceInfo->name, sizeof(pDeviceInfo->name), (deviceType == mal_device_type_playback) ? MAL_DEFAULT_PLAYBACK_DEVICE_NAME : MAL_DEFAULT_CAPTURE_DEVICE_NAME); + } else { + mal_strcpy_s(devid, sizeof(devid), pDeviceID->sndio); + mal_strcpy_s(pDeviceInfo->name, sizeof(pDeviceInfo->name), devid); + } + + struct mal_sio_hdl* handle = ((mal_sio_open_proc)pContext->sndio.sio_open)(devid, (deviceType == mal_device_type_playback) ? MAL_SIO_PLAY : MAL_SIO_REC, 0); + if (handle == NULL) { + return MAL_NO_DEVICE; + } + + struct mal_sio_cap caps; + if (((mal_sio_getcap_proc)pContext->sndio.sio_getcap)(handle, &caps) == 0) { + return MAL_ERROR; + } + + for (unsigned int iConfig = 0; iConfig < caps.nconf; iConfig += 1) { + // The main thing we care about is that the encoding is supported by mini_al. If it is, we want to give + // preference to some formats over others. + for (unsigned int iEncoding = 0; iEncoding < MAL_SIO_NENC; iEncoding += 1) { + if ((caps.confs[iConfig].enc & (1UL << iEncoding)) == 0) { + continue; + } + + unsigned int bits = caps.enc[iEncoding].bits; + unsigned int bps = caps.enc[iEncoding].bps; + unsigned int sig = caps.enc[iEncoding].sig; + unsigned int le = caps.enc[iEncoding].le; + unsigned int msb = caps.enc[iEncoding].msb; + mal_format format = mal_format_from_sio_enc__sndio(bits, bps, sig, le, msb); + if (format == mal_format_unknown) { + continue; // Format not supported. + } + + // Add this format if it doesn't already exist. + mal_bool32 formatExists = MAL_FALSE; + for (mal_uint32 iExistingFormat = 0; iExistingFormat < pDeviceInfo->formatCount; iExistingFormat += 1) { + if (pDeviceInfo->formats[iExistingFormat] == format) { + formatExists = MAL_TRUE; + break; + } + } + + if (!formatExists) { + pDeviceInfo->formats[pDeviceInfo->formatCount++] = format; + } + } + + // Channels. + for (unsigned int iChannel = 0; iChannel < MAL_SIO_NCHAN; iChannel += 1) { + unsigned int chan = 0; + if (deviceType == mal_device_type_playback) { + chan = caps.confs[iConfig].pchan; + } else { + chan = caps.confs[iConfig].rchan; + } + + if ((chan & (1UL << iChannel)) == 0) { + continue; + } + + unsigned int channels; + if (deviceType == mal_device_type_playback) { + channels = caps.pchan[iChannel]; + } else { + channels = caps.rchan[iChannel]; + } + + if (pDeviceInfo->minChannels > channels) { + pDeviceInfo->minChannels = channels; + } + if (pDeviceInfo->maxChannels < channels) { + pDeviceInfo->maxChannels = channels; + } + } + + // Sample rates. + for (unsigned int iRate = 0; iRate < MAL_SIO_NRATE; iRate += 1) { + if ((caps.confs[iConfig].rate & (1UL << iRate)) != 0) { + unsigned int rate = caps.rate[iRate]; + if (pDeviceInfo->minSampleRate > rate) { + pDeviceInfo->minSampleRate = rate; + } + if (pDeviceInfo->maxSampleRate < rate) { + pDeviceInfo->maxSampleRate = rate; + } + } + } + } + + ((mal_sio_close_proc)pContext->sndio.sio_close)(handle); + return MAL_SUCCESS; +} + +void mal_device_uninit__sndio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + ((mal_sio_close_proc)pDevice->pContext->sndio.sio_close)((struct mal_sio_hdl*)pDevice->sndio.handle); + mal_free(pDevice->sndio.pIntermediaryBuffer); +} + +mal_result mal_device_init__sndio(mal_context* pContext, mal_device_type deviceType, const mal_device_id* pDeviceID, const mal_device_config* pConfig, mal_device* pDevice) +{ + (void)pContext; + + mal_assert(pDevice != NULL); + mal_zero_object(&pDevice->sndio); + + const char* deviceName = MAL_SIO_DEVANY; +//#if defined(__FreeBSD__) || defined(__DragonFly__) +// deviceName = "rsnd/0"; +//#else + if (pDeviceID != NULL) { + deviceName = pDeviceID->sndio; + } + + pDevice->sndio.handle = (mal_ptr)((mal_sio_open_proc)pContext->sndio.sio_open)(deviceName, (deviceType == mal_device_type_playback) ? MAL_SIO_PLAY : MAL_SIO_REC, 0); + if (pDevice->sndio.handle == NULL) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to open device.", MAL_FAILED_TO_OPEN_BACKEND_DEVICE); + } + + // We need to retrieve the device caps to determine the most appropriate format to use. + struct mal_sio_cap caps; + if (((mal_sio_getcap_proc)pContext->sndio.sio_getcap)((struct mal_sio_hdl*)pDevice->sndio.handle, &caps) == 0) { + ((mal_sio_close_proc)pContext->sndio.sio_close)((struct mal_sio_hdl*)pDevice->sndio.handle); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to retrieve device caps.", MAL_ERROR); + } + + mal_format desiredFormat = pDevice->format; + if (pDevice->usingDefaultFormat) { + desiredFormat = mal_find_best_format_from_sio_cap__sndio(&caps); + } + + if (desiredFormat == mal_format_unknown) { + desiredFormat = pDevice->format; + } + + + // Note: sndio reports a huge range of available channels. This is inconvenient for us because there's no real + // way, as far as I can tell, to get the _actual_ channel count of the device. I'm therefore restricting this + // to the requested channels, regardless of whether or not the default channel count is requested. + // + // For hardware devices, I'm suspecting only a single channel count will be reported and we can safely use the + // value returned by mal_find_best_channels_from_sio_cap__sndio(). + mal_uint32 desiredChannels = pDevice->channels; + if (pDevice->usingDefaultChannels) { + if (strlen(deviceName) > strlen("rsnd/") && strncmp(deviceName, "rsnd/", strlen("rsnd/")) == 0) { + desiredChannels = mal_find_best_channels_from_sio_cap__sndio(&caps, deviceType, desiredFormat); + } + } + + if (desiredChannels == 0) { + desiredChannels = pDevice->channels; + } + + + mal_uint32 desiredSampleRate = pDevice->sampleRate; + if (pDevice->usingDefaultSampleRate) { + desiredSampleRate = mal_find_best_sample_rate_from_sio_cap__sndio(&caps, deviceType, desiredFormat, desiredChannels); + } + + if (desiredSampleRate == 0) { + desiredSampleRate = pDevice->sampleRate; + } + + + struct mal_sio_par par; + ((mal_sio_initpar_proc)pDevice->pContext->sndio.sio_initpar)(&par); + par.msb = 0; + par.le = mal_is_little_endian(); + + switch (desiredFormat) { + case mal_format_u8: + { + par.bits = 8; + par.bps = 1; + par.sig = 0; + } break; + + case mal_format_s24: + { + par.bits = 24; + par.bps = 3; + par.sig = 1; + } break; + + case mal_format_s32: + { + par.bits = 32; + par.bps = 4; + par.sig = 1; + } break; + + case mal_format_s16: + case mal_format_f32: + default: + { + par.bits = 16; + par.bps = 2; + par.sig = 1; + } break; + } + + if (deviceType == mal_device_type_playback) { + par.pchan = desiredChannels; + } else { + par.rchan = desiredChannels; + } + + par.rate = desiredSampleRate; + + // Try calculating an appropriate default buffer size after we have the sample rate. + mal_uint32 desiredBufferSizeInFrames = pDevice->bufferSizeInFrames; + if (pDevice->usingDefaultBufferSize) { + // CPU speed factor. + float fCPUSpeed = mal_calculate_cpu_speed_factor(); + + // Playback vs capture latency. + float fDeviceType = 1; + + // Backend tax. + float fBackend = 1; + + desiredBufferSizeInFrames = mal_calculate_default_buffer_size_in_frames(pConfig->performanceProfile, par.rate, fCPUSpeed*fDeviceType*fBackend); + } + + par.round = desiredBufferSizeInFrames / pDevice->periods; + par.appbufsz = par.round * pDevice->periods; + + if (((mal_sio_setpar_proc)pContext->sndio.sio_setpar)((struct mal_sio_hdl*)pDevice->sndio.handle, &par) == 0) { + ((mal_sio_close_proc)pContext->sndio.sio_close)((struct mal_sio_hdl*)pDevice->sndio.handle); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to set buffer size.", MAL_FORMAT_NOT_SUPPORTED); + } + if (((mal_sio_getpar_proc)pContext->sndio.sio_getpar)((struct mal_sio_hdl*)pDevice->sndio.handle, &par) == 0) { + ((mal_sio_close_proc)pContext->sndio.sio_close)((struct mal_sio_hdl*)pDevice->sndio.handle); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to retrieve buffer size.", MAL_FORMAT_NOT_SUPPORTED); + } + + pDevice->internalFormat = mal_format_from_sio_enc__sndio(par.bits, par.bps, par.sig, par.le, par.msb); + + if (deviceType == mal_device_type_playback) { + pDevice->internalChannels = par.pchan; + } else { + pDevice->internalChannels = par.rchan; + } + + pDevice->internalSampleRate = par.rate; + + pDevice->periods = par.appbufsz / par.round; + if (pDevice->periods < 2) { + pDevice->periods = 2; + } + pDevice->bufferSizeInFrames = par.round * pDevice->periods; + pDevice->sndio.fragmentSizeInFrames = par.round; + + mal_get_standard_channel_map(mal_standard_channel_map_sndio, pDevice->internalChannels, pDevice->internalChannelMap); + + pDevice->sndio.pIntermediaryBuffer = mal_malloc(pDevice->sndio.fragmentSizeInFrames * mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels)); + if (pDevice->sndio.pIntermediaryBuffer == NULL) { + ((mal_sio_close_proc)pContext->sndio.sio_close)((struct mal_sio_hdl*)pDevice->sndio.handle); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to allocate memory for intermediary buffer.", MAL_OUT_OF_MEMORY); + } + +#ifdef MAL_DEBUG_OUTPUT + printf("DEVICE INFO\n"); + printf(" Format: %s\n", mal_get_format_name(pDevice->internalFormat)); + printf(" Channels: %d\n", pDevice->internalChannels); + printf(" Sample Rate: %d\n", pDevice->internalSampleRate); + printf(" Buffer Size: %d\n", pDevice->bufferSizeInFrames); + printf(" Periods: %d\n", pDevice->periods); + printf(" appbufsz: %d\n", par.appbufsz); + printf(" round: %d\n", par.round); +#endif + + return MAL_SUCCESS; +} + +mal_result mal_device__start_backend__sndio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + if (((mal_sio_start_proc)pDevice->pContext->sndio.sio_start)((struct mal_sio_hdl*)pDevice->sndio.handle) == 0) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to start backend device.", MAL_FAILED_TO_START_BACKEND_DEVICE); + } + + // The device is started by the next calls to read() and write(). For playback it's simple - just read + // data from the client, then write it to the device with write() which will in turn start the device. + // For capture it's a bit less intuitive - we do nothing (it'll be started automatically by the first + // call to read(). + if (pDevice->type == mal_device_type_playback) { + // Playback. Need to load the entire buffer, which means we need to write a fragment for each period. + for (mal_uint32 iPeriod = 0; iPeriod < pDevice->periods; iPeriod += 1) { + mal_device__read_frames_from_client(pDevice, pDevice->sndio.fragmentSizeInFrames, pDevice->sndio.pIntermediaryBuffer); + + int bytesWritten = ((mal_sio_write_proc)pDevice->pContext->sndio.sio_write)((struct mal_sio_hdl*)pDevice->sndio.handle, pDevice->sndio.pIntermediaryBuffer, pDevice->sndio.fragmentSizeInFrames * mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels)); + if (bytesWritten == 0) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to send initial chunk of data to the device.", MAL_FAILED_TO_SEND_DATA_TO_DEVICE); + } + } + } else { + // Capture. Do nothing. + } + + return MAL_SUCCESS; +} + +mal_result mal_device__stop_backend__sndio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + ((mal_sio_stop_proc)pDevice->pContext->sndio.sio_stop)((struct mal_sio_hdl*)pDevice->sndio.handle); + return MAL_SUCCESS; +} + +mal_result mal_device__break_main_loop__sndio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + pDevice->sndio.breakFromMainLoop = MAL_TRUE; + return MAL_SUCCESS; +} + +mal_result mal_device__main_loop__sndio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + pDevice->sndio.breakFromMainLoop = MAL_FALSE; + while (!pDevice->sndio.breakFromMainLoop) { + // Break from the main loop if the device isn't started anymore. Likely what's happened is the application + // has requested that the device be stopped. + if (!mal_device_is_started(pDevice)) { + break; + } + + if (pDevice->type == mal_device_type_playback) { + // Playback. + mal_device__read_frames_from_client(pDevice, pDevice->sndio.fragmentSizeInFrames, pDevice->sndio.pIntermediaryBuffer); + + int bytesWritten = ((mal_sio_write_proc)pDevice->pContext->sndio.sio_write)((struct mal_sio_hdl*)pDevice->sndio.handle, pDevice->sndio.pIntermediaryBuffer, pDevice->sndio.fragmentSizeInFrames * pDevice->internalChannels * mal_get_bytes_per_sample(pDevice->internalFormat)); + if (bytesWritten == 0) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to send data from the client to the device.", MAL_FAILED_TO_SEND_DATA_TO_DEVICE); + } + } else { + // Capture. + int bytesRead = ((mal_sio_read_proc)pDevice->pContext->sndio.sio_read)((struct mal_sio_hdl*)pDevice->sndio.handle, pDevice->sndio.pIntermediaryBuffer, pDevice->sndio.fragmentSizeInFrames * mal_get_bytes_per_sample(pDevice->internalFormat)); + if (bytesRead == 0) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[sndio] Failed to read data from the device to be sent to the client.", MAL_FAILED_TO_READ_DATA_FROM_DEVICE); + } + + mal_uint32 framesRead = (mal_uint32)bytesRead / pDevice->internalChannels / mal_get_bytes_per_sample(pDevice->internalFormat); + mal_device__send_frames_to_client(pDevice, framesRead, pDevice->sndio.pIntermediaryBuffer); + } + } + + return MAL_SUCCESS; +} + +mal_result mal_context_uninit__sndio(mal_context* pContext) +{ + mal_assert(pContext != NULL); + mal_assert(pContext->backend == mal_backend_sndio); + + (void)pContext; + return MAL_SUCCESS; +} + +mal_result mal_context_init__sndio(mal_context* pContext) +{ + mal_assert(pContext != NULL); + +#ifndef MAL_NO_RUNTIME_LINKING + // libpulse.so + const char* libsndioNames[] = { + "libsndio.so" + }; + + for (size_t i = 0; i < mal_countof(libsndioNames); ++i) { + pContext->sndio.sndioSO = mal_dlopen(libsndioNames[i]); + if (pContext->sndio.sndioSO != NULL) { + break; + } + } + + if (pContext->sndio.sndioSO == NULL) { + return MAL_NO_BACKEND; + } + + pContext->sndio.sio_open = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_open"); + pContext->sndio.sio_close = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_close"); + pContext->sndio.sio_setpar = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_setpar"); + pContext->sndio.sio_getpar = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_getpar"); + pContext->sndio.sio_getcap = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_getcap"); + pContext->sndio.sio_write = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_write"); + pContext->sndio.sio_read = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_read"); + pContext->sndio.sio_start = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_start"); + pContext->sndio.sio_stop = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_stop"); + pContext->sndio.sio_initpar = (mal_proc)mal_dlsym(pContext->sndio.sndioSO, "sio_initpar"); +#else + pContext->sndio.sio_open = sio_open; + pContext->sndio.sio_close = sio_close; + pContext->sndio.sio_setpar = sio_setpar; + pContext->sndio.sio_getpar = sio_getpar; + pContext->sndio.sio_getcap = sio_getcap; + pContext->sndio.sio_write = sio_write; + pContext->sndio.sio_read = sio_read; + pContext->sndio.sio_start = sio_start; + pContext->sndio.sio_stop = sio_stop; + pContext->sndio.sio_initpar = sio_initpar; +#endif + + pContext->onUninit = mal_context_uninit__sndio; + pContext->onDeviceIDEqual = mal_context_is_device_id_equal__sndio; + pContext->onEnumDevices = mal_context_enumerate_devices__sndio; + pContext->onGetDeviceInfo = mal_context_get_device_info__sndio; + pContext->onDeviceInit = mal_device_init__sndio; + pContext->onDeviceUninit = mal_device_uninit__sndio; + pContext->onDeviceStart = mal_device__start_backend__sndio; + pContext->onDeviceStop = mal_device__stop_backend__sndio; + pContext->onDeviceBreakMainLoop = mal_device__break_main_loop__sndio; + pContext->onDeviceMainLoop = mal_device__main_loop__sndio; + + return MAL_SUCCESS; +} +#endif // sndio + + + +/////////////////////////////////////////////////////////////////////////////// +// +// audioio Backend +// +/////////////////////////////////////////////////////////////////////////////// +#ifdef MAL_HAS_AUDIOIO +#include +#include +#include +#include +#include + +void mal_construct_device_id__audioio(char* id, size_t idSize, const char* base, int deviceIndex) +{ + mal_assert(id != NULL); + mal_assert(idSize > 0); + mal_assert(deviceIndex >= 0); + + size_t baseLen = strlen(base); + mal_assert(idSize > baseLen); + + mal_strcpy_s(id, idSize, base); + mal_itoa_s(deviceIndex, id+baseLen, idSize-baseLen, 10); +} + +mal_result mal_extract_device_index_from_id__audioio(const char* id, const char* base, int* pIndexOut) +{ + mal_assert(id != NULL); + mal_assert(base != NULL); + mal_assert(pIndexOut != NULL); + + size_t idLen = strlen(id); + size_t baseLen = strlen(base); + if (idLen <= baseLen) { + return MAL_ERROR; // Doesn't look like the id starts with the base. + } + + if (strncmp(id, base, baseLen) != 0) { + return MAL_ERROR; // ID does not begin with base. + } + + const char* deviceIndexStr = id + baseLen; + if (deviceIndexStr[0] == '\0') { + return MAL_ERROR; // No index specified in the ID. + } + + if (pIndexOut) { + *pIndexOut = atoi(deviceIndexStr); + } + + return MAL_SUCCESS; +} + +mal_bool32 mal_context_is_device_id_equal__audioio(mal_context* pContext, const mal_device_id* pID0, const mal_device_id* pID1) +{ + mal_assert(pContext != NULL); + mal_assert(pID0 != NULL); + mal_assert(pID1 != NULL); + (void)pContext; + + return mal_strcmp(pID0->audioio, pID1->audioio) == 0; +} + +mal_format mal_format_from_encoding__audioio(unsigned int encoding, unsigned int precision) +{ + if (precision == 8 && (encoding == AUDIO_ENCODING_ULINEAR || encoding == AUDIO_ENCODING_ULINEAR || encoding == AUDIO_ENCODING_ULINEAR_LE || encoding == AUDIO_ENCODING_ULINEAR_BE)) { + return mal_format_u8; + } else { + if (mal_is_little_endian() && encoding == AUDIO_ENCODING_SLINEAR_LE) { + if (precision == 16) { + return mal_format_s16; + } else if (precision == 24) { + return mal_format_s24; + } else if (precision == 32) { + return mal_format_s32; + } + } else if (mal_is_big_endian() && encoding == AUDIO_ENCODING_SLINEAR_BE) { + if (precision == 16) { + return mal_format_s16; + } else if (precision == 24) { + return mal_format_s24; + } else if (precision == 32) { + return mal_format_s32; + } + } + } + + return mal_format_unknown; // Encoding not supported. +} + +mal_format mal_format_from_prinfo__audioio(struct audio_prinfo* prinfo) +{ + return mal_format_from_encoding__audioio(prinfo->encoding, prinfo->precision); +} + +mal_result mal_context_get_device_info_from_fd__audioio(mal_context* pContext, mal_device_type deviceType, int fd, mal_device_info* pInfoOut) +{ + mal_assert(pContext != NULL); + mal_assert(fd >= 0); + mal_assert(pInfoOut != NULL); + + (void)pContext; + (void)deviceType; + + audio_device_t fdDevice; + if (ioctl(fd, AUDIO_GETDEV, &fdDevice) < 0) { + return MAL_ERROR; // Failed to retrieve device info. + } + + // Name. + mal_strcpy_s(pInfoOut->name, sizeof(pInfoOut->name), fdDevice.name); + + // Supported formats. We get this by looking at the encodings. + int counter = 0; + for (;;) { + audio_encoding_t encoding; + mal_zero_object(&encoding); + encoding.index = counter; + if (ioctl(fd, AUDIO_GETENC, &encoding) < 0) { + break; + } + + mal_format format = mal_format_from_encoding__audioio(encoding.encoding, encoding.precision); + if (format != mal_format_unknown) { + pInfoOut->formats[pInfoOut->formatCount++] = format; + } + + counter += 1; + } + + audio_info_t fdInfo; + if (ioctl(fd, AUDIO_GETINFO, &fdInfo) < 0) { + return MAL_ERROR; + } + + if (deviceType == mal_device_type_playback) { + pInfoOut->minChannels = fdInfo.play.channels; + pInfoOut->maxChannels = fdInfo.play.channels; + pInfoOut->minSampleRate = fdInfo.play.sample_rate; + pInfoOut->maxSampleRate = fdInfo.play.sample_rate; + } else { + pInfoOut->minChannels = fdInfo.record.channels; + pInfoOut->maxChannels = fdInfo.record.channels; + pInfoOut->minSampleRate = fdInfo.record.sample_rate; + pInfoOut->maxSampleRate = fdInfo.record.sample_rate; + } + + return MAL_SUCCESS; +} + +mal_result mal_context_enumerate_devices__audioio(mal_context* pContext, mal_enum_devices_callback_proc callback, void* pUserData) +{ + mal_assert(pContext != NULL); + mal_assert(callback != NULL); + + const int maxDevices = 64; + + // Every device will be named "/dev/audioN", with a "/dev/audioctlN" equivalent. We use the "/dev/audioctlN" + // version here since we can open it even when another process has control of the "/dev/audioN" device. + char devpath[256]; + for (int iDevice = 0; iDevice < maxDevices; ++iDevice) { + mal_strcpy_s(devpath, sizeof(devpath), "/dev/audioctl"); + mal_itoa_s(iDevice, devpath+strlen(devpath), sizeof(devpath)-strlen(devpath), 10); + + struct stat st; + if (stat(devpath, &st) < 0) { + break; + } + + // The device exists, but we need to check if it's usable as playback and/or capture. + int fd; + mal_bool32 isTerminating = MAL_FALSE; + + // Playback. + if (!isTerminating) { + fd = open(devpath, O_RDONLY, 0); + if (fd >= 0) { + // Supports playback. + mal_device_info deviceInfo; + mal_zero_object(&deviceInfo); + mal_construct_device_id__audioio(deviceInfo.id.audioio, sizeof(deviceInfo.id.audioio), "/dev/audio", iDevice); + if (mal_context_get_device_info_from_fd__audioio(pContext, mal_device_type_playback, fd, &deviceInfo) == MAL_SUCCESS) { + isTerminating = !callback(pContext, mal_device_type_playback, &deviceInfo, pUserData); + } + + close(fd); + } + } + + // Capture. + if (!isTerminating) { + fd = open(devpath, O_WRONLY, 0); + if (fd >= 0) { + // Supports capture. + mal_device_info deviceInfo; + mal_zero_object(&deviceInfo); + mal_construct_device_id__audioio(deviceInfo.id.audioio, sizeof(deviceInfo.id.audioio), "/dev/audio", iDevice); + if (mal_context_get_device_info_from_fd__audioio(pContext, mal_device_type_capture, fd, &deviceInfo) == MAL_SUCCESS) { + isTerminating = !callback(pContext, mal_device_type_capture, &deviceInfo, pUserData); + } + + close(fd); + } + } + + if (isTerminating) { + break; + } + } + + return MAL_SUCCESS; +} + +mal_result mal_context_get_device_info__audioio(mal_context* pContext, mal_device_type deviceType, const mal_device_id* pDeviceID, mal_share_mode shareMode, mal_device_info* pDeviceInfo) +{ + mal_assert(pContext != NULL); + (void)shareMode; + + // We need to open the "/dev/audioctlN" device to get the info. To do this we need to extract the number + // from the device ID which will be in "/dev/audioN" format. + int fd = -1; + int deviceIndex = -1; + char ctlid[256]; + if (pDeviceID == NULL) { + // Default device. + mal_strcpy_s(ctlid, sizeof(ctlid), "/dev/audioctl"); + } else { + // Specific device. We need to convert from "/dev/audioN" to "/dev/audioctlN". + mal_result result = mal_extract_device_index_from_id__audioio(pDeviceID->audioio, "/dev/audio", &deviceIndex); + if (result != MAL_SUCCESS) { + return result; + } + + mal_construct_device_id__audioio(ctlid, sizeof(ctlid), "/dev/audioctl", deviceIndex); + } + + fd = open(ctlid, (deviceType == mal_device_type_playback) ? O_WRONLY : O_RDONLY, 0); + if (fd == -1) { + return MAL_NO_DEVICE; + } + + if (deviceIndex == -1) { + mal_strcpy_s(pDeviceInfo->id.audioio, sizeof(pDeviceInfo->id.audioio), "/dev/audio"); + } else { + mal_construct_device_id__audioio(pDeviceInfo->id.audioio, sizeof(pDeviceInfo->id.audioio), "/dev/audio", deviceIndex); + } + + mal_result result = mal_context_get_device_info_from_fd__audioio(pContext, deviceType, fd, pDeviceInfo); + + close(fd); + return result; +} + +void mal_device_uninit__audioio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + close(pDevice->audioio.fd); + mal_free(pDevice->audioio.pIntermediaryBuffer); +} + +mal_result mal_device_init__audioio(mal_context* pContext, mal_device_type deviceType, const mal_device_id* pDeviceID, const mal_device_config* pConfig, mal_device* pDevice) +{ + (void)pContext; + + mal_assert(pDevice != NULL); + mal_zero_object(&pDevice->audioio); + + // The first thing to do is open the file. + const char* deviceName = "/dev/audio"; + if (pDeviceID != NULL) { + deviceName = pDeviceID->audioio; + } + + pDevice->audioio.fd = open(deviceName, (deviceType == mal_device_type_playback) ? O_WRONLY : O_RDONLY, 0); + if (pDevice->audioio.fd == -1) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to open device.", MAL_FAILED_TO_OPEN_BACKEND_DEVICE); + } + + audio_info_t fdInfo; + AUDIO_INITINFO(&fdInfo); + + struct audio_prinfo* prinfo; + if (deviceType == mal_device_type_playback) { + prinfo = &fdInfo.play; + fdInfo.mode = AUMODE_PLAY; + } else { + prinfo = &fdInfo.record; + fdInfo.mode = AUMODE_RECORD; + } + + // Format. Note that it looks like audioio does not support floating point formats. In this case + // we just fall back to s16. + switch (pDevice->format) + { + case mal_format_u8: + { + prinfo->encoding = AUDIO_ENCODING_ULINEAR; + prinfo->precision = 8; + } break; + + case mal_format_s24: + { + prinfo->encoding = (mal_is_little_endian()) ? AUDIO_ENCODING_SLINEAR_LE : AUDIO_ENCODING_SLINEAR_BE; + prinfo->precision = 24; + } break; + + case mal_format_s32: + { + prinfo->encoding = (mal_is_little_endian()) ? AUDIO_ENCODING_SLINEAR_LE : AUDIO_ENCODING_SLINEAR_BE; + prinfo->precision = 32; + } break; + + case mal_format_s16: + case mal_format_f32: + default: + { + prinfo->encoding = (mal_is_little_endian()) ? AUDIO_ENCODING_SLINEAR_LE : AUDIO_ENCODING_SLINEAR_BE; + prinfo->precision = 16; + } break; + } + + // We always want to the use the devices native channel count and sample rate. + mal_device_info nativeInfo; + mal_result result = mal_context_get_device_info(pContext, deviceType, pDeviceID, pConfig->shareMode, &nativeInfo); + if (result != MAL_SUCCESS) { + close(pDevice->audioio.fd); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to retrieve device format.", result); + } + + prinfo->channels = nativeInfo.maxChannels; + prinfo->sample_rate = nativeInfo.maxSampleRate; + + // We need to apply the settings so far so we can get back the actual sample rate which we need for calculating + // the default buffer size below. + if (ioctl(pDevice->audioio.fd, AUDIO_SETINFO, &fdInfo) < 0) { + close(pDevice->audioio.fd); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to set device format. AUDIO_SETINFO failed.", MAL_FORMAT_NOT_SUPPORTED); + } + + if (ioctl(pDevice->audioio.fd, AUDIO_GETINFO, &fdInfo) < 0) { + close(pDevice->audioio.fd); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] AUDIO_GETINFO failed.", MAL_FORMAT_NOT_SUPPORTED); + } + + pDevice->internalFormat = mal_format_from_prinfo__audioio(prinfo); + if (pDevice->internalFormat == mal_format_unknown) { + close(pDevice->audioio.fd); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] The device's internal device format is not supported by mini_al. The device is unusable.", MAL_FORMAT_NOT_SUPPORTED); + } + + pDevice->internalChannels = prinfo->channels; + pDevice->internalSampleRate = prinfo->sample_rate; + + + + // Try calculating an appropriate default buffer size. + if (pDevice->usingDefaultBufferSize) { + // CPU speed factor. + float fCPUSpeed = mal_calculate_cpu_speed_factor(); + + // Playback vs capture latency. + float fDeviceType = 1; + + // Backend tax. + float fBackend = 1; + + pDevice->bufferSizeInFrames = mal_calculate_default_buffer_size_in_frames(pConfig->performanceProfile, pDevice->internalSampleRate, fCPUSpeed*fDeviceType*fBackend); + } + + // What mini_al calls a fragment, audioio calls a block. + mal_uint32 fragmentSizeInBytes = pDevice->bufferSizeInFrames * mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels); + if (fragmentSizeInBytes < 16) { + fragmentSizeInBytes = 16; + } + + + AUDIO_INITINFO(&fdInfo); + fdInfo.blocksize = fragmentSizeInBytes; + fdInfo.hiwat = mal_max(pDevice->periods, 5); + fdInfo.lowat = (unsigned int)(fdInfo.hiwat * 0.75); + if (ioctl(pDevice->audioio.fd, AUDIO_SETINFO, &fdInfo) < 0) { + close(pDevice->audioio.fd); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to set internal buffer size. AUDIO_SETINFO failed.", MAL_FORMAT_NOT_SUPPORTED); + } + + pDevice->periods = fdInfo.hiwat; + pDevice->bufferSizeInFrames = (fdInfo.blocksize * fdInfo.hiwat) / mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels); + + pDevice->audioio.fragmentSizeInFrames = fdInfo.blocksize / mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels); + + + // For the channel map, I'm not sure how to query the channel map (or if it's even possible). I'm just + // using mini_al's default channel map for now. + mal_get_standard_channel_map(mal_standard_channel_map_default, pDevice->internalChannels, pDevice->internalChannelMap); + + + // When not using MMAP mode we need to use an intermediary buffer to the data transfer between the client + // and device. Everything is done by the size of a fragment. + pDevice->audioio.pIntermediaryBuffer = mal_malloc(fdInfo.blocksize); + if (pDevice->audioio.pIntermediaryBuffer == NULL) { + close(pDevice->audioio.fd); + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to allocate memory for intermediary buffer.", MAL_OUT_OF_MEMORY); + } + + + return MAL_SUCCESS; +} + +mal_result mal_device__start_backend__audioio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + // The device is started by the next calls to read() and write(). For playback it's simple - just read + // data from the client, then write it to the device with write() which will in turn start the device. + // For capture it's a bit less intuitive - we do nothing (it'll be started automatically by the first + // call to read(). + if (pDevice->type == mal_device_type_playback) { + // Playback. Need to load the entire buffer, which means we need to write a fragment for each period. + for (mal_uint32 iPeriod = 0; iPeriod < pDevice->periods; iPeriod += 1) { + mal_device__read_frames_from_client(pDevice, pDevice->audioio.fragmentSizeInFrames, pDevice->audioio.pIntermediaryBuffer); + + int bytesWritten = write(pDevice->audioio.fd, pDevice->audioio.pIntermediaryBuffer, pDevice->audioio.fragmentSizeInFrames * mal_get_bytes_per_frame(pDevice->internalFormat, pDevice->internalChannels)); + if (bytesWritten == -1) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to send initial chunk of data to the device.", MAL_FAILED_TO_SEND_DATA_TO_DEVICE); + } + } + } else { + // Capture. Do nothing. + } + + return MAL_SUCCESS; +} + +mal_result mal_device__stop_backend__audioio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + if (ioctl(pDevice->audioio.fd, AUDIO_FLUSH, 0) < 0) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to stop device. AUDIO_FLUSH failed.", MAL_FAILED_TO_STOP_BACKEND_DEVICE); + } + + return MAL_SUCCESS; +} + +mal_result mal_device__break_main_loop__audioio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + pDevice->audioio.breakFromMainLoop = MAL_TRUE; + return MAL_SUCCESS; +} + +mal_result mal_device__main_loop__audioio(mal_device* pDevice) +{ + mal_assert(pDevice != NULL); + + pDevice->audioio.breakFromMainLoop = MAL_FALSE; + while (!pDevice->audioio.breakFromMainLoop) { + // Break from the main loop if the device isn't started anymore. Likely what's happened is the application + // has requested that the device be stopped. + if (!mal_device_is_started(pDevice)) { + break; + } + + if (pDevice->type == mal_device_type_playback) { + // Playback. + mal_device__read_frames_from_client(pDevice, pDevice->audioio.fragmentSizeInFrames, pDevice->audioio.pIntermediaryBuffer); + + int bytesWritten = write(pDevice->audioio.fd, pDevice->audioio.pIntermediaryBuffer, pDevice->audioio.fragmentSizeInFrames * pDevice->internalChannels * mal_get_bytes_per_sample(pDevice->internalFormat)); + if (bytesWritten < 0) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to send data from the client to the device.", MAL_FAILED_TO_SEND_DATA_TO_DEVICE); + } + } else { + // Capture. + int bytesRead = read(pDevice->audioio.fd, pDevice->audioio.pIntermediaryBuffer, pDevice->audioio.fragmentSizeInFrames * mal_get_bytes_per_sample(pDevice->internalFormat)); + if (bytesRead < 0) { + return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[audioio] Failed to read data from the device to be sent to the client.", MAL_FAILED_TO_READ_DATA_FROM_DEVICE); + } + + mal_uint32 framesRead = (mal_uint32)bytesRead / pDevice->internalChannels / mal_get_bytes_per_sample(pDevice->internalFormat); + mal_device__send_frames_to_client(pDevice, framesRead, pDevice->audioio.pIntermediaryBuffer); + } + } + + return MAL_SUCCESS; +} + +mal_result mal_context_uninit__audioio(mal_context* pContext) +{ + mal_assert(pContext != NULL); + mal_assert(pContext->backend == mal_backend_audioio); + + (void)pContext; + return MAL_SUCCESS; +} + +mal_result mal_context_init__audioio(mal_context* pContext) +{ + mal_assert(pContext != NULL); + + pContext->onUninit = mal_context_uninit__audioio; + pContext->onDeviceIDEqual = mal_context_is_device_id_equal__audioio; + pContext->onEnumDevices = mal_context_enumerate_devices__audioio; + pContext->onGetDeviceInfo = mal_context_get_device_info__audioio; + pContext->onDeviceInit = mal_device_init__audioio; + pContext->onDeviceUninit = mal_device_uninit__audioio; + pContext->onDeviceStart = mal_device__start_backend__audioio; + pContext->onDeviceStop = mal_device__stop_backend__audioio; + pContext->onDeviceBreakMainLoop = mal_device__break_main_loop__audioio; + pContext->onDeviceMainLoop = mal_device__main_loop__audioio; + + return MAL_SUCCESS; +} +#endif // audioio + + /////////////////////////////////////////////////////////////////////////////// // // OSS Backend @@ -14747,10 +16463,10 @@ mal_result mal_context_get_device_info__oss(mal_context* pContext, mal_device_ty if ((formatMask & AFMT_U8) != 0) { pDeviceInfo->formats[pDeviceInfo->formatCount++] = mal_format_u8; } - if ((formatMask & AFMT_S16_LE) != 0) { + if (((formatMask & AFMT_S16_LE) != 0 && mal_is_little_endian()) || (AFMT_S16_BE && mal_is_big_endian())) { pDeviceInfo->formats[pDeviceInfo->formatCount++] = mal_format_s16; } - if ((formatMask & AFMT_S32_LE) != 0) { + if (((formatMask & AFMT_S32_LE) != 0 && mal_is_little_endian()) || (AFMT_S32_BE && mal_is_big_endian())) { pDeviceInfo->formats[pDeviceInfo->formatCount++] = mal_format_s32; } @@ -14804,10 +16520,10 @@ mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, con // Format. int ossFormat = AFMT_U8; switch (pDevice->format) { - case mal_format_s16: ossFormat = AFMT_S16_LE; break; - case mal_format_s24: ossFormat = AFMT_S32_LE; break; - case mal_format_s32: ossFormat = AFMT_S32_LE; break; - case mal_format_f32: ossFormat = AFMT_S32_LE; break; + case mal_format_s16: ossFormat = (mal_is_little_endian()) ? AFMT_S16_LE : AFMT_S16_BE; break; + case mal_format_s24: ossFormat = (mal_is_little_endian()) ? AFMT_S32_LE : AFMT_S32_BE; break; + case mal_format_s32: ossFormat = (mal_is_little_endian()) ? AFMT_S32_LE : AFMT_S32_BE; break; + case mal_format_f32: ossFormat = (mal_is_little_endian()) ? AFMT_S32_LE : AFMT_S32_BE; break; case mal_format_u8: default: ossFormat = AFMT_U8; break; } @@ -14817,14 +16533,24 @@ mal_result mal_device_init__oss(mal_context* pContext, mal_device_type type, con return mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[OSS] Failed to set format.", MAL_FORMAT_NOT_SUPPORTED); } - switch (ossFormat) { - case AFMT_U8: pDevice->internalFormat = mal_format_u8; break; - case AFMT_S16_LE: pDevice->internalFormat = mal_format_s16; break; - case AFMT_S32_LE: pDevice->internalFormat = mal_format_s32; break; - default: mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[OSS] The device's internal format is not supported by mini_al.", MAL_FORMAT_NOT_SUPPORTED); + if (ossFormat == AFMT_U8) { + pDevice->internalFormat = mal_format_u8; + } else { + if (mal_is_little_endian()) { + switch (ossFormat) { + case AFMT_S16_LE: pDevice->internalFormat = mal_format_s16; break; + case AFMT_S32_LE: pDevice->internalFormat = mal_format_s32; break; + default: mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[OSS] The device's internal format is not supported by mini_al.", MAL_FORMAT_NOT_SUPPORTED); + } + } else { + switch (ossFormat) { + case AFMT_S16_BE: pDevice->internalFormat = mal_format_s16; break; + case AFMT_S32_BE: pDevice->internalFormat = mal_format_s32; break; + default: mal_post_error(pDevice, MAL_LOG_LEVEL_ERROR, "[OSS] The device's internal format is not supported by mini_al.", MAL_FORMAT_NOT_SUPPORTED); + } + } } - // Channels. int ossChannels = (int)pConfig->channels; ossResult = ioctl(pDevice->oss.fd, SNDCTL_DSP_CHANNELS, &ossChannels); @@ -15538,7 +17264,7 @@ mal_result mal_device_init__opensl(mal_context* pContext, mal_device_type type, pFormat->bitsPerSample = mal_get_bytes_per_sample(pDevice->format)*8; pFormat->containerSize = pFormat->bitsPerSample; // Always tightly packed for now. pFormat->channelMask = mal_channel_map_to_channel_mask__opensl(pConfig->channelMap, pFormat->numChannels); - pFormat->endianness = SL_BYTEORDER_LITTLEENDIAN; + pFormat->endianness = (mal_is_little_endian()) ? SL_BYTEORDER_LITTLEENDIAN : SL_BYTEORDER_BIGENDIAN; // Android has a few restrictions on the format as documented here: https://developer.android.com/ndk/guides/audio/opensl-for-android.html // - Only mono and stereo is supported. @@ -15591,7 +17317,8 @@ mal_result mal_device_init__opensl(mal_context* pContext, mal_device_type type, // Set the output device. if (pDeviceID != NULL) { - MAL_OPENSL_OUTPUTMIX(pDevice->opensl.pOutputMix)->ReRoute((SLOutputMixItf)pDevice->opensl.pOutputMix, 1, &pDeviceID->opensl); + SLuint32 deviceID_OpenSL = pDeviceID->opensl; + MAL_OPENSL_OUTPUTMIX(pDevice->opensl.pOutputMix)->ReRoute((SLOutputMixItf)pDevice->opensl.pOutputMix, 1, &deviceID_OpenSL); } SLDataSource source; @@ -17449,6 +19176,62 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData) mal_CoInitializeEx(pDevice->pContext, NULL, 0); // 0 = COINIT_MULTITHREADED #endif +#if 1 + // When the device is being initialized it's initial state is set to MAL_STATE_UNINITIALIZED. Before returning from + // mal_device_init(), the state needs to be set to something valid. In mini_al the device's default state immediately + // after initialization is stopped, so therefore we need to mark the device as such. mini_al will wait on the worker + // thread to signal an event to know when the worker thread is ready for action. + mal_device__set_state(pDevice, MAL_STATE_STOPPED); + mal_event_signal(&pDevice->stopEvent); + + for (;;) { + // We wait on an event to know when something has requested that the device be started and the main loop entered. + mal_event_wait(&pDevice->wakeupEvent); + + // Default result code. + pDevice->workResult = MAL_SUCCESS; + + // If the reason for the wake up is that we are terminating, just break from the loop. + if (mal_device__get_state(pDevice) == MAL_STATE_UNINITIALIZED) { + break; + } + + // Getting to this point means the device is wanting to get started. The function that has requested that the device + // be started will be waiting on an event (pDevice->startEvent) which means we need to make sure we signal the event + // in both the success and error case. It's important that the state of the device is set _before_ signaling the event. + mal_assert(mal_device__get_state(pDevice) == MAL_STATE_STARTING); + + pDevice->workResult = pDevice->pContext->onDeviceStart(pDevice); + if (pDevice->workResult != MAL_SUCCESS) { + mal_device__set_state(pDevice, MAL_STATE_STOPPED); + mal_event_signal(&pDevice->startEvent); + continue; + } + + // At this point the device should be started. + mal_device__set_state(pDevice, MAL_STATE_STARTED); + mal_event_signal(&pDevice->startEvent); + + + // Now we just enter the main loop. When the main loop is terminated the device needs to be marked as stopped. This can + // be broken with mal_device__break_main_loop(). + pDevice->pContext->onDeviceMainLoop(pDevice); + + + // Getting here means we have broken from the main loop which happens the application has requested that device be stopped. + pDevice->pContext->onDeviceStop(pDevice); + + // After the device has stopped, make sure an event is posted. + mal_stop_proc onStop = pDevice->onStop; + if (onStop) { + onStop(pDevice); + } + + // A function somewhere is waiting for the device to have stopped for real so we need to signal an event to allow it to continue. + mal_device__set_state(pDevice, MAL_STATE_STOPPED); + mal_event_signal(&pDevice->stopEvent); + } +#else // This is only used to prevent posting onStop() when the device is first initialized. mal_bool32 skipNextStopEvent = MAL_TRUE; @@ -17500,6 +19283,7 @@ mal_thread_result MAL_THREADCALL mal_worker_thread(void* pData) // Now we just enter the main loop. The main loop can be broken with mal_device__break_main_loop(). pDevice->pContext->onDeviceMainLoop(pDevice); } +#endif // Make sure we aren't continuously waiting on a stop event. mal_event_signal(&pDevice->stopEvent); // <-- Is this still needed? @@ -17668,20 +19452,6 @@ mal_result mal_context_uninit_backend_apis(mal_context* pContext) return result; } -const mal_backend g_malDefaultBackends[] = { - mal_backend_wasapi, - mal_backend_dsound, - mal_backend_winmm, - mal_backend_coreaudio, - mal_backend_oss, - mal_backend_pulseaudio, - mal_backend_alsa, - mal_backend_jack, - mal_backend_opensl, - mal_backend_openal, - mal_backend_sdl, - mal_backend_null -}; mal_bool32 mal_context_is_backend_asynchronous(mal_context* pContext) { @@ -17765,6 +19535,18 @@ mal_result mal_context_init(const mal_backend backends[], mal_uint32 backendCoun result = mal_context_init__coreaudio(pContext); } break; #endif + #ifdef MAL_HAS_SNDIO + case mal_backend_sndio: + { + result = mal_context_init__sndio(pContext); + } break; + #endif + #ifdef MAL_HAS_AUDIOIO + case mal_backend_audioio: + { + result = mal_context_init__audioio(pContext); + } break; + #endif #ifdef MAL_HAS_OSS case mal_backend_oss: { @@ -18387,19 +20169,6 @@ mal_uint32 mal_device_get_buffer_size_in_bytes(mal_device* pDevice) return pDevice->bufferSizeInFrames * pDevice->channels * mal_get_bytes_per_sample(pDevice->format); } -mal_uint32 mal_get_bytes_per_sample(mal_format format) -{ - mal_uint32 sizes[] = { - 0, // unknown - 1, // u8 - 2, // s16 - 3, // s24 - 4, // s32 - 4, // f32 - }; - return sizes[format]; -} - mal_context_config mal_context_config_init(mal_log_proc onLog) { mal_context_config config; @@ -18462,6 +20231,7 @@ mal_device_config mal_device_config_init_ex(mal_format format, mal_uint32 channe return config; } +#endif // MAL_NO_DEVICE_IO void mal_get_standard_channel_map_microsoft(mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS]) @@ -18863,6 +20633,65 @@ void mal_get_standard_channel_map_vorbis(mal_uint32 channels, mal_channel channe } } +void mal_get_standard_channel_map_sndio(mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS]) +{ + switch (channels) + { + case 1: + { + channelMap[0] = MAL_CHANNEL_MONO; + } break; + + case 2: + { + channelMap[0] = MAL_CHANNEL_LEFT; + channelMap[1] = MAL_CHANNEL_RIGHT; + } break; + + case 3: + { + channelMap[0] = MAL_CHANNEL_FRONT_LEFT; + channelMap[1] = MAL_CHANNEL_FRONT_RIGHT; + channelMap[2] = MAL_CHANNEL_FRONT_CENTER; + } break; + + case 4: + { + channelMap[0] = MAL_CHANNEL_FRONT_LEFT; + channelMap[1] = MAL_CHANNEL_FRONT_RIGHT; + channelMap[2] = MAL_CHANNEL_BACK_LEFT; + channelMap[3] = MAL_CHANNEL_BACK_RIGHT; + } break; + + case 5: + { + channelMap[0] = MAL_CHANNEL_FRONT_LEFT; + channelMap[1] = MAL_CHANNEL_FRONT_RIGHT; + channelMap[2] = MAL_CHANNEL_BACK_LEFT; + channelMap[3] = MAL_CHANNEL_BACK_RIGHT; + channelMap[4] = MAL_CHANNEL_FRONT_CENTER; + } break; + + case 6: + default: + { + channelMap[0] = MAL_CHANNEL_FRONT_LEFT; + channelMap[1] = MAL_CHANNEL_FRONT_RIGHT; + channelMap[2] = MAL_CHANNEL_BACK_LEFT; + channelMap[3] = MAL_CHANNEL_BACK_RIGHT; + channelMap[4] = MAL_CHANNEL_FRONT_CENTER; + channelMap[5] = MAL_CHANNEL_LFE; + } break; + } + + // Remainder. + if (channels > 6) { + for (mal_uint32 iChannel = 6; iChannel < MAL_MAX_CHANNELS; ++iChannel) { + channelMap[iChannel] = (mal_channel)(MAL_CHANNEL_AUX_0 + (iChannel-6)); + } + } +} + void mal_get_standard_channel_map(mal_standard_channel_map standardChannelMap, mal_uint32 channels, mal_channel channelMap[MAL_MAX_CHANNELS]) { switch (standardChannelMap) @@ -18886,6 +20715,11 @@ void mal_get_standard_channel_map(mal_standard_channel_map standardChannelMap, m { mal_get_standard_channel_map_vorbis(channels, channelMap); } break; + + case mal_standard_channel_map_sndio: + { + mal_get_standard_channel_map_sndio(channels, channelMap); + } break; case mal_standard_channel_map_microsoft: default: @@ -22555,6 +24389,23 @@ mal_result mal_src_set_output_sample_rate(mal_src* pSRC, mal_uint32 sampleRateOu return MAL_SUCCESS; } +mal_result mal_src_set_sample_rate(mal_src* pSRC, mal_uint32 sampleRateIn, mal_uint32 sampleRateOut) +{ + if (pSRC == NULL) { + return MAL_INVALID_ARGS; + } + + // Must have a sample rate of > 0. + if (sampleRateIn == 0 || sampleRateOut == 0) { + return MAL_INVALID_ARGS; + } + + mal_atomic_exchange_32(&pSRC->config.sampleRateIn, sampleRateIn); + mal_atomic_exchange_32(&pSRC->config.sampleRateOut, sampleRateOut); + + return MAL_SUCCESS; +} + mal_uint64 mal_src_read_deinterleaved(mal_src* pSRC, mal_uint64 frameCount, void** ppSamplesOut, void* pUserData) { if (pSRC == NULL || frameCount == 0 || ppSamplesOut == NULL) { @@ -23056,8 +24907,8 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount maxInputSamplesAvailableInCache = pSRC->sinc.inputFrameCount; } - // If the last of the input data has been loaded, we need to ensure we don't read into it if it's configured such. - if (pSRC->config.neverConsumeEndOfInput && pSRC->isEndOfInputLoaded) { + // Never consume the tail end of the input data if requested. + if (pSRC->config.neverConsumeEndOfInput) { if (maxInputSamplesAvailableInCache >= pSRC->config.sinc.windowWidth) { maxInputSamplesAvailableInCache -= pSRC->config.sinc.windowWidth; } else { @@ -23249,6 +25100,15 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount } // Read more data from the client if required. + if (pSRC->isEndOfInputLoaded) { + pSRC->isEndOfInputLoaded = MAL_FALSE; + break; + } + + // Everything beyond this point is reloading. If we're at the end of the input data we do _not_ want to try reading any more in this function call. If the + // caller wants to keep trying, they can reload their internal data sources and call this function again. We should never be + mal_assert(pSRC->isEndOfInputLoaded == MAL_FALSE); + if (pSRC->sinc.inputFrameCount <= pSRC->config.sinc.windowWidth || availableOutputFrames == 0) { float* ppInputDst[MAL_MAX_CHANNELS] = {0}; for (mal_uint32 iChannel = 0; iChannel < pSRC->config.channels; iChannel += 1) { @@ -23257,20 +25117,29 @@ mal_uint64 mal_src_read_deinterleaved__sinc(mal_src* pSRC, mal_uint64 frameCount // Now read data from the client. mal_uint32 framesToReadFromClient = mal_countof(pSRC->sinc.input[0]) - (pSRC->config.sinc.windowWidth + pSRC->sinc.inputFrameCount); - if (framesToReadFromClient > 0) { - mal_uint32 framesReadFromClient = pSRC->config.onReadDeinterleaved(pSRC, framesToReadFromClient, (void**)ppInputDst, pUserData); - if (framesReadFromClient != framesToReadFromClient) { - pSRC->isEndOfInputLoaded = MAL_TRUE; - } else { - pSRC->isEndOfInputLoaded = MAL_FALSE; - } - if (framesReadFromClient != 0) { - pSRC->sinc.inputFrameCount += framesReadFromClient; + mal_uint32 framesReadFromClient = 0; + if (framesToReadFromClient > 0) { + framesReadFromClient = pSRC->config.onReadDeinterleaved(pSRC, framesToReadFromClient, (void**)ppInputDst, pUserData); + } + + if (framesReadFromClient != framesToReadFromClient) { + pSRC->isEndOfInputLoaded = MAL_TRUE; + } else { + pSRC->isEndOfInputLoaded = MAL_FALSE; + } + + if (framesReadFromClient != 0) { + pSRC->sinc.inputFrameCount += framesReadFromClient; + } else { + // We couldn't get anything more from the client. If no more output samples can be computed from the available input samples + // we need to return. + if (pSRC->config.neverConsumeEndOfInput) { + if ((pSRC->sinc.inputFrameCount * inverseFactor) <= pSRC->config.sinc.windowWidth) { + break; + } } else { - // We couldn't get anything more from the client. If no more output samples can be computed from the available input samples - // we need to return. - if (((pSRC->sinc.timeIn - pSRC->sinc.inputFrameCount) * inverseFactor) < 1) { + if ((pSRC->sinc.inputFrameCount * inverseFactor) < 1) { break; } } @@ -23712,6 +25581,28 @@ mal_result mal_dsp_set_output_sample_rate(mal_dsp* pDSP, mal_uint32 sampleRateOu return mal_dsp_refresh_sample_rate(pDSP); } +mal_result mal_dsp_set_sample_rate(mal_dsp* pDSP, mal_uint32 sampleRateIn, mal_uint32 sampleRateOut) +{ + if (pDSP == NULL) { + return MAL_INVALID_ARGS; + } + + // Must have a sample rate of > 0. + if (sampleRateIn == 0 || sampleRateOut == 0) { + return MAL_INVALID_ARGS; + } + + // Must have been initialized with allowDynamicSampleRate. + if (!pDSP->isDynamicSampleRateAllowed) { + return MAL_INVALID_OPERATION; + } + + mal_atomic_exchange_32(&pDSP->src.config.sampleRateIn, sampleRateIn); + mal_atomic_exchange_32(&pDSP->src.config.sampleRateOut, sampleRateOut); + + return mal_dsp_refresh_sample_rate(pDSP); +} + mal_uint64 mal_dsp_read(mal_dsp* pDSP, mal_uint64 frameCount, void* pFramesOut, void* pUserData) { if (pDSP == NULL || pFramesOut == NULL) return 0; @@ -23970,26 +25861,6 @@ void mal_aligned_free(void* p) mal_free(((void**)p)[-1]); } -const char* mal_get_backend_name(mal_backend backend) -{ - switch (backend) - { - case mal_backend_null: return "Null"; - case mal_backend_wasapi: return "WASAPI"; - case mal_backend_dsound: return "DirectSound"; - case mal_backend_winmm: return "WinMM"; - case mal_backend_alsa: return "ALSA"; - case mal_backend_pulseaudio: return "PulseAudio"; - case mal_backend_jack: return "JACK"; - case mal_backend_coreaudio: return "Core Audio"; - case mal_backend_oss: return "OSS"; - case mal_backend_opensl: return "OpenSL|ES"; - case mal_backend_openal: return "OpenAL"; - case mal_backend_sdl: return "SDL"; - default: return "Unknown"; - } -} - const char* mal_get_format_name(mal_format format) { switch (format) @@ -24012,136 +25883,19 @@ void mal_blend_f32(float* pOut, float* pInA, float* pInB, float factor, mal_uint } -typedef struct +mal_uint32 mal_get_bytes_per_sample(mal_format format) { - mal_uint8* pInputFrames; - mal_uint32 framesRemaining; -} mal_calculate_cpu_speed_factor_data; - -mal_uint32 mal_calculate_cpu_speed_factor__on_read(mal_dsp* pDSP, mal_uint32 framesToRead, void* pFramesOut, void* pUserData) -{ - mal_calculate_cpu_speed_factor_data* pData = (mal_calculate_cpu_speed_factor_data*)pUserData; - mal_assert(pData != NULL); - - if (framesToRead > pData->framesRemaining) { - framesToRead = pData->framesRemaining; - } - - mal_copy_memory(pFramesOut, pData->pInputFrames, framesToRead*pDSP->formatConverterIn.config.channels * sizeof(*pData->pInputFrames)); - - pData->pInputFrames += framesToRead; - pData->framesRemaining -= framesToRead; - - return framesToRead; + mal_uint32 sizes[] = { + 0, // unknown + 1, // u8 + 2, // s16 + 3, // s24 + 4, // s32 + 4, // f32 + }; + return sizes[format]; } -float mal_calculate_cpu_speed_factor() -{ - // Our profiling test is based on how quick it can process 1 second worth of samples through mini_al's data conversion pipeline. - - // This factor is multiplied with the profiling time. May need to fiddle with this to get an accurate value. - double f = 1000; - - // Experiment: Reduce the factor a little when debug mode is used to reduce a blowout. -#if !defined(NDEBUG) || defined(_DEBUG) - f /= 2; -#endif - - mal_uint32 sampleRateIn = 44100; - mal_uint32 sampleRateOut = 48000; - mal_uint32 channelsIn = 2; - mal_uint32 channelsOut = 6; - - // Using the heap here to avoid an unnecessary static memory allocation. Also too big for the stack. - mal_uint8* pInputFrames = NULL; - float* pOutputFrames = NULL; - - size_t inputDataSize = sampleRateIn * channelsIn * sizeof(*pInputFrames); - size_t outputDataSize = sampleRateOut * channelsOut * sizeof(*pOutputFrames); - - void* pData = mal_malloc(inputDataSize + outputDataSize); - if (pData == NULL) { - return 1; - } - - pInputFrames = (mal_uint8*)pData; - pOutputFrames = (float*)(pInputFrames + inputDataSize); - - - - - mal_calculate_cpu_speed_factor_data data; - data.pInputFrames = pInputFrames; - data.framesRemaining = sampleRateIn; - - mal_dsp_config config = mal_dsp_config_init(mal_format_u8, channelsIn, sampleRateIn, mal_format_f32, channelsOut, sampleRateOut, mal_calculate_cpu_speed_factor__on_read, &data); - - // Use linear sample rate conversion because it's the simplest and least likely to cause skewing as a result of tweaks to default - // configurations in the future. - config.srcAlgorithm = mal_src_algorithm_linear; - - // Experiment: Disable SIMD extensions when profiling just to try and keep things a bit more consistent. The idea is to get a general - // indication on the speed of the system, but SIMD is used more heavily in the DSP pipeline than in the general case which may make - // the results a little less realistic. - config.noSSE2 = MAL_TRUE; - config.noAVX2 = MAL_TRUE; - config.noAVX512 = MAL_TRUE; - config.noNEON = MAL_TRUE; - - mal_dsp dsp; - mal_result result = mal_dsp_init(&config, &dsp); - if (result != MAL_SUCCESS) { - mal_free(pData); - return 1; - } - - - int iterationCount = 2; - - mal_timer timer; - mal_timer_init(&timer); - double startTime = mal_timer_get_time_in_seconds(&timer); - { - for (int i = 0; i < iterationCount; ++i) { - mal_dsp_read(&dsp, sampleRateOut, pOutputFrames, &data); - data.pInputFrames = pInputFrames; - data.framesRemaining = sampleRateIn; - } - } - double executionTimeInSeconds = mal_timer_get_time_in_seconds(&timer) - startTime; - executionTimeInSeconds /= iterationCount; - - - mal_free(pData); - - // Guard against extreme blowouts. - return (float)mal_clamp(executionTimeInSeconds * f, 0.1, 100.0); -} - -mal_uint32 mal_scale_buffer_size(mal_uint32 baseBufferSize, float scale) -{ - return mal_max(1, (mal_uint32)(baseBufferSize*scale)); -} - -mal_uint32 mal_calculate_default_buffer_size_in_frames(mal_performance_profile performanceProfile, mal_uint32 sampleRate, float scale) -{ - mal_uint32 baseLatency; - if (performanceProfile == mal_performance_profile_low_latency) { - baseLatency = MAL_BASE_BUFFER_SIZE_IN_MILLISECONDS_LOW_LATENCY; - } else { - baseLatency = MAL_BASE_BUFFER_SIZE_IN_MILLISECONDS_CONSERVATIVE; - } - - mal_uint32 sampleRateMS = (sampleRate/1000); - - mal_uint32 minBufferSize = sampleRateMS * mal_min(baseLatency / 5, 1); // <-- Guard against multiply by zero. - mal_uint32 maxBufferSize = sampleRateMS * (baseLatency * 40); - - mal_uint32 bufferSize = mal_scale_buffer_size((sampleRate/1000) * baseLatency, scale); - return mal_clamp(bufferSize, minBufferSize, maxBufferSize); -} - - ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -24211,6 +25965,11 @@ mal_result mal_decoder__init_dsp(mal_decoder* pDecoder, const mal_decoder_config pDecoder->internalFormat, pDecoder->internalChannels, pDecoder->internalSampleRate, pDecoder->internalChannelMap, pDecoder->outputFormat, pDecoder->outputChannels, pDecoder->outputSampleRate, pDecoder->outputChannelMap, onRead, pDecoder); + dspConfig.channelMixMode = pConfig->channelMixMode; + dspConfig.ditherMode = pConfig->ditherMode; + dspConfig.srcAlgorithm = pConfig->srcAlgorithm; + dspConfig.sinc = pConfig->src.sinc; + return mal_dsp_init(&dspConfig, &pDecoder->dsp); } @@ -25624,6 +27383,21 @@ mal_uint64 mal_sine_wave_read(mal_sine_wave* pSineWave, mal_uint64 count, float* // REVISION HISTORY // ================ // +// v0.8.5-rc - 2018-xx-xx +// - Fix a bug where an incorrect number of samples is returned from sinc resampling. +// +// v0.8.4 - 2018-08-06 +// - Add sndio backend for OpenBSD. +// - Add audioio backend for NetBSD. +// - Drop support for the OSS backend on everything except FreeBSD and DragonFly BSD. +// - Formats are now native-endian (were previously little-endian). +// - Mark some APIs as deprecated: +// - mal_src_set_input_sample_rate() and mal_src_set_output_sample_rate() are replaced with mal_src_set_sample_rate(). +// - mal_dsp_set_input_sample_rate() and mal_dsp_set_output_sample_rate() are replaced with mal_dsp_set_sample_rate(). +// - Fix a bug when capturing using the WASAPI backend. +// - Fix some aliasing issues with resampling, specifically when increasing the sample rate. +// - Fix warnings. +// // v0.8.3 - 2018-07-15 // - Fix a crackling bug when resampling in capture mode. // - Core Audio: Fix a bug where capture does not work.