diff options
| author | Andre Weissflog <floooh@gmail.com> | 2022-10-22 14:23:00 +0200 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2022-10-22 14:23:00 +0200 |
| commit | e4b2aad7f27929b6ca58777c4f6884a23b1b0fbb (patch) | |
| tree | 8717a18f409c9bdcc46a9b4d14a51d223143f472 /sokol_audio.h | |
| parent | 2057da7e15367ba9cf1deee82f8660a19aefe154 (diff) | |
| parent | 3797da8c7f140f1406671a8ddcac1f7a2d4fc354 (diff) | |
Merge branch 'log-callback' of github.com:Manuzor/sokol into Manuzor-log-callback
Diffstat (limited to 'sokol_audio.h')
| -rw-r--r-- | sokol_audio.h | 126 |
1 files changed, 95 insertions, 31 deletions
diff --git a/sokol_audio.h b/sokol_audio.h index 4686425a..eed1e311 100644 --- a/sokol_audio.h +++ b/sokol_audio.h @@ -17,7 +17,6 @@ SOKOL_DUMMY_BACKEND - use a dummy backend SOKOL_ASSERT(c) - your own assert macro (default: assert(c)) - SOKOL_LOG(msg) - your own logging function (default: puts(msg)) SOKOL_AUDIO_API_DECL- public function declaration prefix (default: extern) SOKOL_API_DECL - same as SOKOL_AUDIO_API_DECL SOKOL_API_IMPL - public function implementation prefix (default: -) @@ -383,7 +382,7 @@ .allocator = { .alloc = my_alloc, .free = my_free, - .user_data = ...; + .user_data = ..., } }); ... @@ -397,6 +396,28 @@ 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); + } + + ... + saudio_setup(&(saudio_desc){ + // ... + .logger = { + .log_cb = 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. + + LICENSE ======= @@ -459,6 +480,17 @@ 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 SAUDIO_LOG_DEFAULT(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) @@ -469,6 +501,7 @@ typedef struct saudio_desc { void (*stream_userdata_cb)(float* buffer, int num_frames, int num_channels, void* user_data); //... and with user data void* user_data; // optional user data argument for stream_userdata_cb saudio_allocator allocator; // optional allocation override functions + saudio_logger logger; // optional log override functions } saudio_desc; /* setup sokol-audio */ @@ -527,14 +560,34 @@ inline void saudio_setup(const saudio_desc& desc) { return saudio_setup(&desc); #include <assert.h> #define SOKOL_ASSERT(c) assert(c) #endif -#ifndef SOKOL_LOG + +#if defined(SOKOL_LOG) +#error "SOKOL_LOG macro is no longer supported, please use saudio_desc.logger to override log functions" +#endif +#ifndef SOKOL_NO_LOG #ifdef SOKOL_DEBUG - #include <stdio.h> - #define SOKOL_LOG(s) { SOKOL_ASSERT(s); puts(s); } + #define SOKOL_NO_LOG 0 #else - #define SOKOL_LOG(s) + #define SOKOL_NO_LOG 1 #endif #endif +#if !SOKOL_NO_LOG + #define SAUDIO_LOG(s) { SOKOL_ASSERT(s); _saudio_log(s); } + #ifndef SAUDIO_LOG_DEFAULT + #if defined(__ANDROID__) + #include <android/log.h> + #define SAUDIO_LOG_DEFAULT(s) __android_log_write(ANDROID_LOG_INFO, "SOKOL_AUDIO", s) + #else + #include <stdio.h> + #define SAUDIO_LOG_DEFAULT(s) puts(s) + #endif + #endif +#else + #define SAUDIO_LOG(s) +#endif +#ifndef SAUDIO_LOG_DEFAULT + #define SAUDIO_LOG_DEFAULT(s) +#endif #ifndef _SOKOL_PRIVATE #if defined(__GNUC__) || defined(__clang__) @@ -984,6 +1037,17 @@ _SOKOL_PRIVATE void _saudio_free(void* ptr) { } } +#if !SOKOL_NO_LOG +_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 { + SAUDIO_LOG_DEFAULT(msg); + } +} +#endif + /*=== MUTEX IMPLEMENTATION ===================================================*/ #if defined(_SAUDIO_NOTHREADS) @@ -1386,7 +1450,7 @@ _SOKOL_PRIVATE bool _saudio_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) { - SOKOL_LOG("sokol_audio.h: snd_pcm_open() failed"); + SAUDIO_LOG("sokol_audio.h: snd_pcm_open() failed"); return false; } @@ -1399,26 +1463,26 @@ _SOKOL_PRIVATE bool _saudio_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)) { - SOKOL_LOG("sokol_audio.h: float samples not supported"); + SAUDIO_LOG("sokol_audio.h: 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)) { - SOKOL_LOG("sokol_audio.h: requested buffer size not supported"); + SAUDIO_LOG("sokol_audio.h: requested buffer size not supported"); goto error; } if (0 > snd_pcm_hw_params_set_channels(_saudio.backend.device, params, (uint32_t)_saudio.num_channels)) { - SOKOL_LOG("sokol_audio.h: requested channel count not supported"); + SAUDIO_LOG("sokol_audio.h: 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)) { - SOKOL_LOG("sokol_audio.h: snd_pcm_hw_params_set_rate_near() failed"); + SAUDIO_LOG("sokol_audio.h: snd_pcm_hw_params_set_rate_near() failed"); goto error; } if (0 > snd_pcm_hw_params(_saudio.backend.device, params)) { - SOKOL_LOG("sokol_audio.h: snd_pcm_hw_params() failed"); + SAUDIO_LOG("sokol_audio.h: snd_pcm_hw_params() failed"); goto error; } @@ -1433,7 +1497,7 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) { /* create the buffer-streaming start thread */ if (0 != pthread_create(&_saudio.backend.thread, 0, _saudio_alsa_cb, 0)) { - SOKOL_LOG("sokol_audio.h: pthread_create() failed"); + SAUDIO_LOG("sokol_audio.h: pthread_create() failed"); goto error; } @@ -1626,17 +1690,17 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) { #endif _saudio.backend.thread.buffer_end_event = CreateEvent(0, FALSE, FALSE, 0); if (0 == _saudio.backend.thread.buffer_end_event) { - SOKOL_LOG("sokol_audio wasapi: failed to create buffer_end_event"); + SAUDIO_LOG("sokol_audio wasapi: failed to create buffer_end_event"); goto error; } #if defined(_SAUDIO_UWP) _saudio.backend.interface_activation_mutex = CreateMutexA(NULL, FALSE, "interface_activation_mutex"); if (_saudio.backend.interface_activation_mutex == NULL) { - SOKOL_LOG("sokol_audio wasapi: failed to create interface activation mutex"); + 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))) { - SOKOL_LOG("sokol_audio wasapi: failed to get default audio device ID string"); + SAUDIO_LOG("sokol_audio wasapi: failed to get default audio device ID string"); goto error; } @@ -1650,7 +1714,7 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) { 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))) { - SOKOL_LOG("sokol_audio wasapi: failed to get default audio device ID string"); + SAUDIO_LOG("sokol_audio wasapi: failed to get default audio device ID string"); goto error; } while (!(_saudio.backend.audio_client)) { @@ -1660,7 +1724,7 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) { } if (!(_saudio.backend.interface_activation_success)) { - SOKOL_LOG("sokol_audio wasapi: interface activation failed. Unable to get audio client"); + SAUDIO_LOG("sokol_audio wasapi: interface activation failed. Unable to get audio client"); goto error; } @@ -1670,14 +1734,14 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) { _SOKOL_AUDIO_WIN32COM_ID(_saudio_IID_IMMDeviceEnumerator), (void**)&_saudio.backend.device_enumerator))) { - SOKOL_LOG("sokol_audio wasapi: failed to create 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))) { - SOKOL_LOG("sokol_audio wasapi: GetDefaultAudioEndPoint failed"); + SAUDIO_LOG("sokol_audio wasapi: GetDefaultAudioEndPoint failed"); goto error; } if (FAILED(IMMDevice_Activate(_saudio.backend.device, @@ -1685,7 +1749,7 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) { CLSCTX_ALL, 0, (void**)&_saudio.backend.audio_client))) { - SOKOL_LOG("sokol_audio wasapi: device activate failed"); + SAUDIO_LOG("sokol_audio wasapi: device activate failed"); goto error; } #endif @@ -1714,22 +1778,22 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) { AUDCLNT_STREAMFLAGS_EVENTCALLBACK|AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM|AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY, dur, 0, (WAVEFORMATEX*)&fmtex, 0))) { - SOKOL_LOG("sokol_audio wasapi: audio client initialize failed"); + SAUDIO_LOG("sokol_audio wasapi: audio client initialize failed"); goto error; } if (FAILED(IAudioClient_GetBufferSize(_saudio.backend.audio_client, &_saudio.backend.thread.dst_buffer_frames))) { - SOKOL_LOG("sokol_audio wasapi: audio client get buffer size failed"); + SAUDIO_LOG("sokol_audio 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))) { - SOKOL_LOG("sokol_audio wasapi: audio client GetService failed"); + SAUDIO_LOG("sokol_audio wasapi: audio client GetService failed"); goto error; } if (FAILED(IAudioClient_SetEventHandle(_saudio.backend.audio_client, _saudio.backend.thread.buffer_end_event))) { - SOKOL_LOG("sokol_audio wasapi: audio client SetEventHandle failed"); + SAUDIO_LOG("sokol_audio wasapi: audio client SetEventHandle failed"); goto error; } _saudio.bytes_per_frame = _saudio.num_channels * (int)sizeof(float); @@ -1742,7 +1806,7 @@ _SOKOL_PRIVATE bool _saudio_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) { - SOKOL_LOG("sokol_audio wasapi: CreateThread failed"); + SAUDIO_LOG("sokol_audio wasapi: CreateThread failed"); goto error; } return true; @@ -2065,14 +2129,14 @@ _SOKOL_PRIVATE bool _saudio_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) { - SOKOL_LOG("sokol_audio opensles: slCreateEngine failed"); + SAUDIO_LOG("sokol_audio opensles: slCreateEngine failed"); _saudio_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) { - SOKOL_LOG("sokol_audio opensles: GetInterface->Engine failed"); + SAUDIO_LOG("sokol_audio opensles: GetInterface->Engine failed"); _saudio_backend_shutdown(); return false; } @@ -2084,14 +2148,14 @@ _SOKOL_PRIVATE bool _saudio_backend_init(void) { if( (*_saudio.backend.engine)->CreateOutputMix(_saudio.backend.engine, &_saudio.backend.output_mix_obj, 1, ids, req) != SL_RESULT_SUCCESS) { - SOKOL_LOG("sokol_audio opensles: CreateOutputMix failed"); + SAUDIO_LOG("sokol_audio opensles: CreateOutputMix failed"); _saudio_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) { - SOKOL_LOG("sokol_audio opensles: GetInterface->OutputMixVol failed"); + SAUDIO_LOG("sokol_audio opensles: GetInterface->OutputMixVol failed"); } } @@ -2190,7 +2254,7 @@ SOKOL_API_IMPL void saudio_setup(const saudio_desc* desc) { the requested packet size */ if (0 != (_saudio.buffer_frames % _saudio.packet_frames)) { - SOKOL_LOG("sokol_audio.h: actual backend buffer size isn't multiple of requested packet size"); + SAUDIO_LOG("sokol_audio.h: actual backend buffer size isn't multiple of requested packet size"); _saudio_backend_shutdown(); return; } |