|
@@ -400,27 +400,36 @@
|
|
|
was called, so you don't need to worry about thread-safety.
|
|
|
|
|
|
|
|
|
- LOG FUNCTION OVERRIDE
|
|
|
- =====================
|
|
|
- You can override the log function at initialization time like this:
|
|
|
-
|
|
|
- void my_log(const char* message, void* user_data) {
|
|
|
- printf("saudio says: \s\n", message);
|
|
|
+ LOGGING AND ERROR REPORTING OVERRIDE
|
|
|
+ ====================================
|
|
|
+ To override logging, first write a logging function like this:
|
|
|
+
|
|
|
+ void my_log(const char* tag, // e.g. 'saudio'
|
|
|
+ uint32_t log_level, // 0=panic, 1=error, 2=warn, 3=info
|
|
|
+ uint32_t log_item, // SAUDIO_LOGITEM_*
|
|
|
+ const char* log_item_str, // log item as string, only in debug mode, otherwise empty string
|
|
|
+ int line_nr, // line number in sokol_audio.h
|
|
|
+ const char* filename, // debug mode only, otherwise empty string
|
|
|
+ void* user_data)
|
|
|
+ {
|
|
|
+ ...
|
|
|
}
|
|
|
|
|
|
- ...
|
|
|
- saudio_setup(&(saudio_desc){
|
|
|
- // ...
|
|
|
- .logger = {
|
|
|
- .log_cb = my_log,
|
|
|
- .user_data = ...,
|
|
|
- }
|
|
|
- });
|
|
|
- ...
|
|
|
+ ...and then setup sokol-audio like this:
|
|
|
+
|
|
|
+ saudio_setup(&(saudio_desc){
|
|
|
+ .logger = {
|
|
|
+ .func = my_log,
|
|
|
+ .user_data = ...,
|
|
|
+ }
|
|
|
+ });
|
|
|
|
|
|
- If no overrides are provided, puts will be used on most platforms.
|
|
|
- On Android, __android_log_write will be used instead.
|
|
|
+ The provided logging function should be reentrant (e.g. be callable from
|
|
|
+ different threads).
|
|
|
|
|
|
+ If no custom logger is provided, verbose default logging goes to stderr
|
|
|
+ (this means you won't see any logging messages on Android, or on Windows
|
|
|
+ unless the process is attached to a terminal!).
|
|
|
|
|
|
LICENSE
|
|
|
=======
|
|
@@ -470,6 +479,91 @@
|
|
|
extern "C" {
|
|
|
#endif
|
|
|
|
|
|
+/*
|
|
|
+ saudio_log_item
|
|
|
+
|
|
|
+ Log items are defined via X-Macros, and expanded to an
|
|
|
+ enum 'saudio_log_item', and in debug mode only,
|
|
|
+ corresponding strings.
|
|
|
+
|
|
|
+ Used as parameter in the logging callback.
|
|
|
+*/
|
|
|
+#define _SAUDIO_LOG_ITEMS \
|
|
|
+ _SAUDIO_XMACRO(OK) \
|
|
|
+ _SAUDIO_XMACRO(MALLOC_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(ALSA_SNDPCMOPEN_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(ALSA_FLOAT_SAMPLES_NOT_SUPPORTED) \
|
|
|
+ _SAUDIO_XMACRO(ALSA_REQUESTED_BUFFER_SIZE_NOT_SUPPORTED) \
|
|
|
+ _SAUDIO_XMACRO(ALSA_REQUESTED_CHANNEL_COUNT_NOT_SUPPORTED) \
|
|
|
+ _SAUDIO_XMACRO(ALSA_SND_PCM_HW_PARAMS_SET_RATE_NEAR_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(ALSA_SND_PCM_HW_PARAMS_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(ALSA_PTHREAD_CREATE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_CREATE_EVENT_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_CREATE_DEVICE_ENUMERATOR_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_GET_DEFAULT_AUDIO_ENDPOINT_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_DEVICE_ACTIVATE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_AUDIO_CLIENT_INITIALIZE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_AUDIO_CLIENT_GET_BUFFER_SIZE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_AUDIO_CLIENT_GET_SERVICE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_AUDIO_CLIENT_SET_EVENT_HANDLE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(WASAPI_CREATE_THREAD_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(AAUDIO_STREAMBUILDER_OPEN_STREAM_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(AAUDIO_PTHREAD_CREATE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(AAUDIO_RESTARTING_STREAM_AFTER_ERROR) \
|
|
|
+ _SAUDIO_XMACRO(USING_AAUDIO_BACKEND) \
|
|
|
+ _SAUDIO_XMACRO(AAUDIO_CREATE_STREAMBUILDER_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(USING_SLES_BACKEND) \
|
|
|
+ _SAUDIO_XMACRO(SLES_CREATE_ENGINE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(SLES_ENGINE_GET_ENGINE_INTERFACE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(SLES_CREATE_OUTPUT_MIX_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(SLES_MIXER_GET_VOLUME_INTERFACE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(SLES_ENGINE_CREATE_AUDIO_PLAYER_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(SLES_PLAYER_GET_PLAY_INTERFACE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(SLES_PLAYER_GET_VOLUME_INTERFACE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(SLES_PLAYER_GET_BUFFERQUEUE_INTERFACE_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(COREAUDIO_NEW_OUTPUT_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(COREAUDIO_ALLOCATE_BUFFER_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(COREAUDIO_START_FAILED) \
|
|
|
+ _SAUDIO_XMACRO(BACKEND_BUFFER_SIZE_ISNT_MULTIPLE_OF_PACKET_SIZE) \
|
|
|
+
|
|
|
+#define _SAUDIO_XMACRO(item) SAUDIO_LOGITEM_##item,
|
|
|
+typedef enum saudio_log_item {
|
|
|
+ _SAUDIO_LOG_ITEMS
|
|
|
+} saudio_log_item;
|
|
|
+#undef _SAUDIO_XMACRO
|
|
|
+
|
|
|
+/*
|
|
|
+ saudio_loglevel
|
|
|
+
|
|
|
+ Used as parameter in the logging callback. Note that
|
|
|
+ loglevel PANIC is expected to terminate the application
|
|
|
+ because execution cannot continue.
|
|
|
+*/
|
|
|
+typedef enum saudio_loglevel {
|
|
|
+ SAUDIO_LOGLEVEL_PANIC = 0,
|
|
|
+ SAUDIO_LOGLEVEL_ERROR = 1,
|
|
|
+ SAUDIO_LOGLEVEL_WARN = 2,
|
|
|
+ SAUDIO_LOGLEVEL_INFO = 3,
|
|
|
+} saudio_loglevel;
|
|
|
+
|
|
|
+/*
|
|
|
+ saudio_logger
|
|
|
+
|
|
|
+ Used in saudio_desc to provide a custom logging and error reporting
|
|
|
+ callback to sokol-audio.
|
|
|
+*/
|
|
|
+typedef struct saudio_logger {
|
|
|
+ void (*func)(
|
|
|
+ const char* tag, // always "saudio"
|
|
|
+ uint32_t log_level, // 0=panic, 1=error, 2=warning, 3=info
|
|
|
+ uint32_t log_item, // SAUDIO_LOGITEM_*
|
|
|
+ const char* log_item_str, // log item as string, debug only, otherwise empty string
|
|
|
+ int line_nr, // line number in sokol_audio.h
|
|
|
+ const char* filename, // debug mode only, otherwise empty string
|
|
|
+ void* user_data);
|
|
|
+ void* user_data;
|
|
|
+} saudio_logger;
|
|
|
+
|
|
|
/*
|
|
|
saudio_allocator
|
|
|
|
|
@@ -484,17 +578,6 @@ typedef struct saudio_allocator {
|
|
|
void* user_data;
|
|
|
} saudio_allocator;
|
|
|
|
|
|
-/*
|
|
|
- saudio_logger
|
|
|
-
|
|
|
- Used in saudio_desc to provide custom log callbacks to sokol_audio.h.
|
|
|
- Default behavior is SOKOL_LOG(message).
|
|
|
-*/
|
|
|
-typedef struct saudio_logger {
|
|
|
- void (*log_cb)(const char* message, void* user_data);
|
|
|
- void* user_data;
|
|
|
-} saudio_logger;
|
|
|
-
|
|
|
typedef struct saudio_desc {
|
|
|
int sample_rate; // requested sample rate
|
|
|
int num_channels; // number of channels, default: 1 (mono)
|
|
@@ -572,21 +655,6 @@ inline void saudio_setup(const saudio_desc& desc) { return saudio_setup(&desc);
|
|
|
#define SOKOL_ASSERT(c) assert(c)
|
|
|
#endif
|
|
|
|
|
|
-#if !defined(SOKOL_DEBUG)
|
|
|
- #define SAUDIO_LOG(s)
|
|
|
-#else
|
|
|
- #define SAUDIO_LOG(s) _saudio_log(s)
|
|
|
- #ifndef SOKOL_LOG
|
|
|
- #if defined(__ANDROID__)
|
|
|
- #include <android/log.h>
|
|
|
- #define SOKOL_LOG(s) __android_log_write(ANDROID_LOG_INFO, "SOKOL_AUDIO", s)
|
|
|
- #else
|
|
|
- #include <stdio.h>
|
|
|
- #define SOKOL_LOG(s) puts(s)
|
|
|
- #endif
|
|
|
- #endif
|
|
|
-#endif
|
|
|
-
|
|
|
#ifndef _SOKOL_PRIVATE
|
|
|
#if defined(__GNUC__) || defined(__clang__)
|
|
|
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
|
@@ -616,9 +684,7 @@ inline void saudio_setup(const saudio_desc& desc) { return saudio_setup(&desc);
|
|
|
#define _SAUDIO_WINDOWS (1)
|
|
|
#include <winapifamily.h>
|
|
|
#if (defined(WINAPI_FAMILY_PARTITION) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
|
|
|
- #define _SAUDIO_UWP (1)
|
|
|
- #else
|
|
|
- #define _SAUDIO_WIN32 (1)
|
|
|
+ #error "sokol_audio.h no longer supports UWP"
|
|
|
#endif
|
|
|
#elif defined(__ANDROID__)
|
|
|
#define _SAUDIO_ANDROID (1)
|
|
@@ -644,12 +710,8 @@ inline void saudio_setup(const saudio_desc& desc) { return saudio_setup(&desc);
|
|
|
#endif
|
|
|
#include <windows.h>
|
|
|
#include <synchapi.h>
|
|
|
- #if defined(_SAUDIO_UWP)
|
|
|
- #pragma comment (lib, "WindowsApp")
|
|
|
- #else
|
|
|
- #pragma comment (lib, "kernel32")
|
|
|
- #pragma comment (lib, "ole32")
|
|
|
- #endif
|
|
|
+ #pragma comment (lib, "kernel32")
|
|
|
+ #pragma comment (lib, "ole32")
|
|
|
#ifndef CINTERFACE
|
|
|
#define CINTERFACE
|
|
|
#endif
|
|
@@ -939,15 +1001,8 @@ typedef struct {
|
|
|
} _saudio_wasapi_thread_data_t;
|
|
|
|
|
|
typedef struct {
|
|
|
- #if defined(_SAUDIO_UWP)
|
|
|
- LPOLESTR interface_activation_audio_interface_uid_string;
|
|
|
- IActivateAudioInterfaceAsyncOperation* interface_activation_operation;
|
|
|
- BOOL interface_activation_success;
|
|
|
- HANDLE interface_activation_mutex;
|
|
|
- #else
|
|
|
- IMMDeviceEnumerator* device_enumerator;
|
|
|
- IMMDevice* device;
|
|
|
- #endif
|
|
|
+ IMMDeviceEnumerator* device_enumerator;
|
|
|
+ IMMDevice* device;
|
|
|
IAudioClient* audio_client;
|
|
|
IAudioRenderClient* render_client;
|
|
|
_saudio_wasapi_thread_data_t thread;
|
|
@@ -1032,6 +1087,69 @@ _SOKOL_PRIVATE void _saudio_stream_callback(float* buffer, int num_frames, int n
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// ██╗ ██████╗ ██████╗ ██████╗ ██╗███╗ ██╗ ██████╗
|
|
|
+// ██║ ██╔═══██╗██╔════╝ ██╔════╝ ██║████╗ ██║██╔════╝
|
|
|
+// ██║ ██║ ██║██║ ███╗██║ ███╗██║██╔██╗ ██║██║ ███╗
|
|
|
+// ██║ ██║ ██║██║ ██║██║ ██║██║██║╚██╗██║██║ ██║
|
|
|
+// ███████╗╚██████╔╝╚██████╔╝╚██████╔╝██║██║ ╚████║╚██████╔╝
|
|
|
+// ╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝
|
|
|
+//
|
|
|
+// >>logging
|
|
|
+#if defined(SOKOL_DEBUG)
|
|
|
+#define _SAUDIO_XMACRO(item) #item,
|
|
|
+static const char* _saudio_log_item_str[] = {
|
|
|
+ _SAUDIO_LOG_ITEMS
|
|
|
+};
|
|
|
+#undef _SSPINE_XMACRO
|
|
|
+#endif // SOKOL_DEBUG
|
|
|
+
|
|
|
+#define _SAUDIO_PANIC(code) _saudio_log(SAUDIO_LOGITEM_ ##code, SAUDIO_LOGLEVEL_PANIC, __LINE__)
|
|
|
+#define _SAUDIO_ERROR(code) _saudio_log(SAUDIO_LOGITEM_ ##code, SAUDIO_LOGLEVEL_ERROR, __LINE__)
|
|
|
+#define _SAUDIO_WARN(code) _saudio_log(SAUDIO_LOGITEM_ ##code, SAUDIO_LOGLEVEL_WARN, __LINE__)
|
|
|
+#define _SAUDIO_INFO(code) _saudio_log(SAUDIO_LOGITEM_ ##code, SAUDIO_LOGLEVEL_INFO, __LINE__)
|
|
|
+
|
|
|
+static void _saudio_log(saudio_log_item log_item, saudio_loglevel log_level, int line_nr) {
|
|
|
+ if (_saudio.desc.logger.func) {
|
|
|
+ #if defined(SOKOL_DEBUG)
|
|
|
+ const char* filename = __FILE__;
|
|
|
+ const char* log_item_str = _saudio_log_item_str[log_item];
|
|
|
+ #else
|
|
|
+ const char* filename = "";
|
|
|
+ const char* log_item_str = "";
|
|
|
+ #endif
|
|
|
+ _saudio.desc.logger.func("saudio", log_level, log_item, log_item_str, line_nr, filename, _saudio.desc.logger.user_data);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ // default logging function, uses printf only if debugging is enabled to save executable size
|
|
|
+ const char* loglevel_str;
|
|
|
+ switch (log_level) {
|
|
|
+ case SAUDIO_LOGLEVEL_PANIC: loglevel_str = "panic"; break;
|
|
|
+ case SAUDIO_LOGLEVEL_ERROR: loglevel_str = "error"; break;
|
|
|
+ case SAUDIO_LOGLEVEL_WARN: loglevel_str = "warning"; break;
|
|
|
+ default: loglevel_str = "info"; break;
|
|
|
+ }
|
|
|
+ #if defined(SOKOL_DEBUG)
|
|
|
+ const char* log_item_str = _saudio_log_item_str[log_item];
|
|
|
+ #if defined(_MSC_VER)
|
|
|
+ // Visual Studio compiler error format
|
|
|
+ fprintf(stderr, "[saudio] %s(%d): %s: %s\n", __FILE__, line_nr, loglevel_str, log_item_str);
|
|
|
+ #else
|
|
|
+ // GCC error format
|
|
|
+ fprintf(stderr, "[saudio] %s:%d:0: %s: %s\n", __FILE__, line_nr, loglevel_str, log_item_str);
|
|
|
+ #endif
|
|
|
+ #else
|
|
|
+ fputs("[saudio] ", stderr);
|
|
|
+ fputs(loglevel_str, stderr);
|
|
|
+ fputs(" (build in debug mode for more info)\n", stderr);
|
|
|
+ #endif // SOKOL_DEBUG
|
|
|
+
|
|
|
+ // for log level PANIC it would be 'undefined behaviour' to continue
|
|
|
+ if (log_level == SAUDIO_LOGLEVEL_PANIC) {
|
|
|
+ abort();
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
// ███╗ ███╗███████╗███╗ ███╗ ██████╗ ██████╗ ██╗ ██╗
|
|
|
// ████╗ ████║██╔════╝████╗ ████║██╔═══██╗██╔══██╗╚██╗ ██╔╝
|
|
|
// ██╔████╔██║█████╗ ██╔████╔██║██║ ██║██████╔╝ ╚████╔╝
|
|
@@ -1054,7 +1172,9 @@ _SOKOL_PRIVATE void* _saudio_malloc(size_t size) {
|
|
|
else {
|
|
|
ptr = malloc(size);
|
|
|
}
|
|
|
- SOKOL_ASSERT(ptr);
|
|
|
+ if (0 == ptr) {
|
|
|
+ _SAUDIO_PANIC(MALLOC_FAILED);
|
|
|
+ }
|
|
|
return ptr;
|
|
|
}
|
|
|
|
|
@@ -1073,17 +1193,6 @@ _SOKOL_PRIVATE void _saudio_free(void* ptr) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#if defined(SOKOL_DEBUG)
|
|
|
-_SOKOL_PRIVATE void _saudio_log(const char* msg) {
|
|
|
- SOKOL_ASSERT(msg);
|
|
|
- if (_saudio.desc.logger.log_cb) {
|
|
|
- _saudio.desc.logger.log_cb(msg, _saudio.desc.logger.user_data);
|
|
|
- } else {
|
|
|
- SOKOL_LOG(msg);
|
|
|
- }
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
// ███╗ ███╗██╗ ██╗████████╗███████╗██╗ ██╗
|
|
|
// ████╗ ████║██║ ██║╚══██╔══╝██╔════╝╚██╗██╔╝
|
|
|
// ██╔████╔██║██║ ██║ ██║ █████╗ ╚███╔╝
|
|
@@ -1385,7 +1494,7 @@ _SOKOL_PRIVATE bool _saudio_alsa_backend_init(void) {
|
|
|
int dir; uint32_t rate;
|
|
|
int rc = snd_pcm_open(&_saudio.backend.device, "default", SND_PCM_STREAM_PLAYBACK, 0);
|
|
|
if (rc < 0) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: snd_pcm_open() failed");
|
|
|
+ _SAUDIO_ERROR(ALSA_SND_PCM_OPEN_FAILED);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -1398,26 +1507,26 @@ _SOKOL_PRIVATE bool _saudio_alsa_backend_init(void) {
|
|
|
snd_pcm_hw_params_any(_saudio.backend.device, params);
|
|
|
snd_pcm_hw_params_set_access(_saudio.backend.device, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
|
|
if (0 > snd_pcm_hw_params_set_format(_saudio.backend.device, params, SND_PCM_FORMAT_FLOAT_LE)) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: float samples not supported");
|
|
|
+ _SAUDIO_ERROR(ALSA_FLOAT_SAMPLES_NOT_SUPPORTED);
|
|
|
goto error;
|
|
|
}
|
|
|
if (0 > snd_pcm_hw_params_set_buffer_size(_saudio.backend.device, params, (snd_pcm_uframes_t)_saudio.buffer_frames)) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: requested buffer size not supported");
|
|
|
+ _SAUDIO_ERROR(ALSA_REQUESTED_BUFFER_SIZE_NOT_SUPPORTED);
|
|
|
goto error;
|
|
|
}
|
|
|
if (0 > snd_pcm_hw_params_set_channels(_saudio.backend.device, params, (uint32_t)_saudio.num_channels)) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: requested channel count not supported");
|
|
|
+ _SAUDIO_ERROR(ALSA_REQUESTED_CHANNEL_COUNT_NOT_SUPPORTED);
|
|
|
goto error;
|
|
|
}
|
|
|
/* let ALSA pick a nearby sampling rate */
|
|
|
rate = (uint32_t) _saudio.sample_rate;
|
|
|
dir = 0;
|
|
|
if (0 > snd_pcm_hw_params_set_rate_near(_saudio.backend.device, params, &rate, &dir)) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: snd_pcm_hw_params_set_rate_near() failed");
|
|
|
+ _SAUDIO_ERROR(ALSA_SND_PCM_HW_PARAMS_SET_RATE_NEAR_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
if (0 > snd_pcm_hw_params(_saudio.backend.device, params)) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: snd_pcm_hw_params() failed");
|
|
|
+ _SAUDIO_ERROR(ALSA_SND_PCM_HW_PARAMS_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
|
|
@@ -1432,7 +1541,7 @@ _SOKOL_PRIVATE bool _saudio_alsa_backend_init(void) {
|
|
|
|
|
|
/* create the buffer-streaming start thread */
|
|
|
if (0 != pthread_create(&_saudio.backend.thread, 0, _saudio_alsa_cb, 0)) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: pthread_create() failed");
|
|
|
+ _SAUDIO_ERROR(ALSA_PTHREAD_CREATE_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
|
|
@@ -1464,48 +1573,6 @@ _SOKOL_PRIVATE void _saudio_alsa_backend_shutdown(void) {
|
|
|
// >>wasapi
|
|
|
#elif defined(_SAUDIO_WINDOWS)
|
|
|
|
|
|
-#if defined(_SAUDIO_UWP)
|
|
|
-/* Minimal implementation of an IActivateAudioInterfaceCompletionHandler COM object in plain C.
|
|
|
- Meant to be a static singleton (always one reference when add/remove reference)
|
|
|
- and implements IUnknown and IActivateAudioInterfaceCompletionHandler when queryinterface'd
|
|
|
-
|
|
|
- Do not know why but IActivateAudioInterfaceCompletionHandler's GUID is not the one system queries for,
|
|
|
- so I'm advertising the one actually requested.
|
|
|
-*/
|
|
|
-_SOKOL_PRIVATE HRESULT STDMETHODCALLTYPE _saudio_interface_completion_handler_queryinterface(IActivateAudioInterfaceCompletionHandler* instance, REFIID riid, void** ppvObject) {
|
|
|
- if (!ppvObject) {
|
|
|
- return E_POINTER;
|
|
|
- }
|
|
|
-
|
|
|
- if (IsEqualIID(riid, _SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_IActivateAudioInterface_Completion_Handler)) || IsEqualIID(riid, _SOKOL_AUDIO_WIN32COM_ID(IID_IUnknown)))
|
|
|
- {
|
|
|
- *ppvObject = (void*)instance;
|
|
|
- return S_OK;
|
|
|
- }
|
|
|
-
|
|
|
- *ppvObject = NULL;
|
|
|
- return E_NOINTERFACE;
|
|
|
-}
|
|
|
-
|
|
|
-_SOKOL_PRIVATE ULONG STDMETHODCALLTYPE _saudio_interface_completion_handler_addref_release(IActivateAudioInterfaceCompletionHandler* instance) {
|
|
|
- _SOKOL_UNUSED(instance);
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-_SOKOL_PRIVATE HRESULT STDMETHODCALLTYPE _saudio_backend_activate_audio_interface_cb(IActivateAudioInterfaceCompletionHandler* instance, IActivateAudioInterfaceAsyncOperation* activateOperation) {
|
|
|
- _SOKOL_UNUSED(instance);
|
|
|
- WaitForSingleObject(_saudio.backend.interface_activation_mutex, INFINITE);
|
|
|
- _saudio.backend.interface_activation_success = TRUE;
|
|
|
- HRESULT activation_result;
|
|
|
- if (FAILED(activateOperation->lpVtbl->GetActivateResult(activateOperation, &activation_result, (IUnknown**)(&_saudio.backend.audio_client))) || FAILED(activation_result)) {
|
|
|
- _saudio.backend.interface_activation_success = FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- ReleaseMutex(_saudio.backend.interface_activation_mutex);
|
|
|
- return S_OK;
|
|
|
-}
|
|
|
-#endif // _SAUDIO_UWP
|
|
|
-
|
|
|
/* fill intermediate buffer with new data and reset buffer_pos */
|
|
|
_SOKOL_PRIVATE void _saudio_wasapi_fill_buffer(void) {
|
|
|
if (_saudio_has_callback()) {
|
|
@@ -1593,25 +1660,14 @@ _SOKOL_PRIVATE void _saudio_wasapi_release(void) {
|
|
|
IAudioClient_Release(_saudio.backend.audio_client);
|
|
|
_saudio.backend.audio_client = 0;
|
|
|
}
|
|
|
- #if defined(_SAUDIO_UWP)
|
|
|
- if (_saudio.backend.interface_activation_audio_interface_uid_string) {
|
|
|
- CoTaskMemFree(_saudio.backend.interface_activation_audio_interface_uid_string);
|
|
|
- _saudio.backend.interface_activation_audio_interface_uid_string = 0;
|
|
|
- }
|
|
|
- if (_saudio.backend.interface_activation_operation) {
|
|
|
- IActivateAudioInterfaceAsyncOperation_Release(_saudio.backend.interface_activation_operation);
|
|
|
- _saudio.backend.interface_activation_operation = 0;
|
|
|
- }
|
|
|
- #else
|
|
|
- if (_saudio.backend.device) {
|
|
|
- IMMDevice_Release(_saudio.backend.device);
|
|
|
- _saudio.backend.device = 0;
|
|
|
- }
|
|
|
- if (_saudio.backend.device_enumerator) {
|
|
|
- IMMDeviceEnumerator_Release(_saudio.backend.device_enumerator);
|
|
|
- _saudio.backend.device_enumerator = 0;
|
|
|
- }
|
|
|
- #endif
|
|
|
+ if (_saudio.backend.device) {
|
|
|
+ IMMDevice_Release(_saudio.backend.device);
|
|
|
+ _saudio.backend.device = 0;
|
|
|
+ }
|
|
|
+ if (_saudio.backend.device_enumerator) {
|
|
|
+ IMMDeviceEnumerator_Release(_saudio.backend.device_enumerator);
|
|
|
+ _saudio.backend.device_enumerator = 0;
|
|
|
+ }
|
|
|
if (0 != _saudio.backend.thread.buffer_end_event) {
|
|
|
CloseHandle(_saudio.backend.thread.buffer_end_event);
|
|
|
_saudio.backend.thread.buffer_end_event = 0;
|
|
@@ -1620,81 +1676,40 @@ _SOKOL_PRIVATE void _saudio_wasapi_release(void) {
|
|
|
|
|
|
_SOKOL_PRIVATE bool _saudio_wasapi_backend_init(void) {
|
|
|
REFERENCE_TIME dur;
|
|
|
- /* UWP Threads are CoInitialized by default with a different threading model, and this call fails
|
|
|
- See https://github.com/Microsoft/cppwinrt/issues/6#issuecomment-253930637 */
|
|
|
- #if defined(_SAUDIO_WIN32)
|
|
|
- /* CoInitializeEx could have been called elsewhere already, in which
|
|
|
- case the function returns with S_FALSE (thus it does not make much
|
|
|
- sense to check the result)
|
|
|
- */
|
|
|
- HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
|
|
|
- _SOKOL_UNUSED(hr);
|
|
|
- #endif
|
|
|
+ /* CoInitializeEx could have been called elsewhere already, in which
|
|
|
+ case the function returns with S_FALSE (thus it does not make much
|
|
|
+ sense to check the result)
|
|
|
+ */
|
|
|
+ HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
|
|
|
+ _SOKOL_UNUSED(hr);
|
|
|
_saudio.backend.thread.buffer_end_event = CreateEvent(0, FALSE, FALSE, 0);
|
|
|
if (0 == _saudio.backend.thread.buffer_end_event) {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: failed to create buffer_end_event");
|
|
|
+ _SAUDIO_ERROR(WASAPI_CREATE_EVENT_FAILED);
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ if (FAILED(CoCreateInstance(_SOKOL_AUDIO_WIN32COM_ID(_saudio_CLSID_IMMDeviceEnumerator),
|
|
|
+ 0, CLSCTX_ALL,
|
|
|
+ _SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_IMMDeviceEnumerator),
|
|
|
+ (void**)&_saudio.backend.device_enumerator)))
|
|
|
+ {
|
|
|
+ _SAUDIO_ERROR(WASAPI_CREATE_DEVICE_ENUMERATOR_FAILED);
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ if (FAILED(IMMDeviceEnumerator_GetDefaultAudioEndpoint(_saudio.backend.device_enumerator,
|
|
|
+ eRender, eConsole,
|
|
|
+ &_saudio.backend.device)))
|
|
|
+ {
|
|
|
+ _SOKOL_ERROR(WASAPI_GET_DEFAULT_AUDIO_ENDPOINT_FAILED);
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ if (FAILED(IMMDevice_Activate(_saudio.backend.device,
|
|
|
+ _SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_IAudioClient),
|
|
|
+ CLSCTX_ALL, 0,
|
|
|
+ (void**)&_saudio.backend.audio_client)))
|
|
|
+ {
|
|
|
+ _SOKOL_ERROR(WASAPI_DEVICE_ACTIVATE_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
- #if defined(_SAUDIO_UWP)
|
|
|
- _saudio.backend.interface_activation_mutex = CreateMutexA(NULL, FALSE, "interface_activation_mutex");
|
|
|
- if (_saudio.backend.interface_activation_mutex == NULL) {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: failed to create interface activation mutex");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- if (FAILED(StringFromIID(_SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_Devinterface_Audio_Render), &_saudio.backend.interface_activation_audio_interface_uid_string))) {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: failed to get default audio device ID string");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- /* static instance of the fake COM object */
|
|
|
- static IActivateAudioInterfaceCompletionHandlerVtbl completion_handler_interface_vtable = {
|
|
|
- _saudio_interface_completion_handler_queryinterface,
|
|
|
- _saudio_interface_completion_handler_addref_release,
|
|
|
- _saudio_interface_completion_handler_addref_release,
|
|
|
- _saudio_backend_activate_audio_interface_cb
|
|
|
- };
|
|
|
- static IActivateAudioInterfaceCompletionHandler completion_handler_interface = { &completion_handler_interface_vtable };
|
|
|
-
|
|
|
- if (FAILED(ActivateAudioInterfaceAsync(_saudio.backend.interface_activation_audio_interface_uid_string, _SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_IAudioClient), NULL, &completion_handler_interface, &_saudio.backend.interface_activation_operation))) {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: failed to get default audio device ID string");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- while (!(_saudio.backend.audio_client)) {
|
|
|
- if (WaitForSingleObject(_saudio.backend.interface_activation_mutex, 10) != WAIT_TIMEOUT) {
|
|
|
- ReleaseMutex(_saudio.backend.interface_activation_mutex);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!(_saudio.backend.interface_activation_success)) {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: interface activation failed. Unable to get audio client");
|
|
|
- goto error;
|
|
|
- }
|
|
|
-
|
|
|
- #else
|
|
|
- if (FAILED(CoCreateInstance(_SOKOL_AUDIO_WIN32COM_ID(_saudio_CLSID_IMMDeviceEnumerator),
|
|
|
- 0, CLSCTX_ALL,
|
|
|
- _SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_IMMDeviceEnumerator),
|
|
|
- (void**)&_saudio.backend.device_enumerator)))
|
|
|
- {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: failed to create device enumerator");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- if (FAILED(IMMDeviceEnumerator_GetDefaultAudioEndpoint(_saudio.backend.device_enumerator,
|
|
|
- eRender, eConsole,
|
|
|
- &_saudio.backend.device)))
|
|
|
- {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: GetDefaultAudioEndPoint failed");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- if (FAILED(IMMDevice_Activate(_saudio.backend.device,
|
|
|
- _SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_IAudioClient),
|
|
|
- CLSCTX_ALL, 0,
|
|
|
- (void**)&_saudio.backend.audio_client)))
|
|
|
- {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: device activate failed");
|
|
|
- goto error;
|
|
|
- }
|
|
|
- #endif
|
|
|
|
|
|
WAVEFORMATEXTENSIBLE fmtex;
|
|
|
_saudio_clear(&fmtex, sizeof(fmtex));
|
|
@@ -1720,22 +1735,22 @@ _SOKOL_PRIVATE bool _saudio_wasapi_backend_init(void) {
|
|
|
AUDCLNT_STREAMFLAGS_EVENTCALLBACK|AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM|AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY,
|
|
|
dur, 0, (WAVEFORMATEX*)&fmtex, 0)))
|
|
|
{
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: audio client initialize failed");
|
|
|
+ _SAUDIO_ERROR(WASAPI_AUDIO_CLIENT_INITIALIZE_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
if (FAILED(IAudioClient_GetBufferSize(_saudio.backend.audio_client, &_saudio.backend.thread.dst_buffer_frames))) {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: audio client get buffer size failed");
|
|
|
+ _SAUDIO_ERROR(WASAPI_AUDIO_CLIENT_GET_BUFFER_SIZE_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
if (FAILED(IAudioClient_GetService(_saudio.backend.audio_client,
|
|
|
_SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_IAudioRenderClient),
|
|
|
(void**)&_saudio.backend.render_client)))
|
|
|
{
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: audio client GetService failed");
|
|
|
+ _SAUDIO_ERROR(WASAPI_AUDIO_CLIENT_GET_SERVICE_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
if (FAILED(IAudioClient_SetEventHandle(_saudio.backend.audio_client, _saudio.backend.thread.buffer_end_event))) {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: audio client SetEventHandle failed");
|
|
|
+ _SAUDIO_ERROR(WASAPI_AUDIO_CLIENT_SET_EVENT_HANDLE_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
_saudio.bytes_per_frame = _saudio.num_channels * (int)sizeof(float);
|
|
@@ -1748,7 +1763,7 @@ _SOKOL_PRIVATE bool _saudio_wasapi_backend_init(void) {
|
|
|
/* create streaming thread */
|
|
|
_saudio.backend.thread.thread_handle = CreateThread(NULL, 0, _saudio_wasapi_thread_fn, 0, 0, 0);
|
|
|
if (0 == _saudio.backend.thread.thread_handle) {
|
|
|
- SAUDIO_LOG("sokol_audio wasapi: CreateThread failed");
|
|
|
+ _SAUDIO_ERROR(WASAPI_CREATE_THREAD_FAILED);
|
|
|
goto error;
|
|
|
}
|
|
|
return true;
|
|
@@ -1769,10 +1784,7 @@ _SOKOL_PRIVATE void _saudio_wasapi_backend_shutdown(void) {
|
|
|
IAudioClient_Stop(_saudio.backend.audio_client);
|
|
|
}
|
|
|
_saudio_wasapi_release();
|
|
|
-
|
|
|
- #if defined(_SAUDIO_WIN32)
|
|
|
- CoUninitialize();
|
|
|
- #endif
|
|
|
+ CoUninitialize();
|
|
|
}
|
|
|
|
|
|
// ██╗ ██╗███████╗██████╗ █████╗ ██╗ ██╗██████╗ ██╗ ██████╗
|
|
@@ -1961,7 +1973,7 @@ _SOKOL_PRIVATE aaudio_data_callback_result_t _saudio_aaudio_data_callback(AAudio
|
|
|
|
|
|
_SOKOL_PRIVATE bool _saudio_aaudio_start_stream(void) {
|
|
|
if (AAudioStreamBuilder_openStream(_saudio.backend.builder, &_saudio.backend.stream) != AAUDIO_OK) {
|
|
|
- SAUDIO_LOG("sokol_audio.h aaudio: AAudioStreamBuilder_openStream failed");
|
|
|
+ _SAUDIO_ERROR(AAUDIO_STREAMBUILDER_OPEN_STREAM_FAILED);
|
|
|
return false;
|
|
|
}
|
|
|
AAudioStream_requestStart(_saudio.backend.stream);
|
|
@@ -1978,7 +1990,7 @@ _SOKOL_PRIVATE void _saudio_aaudio_stop_stream(void) {
|
|
|
|
|
|
_SOKOL_PRIVATE void* _saudio_aaudio_restart_stream_thread_fn(void* param) {
|
|
|
_SOKOL_UNUSED(param);
|
|
|
- SAUDIO_LOG("sokol_audio.h aaudio: restarting stream after error");
|
|
|
+ _SAUDIO_WARN(AAUDIO_RESTARTING_STREAM_AFTER_ERROR);
|
|
|
pthread_mutex_lock(&_saudio.backend.mutex);
|
|
|
_saudio_aaudio_stop_stream();
|
|
|
_saudio_aaudio_start_stream();
|
|
@@ -1991,7 +2003,7 @@ _SOKOL_PRIVATE void _saudio_aaudio_error_callback(AAudioStream* stream, void* us
|
|
|
_SOKOL_UNUSED(user_data);
|
|
|
if (error == AAUDIO_ERROR_DISCONNECTED) {
|
|
|
if (0 != pthread_create(&_saudio.backend.thread, 0, _saudio_aaudio_restart_stream_thread_fn, 0)) {
|
|
|
- SAUDIO_LOG("sokol_audio.h aaudio: pthread_create failed in _saudio_audio_error_callback");
|
|
|
+ _SAUDIO_ERROR(AAUDIO_PTHREAD_CREATE_FAILED);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -2008,7 +2020,7 @@ _SOKOL_PRIVATE void _saudio_aaudio_backend_shutdown(void) {
|
|
|
}
|
|
|
|
|
|
_SOKOL_PRIVATE bool _saudio_aaudio_backend_init(void) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: using AAudio backend");
|
|
|
+ _SAUDIO_INFO(USING_AAUDIO_BACKEND);
|
|
|
|
|
|
_saudio.bytes_per_frame = _saudio.num_channels * (int)sizeof(float);
|
|
|
|
|
@@ -2017,7 +2029,7 @@ _SOKOL_PRIVATE bool _saudio_aaudio_backend_init(void) {
|
|
|
pthread_mutex_init(&_saudio.backend.mutex, &attr);
|
|
|
|
|
|
if (AAudio_createStreamBuilder(&_saudio.backend.builder) != AAUDIO_OK) {
|
|
|
- SAUDIO_LOG("sokol_audio.h aaudio: AAudio_createStreamBuilder() failed!");
|
|
|
+ _SAUDIO_ERROR(AAUDIO_CREATE_STREAMBUILDER_FAILED);
|
|
|
_saudio_aaudio_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
@@ -2107,9 +2119,8 @@ _SOKOL_PRIVATE void _saudio_sles_fill_buffer(void) {
|
|
|
}
|
|
|
|
|
|
_SOKOL_PRIVATE void SLAPIENTRY _saudio_sles_play_cb(SLPlayItf player, void *context, SLuint32 event) {
|
|
|
- (void)(context);
|
|
|
- (void)(player);
|
|
|
-
|
|
|
+ _SOKOL_UNUSED(context);
|
|
|
+ _SOKOL_UNUSED(player);
|
|
|
if (event & SL_PLAYEVENT_HEADATEND) {
|
|
|
_saudio_sles_semaphore_post(&_saudio.backend.buffer_sem, 1);
|
|
|
}
|
|
@@ -2163,7 +2174,7 @@ _SOKOL_PRIVATE void _saudio_sles_backend_shutdown(void) {
|
|
|
}
|
|
|
|
|
|
_SOKOL_PRIVATE bool _saudio_sles_backend_init(void) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: using OpenSLES backend");
|
|
|
+ _SAUDIO_INFO(USING_SLES_BACKEND);
|
|
|
|
|
|
_saudio.bytes_per_frame = (int)sizeof(float) * _saudio.num_channels;
|
|
|
|
|
@@ -2180,14 +2191,14 @@ _SOKOL_PRIVATE bool _saudio_sles_backend_init(void) {
|
|
|
/* Create engine */
|
|
|
const SLEngineOption opts[] = { { SL_ENGINEOPTION_THREADSAFE, SL_BOOLEAN_TRUE } };
|
|
|
if (slCreateEngine(&_saudio.backend.engine_obj, 1, opts, 0, NULL, NULL ) != SL_RESULT_SUCCESS) {
|
|
|
- SAUDIO_LOG("sokol_audio opensles: slCreateEngine failed");
|
|
|
+ _SAUDIO_ERROR(SLES_CREATE_ENGINE_FAILED);
|
|
|
_saudio_sles_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
(*_saudio.backend.engine_obj)->Realize(_saudio.backend.engine_obj, SL_BOOLEAN_FALSE);
|
|
|
if ((*_saudio.backend.engine_obj)->GetInterface(_saudio.backend.engine_obj, SL_IID_ENGINE, &_saudio.backend.engine) != SL_RESULT_SUCCESS) {
|
|
|
- SAUDIO_LOG("sokol_audio opensles: GetInterface->Engine failed");
|
|
|
+ _SAUDIO_ERROR(SLES_ENGINE_GET_ENGINE_INTERFACE_FAILED);
|
|
|
_saudio_sles_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
@@ -2197,16 +2208,15 @@ _SOKOL_PRIVATE bool _saudio_sles_backend_init(void) {
|
|
|
const SLInterfaceID ids[] = { SL_IID_VOLUME };
|
|
|
const SLboolean req[] = { SL_BOOLEAN_FALSE };
|
|
|
|
|
|
- if( (*_saudio.backend.engine)->CreateOutputMix(_saudio.backend.engine, &_saudio.backend.output_mix_obj, 1, ids, req) != SL_RESULT_SUCCESS)
|
|
|
- {
|
|
|
- SAUDIO_LOG("sokol_audio opensles: CreateOutputMix failed");
|
|
|
+ if ((*_saudio.backend.engine)->CreateOutputMix(_saudio.backend.engine, &_saudio.backend.output_mix_obj, 1, ids, req) != SL_RESULT_SUCCESS) {
|
|
|
+ _SAUDIO_ERROR(SLES_CREATE_OUTPUT_MIX_FAILED);
|
|
|
_saudio_sles_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
|
(*_saudio.backend.output_mix_obj)->Realize(_saudio.backend.output_mix_obj, SL_BOOLEAN_FALSE);
|
|
|
|
|
|
- if((*_saudio.backend.output_mix_obj)->GetInterface(_saudio.backend.output_mix_obj, SL_IID_VOLUME, &_saudio.backend.output_mix_vol) != SL_RESULT_SUCCESS) {
|
|
|
- SAUDIO_LOG("sokol_audio opensles: GetInterface->OutputMixVol failed");
|
|
|
+ if ((*_saudio.backend.output_mix_obj)->GetInterface(_saudio.backend.output_mix_obj, SL_IID_VOLUME, &_saudio.backend.output_mix_vol) != SL_RESULT_SUCCESS) {
|
|
|
+ _SAUDIO_WARN(SLES_MIXER_GET_VOLUME_INTERFACE_FAILED);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2245,24 +2255,24 @@ _SOKOL_PRIVATE bool _saudio_sles_backend_init(void) {
|
|
|
const SLInterfaceID ids[] = { SL_IID_VOLUME, SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
|
|
|
const SLboolean req[] = { SL_BOOLEAN_FALSE, SL_BOOLEAN_TRUE };
|
|
|
|
|
|
- if( (*_saudio.backend.engine)->CreateAudioPlayer(_saudio.backend.engine, &_saudio.backend.player_obj, &src, &_saudio.backend.dst_data_sink, sizeof(ids) / sizeof(ids[0]), ids, req) != SL_RESULT_SUCCESS)
|
|
|
+ if ((*_saudio.backend.engine)->CreateAudioPlayer(_saudio.backend.engine, &_saudio.backend.player_obj, &src, &_saudio.backend.dst_data_sink, sizeof(ids) / sizeof(ids[0]), ids, req) != SL_RESULT_SUCCESS)
|
|
|
{
|
|
|
- SAUDIO_LOG("sokol_audio opensles: CreateAudioPlayer failed");
|
|
|
+ _SAUDIO_ERROR(SLES_ENGINE_CREATE_AUDIO_PLAYER_FAILED);
|
|
|
_saudio_sles_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
|
(*_saudio.backend.player_obj)->Realize(_saudio.backend.player_obj, SL_BOOLEAN_FALSE);
|
|
|
|
|
|
- if((*_saudio.backend.player_obj)->GetInterface(_saudio.backend.player_obj, SL_IID_PLAY, &_saudio.backend.player) != SL_RESULT_SUCCESS) {
|
|
|
- SAUDIO_LOG("sokol_audio opensles: GetInterface->Play failed");
|
|
|
+ if ((*_saudio.backend.player_obj)->GetInterface(_saudio.backend.player_obj, SL_IID_PLAY, &_saudio.backend.player) != SL_RESULT_SUCCESS) {
|
|
|
+ _SAUDIO_ERROR(SLES_PLAYER_GET_PLAY_INTERFACE_FAILED);
|
|
|
_saudio_sles_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
|
- if((*_saudio.backend.player_obj)->GetInterface(_saudio.backend.player_obj, SL_IID_VOLUME, &_saudio.backend.player_vol) != SL_RESULT_SUCCESS) {
|
|
|
- SAUDIO_LOG("sokol_audio opensles: GetInterface->PlayerVol failed");
|
|
|
+ if ((*_saudio.backend.player_obj)->GetInterface(_saudio.backend.player_obj, SL_IID_VOLUME, &_saudio.backend.player_vol) != SL_RESULT_SUCCESS) {
|
|
|
+ _SAUDIO_ERROR(SLES_PLAYER_GET_VOLUME_INTERFACE_FAILED);
|
|
|
}
|
|
|
- if((*_saudio.backend.player_obj)->GetInterface(_saudio.backend.player_obj, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &_saudio.backend.player_buffer_queue) != SL_RESULT_SUCCESS) {
|
|
|
- SAUDIO_LOG("sokol_audio opensles: GetInterface->BufferQ failed");
|
|
|
+ if ((*_saudio.backend.player_obj)->GetInterface(_saudio.backend.player_obj, SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &_saudio.backend.player_buffer_queue) != SL_RESULT_SUCCESS) {
|
|
|
+ _SAUDIO_ERROR(SLES_PLAYER_GET_BUFFERQUEUE_INTERFACE_FAILED);
|
|
|
_saudio_sles_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
@@ -2418,7 +2428,7 @@ _SOKOL_PRIVATE bool _saudio_coreaudio_backend_init(void) {
|
|
|
fmt.mBitsPerChannel = 32;
|
|
|
_saudio_OSStatus res = AudioQueueNewOutput(&fmt, _saudio_coreaudio_callback, 0, NULL, NULL, 0, &_saudio.backend.ca_audio_queue);
|
|
|
if (0 != res) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: AudioQueueNewOutput() failed!\n");
|
|
|
+ _SAUDIO_ERROR(COREAUDIO_NEW_OUTPUT_FAILED);
|
|
|
return false;
|
|
|
}
|
|
|
SOKOL_ASSERT(_saudio.backend.ca_audio_queue);
|
|
@@ -2429,7 +2439,7 @@ _SOKOL_PRIVATE bool _saudio_coreaudio_backend_init(void) {
|
|
|
const uint32_t buf_byte_size = (uint32_t)_saudio.buffer_frames * fmt.mBytesPerFrame;
|
|
|
res = AudioQueueAllocateBuffer(_saudio.backend.ca_audio_queue, buf_byte_size, &buf);
|
|
|
if (0 != res) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: AudioQueueAllocateBuffer() failed!\n");
|
|
|
+ _SAUDIO_ERROR(COREAUDIO_ALLOCATE_BUFFER_FAILED);
|
|
|
_saudio_coreaudio_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
@@ -2444,7 +2454,7 @@ _SOKOL_PRIVATE bool _saudio_coreaudio_backend_init(void) {
|
|
|
/* ...and start playback */
|
|
|
res = AudioQueueStart(_saudio.backend.ca_audio_queue, NULL);
|
|
|
if (0 != res) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: AudioQueueStart() failed!\n");
|
|
|
+ _SAUDIO_ERROR(COREAUDIO_START_FAILED);
|
|
|
_saudio_coreaudio_backend_shutdown();
|
|
|
return false;
|
|
|
}
|
|
@@ -2524,7 +2534,7 @@ SOKOL_API_IMPL void saudio_setup(const saudio_desc* desc) {
|
|
|
the requested packet size
|
|
|
*/
|
|
|
if (0 != (_saudio.buffer_frames % _saudio.packet_frames)) {
|
|
|
- SAUDIO_LOG("sokol_audio.h: actual backend buffer size isn't multiple of requested packet size");
|
|
|
+ _SAUDIO_ERROR(BACKEND_BUFFER_SIZE_ISNT_MULTIPLE_OF_PACKET_SIZE);
|
|
|
_saudio_backend_shutdown();
|
|
|
return;
|
|
|
}
|