closer to compiling on OS X

This commit is contained in:
Andrew Kelley 2015-07-01 13:24:47 -07:00
parent 46b43356f9
commit 24557e0ee3
5 changed files with 56 additions and 43 deletions

View file

@ -18,6 +18,11 @@
#include <errno.h> #include <errno.h>
#include <stdio.h> #include <stdio.h>
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
#endif
struct SoundIoOsThread { struct SoundIoOsThread {
pthread_attr_t attr; pthread_attr_t attr;
bool attr_init; bool attr_init;
@ -43,11 +48,26 @@ struct SoundIoOsCond {
}; };
double soundio_os_get_time(void) { double soundio_os_get_time(void) {
#ifdef __MACH__
clock_serv_t cclock;
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
kern_return_t err = clock_get_time(cclock, &mts);
assert(!err);
mach_port_deallocate(mach_task_self(), cclock);
double seconds = (double)mts.tv_sec;
seconds += ((double)mts.tv_nsec) / 1000000000.0;
return seconds;
#else
struct timespec tms; struct timespec tms;
clock_gettime(CLOCK_MONOTONIC, &tms); clock_gettime(CLOCK_MONOTONIC, &tms);
double seconds = (double)tms.tv_sec; double seconds = (double)tms.tv_sec;
seconds += ((double)tms.tv_nsec) / 1000000000.0; seconds += ((double)tms.tv_nsec) / 1000000000.0;
return seconds; return seconds;
#endif
} }
static void assert_no_err(int err) { static void assert_no_err(int err) {
@ -64,13 +84,6 @@ static void emit_rtprio_warning(void) {
"warning:-unable-to-set-high-priority-thread:-Operation-not-permitted\n"); "warning:-unable-to-set-high-priority-thread:-Operation-not-permitted\n");
} }
int soundio_os_concurrency(void) {
long cpu_core_count = sysconf(_SC_NPROCESSORS_ONLN);
if (cpu_core_count <= 0)
cpu_core_count = 1;
return cpu_core_count;
}
static void *run_thread(void *userdata) { static void *run_thread(void *userdata) {
struct SoundIoOsThread *thread = (struct SoundIoOsThread *)userdata; struct SoundIoOsThread *thread = (struct SoundIoOsThread *)userdata;
thread->run(thread->arg); thread->run(thread->arg);

View file

@ -62,7 +62,7 @@ static void subscribe_to_events(SoundIo *soundio) {
pa_operation *subscribe_op = pa_context_subscribe(ah->pulse_context, pa_operation *subscribe_op = pa_context_subscribe(ah->pulse_context,
events, nullptr, soundio); events, nullptr, soundio);
if (!subscribe_op) if (!subscribe_op)
panic("pa_context_subscribe failed: %s", pa_strerror(pa_context_errno(ah->pulse_context))); soundio_panic("pa_context_subscribe failed: %s", pa_strerror(pa_context_errno(ah->pulse_context)));
pa_operation_unref(subscribe_op); pa_operation_unref(subscribe_op);
} }
@ -94,7 +94,7 @@ static void context_state_callback(pa_context *context, void *userdata) {
if (err_number == PA_ERR_CONNECTIONREFUSED) { if (err_number == PA_ERR_CONNECTIONREFUSED) {
ah->connection_refused = true; ah->connection_refused = true;
} else { } else {
panic("pulseaudio connect failure: %s", pa_strerror(pa_context_errno(context))); soundio_panic("pulseaudio connect failure: %s", pa_strerror(pa_context_errno(context)));
} }
return; return;
} }
@ -195,7 +195,7 @@ static SoundIoChannelId from_pulseaudio_channel_pos(pa_channel_position_t pos) {
case PA_CHANNEL_POSITION_TOP_REAR_CENTER: return SoundIoChannelIdTopBackCenter; case PA_CHANNEL_POSITION_TOP_REAR_CENTER: return SoundIoChannelIdTopBackCenter;
default: default:
panic("cannot map pulseaudio channel to libsoundio"); soundio_panic("cannot map pulseaudio channel to libsoundio");
} }
} }
@ -277,14 +277,14 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in
} else { } else {
SoundIoDevice *device = create<SoundIoDevice>(); SoundIoDevice *device = create<SoundIoDevice>();
if (!device) if (!device)
panic("out of memory"); soundio_panic("out of memory");
device->ref_count = 1; device->ref_count = 1;
device->soundio = soundio; device->soundio = soundio;
device->name = strdup(info->name); device->name = strdup(info->name);
device->description = strdup(info->description); device->description = strdup(info->description);
if (!device->name || !device->description) if (!device->name || !device->description)
panic("out of memory"); soundio_panic("out of memory");
set_from_pulseaudio_channel_map(info->channel_map, &device->channel_layout); set_from_pulseaudio_channel_map(info->channel_map, &device->channel_layout);
device->default_sample_format = sample_format_from_pulseaudio(info->sample_spec); device->default_sample_format = sample_format_from_pulseaudio(info->sample_spec);
device->default_latency = usec_to_sec(info->configured_latency); device->default_latency = usec_to_sec(info->configured_latency);
@ -292,7 +292,7 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in
device->purpose = SoundIoDevicePurposeOutput; device->purpose = SoundIoDevicePurposeOutput;
if (ah->current_devices_info->output_devices.append(device)) if (ah->current_devices_info->output_devices.append(device))
panic("out of memory"); soundio_panic("out of memory");
} }
pa_threaded_mainloop_signal(ah->main_loop, 0); pa_threaded_mainloop_signal(ah->main_loop, 0);
} }
@ -306,14 +306,14 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info
} else { } else {
SoundIoDevice *device = create<SoundIoDevice>(); SoundIoDevice *device = create<SoundIoDevice>();
if (!device) if (!device)
panic("out of memory"); soundio_panic("out of memory");
device->ref_count = 1; device->ref_count = 1;
device->soundio = soundio; device->soundio = soundio;
device->name = strdup(info->name); device->name = strdup(info->name);
device->description = strdup(info->description); device->description = strdup(info->description);
if (!device->name || !device->description) if (!device->name || !device->description)
panic("out of memory"); soundio_panic("out of memory");
set_from_pulseaudio_channel_map(info->channel_map, &device->channel_layout); set_from_pulseaudio_channel_map(info->channel_map, &device->channel_layout);
device->default_sample_format = sample_format_from_pulseaudio(info->sample_spec); device->default_sample_format = sample_format_from_pulseaudio(info->sample_spec);
device->default_latency = usec_to_sec(info->configured_latency); device->default_latency = usec_to_sec(info->configured_latency);
@ -321,7 +321,7 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info
device->purpose = SoundIoDevicePurposeInput; device->purpose = SoundIoDevicePurposeInput;
if (ah->current_devices_info->input_devices.append(device)) if (ah->current_devices_info->input_devices.append(device))
panic("out of memory"); soundio_panic("out of memory");
} }
pa_threaded_mainloop_signal(ah->main_loop, 0); pa_threaded_mainloop_signal(ah->main_loop, 0);
} }
@ -338,7 +338,7 @@ static void server_info_callback(pa_context *pulse_context, const pa_server_info
ah->default_source_name = strdup(info->default_source_name); ah->default_source_name = strdup(info->default_source_name);
if (!ah->default_sink_name || !ah->default_source_name) if (!ah->default_sink_name || !ah->default_source_name)
panic("out of memory"); soundio_panic("out of memory");
ah->have_default_sink = true; ah->have_default_sink = true;
finish_device_query(soundio); finish_device_query(soundio);
@ -355,7 +355,7 @@ static void scan_devices(SoundIo *soundio) {
destroy_current_devices_info(soundio); destroy_current_devices_info(soundio);
ah->current_devices_info = create<SoundIoDevicesInfo>(); ah->current_devices_info = create<SoundIoDevicesInfo>();
if (!ah->current_devices_info) if (!ah->current_devices_info)
panic("out of memory"); soundio_panic("out of memory");
pa_threaded_mainloop_lock(ah->main_loop); pa_threaded_mainloop_lock(ah->main_loop);
@ -367,11 +367,11 @@ static void scan_devices(SoundIo *soundio) {
server_info_callback, soundio); server_info_callback, soundio);
if (perform_operation(soundio, list_sink_op)) if (perform_operation(soundio, list_sink_op))
panic("list sinks failed"); soundio_panic("list sinks failed");
if (perform_operation(soundio, list_source_op)) if (perform_operation(soundio, list_source_op))
panic("list sources failed"); soundio_panic("list sources failed");
if (perform_operation(soundio, server_info_op)) if (perform_operation(soundio, server_info_op))
panic("get server info failed"); soundio_panic("get server info failed");
pa_threaded_mainloop_signal(ah->main_loop, 0); pa_threaded_mainloop_signal(ah->main_loop, 0);
@ -447,18 +447,18 @@ static pa_sample_format_t to_pulseaudio_sample_format(SoundIoSampleFormat sample
case SoundIoSampleFormatFloat: case SoundIoSampleFormatFloat:
return PA_SAMPLE_FLOAT32NE; return PA_SAMPLE_FLOAT32NE;
case SoundIoSampleFormatDouble: case SoundIoSampleFormatDouble:
panic("cannot use double sample format with pulseaudio"); soundio_panic("cannot use double sample format with pulseaudio");
case SoundIoSampleFormatInvalid: case SoundIoSampleFormatInvalid:
panic("invalid sample format"); soundio_panic("invalid sample format");
} }
panic("invalid sample format"); soundio_panic("invalid sample format");
} }
static pa_channel_position_t to_pulseaudio_channel_pos(SoundIoChannelId channel_id) { static pa_channel_position_t to_pulseaudio_channel_pos(SoundIoChannelId channel_id) {
switch (channel_id) { switch (channel_id) {
case SoundIoChannelIdInvalid: case SoundIoChannelIdInvalid:
case SoundIoChannelIdCount: case SoundIoChannelIdCount:
panic("invalid channel id"); soundio_panic("invalid channel id");
case SoundIoChannelIdFrontLeft: case SoundIoChannelIdFrontLeft:
return PA_CHANNEL_POSITION_FRONT_LEFT; return PA_CHANNEL_POSITION_FRONT_LEFT;
case SoundIoChannelIdFrontRight: case SoundIoChannelIdFrontRight:
@ -496,7 +496,7 @@ static pa_channel_position_t to_pulseaudio_channel_pos(SoundIoChannelId channel_
case SoundIoChannelIdTopBackRight: case SoundIoChannelIdTopBackRight:
return PA_CHANNEL_POSITION_TOP_REAR_RIGHT; return PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
} }
panic("invalid channel id"); soundio_panic("invalid channel id");
} }
static pa_channel_map to_pulseaudio_channel_map(const SoundIoChannelLayout *channel_layout) { static pa_channel_map to_pulseaudio_channel_map(const SoundIoChannelLayout *channel_layout) {
@ -504,7 +504,7 @@ static pa_channel_map to_pulseaudio_channel_map(const SoundIoChannelLayout *chan
channel_map.channels = channel_layout->channel_count; channel_map.channels = channel_layout->channel_count;
if ((unsigned)channel_layout->channel_count > PA_CHANNELS_MAX) if ((unsigned)channel_layout->channel_count > PA_CHANNELS_MAX)
panic("channel layout greater than pulseaudio max channels"); soundio_panic("channel layout greater than pulseaudio max channels");
for (int i = 0; i < channel_layout->channel_count; i += 1) for (int i = 0; i < channel_layout->channel_count; i += 1)
channel_map.map[i] = to_pulseaudio_channel_pos(channel_layout->channels[i]); channel_map.map[i] = to_pulseaudio_channel_pos(channel_layout->channels[i]);
@ -527,7 +527,7 @@ static void playback_stream_state_callback(pa_stream *stream, void *userdata) {
pa_threaded_mainloop_signal(ah->main_loop, 0); pa_threaded_mainloop_signal(ah->main_loop, 0);
break; break;
case PA_STREAM_FAILED: case PA_STREAM_FAILED:
panic("pulseaudio stream error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); soundio_panic("pulseaudio stream error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
break; break;
} }
} }
@ -651,7 +651,7 @@ static void output_device_begin_write_pa(SoundIo *soundio,
pa_stream *stream = opd->stream; pa_stream *stream = opd->stream;
size_t byte_count = *frame_count * output_device->bytes_per_frame; size_t byte_count = *frame_count * output_device->bytes_per_frame;
if (pa_stream_begin_write(stream, (void**)data, &byte_count)) if (pa_stream_begin_write(stream, (void**)data, &byte_count))
panic("pa_stream_begin_write error: %s", pa_strerror(pa_context_errno(ah->pulse_context))); soundio_panic("pa_stream_begin_write error: %s", pa_strerror(pa_context_errno(ah->pulse_context)));
*frame_count = byte_count / output_device->bytes_per_frame; *frame_count = byte_count / output_device->bytes_per_frame;
} }
@ -664,7 +664,7 @@ static void output_device_write_pa(SoundIo *soundio,
pa_stream *stream = opd->stream; pa_stream *stream = opd->stream;
size_t byte_count = frame_count * output_device->bytes_per_frame; size_t byte_count = frame_count * output_device->bytes_per_frame;
if (pa_stream_write(stream, data, byte_count, NULL, 0, PA_SEEK_RELATIVE)) if (pa_stream_write(stream, data, byte_count, NULL, 0, PA_SEEK_RELATIVE))
panic("pa_stream_write error: %s", pa_strerror(pa_context_errno(ah->pulse_context))); soundio_panic("pa_stream_write error: %s", pa_strerror(pa_context_errno(ah->pulse_context)));
} }
static void output_device_clear_buffer_pa(SoundIo *soundio, static void output_device_clear_buffer_pa(SoundIo *soundio,
@ -676,7 +676,7 @@ static void output_device_clear_buffer_pa(SoundIo *soundio,
pa_threaded_mainloop_lock(ah->main_loop); pa_threaded_mainloop_lock(ah->main_loop);
pa_operation *op = pa_stream_flush(stream, NULL, NULL); pa_operation *op = pa_stream_flush(stream, NULL, NULL);
if (!op) if (!op)
panic("pa_stream_flush failed: %s", pa_strerror(pa_context_errno(ah->pulse_context))); soundio_panic("pa_stream_flush failed: %s", pa_strerror(pa_context_errno(ah->pulse_context)));
pa_operation_unref(op); pa_operation_unref(op);
pa_threaded_mainloop_unlock(ah->main_loop); pa_threaded_mainloop_unlock(ah->main_loop);
} }
@ -693,7 +693,7 @@ static void recording_stream_state_callback(pa_stream *stream, void *userdata) {
ord->stream_ready = true; ord->stream_ready = true;
break; break;
case PA_STREAM_FAILED: case PA_STREAM_FAILED:
panic("pulseaudio stream error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); soundio_panic("pulseaudio stream error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
break; break;
} }
} }
@ -793,7 +793,7 @@ static void input_device_peek_pa(SoundIo *soundio,
if (ord->stream_ready) { if (ord->stream_ready) {
size_t nbytes; size_t nbytes;
if (pa_stream_peek(stream, (const void **)data, &nbytes)) if (pa_stream_peek(stream, (const void **)data, &nbytes))
panic("pa_stream_peek error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); soundio_panic("pa_stream_peek error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
*frame_count = ((int)nbytes) / input_device->bytes_per_frame; *frame_count = ((int)nbytes) / input_device->bytes_per_frame;
} else { } else {
*data = nullptr; *data = nullptr;
@ -807,7 +807,7 @@ static void input_device_drop_pa(SoundIo *soundio,
SoundIoInputDevicePulseAudio *ord = (SoundIoInputDevicePulseAudio *)input_device->backend_data; SoundIoInputDevicePulseAudio *ord = (SoundIoInputDevicePulseAudio *)input_device->backend_data;
pa_stream *stream = ord->stream; pa_stream *stream = ord->stream;
if (pa_stream_drop(stream)) if (pa_stream_drop(stream))
panic("pa_stream_drop error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); soundio_panic("pa_stream_drop error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
} }
static void input_device_clear_buffer_pa(SoundIo *soundio, static void input_device_clear_buffer_pa(SoundIo *soundio,
@ -826,13 +826,13 @@ static void input_device_clear_buffer_pa(SoundIo *soundio,
const char *data; const char *data;
size_t nbytes; size_t nbytes;
if (pa_stream_peek(stream, (const void **)&data, &nbytes)) if (pa_stream_peek(stream, (const void **)&data, &nbytes))
panic("pa_stream_peek error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); soundio_panic("pa_stream_peek error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
if (nbytes == 0) if (nbytes == 0)
break; break;
if (pa_stream_drop(stream)) if (pa_stream_drop(stream))
panic("pa_stream_drop error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream)))); soundio_panic("pa_stream_drop error: %s", pa_strerror(pa_context_errno(pa_stream_get_context(stream))));
} }
pa_threaded_mainloop_unlock(ah->main_loop); pa_threaded_mainloop_unlock(ah->main_loop);

View file

@ -21,7 +21,7 @@ const char *soundio_error_string(int error) {
case SoundIoErrorSystemResources: return "system resource not available"; case SoundIoErrorSystemResources: return "system resource not available";
case SoundIoErrorOpeningDevice: return "unable to open device"; case SoundIoErrorOpeningDevice: return "unable to open device";
} }
panic("invalid error enum value: %d", error); soundio_panic("invalid error enum value: %d", error);
} }
int soundio_get_bytes_per_sample(enum SoundIoSampleFormat sample_format) { int soundio_get_bytes_per_sample(enum SoundIoSampleFormat sample_format) {
@ -32,9 +32,9 @@ int soundio_get_bytes_per_sample(enum SoundIoSampleFormat sample_format) {
case SoundIoSampleFormatInt32: return 4; case SoundIoSampleFormatInt32: return 4;
case SoundIoSampleFormatFloat: return 4; case SoundIoSampleFormatFloat: return 4;
case SoundIoSampleFormatDouble: return 8; case SoundIoSampleFormatDouble: return 8;
case SoundIoSampleFormatInvalid: panic("invalid sample format"); case SoundIoSampleFormatInvalid: soundio_panic("invalid sample format");
} }
panic("invalid sample format"); soundio_panic("invalid sample format");
} }
const char * soundio_sample_format_string(enum SoundIoSampleFormat sample_format) { const char * soundio_sample_format_string(enum SoundIoSampleFormat sample_format) {
@ -47,7 +47,7 @@ const char * soundio_sample_format_string(enum SoundIoSampleFormat sample_format
case SoundIoSampleFormatDouble: return "64-bit float"; case SoundIoSampleFormatDouble: return "64-bit float";
case SoundIoSampleFormatInvalid: return "invalid sample format"; case SoundIoSampleFormatInvalid: return "invalid sample format";
} }
panic("invalid sample format"); soundio_panic("invalid sample format");
} }
@ -58,7 +58,7 @@ const char *soundio_backend_name(enum SoundIoBackend backend) {
case SoundIoBackendPulseAudio: return "PulseAudio"; case SoundIoBackendPulseAudio: return "PulseAudio";
case SoundIoBackendDummy: return "Dummy"; case SoundIoBackendDummy: return "Dummy";
} }
panic("invalid backend enum value: %d", (int)backend); soundio_panic("invalid backend enum value: %d", (int)backend);
} }
void soundio_destroy(struct SoundIo *soundio) { void soundio_destroy(struct SoundIo *soundio) {

View file

@ -11,7 +11,7 @@
#include "util.hpp" #include "util.hpp"
void panic(const char *format, ...) { void soundio_panic(const char *format, ...) {
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
vfprintf(stderr, format, ap); vfprintf(stderr, format, ap);

View file

@ -79,7 +79,7 @@ static inline void destroy(T * ptr) {
free(ptr); free(ptr);
} }
void panic(const char *format, ...) void soundio_panic(const char *format, ...)
__attribute__((cold)) __attribute__((cold))
__attribute__ ((noreturn)) __attribute__ ((noreturn))
__attribute__ ((format (printf, 1, 2))); __attribute__ ((format (printf, 1, 2)));