diff --git a/CMakeLists.txt b/CMakeLists.txt index 8959a9e..be7239e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 2.8.5) -project(libsoundio C CXX) +project(libsoundio C) set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH}) if(CMAKE_VERSION VERSION_LESS 3.0.0) @@ -135,12 +135,12 @@ endif() set(LIBSOUNDIO_SOURCES - "${CMAKE_SOURCE_DIR}/src/soundio.cpp" - "${CMAKE_SOURCE_DIR}/src/util.cpp" - "${CMAKE_SOURCE_DIR}/src/os.cpp" - "${CMAKE_SOURCE_DIR}/src/dummy.cpp" - "${CMAKE_SOURCE_DIR}/src/channel_layout.cpp" - "${CMAKE_SOURCE_DIR}/src/ring_buffer.cpp" + "${CMAKE_SOURCE_DIR}/src/soundio.c" + "${CMAKE_SOURCE_DIR}/src/util.c" + "${CMAKE_SOURCE_DIR}/src/os.c" + "${CMAKE_SOURCE_DIR}/src/dummy.c" + "${CMAKE_SOURCE_DIR}/src/channel_layout.c" + "${CMAKE_SOURCE_DIR}/src/ring_buffer.c" ) set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h") @@ -152,27 +152,27 @@ set(LIBSOUNDIO_HEADERS if(SOUNDIO_HAVE_JACK) set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES} - "${CMAKE_SOURCE_DIR}/src/jack.cpp" + "${CMAKE_SOURCE_DIR}/src/jack.c" ) endif() if(SOUNDIO_HAVE_PULSEAUDIO) set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES} - "${CMAKE_SOURCE_DIR}/src/pulseaudio.cpp" + "${CMAKE_SOURCE_DIR}/src/pulseaudio.c" ) endif() if(SOUNDIO_HAVE_ALSA) set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES} - "${CMAKE_SOURCE_DIR}/src/alsa.cpp" + "${CMAKE_SOURCE_DIR}/src/alsa.c" ) endif() if(SOUNDIO_HAVE_COREAUDIO) set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES} - "${CMAKE_SOURCE_DIR}/src/coreaudio.cpp" + "${CMAKE_SOURCE_DIR}/src/coreaudio.c" ) endif() if(SOUNDIO_HAVE_WASAPI) set(LIBSOUNDIO_SOURCES ${LIBSOUNDIO_SOURCES} - "${CMAKE_SOURCE_DIR}/src/wasapi.cpp" + "${CMAKE_SOURCE_DIR}/src/wasapi.c" ) endif() @@ -195,15 +195,10 @@ set(LIBSOUNDIO_LIBS -# GTFO, -lstdc++ !! -set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") -set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "") - set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Werror -pedantic") -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Werror -pedantic") -set(LIB_CFLAGS "-std=c++11 -fno-exceptions -fno-rtti -fvisibility=hidden -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes -Wno-c99-extensions") +set(LIB_CFLAGS "-std=c11 -fvisibility=hidden -Wall -Werror=strict-prototypes -Werror=old-style-definition -Werror=missing-prototypes -D_REENTRANT -D_POSIX_C_SOURCE=200809L") set(EXAMPLE_CFLAGS "-std=c99 -Wall") set(TEST_CFLAGS "${LIB_CFLAGS} -fprofile-arcs -ftest-coverage") set(TEST_LDFLAGS "-fprofile-arcs -ftest-coverage") @@ -277,7 +272,7 @@ if(BUILD_EXAMPLE_PROGRAMS) endif() if(BUILD_TESTS) - add_executable(unit_tests "${CMAKE_SOURCE_DIR}/test/unit_tests.cpp" ${LIBSOUNDIO_SOURCES}) + add_executable(unit_tests "${CMAKE_SOURCE_DIR}/test/unit_tests.c" ${LIBSOUNDIO_SOURCES}) target_link_libraries(unit_tests LINK_PUBLIC ${LIBSOUNDIO_LIBS}) set_target_properties(unit_tests PROPERTIES LINKER_LANGUAGE C @@ -285,7 +280,7 @@ if(BUILD_TESTS) LINK_FLAGS ${TEST_LDFLAGS} ) - add_executable(latency "${CMAKE_SOURCE_DIR}/test/latency.cpp" ${LIBSOUNDIO_SOURCES}) + add_executable(latency "${CMAKE_SOURCE_DIR}/test/latency.c" ${LIBSOUNDIO_SOURCES}) target_link_libraries(latency LINK_PUBLIC ${LIBSOUNDIO_LIBS} m) set_target_properties(latency PROPERTIES LINKER_LANGUAGE C diff --git a/README.md b/README.md index e2c3b5a..8de897f 100644 --- a/README.md +++ b/README.md @@ -181,22 +181,6 @@ and `soundio_get_backend` to get the list of available backends. [API Documentation](http://libsound.io/doc) -## Contributing - -libsoundio is programmed in a tiny subset of C++11: - - * No STL. - * No `new` or `delete`. - * No `class`. All fields in structs are `public`. - * No constructors or destructors. - * No exceptions or run-time type information. - * No references. - * No linking against libstdc++. - -Do not be fooled - this is a *C library*, not a C++ library. We just take -advantage of a select few C++11 compiler features such as templates, and then -link against libc. - ### Building Install the dependencies: diff --git a/src/alsa.cpp b/src/alsa.c similarity index 84% rename from src/alsa.cpp rename to src/alsa.c index e8cd2c7..88a199d 100644 --- a/src/alsa.cpp +++ b/src/alsa.c @@ -5,10 +5,13 @@ * See http://opensource.org/licenses/MIT */ -#include "alsa.hpp" -#include "soundio.hpp" +#define _GNU_SOURCE +#include "alsa.h" +#include "soundio_private.h" #include +#include +#include static snd_pcm_stream_t stream_types[] = {SND_PCM_STREAM_PLAYBACK, SND_PCM_STREAM_CAPTURE}; @@ -20,8 +23,9 @@ static snd_pcm_access_t prioritized_access_types[] = { SND_PCM_ACCESS_RW_NONINTERLEAVED, }; +SOUNDIO_MAKE_LIST_DEF(struct SoundIoAlsaPendingFile, SoundIoListAlsaPendingFile, SOUNDIO_LIST_STATIC) -static void wakeup_device_poll(SoundIoAlsa *sia) { +static void wakeup_device_poll(struct SoundIoAlsa *sia) { ssize_t amt = write(sia->notify_pipe_fd[1], "a", 1); if (amt == -1) { assert(errno != EBADF); @@ -32,16 +36,16 @@ static void wakeup_device_poll(SoundIoAlsa *sia) { } } -static void destroy_alsa(SoundIoPrivate *si) { - SoundIoAlsa *sia = &si->backend_data.alsa; +static void destroy_alsa(struct SoundIoPrivate *si) { + struct SoundIoAlsa *sia = &si->backend_data.alsa; if (sia->thread) { - sia->abort_flag.clear(); + atomic_flag_clear(&sia->abort_flag); wakeup_device_poll(sia); soundio_os_thread_destroy(sia->thread); } - sia->pending_files.deinit(); + SoundIoListAlsaPendingFile_deinit(&sia->pending_files); if (sia->cond) soundio_os_cond_destroy(sia->cond); @@ -71,10 +75,10 @@ static char * str_partition_on_char(char *str, char c) { } str += 1; } - return nullptr; + return NULL; } -static snd_pcm_stream_t aim_to_stream(SoundIoDeviceAim aim) { +static snd_pcm_stream_t aim_to_stream(enum SoundIoDeviceAim aim) { switch (aim) { case SoundIoDeviceAimOutput: return SND_PCM_STREAM_PLAYBACK; case SoundIoDeviceAimInput: return SND_PCM_STREAM_CAPTURE; @@ -83,8 +87,8 @@ static snd_pcm_stream_t aim_to_stream(SoundIoDeviceAim aim) { return SND_PCM_STREAM_PLAYBACK; } -static SoundIoChannelId from_alsa_chmap_pos(unsigned int pos) { - switch ((snd_pcm_chmap_position)pos) { +static enum SoundIoChannelId from_alsa_chmap_pos(unsigned int pos) { + switch ((enum snd_pcm_chmap_position)pos) { case SND_CHMAP_UNKNOWN: return SoundIoChannelIdInvalid; case SND_CHMAP_NA: return SoundIoChannelIdInvalid; case SND_CHMAP_MONO: return SoundIoChannelIdFrontCenter; @@ -126,7 +130,7 @@ static SoundIoChannelId from_alsa_chmap_pos(unsigned int pos) { return SoundIoChannelIdInvalid; } -static int to_alsa_chmap_pos(SoundIoChannelId channel_id) { +static int to_alsa_chmap_pos(enum SoundIoChannelId channel_id) { switch (channel_id) { case SoundIoChannelIdFrontLeft: return SND_CHMAP_FL; case SoundIoChannelIdFrontRight: return SND_CHMAP_FR; @@ -168,8 +172,8 @@ static int to_alsa_chmap_pos(SoundIoChannelId channel_id) { } } -static void get_channel_layout(SoundIoChannelLayout *dest, snd_pcm_chmap_t *chmap) { - int channel_count = min((unsigned int)SOUNDIO_MAX_CHANNELS, chmap->channels); +static void get_channel_layout(struct SoundIoChannelLayout *dest, snd_pcm_chmap_t *chmap) { + int channel_count = soundio_int_min(SOUNDIO_MAX_CHANNELS, chmap->channels); dest->channel_count = channel_count; for (int i = 0; i < channel_count; i += 1) { dest->channels[i] = from_alsa_chmap_pos(chmap->pos[i]); @@ -177,7 +181,7 @@ static void get_channel_layout(SoundIoChannelLayout *dest, snd_pcm_chmap_t *chma soundio_channel_layout_detect_builtin(dest); } -static int handle_channel_maps(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { +static int handle_channel_maps(struct SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { if (!maps) return 0; @@ -187,7 +191,7 @@ static int handle_channel_maps(SoundIoDevice *device, snd_pcm_chmap_query_t **ma // one iteration to count int layout_count = 0; for (p = maps; (v = *p) && layout_count < SOUNDIO_MAX_CHANNELS; p += 1, layout_count += 1) { } - device->layouts = allocate(layout_count); + device->layouts = ALLOCATE(struct SoundIoChannelLayout, layout_count); if (!device->layouts) { snd_pcm_free_chmaps(maps); return SoundIoErrorNoMem; @@ -207,7 +211,7 @@ static int handle_channel_maps(SoundIoDevice *device, snd_pcm_chmap_query_t **ma return 0; } -static snd_pcm_format_t to_alsa_fmt(SoundIoFormat fmt) { +static snd_pcm_format_t to_alsa_fmt(enum SoundIoFormat fmt) { switch (fmt) { case SoundIoFormatS8: return SND_PCM_FORMAT_S8; case SoundIoFormatU8: return SND_PCM_FORMAT_U8; @@ -234,7 +238,9 @@ static snd_pcm_format_t to_alsa_fmt(SoundIoFormat fmt) { return SND_PCM_FORMAT_UNKNOWN; } -static void test_fmt_mask(SoundIoDevice *device, const snd_pcm_format_mask_t *fmt_mask, SoundIoFormat fmt) { +static void test_fmt_mask(struct SoundIoDevice *device, const snd_pcm_format_mask_t *fmt_mask, + enum SoundIoFormat fmt) +{ if (snd_pcm_format_mask_test(fmt_mask, to_alsa_fmt(fmt))) { device->formats[device->format_count] = fmt; device->format_count += 1; @@ -242,7 +248,7 @@ static void test_fmt_mask(SoundIoDevice *device, const snd_pcm_format_mask_t *fm } static int set_access(snd_pcm_t *handle, snd_pcm_hw_params_t *hwparams, snd_pcm_access_t *out_access) { - for (int i = 0; i < array_length(prioritized_access_types); i += 1) { + for (int i = 0; i < ARRAY_LENGTH(prioritized_access_types); i += 1) { snd_pcm_access_t access = prioritized_access_types[i]; int err = snd_pcm_hw_params_set_access(handle, hwparams, access); if (err >= 0) { @@ -255,10 +261,10 @@ static int set_access(snd_pcm_t *handle, snd_pcm_hw_params_t *hwparams, snd_pcm_ } // this function does not override device->formats, so if you want it to, deallocate and set it to NULL -static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, int resample, +static int probe_open_device(struct SoundIoDevice *device, snd_pcm_t *handle, int resample, int *out_channels_min, int *out_channels_max) { - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; int err; snd_pcm_hw_params_t *hwparams; @@ -270,7 +276,7 @@ static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, int resam if ((err = snd_pcm_hw_params_set_rate_resample(handle, hwparams, resample)) < 0) return SoundIoErrorOpeningDevice; - if ((err = set_access(handle, hwparams, nullptr))) + if ((err = set_access(handle, hwparams, NULL))) return err; unsigned int channels_min; @@ -287,10 +293,10 @@ static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, int resam unsigned int rate_min; unsigned int rate_max; - if ((err = snd_pcm_hw_params_get_rate_min(hwparams, &rate_min, nullptr)) < 0) + if ((err = snd_pcm_hw_params_get_rate_min(hwparams, &rate_min, NULL)) < 0) return SoundIoErrorOpeningDevice; - if ((err = snd_pcm_hw_params_set_rate_last(handle, hwparams, &rate_max, nullptr)) < 0) + if ((err = snd_pcm_hw_params_set_rate_last(handle, hwparams, &rate_max, NULL)) < 0) return SoundIoErrorOpeningDevice; device->sample_rate_count = 1; @@ -345,7 +351,7 @@ static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, int resam if (!device->formats) { snd_pcm_hw_params_get_format_mask(hwparams, fmt_mask); - device->formats = allocate(18); + device->formats = ALLOCATE(enum SoundIoFormat, 18); if (!device->formats) return SoundIoErrorNoMem; @@ -373,7 +379,7 @@ static int probe_open_device(SoundIoDevice *device, snd_pcm_t *handle, int resam return 0; } -static int probe_device(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { +static int probe_device(struct SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { int err; snd_pcm_t *handle; @@ -398,20 +404,20 @@ static int probe_device(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { // the min and max channel counts are correct. int layout_count = 0; for (int i = 0; i < soundio_channel_layout_builtin_count(); i += 1) { - const SoundIoChannelLayout *layout = soundio_channel_layout_get_builtin(i); + const struct SoundIoChannelLayout *layout = soundio_channel_layout_get_builtin(i); if (layout->channel_count >= channels_min && layout->channel_count <= channels_max) { layout_count += 1; } } device->layout_count = layout_count; - device->layouts = allocate(device->layout_count); + device->layouts = ALLOCATE(struct SoundIoChannelLayout, device->layout_count); if (!device->layouts) { snd_pcm_close(handle); return SoundIoErrorNoMem; } int layout_index = 0; for (int i = 0; i < soundio_channel_layout_builtin_count(); i += 1) { - const SoundIoChannelLayout *layout = soundio_channel_layout_get_builtin(i); + const struct SoundIoChannelLayout *layout = soundio_channel_layout_get_builtin(i); if (layout->channel_count >= channels_min && layout->channel_count <= channels_max) { device->layouts[layout_index++] = *soundio_channel_layout_get_builtin(i); } @@ -428,7 +434,7 @@ static int probe_device(SoundIoDevice *device, snd_pcm_chmap_query_t **maps) { snd_pcm_close(handle); return err; } - maps = nullptr; + maps = NULL; if (!device->is_raw) { if (device->sample_rates[0].min == device->sample_rates[0].max) @@ -452,9 +458,9 @@ static inline bool str_has_prefix(const char *big_str, const char *prefix) { return strncmp(big_str, prefix, strlen(prefix)) == 0; } -static int refresh_devices(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoAlsa *sia = &si->backend_data.alsa; +static int refresh_devices(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoAlsa *sia = &si->backend_data.alsa; int err; if ((err = snd_config_update_free_global()) < 0) @@ -462,7 +468,7 @@ static int refresh_devices(SoundIoPrivate *si) { if ((err = snd_config_update()) < 0) return SoundIoErrorSystemResources; - SoundIoDevicesInfo *devices_info = allocate(1); + struct SoundIoDevicesInfo *devices_info = ALLOCATE(struct SoundIoDevicesInfo, 1); if (!devices_info) return SoundIoErrorNoMem; devices_info->default_output_index = -1; @@ -517,7 +523,7 @@ static int refresh_devices(SoundIoPrivate *si) { is_capture = true; } - for (int stream_type_i = 0; stream_type_i < array_length(stream_types); stream_type_i += 1) { + for (int stream_type_i = 0; stream_type_i < ARRAY_LENGTH(stream_types); stream_type_i += 1) { snd_pcm_stream_t stream = stream_types[stream_type_i]; if (stream == SND_PCM_STREAM_PLAYBACK && !is_playback) continue; if (stream == SND_PCM_STREAM_CAPTURE && !is_capture) continue; @@ -528,7 +534,7 @@ static int refresh_devices(SoundIoPrivate *si) { } - SoundIoDevicePrivate *dev = allocate(1); + struct SoundIoDevicePrivate *dev = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev) { free(name); free(descr); @@ -536,13 +542,13 @@ static int refresh_devices(SoundIoPrivate *si) { snd_device_name_free_hint(hints); return SoundIoErrorNoMem; } - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; device->ref_count = 1; device->soundio = soundio; device->is_raw = false; device->id = strdup(name); device->name = descr1 ? - soundio_alloc_sprintf(nullptr, "%s: %s", descr, descr1) : strdup(descr); + soundio_alloc_sprintf(NULL, "%s: %s", descr, descr1) : strdup(descr); if (!device->id || !device->name) { soundio_device_unref(device); @@ -553,7 +559,7 @@ static int refresh_devices(SoundIoPrivate *si) { return SoundIoErrorNoMem; } - SoundIoList *device_list; + struct SoundIoListDevicePtr *device_list; bool is_default = str_has_prefix(name, "default:") || strcmp(name, "default") == 0; if (stream == SND_PCM_STREAM_PLAYBACK) { device->aim = SoundIoDeviceAimOutput; @@ -568,9 +574,9 @@ static int refresh_devices(SoundIoPrivate *si) { devices_info->default_input_index = device_list->length; } - device->probe_error = probe_device(device, nullptr); + device->probe_error = probe_device(device, NULL); - if (device_list->append(device)) { + if (SoundIoListDevicePtr_append(device_list, device)) { soundio_device_unref(device); free(name); free(descr); @@ -631,7 +637,7 @@ static int refresh_devices(SoundIoPrivate *si) { snd_pcm_info_set_device(pcm_info, device_index); snd_pcm_info_set_subdevice(pcm_info, 0); - for (int stream_type_i = 0; stream_type_i < array_length(stream_types); stream_type_i += 1) { + for (int stream_type_i = 0; stream_type_i < ARRAY_LENGTH(stream_types); stream_type_i += 1) { snd_pcm_stream_t stream = stream_types[stream_type_i]; snd_pcm_info_set_stream(pcm_info, stream); @@ -647,17 +653,17 @@ static int refresh_devices(SoundIoPrivate *si) { const char *device_name = snd_pcm_info_get_name(pcm_info); - SoundIoDevicePrivate *dev = allocate(1); + struct SoundIoDevicePrivate *dev = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev) { snd_ctl_close(handle); soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; device->ref_count = 1; device->soundio = soundio; - device->id = soundio_alloc_sprintf(nullptr, "hw:%d,%d", card_index, device_index); - device->name = soundio_alloc_sprintf(nullptr, "%s %s", card_name, device_name); + device->id = soundio_alloc_sprintf(NULL, "hw:%d,%d", card_index, device_index); + device->name = soundio_alloc_sprintf(NULL, "%s %s", card_name, device_name); device->is_raw = true; if (!device->id || !device->name) { @@ -667,7 +673,7 @@ static int refresh_devices(SoundIoPrivate *si) { return SoundIoErrorNoMem; } - SoundIoList *device_list; + struct SoundIoListDevicePtr *device_list; if (stream == SND_PCM_STREAM_PLAYBACK) { device->aim = SoundIoDeviceAimOutput; device_list = &devices_info->output_devices; @@ -680,7 +686,7 @@ static int refresh_devices(SoundIoPrivate *si) { snd_pcm_chmap_query_t **maps = snd_pcm_query_chmaps_from_hw(card_index, device_index, -1, stream); device->probe_error = probe_device(device, maps); - if (device_list->append(device)) { + if (SoundIoListDevicePtr_append(device_list, device)) { soundio_device_unref(device); soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; @@ -704,9 +710,9 @@ static int refresh_devices(SoundIoPrivate *si) { return 0; } -static void shutdown_backend(SoundIoPrivate *si, int err) { - SoundIo *soundio = &si->pub; - SoundIoAlsa *sia = &si->backend_data.alsa; +static void shutdown_backend(struct SoundIoPrivate *si, int err) { + struct SoundIo *soundio = &si->pub; + struct SoundIoAlsa *sia = &si->backend_data.alsa; soundio_os_mutex_lock(sia->mutex); sia->shutdown_err = err; soundio_os_cond_signal(sia->cond, sia->mutex); @@ -730,8 +736,8 @@ static bool copy_str(char *dest, const char *src, int buf_len) { } static void device_thread_run(void *arg) { - SoundIoPrivate *si = (SoundIoPrivate *)arg; - SoundIoAlsa *sia = &si->backend_data.alsa; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)arg; + struct SoundIoAlsa *sia = &si->backend_data.alsa; // Some systems cannot read integer variables if they are not // properly aligned. On other systems, incorrect alignment may @@ -751,7 +757,7 @@ static void device_thread_run(void *arg) { int err; for (;;) { int poll_num = poll(fds, 2, -1); - if (!sia->abort_flag.test_and_set()) + if (!atomic_flag_test_and_set(&sia->abort_flag)) break; if (poll_num == -1) { if (errno == EINTR) @@ -801,13 +807,14 @@ static void device_thread_run(void *arg) { continue; } if (event->mask & IN_CREATE) { - if ((err = sia->pending_files.add_one())) { + if ((err = SoundIoListAlsaPendingFile_add_one(&sia->pending_files))) { shutdown_backend(si, SoundIoErrorNoMem); return; } - SoundIoAlsaPendingFile *pending_file = &sia->pending_files.last(); + struct SoundIoAlsaPendingFile *pending_file = + SoundIoListAlsaPendingFile_last_ptr(&sia->pending_files); if (!copy_str(pending_file->name, event->name, SOUNDIO_MAX_ALSA_SND_FILE_LEN)) { - sia->pending_files.pop(); + SoundIoListAlsaPendingFile_pop(&sia->pending_files); } continue; } @@ -817,9 +824,10 @@ static void device_thread_run(void *arg) { if (!(event->mask & IN_CLOSE_WRITE)) continue; for (int i = 0; i < sia->pending_files.length; i += 1) { - SoundIoAlsaPendingFile *pending_file = &sia->pending_files.at(i); + struct SoundIoAlsaPendingFile *pending_file = + SoundIoListAlsaPendingFile_ptr_at(&sia->pending_files, i); if (strcmp(pending_file->name, event->name) == 0) { - sia->pending_files.swap_remove(i); + SoundIoListAlsaPendingFile_swap_remove(&sia->pending_files, i); if (sia->pending_files.length == 0) { got_rescan_event = true; } @@ -864,13 +872,13 @@ static void device_thread_run(void *arg) { } } -static void my_flush_events(SoundIoPrivate *si, bool wait) { - SoundIo *soundio = &si->pub; - SoundIoAlsa *sia = &si->backend_data.alsa; +static void my_flush_events(struct SoundIoPrivate *si, bool wait) { + struct SoundIo *soundio = &si->pub; + struct SoundIoAlsa *sia = &si->backend_data.alsa; bool change = false; bool cb_shutdown = false; - SoundIoDevicesInfo *old_devices_info = nullptr; + struct SoundIoDevicesInfo *old_devices_info = NULL; soundio_os_mutex_lock(sia->mutex); @@ -886,7 +894,7 @@ static void my_flush_events(SoundIoPrivate *si, bool wait) { } else if (sia->ready_devices_info) { old_devices_info = si->safe_devices_info; si->safe_devices_info = sia->ready_devices_info; - sia->ready_devices_info = nullptr; + sia->ready_devices_info = NULL; change = true; } @@ -900,54 +908,54 @@ static void my_flush_events(SoundIoPrivate *si, bool wait) { soundio_destroy_devices_info(old_devices_info); } -static void flush_events_alsa(SoundIoPrivate *si) { +static void flush_events_alsa(struct SoundIoPrivate *si) { my_flush_events(si, false); } -static void wait_events_alsa(SoundIoPrivate *si) { +static void wait_events_alsa(struct SoundIoPrivate *si) { my_flush_events(si, false); my_flush_events(si, true); } -static void wakeup_alsa(SoundIoPrivate *si) { - SoundIoAlsa *sia = &si->backend_data.alsa; +static void wakeup_alsa(struct SoundIoPrivate *si) { + struct SoundIoAlsa *sia = &si->backend_data.alsa; soundio_os_mutex_lock(sia->mutex); soundio_os_cond_signal(sia->cond, sia->mutex); soundio_os_mutex_unlock(sia->mutex); } -static void force_device_scan_alsa(SoundIoPrivate *si) { - SoundIoAlsa *sia = &si->backend_data.alsa; +static void force_device_scan_alsa(struct SoundIoPrivate *si) { + struct SoundIoAlsa *sia = &si->backend_data.alsa; wakeup_device_poll(sia); } -static void outstream_destroy_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; +static void outstream_destroy_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; if (osa->thread) { - osa->thread_exit_flag.clear(); + atomic_flag_clear(&osa->thread_exit_flag); soundio_os_thread_destroy(osa->thread); - osa->thread = nullptr; + osa->thread = NULL; } if (osa->handle) { snd_pcm_close(osa->handle); - osa->handle = nullptr; + osa->handle = NULL; } free(osa->poll_fds); - osa->poll_fds = nullptr; + osa->poll_fds = NULL; free(osa->chmap); - osa->chmap = nullptr; + osa->chmap = NULL; free(osa->sample_buffer); - osa->sample_buffer = nullptr; + osa->sample_buffer = NULL; } -static int outstream_xrun_recovery(SoundIoOutStreamPrivate *os, int err) { - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; +static int outstream_xrun_recovery(struct SoundIoOutStreamPrivate *os, int err) { + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; if (err == -EPIPE) { err = snd_pcm_prepare(osa->handle); if (err >= 0) @@ -955,7 +963,7 @@ static int outstream_xrun_recovery(SoundIoOutStreamPrivate *os, int err) { } else if (err == -ESTRPIPE) { while ((err = snd_pcm_resume(osa->handle)) == -EAGAIN) { // wait until suspend flag is released - poll(nullptr, 0, 1); + poll(NULL, 0, 1); } if (err < 0) err = snd_pcm_prepare(osa->handle); @@ -965,9 +973,9 @@ static int outstream_xrun_recovery(SoundIoOutStreamPrivate *os, int err) { return err; } -static int instream_xrun_recovery(SoundIoInStreamPrivate *is, int err) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; +static int instream_xrun_recovery(struct SoundIoInStreamPrivate *is, int err) { + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; if (err == -EPIPE) { err = snd_pcm_prepare(isa->handle); if (err >= 0) @@ -975,7 +983,7 @@ static int instream_xrun_recovery(SoundIoInStreamPrivate *is, int err) { } else if (err == -ESTRPIPE) { while ((err = snd_pcm_resume(isa->handle)) == -EAGAIN) { // wait until suspend flag is released - poll(nullptr, 0, 1); + poll(NULL, 0, 1); } if (err < 0) err = snd_pcm_prepare(isa->handle); @@ -985,8 +993,8 @@ static int instream_xrun_recovery(SoundIoInStreamPrivate *is, int err) { return err; } -static int outstream_wait_for_poll(SoundIoOutStreamPrivate *os) { - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; +static int outstream_wait_for_poll(struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; int err; unsigned short revents; for (;;) { @@ -1006,8 +1014,8 @@ static int outstream_wait_for_poll(SoundIoOutStreamPrivate *os) { } } -static int instream_wait_for_poll(SoundIoInStreamPrivate *is) { - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; +static int instream_wait_for_poll(struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; int err; unsigned short revents; for (;;) { @@ -1028,9 +1036,9 @@ static int instream_wait_for_poll(SoundIoInStreamPrivate *is) { } static void outstream_thread_run(void *arg) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *) arg; - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *) arg; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; int err; @@ -1055,7 +1063,7 @@ static void outstream_thread_run(void *arg) { if ((snd_pcm_uframes_t)avail == osa->buffer_size_frames) { outstream->write_callback(outstream, 0, avail); - if (!osa->thread_exit_flag.test_and_set()) + if (!atomic_flag_test_and_set(&osa->thread_exit_flag)) return; continue; } @@ -1070,14 +1078,14 @@ static void outstream_thread_run(void *arg) { case SND_PCM_STATE_PAUSED: { if ((err = outstream_wait_for_poll(os)) < 0) { - if (!osa->thread_exit_flag.test_and_set()) + if (!atomic_flag_test_and_set(&osa->thread_exit_flag)) return; outstream->error_callback(outstream, SoundIoErrorStreaming); return; } - if (!osa->thread_exit_flag.test_and_set()) + if (!atomic_flag_test_and_set(&osa->thread_exit_flag)) return; - if (!osa->clear_buffer_flag.test_and_set()) { + if (!atomic_flag_test_and_set(&osa->clear_buffer_flag)) { if ((err = snd_pcm_drop(osa->handle)) < 0) { outstream->error_callback(outstream, SoundIoErrorStreaming); return; @@ -1130,9 +1138,9 @@ static void outstream_thread_run(void *arg) { } static void instream_thread_run(void *arg) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *) arg; - SoundIoInStream *instream = &is->pub; - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *) arg; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; int err; @@ -1155,12 +1163,12 @@ static void instream_thread_run(void *arg) { case SND_PCM_STATE_PAUSED: { if ((err = instream_wait_for_poll(is)) < 0) { - if (!isa->thread_exit_flag.test_and_set()) + if (!atomic_flag_test_and_set(&isa->thread_exit_flag)) return; instream->error_callback(instream, SoundIoErrorStreaming); return; } - if (!isa->thread_exit_flag.test_and_set()) + if (!atomic_flag_test_and_set(&isa->thread_exit_flag)) return; snd_pcm_sframes_t avail = snd_pcm_avail_update(isa->handle); @@ -1198,21 +1206,21 @@ static void instream_thread_run(void *arg) { } } -static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; - SoundIoOutStream *outstream = &os->pub; - SoundIoDevice *device = outstream->device; +static int outstream_open_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoDevice *device = outstream->device; - osa->clear_buffer_flag.test_and_set(); + atomic_flag_test_and_set(&osa->clear_buffer_flag); if (outstream->software_latency == 0.0) outstream->software_latency = 1.0; - outstream->software_latency = clamp(device->software_latency_min, outstream->software_latency, device->software_latency_max); + outstream->software_latency = soundio_double_clamp(device->software_latency_min, outstream->software_latency, device->software_latency_max); int ch_count = outstream->layout.channel_count; osa->chmap_size = sizeof(int) + sizeof(int) * ch_count; - osa->chmap = (snd_pcm_chmap_t *)allocate(osa->chmap_size); + osa->chmap = (snd_pcm_chmap_t *)ALLOCATE(char, osa->chmap_size); if (!osa->chmap) { outstream_destroy_alsa(si, os); return SoundIoErrorNoMem; @@ -1272,7 +1280,7 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) if (device->is_raw) { period_count = 4; unsigned int microseconds = 0.25 * outstream->software_latency * 1000000.0; - if ((err = snd_pcm_hw_params_set_period_time_near(osa->handle, hwparams, µseconds, nullptr)) < 0) { + if ((err = snd_pcm_hw_params_set_period_time_near(osa->handle, hwparams, µseconds, NULL)) < 0) { outstream_destroy_alsa(si, os); return SoundIoErrorOpeningDevice; } @@ -1282,14 +1290,14 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) snd_pcm_uframes_t period_frames = ceil_dbl_to_uframes(period_duration * (double)outstream->sample_rate); - if ((err = snd_pcm_hw_params_set_period_size_near(osa->handle, hwparams, &period_frames, nullptr)) < 0) { + if ((err = snd_pcm_hw_params_set_period_size_near(osa->handle, hwparams, &period_frames, NULL)) < 0) { outstream_destroy_alsa(si, os); return SoundIoErrorOpeningDevice; } } snd_pcm_uframes_t period_size; - if ((snd_pcm_hw_params_get_period_size(hwparams, &period_size, nullptr)) < 0) { + if ((snd_pcm_hw_params_get_period_size(hwparams, &period_size, NULL)) < 0) { outstream_destroy_alsa(si, os); return SoundIoErrorOpeningDevice; } @@ -1343,7 +1351,7 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) if (osa->access == SND_PCM_ACCESS_RW_INTERLEAVED || osa->access == SND_PCM_ACCESS_RW_NONINTERLEAVED) { osa->sample_buffer_size = ch_count * osa->period_size * phys_bytes_per_sample; - osa->sample_buffer = allocate_nonzero(osa->sample_buffer_size); + osa->sample_buffer = ALLOCATE_NONZERO(char, osa->sample_buffer_size); if (!osa->sample_buffer) { outstream_destroy_alsa(si, os); return SoundIoErrorNoMem; @@ -1356,7 +1364,7 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) return SoundIoErrorOpeningDevice; } - osa->poll_fds = allocate(osa->poll_fd_count); + osa->poll_fds = ALLOCATE(struct pollfd, osa->poll_fd_count); if (!osa->poll_fds) { outstream_destroy_alsa(si, os); return SoundIoErrorNoMem; @@ -1370,26 +1378,26 @@ static int outstream_open_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) return 0; } -static int outstream_start_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; - SoundIo *soundio = &si->pub; +static int outstream_start_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; + struct SoundIo *soundio = &si->pub; assert(!osa->thread); int err; - osa->thread_exit_flag.test_and_set(); + atomic_flag_test_and_set(&osa->thread_exit_flag); if ((err = soundio_os_thread_create(outstream_thread_run, os, soundio->emit_rtprio_warning, &osa->thread))) return err; return 0; } -static int outstream_begin_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, +static int outstream_begin_write_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, struct SoundIoChannelArea **out_areas, int *frame_count) { - *out_areas = nullptr; - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; - SoundIoOutStream *outstream = &os->pub; + *out_areas = NULL; + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; + struct SoundIoOutStream *outstream = &os->pub; if (osa->access == SND_PCM_ACCESS_RW_INTERLEAVED) { for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) { @@ -1397,7 +1405,7 @@ static int outstream_begin_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivat osa->areas[ch].step = outstream->bytes_per_frame; } - osa->write_frame_count = min(*frame_count, osa->period_size); + osa->write_frame_count = soundio_int_min(*frame_count, osa->period_size); *frame_count = osa->write_frame_count; } else if (osa->access == SND_PCM_ACCESS_RW_NONINTERLEAVED) { for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) { @@ -1405,7 +1413,7 @@ static int outstream_begin_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivat osa->areas[ch].step = outstream->bytes_per_sample; } - osa->write_frame_count = min(*frame_count, osa->period_size); + osa->write_frame_count = soundio_int_min(*frame_count, osa->period_size); *frame_count = osa->write_frame_count; } else { const snd_pcm_channel_area_t *areas; @@ -1435,9 +1443,9 @@ static int outstream_begin_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivat return 0; } -static int outstream_end_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; - SoundIoOutStream *outstream = &os->pub; +static int outstream_end_write_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; + struct SoundIoOutStream *outstream = &os->pub; snd_pcm_sframes_t commitres; if (osa->access == SND_PCM_ACCESS_RW_INTERLEAVED) { @@ -1462,11 +1470,11 @@ static int outstream_end_write_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate return 0; } -static int outstream_clear_buffer_alsa(SoundIoPrivate *si, - SoundIoOutStreamPrivate *os) +static int outstream_clear_buffer_alsa(struct SoundIoPrivate *si, + struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; - osa->clear_buffer_flag.clear(); + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; + atomic_flag_clear(&osa->clear_buffer_flag); return 0; } @@ -1474,7 +1482,7 @@ static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStre if (!si) return SoundIoErrorInvalid; - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; if (!osa->handle) return SoundIoErrorInvalid; @@ -1494,8 +1502,8 @@ static int outstream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoOutStre static int outstream_get_latency_alsa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, double *out_latency) { - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamAlsa *osa = &os->backend_data.alsa; int err; snd_pcm_sframes_t delay; @@ -1507,43 +1515,43 @@ static int outstream_get_latency_alsa(struct SoundIoPrivate *si, struct SoundIoO return 0; } -static void instream_destroy_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; +static void instream_destroy_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; if (isa->thread) { - isa->thread_exit_flag.clear(); + atomic_flag_clear(&isa->thread_exit_flag); soundio_os_thread_destroy(isa->thread); - isa->thread = nullptr; + isa->thread = NULL; } if (isa->handle) { snd_pcm_close(isa->handle); - isa->handle = nullptr; + isa->handle = NULL; } free(isa->poll_fds); - isa->poll_fds = nullptr; + isa->poll_fds = NULL; free(isa->chmap); - isa->chmap = nullptr; + isa->chmap = NULL; free(isa->sample_buffer); - isa->sample_buffer = nullptr; + isa->sample_buffer = NULL; } -static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; - SoundIoInStream *instream = &is->pub; - SoundIoDevice *device = instream->device; +static int instream_open_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoDevice *device = instream->device; if (instream->software_latency == 0.0) instream->software_latency = 1.0; - instream->software_latency = clamp(device->software_latency_min, instream->software_latency, device->software_latency_max); + instream->software_latency = soundio_double_clamp(device->software_latency_min, instream->software_latency, device->software_latency_max); int ch_count = instream->layout.channel_count; isa->chmap_size = sizeof(int) + sizeof(int) * ch_count; - isa->chmap = (snd_pcm_chmap_t *)allocate(isa->chmap_size); + isa->chmap = (snd_pcm_chmap_t *)ALLOCATE(char, isa->chmap_size); if (!isa->chmap) { instream_destroy_alsa(si, is); return SoundIoErrorNoMem; @@ -1600,7 +1608,7 @@ static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { } snd_pcm_uframes_t period_frames = ceil_dbl_to_uframes(0.5 * instream->software_latency * (double)instream->sample_rate); - if ((err = snd_pcm_hw_params_set_period_size_near(isa->handle, hwparams, &period_frames, nullptr)) < 0) { + if ((err = snd_pcm_hw_params_set_period_size_near(isa->handle, hwparams, &period_frames, NULL)) < 0) { instream_destroy_alsa(si, is); return SoundIoErrorOpeningDevice; } @@ -1645,7 +1653,7 @@ static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { if (isa->access == SND_PCM_ACCESS_RW_INTERLEAVED || isa->access == SND_PCM_ACCESS_RW_NONINTERLEAVED) { isa->sample_buffer_size = ch_count * isa->period_size * phys_bytes_per_sample; - isa->sample_buffer = allocate_nonzero(isa->sample_buffer_size); + isa->sample_buffer = ALLOCATE_NONZERO(char, isa->sample_buffer_size); if (!isa->sample_buffer) { instream_destroy_alsa(si, is); return SoundIoErrorNoMem; @@ -1658,7 +1666,7 @@ static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { return SoundIoErrorOpeningDevice; } - isa->poll_fds = allocate(isa->poll_fd_count); + isa->poll_fds = ALLOCATE(struct pollfd, isa->poll_fd_count); if (!isa->poll_fds) { instream_destroy_alsa(si, is); return SoundIoErrorNoMem; @@ -1672,13 +1680,13 @@ static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { return 0; } -static int instream_start_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; - SoundIo *soundio = &si->pub; +static int instream_start_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; + struct SoundIo *soundio = &si->pub; assert(!isa->thread); - isa->thread_exit_flag.test_and_set(); + atomic_flag_test_and_set(&isa->thread_exit_flag); int err; if ((err = soundio_os_thread_create(instream_thread_run, is, soundio->emit_rtprio_warning, &isa->thread))) { instream_destroy_alsa(si, is); @@ -1688,12 +1696,12 @@ static int instream_start_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { return 0; } -static int instream_begin_read_alsa(SoundIoPrivate *si, - SoundIoInStreamPrivate *is, SoundIoChannelArea **out_areas, int *frame_count) +static int instream_begin_read_alsa(struct SoundIoPrivate *si, + struct SoundIoInStreamPrivate *is, struct SoundIoChannelArea **out_areas, int *frame_count) { - *out_areas = nullptr; - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; - SoundIoInStream *instream = &is->pub; + *out_areas = NULL; + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; + struct SoundIoInStream *instream = &is->pub; if (isa->access == SND_PCM_ACCESS_RW_INTERLEAVED) { for (int ch = 0; ch < instream->layout.channel_count; ch += 1) { @@ -1701,7 +1709,7 @@ static int instream_begin_read_alsa(SoundIoPrivate *si, isa->areas[ch].step = instream->bytes_per_frame; } - isa->read_frame_count = min(*frame_count, isa->period_size); + isa->read_frame_count = soundio_int_min(*frame_count, isa->period_size); *frame_count = isa->read_frame_count; snd_pcm_sframes_t commitres = snd_pcm_readi(isa->handle, isa->sample_buffer, isa->read_frame_count); @@ -1718,7 +1726,7 @@ static int instream_begin_read_alsa(SoundIoPrivate *si, ptrs[ch] = isa->areas[ch].ptr; } - isa->read_frame_count = min(*frame_count, isa->period_size); + isa->read_frame_count = soundio_int_min(*frame_count, isa->period_size); *frame_count = isa->read_frame_count; snd_pcm_sframes_t commitres = snd_pcm_readn(isa->handle, (void**)ptrs, isa->read_frame_count); @@ -1753,8 +1761,8 @@ static int instream_begin_read_alsa(SoundIoPrivate *si, return 0; } -static int instream_end_read_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; +static int instream_end_read_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; if (isa->access == SND_PCM_ACCESS_RW_INTERLEAVED) { // nothing to do @@ -1773,7 +1781,7 @@ static int instream_end_read_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is } static int instream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) { - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; if (isa->is_paused == pause) return 0; @@ -1789,8 +1797,8 @@ static int instream_pause_alsa(struct SoundIoPrivate *si, struct SoundIoInStream static int instream_get_latency_alsa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, double *out_latency) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamAlsa *isa = &is->backend_data.alsa; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamAlsa *isa = &is->backend_data.alsa; int err; snd_pcm_sframes_t delay; @@ -1802,13 +1810,13 @@ static int instream_get_latency_alsa(struct SoundIoPrivate *si, struct SoundIoIn return 0; } -int soundio_alsa_init(SoundIoPrivate *si) { - SoundIoAlsa *sia = &si->backend_data.alsa; +int soundio_alsa_init(struct SoundIoPrivate *si) { + struct SoundIoAlsa *sia = &si->backend_data.alsa; int err; sia->notify_fd = -1; sia->notify_wd = -1; - sia->abort_flag.test_and_set(); + atomic_flag_test_and_set(&sia->abort_flag); sia->mutex = soundio_os_mutex_create(); if (!sia->mutex) { @@ -1865,7 +1873,7 @@ int soundio_alsa_init(SoundIoPrivate *si) { wakeup_device_poll(sia); - if ((err = soundio_os_thread_create(device_thread_run, si, nullptr, &sia->thread))) { + if ((err = soundio_os_thread_create(device_thread_run, si, NULL, &sia->thread))) { destroy_alsa(si); return err; } diff --git a/src/alsa.hpp b/src/alsa.h similarity index 71% rename from src/alsa.hpp rename to src/alsa.h index cb6eda2..25c5587 100644 --- a/src/alsa.hpp +++ b/src/alsa.h @@ -5,28 +5,31 @@ * See http://opensource.org/licenses/MIT */ -#ifndef SOUNDIO_ALSA_HPP -#define SOUNDIO_ALSA_HPP +#ifndef SOUNDIO_ALSA_H +#define SOUNDIO_ALSA_H -#include "soundio_private.h" +#include "soundio_internal.h" #include "os.h" -#include "atomics.hpp" -#include "list.hpp" +#include "list.h" +#include "atomics.h" #include +struct SoundIoPrivate; int soundio_alsa_init(struct SoundIoPrivate *si); -struct SoundIoDeviceAlsa { }; +struct SoundIoDeviceAlsa { int make_the_struct_not_empty; }; #define SOUNDIO_MAX_ALSA_SND_FILE_LEN 16 struct SoundIoAlsaPendingFile { char name[SOUNDIO_MAX_ALSA_SND_FILE_LEN]; }; +SOUNDIO_MAKE_LIST_STRUCT(struct SoundIoAlsaPendingFile, SoundIoListAlsaPendingFile, SOUNDIO_LIST_STATIC) + struct SoundIoAlsa { - SoundIoOsMutex *mutex; - SoundIoOsCond *cond; + struct SoundIoOsMutex *mutex; + struct SoundIoOsCond *cond; struct SoundIoOsThread *thread; atomic_flag abort_flag; @@ -34,7 +37,7 @@ struct SoundIoAlsa { int notify_wd; bool have_devices_flag; int notify_pipe_fd[2]; - SoundIoList pending_files; + struct SoundIoListAlsaPendingFile pending_files; // this one is ready to be read with flush_events. protected by mutex struct SoundIoDevicesInfo *ready_devices_info; @@ -54,13 +57,13 @@ struct SoundIoOutStreamAlsa { char *sample_buffer; int poll_fd_count; struct pollfd *poll_fds; - SoundIoOsThread *thread; + struct SoundIoOsThread *thread; atomic_flag thread_exit_flag; int period_size; int write_frame_count; bool is_paused; atomic_flag clear_buffer_flag; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; struct SoundIoInStreamAlsa { @@ -73,12 +76,12 @@ struct SoundIoInStreamAlsa { char *sample_buffer; int poll_fd_count; struct pollfd *poll_fds; - SoundIoOsThread *thread; + struct SoundIoOsThread *thread; atomic_flag thread_exit_flag; int period_size; int read_frame_count; bool is_paused; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; #endif diff --git a/src/atomics.h b/src/atomics.h new file mode 100644 index 0000000..6f0bcce --- /dev/null +++ b/src/atomics.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015 Andrew Kelley + * + * This file is part of libsoundio, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef SOUNDIO_ATOMICS_H +#define SOUNDIO_ATOMICS_H + +// Simple wrappers around atomic values so that the compiler will catch it if +// I accidentally use operators such as +, -, += on them. + +#include + +struct SoundIoAtomicLong { + atomic_long x; +}; + +struct SoundIoAtomicInt { + atomic_int x; +}; + +struct SoundIoAtomicBool { + atomic_bool x; +}; + +#define SOUNDIO_ATOMIC_LOAD(a) atomic_load(&a.x) +#define SOUNDIO_ATOMIC_FETCH_ADD(a, delta) atomic_fetch_add(&a.x, delta) +#define SOUNDIO_ATOMIC_STORE(a, value) atomic_store(&a.x, value) +#define SOUNDIO_ATOMIC_EXCHANGE(a, value) atomic_exchange(&a.x, value) + +#endif diff --git a/src/atomics.hpp b/src/atomics.hpp deleted file mode 100644 index 6dd77f5..0000000 --- a/src/atomics.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Kelley - * - * This file is part of libsoundio, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#ifndef SOUNDIO_ATOMICS_HPP -#define SOUNDIO_ATOMICS_HPP - -#include -using std::atomic_flag; -using std::atomic_int; -using std::atomic_long; -using std::atomic_bool; -using std::atomic_uintptr_t; - -#if ATOMIC_INT_LOCK_FREE != 2 -#error "require atomic_int to be lock free" -#endif - -#if ATOMIC_LONG_LOCK_FREE != 2 -#error "require atomic_long to be lock free" -#endif - -#if ATOMIC_BOOL_LOCK_FREE != 2 -#error "require atomic_bool to be lock free" -#endif - -#if ATOMIC_POINTER_LOCK_FREE != 2 -#error "require atomic pointers to be lock free" -#endif - -#endif diff --git a/src/channel_layout.cpp b/src/channel_layout.c similarity index 87% rename from src/channel_layout.cpp rename to src/channel_layout.c index 4f023c8..bcefa9a 100644 --- a/src/channel_layout.cpp +++ b/src/channel_layout.c @@ -5,7 +5,7 @@ * See http://opensource.org/licenses/MIT */ -#include "soundio.hpp" +#include "soundio_private.h" #include @@ -308,12 +308,12 @@ static struct SoundIoChannelLayout builtin_channel_layouts[] = { }, }; -static const int channel_name_alias_count = 3; -static const char *channel_names[][channel_name_alias_count] = { +#define CHANNEL_NAME_ALIAS_COUNT 3 +static const char *channel_names[][CHANNEL_NAME_ALIAS_COUNT] = { [SoundIoChannelIdInvalid] = { "(Invalid Channel)", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdFrontLeft] = { "Front Left", @@ -407,258 +407,258 @@ static const char *channel_names[][channel_name_alias_count] = { }, [SoundIoChannelIdBackLeftCenter] = { "Back Left Center", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdBackRightCenter] = { "Back Right Center", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdFrontLeftWide] = { "Front Left Wide", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdFrontRightWide] = { "Front Right Wide", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdFrontLeftHigh] = { "Front Left High", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdFrontCenterHigh] = { "Front Center High", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdFrontRightHigh] = { "Front Right High", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdTopFrontLeftCenter] = { "Top Front Left Center", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdTopFrontRightCenter] = { "Top Front Right Center", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdTopSideLeft] = { "Top Side Left", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdTopSideRight] = { "Top Side Right", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdLeftLfe] = { "Left LFE", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdRightLfe] = { "Right LFE", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdLfe2] = { "LFE 2", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdBottomCenter] = { "Bottom Center", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdBottomLeftCenter] = { "Bottom Left Center", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdBottomRightCenter] = { "Bottom Right Center", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdMsMid] = { "Mid/Side Mid", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdMsSide] = { "Mid/Side Side", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAmbisonicW] = { "Ambisonic W", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAmbisonicX] = { "Ambisonic X", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAmbisonicY] = { "Ambisonic Y", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAmbisonicZ] = { "Ambisonic Z", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdXyX] = { "X-Y X", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdXyY] = { "X-Y Y", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdHeadphonesLeft] = { "Headphones Left", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdHeadphonesRight] = { "Headphones Right", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdClickTrack] = { "Click Track", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdForeignLanguage] = { "Foreign Language", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdHearingImpaired] = { "Hearing Impaired", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdNarration] = { "Narration", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdHaptic] = { "Haptic", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdDialogCentricMix] = { "Dialog Centric Mix", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux] = { "Aux", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux0] = { "Aux 0", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux1] = { "Aux 1", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux2] = { "Aux 2", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux3] = { "Aux 3", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux4] = { "Aux 4", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux5] = { "Aux 5", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux6] = { "Aux 6", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux7] = { "Aux 7", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux8] = { "Aux 8", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux9] = { "Aux 9", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux10] = { "Aux 10", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux11] = { "Aux 11", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux12] = { "Aux 12", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux13] = { "Aux 13", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux14] = { "Aux 14", - nullptr, - nullptr, + NULL, + NULL, }, [SoundIoChannelIdAux15] = { "Aux 15", - nullptr, - nullptr, + NULL, + NULL, }, }; const char *soundio_get_channel_name(enum SoundIoChannelId id) { - if (id < 0 || id > array_length(channel_names)) + if (id >= ARRAY_LENGTH(channel_names)) return "(Invalid Channel)"; else return channel_names[id][0]; @@ -680,12 +680,12 @@ bool soundio_channel_layout_equal( } int soundio_channel_layout_builtin_count(void) { - return array_length(builtin_channel_layouts); + return ARRAY_LENGTH(builtin_channel_layouts); } const struct SoundIoChannelLayout *soundio_channel_layout_get_builtin(int index) { assert(index >= 0); - assert(index <= array_length(builtin_channel_layouts)); + assert(index <= ARRAY_LENGTH(builtin_channel_layouts)); return &builtin_channel_layouts[index]; } @@ -700,14 +700,14 @@ int soundio_channel_layout_find_channel( } bool soundio_channel_layout_detect_builtin(struct SoundIoChannelLayout *layout) { - for (int i = 0; i < array_length(builtin_channel_layouts); i += 1) { + for (int i = 0; i < ARRAY_LENGTH(builtin_channel_layouts); i += 1) { const struct SoundIoChannelLayout *builtin_layout = &builtin_channel_layouts[i]; if (soundio_channel_layout_equal(builtin_layout, layout)) { layout->name = builtin_layout->name; return true; } } - layout->name = nullptr; + layout->name = NULL; return false; } @@ -722,18 +722,18 @@ const struct SoundIoChannelLayout *soundio_channel_layout_get_default(int channe case 7: return soundio_channel_layout_get_builtin(SoundIoChannelLayoutId6Point1); case 8: return soundio_channel_layout_get_builtin(SoundIoChannelLayoutId7Point1); } - return nullptr; + return NULL; } enum SoundIoChannelId soundio_parse_channel_id(const char *str, int str_len) { - for (int id = 0; id < array_length(channel_names); id += 1) { - for (int i = 0; i < channel_name_alias_count; i += 1) { + for (int id = 0; id < ARRAY_LENGTH(channel_names); id += 1) { + for (int i = 0; i < CHANNEL_NAME_ALIAS_COUNT; i += 1) { const char *alias = channel_names[id][i]; if (!alias) break; int alias_len = strlen(alias); if (soundio_streql(alias, alias_len, str, str_len)) - return (SoundIoChannelId)id; + return (enum SoundIoChannelId)id; } } return SoundIoChannelIdInvalid; diff --git a/src/coreaudio.cpp b/src/coreaudio.c similarity index 83% rename from src/coreaudio.cpp rename to src/coreaudio.c index 0a9f85a..f625af0 100644 --- a/src/coreaudio.cpp +++ b/src/coreaudio.c @@ -5,8 +5,8 @@ * See http://opensource.org/licenses/MIT */ -#include "coreaudio.hpp" -#include "soundio.hpp" +#include "coreaudio.h" +#include "soundio_private.h" #include @@ -91,19 +91,21 @@ static AudioObjectPropertyAddress device_listen_props[] = { }, }; -static SoundIoDeviceAim aims[] = { +static enum SoundIoDeviceAim aims[] = { SoundIoDeviceAimInput, SoundIoDeviceAimOutput, }; +SOUNDIO_MAKE_LIST_DEF(AudioDeviceID, SoundIoListAudioDeviceID, SOUNDIO_LIST_STATIC) + static OSStatus on_devices_changed(AudioObjectID in_object_id, UInt32 in_number_addresses, const AudioObjectPropertyAddress in_addresses[], void *in_client_data) { - SoundIoPrivate *si = (SoundIoPrivate*)in_client_data; - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + struct SoundIoPrivate *si = (struct SoundIoPrivate*)in_client_data; + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; - sica->device_scan_queued.store(true); - soundio_os_cond_signal(sica->scan_devices_cond, nullptr); + SOUNDIO_ATOMIC_STORE(sica->device_scan_queued, true); + soundio_os_cond_signal(sica->scan_devices_cond, NULL); return noErr; } @@ -111,30 +113,30 @@ static OSStatus on_devices_changed(AudioObjectID in_object_id, UInt32 in_number_ static OSStatus on_service_restarted(AudioObjectID in_object_id, UInt32 in_number_addresses, const AudioObjectPropertyAddress in_addresses[], void *in_client_data) { - SoundIoPrivate *si = (SoundIoPrivate*)in_client_data; - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + struct SoundIoPrivate *si = (struct SoundIoPrivate*)in_client_data; + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; - sica->service_restarted.store(true); - soundio_os_cond_signal(sica->scan_devices_cond, nullptr); + SOUNDIO_ATOMIC_STORE(sica->service_restarted, true); + soundio_os_cond_signal(sica->scan_devices_cond, NULL); return noErr; } -static void unsubscribe_device_listeners(SoundIoPrivate *si) { - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; +static void unsubscribe_device_listeners(struct SoundIoPrivate *si) { + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; for (int device_index = 0; device_index < sica->registered_listeners.length; device_index += 1) { - AudioDeviceID device_id = sica->registered_listeners.at(device_index); - for (int i = 0; i < array_length(device_listen_props); i += 1) { + AudioDeviceID device_id = SoundIoListAudioDeviceID_val_at(&sica->registered_listeners, device_index); + for (int i = 0; i < ARRAY_LENGTH(device_listen_props); i += 1) { AudioObjectRemovePropertyListener(device_id, &device_listen_props[i], on_devices_changed, si); } } - sica->registered_listeners.clear(); + SoundIoListAudioDeviceID_clear(&sica->registered_listeners); } static void destroy_ca(struct SoundIoPrivate *si) { - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; AudioObjectPropertyAddress prop_address = { kAudioHardwarePropertyDevices, @@ -147,11 +149,11 @@ static void destroy_ca(struct SoundIoPrivate *si) { AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &prop_address, on_service_restarted, si); unsubscribe_device_listeners(si); - sica->registered_listeners.deinit(); + SoundIoListAudioDeviceID_deinit(&sica->registered_listeners); if (sica->thread) { - sica->abort_flag.clear(); - soundio_os_cond_signal(sica->scan_devices_cond, nullptr); + atomic_flag_clear(&sica->abort_flag); + soundio_os_cond_signal(sica->scan_devices_cond, NULL); soundio_os_thread_destroy(sica->thread); } @@ -178,7 +180,7 @@ static int from_cf_string(CFStringRef string_ref, char **out_str, int *out_str_l CFIndex length = CFStringGetLength(string_ref); CFIndex max_size = CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8); - char *buf = allocate_nonzero(max_size); + char *buf = ALLOCATE_NONZERO(char, max_size); if (!buf) return SoundIoErrorNoMem; @@ -192,12 +194,12 @@ static int from_cf_string(CFStringRef string_ref, char **out_str, int *out_str_l return 0; } -static int aim_to_scope(SoundIoDeviceAim aim) { +static int aim_to_scope(enum SoundIoDeviceAim aim) { return (aim == SoundIoDeviceAimInput) ? kAudioObjectPropertyScopeInput : kAudioObjectPropertyScopeOutput; } -static SoundIoChannelId from_channel_descr(const AudioChannelDescription *descr) { +static enum SoundIoChannelId from_channel_descr(const AudioChannelDescription *descr) { switch (descr->mChannelLabel) { default: return SoundIoChannelIdInvalid; case kAudioChannelLabel_Left: return SoundIoChannelIdFrontLeft; @@ -274,7 +276,7 @@ static SoundIoChannelId from_channel_descr(const AudioChannelDescription *descr) // * SoundIoErrorIncompatibleDevice // This does not handle all the possible layout enum values and it does not // handle channel bitmaps. -static int from_coreaudio_layout(const AudioChannelLayout *ca_layout, SoundIoChannelLayout *layout) { +static int from_coreaudio_layout(const AudioChannelLayout *ca_layout, struct SoundIoChannelLayout *layout) { switch (ca_layout->mChannelLayoutTag) { case kAudioChannelLayoutTag_UseChannelDescriptions: { @@ -377,15 +379,15 @@ static bool all_channels_invalid(const struct SoundIoChannelLayout *layout) { } struct RefreshDevices { - SoundIoPrivate *si; - SoundIoDevicesInfo *devices_info; + struct SoundIoPrivate *si; + struct SoundIoDevicesInfo *devices_info; int devices_size; AudioObjectID *devices; CFStringRef string_ref; char *device_name; int device_name_len; AudioBufferList *buffer_list; - SoundIoDevice *device; + struct SoundIoDevice *device; AudioChannelLayout *audio_channel_layout; char *device_uid; int device_uid_len; @@ -393,7 +395,7 @@ struct RefreshDevices { bool ok; }; -static void deinit_refresh_devices(RefreshDevices *rd) { +static void deinit_refresh_devices(struct RefreshDevices *rd) { if (!rd->ok) unsubscribe_device_listeners(rd->si); soundio_destroy_devices_info(rd->devices_info); @@ -409,8 +411,8 @@ static void deinit_refresh_devices(RefreshDevices *rd) { } static int refresh_devices(struct SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + struct SoundIo *soundio = &si->pub; + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; UInt32 io_size; OSStatus os_err; @@ -418,10 +420,10 @@ static int refresh_devices(struct SoundIoPrivate *si) { unsubscribe_device_listeners(si); - RefreshDevices rd = {0}; + struct RefreshDevices rd = {0}; rd.si = si; - if (!(rd.devices_info = allocate(1))) { + if (!(rd.devices_info = ALLOCATE(struct SoundIoDevicesInfo, 1))) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } @@ -433,7 +435,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { }; if ((os_err = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, - &prop_address, 0, nullptr, &io_size))) + &prop_address, 0, NULL, &io_size))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; @@ -445,13 +447,13 @@ static int refresh_devices(struct SoundIoPrivate *si) { int device_count = io_size / (UInt32)sizeof(AudioObjectID); if (device_count >= 1) { rd.devices_size = io_size; - rd.devices = (AudioObjectID *)allocate(rd.devices_size); + rd.devices = (AudioObjectID *)ALLOCATE(char, rd.devices_size); if (!rd.devices) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } - if ((os_err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop_address, 0, NULL, &io_size, rd.devices))) { deinit_refresh_devices(&rd); @@ -462,7 +464,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { io_size = sizeof(AudioObjectID); prop_address.mSelector = kAudioHardwarePropertyDefaultInputDevice; if ((os_err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop_address, - 0, nullptr, &io_size, &default_input_id))) + 0, NULL, &io_size, &default_input_id))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; @@ -471,7 +473,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { io_size = sizeof(AudioObjectID); prop_address.mSelector = kAudioHardwarePropertyDefaultOutputDevice; if ((os_err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &prop_address, - 0, nullptr, &io_size, &default_output_id))) + 0, NULL, &io_size, &default_output_id))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; @@ -481,8 +483,8 @@ static int refresh_devices(struct SoundIoPrivate *si) { for (int device_i = 0; device_i < device_count; device_i += 1) { AudioObjectID device_id = rd.devices[device_i]; - for (int i = 0; i < array_length(device_listen_props); i += 1) { - if ((err = sica->registered_listeners.add_one())) { + for (int i = 0; i < ARRAY_LENGTH(device_listen_props); i += 1) { + if ((err = SoundIoListAudioDeviceID_add_one(&sica->registered_listeners))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } @@ -492,7 +494,8 @@ static int refresh_devices(struct SoundIoPrivate *si) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } - sica->registered_listeners.last() = device_id; + AudioDeviceID *last_device_id = SoundIoListAudioDeviceID_last_ptr(&sica->registered_listeners); + *last_device_id = device_id; } prop_address.mSelector = kAudioObjectPropertyName; @@ -501,17 +504,17 @@ static int refresh_devices(struct SoundIoPrivate *si) { io_size = sizeof(CFStringRef); if (rd.string_ref) { CFRelease(rd.string_ref); - rd.string_ref = nullptr; + rd.string_ref = NULL; } if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, - 0, nullptr, &io_size, &rd.string_ref))) + 0, NULL, &io_size, &rd.string_ref))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } free(rd.device_name); - rd.device_name = nullptr; + rd.device_name = NULL; if ((err = from_cf_string(rd.string_ref, &rd.device_name, &rd.device_name_len))) { deinit_refresh_devices(&rd); return err; @@ -523,43 +526,43 @@ static int refresh_devices(struct SoundIoPrivate *si) { io_size = sizeof(CFStringRef); if (rd.string_ref) { CFRelease(rd.string_ref); - rd.string_ref = nullptr; + rd.string_ref = NULL; } if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, - 0, nullptr, &io_size, &rd.string_ref))) + 0, NULL, &io_size, &rd.string_ref))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } free(rd.device_uid); - rd.device_uid = nullptr; + rd.device_uid = NULL; if ((err = from_cf_string(rd.string_ref, &rd.device_uid, &rd.device_uid_len))) { deinit_refresh_devices(&rd); return err; } - for (int aim_i = 0; aim_i < array_length(aims); aim_i += 1) { - SoundIoDeviceAim aim = aims[aim_i]; + for (int aim_i = 0; aim_i < ARRAY_LENGTH(aims); aim_i += 1) { + enum SoundIoDeviceAim aim = aims[aim_i]; io_size = 0; prop_address.mSelector = kAudioDevicePropertyStreamConfiguration; prop_address.mScope = aim_to_scope(aim); prop_address.mElement = kAudioObjectPropertyElementMaster; - if ((os_err = AudioObjectGetPropertyDataSize(device_id, &prop_address, 0, nullptr, &io_size))) { + if ((os_err = AudioObjectGetPropertyDataSize(device_id, &prop_address, 0, NULL, &io_size))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } free(rd.buffer_list); - rd.buffer_list = (AudioBufferList*)allocate_nonzero(io_size); + rd.buffer_list = (AudioBufferList*)ALLOCATE_NONZERO(char, io_size); if (!rd.buffer_list) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } - if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, &io_size, rd.buffer_list))) { deinit_refresh_devices(&rd); @@ -574,12 +577,12 @@ static int refresh_devices(struct SoundIoPrivate *si) { if (channel_count <= 0) continue; - SoundIoDevicePrivate *dev = allocate(1); + struct SoundIoDevicePrivate *dev = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } - SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; + struct SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; dca->device_id = device_id; assert(!rd.device); rd.device = &dev->pub; @@ -599,14 +602,14 @@ static int refresh_devices(struct SoundIoPrivate *si) { prop_address.mScope = aim_to_scope(aim); prop_address.mElement = kAudioObjectPropertyElementMaster; if (!(os_err = AudioObjectGetPropertyDataSize(device_id, &prop_address, - 0, nullptr, &io_size))) + 0, NULL, &io_size))) { - rd.audio_channel_layout = (AudioChannelLayout *)allocate(io_size); + rd.audio_channel_layout = (AudioChannelLayout *)ALLOCATE(char, io_size); if (!rd.audio_channel_layout) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } - if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, &io_size, rd.audio_channel_layout))) { deinit_refresh_devices(&rd); @@ -635,7 +638,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { prop_address.mElement = kAudioObjectPropertyElementMaster; io_size = sizeof(double); double value; - if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, &io_size, &value))) { deinit_refresh_devices(&rd); @@ -659,21 +662,21 @@ static int refresh_devices(struct SoundIoPrivate *si) { prop_address.mSelector = kAudioDevicePropertyAvailableNominalSampleRates; prop_address.mScope = aim_to_scope(aim); prop_address.mElement = kAudioObjectPropertyElementMaster; - if ((os_err = AudioObjectGetPropertyDataSize(device_id, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyDataSize(device_id, &prop_address, 0, NULL, &io_size))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } int avr_array_len = io_size / sizeof(AudioValueRange); - rd.avr_array = (AudioValueRange*)allocate(io_size); + rd.avr_array = (AudioValueRange*)ALLOCATE(char, io_size); if (!rd.avr_array) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } - if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, &io_size, rd.avr_array))) { deinit_refresh_devices(&rd); @@ -687,7 +690,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { rd.device->sample_rates[0].max = (int)(rd.avr_array[0].mMaximum); } else { rd.device->sample_rate_count = avr_array_len; - rd.device->sample_rates = allocate(avr_array_len); + rd.device->sample_rates = ALLOCATE(struct SoundIoSampleRateRange, avr_array_len); if (!rd.device->sample_rates) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; @@ -707,7 +710,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { prop_address.mElement = kAudioObjectPropertyElementMaster; io_size = sizeof(UInt32); UInt32 buffer_frame_size; - if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, &io_size, &buffer_frame_size))) { deinit_refresh_devices(&rd); @@ -721,7 +724,7 @@ static int refresh_devices(struct SoundIoPrivate *si) { prop_address.mElement = kAudioObjectPropertyElementMaster; io_size = sizeof(AudioValueRange); AudioValueRange avr; - if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, &io_size, &avr))) { deinit_refresh_devices(&rd); @@ -734,14 +737,14 @@ static int refresh_devices(struct SoundIoPrivate *si) { prop_address.mScope = aim_to_scope(aim); prop_address.mElement = kAudioObjectPropertyElementMaster; io_size = sizeof(UInt32); - if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, nullptr, + if ((os_err = AudioObjectGetPropertyData(device_id, &prop_address, 0, NULL, &io_size, &dca->latency_frames))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } - SoundIoList *device_list; + struct SoundIoListDevicePtr *device_list; if (rd.device->aim == SoundIoDeviceAimOutput) { device_list = &rd.devices_info->output_devices; if (device_id == default_output_id) @@ -753,11 +756,11 @@ static int refresh_devices(struct SoundIoPrivate *si) { rd.devices_info->default_input_index = device_list->length; } - if ((err = device_list->append(rd.device))) { + if ((err = SoundIoListDevicePtr_append(device_list, rd.device))) { deinit_refresh_devices(&rd); return err; } - rd.device = nullptr; + rd.device = NULL; } } @@ -766,36 +769,36 @@ static int refresh_devices(struct SoundIoPrivate *si) { sica->ready_devices_info = rd.devices_info; soundio_os_mutex_unlock(sica->mutex); - rd.devices_info = nullptr; + rd.devices_info = NULL; rd.ok = true; deinit_refresh_devices(&rd); return 0; } -static void shutdown_backend(SoundIoPrivate *si, int err) { - SoundIo *soundio = &si->pub; - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; +static void shutdown_backend(struct SoundIoPrivate *si, int err) { + struct SoundIo *soundio = &si->pub; + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; soundio_os_mutex_lock(sica->mutex); sica->shutdown_err = err; - sica->have_devices_flag.store(true); + SOUNDIO_ATOMIC_STORE(sica->have_devices_flag, true); soundio_os_mutex_unlock(sica->mutex); - soundio_os_cond_signal(sica->cond, nullptr); - soundio_os_cond_signal(sica->have_devices_cond, nullptr); + soundio_os_cond_signal(sica->cond, NULL); + soundio_os_cond_signal(sica->have_devices_cond, NULL); soundio->on_events_signal(soundio); } static void flush_events_ca(struct SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + struct SoundIo *soundio = &si->pub; + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; // block until have devices - while (!sica->have_devices_flag.load()) - soundio_os_cond_wait(sica->have_devices_cond, nullptr); + while (!SOUNDIO_ATOMIC_LOAD(sica->have_devices_flag)) + soundio_os_cond_wait(sica->have_devices_cond, NULL); bool change = false; bool cb_shutdown = false; - SoundIoDevicesInfo *old_devices_info = nullptr; + struct SoundIoDevicesInfo *old_devices_info = NULL; soundio_os_mutex_lock(sica->mutex); @@ -805,7 +808,7 @@ static void flush_events_ca(struct SoundIoPrivate *si) { } else if (sica->ready_devices_info) { old_devices_info = si->safe_devices_info; si->safe_devices_info = sica->ready_devices_info; - sica->ready_devices_info = nullptr; + sica->ready_devices_info = NULL; change = true; } @@ -820,65 +823,65 @@ static void flush_events_ca(struct SoundIoPrivate *si) { } static void wait_events_ca(struct SoundIoPrivate *si) { - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; flush_events_ca(si); - soundio_os_cond_wait(sica->cond, nullptr); + soundio_os_cond_wait(sica->cond, NULL); } static void wakeup_ca(struct SoundIoPrivate *si) { - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; - soundio_os_cond_signal(sica->cond, nullptr); + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + soundio_os_cond_signal(sica->cond, NULL); } static void force_device_scan_ca(struct SoundIoPrivate *si) { - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; - sica->device_scan_queued.store(true); - soundio_os_cond_signal(sica->scan_devices_cond, nullptr); + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + SOUNDIO_ATOMIC_STORE(sica->device_scan_queued, true); + soundio_os_cond_signal(sica->scan_devices_cond, NULL); } static void device_thread_run(void *arg) { - SoundIoPrivate *si = (SoundIoPrivate *)arg; - SoundIo *soundio = &si->pub; - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)arg; + struct SoundIo *soundio = &si->pub; + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; int err; for (;;) { - if (!sica->abort_flag.test_and_set()) + if (!atomic_flag_test_and_set(&sica->abort_flag)) break; - if (sica->service_restarted.load()) { + if (SOUNDIO_ATOMIC_LOAD(sica->service_restarted)) { shutdown_backend(si, SoundIoErrorBackendDisconnected); return; } - if (sica->device_scan_queued.exchange(false)) { + if (SOUNDIO_ATOMIC_EXCHANGE(sica->device_scan_queued, false)) { err = refresh_devices(si); if (err) { shutdown_backend(si, err); return; } - if (!sica->have_devices_flag.exchange(true)) - soundio_os_cond_signal(sica->have_devices_cond, nullptr); - soundio_os_cond_signal(sica->cond, nullptr); + if (!SOUNDIO_ATOMIC_EXCHANGE(sica->have_devices_flag, true)) + soundio_os_cond_signal(sica->have_devices_cond, NULL); + soundio_os_cond_signal(sica->cond, NULL); soundio->on_events_signal(soundio); } - soundio_os_cond_wait(sica->scan_devices_cond, nullptr); + soundio_os_cond_wait(sica->scan_devices_cond, NULL); } } static OSStatus on_outstream_device_overload(AudioObjectID in_object_id, UInt32 in_number_addresses, const AudioObjectPropertyAddress in_addresses[], void *in_client_data) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)in_client_data; - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)in_client_data; + struct SoundIoOutStream *outstream = &os->pub; outstream->underflow_callback(outstream); return noErr; } static void outstream_destroy_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; - SoundIoOutStream *outstream = &os->pub; - SoundIoDevice *device = outstream->device; - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; + struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoDevice *device = outstream->device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; AudioObjectPropertyAddress prop_address = { kAudioDeviceProcessorOverload, @@ -890,7 +893,7 @@ static void outstream_destroy_ca(struct SoundIoPrivate *si, struct SoundIoOutStr if (osca->instance) { AudioOutputUnitStop(osca->instance); AudioComponentInstanceDispose(osca->instance); - osca->instance = nullptr; + osca->instance = NULL; } } @@ -898,30 +901,30 @@ static OSStatus write_callback_ca(void *userdata, AudioUnitRenderActionFlags *io const AudioTimeStamp *in_time_stamp, UInt32 in_bus_number, UInt32 in_number_frames, AudioBufferList *io_data) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *) userdata; - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *) userdata; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; osca->io_data = io_data; osca->buffer_index = 0; osca->frames_left = in_number_frames; outstream->write_callback(outstream, osca->frames_left, osca->frames_left); - osca->io_data = nullptr; + osca->io_data = NULL; return noErr; } static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; - SoundIoOutStream *outstream = &os->pub; - SoundIoDevice *device = outstream->device; - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; + struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoDevice *device = outstream->device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; if (outstream->software_latency == 0.0) outstream->software_latency = device->software_latency_current; - outstream->software_latency = clamp( + outstream->software_latency = soundio_double_clamp( device->software_latency_min, outstream->software_latency, device->software_latency_max); @@ -931,7 +934,7 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP desc.componentSubType = kAudioUnitSubType_HALOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; - AudioComponent component = AudioComponentFindNext(nullptr, &desc); + AudioComponent component = AudioComponentFindNext(NULL, &desc); if (!component) { outstream_destroy_ca(si, os); return SoundIoErrorOpeningDevice; @@ -987,7 +990,7 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP }; UInt32 buffer_frame_size = outstream->software_latency * outstream->sample_rate; if ((os_err = AudioObjectSetPropertyData(dca->device_id, &prop_address, - 0, nullptr, sizeof(UInt32), &buffer_frame_size))) + 0, NULL, sizeof(UInt32), &buffer_frame_size))) { outstream_destroy_ca(si, os); return SoundIoErrorOpeningDevice; @@ -1009,7 +1012,7 @@ static int outstream_open_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamP } static int outstream_pause_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) { - SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; + struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; OSStatus os_err; if (pause) { if ((os_err = AudioOutputUnitStop(osca->instance))) { @@ -1029,10 +1032,10 @@ static int outstream_start_ca(struct SoundIoPrivate *si, struct SoundIoOutStream } static int outstream_begin_write_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, - SoundIoChannelArea **out_areas, int *frame_count) + struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; if (osca->buffer_index >= osca->io_data->mNumberBuffers) return SoundIoErrorInvalid; @@ -1054,7 +1057,7 @@ static int outstream_begin_write_ca(struct SoundIoPrivate *si, struct SoundIoOut } static int outstream_end_write_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; + struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; osca->buffer_index += 1; osca->frames_left -= osca->write_frame_count; assert(osca->frames_left >= 0); @@ -1068,7 +1071,7 @@ static int outstream_clear_buffer_ca(struct SoundIoPrivate *si, struct SoundIoOu static int outstream_get_latency_ca(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, double *out_latency) { - SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; + struct SoundIoOutStreamCoreAudio *osca = &os->backend_data.coreaudio; *out_latency = osca->hardware_latency; return 0; } @@ -1076,18 +1079,18 @@ static int outstream_get_latency_ca(struct SoundIoPrivate *si, struct SoundIoOut static OSStatus on_instream_device_overload(AudioObjectID in_object_id, UInt32 in_number_addresses, const AudioObjectPropertyAddress in_addresses[], void *in_client_data) { - SoundIoInStreamPrivate *os = (SoundIoInStreamPrivate *)in_client_data; - SoundIoInStream *instream = &os->pub; + struct SoundIoInStreamPrivate *os = (struct SoundIoInStreamPrivate *)in_client_data; + struct SoundIoInStream *instream = &os->pub; instream->overflow_callback(instream); return noErr; } static void instream_destroy_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; - SoundIoInStream *instream = &is->pub; - SoundIoDevice *device = instream->device; - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; + struct SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoDevice *device = instream->device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; AudioObjectPropertyAddress prop_address = { kAudioDeviceProcessorOverload, @@ -1099,23 +1102,23 @@ static void instream_destroy_ca(struct SoundIoPrivate *si, struct SoundIoInStrea if (isca->instance) { AudioOutputUnitStop(isca->instance); AudioComponentInstanceDispose(isca->instance); - isca->instance = nullptr; + isca->instance = NULL; } free(isca->buffer_list); - isca->buffer_list = nullptr; + isca->buffer_list = NULL; } static OSStatus read_callback_ca(void *userdata, AudioUnitRenderActionFlags *io_action_flags, const AudioTimeStamp *in_time_stamp, UInt32 in_bus_number, UInt32 in_number_frames, AudioBufferList *io_data) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *) userdata; - SoundIoInStream *instream = &is->pub; - SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *) userdata; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; for (int i = 0; i < isca->buffer_list->mNumberBuffers; i += 1) { - isca->buffer_list->mBuffers[i].mData = nullptr; + isca->buffer_list->mBuffers[i].mData = NULL; } OSStatus os_err; @@ -1151,18 +1154,18 @@ static OSStatus read_callback_ca(void *userdata, AudioUnitRenderActionFlags *io_ } static int instream_open_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; - SoundIoInStream *instream = &is->pub; - SoundIoDevice *device = instream->device; - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; + struct SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoDevice *device = instream->device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceCoreAudio *dca = &dev->backend_data.coreaudio; UInt32 io_size; OSStatus os_err; if (instream->software_latency == 0.0) instream->software_latency = device->software_latency_current; - instream->software_latency = clamp( + instream->software_latency = soundio_double_clamp( device->software_latency_min, instream->software_latency, device->software_latency_max); @@ -1174,20 +1177,20 @@ static int instream_open_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPri prop_address.mElement = kAudioObjectPropertyElementMaster; io_size = 0; if ((os_err = AudioObjectGetPropertyDataSize(dca->device_id, &prop_address, - 0, nullptr, &io_size))) + 0, NULL, &io_size))) { instream_destroy_ca(si, is); return SoundIoErrorOpeningDevice; } - isca->buffer_list = (AudioBufferList*)allocate_nonzero(io_size); + isca->buffer_list = (AudioBufferList*)ALLOCATE_NONZERO(char, io_size); if (!isca->buffer_list) { instream_destroy_ca(si, is); return SoundIoErrorNoMem; } if ((os_err = AudioObjectGetPropertyData(dca->device_id, &prop_address, - 0, nullptr, &io_size, isca->buffer_list))) + 0, NULL, &io_size, isca->buffer_list))) { instream_destroy_ca(si, is); return SoundIoErrorOpeningDevice; @@ -1199,7 +1202,7 @@ static int instream_open_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPri desc.componentSubType = kAudioUnitSubType_HALOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; - AudioComponent component = AudioComponentFindNext(nullptr, &desc); + AudioComponent component = AudioComponentFindNext(NULL, &desc); if (!component) { instream_destroy_ca(si, is); return SoundIoErrorOpeningDevice; @@ -1270,7 +1273,7 @@ static int instream_open_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPri prop_address.mElement = INPUT_ELEMENT; UInt32 buffer_frame_size = instream->software_latency * instream->sample_rate; if ((os_err = AudioObjectSetPropertyData(dca->device_id, &prop_address, - 0, nullptr, sizeof(UInt32), &buffer_frame_size))) + 0, NULL, sizeof(UInt32), &buffer_frame_size))) { instream_destroy_ca(si, is); return SoundIoErrorOpeningDevice; @@ -1291,7 +1294,7 @@ static int instream_open_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPri } static int instream_pause_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) { - SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; + struct SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; OSStatus os_err; if (pause) { if ((os_err = AudioOutputUnitStop(isca->instance))) { @@ -1311,9 +1314,9 @@ static int instream_start_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPr } static int instream_begin_read_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, - SoundIoChannelArea **out_areas, int *frame_count) + struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; + struct SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; if (*frame_count != isca->frames_left) return SoundIoErrorInvalid; @@ -1324,7 +1327,7 @@ static int instream_begin_read_ca(struct SoundIoPrivate *si, struct SoundIoInStr } static int instream_end_read_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; + struct SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; isca->frames_left = 0; return 0; } @@ -1332,20 +1335,20 @@ static int instream_end_read_ca(struct SoundIoPrivate *si, struct SoundIoInStrea static int instream_get_latency_ca(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, double *out_latency) { - SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; + struct SoundIoInStreamCoreAudio *isca = &is->backend_data.coreaudio; *out_latency = isca->hardware_latency; return 0; } -int soundio_coreaudio_init(SoundIoPrivate *si) { - SoundIoCoreAudio *sica = &si->backend_data.coreaudio; +int soundio_coreaudio_init(struct SoundIoPrivate *si) { + struct SoundIoCoreAudio *sica = &si->backend_data.coreaudio; int err; - sica->have_devices_flag.store(false); - sica->device_scan_queued.store(true); - sica->service_restarted.store(false); - sica->abort_flag.test_and_set(); + SOUNDIO_ATOMIC_STORE(sica->have_devices_flag, false); + SOUNDIO_ATOMIC_STORE(sica->device_scan_queued, true); + SOUNDIO_ATOMIC_STORE(sica->service_restarted, false); + atomic_flag_test_and_set(&sica->abort_flag); sica->mutex = soundio_os_mutex_create(); if (!sica->mutex) { @@ -1391,7 +1394,7 @@ int soundio_coreaudio_init(SoundIoPrivate *si) { return SoundIoErrorSystemResources; } - if ((err = soundio_os_thread_create(device_thread_run, si, nullptr, &sica->thread))) { + if ((err = soundio_os_thread_create(device_thread_run, si, NULL, &sica->thread))) { destroy_ca(si); return err; } diff --git a/src/coreaudio.hpp b/src/coreaudio.h similarity index 58% rename from src/coreaudio.hpp rename to src/coreaudio.h index fb4e61a..a919f0e 100644 --- a/src/coreaudio.hpp +++ b/src/coreaudio.h @@ -5,17 +5,18 @@ * See http://opensource.org/licenses/MIT */ -#ifndef SOUNDIO_COREAUDIO_HPP -#define SOUNDIO_COREAUDIO_HPP +#ifndef SOUNDIO_COREAUDIO_H +#define SOUNDIO_COREAUDIO_H -#include "soundio_private.h" +#include "soundio_internal.h" #include "os.h" -#include "atomics.hpp" -#include "list.hpp" +#include "list.h" +#include "atomics.h" #include #include +struct SoundIoPrivate; int soundio_coreaudio_init(struct SoundIoPrivate *si); struct SoundIoDeviceCoreAudio { @@ -23,21 +24,23 @@ struct SoundIoDeviceCoreAudio { UInt32 latency_frames; }; +SOUNDIO_MAKE_LIST_STRUCT(AudioDeviceID, SoundIoListAudioDeviceID, SOUNDIO_LIST_STATIC) + struct SoundIoCoreAudio { - SoundIoOsMutex *mutex; - SoundIoOsCond *cond; + struct SoundIoOsMutex *mutex; + struct SoundIoOsCond *cond; struct SoundIoOsThread *thread; atomic_flag abort_flag; // this one is ready to be read with flush_events. protected by mutex struct SoundIoDevicesInfo *ready_devices_info; - atomic_bool have_devices_flag; - SoundIoOsCond *have_devices_cond; - SoundIoOsCond *scan_devices_cond; - SoundIoList registered_listeners; + struct SoundIoAtomicBool have_devices_flag; + struct SoundIoOsCond *have_devices_cond; + struct SoundIoOsCond *scan_devices_cond; + struct SoundIoListAudioDeviceID registered_listeners; - atomic_bool device_scan_queued; - atomic_bool service_restarted; + struct SoundIoAtomicBool device_scan_queued; + struct SoundIoAtomicBool service_restarted; int shutdown_err; bool emitted_shutdown_cb; }; @@ -49,7 +52,7 @@ struct SoundIoOutStreamCoreAudio { int frames_left; int write_frame_count; double hardware_latency; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; struct SoundIoInStreamCoreAudio { @@ -57,7 +60,7 @@ struct SoundIoInStreamCoreAudio { AudioBufferList *buffer_list; int frames_left; double hardware_latency; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; #endif diff --git a/src/dummy.cpp b/src/dummy.c similarity index 66% rename from src/dummy.cpp rename to src/dummy.c index 8090aeb..3ae5d78 100644 --- a/src/dummy.cpp +++ b/src/dummy.c @@ -5,16 +5,16 @@ * See http://opensource.org/licenses/MIT */ -#include "dummy.hpp" -#include "soundio.hpp" +#include "dummy.h" +#include "soundio_private.h" #include #include static void playback_thread_run(void *arg) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg; - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)arg; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; int fill_bytes = soundio_ring_buffer_fill_count(&osd->ring_buffer); int free_bytes = soundio_ring_buffer_capacity(&osd->ring_buffer) - fill_bytes; @@ -25,14 +25,14 @@ static void playback_thread_run(void *arg) { double start_time = soundio_os_get_time(); long frames_consumed = 0; - while (osd->abort_flag.test_and_set()) { + while (atomic_flag_test_and_set(&osd->abort_flag)) { double now = soundio_os_get_time(); double time_passed = now - start_time; double next_period = start_time + ceil_dbl(time_passed / osd->period_duration) * osd->period_duration; double relative_time = next_period - now; - soundio_os_cond_timed_wait(osd->cond, nullptr, relative_time); - if (!osd->clear_buffer_flag.test_and_set()) { + soundio_os_cond_timed_wait(osd->cond, NULL, relative_time); + if (!atomic_flag_test_and_set(&osd->clear_buffer_flag)) { soundio_ring_buffer_clear(&osd->ring_buffer); int free_bytes = soundio_ring_buffer_capacity(&osd->ring_buffer); int free_frames = free_bytes / outstream->bytes_per_frame; @@ -44,7 +44,7 @@ static void playback_thread_run(void *arg) { continue; } - if (osd->pause_requested.load()) { + if (SOUNDIO_ATOMIC_LOAD(osd->pause_requested)) { start_time = now; frames_consumed = 0; continue; @@ -58,7 +58,7 @@ static void playback_thread_run(void *arg) { double total_time = soundio_os_get_time() - start_time; long total_frames = total_time * outstream->sample_rate; int frames_to_kill = total_frames - frames_consumed; - int read_count = min(frames_to_kill, fill_frames); + int read_count = soundio_int_min(frames_to_kill, fill_frames); int byte_count = read_count * outstream->bytes_per_frame; soundio_ring_buffer_advance_read_ptr(&osd->ring_buffer, byte_count); frames_consumed += read_count; @@ -78,21 +78,21 @@ static void playback_thread_run(void *arg) { } static void capture_thread_run(void *arg) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)arg; - SoundIoInStream *instream = &is->pub; - SoundIoInStreamDummy *isd = &is->backend_data.dummy; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)arg; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamDummy *isd = &is->backend_data.dummy; long frames_consumed = 0; double start_time = soundio_os_get_time(); - while (isd->abort_flag.test_and_set()) { + while (atomic_flag_test_and_set(&isd->abort_flag)) { double now = soundio_os_get_time(); double time_passed = now - start_time; double next_period = start_time + ceil_dbl(time_passed / isd->period_duration) * isd->period_duration; double relative_time = next_period - now; - soundio_os_cond_timed_wait(isd->cond, nullptr, relative_time); + soundio_os_cond_timed_wait(isd->cond, NULL, relative_time); - if (isd->pause_requested.load()) { + if (SOUNDIO_ATOMIC_LOAD(isd->pause_requested)) { start_time = now; frames_consumed = 0; continue; @@ -106,7 +106,7 @@ static void capture_thread_run(void *arg) { double total_time = soundio_os_get_time() - start_time; long total_frames = total_time * instream->sample_rate; int frames_to_kill = total_frames - frames_consumed; - int write_count = min(frames_to_kill, free_frames); + int write_count = soundio_int_min(frames_to_kill, free_frames); int byte_count = write_count * instream->bytes_per_frame; soundio_ring_buffer_advance_write_ptr(&isd->ring_buffer, byte_count); frames_consumed += write_count; @@ -123,8 +123,8 @@ static void capture_thread_run(void *arg) { } } -static void destroy_dummy(SoundIoPrivate *si) { - SoundIoDummy *sid = &si->backend_data.dummy; +static void destroy_dummy(struct SoundIoPrivate *si) { + struct SoundIoDummy *sid = &si->backend_data.dummy; if (sid->cond) soundio_os_cond_destroy(sid->cond); @@ -133,55 +133,57 @@ static void destroy_dummy(SoundIoPrivate *si) { soundio_os_mutex_destroy(sid->mutex); } -static void flush_events_dummy(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoDummy *sid = &si->backend_data.dummy; +static void flush_events_dummy(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoDummy *sid = &si->backend_data.dummy; if (sid->devices_emitted) return; sid->devices_emitted = true; soundio->on_devices_change(soundio); } -static void wait_events_dummy(SoundIoPrivate *si) { - SoundIoDummy *sid = &si->backend_data.dummy; +static void wait_events_dummy(struct SoundIoPrivate *si) { + struct SoundIoDummy *sid = &si->backend_data.dummy; flush_events_dummy(si); - soundio_os_cond_wait(sid->cond, nullptr); + soundio_os_cond_wait(sid->cond, NULL); } -static void wakeup_dummy(SoundIoPrivate *si) { - SoundIoDummy *sid = &si->backend_data.dummy; - soundio_os_cond_signal(sid->cond, nullptr); +static void wakeup_dummy(struct SoundIoPrivate *si) { + struct SoundIoDummy *sid = &si->backend_data.dummy; + soundio_os_cond_signal(sid->cond, NULL); } -static void force_device_scan_dummy(SoundIoPrivate *si) { +static void force_device_scan_dummy(struct SoundIoPrivate *si) { // nothing to do; dummy devices never change } -static void outstream_destroy_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; +static void outstream_destroy_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; if (osd->thread) { - osd->abort_flag.clear(); - soundio_os_cond_signal(osd->cond, nullptr); + atomic_flag_clear(&osd->abort_flag); + soundio_os_cond_signal(osd->cond, NULL); soundio_os_thread_destroy(osd->thread); - osd->thread = nullptr; + osd->thread = NULL; } soundio_os_cond_destroy(osd->cond); - osd->cond = nullptr; + osd->cond = NULL; soundio_ring_buffer_deinit(&osd->ring_buffer); } -static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; - SoundIoOutStream *outstream = &os->pub; - SoundIoDevice *device = outstream->device; +static int outstream_open_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoDevice *device = outstream->device; - osd->clear_buffer_flag.test_and_set(); - osd->pause_requested.store(false); + atomic_flag_test_and_set(&osd->clear_buffer_flag); + SOUNDIO_ATOMIC_STORE(osd->pause_requested, false); - if (outstream->software_latency == 0.0) - outstream->software_latency = clamp(device->software_latency_min, 1.0, device->software_latency_max); + if (outstream->software_latency == 0.0) { + outstream->software_latency = soundio_double_clamp( + device->software_latency_min, 1.0, device->software_latency_max); + } osd->period_duration = outstream->software_latency / 2.0; @@ -205,16 +207,16 @@ static int outstream_open_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) } static int outstream_pause_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) { - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; - osd->pause_requested.store(pause); + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; + SOUNDIO_ATOMIC_STORE(osd->pause_requested, pause); return 0; } -static int outstream_start_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; - SoundIo *soundio = &si->pub; +static int outstream_start_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; + struct SoundIo *soundio = &si->pub; assert(!osd->thread); - osd->abort_flag.test_and_set(); + atomic_flag_test_and_set(&osd->abort_flag); int err; if ((err = soundio_os_thread_create(playback_thread_run, os, soundio->emit_rtprio_warning, &osd->thread))) @@ -224,11 +226,11 @@ static int outstream_start_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os return 0; } -static int outstream_begin_write_dummy(SoundIoPrivate *si, - SoundIoOutStreamPrivate *os, SoundIoChannelArea **out_areas, int *frame_count) +static int outstream_begin_write_dummy(struct SoundIoPrivate *si, + struct SoundIoOutStreamPrivate *os, struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; if (*frame_count > osd->frames_left) return SoundIoErrorInvalid; @@ -244,55 +246,57 @@ static int outstream_begin_write_dummy(SoundIoPrivate *si, return 0; } -static int outstream_end_write_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; - SoundIoOutStream *outstream = &os->pub; +static int outstream_end_write_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; + struct SoundIoOutStream *outstream = &os->pub; int byte_count = osd->write_frame_count * outstream->bytes_per_frame; soundio_ring_buffer_advance_write_ptr(&osd->ring_buffer, byte_count); osd->frames_left -= osd->write_frame_count; return 0; } -static int outstream_clear_buffer_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; - osd->clear_buffer_flag.clear(); - soundio_os_cond_signal(osd->cond, nullptr); +static int outstream_clear_buffer_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; + atomic_flag_clear(&osd->clear_buffer_flag); + soundio_os_cond_signal(osd->cond, NULL); return 0; } -static int outstream_get_latency_dummy(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, double *out_latency) { - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamDummy *osd = &os->backend_data.dummy; +static int outstream_get_latency_dummy(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, double *out_latency) { + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamDummy *osd = &os->backend_data.dummy; int fill_bytes = soundio_ring_buffer_fill_count(&osd->ring_buffer); *out_latency = (fill_bytes / outstream->bytes_per_frame) / (double)outstream->sample_rate; return 0; } -static void instream_destroy_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamDummy *isd = &is->backend_data.dummy; +static void instream_destroy_dummy(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamDummy *isd = &is->backend_data.dummy; if (isd->thread) { - isd->abort_flag.clear(); - soundio_os_cond_signal(isd->cond, nullptr); + atomic_flag_clear(&isd->abort_flag); + soundio_os_cond_signal(isd->cond, NULL); soundio_os_thread_destroy(isd->thread); - isd->thread = nullptr; + isd->thread = NULL; } soundio_os_cond_destroy(isd->cond); - isd->cond = nullptr; + isd->cond = NULL; soundio_ring_buffer_deinit(&isd->ring_buffer); } -static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamDummy *isd = &is->backend_data.dummy; - SoundIoInStream *instream = &is->pub; - SoundIoDevice *device = instream->device; +static int instream_open_dummy(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamDummy *isd = &is->backend_data.dummy; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoDevice *device = instream->device; - isd->pause_requested.store(false); + SOUNDIO_ATOMIC_STORE(isd->pause_requested, false); - if (instream->software_latency == 0.0) - instream->software_latency = clamp(device->software_latency_min, 1.0, device->software_latency_max); + if (instream->software_latency == 0.0) { + instream->software_latency = soundio_double_clamp( + device->software_latency_min, 1.0, device->software_latency_max); + } isd->period_duration = instream->software_latency; @@ -317,17 +321,17 @@ static int instream_open_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { return 0; } -static int instream_pause_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is, bool pause) { - SoundIoInStreamDummy *isd = &is->backend_data.dummy; - isd->pause_requested.store(pause); +static int instream_pause_dummy(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) { + struct SoundIoInStreamDummy *isd = &is->backend_data.dummy; + SOUNDIO_ATOMIC_STORE(isd->pause_requested, pause); return 0; } -static int instream_start_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamDummy *isd = &is->backend_data.dummy; - SoundIo *soundio = &si->pub; +static int instream_start_dummy(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamDummy *isd = &is->backend_data.dummy; + struct SoundIo *soundio = &si->pub; assert(!isd->thread); - isd->abort_flag.test_and_set(); + atomic_flag_test_and_set(&isd->abort_flag); int err; if ((err = soundio_os_thread_create(capture_thread_run, is, soundio->emit_rtprio_warning, &isd->thread))) @@ -337,11 +341,11 @@ static int instream_start_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) return 0; } -static int instream_begin_read_dummy(SoundIoPrivate *si, - SoundIoInStreamPrivate *is, SoundIoChannelArea **out_areas, int *frame_count) +static int instream_begin_read_dummy(struct SoundIoPrivate *si, + struct SoundIoInStreamPrivate *is, struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamDummy *isd = &is->backend_data.dummy; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamDummy *isd = &is->backend_data.dummy; assert(*frame_count <= isd->frames_left); @@ -357,27 +361,27 @@ static int instream_begin_read_dummy(SoundIoPrivate *si, return 0; } -static int instream_end_read_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamDummy *isd = &is->backend_data.dummy; - SoundIoInStream *instream = &is->pub; +static int instream_end_read_dummy(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamDummy *isd = &is->backend_data.dummy; + struct SoundIoInStream *instream = &is->pub; int byte_count = isd->read_frame_count * instream->bytes_per_frame; soundio_ring_buffer_advance_read_ptr(&isd->ring_buffer, byte_count); isd->frames_left -= isd->read_frame_count; return 0; } -static int instream_get_latency_dummy(SoundIoPrivate *si, SoundIoInStreamPrivate *is, double *out_latency) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamDummy *osd = &is->backend_data.dummy; +static int instream_get_latency_dummy(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, double *out_latency) { + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamDummy *osd = &is->backend_data.dummy; int fill_bytes = soundio_ring_buffer_fill_count(&osd->ring_buffer); *out_latency = (fill_bytes / instream->bytes_per_frame) / (double)instream->sample_rate; return 0; } -static int set_all_device_formats(SoundIoDevice *device) { +static int set_all_device_formats(struct SoundIoDevice *device) { device->format_count = 18; - device->formats = allocate(device->format_count); + device->formats = ALLOCATE(enum SoundIoFormat, device->format_count); if (!device->formats) return SoundIoErrorNoMem; @@ -403,17 +407,17 @@ static int set_all_device_formats(SoundIoDevice *device) { return 0; } -static void set_all_device_sample_rates(SoundIoDevice *device) { - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; +static void set_all_device_sample_rates(struct SoundIoDevice *device) { + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; device->sample_rate_count = 1; device->sample_rates = &dev->prealloc_sample_rate_range; device->sample_rates[0].min = SOUNDIO_MIN_SAMPLE_RATE; device->sample_rates[0].max = SOUNDIO_MAX_SAMPLE_RATE; } -static int set_all_device_channel_layouts(SoundIoDevice *device) { +static int set_all_device_channel_layouts(struct SoundIoDevice *device) { device->layout_count = soundio_channel_layout_builtin_count(); - device->layouts = allocate(device->layout_count); + device->layouts = ALLOCATE(struct SoundIoChannelLayout, device->layout_count); if (!device->layouts) return SoundIoErrorNoMem; for (int i = 0; i < device->layout_count; i += 1) @@ -421,9 +425,9 @@ static int set_all_device_channel_layouts(SoundIoDevice *device) { return 0; } -int soundio_dummy_init(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoDummy *sid = &si->backend_data.dummy; +int soundio_dummy_init(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoDummy *sid = &si->backend_data.dummy; sid->mutex = soundio_os_mutex_create(); if (!sid->mutex) { @@ -438,7 +442,7 @@ int soundio_dummy_init(SoundIoPrivate *si) { } assert(!si->safe_devices_info); - si->safe_devices_info = allocate(1); + si->safe_devices_info = ALLOCATE(struct SoundIoDevicesInfo, 1); if (!si->safe_devices_info) { destroy_dummy(si); return SoundIoErrorNoMem; @@ -449,12 +453,12 @@ int soundio_dummy_init(SoundIoPrivate *si) { // create output device { - SoundIoDevicePrivate *dev = allocate(1); + struct SoundIoDevicePrivate *dev = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev) { destroy_dummy(si); return SoundIoErrorNoMem; } - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; device->ref_count = 1; device->soundio = soundio; @@ -486,7 +490,7 @@ int soundio_dummy_init(SoundIoPrivate *si) { device->sample_rate_current = 48000; device->aim = SoundIoDeviceAimOutput; - if (si->safe_devices_info->output_devices.append(device)) { + if (SoundIoListDevicePtr_append(&si->safe_devices_info->output_devices, device)) { soundio_device_unref(device); destroy_dummy(si); return SoundIoErrorNoMem; @@ -495,12 +499,12 @@ int soundio_dummy_init(SoundIoPrivate *si) { // create input device { - SoundIoDevicePrivate *dev = allocate(1); + struct SoundIoDevicePrivate *dev = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev) { destroy_dummy(si); return SoundIoErrorNoMem; } - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; device->ref_count = 1; device->soundio = soundio; @@ -531,7 +535,7 @@ int soundio_dummy_init(SoundIoPrivate *si) { device->sample_rate_current = 48000; device->aim = SoundIoDeviceAimInput; - if (si->safe_devices_info->input_devices.append(device)) { + if (SoundIoListDevicePtr_append(&si->safe_devices_info->input_devices, device)) { soundio_device_unref(device); destroy_dummy(si); return SoundIoErrorNoMem; diff --git a/src/dummy.hpp b/src/dummy.h similarity index 64% rename from src/dummy.hpp rename to src/dummy.h index 26b79fd..6ea4761 100644 --- a/src/dummy.hpp +++ b/src/dummy.h @@ -5,23 +5,24 @@ * See http://opensource.org/licenses/MIT */ -#ifndef SOUNDIO_DUMMY_HPP -#define SOUNDIO_DUMMY_HPP +#ifndef SOUNDIO_DUMMY_H +#define SOUNDIO_DUMMY_H -#include "soundio_private.h" +#include "soundio_internal.h" #include "os.h" -#include "atomics.hpp" -#include "ring_buffer.hpp" +#include "ring_buffer.h" +#include "atomics.h" +struct SoundIoPrivate; int soundio_dummy_init(struct SoundIoPrivate *si); struct SoundIoDummy { - SoundIoOsMutex *mutex; - SoundIoOsCond *cond; + struct SoundIoOsMutex *mutex; + struct SoundIoOsCond *cond; bool devices_emitted; }; -struct SoundIoDeviceDummy { }; +struct SoundIoDeviceDummy { int make_the_struct_not_empty; }; struct SoundIoOutStreamDummy { struct SoundIoOsThread *thread; @@ -34,8 +35,8 @@ struct SoundIoOutStreamDummy { struct SoundIoRingBuffer ring_buffer; double playback_start_time; atomic_flag clear_buffer_flag; - atomic_bool pause_requested; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoAtomicBool pause_requested; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; struct SoundIoInStreamDummy { @@ -47,8 +48,8 @@ struct SoundIoInStreamDummy { int read_frame_count; int buffer_frame_count; struct SoundIoRingBuffer ring_buffer; - atomic_bool pause_requested; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoAtomicBool pause_requested; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; #endif diff --git a/src/jack.cpp b/src/jack.c similarity index 73% rename from src/jack.cpp rename to src/jack.c index 2ffd9b7..0d6882a 100644 --- a/src/jack.cpp +++ b/src/jack.c @@ -5,9 +5,9 @@ * See http://opensource.org/licenses/MIT */ -#include "jack.hpp" -#include "soundio.hpp" -#include "list.hpp" +#include "jack.h" +#include "soundio_private.h" +#include "list.h" #include @@ -18,7 +18,7 @@ struct SoundIoJackPort { int full_name_len; const char *name; int name_len; - SoundIoChannelId channel_id; + enum SoundIoChannelId channel_id; jack_latency_range_t latency_range; }; @@ -26,11 +26,14 @@ struct SoundIoJackClient { const char *name; int name_len; bool is_physical; - SoundIoDeviceAim aim; + enum SoundIoDeviceAim aim; int port_count; - SoundIoJackPort ports[SOUNDIO_MAX_CHANNELS]; + struct SoundIoJackPort ports[SOUNDIO_MAX_CHANNELS]; }; +SOUNDIO_MAKE_LIST_STRUCT(struct SoundIoJackClient, SoundIoListJackClient, SOUNDIO_LIST_STATIC) +SOUNDIO_MAKE_LIST_DEF(struct SoundIoJackClient, SoundIoListJackClient, SOUNDIO_LIST_STATIC) + static void split_str(const char *input_str, int input_str_len, char c, const char **out_1, int *out_len_1, const char **out_2, int *out_len_2) { @@ -46,11 +49,11 @@ static void split_str(const char *input_str, int input_str_len, char c, } } -static SoundIoJackClient *find_or_create_client(SoundIoList *clients, - SoundIoDeviceAim aim, bool is_physical, const char *client_name, int client_name_len) +static struct SoundIoJackClient *find_or_create_client(struct SoundIoListJackClient *clients, + enum SoundIoDeviceAim aim, bool is_physical, const char *client_name, int client_name_len) { for (int i = 0; i < clients->length; i += 1) { - SoundIoJackClient *client = &clients->at(i); + struct SoundIoJackClient *client = SoundIoListJackClient_ptr_at(clients, i); if (client->is_physical == is_physical && client->aim == aim && soundio_streql(client->name, client->name_len, client_name, client_name_len)) @@ -59,9 +62,9 @@ static SoundIoJackClient *find_or_create_client(SoundIoList * } } int err; - if ((err = clients->add_one())) - return nullptr; - SoundIoJackClient *client = &clients->last(); + if ((err = SoundIoListJackClient_add_one(clients))) + return NULL; + struct SoundIoJackClient *client = SoundIoListJackClient_last_ptr(clients); client->is_physical = is_physical; client->aim = aim; client->name = client_name; @@ -70,36 +73,36 @@ static SoundIoJackClient *find_or_create_client(SoundIoList * return client; } -static void destruct_device(SoundIoDevicePrivate *dp) { - SoundIoDeviceJack *dj = &dp->backend_data.jack; +static void destruct_device(struct SoundIoDevicePrivate *dp) { + struct SoundIoDeviceJack *dj = &dp->backend_data.jack; for (int i = 0; i < dj->port_count; i += 1) { - SoundIoDeviceJackPort *djp = &dj->ports[i]; + struct SoundIoDeviceJackPort *djp = &dj->ports[i]; free(djp->full_name); } free(dj->ports); } -static int refresh_devices_bare(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoJack *sij = &si->backend_data.jack; +static int refresh_devices_bare(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoJack *sij = &si->backend_data.jack; if (sij->is_shutdown) return SoundIoErrorBackendDisconnected; - SoundIoDevicesInfo *devices_info = allocate(1); + struct SoundIoDevicesInfo *devices_info = ALLOCATE(struct SoundIoDevicesInfo, 1); if (!devices_info) return SoundIoErrorNoMem; devices_info->default_output_index = -1; devices_info->default_input_index = -1; - const char **port_names = jack_get_ports(sij->client, nullptr, nullptr, 0); + const char **port_names = jack_get_ports(sij->client, NULL, NULL, 0); if (!port_names) { soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } - SoundIoList clients = {0}; + struct SoundIoListJackClient clients = {0}; const char **port_name_ptr = port_names; for (; *port_name_ptr; port_name_ptr += 1) { const char *client_and_port_name = *port_name_ptr; @@ -120,12 +123,12 @@ static int refresh_devices_bare(SoundIoPrivate *si) { continue; } - SoundIoDeviceAim aim = (flags & JackPortIsInput) ? + enum SoundIoDeviceAim aim = (flags & JackPortIsInput) ? SoundIoDeviceAimOutput : SoundIoDeviceAimInput; bool is_physical = flags & JackPortIsPhysical; - const char *client_name = nullptr; - const char *port_name = nullptr; + const char *client_name = NULL; + const char *port_name = NULL; int client_name_len; int port_name_len; split_str(client_and_port_name, client_and_port_name_len, ':', @@ -134,7 +137,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { // device does not have colon, skip it continue; } - SoundIoJackClient *client = find_or_create_client(&clients, aim, is_physical, + struct SoundIoJackClient *client = find_or_create_client(&clients, aim, is_physical, client_name, client_name_len); if (!client) { jack_free(port_names); @@ -145,7 +148,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { // we hit the channel limit, skip the leftovers continue; } - SoundIoJackPort *port = &client->ports[client->port_count++]; + struct SoundIoJackPort *port = &client->ports[client->port_count++]; port->full_name = client_and_port_name; port->full_name_len = client_and_port_name_len; port->name = port_name; @@ -158,21 +161,21 @@ static int refresh_devices_bare(SoundIoPrivate *si) { } for (int i = 0; i < clients.length; i += 1) { - SoundIoJackClient *client = &clients.at(i); + struct SoundIoJackClient *client = SoundIoListJackClient_ptr_at(&clients, i); if (client->port_count <= 0) continue; - SoundIoDevicePrivate *dev = allocate(1); + struct SoundIoDevicePrivate *dev = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev) { jack_free(port_names); soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; } - SoundIoDevice *device = &dev->pub; - SoundIoDeviceJack *dj = &dev->backend_data.jack; + struct SoundIoDevice *device = &dev->pub; + struct SoundIoDeviceJack *dj = &dev->backend_data.jack; int description_len = client->name_len + 3 + 2 * client->port_count; for (int port_index = 0; port_index < client->port_count; port_index += 1) { - SoundIoJackPort *port = &client->ports[port_index]; + struct SoundIoJackPort *port = &client->ports[port_index]; description_len += port->name_len; } @@ -184,7 +187,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { device->is_raw = false; device->aim = client->aim; device->id = soundio_str_dupe(client->name, client->name_len); - device->name = allocate(description_len); + device->name = ALLOCATE(char, description_len); device->current_format = SoundIoFormatFloat32NE; device->sample_rate_count = 1; device->sample_rates = &dev->prealloc_sample_rate_range; @@ -197,7 +200,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { device->software_latency_max = sij->period_size / (double) sij->sample_rate; dj->port_count = client->port_count; - dj->ports = allocate(dj->port_count); + dj->ports = ALLOCATE(struct SoundIoDeviceJackPort, dj->port_count); if (!device->id || !device->name || !dj->ports) { jack_free(port_names); @@ -207,8 +210,8 @@ static int refresh_devices_bare(SoundIoPrivate *si) { } for (int port_index = 0; port_index < client->port_count; port_index += 1) { - SoundIoJackPort *port = &client->ports[port_index]; - SoundIoDeviceJackPort *djp = &dj->ports[port_index]; + struct SoundIoJackPort *port = &client->ports[port_index]; + struct SoundIoDeviceJackPort *djp = &dj->ports[port_index]; djp->full_name = soundio_str_dupe(port->full_name, port->full_name_len); djp->full_name_len = port->full_name_len; djp->channel_id = port->channel_id; @@ -226,7 +229,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { memcpy(&device->name[client->name_len], ": ", 2); int index = client->name_len + 2; for (int port_index = 0; port_index < client->port_count; port_index += 1) { - SoundIoJackPort *port = &client->ports[port_index]; + struct SoundIoJackPort *port = &client->ports[port_index]; memcpy(&device->name[index], port->name, port->name_len); index += port->name_len; if (port_index + 1 < client->port_count) { @@ -238,7 +241,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { device->current_layout.channel_count = client->port_count; bool any_invalid = false; for (int port_index = 0; port_index < client->port_count; port_index += 1) { - SoundIoJackPort *port = &client->ports[port_index]; + struct SoundIoJackPort *port = &client->ports[port_index]; device->current_layout.channels[port_index] = port->channel_id; any_invalid = any_invalid || (port->channel_id == SoundIoChannelIdInvalid); } @@ -256,7 +259,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { device->formats = &dev->prealloc_format; device->formats[0] = device->current_format; - SoundIoList *device_list; + struct SoundIoListDevicePtr *device_list; if (device->aim == SoundIoDeviceAimOutput) { device_list = &devices_info->output_devices; if (devices_info->default_output_index < 0 && client->is_physical) @@ -268,7 +271,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { devices_info->default_input_index = device_list->length; } - if (device_list->append(device)) { + if (SoundIoListDevicePtr_append(device_list, device)) { soundio_device_unref(device); soundio_destroy_devices_info(devices_info); return SoundIoErrorNoMem; @@ -283,7 +286,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) { return 0; } -static int refresh_devices(SoundIoPrivate *si) { +static int refresh_devices(struct SoundIoPrivate *si) { int err = SoundIoErrorInterrupted; while (err == SoundIoErrorInterrupted) err = refresh_devices_bare(si); @@ -291,8 +294,8 @@ static int refresh_devices(SoundIoPrivate *si) { } static void my_flush_events(struct SoundIoPrivate *si, bool wait) { - SoundIo *soundio = &si->pub; - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIo *soundio = &si->pub; + struct SoundIoJack *sij = &si->backend_data.jack; int err; bool cb_shutdown = false; @@ -312,9 +315,9 @@ static void my_flush_events(struct SoundIoPrivate *si, bool wait) { if (cb_shutdown) { soundio->on_backend_disconnect(soundio, SoundIoErrorBackendDisconnected); } else { - if (!sij->refresh_devices_flag.test_and_set()) { + if (!atomic_flag_test_and_set(&sij->refresh_devices_flag)) { if ((err = refresh_devices(si))) { - sij->refresh_devices_flag.clear(); + atomic_flag_clear(&sij->refresh_devices_flag); } else { soundio->on_devices_change(soundio); } @@ -332,16 +335,16 @@ static void wait_events_jack(struct SoundIoPrivate *si) { } static void wakeup_jack(struct SoundIoPrivate *si) { - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoJack *sij = &si->backend_data.jack; soundio_os_mutex_lock(sij->mutex); soundio_os_cond_signal(sij->cond, sij->mutex); soundio_os_mutex_unlock(sij->mutex); } static void force_device_scan_jack(struct SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoJack *sij = &si->backend_data.jack; - sij->refresh_devices_flag.clear(); + struct SoundIo *soundio = &si->pub; + struct SoundIoJack *sij = &si->backend_data.jack; + atomic_flag_clear(&sij->refresh_devices_flag); soundio_os_mutex_lock(sij->mutex); soundio_os_cond_signal(sij->cond, sij->mutex); soundio->on_events_signal(soundio); @@ -349,12 +352,12 @@ static void force_device_scan_jack(struct SoundIoPrivate *si) { } static int outstream_process_callback(jack_nframes_t nframes, void *arg) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg; - SoundIoOutStreamJack *osj = &os->backend_data.jack; - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)arg; + struct SoundIoOutStreamJack *osj = &os->backend_data.jack; + struct SoundIoOutStream *outstream = &os->pub; osj->frames_left = nframes; for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) { - SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; + struct SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; osj->areas[ch].ptr = (char*)jack_port_get_buffer(osjp->source_port, nframes); osj->areas[ch].step = outstream->bytes_per_sample; } @@ -363,36 +366,36 @@ static int outstream_process_callback(jack_nframes_t nframes, void *arg) { } static void outstream_destroy_jack(struct SoundIoPrivate *is, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamJack *osj = &os->backend_data.jack; + struct SoundIoOutStreamJack *osj = &os->backend_data.jack; jack_client_close(osj->client); - osj->client = nullptr; + osj->client = NULL; } -static SoundIoDeviceJackPort *find_port_matching_channel(SoundIoDevice *device, SoundIoChannelId id) { - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceJack *dj = &dev->backend_data.jack; +static struct SoundIoDeviceJackPort *find_port_matching_channel(struct SoundIoDevice *device, enum SoundIoChannelId id) { + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceJack *dj = &dev->backend_data.jack; for (int ch = 0; ch < device->current_layout.channel_count; ch += 1) { - SoundIoChannelId chan_id = device->current_layout.channels[ch]; + enum SoundIoChannelId chan_id = device->current_layout.channels[ch]; if (chan_id == id) return &dj->ports[ch]; } - return nullptr; + return NULL; } static int outstream_xrun_callback(void *arg) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg; - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)arg; + struct SoundIoOutStream *outstream = &os->pub; outstream->underflow_callback(outstream); return 0; } static int outstream_buffer_size_callback(jack_nframes_t nframes, void *arg) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg; - SoundIoOutStreamJack *osj = &os->backend_data.jack; - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)arg; + struct SoundIoOutStreamJack *osj = &os->backend_data.jack; + struct SoundIoOutStream *outstream = &os->pub; if ((jack_nframes_t)osj->period_size == nframes) { return 0; } else { @@ -402,8 +405,8 @@ static int outstream_buffer_size_callback(jack_nframes_t nframes, void *arg) { } static int outstream_sample_rate_callback(jack_nframes_t nframes, void *arg) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg; - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)arg; + struct SoundIoOutStream *outstream = &os->pub; if (nframes == (jack_nframes_t)outstream->sample_rate) { return 0; } else { @@ -413,18 +416,22 @@ static int outstream_sample_rate_callback(jack_nframes_t nframes, void *arg) { } static void outstream_shutdown_callback(void *arg) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg; - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)arg; + struct SoundIoOutStream *outstream = &os->pub; outstream->error_callback(outstream, SoundIoErrorStreaming); } +static inline jack_nframes_t nframes_max(jack_nframes_t a, jack_nframes_t b) { + return (a >= b) ? a : b; +} + static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoJack *sij = &si->backend_data.jack; - SoundIoOutStreamJack *osj = &os->backend_data.jack; - SoundIoOutStream *outstream = &os->pub; - SoundIoDevice *device = outstream->device; - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceJack *dj = &dev->backend_data.jack; + struct SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoOutStreamJack *osj = &os->backend_data.jack; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoDevice *device = outstream->device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceJack *dj = &dev->backend_data.jack; if (sij->is_shutdown) return SoundIoErrorBackendDisconnected; @@ -472,7 +479,7 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea // register ports and map channels int connected_count = 0; for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) { - SoundIoChannelId my_channel_id = outstream->layout.channels[ch]; + enum SoundIoChannelId my_channel_id = outstream->layout.channels[ch]; const char *channel_name = soundio_get_channel_name(my_channel_id); unsigned long flags = JackPortIsOutput; if (!outstream->non_terminal_hint) @@ -482,15 +489,15 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea outstream_destroy_jack(si, os); return SoundIoErrorOpeningDevice; } - SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; + struct SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; osjp->source_port = jport; // figure out which dest port this connects to - SoundIoDeviceJackPort *djp = find_port_matching_channel(device, my_channel_id); + struct SoundIoDeviceJackPort *djp = find_port_matching_channel(device, my_channel_id); if (djp) { osjp->dest_port_name = djp->full_name; osjp->dest_port_name_len = djp->full_name_len; connected_count += 1; - max_port_latency = max(max_port_latency, djp->latency_range.max); + max_port_latency = nframes_max(max_port_latency, djp->latency_range.max); } } // If nothing got connected, channel layouts aren't working. Just send the @@ -499,13 +506,13 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea max_port_latency = 0; outstream->layout_error = SoundIoErrorIncompatibleDevice; - int ch_count = min(outstream->layout.channel_count, dj->port_count); + int ch_count = soundio_int_min(outstream->layout.channel_count, dj->port_count); for (int ch = 0; ch < ch_count; ch += 1) { - SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; - SoundIoDeviceJackPort *djp = &dj->ports[ch]; + struct SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; + struct SoundIoDeviceJackPort *djp = &dj->ports[ch]; osjp->dest_port_name = djp->full_name; osjp->dest_port_name_len = djp->full_name_len; - max_port_latency = max(max_port_latency, djp->latency_range.max); + max_port_latency = nframes_max(max_port_latency, djp->latency_range.max); } } @@ -515,7 +522,7 @@ static int outstream_open_jack(struct SoundIoPrivate *si, struct SoundIoOutStrea } static int outstream_pause_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) { - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoJack *sij = &si->backend_data.jack; if (sij->is_shutdown) return SoundIoErrorBackendDisconnected; @@ -524,9 +531,9 @@ static int outstream_pause_jack(struct SoundIoPrivate *si, struct SoundIoOutStre } static int outstream_start_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamJack *osj = &os->backend_data.jack; - SoundIoOutStream *outstream = &os->pub; - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoOutStreamJack *osj = &os->backend_data.jack; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoJack *sij = &si->backend_data.jack; int err; if (sij->is_shutdown) @@ -536,7 +543,7 @@ static int outstream_start_jack(struct SoundIoPrivate *si, struct SoundIoOutStre return SoundIoErrorStreaming; for (int ch = 0; ch < outstream->layout.channel_count; ch += 1) { - SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; + struct SoundIoOutStreamJackPort *osjp = &osj->ports[ch]; const char *dest_port_name = osjp->dest_port_name; // allow unconnected ports if (!dest_port_name) @@ -550,9 +557,9 @@ static int outstream_start_jack(struct SoundIoPrivate *si, struct SoundIoOutStre } static int outstream_begin_write_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, - SoundIoChannelArea **out_areas, int *frame_count) + struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoOutStreamJack *osj = &os->backend_data.jack; + struct SoundIoOutStreamJack *osj = &os->backend_data.jack; if (*frame_count != osj->frames_left) return SoundIoErrorInvalid; @@ -563,7 +570,7 @@ static int outstream_begin_write_jack(struct SoundIoPrivate *si, struct SoundIoO } static int outstream_end_write_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamJack *osj = &os->backend_data.jack; + struct SoundIoOutStreamJack *osj = &os->backend_data.jack; osj->frames_left = 0; return 0; } @@ -575,30 +582,30 @@ static int outstream_clear_buffer_jack(struct SoundIoPrivate *si, struct SoundIo static int outstream_get_latency_jack(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, double *out_latency) { - SoundIoOutStreamJack *osj = &os->backend_data.jack; + struct SoundIoOutStreamJack *osj = &os->backend_data.jack; *out_latency = osj->hardware_latency; return 0; } static void instream_destroy_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamJack *isj = &is->backend_data.jack; + struct SoundIoInStreamJack *isj = &is->backend_data.jack; jack_client_close(isj->client); - isj->client = nullptr; + isj->client = NULL; } static int instream_xrun_callback(void *arg) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)arg; - SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)arg; + struct SoundIoInStream *instream = &is->pub; instream->overflow_callback(instream); return 0; } static int instream_buffer_size_callback(jack_nframes_t nframes, void *arg) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)arg; - SoundIoInStreamJack *isj = &is->backend_data.jack; - SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)arg; + struct SoundIoInStreamJack *isj = &is->backend_data.jack; + struct SoundIoInStream *instream = &is->pub; if ((jack_nframes_t)isj->period_size == nframes) { return 0; @@ -609,8 +616,8 @@ static int instream_buffer_size_callback(jack_nframes_t nframes, void *arg) { } static int instream_sample_rate_callback(jack_nframes_t nframes, void *arg) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)arg; - SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)arg; + struct SoundIoInStream *instream = &is->pub; if (nframes == (jack_nframes_t)instream->sample_rate) { return 0; } else { @@ -620,18 +627,18 @@ static int instream_sample_rate_callback(jack_nframes_t nframes, void *arg) { } static void instream_shutdown_callback(void *arg) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)arg; - SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)arg; + struct SoundIoInStream *instream = &is->pub; instream->error_callback(instream, SoundIoErrorStreaming); } static int instream_process_callback(jack_nframes_t nframes, void *arg) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)arg; - SoundIoInStream *instream = &is->pub; - SoundIoInStreamJack *isj = &is->backend_data.jack; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)arg; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamJack *isj = &is->backend_data.jack; isj->frames_left = nframes; for (int ch = 0; ch < instream->layout.channel_count; ch += 1) { - SoundIoInStreamJackPort *isjp = &isj->ports[ch]; + struct SoundIoInStreamJackPort *isjp = &isj->ports[ch]; isj->areas[ch].ptr = (char*)jack_port_get_buffer(isjp->dest_port, nframes); isj->areas[ch].step = instream->bytes_per_sample; } @@ -640,12 +647,12 @@ static int instream_process_callback(jack_nframes_t nframes, void *arg) { } static int instream_open_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamJack *isj = &is->backend_data.jack; - SoundIoJack *sij = &si->backend_data.jack; - SoundIoDevice *device = instream->device; - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceJack *dj = &dev->backend_data.jack; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamJack *isj = &is->backend_data.jack; + struct SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoDevice *device = instream->device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceJack *dj = &dev->backend_data.jack; if (sij->is_shutdown) return SoundIoErrorBackendDisconnected; @@ -692,7 +699,7 @@ static int instream_open_jack(struct SoundIoPrivate *si, struct SoundIoInStreamP // register ports and map channels int connected_count = 0; for (int ch = 0; ch < instream->layout.channel_count; ch += 1) { - SoundIoChannelId my_channel_id = instream->layout.channels[ch]; + enum SoundIoChannelId my_channel_id = instream->layout.channels[ch]; const char *channel_name = soundio_get_channel_name(my_channel_id); unsigned long flags = JackPortIsInput; if (!instream->non_terminal_hint) @@ -702,15 +709,15 @@ static int instream_open_jack(struct SoundIoPrivate *si, struct SoundIoInStreamP instream_destroy_jack(si, is); return SoundIoErrorOpeningDevice; } - SoundIoInStreamJackPort *isjp = &isj->ports[ch]; + struct SoundIoInStreamJackPort *isjp = &isj->ports[ch]; isjp->dest_port = jport; // figure out which source port this connects to - SoundIoDeviceJackPort *djp = find_port_matching_channel(device, my_channel_id); + struct SoundIoDeviceJackPort *djp = find_port_matching_channel(device, my_channel_id); if (djp) { isjp->source_port_name = djp->full_name; isjp->source_port_name_len = djp->full_name_len; connected_count += 1; - max_port_latency = max(max_port_latency, djp->latency_range.max); + max_port_latency = nframes_max(max_port_latency, djp->latency_range.max); } } // If nothing got connected, channel layouts aren't working. Just send the @@ -719,13 +726,13 @@ static int instream_open_jack(struct SoundIoPrivate *si, struct SoundIoInStreamP max_port_latency = 0; instream->layout_error = SoundIoErrorIncompatibleDevice; - int ch_count = min(instream->layout.channel_count, dj->port_count); + int ch_count = soundio_int_min(instream->layout.channel_count, dj->port_count); for (int ch = 0; ch < ch_count; ch += 1) { - SoundIoInStreamJackPort *isjp = &isj->ports[ch]; - SoundIoDeviceJackPort *djp = &dj->ports[ch]; + struct SoundIoInStreamJackPort *isjp = &isj->ports[ch]; + struct SoundIoDeviceJackPort *djp = &dj->ports[ch]; isjp->source_port_name = djp->full_name; isjp->source_port_name_len = djp->full_name_len; - max_port_latency = max(max_port_latency, djp->latency_range.max); + max_port_latency = nframes_max(max_port_latency, djp->latency_range.max); } } @@ -735,7 +742,7 @@ static int instream_open_jack(struct SoundIoPrivate *si, struct SoundIoInStreamP } static int instream_pause_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) { - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoJack *sij = &si->backend_data.jack; if (sij->is_shutdown) return SoundIoErrorBackendDisconnected; @@ -744,9 +751,9 @@ static int instream_pause_jack(struct SoundIoPrivate *si, struct SoundIoInStream } static int instream_start_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamJack *isj = &is->backend_data.jack; - SoundIoInStream *instream = &is->pub; - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoInStreamJack *isj = &is->backend_data.jack; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoJack *sij = &si->backend_data.jack; int err; if (sij->is_shutdown) @@ -756,7 +763,7 @@ static int instream_start_jack(struct SoundIoPrivate *si, struct SoundIoInStream return SoundIoErrorStreaming; for (int ch = 0; ch < instream->layout.channel_count; ch += 1) { - SoundIoInStreamJackPort *isjp = &isj->ports[ch]; + struct SoundIoInStreamJackPort *isjp = &isj->ports[ch]; const char *source_port_name = isjp->source_port_name; // allow unconnected ports if (!source_port_name) @@ -770,9 +777,9 @@ static int instream_start_jack(struct SoundIoPrivate *si, struct SoundIoInStream } static int instream_begin_read_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, - SoundIoChannelArea **out_areas, int *frame_count) + struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoInStreamJack *isj = &is->backend_data.jack; + struct SoundIoInStreamJack *isj = &is->backend_data.jack; if (*frame_count != isj->frames_left) return SoundIoErrorInvalid; @@ -783,7 +790,7 @@ static int instream_begin_read_jack(struct SoundIoPrivate *si, struct SoundIoInS } static int instream_end_read_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamJack *isj = &is->backend_data.jack; + struct SoundIoInStreamJack *isj = &is->backend_data.jack; isj->frames_left = 0; return 0; } @@ -791,15 +798,15 @@ static int instream_end_read_jack(struct SoundIoPrivate *si, struct SoundIoInStr static int instream_get_latency_jack(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, double *out_latency) { - SoundIoInStreamJack *isj = &is->backend_data.jack; + struct SoundIoInStreamJack *isj = &is->backend_data.jack; *out_latency = isj->hardware_latency; return 0; } -static void notify_devices_change(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoJack *sij = &si->backend_data.jack; - sij->refresh_devices_flag.clear(); +static void notify_devices_change(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoJack *sij = &si->backend_data.jack; + atomic_flag_clear(&sij->refresh_devices_flag); soundio_os_mutex_lock(sij->mutex); soundio_os_cond_signal(sij->cond, sij->mutex); soundio->on_events_signal(soundio); @@ -807,37 +814,37 @@ static void notify_devices_change(SoundIoPrivate *si) { } static int buffer_size_callback(jack_nframes_t nframes, void *arg) { - SoundIoPrivate *si = (SoundIoPrivate *)arg; - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)arg; + struct SoundIoJack *sij = &si->backend_data.jack; sij->period_size = nframes; notify_devices_change(si); return 0; } static int sample_rate_callback(jack_nframes_t nframes, void *arg) { - SoundIoPrivate *si = (SoundIoPrivate *)arg; - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)arg; + struct SoundIoJack *sij = &si->backend_data.jack; sij->sample_rate = nframes; notify_devices_change(si); return 0; } static void port_registration_callback(jack_port_id_t port_id, int reg, void *arg) { - SoundIoPrivate *si = (SoundIoPrivate *)arg; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)arg; notify_devices_change(si); } static void port_rename_calllback(jack_port_id_t port_id, const char *old_name, const char *new_name, void *arg) { - SoundIoPrivate *si = (SoundIoPrivate *)arg; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)arg; notify_devices_change(si); } static void shutdown_callback(void *arg) { - SoundIoPrivate *si = (SoundIoPrivate *)arg; - SoundIo *soundio = &si->pub; - SoundIoJack *sij = &si->backend_data.jack; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)arg; + struct SoundIo *soundio = &si->pub; + struct SoundIoJack *sij = &si->backend_data.jack; soundio_os_mutex_lock(sij->mutex); sij->is_shutdown = true; soundio_os_cond_signal(sij->cond, sij->mutex); @@ -845,8 +852,8 @@ static void shutdown_callback(void *arg) { soundio_os_mutex_unlock(sij->mutex); } -static void destroy_jack(SoundIoPrivate *si) { - SoundIoJack *sij = &si->backend_data.jack; +static void destroy_jack(struct SoundIoPrivate *si) { + struct SoundIoJack *sij = &si->backend_data.jack; if (sij->client) jack_client_close(sij->client); @@ -859,15 +866,15 @@ static void destroy_jack(SoundIoPrivate *si) { } int soundio_jack_init(struct SoundIoPrivate *si) { - SoundIoJack *sij = &si->backend_data.jack; - SoundIo *soundio = &si->pub; + struct SoundIoJack *sij = &si->backend_data.jack; + struct SoundIo *soundio = &si->pub; - if (!global_msg_callback_flag.test_and_set()) { + if (!atomic_flag_test_and_set(&global_msg_callback_flag)) { if (soundio->jack_error_callback) jack_set_error_function(soundio->jack_error_callback); if (soundio->jack_info_callback) jack_set_info_function(soundio->jack_info_callback); - global_msg_callback_flag.clear(); + atomic_flag_clear(&global_msg_callback_flag); } sij->mutex = soundio_os_mutex_create(); @@ -916,7 +923,7 @@ int soundio_jack_init(struct SoundIoPrivate *si) { } jack_on_shutdown(sij->client, shutdown_callback, si); - sij->refresh_devices_flag.clear(); + atomic_flag_clear(&sij->refresh_devices_flag); sij->period_size = jack_get_buffer_size(sij->client); sij->sample_rate = jack_get_sample_rate(sij->client); diff --git a/src/jack.hpp b/src/jack.h similarity index 60% rename from src/jack.hpp rename to src/jack.h index cb66291..5381360 100644 --- a/src/jack.hpp +++ b/src/jack.h @@ -5,33 +5,39 @@ * See http://opensource.org/licenses/MIT */ -#ifndef SOUNDIO_JACK_HPP -#define SOUNDIO_JACK_HPP +#ifndef SOUNDIO_JACK_H +#define SOUNDIO_JACK_H -#include "soundio_private.h" +#include "soundio_internal.h" #include "os.h" -#include "atomics.hpp" +#include "atomics.h" +// jack.h does not properly put `void` in function prototypes with no +// arguments, so we're forced to temporarily disable -Werror=strict-prototypes +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-prototypes" #include +#pragma GCC diagnostic pop +struct SoundIoPrivate; int soundio_jack_init(struct SoundIoPrivate *si); struct SoundIoDeviceJackPort { char *full_name; int full_name_len; - SoundIoChannelId channel_id; + enum SoundIoChannelId channel_id; jack_latency_range_t latency_range; }; struct SoundIoDeviceJack { int port_count; - SoundIoDeviceJackPort *ports; + struct SoundIoDeviceJackPort *ports; }; struct SoundIoJack { jack_client_t *client; - SoundIoOsMutex *mutex; - SoundIoOsCond *cond; + struct SoundIoOsMutex *mutex; + struct SoundIoOsCond *cond; atomic_flag refresh_devices_flag; int sample_rate; int period_size; @@ -50,8 +56,8 @@ struct SoundIoOutStreamJack { int period_size; int frames_left; double hardware_latency; - SoundIoOutStreamJackPort ports[SOUNDIO_MAX_CHANNELS]; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoOutStreamJackPort ports[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; struct SoundIoInStreamJackPort { @@ -65,8 +71,8 @@ struct SoundIoInStreamJack { int period_size; int frames_left; double hardware_latency; - SoundIoInStreamJackPort ports[SOUNDIO_MAX_CHANNELS]; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoInStreamJackPort ports[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; char *buf_ptrs[SOUNDIO_MAX_CHANNELS]; }; diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..e3ba630 --- /dev/null +++ b/src/list.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2015 Andrew Kelley + * + * This file is part of libsoundio, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef SOUNDIO_LIST_H +#define SOUNDIO_LIST_H + +#include "util.h" +#include "soundio_internal.h" + +#include + +#define SOUNDIO_LIST_STATIC static +#define SOUNDIO_LIST_NOT_STATIC + +#define SOUNDIO_MAKE_LIST_STRUCT(Type, Name, static_kw) \ + struct Name { \ + Type *items; \ + int length; \ + int capacity; \ + }; + +#define SOUNDIO_MAKE_LIST_PROTO(Type, Name, static_kw) \ + static_kw void Name##_deinit(struct Name *s); \ + static_kw int __attribute__((warn_unused_result)) Name##_append(struct Name *s, Type item); \ + static_kw Type Name##_val_at(struct Name *s, int index); \ + static_kw Type * Name##_ptr_at(struct Name *s, int index); \ + static_kw Type Name##_pop(struct Name *s); \ + static_kw int __attribute__((warn_unused_result)) Name##_add_one(struct Name *s); \ + static_kw Type Name##_last_val(struct Name *s); \ + static_kw Type *Name##_last_ptr(struct Name *s); \ + static_kw int __attribute__((warn_unused_result)) Name##_resize(struct Name *s, int new_length); \ + static_kw void Name##_clear(struct Name *s); \ + static_kw int __attribute__((warn_unused_result)) \ + Name##_ensure_capacity(struct Name *s, int new_capacity); \ + static_kw Type Name##_swap_remove(struct Name *s, int index); + + +#define SOUNDIO_MAKE_LIST_DEF(Type, Name, static_kw) \ + __attribute__ ((unused)) \ + static_kw void Name##_deinit(struct Name *s) { \ + free(s->items); \ + } \ +\ + __attribute__ ((unused)) \ + __attribute__ ((warn_unused_result)) \ + static_kw int Name##_ensure_capacity(struct Name *s, int new_capacity) { \ + int better_capacity = soundio_int_max(s->capacity, 16); \ + while (better_capacity < new_capacity) \ + better_capacity = better_capacity * 2; \ + if (better_capacity != s->capacity) { \ + Type *new_items = REALLOCATE_NONZERO(Type, s->items, better_capacity); \ + if (!new_items) \ + return SoundIoErrorNoMem; \ + s->items = new_items; \ + s->capacity = better_capacity; \ + } \ + return 0; \ + } \ +\ + __attribute__ ((unused)) \ + __attribute__ ((warn_unused_result)) \ + static_kw int Name##_append(struct Name *s, Type item) { \ + int err = Name##_ensure_capacity(s, s->length + 1); \ + if (err) \ + return err; \ + s->items[s->length] = item; \ + s->length += 1; \ + return 0; \ + } \ +\ + __attribute__ ((unused)) \ + static_kw Type Name##_val_at(struct Name *s, int index) { \ + assert(index >= 0); \ + assert(index < s->length); \ + return s->items[index]; \ + } \ +\ + /* remember that the pointer to this item is invalid after you \ + * modify the length of the list \ + */ \ + __attribute__ ((unused)) \ + static_kw Type * Name##_ptr_at(struct Name *s, int index) { \ + assert(index >= 0); \ + assert(index < s->length); \ + return &s->items[index]; \ + } \ +\ + __attribute__ ((unused)) \ + static_kw Type Name##_pop(struct Name *s) { \ + assert(s->length >= 1); \ + s->length -= 1; \ + return s->items[s->length]; \ + } \ +\ + __attribute__ ((unused)) \ + __attribute__ ((warn_unused_result)) \ + static_kw int Name##_resize(struct Name *s, int new_length) { \ + assert(new_length >= 0); \ + int err = Name##_ensure_capacity(s, new_length); \ + if (err) \ + return err; \ + s->length = new_length; \ + return 0; \ + } \ +\ + __attribute__ ((unused)) \ + __attribute__ ((warn_unused_result)) \ + static_kw int Name##_add_one(struct Name *s) { \ + return Name##_resize(s, s->length + 1); \ + } \ +\ + __attribute__ ((unused)) \ + static_kw Type Name##_last_val(struct Name *s) { \ + assert(s->length >= 1); \ + return s->items[s->length - 1]; \ + } \ +\ + __attribute__ ((unused)) \ + static_kw Type *Name##_last_ptr(struct Name *s) { \ + assert(s->length >= 1); \ + return &s->items[s->length - 1]; \ + } \ +\ + __attribute__ ((unused)) \ + static_kw void Name##_clear(struct Name *s) { \ + s->length = 0; \ + } \ +\ + __attribute__ ((unused)) \ + static_kw Type Name##_swap_remove(struct Name *s, int index) { \ + assert(index >= 0); \ + assert(index < s->length); \ + Type last = Name##_pop(s); \ + if (index == s->length) \ + return last; \ + Type item = s->items[index]; \ + s->items[index] = last; \ + return item; \ + } + +#endif diff --git a/src/list.hpp b/src/list.hpp deleted file mode 100644 index 0105ed1..0000000 --- a/src/list.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Kelley - * - * This file is part of libsoundio, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#ifndef SOUNDIO_LIST_HPP -#define SOUNDIO_LIST_HPP - -#include "util.hpp" -#include "soundio_private.h" - -#include - -template -struct SoundIoList { - void deinit() { - free(items); - } - int __attribute__((warn_unused_result)) append(T item) { - int err = ensure_capacity(length + 1); - if (err) - return err; - items[length++] = item; - return 0; - } - // remember that the pointer to this item is invalid after you - // modify the length of the list - const T & at(int index) const { - assert(index >= 0); - assert(index < length); - return items[index]; - } - T & at(int index) { - assert(index >= 0); - assert(index < length); - return items[index]; - } - T pop() { - assert(length >= 1); - return items[--length]; - } - - int __attribute__((warn_unused_result)) add_one() { - return resize(length + 1); - } - - const T & last() const { - assert(length >= 1); - return items[length - 1]; - } - - T & last() { - assert(length >= 1); - return items[length - 1]; - } - - int __attribute__((warn_unused_result)) resize(int new_length) { - assert(new_length >= 0); - int err = ensure_capacity(new_length); - if (err) - return err; - length = new_length; - return 0; - } - - void clear() { - length = 0; - } - - int __attribute__((warn_unused_result)) ensure_capacity(int new_capacity) { - int better_capacity = max(capacity, 16); - while (better_capacity < new_capacity) - better_capacity = better_capacity * 2; - if (better_capacity != capacity) { - T *new_items = reallocate_nonzero(items, better_capacity); - if (!new_items) - return SoundIoErrorNoMem; - items = new_items; - capacity = better_capacity; - } - return 0; - } - - T swap_remove(int index) { - assert(index >= 0); - assert(index < length); - T last = pop(); - if (index == length) - return last; - T item = items[index]; - items[index] = last; - return item; - } - - T * items; - int length; - int capacity; -}; - -#endif diff --git a/src/os.cpp b/src/os.c similarity index 96% rename from src/os.cpp rename to src/os.c index 4714610..7fc35b6 100644 --- a/src/os.cpp +++ b/src/os.c @@ -5,9 +5,16 @@ * See http://opensource.org/licenses/MIT */ +#if defined(__APPLE__) +#define _DARWIN_C_SOURCE +#undef _POSIX_C_SOURCE +#else +#define _GNU_SOURCE +#endif + #include "os.h" -#include "soundio_private.h" -#include "util.hpp" +#include "soundio_internal.h" +#include "util.h" #include #include @@ -53,7 +60,7 @@ #include #include #include -#ifndef MAP_ANONYMOUS +#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) #define MAP_ANONYMOUS MAP_ANON #endif @@ -159,7 +166,7 @@ double soundio_os_get_time(void) { #if defined(SOUNDIO_OS_WINDOWS) static DWORD WINAPI run_win32_thread(LPVOID userdata) { struct SoundIoOsThread *thread = (struct SoundIoOsThread *)userdata; - HRESULT err = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + HRESULT err = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); assert(err == S_OK); thread->run(thread->arg); CoUninitialize(); @@ -184,7 +191,7 @@ int soundio_os_thread_create( { *out_thread = NULL; - struct SoundIoOsThread *thread = allocate(1); + struct SoundIoOsThread *thread = ALLOCATE(struct SoundIoOsThread, 1); if (!thread) { soundio_os_thread_destroy(thread); return SoundIoErrorNoMem; @@ -276,7 +283,7 @@ void soundio_os_thread_destroy(struct SoundIoOsThread *thread) { } struct SoundIoOsMutex *soundio_os_mutex_create(void) { - struct SoundIoOsMutex *mutex = allocate(1); + struct SoundIoOsMutex *mutex = ALLOCATE(struct SoundIoOsMutex, 1); if (!mutex) { soundio_os_mutex_destroy(mutex); return NULL; @@ -328,7 +335,7 @@ void soundio_os_mutex_unlock(struct SoundIoOsMutex *mutex) { } struct SoundIoOsCond * soundio_os_cond_create(void) { - struct SoundIoOsCond *cond = allocate(1); + struct SoundIoOsCond *cond = ALLOCATE(struct SoundIoOsCond, 1); if (!cond) { soundio_os_cond_destroy(cond); @@ -558,7 +565,7 @@ static int internal_init(void) { GetSystemInfo(&win32_system_info); page_size = win32_system_info.dwAllocationGranularity; #else - page_size = getpagesize(); + page_size = sysconf(_SC_PAGESIZE); #if defined(__MACH__) host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); #endif @@ -581,7 +588,7 @@ int soundio_os_init(void) { if ((err = internal_init())) return err; - if (!InitOnceComplete(&win32_init_once, INIT_ONCE_ASYNC, nullptr)) + if (!InitOnceComplete(&win32_init_once, INIT_ONCE_ASYNC, NULL)) return SoundIoErrorSystemResources; #else assert_no_err(pthread_mutex_lock(&init_mutex)); @@ -734,5 +741,5 @@ void soundio_os_deinit_mirrored_memory(struct SoundIoOsMirroredMemory *mem) { int err = munmap(mem->address, 2 * mem->capacity); assert(!err); #endif - mem->address = nullptr; + mem->address = NULL; } diff --git a/src/pulseaudio.cpp b/src/pulseaudio.c similarity index 75% rename from src/pulseaudio.cpp rename to src/pulseaudio.c index a91bb30..4e8c790 100644 --- a/src/pulseaudio.cpp +++ b/src/pulseaudio.c @@ -5,8 +5,8 @@ * See http://opensource.org/licenses/MIT */ -#include "pulseaudio.hpp" -#include "soundio.hpp" +#include "pulseaudio.h" +#include "soundio_private.h" #include #include @@ -15,19 +15,19 @@ static void subscribe_callback(pa_context *context, pa_subscription_event_type_t event_bits, uint32_t index, void *userdata) { - SoundIoPrivate *si = (SoundIoPrivate *)userdata; - SoundIo *soundio = &si->pub; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)userdata; + struct SoundIo *soundio = &si->pub; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; sipa->device_scan_queued = true; pa_threaded_mainloop_signal(sipa->main_loop, 0); soundio->on_events_signal(soundio); } -static int subscribe_to_events(SoundIoPrivate *si) { - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static int subscribe_to_events(struct SoundIoPrivate *si) { + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; pa_subscription_mask_t events = (pa_subscription_mask_t)( PA_SUBSCRIPTION_MASK_SINK|PA_SUBSCRIPTION_MASK_SOURCE|PA_SUBSCRIPTION_MASK_SERVER); - pa_operation *subscribe_op = pa_context_subscribe(sipa->pulse_context, events, nullptr, si); + pa_operation *subscribe_op = pa_context_subscribe(sipa->pulse_context, events, NULL, si); if (!subscribe_op) return SoundIoErrorNoMem; pa_operation_unref(subscribe_op); @@ -35,9 +35,9 @@ static int subscribe_to_events(SoundIoPrivate *si) { } static void context_state_callback(pa_context *context, void *userdata) { - SoundIoPrivate *si = (SoundIoPrivate *)userdata; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; - SoundIo *soundio = &si->pub; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)userdata; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIo *soundio = &si->pub; switch (pa_context_get_state(context)) { case PA_CONTEXT_UNCONNECTED: // The context hasn't been connected yet. @@ -68,8 +68,8 @@ static void context_state_callback(pa_context *context, void *userdata) { } } -static void destroy_pa(SoundIoPrivate *si) { - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static void destroy_pa(struct SoundIoPrivate *si) { + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; if (sipa->main_loop) pa_threaded_mainloop_stop(sipa->main_loop); @@ -90,7 +90,7 @@ static void destroy_pa(SoundIoPrivate *si) { free(sipa->default_source_name); } -static SoundIoFormat from_pulseaudio_format(pa_sample_spec sample_spec) { +static enum SoundIoFormat from_pulseaudio_format(pa_sample_spec sample_spec) { switch (sample_spec.format) { case PA_SAMPLE_U8: return SoundIoFormatU8; case PA_SAMPLE_S16LE: return SoundIoFormatS16LE; @@ -113,7 +113,7 @@ static SoundIoFormat from_pulseaudio_format(pa_sample_spec sample_spec) { return SoundIoFormatInvalid; } -static SoundIoChannelId from_pulseaudio_channel_pos(pa_channel_position_t pos) { +static enum SoundIoChannelId from_pulseaudio_channel_pos(pa_channel_position_t pos) { switch (pos) { case PA_CHANNEL_POSITION_MONO: return SoundIoChannelIdFrontCenter; case PA_CHANNEL_POSITION_FRONT_LEFT: return SoundIoChannelIdFrontLeft; @@ -156,15 +156,15 @@ static SoundIoChannelId from_pulseaudio_channel_pos(pa_channel_position_t pos) { } } -static void set_from_pulseaudio_channel_map(pa_channel_map channel_map, SoundIoChannelLayout *channel_layout) { +static void set_from_pulseaudio_channel_map(pa_channel_map channel_map, struct SoundIoChannelLayout *channel_layout) { channel_layout->channel_count = channel_map.channels; for (int i = 0; i < channel_map.channels; i += 1) { channel_layout->channels[i] = from_pulseaudio_channel_pos(channel_map.map[i]); } - channel_layout->name = nullptr; + channel_layout->name = NULL; int builtin_layout_count = soundio_channel_layout_builtin_count(); for (int i = 0; i < builtin_layout_count; i += 1) { - const SoundIoChannelLayout *builtin_layout = soundio_channel_layout_get_builtin(i); + const struct SoundIoChannelLayout *builtin_layout = soundio_channel_layout_get_builtin(i); if (soundio_channel_layout_equal(builtin_layout, channel_layout)) { channel_layout->name = builtin_layout->name; break; @@ -172,9 +172,9 @@ static void set_from_pulseaudio_channel_map(pa_channel_map channel_map, SoundIoC } } -static int set_all_device_channel_layouts(SoundIoDevice *device) { +static int set_all_device_channel_layouts(struct SoundIoDevice *device) { device->layout_count = soundio_channel_layout_builtin_count(); - device->layouts = allocate(device->layout_count); + device->layouts = ALLOCATE(struct SoundIoChannelLayout, device->layout_count); if (!device->layouts) return SoundIoErrorNoMem; for (int i = 0; i < device->layout_count; i += 1) @@ -182,9 +182,9 @@ static int set_all_device_channel_layouts(SoundIoDevice *device) { return 0; } -static int set_all_device_formats(SoundIoDevice *device) { +static int set_all_device_formats(struct SoundIoDevice *device) { device->format_count = 9; - device->formats = allocate(device->format_count); + device->formats = ALLOCATE(enum SoundIoFormat, device->format_count); if (!device->formats) return SoundIoErrorNoMem; device->formats[0] = SoundIoFormatU8; @@ -199,10 +199,10 @@ static int set_all_device_formats(SoundIoDevice *device) { return 0; } -static int perform_operation(SoundIoPrivate *si, pa_operation *op) { +static int perform_operation(struct SoundIoPrivate *si, pa_operation *op) { if (!op) return SoundIoErrorNoMem; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; for (;;) { switch (pa_operation_get_state(op)) { case PA_OPERATION_RUNNING: @@ -219,9 +219,9 @@ static int perform_operation(SoundIoPrivate *si, pa_operation *op) { } static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *info, int eol, void *userdata) { - SoundIoPrivate *si = (SoundIoPrivate *)userdata; - SoundIo *soundio = &si->pub; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)userdata; + struct SoundIo *soundio = &si->pub; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; int err; if (eol) { pa_threaded_mainloop_signal(sipa->main_loop, 0); @@ -230,12 +230,12 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in if (sipa->device_query_err) return; - SoundIoDevicePrivate *dev = allocate(1); + struct SoundIoDevicePrivate *dev = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev) { sipa->device_query_err = SoundIoErrorNoMem; return; } - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; device->ref_count = 1; device->soundio = soundio; @@ -252,8 +252,8 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in // some reasonable min and max values. device->sample_rate_count = 1; device->sample_rates = &dev->prealloc_sample_rate_range; - device->sample_rates[0].min = min(SOUNDIO_MIN_SAMPLE_RATE, device->sample_rate_current); - device->sample_rates[0].max = max(SOUNDIO_MAX_SAMPLE_RATE, device->sample_rate_current); + device->sample_rates[0].min = soundio_int_min(SOUNDIO_MIN_SAMPLE_RATE, device->sample_rate_current); + device->sample_rates[0].max = soundio_int_max(SOUNDIO_MAX_SAMPLE_RATE, device->sample_rate_current); device->current_format = from_pulseaudio_format(info->sample_spec); // PulseAudio performs sample format conversion, so any PulseAudio @@ -274,7 +274,7 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in device->aim = SoundIoDeviceAimOutput; - if (sipa->current_devices_info->output_devices.append(device)) { + if (SoundIoListDevicePtr_append(&sipa->current_devices_info->output_devices, device)) { soundio_device_unref(device); sipa->device_query_err = SoundIoErrorNoMem; return; @@ -282,9 +282,9 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in } static void source_info_callback(pa_context *pulse_context, const pa_source_info *info, int eol, void *userdata) { - SoundIoPrivate *si = (SoundIoPrivate *)userdata; - SoundIo *soundio = &si->pub; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)userdata; + struct SoundIo *soundio = &si->pub; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; int err; if (eol) { @@ -294,12 +294,12 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info if (sipa->device_query_err) return; - SoundIoDevicePrivate *dev = allocate(1); + struct SoundIoDevicePrivate *dev = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev) { sipa->device_query_err = SoundIoErrorNoMem; return; } - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; device->ref_count = 1; device->soundio = soundio; @@ -316,8 +316,8 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info // some reasonable min and max values. device->sample_rate_count = 1; device->sample_rates = &dev->prealloc_sample_rate_range; - device->sample_rates[0].min = min(8000, device->sample_rate_current); - device->sample_rates[0].max = max(5644800, device->sample_rate_current); + device->sample_rates[0].min = soundio_int_min(SOUNDIO_MIN_SAMPLE_RATE, device->sample_rate_current); + device->sample_rates[0].max = soundio_int_max(SOUNDIO_MAX_SAMPLE_RATE, device->sample_rate_current); device->current_format = from_pulseaudio_format(info->sample_spec); // PulseAudio performs sample format conversion, so any PulseAudio @@ -338,7 +338,7 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info device->aim = SoundIoDeviceAimInput; - if (sipa->current_devices_info->input_devices.append(device)) { + if (SoundIoListDevicePtr_append(&sipa->current_devices_info->input_devices, device)) { soundio_device_unref(device); sipa->device_query_err = SoundIoErrorNoMem; return; @@ -346,9 +346,9 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info } static void server_info_callback(pa_context *pulse_context, const pa_server_info *info, void *userdata) { - SoundIoPrivate *si = (SoundIoPrivate *)userdata; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)userdata; assert(si); - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; assert(!sipa->default_sink_name); assert(!sipa->default_source_name); @@ -363,26 +363,26 @@ static void server_info_callback(pa_context *pulse_context, const pa_server_info } // always called even when refresh_devices succeeds -static void cleanup_refresh_devices(SoundIoPrivate *si) { - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static void cleanup_refresh_devices(struct SoundIoPrivate *si) { + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; soundio_destroy_devices_info(sipa->current_devices_info); - sipa->current_devices_info = nullptr; + sipa->current_devices_info = NULL; free(sipa->default_sink_name); - sipa->default_sink_name = nullptr; + sipa->default_sink_name = NULL; free(sipa->default_source_name); - sipa->default_source_name = nullptr; + sipa->default_source_name = NULL; } // call this while holding the main loop lock -static int refresh_devices(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static int refresh_devices(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; assert(!sipa->current_devices_info); - sipa->current_devices_info = allocate(1); + sipa->current_devices_info = ALLOCATE(struct SoundIoDevicesInfo, 1); if (!sipa->current_devices_info) return SoundIoErrorNoMem; @@ -414,7 +414,9 @@ static int refresh_devices(SoundIoPrivate *si) { if (sipa->current_devices_info->input_devices.length > 0) { sipa->current_devices_info->default_input_index = 0; for (int i = 0; i < sipa->current_devices_info->input_devices.length; i += 1) { - SoundIoDevice *device = sipa->current_devices_info->input_devices.at(i); + struct SoundIoDevice *device = SoundIoListDevicePtr_val_at( + &sipa->current_devices_info->input_devices, i); + assert(device->aim == SoundIoDeviceAimInput); if (strcmp(device->id, sipa->default_source_name) == 0) { sipa->current_devices_info->default_input_index = i; @@ -425,7 +427,9 @@ static int refresh_devices(SoundIoPrivate *si) { if (sipa->current_devices_info->output_devices.length > 0) { sipa->current_devices_info->default_output_index = 0; for (int i = 0; i < sipa->current_devices_info->output_devices.length; i += 1) { - SoundIoDevice *device = sipa->current_devices_info->output_devices.at(i); + struct SoundIoDevice *device = SoundIoListDevicePtr_val_at( + &sipa->current_devices_info->output_devices, i); + assert(device->aim == SoundIoDeviceAimOutput); if (strcmp(device->id, sipa->default_sink_name) == 0) { sipa->current_devices_info->default_output_index = i; @@ -435,20 +439,20 @@ static int refresh_devices(SoundIoPrivate *si) { soundio_destroy_devices_info(sipa->ready_devices_info); sipa->ready_devices_info = sipa->current_devices_info; - sipa->current_devices_info = nullptr; + sipa->current_devices_info = NULL; pa_threaded_mainloop_signal(sipa->main_loop, 0); soundio->on_events_signal(soundio); return 0; } -static void my_flush_events(SoundIoPrivate *si, bool wait) { - SoundIo *soundio = &si->pub; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static void my_flush_events(struct SoundIoPrivate *si, bool wait) { + struct SoundIo *soundio = &si->pub; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; bool change = false; bool cb_shutdown = false; - SoundIoDevicesInfo *old_devices_info = nullptr; + struct SoundIoDevicesInfo *old_devices_info = NULL; pa_threaded_mainloop_lock(sipa->main_loop); @@ -467,7 +471,7 @@ static void my_flush_events(SoundIoPrivate *si, bool wait) { } else if (sipa->ready_devices_info) { old_devices_info = si->safe_devices_info; si->safe_devices_info = sipa->ready_devices_info; - sipa->ready_devices_info = nullptr; + sipa->ready_devices_info = NULL; change = true; } @@ -481,25 +485,25 @@ static void my_flush_events(SoundIoPrivate *si, bool wait) { soundio_destroy_devices_info(old_devices_info); } -static void flush_events_pa(SoundIoPrivate *si) { +static void flush_events_pa(struct SoundIoPrivate *si) { my_flush_events(si, false); } -static void wait_events_pa(SoundIoPrivate *si) { +static void wait_events_pa(struct SoundIoPrivate *si) { my_flush_events(si, false); my_flush_events(si, true); } -static void wakeup_pa(SoundIoPrivate *si) { - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static void wakeup_pa(struct SoundIoPrivate *si) { + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; pa_threaded_mainloop_lock(sipa->main_loop); pa_threaded_mainloop_signal(sipa->main_loop, 0); pa_threaded_mainloop_unlock(sipa->main_loop); } -static void force_device_scan_pa(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static void force_device_scan_pa(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; pa_threaded_mainloop_lock(sipa->main_loop); sipa->device_scan_queued = true; pa_threaded_mainloop_signal(sipa->main_loop, 0); @@ -507,7 +511,7 @@ static void force_device_scan_pa(SoundIoPrivate *si) { pa_threaded_mainloop_unlock(sipa->main_loop); } -static pa_sample_format_t to_pulseaudio_format(SoundIoFormat format) { +static pa_sample_format_t to_pulseaudio_format(enum SoundIoFormat format) { switch (format) { case SoundIoFormatU8: return PA_SAMPLE_U8; case SoundIoFormatS16LE: return PA_SAMPLE_S16LE; @@ -534,7 +538,7 @@ static pa_sample_format_t to_pulseaudio_format(SoundIoFormat format) { return PA_SAMPLE_INVALID; } -static pa_channel_position_t to_pulseaudio_channel_pos(SoundIoChannelId channel_id) { +static pa_channel_position_t to_pulseaudio_channel_pos(enum SoundIoChannelId channel_id) { switch (channel_id) { case SoundIoChannelIdFrontLeft: return PA_CHANNEL_POSITION_FRONT_LEFT; case SoundIoChannelIdFrontRight: return PA_CHANNEL_POSITION_FRONT_RIGHT; @@ -577,7 +581,7 @@ static pa_channel_position_t to_pulseaudio_channel_pos(SoundIoChannelId channel_ } } -static pa_channel_map to_pulseaudio_channel_map(const SoundIoChannelLayout *channel_layout) { +static pa_channel_map to_pulseaudio_channel_map(const struct SoundIoChannelLayout *channel_layout) { pa_channel_map channel_map; channel_map.channels = channel_layout->channel_count; @@ -590,19 +594,19 @@ static pa_channel_map to_pulseaudio_channel_map(const SoundIoChannelLayout *chan } static void playback_stream_state_callback(pa_stream *stream, void *userdata) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate*) userdata; - SoundIoOutStream *outstream = &os->pub; - SoundIo *soundio = outstream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate*) userdata; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIo *soundio = outstream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; switch (pa_stream_get_state(stream)) { case PA_STREAM_UNCONNECTED: case PA_STREAM_CREATING: case PA_STREAM_TERMINATED: break; case PA_STREAM_READY: - ospa->stream_ready = true; + SOUNDIO_ATOMIC_STORE(ospa->stream_ready, true); pa_threaded_mainloop_signal(sipa->main_loop, 0); break; case PA_STREAM_FAILED: @@ -612,48 +616,48 @@ static void playback_stream_state_callback(pa_stream *stream, void *userdata) { } static void playback_stream_underflow_callback(pa_stream *stream, void *userdata) { - SoundIoOutStream *outstream = (SoundIoOutStream*)userdata; + struct SoundIoOutStream *outstream = (struct SoundIoOutStream*)userdata; outstream->underflow_callback(outstream); } static void playback_stream_write_callback(pa_stream *stream, size_t nbytes, void *userdata) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate*)(userdata); - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate*)(userdata); + struct SoundIoOutStream *outstream = &os->pub; int frame_count = nbytes / outstream->bytes_per_frame; outstream->write_callback(outstream, 0, frame_count); } -static void outstream_destroy_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; +static void outstream_destroy_pa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; pa_stream *stream = ospa->stream; if (stream) { pa_threaded_mainloop_lock(sipa->main_loop); - pa_stream_set_write_callback(stream, nullptr, nullptr); - pa_stream_set_state_callback(stream, nullptr, nullptr); - pa_stream_set_underflow_callback(stream, nullptr, nullptr); - pa_stream_set_overflow_callback(stream, nullptr, nullptr); + pa_stream_set_write_callback(stream, NULL, NULL); + pa_stream_set_state_callback(stream, NULL, NULL); + pa_stream_set_underflow_callback(stream, NULL, NULL); + pa_stream_set_overflow_callback(stream, NULL, NULL); pa_stream_disconnect(stream); pa_stream_unref(stream); pa_threaded_mainloop_unlock(sipa->main_loop); - ospa->stream = nullptr; + ospa->stream = NULL; } } static void timing_update_callback(pa_stream *stream, int success, void *userdata) { - SoundIoPrivate *si = (SoundIoPrivate *)userdata; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)userdata; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; pa_threaded_mainloop_signal(sipa->main_loop, 0); } -static int outstream_open_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; - SoundIoOutStream *outstream = &os->pub; +static int outstream_open_pa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; + struct SoundIoOutStream *outstream = &os->pub; if ((unsigned)outstream->layout.channel_count > PA_CHANNELS_MAX) return SoundIoErrorIncompatibleBackend; @@ -661,9 +665,9 @@ static int outstream_open_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { if (!outstream->name) outstream->name = "SoundIoOutStream"; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; - ospa->stream_ready.store(false); - ospa->clear_buffer_flag.test_and_set(); + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + SOUNDIO_ATOMIC_STORE(ospa->stream_ready, false); + atomic_flag_test_and_set(&ospa->clear_buffer_flag); assert(sipa->pulse_context); @@ -704,13 +708,13 @@ static int outstream_open_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { int err = pa_stream_connect_playback(ospa->stream, outstream->device->id, &ospa->buffer_attr, - flags, nullptr, nullptr); + flags, NULL, NULL); if (err) { pa_threaded_mainloop_unlock(sipa->main_loop); return SoundIoErrorOpeningDevice; } - while (!ospa->stream_ready.load()) + while (!SOUNDIO_ATOMIC_LOAD(ospa->stream_ready)) pa_threaded_mainloop_wait(sipa->main_loop); pa_operation *update_timing_info_op = pa_stream_update_timing_info(ospa->stream, timing_update_callback, si); @@ -727,10 +731,10 @@ static int outstream_open_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { return 0; } -static int outstream_start_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStream *outstream = &os->pub; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; +static int outstream_start_pa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; pa_threaded_mainloop_lock(sipa->main_loop); @@ -738,7 +742,7 @@ static int outstream_start_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { int frame_count = ospa->write_byte_count / outstream->bytes_per_frame; outstream->write_callback(outstream, 0, frame_count); - pa_operation *op = pa_stream_cork(ospa->stream, false, nullptr, nullptr); + pa_operation *op = pa_stream_cork(ospa->stream, false, NULL, NULL); if (!op) { pa_threaded_mainloop_unlock(sipa->main_loop); return SoundIoErrorStreaming; @@ -753,11 +757,11 @@ static int outstream_start_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { return 0; } -static int outstream_begin_write_pa(SoundIoPrivate *si, - SoundIoOutStreamPrivate *os, SoundIoChannelArea **out_areas, int *frame_count) +static int outstream_begin_write_pa(struct SoundIoPrivate *si, + struct SoundIoOutStreamPrivate *os, struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; pa_stream *stream = ospa->stream; ospa->write_byte_count = *frame_count * outstream->bytes_per_frame; @@ -775,28 +779,28 @@ static int outstream_begin_write_pa(SoundIoPrivate *si, return 0; } -static int outstream_end_write_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; +static int outstream_end_write_pa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; pa_stream *stream = ospa->stream; - pa_seek_mode_t seek_mode = ospa->clear_buffer_flag.test_and_set() ? PA_SEEK_RELATIVE : PA_SEEK_RELATIVE_ON_READ; - if (pa_stream_write(stream, ospa->write_ptr, ospa->write_byte_count, nullptr, 0, seek_mode)) + pa_seek_mode_t seek_mode = atomic_flag_test_and_set(&ospa->clear_buffer_flag) ? PA_SEEK_RELATIVE : PA_SEEK_RELATIVE_ON_READ; + if (pa_stream_write(stream, ospa->write_ptr, ospa->write_byte_count, NULL, 0, seek_mode)) return SoundIoErrorStreaming; return 0; } -static int outstream_clear_buffer_pa(SoundIoPrivate *si, - SoundIoOutStreamPrivate *os) +static int outstream_clear_buffer_pa(struct SoundIoPrivate *si, + struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; - ospa->clear_buffer_flag.clear(); + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; + atomic_flag_clear(&ospa->clear_buffer_flag); return 0; } -static int outstream_pause_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, bool pause) { - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static int outstream_pause_pa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) { + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; if (!pa_threaded_mainloop_in_thread(sipa->main_loop)) { pa_threaded_mainloop_lock(sipa->main_loop); @@ -818,8 +822,8 @@ static int outstream_pause_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, b return 0; } -static int outstream_get_latency_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate *os, double *out_latency) { - SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; +static int outstream_get_latency_pa(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, double *out_latency) { + struct SoundIoOutStreamPulseAudio *ospa = &os->backend_data.pulseaudio; int err; pa_usec_t r_usec; @@ -832,19 +836,19 @@ static int outstream_get_latency_pa(SoundIoPrivate *si, SoundIoOutStreamPrivate } static void recording_stream_state_callback(pa_stream *stream, void *userdata) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate*)userdata; - SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; - SoundIoInStream *instream = &is->pub; - SoundIo *soundio = instream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate*)userdata; + struct SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; + struct SoundIoInStream *instream = &is->pub; + struct SoundIo *soundio = instream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; switch (pa_stream_get_state(stream)) { case PA_STREAM_UNCONNECTED: case PA_STREAM_CREATING: case PA_STREAM_TERMINATED: break; case PA_STREAM_READY: - ispa->stream_ready = true; + SOUNDIO_ATOMIC_STORE(ispa->stream_ready, true); pa_threaded_mainloop_signal(sipa->main_loop, 0); break; case PA_STREAM_FAILED: @@ -854,43 +858,43 @@ static void recording_stream_state_callback(pa_stream *stream, void *userdata) { } static void recording_stream_read_callback(pa_stream *stream, size_t nbytes, void *userdata) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate*)userdata; - SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate*)userdata; + struct SoundIoInStream *instream = &is->pub; assert(nbytes % instream->bytes_per_frame == 0); assert(nbytes > 0); int available_frame_count = nbytes / instream->bytes_per_frame; instream->read_callback(instream, 0, available_frame_count); } -static void instream_destroy_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static void instream_destroy_pa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; pa_stream *stream = ispa->stream; if (stream) { pa_threaded_mainloop_lock(sipa->main_loop); - pa_stream_set_state_callback(stream, nullptr, nullptr); - pa_stream_set_read_callback(stream, nullptr, nullptr); + pa_stream_set_state_callback(stream, NULL, NULL); + pa_stream_set_read_callback(stream, NULL, NULL); pa_stream_disconnect(stream); pa_stream_unref(stream); pa_threaded_mainloop_unlock(sipa->main_loop); - ispa->stream = nullptr; + ispa->stream = NULL; } } -static int instream_open_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; - SoundIoInStream *instream = &is->pub; +static int instream_open_pa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; + struct SoundIoInStream *instream = &is->pub; if ((unsigned)instream->layout.channel_count > PA_CHANNELS_MAX) return SoundIoErrorIncompatibleBackend; if (!instream->name) instream->name = "SoundIoInStream"; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; - ispa->stream_ready = false; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; + SOUNDIO_ATOMIC_STORE(ispa->stream_ready, false); pa_threaded_mainloop_lock(sipa->main_loop); @@ -931,10 +935,10 @@ static int instream_open_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { return 0; } -static int instream_start_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static int instream_start_pa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; pa_threaded_mainloop_lock(sipa->main_loop); pa_stream_flags_t flags = (pa_stream_flags_t)(PA_STREAM_AUTO_TIMING_UPDATE | PA_STREAM_INTERPOLATE_TIMING); @@ -947,7 +951,7 @@ static int instream_start_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { return SoundIoErrorOpeningDevice; } - while (!ispa->stream_ready) + while (!SOUNDIO_ATOMIC_LOAD(ispa->stream_ready)) pa_threaded_mainloop_wait(sipa->main_loop); pa_operation *update_timing_info_op = pa_stream_update_timing_info(ispa->stream, timing_update_callback, si); @@ -961,14 +965,14 @@ static int instream_start_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { return 0; } -static int instream_begin_read_pa(SoundIoPrivate *si, - SoundIoInStreamPrivate *is, SoundIoChannelArea **out_areas, int *frame_count) +static int instream_begin_read_pa(struct SoundIoPrivate *si, + struct SoundIoInStreamPrivate *is, struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; pa_stream *stream = ispa->stream; - assert(ispa->stream_ready); + assert(SOUNDIO_ATOMIC_LOAD(ispa->stream_ready)); if (!ispa->peek_buf) { if (pa_stream_peek(stream, (const void **)&ispa->peek_buf, &ispa->peek_buf_size)) @@ -980,12 +984,12 @@ static int instream_begin_read_pa(SoundIoPrivate *si, // hole if (!ispa->peek_buf) { *frame_count = ispa->peek_buf_frames_left; - *out_areas = nullptr; + *out_areas = NULL; return 0; } } - ispa->read_frame_count = min(*frame_count, ispa->peek_buf_frames_left); + ispa->read_frame_count = soundio_int_min(*frame_count, ispa->peek_buf_frames_left); *frame_count = ispa->read_frame_count; for (int ch = 0; ch < instream->layout.channel_count; ch += 1) { ispa->areas[ch].ptr = ispa->peek_buf + ispa->peek_buf_index + instream->bytes_per_sample * ch; @@ -997,9 +1001,9 @@ static int instream_begin_read_pa(SoundIoPrivate *si, return 0; } -static int instream_end_read_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; +static int instream_end_read_pa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; pa_stream *stream = ispa->stream; // hole @@ -1016,15 +1020,15 @@ static int instream_end_read_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) if (ispa->peek_buf_index >= ispa->peek_buf_size) { if (pa_stream_drop(stream)) return SoundIoErrorStreaming; - ispa->peek_buf = nullptr; + ispa->peek_buf = NULL; } return 0; } -static int instream_pause_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is, bool pause) { - SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +static int instream_pause_pa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) { + struct SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; if (!pa_threaded_mainloop_in_thread(sipa->main_loop)) { pa_threaded_mainloop_lock(sipa->main_loop); @@ -1044,8 +1048,8 @@ static int instream_pause_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is, boo return 0; } -static int instream_get_latency_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *is, double *out_latency) { - SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; +static int instream_get_latency_pa(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, double *out_latency) { + struct SoundIoInStreamPulseAudio *ispa = &is->backend_data.pulseaudio; int err; pa_usec_t r_usec; @@ -1057,9 +1061,9 @@ static int instream_get_latency_pa(SoundIoPrivate *si, SoundIoInStreamPrivate *i return 0; } -int soundio_pulseaudio_init(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; +int soundio_pulseaudio_init(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoPulseAudio *sipa = &si->backend_data.pulseaudio; sipa->device_scan_queued = true; diff --git a/src/pulseaudio.hpp b/src/pulseaudio.h similarity index 74% rename from src/pulseaudio.hpp rename to src/pulseaudio.h index b400452..7feff6c 100644 --- a/src/pulseaudio.hpp +++ b/src/pulseaudio.h @@ -5,17 +5,18 @@ * See http://opensource.org/licenses/MIT */ -#ifndef SOUNDIO_PULSEAUDIO_HPP -#define SOUNDIO_PULSEAUDIO_HPP +#ifndef SOUNDIO_PULSEAUDIO_H +#define SOUNDIO_PULSEAUDIO_H -#include "soundio_private.h" -#include "atomics.hpp" +#include "soundio_internal.h" +#include "atomics.h" #include +struct SoundIoPrivate; int soundio_pulseaudio_init(struct SoundIoPrivate *si); -struct SoundIoDevicePulseAudio { }; +struct SoundIoDevicePulseAudio { int make_the_struct_not_empty; }; struct SoundIoPulseAudio { int device_query_err; @@ -41,24 +42,24 @@ struct SoundIoPulseAudio { struct SoundIoOutStreamPulseAudio { pa_stream *stream; - atomic_bool stream_ready; + struct SoundIoAtomicBool stream_ready; pa_buffer_attr buffer_attr; char *write_ptr; size_t write_byte_count; atomic_flag clear_buffer_flag; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; struct SoundIoInStreamPulseAudio { pa_stream *stream; - atomic_bool stream_ready; + struct SoundIoAtomicBool stream_ready; pa_buffer_attr buffer_attr; char *peek_buf; size_t peek_buf_index; size_t peek_buf_size; int peek_buf_frames_left; int read_frame_count; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; #endif diff --git a/src/ring_buffer.cpp b/src/ring_buffer.c similarity index 64% rename from src/ring_buffer.cpp rename to src/ring_buffer.c index 4d5859a..969bb41 100644 --- a/src/ring_buffer.cpp +++ b/src/ring_buffer.c @@ -5,25 +5,25 @@ * See http://opensource.org/licenses/MIT */ -#include "ring_buffer.hpp" -#include "soundio.hpp" -#include "util.hpp" +#include "ring_buffer.h" +#include "soundio_private.h" +#include "util.h" #include struct SoundIoRingBuffer *soundio_ring_buffer_create(struct SoundIo *soundio, int requested_capacity) { - SoundIoRingBuffer *rb = allocate(1); + struct SoundIoRingBuffer *rb = ALLOCATE(struct SoundIoRingBuffer, 1); assert(requested_capacity > 0); if (!rb) { soundio_ring_buffer_destroy(rb); - return nullptr; + return NULL; } if (soundio_ring_buffer_init(rb, requested_capacity)) { soundio_ring_buffer_destroy(rb); - return nullptr; + return NULL; } return rb; @@ -43,25 +43,31 @@ int soundio_ring_buffer_capacity(struct SoundIoRingBuffer *rb) { } char *soundio_ring_buffer_write_ptr(struct SoundIoRingBuffer *rb) { - return rb->mem.address + (rb->write_offset % rb->capacity); + long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset); + return rb->mem.address + (write_offset % rb->capacity); } void soundio_ring_buffer_advance_write_ptr(struct SoundIoRingBuffer *rb, int count) { - rb->write_offset += count; + SOUNDIO_ATOMIC_FETCH_ADD(rb->write_offset, count); assert(soundio_ring_buffer_fill_count(rb) >= 0); } char *soundio_ring_buffer_read_ptr(struct SoundIoRingBuffer *rb) { - return rb->mem.address + (rb->read_offset % rb->capacity); + long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); + return rb->mem.address + (read_offset % rb->capacity); } void soundio_ring_buffer_advance_read_ptr(struct SoundIoRingBuffer *rb, int count) { - rb->read_offset += count; + SOUNDIO_ATOMIC_FETCH_ADD(rb->read_offset, count); assert(soundio_ring_buffer_fill_count(rb) >= 0); } int soundio_ring_buffer_fill_count(struct SoundIoRingBuffer *rb) { - int count = rb->write_offset - rb->read_offset; + // Whichever offset we load first might have a smaller value. So we load + // the read_offset first. + long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); + long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset); + int count = write_offset - read_offset; assert(count >= 0); assert(count <= rb->capacity); return count; @@ -72,15 +78,16 @@ int soundio_ring_buffer_free_count(struct SoundIoRingBuffer *rb) { } void soundio_ring_buffer_clear(struct SoundIoRingBuffer *rb) { - return rb->write_offset.store(rb->read_offset.load()); + long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); + SOUNDIO_ATOMIC_STORE(rb->write_offset, read_offset); } int soundio_ring_buffer_init(struct SoundIoRingBuffer *rb, int requested_capacity) { int err; if ((err = soundio_os_init_mirrored_memory(&rb->mem, requested_capacity))) return err; - rb->write_offset = 0; - rb->read_offset = 0; + SOUNDIO_ATOMIC_STORE(rb->write_offset, 0); + SOUNDIO_ATOMIC_STORE(rb->read_offset, 0); rb->capacity = rb->mem.capacity; return 0; diff --git a/src/ring_buffer.hpp b/src/ring_buffer.h similarity index 64% rename from src/ring_buffer.hpp rename to src/ring_buffer.h index a34a322..c230292 100644 --- a/src/ring_buffer.hpp +++ b/src/ring_buffer.h @@ -5,16 +5,16 @@ * See http://opensource.org/licenses/MIT */ -#ifndef SOUNDIO_RING_BUFFER_HPP -#define SOUNDIO_RING_BUFFER_HPP +#ifndef SOUNDIO_RING_BUFFER_H +#define SOUNDIO_RING_BUFFER_H -#include "atomics.hpp" #include "os.h" +#include "atomics.h" struct SoundIoRingBuffer { - SoundIoOsMirroredMemory mem; - atomic_long write_offset; - atomic_long read_offset; + struct SoundIoOsMirroredMemory mem; + struct SoundIoAtomicLong write_offset; + struct SoundIoAtomicLong read_offset; int capacity; }; diff --git a/src/soundio.cpp b/src/soundio.c similarity index 69% rename from src/soundio.cpp rename to src/soundio.c index d6c017a..e01b78e 100644 --- a/src/soundio.cpp +++ b/src/soundio.c @@ -5,8 +5,8 @@ * See http://opensource.org/licenses/MIT */ -#include "soundio.hpp" -#include "util.hpp" +#include "soundio_private.h" +#include "util.h" #include "os.h" #include "config.h" @@ -14,7 +14,7 @@ #include #include -static const SoundIoBackend available_backends[] = { +static const enum SoundIoBackend available_backends[] = { #ifdef SOUNDIO_HAVE_JACK SoundIoBackendJack, #endif @@ -33,36 +33,40 @@ static const SoundIoBackend available_backends[] = { SoundIoBackendDummy, }; -static int (*backend_init_fns[])(SoundIoPrivate *) = { - [SoundIoBackendNone] = nullptr, +static int (*backend_init_fns[])(struct SoundIoPrivate *) = { + [SoundIoBackendNone] = NULL, #ifdef SOUNDIO_HAVE_JACK [SoundIoBackendJack] = soundio_jack_init, #else - [SoundIoBackendJack] = nullptr, + [SoundIoBackendJack] = NULL, #endif #ifdef SOUNDIO_HAVE_PULSEAUDIO [SoundIoBackendPulseAudio] = soundio_pulseaudio_init, #else - [SoundIoBackendPulseAudio] = nullptr, + [SoundIoBackendPulseAudio] = NULL, #endif #ifdef SOUNDIO_HAVE_ALSA [SoundIoBackendAlsa] = soundio_alsa_init, #else - [SoundIoBackendAlsa] = nullptr, + [SoundIoBackendAlsa] = NULL, #endif #ifdef SOUNDIO_HAVE_COREAUDIO [SoundIoBackendCoreAudio] = soundio_coreaudio_init, #else - [SoundIoBackendCoreAudio] = nullptr, + [SoundIoBackendCoreAudio] = NULL, #endif #ifdef SOUNDIO_HAVE_WASAPI [SoundIoBackendWasapi] = soundio_wasapi_init, #else - [SoundIoBackendWasapi] = nullptr, + [SoundIoBackendWasapi] = NULL, #endif [SoundIoBackendDummy] = soundio_dummy_init, }; + +SOUNDIO_MAKE_LIST_DEF(struct SoundIoDevice*, SoundIoListDevicePtr, SOUNDIO_LIST_NOT_STATIC) +SOUNDIO_MAKE_LIST_DEF(struct SoundIoSampleRateRange, SoundIoListSampleRateRange, SOUNDIO_LIST_NOT_STATIC) + const char *soundio_strerror(int error) { switch ((enum SoundIoError)error) { case SoundIoErrorNone: return "(no error)"; @@ -153,23 +157,23 @@ const char *soundio_backend_name(enum SoundIoBackend backend) { } void soundio_destroy(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; soundio_disconnect(soundio); free(si); } -static void do_nothing_cb(struct SoundIo *) { } +static void do_nothing_cb(struct SoundIo *soundio) { } static void default_msg_callback(const char *msg) { } -static void default_backend_disconnect_cb(struct SoundIo *, int err) { +static void default_backend_disconnect_cb(struct SoundIo *soundio, int err) { soundio_panic("libsoundio: backend disconnected: %s", soundio_strerror(err)); } static atomic_flag rtprio_seen = ATOMIC_FLAG_INIT; static void default_emit_rtprio_warning(void) { - if (!rtprio_seen.test_and_set()) { + if (!atomic_flag_test_and_set(&rtprio_seen)) { fprintf(stderr, "warning: unable to set high priority thread: Operation not permitted\n"); fprintf(stderr, "See " "https://github.com/andrewrk/genesis/wiki/warning:-unable-to-set-high-priority-thread:-Operation-not-permitted\n"); @@ -179,11 +183,11 @@ static void default_emit_rtprio_warning(void) { struct SoundIo *soundio_create(void) { int err; if ((err = soundio_os_init())) - return nullptr; - struct SoundIoPrivate *si = allocate(1); + return NULL; + struct SoundIoPrivate *si = ALLOCATE(struct SoundIoPrivate, 1); if (!si) - return nullptr; - SoundIo *soundio = &si->pub; + return NULL; + struct SoundIo *soundio = &si->pub; soundio->on_devices_change = do_nothing_cb; soundio->on_backend_disconnect = default_backend_disconnect_cb; soundio->on_events_signal = do_nothing_cb; @@ -197,8 +201,8 @@ struct SoundIo *soundio_create(void) { int soundio_connect(struct SoundIo *soundio) { int err = 0; - for (int i = 0; i < array_length(available_backends); i += 1) { - SoundIoBackend backend = available_backends[i]; + for (int i = 0; i < ARRAY_LENGTH(available_backends); i += 1) { + enum SoundIoBackend backend = available_backends[i]; err = soundio_connect_backend(soundio, backend); if (!err) return 0; @@ -209,8 +213,8 @@ int soundio_connect(struct SoundIo *soundio) { return err; } -int soundio_connect_backend(SoundIo *soundio, SoundIoBackend backend) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; +int soundio_connect_backend(struct SoundIo *soundio, enum SoundIoBackend backend) { + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; if (soundio->current_backend) return SoundIoErrorInvalid; @@ -218,7 +222,7 @@ int soundio_connect_backend(SoundIo *soundio, SoundIoBackend backend) { if (backend <= 0 || backend > SoundIoBackendDummy) return SoundIoErrorInvalid; - int (*fn)(SoundIoPrivate *) = backend_init_fns[backend]; + int (*fn)(struct SoundIoPrivate *) = backend_init_fns[backend]; if (!fn) return SoundIoErrorBackendUnavailable; @@ -234,52 +238,52 @@ int soundio_connect_backend(SoundIo *soundio, SoundIoBackend backend) { } void soundio_disconnect(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; if (!si) return; if (si->destroy) si->destroy(si); - memset(&si->backend_data, 0, sizeof(SoundIoBackendData)); + memset(&si->backend_data, 0, sizeof(union SoundIoBackendData)); soundio->current_backend = SoundIoBackendNone; soundio_destroy_devices_info(si->safe_devices_info); - si->safe_devices_info = nullptr; + si->safe_devices_info = NULL; - si->destroy = nullptr; - si->flush_events = nullptr; - si->wait_events = nullptr; - si->wakeup = nullptr; - si->force_device_scan = nullptr; + si->destroy = NULL; + si->flush_events = NULL; + si->wait_events = NULL; + si->wakeup = NULL; + si->force_device_scan = NULL; - si->outstream_open = nullptr; - si->outstream_destroy = nullptr; - si->outstream_start = nullptr; - si->outstream_begin_write = nullptr; - si->outstream_end_write = nullptr; - si->outstream_clear_buffer = nullptr; - si->outstream_pause = nullptr; - si->outstream_get_latency = nullptr; + si->outstream_open = NULL; + si->outstream_destroy = NULL; + si->outstream_start = NULL; + si->outstream_begin_write = NULL; + si->outstream_end_write = NULL; + si->outstream_clear_buffer = NULL; + si->outstream_pause = NULL; + si->outstream_get_latency = NULL; - si->instream_open = nullptr; - si->instream_destroy = nullptr; - si->instream_start = nullptr; - si->instream_begin_read = nullptr; - si->instream_end_read = nullptr; - si->instream_pause = nullptr; - si->instream_get_latency = nullptr; + si->instream_open = NULL; + si->instream_destroy = NULL; + si->instream_start = NULL; + si->instream_begin_read = NULL; + si->instream_end_read = NULL; + si->instream_pause = NULL; + si->instream_get_latency = NULL; } void soundio_flush_events(struct SoundIo *soundio) { assert(soundio->current_backend != SoundIoBackendNone); - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; si->flush_events(si); } int soundio_input_device_count(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; assert(si->safe_devices_info); if (!si->safe_devices_info) @@ -293,7 +297,7 @@ int soundio_input_device_count(struct SoundIo *soundio) { } int soundio_output_device_count(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; assert(si->safe_devices_info); if (!si->safe_devices_info) @@ -307,7 +311,7 @@ int soundio_output_device_count(struct SoundIo *soundio) { } int soundio_default_input_device_index(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; assert(si->safe_devices_info); if (!si->safe_devices_info) @@ -321,7 +325,7 @@ int soundio_default_input_device_index(struct SoundIo *soundio) { } int soundio_default_output_device_index(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; assert(si->safe_devices_info); if (!si->safe_devices_info) @@ -335,43 +339,43 @@ int soundio_default_output_device_index(struct SoundIo *soundio) { } struct SoundIoDevice *soundio_get_input_device(struct SoundIo *soundio, int index) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; assert(soundio->current_backend != SoundIoBackendNone); if (soundio->current_backend == SoundIoBackendNone) - return nullptr; + return NULL; assert(si->safe_devices_info); if (!si->safe_devices_info) - return nullptr; + return NULL; assert(index >= 0); assert(index < si->safe_devices_info->input_devices.length); if (index < 0 || index >= si->safe_devices_info->input_devices.length) - return nullptr; + return NULL; - SoundIoDevice *device = si->safe_devices_info->input_devices.at(index); + struct SoundIoDevice *device = SoundIoListDevicePtr_val_at(&si->safe_devices_info->input_devices, index); soundio_device_ref(device); return device; } struct SoundIoDevice *soundio_get_output_device(struct SoundIo *soundio, int index) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; assert(soundio->current_backend != SoundIoBackendNone); if (soundio->current_backend == SoundIoBackendNone) - return nullptr; + return NULL; assert(si->safe_devices_info); if (!si->safe_devices_info) - return nullptr; + return NULL; assert(index >= 0); assert(index < si->safe_devices_info->output_devices.length); if (index < 0 || index >= si->safe_devices_info->output_devices.length) - return nullptr; + return NULL; - SoundIoDevice *device = si->safe_devices_info->output_devices.at(index); + struct SoundIoDevice *device = SoundIoListDevicePtr_val_at(&si->safe_devices_info->output_devices, index); soundio_device_ref(device); return device; } @@ -384,7 +388,7 @@ void soundio_device_unref(struct SoundIoDevice *device) { assert(device->ref_count >= 0); if (device->ref_count == 0) { - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; if (dev->destruct) dev->destruct(dev); @@ -396,7 +400,7 @@ void soundio_device_unref(struct SoundIoDevice *device) { { free(device->sample_rates); } - dev->sample_rates.deinit(); + SoundIoListSampleRateRange_deinit(&dev->sample_rates); if (device->formats != &dev->prealloc_format) free(device->formats); @@ -414,35 +418,35 @@ void soundio_device_ref(struct SoundIoDevice *device) { } void soundio_wait_events(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; si->wait_events(si); } void soundio_wakeup(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; si->wakeup(si); } void soundio_force_device_scan(struct SoundIo *soundio) { - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; si->force_device_scan(si); } int soundio_outstream_begin_write(struct SoundIoOutStream *outstream, - SoundIoChannelArea **areas, int *frame_count) + struct SoundIoChannelArea **areas, int *frame_count) { - SoundIo *soundio = outstream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream; + struct SoundIo *soundio = outstream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; if (*frame_count <= 0) return SoundIoErrorInvalid; return si->outstream_begin_write(si, os, areas, frame_count); } int soundio_outstream_end_write(struct SoundIoOutStream *outstream) { - SoundIo *soundio = outstream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream; + struct SoundIo *soundio = outstream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; return si->outstream_end_write(si, os); } @@ -453,13 +457,13 @@ static void default_outstream_error_callback(struct SoundIoOutStream *os, int er static void default_underflow_callback(struct SoundIoOutStream *outstream) { } struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device) { - SoundIoOutStreamPrivate *os = allocate(1); - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamPrivate *os = ALLOCATE(struct SoundIoOutStreamPrivate, 1); + struct SoundIoOutStream *outstream = &os->pub; if (!os) - return nullptr; + return NULL; if (!device) - return nullptr; + return NULL; outstream->device = device; soundio_device_ref(device); @@ -471,7 +475,7 @@ struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device) } int soundio_outstream_open(struct SoundIoOutStream *outstream) { - SoundIoDevice *device = outstream->device; + struct SoundIoDevice *device = outstream->device; if (device->aim != SoundIoDeviceAimOutput) return SoundIoErrorInvalid; @@ -491,29 +495,29 @@ int soundio_outstream_open(struct SoundIoOutStream *outstream) { return SoundIoErrorInvalid; if (!outstream->layout.channel_count) { - const SoundIoChannelLayout *stereo = soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdStereo); + const struct SoundIoChannelLayout *stereo = soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdStereo); outstream->layout = soundio_device_supports_layout(device, stereo) ? *stereo : device->layouts[0]; } if (!outstream->sample_rate) outstream->sample_rate = soundio_device_nearest_sample_rate(device, 48000); - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; outstream->bytes_per_frame = soundio_get_bytes_per_frame(outstream->format, outstream->layout.channel_count); outstream->bytes_per_sample = soundio_get_bytes_per_sample(outstream->format); - SoundIo *soundio = device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIo *soundio = device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; return si->outstream_open(si, os); } -void soundio_outstream_destroy(SoundIoOutStream *outstream) { +void soundio_outstream_destroy(struct SoundIoOutStream *outstream) { if (!outstream) return; - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream; - SoundIo *soundio = outstream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; + struct SoundIo *soundio = outstream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; if (si->outstream_destroy) si->outstream_destroy(si, os); @@ -523,30 +527,30 @@ void soundio_outstream_destroy(SoundIoOutStream *outstream) { } int soundio_outstream_start(struct SoundIoOutStream *outstream) { - SoundIo *soundio = outstream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream; + struct SoundIo *soundio = outstream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; return si->outstream_start(si, os); } int soundio_outstream_pause(struct SoundIoOutStream *outstream, bool pause) { - SoundIo *soundio = outstream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream; + struct SoundIo *soundio = outstream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; return si->outstream_pause(si, os, pause); } int soundio_outstream_clear_buffer(struct SoundIoOutStream *outstream) { - SoundIo *soundio = outstream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream; + struct SoundIo *soundio = outstream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; return si->outstream_clear_buffer(si, os); } int soundio_outstream_get_latency(struct SoundIoOutStream *outstream, double *out_latency) { - SoundIo *soundio = outstream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)outstream; + struct SoundIo *soundio = outstream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)outstream; return si->outstream_get_latency(si, os, out_latency); } @@ -557,13 +561,13 @@ static void default_instream_error_callback(struct SoundIoInStream *is, int err) static void default_overflow_callback(struct SoundIoInStream *instream) { } struct SoundIoInStream *soundio_instream_create(struct SoundIoDevice *device) { - SoundIoInStreamPrivate *is = allocate(1); - SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamPrivate *is = ALLOCATE(struct SoundIoInStreamPrivate, 1); + struct SoundIoInStream *instream = &is->pub; if (!is) - return nullptr; + return NULL; if (!device) - return nullptr; + return NULL; instream->device = device; soundio_device_ref(device); @@ -575,7 +579,7 @@ struct SoundIoInStream *soundio_instream_create(struct SoundIoDevice *device) { } int soundio_instream_open(struct SoundIoInStream *instream) { - SoundIoDevice *device = instream->device; + struct SoundIoDevice *device = instream->device; if (device->aim != SoundIoDeviceAimInput) return SoundIoErrorInvalid; @@ -594,7 +598,7 @@ int soundio_instream_open(struct SoundIoInStream *instream) { } if (!instream->layout.channel_count) { - const SoundIoChannelLayout *stereo = soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdStereo); + const struct SoundIoChannelLayout *stereo = soundio_channel_layout_get_builtin(SoundIoChannelLayoutIdStereo); instream->layout = soundio_device_supports_layout(device, stereo) ? *stereo : device->layouts[0]; } @@ -604,16 +608,16 @@ int soundio_instream_open(struct SoundIoInStream *instream) { instream->bytes_per_frame = soundio_get_bytes_per_frame(instream->format, instream->layout.channel_count); instream->bytes_per_sample = soundio_get_bytes_per_sample(instream->format); - SoundIo *soundio = device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)instream; + struct SoundIo *soundio = device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)instream; return si->instream_open(si, is); } int soundio_instream_start(struct SoundIoInStream *instream) { - SoundIo *soundio = instream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)instream; + struct SoundIo *soundio = instream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)instream; return si->instream_start(si, is); } @@ -621,9 +625,9 @@ void soundio_instream_destroy(struct SoundIoInStream *instream) { if (!instream) return; - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)instream; - SoundIo *soundio = instream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)instream; + struct SoundIo *soundio = instream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; if (si->instream_destroy) si->instream_destroy(si, is); @@ -633,69 +637,69 @@ void soundio_instream_destroy(struct SoundIoInStream *instream) { } int soundio_instream_pause(struct SoundIoInStream *instream, bool pause) { - SoundIo *soundio = instream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)instream; + struct SoundIo *soundio = instream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)instream; return si->instream_pause(si, is, pause); } int soundio_instream_begin_read(struct SoundIoInStream *instream, struct SoundIoChannelArea **areas, int *frame_count) { - SoundIo *soundio = instream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)instream; + struct SoundIo *soundio = instream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)instream; return si->instream_begin_read(si, is, areas, frame_count); } int soundio_instream_end_read(struct SoundIoInStream *instream) { - SoundIo *soundio = instream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)instream; + struct SoundIo *soundio = instream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)instream; return si->instream_end_read(si, is); } int soundio_instream_get_latency(struct SoundIoInStream *instream, double *out_latency) { - SoundIo *soundio = instream->device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)instream; + struct SoundIo *soundio = instream->device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)instream; return si->instream_get_latency(si, is, out_latency); } -void soundio_destroy_devices_info(SoundIoDevicesInfo *devices_info) { +void soundio_destroy_devices_info(struct SoundIoDevicesInfo *devices_info) { if (!devices_info) return; for (int i = 0; i < devices_info->input_devices.length; i += 1) - soundio_device_unref(devices_info->input_devices.at(i)); + soundio_device_unref(SoundIoListDevicePtr_val_at(&devices_info->input_devices, i)); for (int i = 0; i < devices_info->output_devices.length; i += 1) - soundio_device_unref(devices_info->output_devices.at(i)); + soundio_device_unref(SoundIoListDevicePtr_val_at(&devices_info->output_devices, i)); - devices_info->input_devices.deinit(); - devices_info->output_devices.deinit(); + SoundIoListDevicePtr_deinit(&devices_info->input_devices); + SoundIoListDevicePtr_deinit(&devices_info->output_devices); free(devices_info); } -bool soundio_have_backend(SoundIoBackend backend) { +bool soundio_have_backend(enum SoundIoBackend backend) { assert(backend > 0); assert(backend <= SoundIoBackendDummy); return backend_init_fns[backend]; } int soundio_backend_count(struct SoundIo *soundio) { - return array_length(available_backends); + return ARRAY_LENGTH(available_backends); } -SoundIoBackend soundio_get_backend(struct SoundIo *soundio, int index) { +enum SoundIoBackend soundio_get_backend(struct SoundIo *soundio, int index) { return available_backends[index]; } -static bool layout_contains(const SoundIoChannelLayout *available_layouts, int available_layouts_count, - const SoundIoChannelLayout *target_layout) +static bool layout_contains(const struct SoundIoChannelLayout *available_layouts, int available_layouts_count, + const struct SoundIoChannelLayout *target_layout) { for (int i = 0; i < available_layouts_count; i += 1) { - const SoundIoChannelLayout *available_layout = &available_layouts[i]; + const struct SoundIoChannelLayout *available_layout = &available_layouts[i]; if (soundio_channel_layout_equal(target_layout, available_layout)) return true; } @@ -707,16 +711,16 @@ const struct SoundIoChannelLayout *soundio_best_matching_channel_layout( const struct SoundIoChannelLayout *available_layouts, int available_layouts_count) { for (int i = 0; i < preferred_layouts_count; i += 1) { - const SoundIoChannelLayout *preferred_layout = &preferred_layouts[i]; + const struct SoundIoChannelLayout *preferred_layout = &preferred_layouts[i]; if (layout_contains(available_layouts, available_layouts_count, preferred_layout)) return preferred_layout; } - return nullptr; + return NULL; } static int compare_layouts(const void *a, const void *b) { - const SoundIoChannelLayout *layout_a = *((SoundIoChannelLayout **)a); - const SoundIoChannelLayout *layout_b = *((SoundIoChannelLayout **)b); + const struct SoundIoChannelLayout *layout_a = *((struct SoundIoChannelLayout **)a); + const struct SoundIoChannelLayout *layout_b = *((struct SoundIoChannelLayout **)b); if (layout_a->channel_count > layout_b->channel_count) return -1; else if (layout_a->channel_count < layout_b->channel_count) @@ -729,7 +733,7 @@ void soundio_sort_channel_layouts(struct SoundIoChannelLayout *layouts, int layo if (!layouts) return; - qsort(layouts, layouts_count, sizeof(SoundIoChannelLayout), compare_layouts); + qsort(layouts, layouts_count, sizeof(struct SoundIoChannelLayout), compare_layouts); } void soundio_device_sort_channel_layouts(struct SoundIoDevice *device) { @@ -756,7 +760,7 @@ bool soundio_device_supports_layout(struct SoundIoDevice *device, bool soundio_device_supports_sample_rate(struct SoundIoDevice *device, int sample_rate) { for (int i = 0; i < device->sample_rate_count; i += 1) { - SoundIoSampleRateRange *range = &device->sample_rates[i]; + struct SoundIoSampleRateRange *range = &device->sample_rates[i]; if (sample_rate >= range->min && sample_rate <= range->max) return true; } @@ -772,8 +776,8 @@ int soundio_device_nearest_sample_rate(struct SoundIoDevice *device, int sample_ int best_rate = -1; int best_delta = -1; for (int i = 0; i < device->sample_rate_count; i += 1) { - SoundIoSampleRateRange *range = &device->sample_rates[i]; - int candidate_rate = clamp(range->min, sample_rate, range->max); + struct SoundIoSampleRateRange *range = &device->sample_rates[i]; + int candidate_rate = soundio_int_clamp(range->min, sample_rate, range->max); if (candidate_rate == sample_rate) return candidate_rate; diff --git a/src/soundio.hpp b/src/soundio.hpp deleted file mode 100644 index 5751270..0000000 --- a/src/soundio.hpp +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2015 Andrew Kelley - * - * This file is part of libsoundio, which is MIT licensed. - * See http://opensource.org/licenses/MIT - */ - -#ifndef SOUNDIO_SOUNDIO_HPP -#define SOUNDIO_SOUNDIO_HPP - -#include "soundio_private.h" -#include "list.hpp" - -#ifdef SOUNDIO_HAVE_JACK -#include "jack.hpp" -#endif - -#ifdef SOUNDIO_HAVE_PULSEAUDIO -#include "pulseaudio.hpp" -#endif - -#ifdef SOUNDIO_HAVE_ALSA -#include "alsa.hpp" -#endif - -#ifdef SOUNDIO_HAVE_COREAUDIO -#include "coreaudio.hpp" -#endif - -#ifdef SOUNDIO_HAVE_WASAPI -#include "wasapi.hpp" -#endif - -#include "dummy.hpp" - -union SoundIoBackendData { -#ifdef SOUNDIO_HAVE_JACK - SoundIoJack jack; -#endif -#ifdef SOUNDIO_HAVE_PULSEAUDIO - SoundIoPulseAudio pulseaudio; -#endif -#ifdef SOUNDIO_HAVE_ALSA - SoundIoAlsa alsa; -#endif -#ifdef SOUNDIO_HAVE_COREAUDIO - SoundIoCoreAudio coreaudio; -#endif -#ifdef SOUNDIO_HAVE_WASAPI - SoundIoWasapi wasapi; -#endif - SoundIoDummy dummy; -}; - -union SoundIoDeviceBackendData { -#ifdef SOUNDIO_HAVE_JACK - SoundIoDeviceJack jack; -#endif -#ifdef SOUNDIO_HAVE_PULSEAUDIO - SoundIoDevicePulseAudio pulseaudio; -#endif -#ifdef SOUNDIO_HAVE_ALSA - SoundIoDeviceAlsa alsa; -#endif -#ifdef SOUNDIO_HAVE_COREAUDIO - SoundIoDeviceCoreAudio coreaudio; -#endif -#ifdef SOUNDIO_HAVE_WASAPI - SoundIoDeviceWasapi wasapi; -#endif - SoundIoDeviceDummy dummy; -}; - -union SoundIoOutStreamBackendData { -#ifdef SOUNDIO_HAVE_JACK - SoundIoOutStreamJack jack; -#endif -#ifdef SOUNDIO_HAVE_PULSEAUDIO - SoundIoOutStreamPulseAudio pulseaudio; -#endif -#ifdef SOUNDIO_HAVE_ALSA - SoundIoOutStreamAlsa alsa; -#endif -#ifdef SOUNDIO_HAVE_COREAUDIO - SoundIoOutStreamCoreAudio coreaudio; -#endif -#ifdef SOUNDIO_HAVE_WASAPI - SoundIoOutStreamWasapi wasapi; -#endif - SoundIoOutStreamDummy dummy; -}; - -union SoundIoInStreamBackendData { -#ifdef SOUNDIO_HAVE_JACK - SoundIoInStreamJack jack; -#endif -#ifdef SOUNDIO_HAVE_PULSEAUDIO - SoundIoInStreamPulseAudio pulseaudio; -#endif -#ifdef SOUNDIO_HAVE_ALSA - SoundIoInStreamAlsa alsa; -#endif -#ifdef SOUNDIO_HAVE_COREAUDIO - SoundIoInStreamCoreAudio coreaudio; -#endif -#ifdef SOUNDIO_HAVE_WASAPI - SoundIoInStreamWasapi wasapi; -#endif - SoundIoInStreamDummy dummy; -}; - -struct SoundIoDevicesInfo { - SoundIoList input_devices; - SoundIoList output_devices; - // can be -1 when default device is unknown - int default_output_index; - int default_input_index; -}; - -struct SoundIoOutStreamPrivate { - SoundIoOutStream pub; - SoundIoOutStreamBackendData backend_data; -}; - -struct SoundIoInStreamPrivate { - SoundIoInStream pub; - SoundIoInStreamBackendData backend_data; -}; - -struct SoundIoPrivate { - struct SoundIo pub; - - // Safe to read from a single thread without a mutex. - struct SoundIoDevicesInfo *safe_devices_info; - - void (*destroy)(struct SoundIoPrivate *); - void (*flush_events)(struct SoundIoPrivate *); - void (*wait_events)(struct SoundIoPrivate *); - void (*wakeup)(struct SoundIoPrivate *); - void (*force_device_scan)(struct SoundIoPrivate *); - - int (*outstream_open)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); - void (*outstream_destroy)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); - int (*outstream_start)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); - int (*outstream_begin_write)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, - SoundIoChannelArea **out_areas, int *out_frame_count); - int (*outstream_end_write)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); - int (*outstream_clear_buffer)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); - int (*outstream_pause)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, bool pause); - int (*outstream_get_latency)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, double *out_latency); - - - int (*instream_open)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *); - void (*instream_destroy)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *); - int (*instream_start)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *); - int (*instream_begin_read)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *, - SoundIoChannelArea **out_areas, int *out_frame_count); - int (*instream_end_read)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *); - int (*instream_pause)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *, bool pause); - int (*instream_get_latency)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *, double *out_latency); - - SoundIoBackendData backend_data; -}; - -struct SoundIoDevicePrivate { - SoundIoDevice pub; - SoundIoDeviceBackendData backend_data; - void (*destruct)(SoundIoDevicePrivate *); - SoundIoSampleRateRange prealloc_sample_rate_range; - SoundIoList sample_rates; - SoundIoFormat prealloc_format; -}; - -void soundio_destroy_devices_info(struct SoundIoDevicesInfo *devices_info); - -static const int SOUNDIO_MIN_SAMPLE_RATE = 8000; -static const int SOUNDIO_MAX_SAMPLE_RATE = 5644800; - -#endif diff --git a/src/soundio_internal.h b/src/soundio_internal.h new file mode 100644 index 0000000..0fbc3ed --- /dev/null +++ b/src/soundio_internal.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2015 Andrew Kelley + * + * This file is part of libsoundio, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef SOUNDIO_SOUNDIO_INTERNAL_H +#define SOUNDIO_SOUNDIO_INTERNAL_H + +// This exists for __declspec(dllexport) and __declspec(dllimport) to be +// defined correctly without the library user having to do anything. +#define SOUNDIO_BUILDING_LIBRARY +#include "soundio/soundio.h" + +#endif diff --git a/src/soundio_private.h b/src/soundio_private.h index 1016a15..ead582d 100644 --- a/src/soundio_private.h +++ b/src/soundio_private.h @@ -8,9 +8,177 @@ #ifndef SOUNDIO_SOUNDIO_PRIVATE_H #define SOUNDIO_SOUNDIO_PRIVATE_H -// This exists for __declspec(dllexport) and __declspec(dllimport) to be -// defined correctly without the library user having to do anything. -#define SOUNDIO_BUILDING_LIBRARY -#include "soundio/soundio.h" +#include "soundio_internal.h" + +#ifdef SOUNDIO_HAVE_JACK +#include "jack.h" +#endif + +#ifdef SOUNDIO_HAVE_PULSEAUDIO +#include "pulseaudio.h" +#endif + +#ifdef SOUNDIO_HAVE_ALSA +#include "alsa.h" +#endif + +#ifdef SOUNDIO_HAVE_COREAUDIO +#include "coreaudio.h" +#endif + +#ifdef SOUNDIO_HAVE_WASAPI +#include "wasapi.h" +#endif + +#include "dummy.h" + +union SoundIoBackendData { +#ifdef SOUNDIO_HAVE_JACK + struct SoundIoJack jack; +#endif +#ifdef SOUNDIO_HAVE_PULSEAUDIO + struct SoundIoPulseAudio pulseaudio; +#endif +#ifdef SOUNDIO_HAVE_ALSA + struct SoundIoAlsa alsa; +#endif +#ifdef SOUNDIO_HAVE_COREAUDIO + struct SoundIoCoreAudio coreaudio; +#endif +#ifdef SOUNDIO_HAVE_WASAPI + struct SoundIoWasapi wasapi; +#endif + struct SoundIoDummy dummy; +}; + +union SoundIoDeviceBackendData { +#ifdef SOUNDIO_HAVE_JACK + struct SoundIoDeviceJack jack; +#endif +#ifdef SOUNDIO_HAVE_PULSEAUDIO + struct SoundIoDevicePulseAudio pulseaudio; +#endif +#ifdef SOUNDIO_HAVE_ALSA + struct SoundIoDeviceAlsa alsa; +#endif +#ifdef SOUNDIO_HAVE_COREAUDIO + struct SoundIoDeviceCoreAudio coreaudio; +#endif +#ifdef SOUNDIO_HAVE_WASAPI + struct SoundIoDeviceWasapi wasapi; +#endif + struct SoundIoDeviceDummy dummy; +}; + +union SoundIoOutStreamBackendData { +#ifdef SOUNDIO_HAVE_JACK + struct SoundIoOutStreamJack jack; +#endif +#ifdef SOUNDIO_HAVE_PULSEAUDIO + struct SoundIoOutStreamPulseAudio pulseaudio; +#endif +#ifdef SOUNDIO_HAVE_ALSA + struct SoundIoOutStreamAlsa alsa; +#endif +#ifdef SOUNDIO_HAVE_COREAUDIO + struct SoundIoOutStreamCoreAudio coreaudio; +#endif +#ifdef SOUNDIO_HAVE_WASAPI + struct SoundIoOutStreamWasapi wasapi; +#endif + struct SoundIoOutStreamDummy dummy; +}; + +union SoundIoInStreamBackendData { +#ifdef SOUNDIO_HAVE_JACK + struct SoundIoInStreamJack jack; +#endif +#ifdef SOUNDIO_HAVE_PULSEAUDIO + struct SoundIoInStreamPulseAudio pulseaudio; +#endif +#ifdef SOUNDIO_HAVE_ALSA + struct SoundIoInStreamAlsa alsa; +#endif +#ifdef SOUNDIO_HAVE_COREAUDIO + struct SoundIoInStreamCoreAudio coreaudio; +#endif +#ifdef SOUNDIO_HAVE_WASAPI + struct SoundIoInStreamWasapi wasapi; +#endif + struct SoundIoInStreamDummy dummy; +}; + +SOUNDIO_MAKE_LIST_STRUCT(struct SoundIoDevice*, SoundIoListDevicePtr, SOUNDIO_LIST_NOT_STATIC) +SOUNDIO_MAKE_LIST_PROTO(struct SoundIoDevice*, SoundIoListDevicePtr, SOUNDIO_LIST_NOT_STATIC) + +struct SoundIoDevicesInfo { + struct SoundIoListDevicePtr input_devices; + struct SoundIoListDevicePtr output_devices; + // can be -1 when default device is unknown + int default_output_index; + int default_input_index; +}; + +struct SoundIoOutStreamPrivate { + struct SoundIoOutStream pub; + union SoundIoOutStreamBackendData backend_data; +}; + +struct SoundIoInStreamPrivate { + struct SoundIoInStream pub; + union SoundIoInStreamBackendData backend_data; +}; + +struct SoundIoPrivate { + struct SoundIo pub; + + // Safe to read from a single thread without a mutex. + struct SoundIoDevicesInfo *safe_devices_info; + + void (*destroy)(struct SoundIoPrivate *); + void (*flush_events)(struct SoundIoPrivate *); + void (*wait_events)(struct SoundIoPrivate *); + void (*wakeup)(struct SoundIoPrivate *); + void (*force_device_scan)(struct SoundIoPrivate *); + + int (*outstream_open)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); + void (*outstream_destroy)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); + int (*outstream_start)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); + int (*outstream_begin_write)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, + struct SoundIoChannelArea **out_areas, int *out_frame_count); + int (*outstream_end_write)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); + int (*outstream_clear_buffer)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *); + int (*outstream_pause)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, bool pause); + int (*outstream_get_latency)(struct SoundIoPrivate *, struct SoundIoOutStreamPrivate *, double *out_latency); + + + int (*instream_open)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *); + void (*instream_destroy)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *); + int (*instream_start)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *); + int (*instream_begin_read)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *, + struct SoundIoChannelArea **out_areas, int *out_frame_count); + int (*instream_end_read)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *); + int (*instream_pause)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *, bool pause); + int (*instream_get_latency)(struct SoundIoPrivate *, struct SoundIoInStreamPrivate *, double *out_latency); + + union SoundIoBackendData backend_data; +}; + +SOUNDIO_MAKE_LIST_STRUCT(struct SoundIoSampleRateRange, SoundIoListSampleRateRange, SOUNDIO_LIST_NOT_STATIC) +SOUNDIO_MAKE_LIST_PROTO(struct SoundIoSampleRateRange, SoundIoListSampleRateRange, SOUNDIO_LIST_NOT_STATIC) + +struct SoundIoDevicePrivate { + struct SoundIoDevice pub; + union SoundIoDeviceBackendData backend_data; + void (*destruct)(struct SoundIoDevicePrivate *); + struct SoundIoSampleRateRange prealloc_sample_rate_range; + struct SoundIoListSampleRateRange sample_rates; + enum SoundIoFormat prealloc_format; +}; + +void soundio_destroy_devices_info(struct SoundIoDevicesInfo *devices_info); + +static const int SOUNDIO_MIN_SAMPLE_RATE = 8000; +static const int SOUNDIO_MAX_SAMPLE_RATE = 5644800; #endif diff --git a/src/util.cpp b/src/util.c similarity index 84% rename from src/util.cpp rename to src/util.c index 4dbdab0..7d0b4c1 100644 --- a/src/util.cpp +++ b/src/util.c @@ -9,7 +9,7 @@ #include #include -#include "util.hpp" +#include "util.h" void soundio_panic(const char *format, ...) { va_list ap; @@ -25,13 +25,13 @@ char *soundio_alloc_sprintf(int *len, const char *format, ...) { va_start(ap, format); va_copy(ap2, ap); - int len1 = vsnprintf(nullptr, 0, format, ap); + int len1 = vsnprintf(NULL, 0, format, ap); assert(len1 >= 0); size_t required_size = len1 + 1; - char *mem = allocate(required_size); + char *mem = ALLOCATE(char, required_size); if (!mem) - return nullptr; + return NULL; int len2 = vsnprintf(mem, required_size, format, ap2); assert(len2 == len1); diff --git a/src/util.hpp b/src/util.h similarity index 53% rename from src/util.hpp rename to src/util.h index 3c1e2de..5d45f4e 100644 --- a/src/util.hpp +++ b/src/util.h @@ -5,26 +5,44 @@ * See http://opensource.org/licenses/MIT */ -#ifndef SOUNDIO_UTIL_HPP -#define SOUNDIO_UTIL_HPP +#ifndef SOUNDIO_UTIL_H +#define SOUNDIO_UTIL_H #include #include #include +#include -template -__attribute__((malloc)) static inline T *allocate_nonzero(size_t count) { - return reinterpret_cast(malloc(count * sizeof(T))); +#define ALLOCATE_NONZERO(Type, count) malloc((count) * sizeof(Type)) + +#define ALLOCATE(Type, count) calloc(count, sizeof(Type)) + +#define REALLOCATE_NONZERO(Type, old, new_count) realloc(old, (new_count) * sizeof(Type)) + +#define ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0])) + +static inline int soundio_int_min(int a, int b) { + return (a <= b) ? a : b; } -template -__attribute__((malloc)) static inline T *allocate(size_t count) { - return reinterpret_cast(calloc(count, sizeof(T))); +static inline int soundio_int_max(int a, int b) { + return (a >= b) ? a : b; } -template -static inline T *reallocate_nonzero(T * old, size_t new_count) { - return reinterpret_cast(realloc(old, new_count * sizeof(T))); +static inline int soundio_int_clamp(int min_value, int value, int max_value) { + return soundio_int_max(soundio_int_min(value, max_value), min_value); +} + +static inline double soundio_double_min(double a, double b) { + return (a <= b) ? a : b; +} + +static inline double soundio_double_max(double a, double b) { + return (a >= b) ? a : b; +} + +static inline double soundio_double_clamp(double min_value, double value, double max_value) { + return soundio_double_max(soundio_double_min(value, max_value), min_value); } void soundio_panic(const char *format, ...) @@ -36,9 +54,9 @@ char *soundio_alloc_sprintf(int *len, const char *format, ...) __attribute__ ((format (printf, 2, 3))); static inline char *soundio_str_dupe(const char *str, int str_len) { - char *out = allocate_nonzero(str_len + 1); + char *out = ALLOCATE_NONZERO(char, str_len + 1); if (!out) - return nullptr; + return NULL; memcpy(out, str, str_len); out[str_len] = 0; return out; @@ -61,24 +79,4 @@ static inline double ceil_dbl(double x) { return ceiling; } - -template -static constexpr long array_length(const T (&)[n]) { - return n; -} - -template -static inline T max(T a, T b) { - return (a >= b) ? a : b; -} - -template -static inline T min(T a, T b) { - return (a <= b) ? a : b; -} - -template -static inline T clamp(T min_value, T value, T max_value) { - return max(min(value, max_value), min_value); -} #endif diff --git a/src/wasapi.cpp b/src/wasapi.c similarity index 82% rename from src/wasapi.cpp rename to src/wasapi.c index 8c16abb..09d52db 100644 --- a/src/wasapi.cpp +++ b/src/wasapi.c @@ -5,8 +5,8 @@ * See http://opensource.org/licenses/MIT */ -#include "wasapi.hpp" -#include "soundio.hpp" +#include "wasapi.h" +#include "soundio_private.h" #include @@ -42,7 +42,7 @@ static int test_sample_rates[] = { }; // If you modify this list, also modify `to_wave_format_format` appropriately. -static SoundIoFormat test_formats[] = { +static enum SoundIoFormat test_formats[] = { SoundIoFormatU8, SoundIoFormatS16LE, SoundIoFormatS24LE, @@ -52,7 +52,7 @@ static SoundIoFormat test_formats[] = { }; // If you modify this list, also modify `to_wave_format_layout` appropriately. -static SoundIoChannelLayoutId test_layouts[] = { +static enum SoundIoChannelLayoutId test_layouts[] = { SoundIoChannelLayoutIdMono, SoundIoChannelLayoutIdStereo, SoundIoChannelLayoutIdQuad, @@ -115,16 +115,16 @@ static const char *hresult_to_str(HRESULT hr) { // * SoundIoErrorEncodingString static int from_lpwstr(LPWSTR lpwstr, char **out_str, int *out_str_len) { DWORD flags = 0; - int buf_size = WideCharToMultiByte(CP_UTF8, flags, lpwstr, -1, nullptr, 0, nullptr, nullptr); + int buf_size = WideCharToMultiByte(CP_UTF8, flags, lpwstr, -1, NULL, 0, NULL, NULL); if (buf_size == 0) return SoundIoErrorEncodingString; - char *buf = allocate(buf_size); + char *buf = ALLOCATE(char, buf_size); if (!buf) return SoundIoErrorNoMem; - if (WideCharToMultiByte(CP_UTF8, flags, lpwstr, -1, buf, buf_size, nullptr, nullptr) != buf_size) { + if (WideCharToMultiByte(CP_UTF8, flags, lpwstr, -1, buf, buf_size, NULL, NULL) != buf_size) { free(buf); return SoundIoErrorEncodingString; } @@ -137,11 +137,11 @@ static int from_lpwstr(LPWSTR lpwstr, char **out_str, int *out_str_len) { static int to_lpwstr(const char *str, int str_len, LPWSTR *out_lpwstr) { DWORD flags = 0; - int w_len = MultiByteToWideChar(CP_UTF8, flags, str, str_len, nullptr, 0); + int w_len = MultiByteToWideChar(CP_UTF8, flags, str, str_len, NULL, 0); if (w_len <= 0) return SoundIoErrorEncodingString; - LPWSTR buf = allocate(w_len + 1); + LPWSTR buf = ALLOCATE(wchar_t, w_len + 1); if (!buf) return SoundIoErrorNoMem; @@ -154,7 +154,7 @@ static int to_lpwstr(const char *str, int str_len, LPWSTR *out_lpwstr) { return 0; } -static void from_channel_mask_layout(UINT channel_mask, SoundIoChannelLayout *layout) { +static void from_channel_mask_layout(UINT channel_mask, struct SoundIoChannelLayout *layout) { layout->channel_count = 0; if (channel_mask & SPEAKER_FRONT_LEFT) layout->channels[layout->channel_count++] = SoundIoChannelIdFrontLeft; @@ -196,16 +196,16 @@ static void from_channel_mask_layout(UINT channel_mask, SoundIoChannelLayout *la soundio_channel_layout_detect_builtin(layout); } -static void from_wave_format_layout(WAVEFORMATEXTENSIBLE *wave_format, SoundIoChannelLayout *layout) { +static void from_wave_format_layout(WAVEFORMATEXTENSIBLE *wave_format, struct SoundIoChannelLayout *layout) { assert(wave_format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE); layout->channel_count = 0; from_channel_mask_layout(wave_format->dwChannelMask, layout); } -static SoundIoFormat from_wave_format_format(WAVEFORMATEXTENSIBLE *wave_format) { +static enum SoundIoFormat from_wave_format_format(WAVEFORMATEXTENSIBLE *wave_format) { assert(wave_format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE); - bool is_pcm = IsEqualGUID(wave_format->SubFormat, SOUNDIO_KSDATAFORMAT_SUBTYPE_PCM); - bool is_float = IsEqualGUID(wave_format->SubFormat, SOUNDIO_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); + bool is_pcm = IsEqualGUID(&wave_format->SubFormat, &SOUNDIO_KSDATAFORMAT_SUBTYPE_PCM); + bool is_float = IsEqualGUID(&wave_format->SubFormat, &SOUNDIO_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); if (wave_format->Samples.wValidBitsPerSample == wave_format->Format.wBitsPerSample) { if (wave_format->Format.wBitsPerSample == 8) { @@ -233,11 +233,11 @@ static SoundIoFormat from_wave_format_format(WAVEFORMATEXTENSIBLE *wave_format) } // only needs to support the layouts in test_layouts -static void to_wave_format_layout(const SoundIoChannelLayout *layout, WAVEFORMATEXTENSIBLE *wave_format) { +static void to_wave_format_layout(const struct SoundIoChannelLayout *layout, WAVEFORMATEXTENSIBLE *wave_format) { wave_format->dwChannelMask = 0; wave_format->Format.nChannels = layout->channel_count; for (int i = 0; i < layout->channel_count; i += 1) { - SoundIoChannelId channel_id = layout->channels[i]; + enum SoundIoChannelId channel_id = layout->channels[i]; switch (channel_id) { case SoundIoChannelIdFrontLeft: wave_format->dwChannelMask |= SPEAKER_FRONT_LEFT; @@ -300,7 +300,7 @@ static void to_wave_format_layout(const SoundIoChannelLayout *layout, WAVEFORMAT } // only needs to support the formats in test_formats -static void to_wave_format_format(SoundIoFormat format, WAVEFORMATEXTENSIBLE *wave_format) { +static void to_wave_format_format(enum SoundIoFormat format, WAVEFORMATEXTENSIBLE *wave_format) { switch (format) { case SoundIoFormatU8: wave_format->SubFormat = SOUNDIO_KSDATAFORMAT_SUBTYPE_PCM; @@ -342,7 +342,7 @@ static void complete_wave_format_data(WAVEFORMATEXTENSIBLE *wave_format) { wave_format->Format.nAvgBytesPerSec = wave_format->Format.nSamplesPerSec * wave_format->Format.nBlockAlign; } -static SoundIoDeviceAim data_flow_to_aim(EDataFlow data_flow) { +static enum SoundIoDeviceAim data_flow_to_aim(EDataFlow data_flow) { return (data_flow == eRender) ? SoundIoDeviceAimOutput : SoundIoDeviceAimInput; } @@ -355,8 +355,8 @@ static REFERENCE_TIME to_reference_time(double seconds) { return seconds * 10000000.0 + 0.5; } -static void destruct_device(SoundIoDevicePrivate *dev) { - SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi; +static void destruct_device(struct SoundIoDevicePrivate *dev) { + struct SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi; if (dw->mm_device) IMMDevice_Release(dw->mm_device); } @@ -373,16 +373,16 @@ struct RefreshDevices { PROPVARIANT prop_variant_value; WAVEFORMATEXTENSIBLE *wave_format; bool prop_variant_value_inited; - SoundIoDevicesInfo *devices_info; - SoundIoDevice *device_shared; - SoundIoDevice *device_raw; + struct SoundIoDevicesInfo *devices_info; + struct SoundIoDevice *device_shared; + struct SoundIoDevice *device_raw; char *default_render_id; int default_render_id_len; char *default_capture_id; int default_capture_id_len; }; -static void deinit_refresh_devices(RefreshDevices *rd) { +static void deinit_refresh_devices(struct RefreshDevices *rd) { soundio_destroy_devices_info(rd->devices_info); soundio_device_unref(rd->device_shared); soundio_device_unref(rd->device_raw); @@ -408,23 +408,23 @@ static void deinit_refresh_devices(RefreshDevices *rd) { IUnknown_Release(rd->audio_client); } -static int detect_valid_layouts(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_format, - SoundIoDevicePrivate *dev, AUDCLNT_SHAREMODE share_mode) +static int detect_valid_layouts(struct RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_format, + struct SoundIoDevicePrivate *dev, AUDCLNT_SHAREMODE share_mode) { - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; HRESULT hr; device->layout_count = 0; - device->layouts = allocate(array_length(test_layouts)); + device->layouts = ALLOCATE(struct SoundIoChannelLayout, ARRAY_LENGTH(test_layouts)); if (!device->layouts) return SoundIoErrorNoMem; - WAVEFORMATEX *closest_match = nullptr; + WAVEFORMATEX *closest_match = NULL; WAVEFORMATEXTENSIBLE orig_wave_format = *wave_format; - for (int i = 0; i < array_length(test_formats); i += 1) { - SoundIoChannelLayoutId test_layout_id = test_layouts[i]; - const SoundIoChannelLayout *test_layout = soundio_channel_layout_get_builtin(test_layout_id); + for (int i = 0; i < ARRAY_LENGTH(test_formats); i += 1) { + enum SoundIoChannelLayoutId test_layout_id = test_layouts[i]; + const struct SoundIoChannelLayout *test_layout = soundio_channel_layout_get_builtin(test_layout_id); to_wave_format_layout(test_layout, wave_format); complete_wave_format_data(wave_format); @@ -432,7 +432,7 @@ static int detect_valid_layouts(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_f (WAVEFORMATEX*)wave_format, &closest_match); if (closest_match) { CoTaskMemFree(closest_match); - closest_match = nullptr; + closest_match = NULL; } if (hr == S_OK) { device->layouts[device->layout_count++] = *test_layout; @@ -448,22 +448,22 @@ static int detect_valid_layouts(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_f return 0; } -static int detect_valid_formats(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_format, - SoundIoDevicePrivate *dev, AUDCLNT_SHAREMODE share_mode) +static int detect_valid_formats(struct RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_format, + struct SoundIoDevicePrivate *dev, AUDCLNT_SHAREMODE share_mode) { - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; HRESULT hr; device->format_count = 0; - device->formats = allocate(array_length(test_formats)); + device->formats = ALLOCATE(enum SoundIoFormat, ARRAY_LENGTH(test_formats)); if (!device->formats) return SoundIoErrorNoMem; - WAVEFORMATEX *closest_match = nullptr; + WAVEFORMATEX *closest_match = NULL; WAVEFORMATEXTENSIBLE orig_wave_format = *wave_format; - for (int i = 0; i < array_length(test_formats); i += 1) { - SoundIoFormat test_format = test_formats[i]; + for (int i = 0; i < ARRAY_LENGTH(test_formats); i += 1) { + enum SoundIoFormat test_format = test_formats[i]; to_wave_format_format(test_format, wave_format); complete_wave_format_data(wave_format); @@ -471,7 +471,7 @@ static int detect_valid_formats(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_f (WAVEFORMATEX*)wave_format, &closest_match); if (closest_match) { CoTaskMemFree(closest_match); - closest_match = nullptr; + closest_match = NULL; } if (hr == S_OK) { device->formats[device->format_count++] = test_format; @@ -487,21 +487,21 @@ static int detect_valid_formats(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_f return 0; } -static int add_sample_rate(SoundIoList *sample_rates, int *current_min, int the_max) { +static int add_sample_rate(struct SoundIoListSampleRateRange *sample_rates, int *current_min, int the_max) { int err; - if ((err = sample_rates->add_one())) + if ((err = SoundIoListSampleRateRange_add_one(sample_rates))) return err; - SoundIoSampleRateRange *last_range = &sample_rates->last(); + struct SoundIoSampleRateRange *last_range = SoundIoListSampleRateRange_last_ptr(sample_rates); last_range->min = *current_min; last_range->max = the_max; return 0; } -static int do_sample_rate_test(RefreshDevices *rd, SoundIoDevicePrivate *dev, WAVEFORMATEXTENSIBLE *wave_format, +static int do_sample_rate_test(struct RefreshDevices *rd, struct SoundIoDevicePrivate *dev, WAVEFORMATEXTENSIBLE *wave_format, int test_sample_rate, AUDCLNT_SHAREMODE share_mode, int *current_min, int *last_success_rate) { - WAVEFORMATEX *closest_match = nullptr; + WAVEFORMATEX *closest_match = NULL; int err; wave_format->Format.nSamplesPerSec = test_sample_rate; @@ -509,7 +509,7 @@ static int do_sample_rate_test(RefreshDevices *rd, SoundIoDevicePrivate *dev, WA (WAVEFORMATEX*)wave_format, &closest_match); if (closest_match) { CoTaskMemFree(closest_match); - closest_match = nullptr; + closest_match = NULL; } if (hr == S_OK) { if (*current_min == -1) { @@ -529,8 +529,8 @@ static int do_sample_rate_test(RefreshDevices *rd, SoundIoDevicePrivate *dev, WA return 0; } -static int detect_valid_sample_rates(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_format, - SoundIoDevicePrivate *dev, AUDCLNT_SHAREMODE share_mode) +static int detect_valid_sample_rates(struct RefreshDevices *rd, WAVEFORMATEXTENSIBLE *wave_format, + struct SoundIoDevicePrivate *dev, AUDCLNT_SHAREMODE share_mode) { int err; @@ -540,7 +540,7 @@ static int detect_valid_sample_rates(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *w int current_min = -1; int last_success_rate = -1; - for (int i = 0; i < array_length(test_sample_rates); i += 1) { + for (int i = 0; i < ARRAY_LENGTH(test_sample_rates); i += 1) { for (int offset = -1; offset <= 1; offset += 1) { int test_sample_rate = test_sample_rates[i] + offset; if ((err = do_sample_rate_test(rd, dev, wave_format, test_sample_rate, share_mode, @@ -559,7 +559,7 @@ static int detect_valid_sample_rates(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *w } } - SoundIoDevice *device = &dev->pub; + struct SoundIoDevice *device = &dev->pub; device->sample_rate_count = dev->sample_rates.length; device->sample_rates = dev->sample_rates.items; @@ -569,10 +569,10 @@ static int detect_valid_sample_rates(RefreshDevices *rd, WAVEFORMATEXTENSIBLE *w } -static int refresh_devices(SoundIoPrivate *si) { - SoundIo *soundio = &si->pub; - SoundIoWasapi *siw = &si->backend_data.wasapi; - RefreshDevices rd = {0}; +static int refresh_devices(struct SoundIoPrivate *si) { + struct SoundIo *soundio = &si->pub; + struct SoundIoWasapi *siw = &si->backend_data.wasapi; + struct RefreshDevices rd = {0}; int err; HRESULT hr; @@ -584,7 +584,7 @@ static int refresh_devices(SoundIoPrivate *si) { } if (rd.lpwstr) { CoTaskMemFree(rd.lpwstr); - rd.lpwstr = nullptr; + rd.lpwstr = NULL; } if (FAILED(hr = IMMDevice_GetId(rd.default_render_device, &rd.lpwstr))) { deinit_refresh_devices(&rd); @@ -604,7 +604,7 @@ static int refresh_devices(SoundIoPrivate *si) { } if (rd.lpwstr) { CoTaskMemFree(rd.lpwstr); - rd.lpwstr = nullptr; + rd.lpwstr = NULL; } if (FAILED(hr = IMMDevice_GetId(rd.default_capture_device, &rd.lpwstr))) { deinit_refresh_devices(&rd); @@ -636,7 +636,7 @@ static int refresh_devices(SoundIoPrivate *si) { int device_count = unsigned_count; - if (!(rd.devices_info = allocate(1))) { + if (!(rd.devices_info = ALLOCATE(struct SoundIoDevicesInfo, 1))) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } @@ -646,7 +646,7 @@ static int refresh_devices(SoundIoPrivate *si) { for (int device_i = 0; device_i < device_count; device_i += 1) { if (rd.mm_device) { IMMDevice_Release(rd.mm_device); - rd.mm_device = nullptr; + rd.mm_device = NULL; } if (FAILED(hr = IMMDeviceCollection_Item(rd.collection, device_i, &rd.mm_device))) { deinit_refresh_devices(&rd); @@ -654,7 +654,7 @@ static int refresh_devices(SoundIoPrivate *si) { } if (rd.lpwstr) { CoTaskMemFree(rd.lpwstr); - rd.lpwstr = nullptr; + rd.lpwstr = NULL; } if (FAILED(hr = IMMDevice_GetId(rd.mm_device, &rd.lpwstr))) { deinit_refresh_devices(&rd); @@ -663,12 +663,12 @@ static int refresh_devices(SoundIoPrivate *si) { - SoundIoDevicePrivate *dev_shared = allocate(1); + struct SoundIoDevicePrivate *dev_shared = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev_shared) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } - SoundIoDeviceWasapi *dev_w_shared = &dev_shared->backend_data.wasapi; + struct SoundIoDeviceWasapi *dev_w_shared = &dev_shared->backend_data.wasapi; dev_shared->destruct = destruct_device; assert(!rd.device_shared); rd.device_shared = &dev_shared->pub; @@ -677,12 +677,12 @@ static int refresh_devices(SoundIoPrivate *si) { rd.device_shared->is_raw = false; rd.device_shared->software_latency_max = 2.0; - SoundIoDevicePrivate *dev_raw = allocate(1); + struct SoundIoDevicePrivate *dev_raw = ALLOCATE(struct SoundIoDevicePrivate, 1); if (!dev_raw) { deinit_refresh_devices(&rd); return SoundIoErrorNoMem; } - SoundIoDeviceWasapi *dev_w_raw = &dev_raw->backend_data.wasapi; + struct SoundIoDeviceWasapi *dev_w_raw = &dev_raw->backend_data.wasapi; dev_raw->destruct = destruct_device; assert(!rd.device_raw); rd.device_raw = &dev_raw->pub; @@ -705,10 +705,10 @@ static int refresh_devices(SoundIoPrivate *si) { if (rd.audio_client) { IUnknown_Release(rd.audio_client); - rd.audio_client = nullptr; + rd.audio_client = NULL; } - if (FAILED(hr = IMMDevice_Activate(rd.mm_device, IID_IAudioClient, - CLSCTX_ALL, nullptr, (void**)&rd.audio_client))) + if (FAILED(hr = IMMDevice_Activate(rd.mm_device, &IID_IAudioClient, + CLSCTX_ALL, NULL, (void**)&rd.audio_client))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; @@ -731,9 +731,9 @@ static int refresh_devices(SoundIoPrivate *si) { if (rd.endpoint) { IMMEndpoint_Release(rd.endpoint); - rd.endpoint = nullptr; + rd.endpoint = NULL; } - if (FAILED(hr = IMMDevice_QueryInterface(rd.mm_device, IID_IMMEndpoint, (void**)&rd.endpoint))) { + if (FAILED(hr = IMMDevice_QueryInterface(rd.mm_device, &IID_IMMEndpoint, (void**)&rd.endpoint))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; } @@ -749,7 +749,7 @@ static int refresh_devices(SoundIoPrivate *si) { if (rd.prop_store) { IPropertyStore_Release(rd.prop_store); - rd.prop_store = nullptr; + rd.prop_store = NULL; } if (FAILED(hr = IMMDevice_OpenPropertyStore(rd.mm_device, STGM_READ, &rd.prop_store))) { deinit_refresh_devices(&rd); @@ -763,7 +763,7 @@ static int refresh_devices(SoundIoPrivate *si) { PropVariantInit(&rd.prop_variant_value); rd.prop_variant_value_inited = true; if (FAILED(hr = IPropertyStore_GetValue(rd.prop_store, - PKEY_Device_FriendlyName, &rd.prop_variant_value))) + &PKEY_Device_FriendlyName, &rd.prop_variant_value))) { deinit_refresh_devices(&rd); return SoundIoErrorOpeningDevice; @@ -793,7 +793,7 @@ static int refresh_devices(SoundIoPrivate *si) { } PropVariantInit(&rd.prop_variant_value); rd.prop_variant_value_inited = true; - if (FAILED(hr = IPropertyStore_GetValue(rd.prop_store, PKEY_AudioEngine_DeviceFormat, + if (FAILED(hr = IPropertyStore_GetValue(rd.prop_store, &PKEY_AudioEngine_DeviceFormat, &rd.prop_variant_value))) { deinit_refresh_devices(&rd); @@ -819,7 +819,7 @@ static int refresh_devices(SoundIoPrivate *si) { if (rd.wave_format) { CoTaskMemFree(rd.wave_format); - rd.wave_format = nullptr; + rd.wave_format = NULL; } if (FAILED(hr = IAudioClient_GetMixFormat(rd.audio_client, (WAVEFORMATEX**)&rd.wave_format))) { deinit_refresh_devices(&rd); @@ -872,9 +872,9 @@ static int refresh_devices(SoundIoPrivate *si) { IMMDevice_AddRef(rd.mm_device); dev_w_shared->mm_device = rd.mm_device; dev_w_raw->mm_device = rd.mm_device; - rd.mm_device = nullptr; + rd.mm_device = NULL; - SoundIoList *device_list; + struct SoundIoListDevicePtr *device_list; if (rd.device_shared->aim == SoundIoDeviceAimOutput) { device_list = &rd.devices_info->output_devices; if (soundio_streql(rd.device_shared->id, device_id_len, @@ -892,17 +892,17 @@ static int refresh_devices(SoundIoPrivate *si) { } } - if ((err = device_list->append(rd.device_shared))) { + if ((err = SoundIoListDevicePtr_append(device_list, rd.device_shared))) { deinit_refresh_devices(&rd); return err; } - rd.device_shared = nullptr; + rd.device_shared = NULL; - if ((err = device_list->append(rd.device_raw))) { + if ((err = SoundIoListDevicePtr_append(device_list, rd.device_raw))) { deinit_refresh_devices(&rd); return err; } - rd.device_raw = nullptr; + rd.device_raw = NULL; } soundio_os_mutex_lock(siw->mutex); @@ -913,16 +913,16 @@ static int refresh_devices(SoundIoPrivate *si) { soundio->on_events_signal(soundio); soundio_os_mutex_unlock(siw->mutex); - rd.devices_info = nullptr; + rd.devices_info = NULL; deinit_refresh_devices(&rd); return 0; } -static void shutdown_backend(SoundIoPrivate *si, int err) { - SoundIo *soundio = &si->pub; - SoundIoWasapi *siw = &si->backend_data.wasapi; +static void shutdown_backend(struct SoundIoPrivate *si, int err) { + struct SoundIo *soundio = &si->pub; + struct SoundIoWasapi *siw = &si->backend_data.wasapi; soundio_os_mutex_lock(siw->mutex); siw->shutdown_err = err; soundio_os_cond_signal(siw->cond, siw->mutex); @@ -931,12 +931,12 @@ static void shutdown_backend(SoundIoPrivate *si, int err) { } static void device_thread_run(void *arg) { - SoundIoPrivate *si = (SoundIoPrivate *)arg; - SoundIoWasapi *siw = &si->backend_data.wasapi; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)arg; + struct SoundIoWasapi *siw = &si->backend_data.wasapi; int err; - HRESULT hr = CoCreateInstance(CLSID_MMDeviceEnumerator, nullptr, - CLSCTX_ALL, IID_IMMDeviceEnumerator, (void**)&siw->device_enumerator); + HRESULT hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, + CLSCTX_ALL, &IID_IMMDeviceEnumerator, (void**)&siw->device_enumerator); if (FAILED(hr)) { shutdown_backend(si, SoundIoErrorSystemResources); return; @@ -970,16 +970,16 @@ static void device_thread_run(void *arg) { IMMDeviceEnumerator_UnregisterEndpointNotificationCallback(siw->device_enumerator, &siw->device_events); IMMDeviceEnumerator_Release(siw->device_enumerator); - siw->device_enumerator = nullptr; + siw->device_enumerator = NULL; } static void my_flush_events(struct SoundIoPrivate *si, bool wait) { - SoundIo *soundio = &si->pub; - SoundIoWasapi *siw = &si->backend_data.wasapi; + struct SoundIo *soundio = &si->pub; + struct SoundIoWasapi *siw = &si->backend_data.wasapi; bool change = false; bool cb_shutdown = false; - SoundIoDevicesInfo *old_devices_info = nullptr; + struct SoundIoDevicesInfo *old_devices_info = NULL; soundio_os_mutex_lock(siw->mutex); @@ -995,7 +995,7 @@ static void my_flush_events(struct SoundIoPrivate *si, bool wait) { } else if (siw->ready_devices_info) { old_devices_info = si->safe_devices_info; si->safe_devices_info = siw->ready_devices_info; - siw->ready_devices_info = nullptr; + siw->ready_devices_info = NULL; change = true; } @@ -1019,20 +1019,20 @@ static void wait_events_wasapi(struct SoundIoPrivate *si) { } static void wakeup_wasapi(struct SoundIoPrivate *si) { - SoundIoWasapi *siw = &si->backend_data.wasapi; + struct SoundIoWasapi *siw = &si->backend_data.wasapi; soundio_os_cond_signal(siw->cond, siw->mutex); } static void force_device_scan_wasapi(struct SoundIoPrivate *si) { - SoundIoWasapi *siw = &si->backend_data.wasapi; + struct SoundIoWasapi *siw = &si->backend_data.wasapi; soundio_os_mutex_lock(siw->scan_devices_mutex); siw->device_scan_queued = true; soundio_os_cond_signal(siw->scan_devices_cond, siw->scan_devices_mutex); soundio_os_mutex_unlock(siw->scan_devices_mutex); } -static void outstream_thread_deinit(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; +static void outstream_thread_deinit(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; if (osw->audio_render_client) IUnknown_Release(osw->audio_render_client); @@ -1045,10 +1045,10 @@ static void outstream_thread_deinit(SoundIoPrivate *si, SoundIoOutStreamPrivate } static void outstream_destroy_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; if (osw->thread) { - osw->thread_exit_flag.clear(); + atomic_flag_clear(&osw->thread_exit_flag); if (osw->h_event) SetEvent(osw->h_event); @@ -1059,37 +1059,37 @@ static void outstream_destroy_wasapi(struct SoundIoPrivate *si, struct SoundIoOu soundio_os_thread_destroy(osw->thread); - osw->thread = nullptr; + osw->thread = NULL; } if (osw->h_event) { CloseHandle(osw->h_event); - osw->h_event = nullptr; + osw->h_event = NULL; } free(osw->stream_name); - osw->stream_name = nullptr; + osw->stream_name = NULL; soundio_os_cond_destroy(osw->cond); - osw->cond = nullptr; + osw->cond = NULL; soundio_os_cond_destroy(osw->start_cond); - osw->start_cond = nullptr; + osw->start_cond = NULL; soundio_os_mutex_destroy(osw->mutex); - osw->mutex = nullptr; + osw->mutex = NULL; } -static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; - SoundIoOutStream *outstream = &os->pub; - SoundIoDevice *device = outstream->device; - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi; +static int outstream_do_open(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoDevice *device = outstream->device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi; HRESULT hr; - if (FAILED(hr = IMMDevice_Activate(dw->mm_device, IID_IAudioClient, - CLSCTX_ALL, nullptr, (void**)&osw->audio_client))) + if (FAILED(hr = IMMDevice_Activate(dw->mm_device, &IID_IAudioClient, + CLSCTX_ALL, NULL, (void**)&osw->audio_client))) { return SoundIoErrorOpeningDevice; } @@ -1115,7 +1115,7 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { } wave_format.Format.nSamplesPerSec = mix_format->Format.nSamplesPerSec; CoTaskMemFree(mix_format); - mix_format = nullptr; + mix_format = NULL; osw->need_resample = (wave_format.Format.nSamplesPerSec != (DWORD)outstream->sample_rate); flags = osw->need_resample ? AUDCLNT_STREAMFLAGS_RATEADJUST : 0; share_mode = AUDCLNT_SHAREMODE_SHARED; @@ -1127,16 +1127,16 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { complete_wave_format_data(&wave_format); if (FAILED(hr = IAudioClient_Initialize(osw->audio_client, share_mode, flags, - buffer_duration, periodicity, (WAVEFORMATEX*)&wave_format, nullptr))) + buffer_duration, periodicity, (WAVEFORMATEX*)&wave_format, NULL))) { if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED) { if (FAILED(hr = IAudioClient_GetBufferSize(osw->audio_client, &osw->buffer_frame_count))) { return SoundIoErrorOpeningDevice; } IUnknown_Release(osw->audio_client); - osw->audio_client = nullptr; - if (FAILED(hr = IMMDevice_Activate(dw->mm_device, IID_IAudioClient, - CLSCTX_ALL, nullptr, (void**)&osw->audio_client))) + osw->audio_client = NULL; + if (FAILED(hr = IMMDevice_Activate(dw->mm_device, &IID_IAudioClient, + CLSCTX_ALL, NULL, (void**)&osw->audio_client))) { return SoundIoErrorOpeningDevice; } @@ -1147,7 +1147,7 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { } wave_format.Format.nSamplesPerSec = mix_format->Format.nSamplesPerSec; CoTaskMemFree(mix_format); - mix_format = nullptr; + mix_format = NULL; osw->need_resample = (wave_format.Format.nSamplesPerSec != (DWORD)outstream->sample_rate); flags = osw->need_resample ? AUDCLNT_STREAMFLAGS_RATEADJUST : 0; to_wave_format_layout(&outstream->layout, &wave_format); @@ -1159,7 +1159,7 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { if (osw->is_raw) periodicity = buffer_duration; if (FAILED(hr = IAudioClient_Initialize(osw->audio_client, share_mode, flags, - buffer_duration, periodicity, (WAVEFORMATEX*)&wave_format, nullptr))) + buffer_duration, periodicity, (WAVEFORMATEX*)&wave_format, NULL))) { if (hr == AUDCLNT_E_UNSUPPORTED_FORMAT) { return SoundIoErrorIncompatibleDevice; @@ -1195,7 +1195,7 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { return SoundIoErrorOpeningDevice; } } else if (osw->need_resample) { - if (FAILED(hr = IAudioClient_GetService(osw->audio_client, IID_IAudioClockAdjustment, + if (FAILED(hr = IAudioClient_GetService(osw->audio_client, &IID_IAudioClockAdjustment, (void**)&osw->audio_clock_adjustment))) { return SoundIoErrorOpeningDevice; @@ -1208,7 +1208,7 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { } if (outstream->name) { - if (FAILED(hr = IAudioClient_GetService(osw->audio_client, IID_IAudioSessionControl, + if (FAILED(hr = IAudioClient_GetService(osw->audio_client, &IID_IAudioSessionControl, (void **)&osw->audio_session_control))) { return SoundIoErrorOpeningDevice; @@ -1219,13 +1219,13 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { return err; } if (FAILED(hr = IAudioSessionControl_SetDisplayName(osw->audio_session_control, - osw->stream_name, nullptr))) + osw->stream_name, NULL))) { return SoundIoErrorOpeningDevice; } } - if (FAILED(hr = IAudioClient_GetService(osw->audio_client, IID_IAudioRenderClient, + if (FAILED(hr = IAudioClient_GetService(osw->audio_client, &IID_IAudioRenderClient, (void **)&osw->audio_render_client))) { return SoundIoErrorOpeningDevice; @@ -1234,9 +1234,9 @@ static int outstream_do_open(SoundIoPrivate *si, SoundIoOutStreamPrivate *os) { return 0; } -void outstream_shared_run(SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; - SoundIoOutStream *outstream = &os->pub; +static void outstream_shared_run(struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStream *outstream = &os->pub; HRESULT hr; @@ -1268,13 +1268,13 @@ void outstream_shared_run(SoundIoOutStreamPrivate *os) { double wait_time = time_until_underrun / 2.0; soundio_os_mutex_lock(osw->mutex); soundio_os_cond_timed_wait(osw->cond, osw->mutex, wait_time); - if (!osw->thread_exit_flag.test_and_set()) { + if (!atomic_flag_test_and_set(&osw->thread_exit_flag)) { soundio_os_mutex_unlock(osw->mutex); return; } soundio_os_mutex_unlock(osw->mutex); bool reset_buffer = false; - if (!osw->clear_buffer_flag.test_and_set()) { + if (!atomic_flag_test_and_set(&osw->clear_buffer_flag)) { if (!osw->is_paused) { if (FAILED(hr = IAudioClient_Stop(osw->audio_client))) { outstream->error_callback(outstream, SoundIoErrorStreaming); @@ -1286,11 +1286,11 @@ void outstream_shared_run(SoundIoOutStreamPrivate *os) { outstream->error_callback(outstream, SoundIoErrorStreaming); return; } - osw->pause_resume_flag.clear(); + atomic_flag_clear(&osw->pause_resume_flag); reset_buffer = true; } - if (!osw->pause_resume_flag.test_and_set()) { - bool pause = osw->desired_pause_state.load(); + if (!atomic_flag_test_and_set(&osw->pause_resume_flag)) { + bool pause = SOUNDIO_ATOMIC_LOAD(osw->desired_pause_state); if (pause && !osw->is_paused) { if (FAILED(hr = IAudioClient_Stop(osw->audio_client))) { outstream->error_callback(outstream, SoundIoErrorStreaming); @@ -1320,9 +1320,9 @@ void outstream_shared_run(SoundIoOutStreamPrivate *os) { } } -void outstream_raw_run(SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; - SoundIoOutStream *outstream = &os->pub; +static void outstream_raw_run(struct SoundIoOutStreamPrivate *os) { + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStream *outstream = &os->pub; HRESULT hr; @@ -1335,10 +1335,10 @@ void outstream_raw_run(SoundIoOutStreamPrivate *os) { for (;;) { WaitForSingleObject(osw->h_event, INFINITE); - if (!osw->thread_exit_flag.test_and_set()) + if (!atomic_flag_test_and_set(&osw->thread_exit_flag)) return; - if (!osw->pause_resume_flag.test_and_set()) { - bool pause = osw->desired_pause_state.load(); + if (!atomic_flag_test_and_set(&osw->pause_resume_flag)) { + bool pause = SOUNDIO_ATOMIC_LOAD(osw->desired_pause_state); if (pause && !osw->is_paused) { if (FAILED(hr = IAudioClient_Stop(osw->audio_client))) { outstream->error_callback(outstream, SoundIoErrorStreaming); @@ -1359,12 +1359,12 @@ void outstream_raw_run(SoundIoOutStreamPrivate *os) { } static void outstream_thread_run(void *arg) { - SoundIoOutStreamPrivate *os = (SoundIoOutStreamPrivate *)arg; - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; - SoundIoOutStream *outstream = &os->pub; - SoundIoDevice *device = outstream->device; - SoundIo *soundio = device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoOutStreamPrivate *os = (struct SoundIoOutStreamPrivate *)arg; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoDevice *device = outstream->device; + struct SoundIo *soundio = device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; int err; if ((err = outstream_do_open(si, os))) { @@ -1382,7 +1382,7 @@ static void outstream_thread_run(void *arg) { osw->open_complete = true; soundio_os_cond_signal(osw->cond, osw->mutex); for (;;) { - if (!osw->thread_exit_flag.test_and_set()) { + if (!atomic_flag_test_and_set(&osw->thread_exit_flag)) { soundio_os_mutex_unlock(osw->mutex); return; } @@ -1402,14 +1402,14 @@ static void outstream_thread_run(void *arg) { } static int outstream_open_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; - SoundIoOutStream *outstream = &os->pub; - SoundIoDevice *device = outstream->device; - SoundIo *soundio = &si->pub; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoDevice *device = outstream->device; + struct SoundIo *soundio = &si->pub; - osw->pause_resume_flag.test_and_set(); - osw->clear_buffer_flag.test_and_set(); - osw->desired_pause_state.store(false); + atomic_flag_test_and_set(&osw->pause_resume_flag); + atomic_flag_test_and_set(&osw->clear_buffer_flag); + SOUNDIO_ATOMIC_STORE(osw->desired_pause_state, false); // All the COM functions are supposed to be called from the same thread. libsoundio API does not // restrict the calling thread context in this way. Furthermore, the user might have called @@ -1436,14 +1436,14 @@ static int outstream_open_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStr } if (osw->is_raw) { - osw->h_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + osw->h_event = CreateEvent(NULL, FALSE, FALSE, NULL); if (!osw->h_event) { outstream_destroy_wasapi(si, os); return SoundIoErrorOpeningDevice; } } - osw->thread_exit_flag.test_and_set(); + atomic_flag_test_and_set(&osw->thread_exit_flag); int err; if ((err = soundio_os_thread_create(outstream_thread_run, os, soundio->emit_rtprio_warning, &osw->thread))) @@ -1466,10 +1466,10 @@ static int outstream_open_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStr } static int outstream_pause_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, bool pause) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; - osw->desired_pause_state.store(pause); - osw->pause_resume_flag.clear(); + SOUNDIO_ATOMIC_STORE(osw->desired_pause_state, pause); + atomic_flag_clear(&osw->pause_resume_flag); if (osw->h_event) { SetEvent(osw->h_event); } else { @@ -1482,7 +1482,7 @@ static int outstream_pause_wasapi(struct SoundIoPrivate *si, struct SoundIoOutSt } static int outstream_start_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; soundio_os_mutex_lock(osw->mutex); osw->started = true; @@ -1493,10 +1493,10 @@ static int outstream_start_wasapi(struct SoundIoPrivate *si, struct SoundIoOutSt } static int outstream_begin_write_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, - SoundIoChannelArea **out_areas, int *frame_count) + struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; - SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStream *outstream = &os->pub; HRESULT hr; osw->write_frame_count = *frame_count; @@ -1520,7 +1520,7 @@ static int outstream_begin_write_wasapi(struct SoundIoPrivate *si, struct SoundI } static int outstream_end_write_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; HRESULT hr; if (FAILED(hr = IAudioRenderClient_ReleaseBuffer(osw->audio_render_client, osw->write_frame_count, 0))) { return SoundIoErrorStreaming; @@ -1529,12 +1529,12 @@ static int outstream_end_write_wasapi(struct SoundIoPrivate *si, struct SoundIoO } static int outstream_clear_buffer_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os) { - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; if (osw->h_event) { return SoundIoErrorIncompatibleDevice; } else { - osw->clear_buffer_flag.clear(); + atomic_flag_clear(&osw->clear_buffer_flag); soundio_os_mutex_lock(osw->mutex); soundio_os_cond_signal(osw->cond, osw->mutex); soundio_os_mutex_unlock(osw->mutex); @@ -1546,8 +1546,8 @@ static int outstream_clear_buffer_wasapi(struct SoundIoPrivate *si, struct Sound static int outstream_get_latency_wasapi(struct SoundIoPrivate *si, struct SoundIoOutStreamPrivate *os, double *out_latency) { - SoundIoOutStream *outstream = &os->pub; - SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; + struct SoundIoOutStream *outstream = &os->pub; + struct SoundIoOutStreamWasapi *osw = &os->backend_data.wasapi; HRESULT hr; UINT32 frames_used; @@ -1559,8 +1559,8 @@ static int outstream_get_latency_wasapi(struct SoundIoPrivate *si, struct SoundI return 0; } -static void instream_thread_deinit(SoundIoPrivate *si, SoundIoInStreamPrivate *is) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; +static void instream_thread_deinit(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; if (isw->audio_capture_client) IUnknown_Release(isw->audio_capture_client); @@ -1570,10 +1570,10 @@ static void instream_thread_deinit(SoundIoPrivate *si, SoundIoInStreamPrivate *i static void instream_destroy_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; if (isw->thread) { - isw->thread_exit_flag.clear(); + atomic_flag_clear(&isw->thread_exit_flag); if (isw->h_event) SetEvent(isw->h_event); @@ -1583,34 +1583,34 @@ static void instream_destroy_wasapi(struct SoundIoPrivate *si, struct SoundIoInS soundio_os_mutex_unlock(isw->mutex); soundio_os_thread_destroy(isw->thread); - isw->thread = nullptr; + isw->thread = NULL; } if (isw->h_event) { CloseHandle(isw->h_event); - isw->h_event = nullptr; + isw->h_event = NULL; } soundio_os_cond_destroy(isw->cond); - isw->cond = nullptr; + isw->cond = NULL; soundio_os_cond_destroy(isw->start_cond); - isw->start_cond = nullptr; + isw->start_cond = NULL; soundio_os_mutex_destroy(isw->mutex); - isw->mutex = nullptr; + isw->mutex = NULL; } static int instream_do_open(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; - SoundIoInStream *instream = &is->pub; - SoundIoDevice *device = instream->device; - SoundIoDevicePrivate *dev = (SoundIoDevicePrivate *)device; - SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoDevice *device = instream->device; + struct SoundIoDevicePrivate *dev = (struct SoundIoDevicePrivate *)device; + struct SoundIoDeviceWasapi *dw = &dev->backend_data.wasapi; HRESULT hr; - if (FAILED(hr = IMMDevice_Activate(dw->mm_device, IID_IAudioClient, - CLSCTX_ALL, nullptr, (void**)&isw->audio_client))) + if (FAILED(hr = IMMDevice_Activate(dw->mm_device, &IID_IAudioClient, + CLSCTX_ALL, NULL, (void**)&isw->audio_client))) { return SoundIoErrorOpeningDevice; } @@ -1635,7 +1635,7 @@ static int instream_do_open(struct SoundIoPrivate *si, struct SoundIoInStreamPri } wave_format.Format.nSamplesPerSec = mix_format->Format.nSamplesPerSec; CoTaskMemFree(mix_format); - mix_format = nullptr; + mix_format = NULL; if (wave_format.Format.nSamplesPerSec != (DWORD)instream->sample_rate) { return SoundIoErrorIncompatibleDevice; } @@ -1649,16 +1649,16 @@ static int instream_do_open(struct SoundIoPrivate *si, struct SoundIoInStreamPri complete_wave_format_data(&wave_format); if (FAILED(hr = IAudioClient_Initialize(isw->audio_client, share_mode, flags, - buffer_duration, periodicity, (WAVEFORMATEX*)&wave_format, nullptr))) + buffer_duration, periodicity, (WAVEFORMATEX*)&wave_format, NULL))) { if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED) { if (FAILED(hr = IAudioClient_GetBufferSize(isw->audio_client, &isw->buffer_frame_count))) { return SoundIoErrorOpeningDevice; } IUnknown_Release(isw->audio_client); - isw->audio_client = nullptr; - if (FAILED(hr = IMMDevice_Activate(dw->mm_device, IID_IAudioClient, - CLSCTX_ALL, nullptr, (void**)&isw->audio_client))) + isw->audio_client = NULL; + if (FAILED(hr = IMMDevice_Activate(dw->mm_device, &IID_IAudioClient, + CLSCTX_ALL, NULL, (void**)&isw->audio_client))) { return SoundIoErrorOpeningDevice; } @@ -1669,7 +1669,7 @@ static int instream_do_open(struct SoundIoPrivate *si, struct SoundIoInStreamPri } wave_format.Format.nSamplesPerSec = mix_format->Format.nSamplesPerSec; CoTaskMemFree(mix_format); - mix_format = nullptr; + mix_format = NULL; flags = 0; to_wave_format_layout(&instream->layout, &wave_format); to_wave_format_format(instream->format, &wave_format); @@ -1680,7 +1680,7 @@ static int instream_do_open(struct SoundIoPrivate *si, struct SoundIoInStreamPri if (isw->is_raw) periodicity = buffer_duration; if (FAILED(hr = IAudioClient_Initialize(isw->audio_client, share_mode, flags, - buffer_duration, periodicity, (WAVEFORMATEX*)&wave_format, nullptr))) + buffer_duration, periodicity, (WAVEFORMATEX*)&wave_format, NULL))) { if (hr == AUDCLNT_E_UNSUPPORTED_FORMAT) { return SoundIoErrorIncompatibleDevice; @@ -1711,7 +1711,7 @@ static int instream_do_open(struct SoundIoPrivate *si, struct SoundIoInStreamPri } if (instream->name) { - if (FAILED(hr = IAudioClient_GetService(isw->audio_client, IID_IAudioSessionControl, + if (FAILED(hr = IAudioClient_GetService(isw->audio_client, &IID_IAudioSessionControl, (void **)&isw->audio_session_control))) { return SoundIoErrorOpeningDevice; @@ -1722,13 +1722,13 @@ static int instream_do_open(struct SoundIoPrivate *si, struct SoundIoInStreamPri return err; } if (FAILED(hr = IAudioSessionControl_SetDisplayName(isw->audio_session_control, - isw->stream_name, nullptr))) + isw->stream_name, NULL))) { return SoundIoErrorOpeningDevice; } } - if (FAILED(hr = IAudioClient_GetService(isw->audio_client, IID_IAudioCaptureClient, + if (FAILED(hr = IAudioClient_GetService(isw->audio_client, &IID_IAudioCaptureClient, (void **)&isw->audio_capture_client))) { return SoundIoErrorOpeningDevice; @@ -1737,9 +1737,9 @@ static int instream_do_open(struct SoundIoPrivate *si, struct SoundIoInStreamPri return 0; } -static void instream_raw_run(SoundIoInStreamPrivate *is) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; - SoundIoInStream *instream = &is->pub; +static void instream_raw_run(struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStream *instream = &is->pub; HRESULT hr; @@ -1750,16 +1750,16 @@ static void instream_raw_run(SoundIoInStreamPrivate *is) { for (;;) { WaitForSingleObject(isw->h_event, INFINITE); - if (!isw->thread_exit_flag.test_and_set()) + if (!atomic_flag_test_and_set(&isw->thread_exit_flag)) return; instream->read_callback(instream, isw->buffer_frame_count, isw->buffer_frame_count); } } -static void instream_shared_run(SoundIoInStreamPrivate *is) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; - SoundIoInStream *instream = &is->pub; +static void instream_shared_run(struct SoundIoInStreamPrivate *is) { + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStream *instream = &is->pub; HRESULT hr; @@ -1771,7 +1771,7 @@ static void instream_shared_run(SoundIoInStreamPrivate *is) { for (;;) { soundio_os_mutex_lock(isw->mutex); soundio_os_cond_timed_wait(isw->cond, isw->mutex, instream->software_latency / 2.0); - if (!isw->thread_exit_flag.test_and_set()) { + if (!atomic_flag_test_and_set(&isw->thread_exit_flag)) { soundio_os_mutex_unlock(isw->mutex); return; } @@ -1790,12 +1790,12 @@ static void instream_shared_run(SoundIoInStreamPrivate *is) { } static void instream_thread_run(void *arg) { - SoundIoInStreamPrivate *is = (SoundIoInStreamPrivate *)arg; - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; - SoundIoInStream *instream = &is->pub; - SoundIoDevice *device = instream->device; - SoundIo *soundio = device->soundio; - SoundIoPrivate *si = (SoundIoPrivate *)soundio; + struct SoundIoInStreamPrivate *is = (struct SoundIoInStreamPrivate *)arg; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoDevice *device = instream->device; + struct SoundIo *soundio = device->soundio; + struct SoundIoPrivate *si = (struct SoundIoPrivate *)soundio; int err; if ((err = instream_do_open(si, is))) { @@ -1813,7 +1813,7 @@ static void instream_thread_run(void *arg) { isw->open_complete = true; soundio_os_cond_signal(isw->cond, isw->mutex); for (;;) { - if (!isw->thread_exit_flag.test_and_set()) { + if (!atomic_flag_test_and_set(&isw->thread_exit_flag)) { soundio_os_mutex_unlock(isw->mutex); return; } @@ -1833,10 +1833,10 @@ static void instream_thread_run(void *arg) { } static int instream_open_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; - SoundIoInStream *instream = &is->pub; - SoundIoDevice *device = instream->device; - SoundIo *soundio = &si->pub; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoDevice *device = instream->device; + struct SoundIo *soundio = &si->pub; // All the COM functions are supposed to be called from the same thread. libsoundio API does not // restrict the calling thread context in this way. Furthermore, the user might have called @@ -1863,14 +1863,14 @@ static int instream_open_wasapi(struct SoundIoPrivate *si, struct SoundIoInStrea } if (isw->is_raw) { - isw->h_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + isw->h_event = CreateEvent(NULL, FALSE, FALSE, NULL); if (!isw->h_event) { instream_destroy_wasapi(si, is); return SoundIoErrorOpeningDevice; } } - isw->thread_exit_flag.test_and_set(); + atomic_flag_test_and_set(&isw->thread_exit_flag); int err; if ((err = soundio_os_thread_create(instream_thread_run, is, soundio->emit_rtprio_warning, &isw->thread))) @@ -1893,7 +1893,7 @@ static int instream_open_wasapi(struct SoundIoPrivate *si, struct SoundIoInStrea } static int instream_pause_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, bool pause) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; HRESULT hr; if (pause && !isw->is_paused) { if (FAILED(hr = IAudioClient_Stop(isw->audio_client))) @@ -1908,7 +1908,7 @@ static int instream_pause_wasapi(struct SoundIoPrivate *si, struct SoundIoInStre } static int instream_start_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; soundio_os_mutex_lock(isw->mutex); isw->started = true; @@ -1919,23 +1919,23 @@ static int instream_start_wasapi(struct SoundIoPrivate *si, struct SoundIoInStre } static int instream_begin_read_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, - SoundIoChannelArea **out_areas, int *frame_count) + struct SoundIoChannelArea **out_areas, int *frame_count) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; - SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStream *instream = &is->pub; HRESULT hr; if (isw->read_buf_frames_left <= 0) { UINT32 frames_to_read; DWORD flags; if (FAILED(hr = IAudioCaptureClient_GetBuffer(isw->audio_capture_client, - (BYTE**)&isw->read_buf, &frames_to_read, &flags, nullptr, nullptr))) + (BYTE**)&isw->read_buf, &frames_to_read, &flags, NULL, NULL))) { return SoundIoErrorStreaming; } isw->read_buf_frames_left = frames_to_read; if (flags & AUDCLNT_BUFFERFLAGS_SILENT) - isw->read_buf = nullptr; + isw->read_buf = NULL; } isw->read_frame_count = min(*frame_count, isw->read_buf_frames_left); @@ -1949,14 +1949,14 @@ static int instream_begin_read_wasapi(struct SoundIoPrivate *si, struct SoundIoI *out_areas = isw->areas; } else { - *out_areas = nullptr; + *out_areas = NULL; } return 0; } static int instream_end_read_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is) { - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; HRESULT hr; if (FAILED(hr = IAudioCaptureClient_ReleaseBuffer(isw->audio_capture_client, isw->read_frame_count))) { return SoundIoErrorStreaming; @@ -1968,8 +1968,8 @@ static int instream_end_read_wasapi(struct SoundIoPrivate *si, struct SoundIoInS static int instream_get_latency_wasapi(struct SoundIoPrivate *si, struct SoundIoInStreamPrivate *is, double *out_latency) { - SoundIoInStream *instream = &is->pub; - SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; + struct SoundIoInStream *instream = &is->pub; + struct SoundIoInStreamWasapi *isw = &is->backend_data.wasapi; HRESULT hr; UINT32 frames_used; @@ -1983,7 +1983,7 @@ static int instream_get_latency_wasapi(struct SoundIoPrivate *si, struct SoundIo static void destroy_wasapi(struct SoundIoPrivate *si) { - SoundIoWasapi *siw = &si->backend_data.wasapi; + struct SoundIoWasapi *siw = &si->backend_data.wasapi; if (siw->thread) { soundio_os_mutex_lock(siw->scan_devices_mutex); @@ -2008,39 +2008,39 @@ static void destroy_wasapi(struct SoundIoPrivate *si) { soundio_destroy_devices_info(siw->ready_devices_info); } -static inline SoundIoPrivate *soundio_MMNotificationClient_si(IMMNotificationClient *client) { - SoundIoWasapi *siw = (SoundIoWasapi *)(((char *)client) - offsetof(SoundIoWasapi, device_events)); - SoundIoPrivate *si = (SoundIoPrivate *)(((char *)siw) - offsetof(SoundIoPrivate, backend_data)); +static inline struct SoundIoPrivate *soundio_MMNotificationClient_si(IMMNotificationClient *client) { + struct SoundIoWasapi *siw = (struct SoundIoWasapi *)(((char *)client) - offsetof(struct SoundIoWasapi, device_events)); + struct SoundIoPrivate *si = (struct SoundIoPrivate *)(((char *)siw) - offsetof(struct SoundIoPrivate, backend_data)); return si; } static STDMETHODIMP soundio_MMNotificationClient_QueryInterface(IMMNotificationClient *client, REFIID riid, void **ppv) { - if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IMMNotificationClient)) { + if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMMNotificationClient)) { *ppv = client; IUnknown_AddRef(client); return S_OK; } else { - *ppv = nullptr; + *ppv = NULL; return E_NOINTERFACE; } } static STDMETHODIMP_(ULONG) soundio_MMNotificationClient_AddRef(IMMNotificationClient *client) { - SoundIoPrivate *si = soundio_MMNotificationClient_si(client); - SoundIoWasapi *siw = &si->backend_data.wasapi; + struct SoundIoPrivate *si = soundio_MMNotificationClient_si(client); + struct SoundIoWasapi *siw = &si->backend_data.wasapi; return InterlockedIncrement(&siw->device_events_refs); } static STDMETHODIMP_(ULONG) soundio_MMNotificationClient_Release(IMMNotificationClient *client) { - SoundIoPrivate *si = soundio_MMNotificationClient_si(client); - SoundIoWasapi *siw = &si->backend_data.wasapi; + struct SoundIoPrivate *si = soundio_MMNotificationClient_si(client); + struct SoundIoWasapi *siw = &si->backend_data.wasapi; return InterlockedDecrement(&siw->device_events_refs); } static HRESULT queue_device_scan(IMMNotificationClient *client) { - SoundIoPrivate *si = soundio_MMNotificationClient_si(client); + struct SoundIoPrivate *si = soundio_MMNotificationClient_si(client); force_device_scan_wasapi(si); return S_OK; } @@ -2083,8 +2083,8 @@ static struct IMMNotificationClientVtbl soundio_MMNotificationClient = { soundio_MMNotificationClient_OnPropertyValueChanged, }; -int soundio_wasapi_init(SoundIoPrivate *si) { - SoundIoWasapi *siw = &si->backend_data.wasapi; +int soundio_wasapi_init(struct SoundIoPrivate *si) { + struct SoundIoWasapi *siw = &si->backend_data.wasapi; int err; siw->device_scan_queued = true; @@ -2116,7 +2116,7 @@ int soundio_wasapi_init(SoundIoPrivate *si) { siw->device_events.lpVtbl = &soundio_MMNotificationClient; siw->device_events_refs = 1; - if ((err = soundio_os_thread_create(device_thread_run, si, nullptr, &siw->thread))) { + if ((err = soundio_os_thread_create(device_thread_run, si, NULL, &siw->thread))) { destroy_wasapi(si); return err; } diff --git a/src/wasapi.hpp b/src/wasapi.h similarity index 73% rename from src/wasapi.hpp rename to src/wasapi.h index a9bf5dc..240c5bf 100644 --- a/src/wasapi.hpp +++ b/src/wasapi.h @@ -5,13 +5,13 @@ * See http://opensource.org/licenses/MIT */ -#ifndef SOUNDIO_WASAPI_HPP -#define SOUNDIO_WASAPI_HPP +#ifndef SOUNDIO_WASAPI_H +#define SOUNDIO_WASAPI_H -#include "soundio_private.h" +#include "soundio_internal.h" #include "os.h" -#include "atomics.hpp" -#include "list.hpp" +#include "list.h" +#include "atomics.h" #define INITGUID #define CINTERFACE @@ -25,6 +25,7 @@ #include #include +struct SoundIoPrivate; int soundio_wasapi_init(struct SoundIoPrivate *si); struct SoundIoDeviceWasapi { @@ -33,10 +34,10 @@ struct SoundIoDeviceWasapi { }; struct SoundIoWasapi { - SoundIoOsMutex *mutex; - SoundIoOsCond *cond; - SoundIoOsCond *scan_devices_cond; - SoundIoOsMutex *scan_devices_mutex; + struct SoundIoOsMutex *mutex; + struct SoundIoOsCond *cond; + struct SoundIoOsCond *scan_devices_cond; + struct SoundIoOsMutex *scan_devices_mutex; struct SoundIoOsThread *thread; bool abort_flag; // this one is ready to be read with flush_events. protected by mutex @@ -58,17 +59,17 @@ struct SoundIoOutStreamWasapi { IAudioSessionControl *audio_session_control; LPWSTR stream_name; bool need_resample; - SoundIoOsThread *thread; - SoundIoOsMutex *mutex; - SoundIoOsCond *cond; - SoundIoOsCond *start_cond; + struct SoundIoOsThread *thread; + struct SoundIoOsMutex *mutex; + struct SoundIoOsCond *cond; + struct SoundIoOsCond *start_cond; atomic_flag thread_exit_flag; bool is_raw; int writable_frame_count; UINT32 buffer_frame_count; int write_frame_count; HANDLE h_event; - atomic_bool desired_pause_state; + struct SoundIoAtomicBool desired_pause_state; atomic_flag pause_resume_flag; atomic_flag clear_buffer_flag; bool is_paused; @@ -76,7 +77,7 @@ struct SoundIoOutStreamWasapi { int open_err; bool started; UINT32 min_padding_frames; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; struct SoundIoInStreamWasapi { @@ -84,10 +85,10 @@ struct SoundIoInStreamWasapi { IAudioCaptureClient *audio_capture_client; IAudioSessionControl *audio_session_control; LPWSTR stream_name; - SoundIoOsThread *thread; - SoundIoOsMutex *mutex; - SoundIoOsCond *cond; - SoundIoOsCond *start_cond; + struct SoundIoOsThread *thread; + struct SoundIoOsMutex *mutex; + struct SoundIoOsCond *cond; + struct SoundIoOsCond *start_cond; atomic_flag thread_exit_flag; bool is_raw; int readable_frame_count; @@ -100,7 +101,7 @@ struct SoundIoInStreamWasapi { bool started; char *read_buf; int read_buf_frames_left; - SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; + struct SoundIoChannelArea areas[SOUNDIO_MAX_CHANNELS]; }; #endif diff --git a/test/latency.cpp b/test/latency.c similarity index 97% rename from test/latency.cpp rename to test/latency.c index eecc607..abce052 100644 --- a/test/latency.cpp +++ b/test/latency.c @@ -5,15 +5,15 @@ * See http://opensource.org/licenses/MIT */ -#include "soundio.hpp" +#include "soundio_private.h" #include "os.h" -#include "util.hpp" -#include "atomics.hpp" +#include "util.h" #include #include #include #include +#include static int usage(char *exe) { fprintf(stderr, "Usage: %s [--backend dummy|alsa|pulseaudio|jack|coreaudio|wasapi] [--latency seconds]\n", exe); @@ -51,9 +51,9 @@ static int pulse_frames_left = -1; static const double PI = 3.14159265358979323846264338328; static double seconds_offset = 0.0; -static SoundIoRingBuffer pulse_rb; +static struct SoundIoRingBuffer pulse_rb; -static void write_time(SoundIoOutStream *outstream, double extra) { +static void write_time(struct SoundIoOutStream *outstream, double extra) { double latency; int err; if ((err = soundio_outstream_get_latency(outstream, &latency))) { diff --git a/test/unit_tests.cpp b/test/unit_tests.c similarity index 83% rename from test/unit_tests.cpp rename to test/unit_tests.c index cec2b03..2a39282 100644 --- a/test/unit_tests.cpp +++ b/test/unit_tests.c @@ -1,9 +1,9 @@ #undef NDEBUG -#include "soundio.hpp" +#include "soundio_private.h" #include "os.h" -#include "util.hpp" -#include "atomics.hpp" +#include "util.h" +#include "atomics.h" #include #include @@ -58,7 +58,7 @@ static void test_create_outstream(void) { static void test_ring_buffer_basic(void) { struct SoundIo *soundio = soundio_create(); assert(soundio); - SoundIoRingBuffer *rb = soundio_ring_buffer_create(soundio, 10); + struct SoundIoRingBuffer *rb = soundio_ring_buffer_create(soundio, 10); assert(rb); int page_size = soundio_os_page_size(); @@ -98,41 +98,41 @@ static void test_ring_buffer_basic(void) { soundio_destroy(soundio); } -static SoundIoRingBuffer *rb = nullptr; +static struct SoundIoRingBuffer *rb = NULL; static const int rb_size = 3528; static long expected_write_head; static long expected_read_head; -static atomic_bool rb_done; -static atomic_int rb_write_it; -static atomic_int rb_read_it; +static struct SoundIoAtomicBool rb_done; +static struct SoundIoAtomicInt rb_write_it; +static struct SoundIoAtomicInt rb_read_it; // just for testing purposes; does not need to be high quality random static double random_double(void) { return ((double)rand() / (double)RAND_MAX); } -static void reader_thread_run(void *) { - while (!rb_done) { - rb_read_it += 1; +static void reader_thread_run(void *arg) { + while (!SOUNDIO_ATOMIC_LOAD(rb_done)) { + SOUNDIO_ATOMIC_FETCH_ADD(rb_read_it, 1); int fill_count = soundio_ring_buffer_fill_count(rb); assert(fill_count >= 0); assert(fill_count <= rb_size); - int amount_to_read = min((int)(random_double() * 2.0 * fill_count), fill_count); + int amount_to_read = soundio_int_min(random_double() * 2.0 * fill_count, fill_count); soundio_ring_buffer_advance_read_ptr(rb, amount_to_read); expected_read_head += amount_to_read; } } -static void writer_thread_run(void *) { - while (!rb_done) { - rb_write_it += 1; +static void writer_thread_run(void *arg) { + while (!SOUNDIO_ATOMIC_LOAD(rb_done)) { + SOUNDIO_ATOMIC_FETCH_ADD(rb_write_it, 1); int fill_count = soundio_ring_buffer_fill_count(rb); assert(fill_count >= 0); assert(fill_count <= rb_size); int free_count = rb_size - fill_count; assert(free_count >= 0); assert(free_count <= rb_size); - int value = min((int)(random_double() * 2.0 * free_count), free_count); + int value = soundio_int_min(random_double() * 2.0 * free_count, free_count); soundio_ring_buffer_advance_write_ptr(rb, value); expected_write_head += value; } @@ -144,18 +144,18 @@ static void test_ring_buffer_threaded(void) { rb = soundio_ring_buffer_create(soundio, rb_size); expected_write_head = 0; expected_read_head = 0; - rb_read_it = 0; - rb_write_it = 0; - rb_done = false; + SOUNDIO_ATOMIC_STORE(rb_read_it, 0); + SOUNDIO_ATOMIC_STORE(rb_write_it, 0); + SOUNDIO_ATOMIC_STORE(rb_done, false); - SoundIoOsThread *reader_thread; - ok_or_panic(soundio_os_thread_create(reader_thread_run, nullptr, nullptr, &reader_thread)); + struct SoundIoOsThread *reader_thread; + ok_or_panic(soundio_os_thread_create(reader_thread_run, NULL, NULL, &reader_thread)); - SoundIoOsThread *writer_thread; - ok_or_panic(soundio_os_thread_create(writer_thread_run, nullptr, nullptr, &writer_thread)); + struct SoundIoOsThread *writer_thread; + ok_or_panic(soundio_os_thread_create(writer_thread_run, NULL, NULL, &writer_thread)); - while (rb_read_it < 100000 || rb_write_it < 100000) {} - rb_done = true; + while (SOUNDIO_ATOMIC_LOAD(rb_read_it) < 100000 || SOUNDIO_ATOMIC_LOAD(rb_write_it) < 100000) {} + SOUNDIO_ATOMIC_STORE(rb_done, true); soundio_os_thread_destroy(reader_thread); soundio_os_thread_destroy(writer_thread); @@ -219,10 +219,10 @@ struct Test { static struct Test tests[] = { {"os_get_time", test_os_get_time}, {"create output stream", test_create_outstream}, - {"ring buffer basic", test_ring_buffer_basic}, - {"ring buffer threaded", test_ring_buffer_threaded}, {"mirrored memory", test_mirrored_memory}, {"soundio_device_nearest_sample_rate", test_nearest_sample_rate}, + {"ring buffer basic", test_ring_buffer_basic}, + {"ring buffer threaded", test_ring_buffer_threaded}, {NULL, NULL}, }; @@ -233,7 +233,7 @@ static void exec_test(struct Test *test) { } int main(int argc, char *argv[]) { - const char *match = nullptr; + const char *match = NULL; if (argc == 2) match = argv[1];