From 7d83e5c7816b5e343695a75ba58b32dbe1be969a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 1 Oct 2007 20:16:28 +0000 Subject: move all sources down to a seperate src/ tree git-svn-id: file:///home/lennart/svn/public/libsydney/trunk@34 9ba3c220-e4d3-45a2-8aa3-73fcc9aff6ce --- common.c | 1266 -------------------------------------------------------------- 1 file changed, 1266 deletions(-) delete mode 100644 common.c (limited to 'common.c') diff --git a/common.c b/common.c deleted file mode 100644 index 5a81d02..0000000 --- a/common.c +++ /dev/null @@ -1,1266 +0,0 @@ -#include -#include -#include - -#include "sydney.h" -#include "macro.h" -#include "malloc.h" -#include "common.h" -#include "driver.h" -#include "mutex.h" - -/* contains code */ -#include "meta-name-table.h" - -static sa_stream_t *stream_alloc(void) { - sa_stream_t *d; - - if (!(d = sa_new0(sa_stream_t, 1))) - return NULL; - - /* All fields a carefully chosen in a way that initializing them - * NUL bytes is sufficient */ - - if (!(d->mutex = sa_mutex_new(0))) { - sa_free(d); - return NULL; - } - - return d; -} - -int sa_stream_create_opaque( - sa_stream_t **s, - const char *client_name, - sa_mode_t mode, - const char *codec) { - - int error; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(mode == SA_MODE_RDONLY || mode == SA_MODE_WRONLY || mode == SA_MODE_RDWR, SA_ERROR_INVALID); - sa_return_val_if_fail(codec, SA_ERROR_INVALID); - - if (!(*s = stream_alloc())) - return SA_ERROR_OOM; - - (*s)->mode = mode; - - if (!((*s)->codec = sa_strdup(codec))) { - error = SA_ERROR_OOM; - goto fail; - } - - oil_init(); - - if (client_name) - if ((error = sa_stream_change_meta_data(*s, SA_META_CLIENT_NAME, client_name, strlen(client_name)+1)) < 0) - goto fail; - - return SA_SUCCESS; - -fail: - sa_stream_destroy(*s); - return error; -} - -int sa_stream_create_pcm( - sa_stream_t **s, - const char *client_name, - sa_mode_t mode, - sa_pcm_format_t format, - unsigned rate, - unsigned nchannels) { - - int ret; - size_t lwm; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(mode == SA_MODE_RDONLY || mode == SA_MODE_WRONLY || mode == SA_MODE_RDWR, SA_ERROR_INVALID); - sa_return_val_if_fail(format < _SA_PCM_FORMAT_MAX, SA_ERROR_INVALID); - sa_return_val_if_fail(rate > 0, SA_ERROR_INVALID); - sa_return_val_if_fail(nchannels > 0, SA_ERROR_INVALID); - - if (!(*s = stream_alloc())) - return SA_ERROR_OOM; - - (*s)->mode = mode; - (*s)->pcm_attrs.format = format; - (*s)->pcm_attrs.nchannels = nchannels; - (*s)->pcm_sample_size = sa_get_pcm_sample_size(format); - (*s)->pcm_frame_size = (*s)->pcm_sample_size * nchannels; - - if (nchannels <= 2) { - static const sa_channel_t map_stereo[2] = { SA_CHANNEL_LEFT, SA_CHANNEL_RIGHT }; - static const sa_channel_t map_mono[1] = { SA_CHANNEL_MONO }; - - if ((ret = sa_stream_set_channel_map(*s, nchannels == 2 ? map_stereo : map_mono, nchannels))) - goto fail; - } - - if ((ret = sa_stream_change_rate(*s, rate))) - goto fail; - - lwm = ((*s)->pcm_frame_size * (*s)->pcm_attrs.rate) / 20; /* 50 ms */ - - if (lwm <= 0) - lwm = (*s)->pcm_frame_size * (*s)->pcm_attrs.rate; /* 1s */ - - if (mode & SA_MODE_RDONLY) { - - if ((ret = sa_stream_set_read_lower_watermark(*s, lwm))) - goto fail; - - if ((ret = sa_stream_set_read_upper_watermark(*s, lwm*2))) - goto fail; - } - - if (mode & SA_MODE_WRONLY) { - - if ((ret = sa_stream_set_write_lower_watermark(*s, lwm))) - goto fail; - - if ((ret = sa_stream_set_write_upper_watermark(*s, lwm*2))) - goto fail; - } - - oil_init(); - - if (client_name) - if ((ret = sa_stream_change_meta_data(*s, SA_META_CLIENT_NAME, client_name, strlen(client_name))) < 0) - goto fail; - - return SA_SUCCESS; - -fail: - - sa_stream_destroy(*s); - return ret; -} - -int sa_stream_open(sa_stream_t *s) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->codec || s->pcm_attrs.channel_map, SA_ERROR_NO_INIT); - sa_return_val_if_fail_mutex(s->mutex, !(s->mode & SA_MODE_RDONLY) || (s->read_lower_watermark <= s->read_upper_watermark), SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, !(s->mode & SA_MODE_WRONLY) || (s->write_lower_watermark <= s->write_upper_watermark), SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, !(s->mode & SA_MODE_RDONLY) || !s->codec || (s->read_lower_watermark > 0 && s->read_upper_watermark > 0), SA_ERROR_NO_INIT); - sa_return_val_if_fail_mutex(s->mutex, !(s->mode & SA_MODE_WRONLY) || !s->codec || (s->write_lower_watermark > 0 && s->write_upper_watermark > 0), SA_ERROR_NO_INIT); - - if ((ret = driver_open(s)) == 0) - s->state = SA_STATE_STOPPED; - - sa_mutex_unlock(s->mutex); - - return ret; -} - -int sa_stream_destroy(sa_stream_t *s) { - int ret; - unsigned u; - - sa_return_val_if_fail_mutex(s->mutex, s, SA_ERROR_INVALID); - - ret = driver_destroy(s); - - sa_free(s->codec); - sa_free(s->driver); - sa_free(s->device); - sa_free(s->pcm_attrs.channel_map); - sa_free(s->read_volume); - sa_free(s->write_volume); - - for (u = 0; u < _META_NAMES_MAX; u++) - sa_free(s->meta_data[u]); - - sa_mutex_free(s->mutex); - sa_free(s); - return ret; -} - -int sa_stream_set_write_lower_watermark(sa_stream_t *s, size_t size) { - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size > 0, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - - s->write_lower_watermark = size; - - sa_mutex_unlock(s->mutex); - - return SA_SUCCESS; -} - -int sa_stream_set_read_lower_watermark(sa_stream_t *s, size_t size) { - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size > 0, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - - s->read_lower_watermark = size; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_write_upper_watermark(sa_stream_t *s, size_t size) { - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size > 0, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - - s->write_upper_watermark = size; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_read_upper_watermark(sa_stream_t *s, size_t size) { - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size > 0, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - - s->read_upper_watermark = size; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t *map, unsigned n) { - const sa_channel_t *c; - sa_channel_t *m; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(map, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, n == s->pcm_attrs.nchannels, SA_ERROR_INVALID); - - for (c = map; n > 0; c++, n--) - if (*c >= _SA_CHANNEL_MAX) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_INVALID; - } - - if (!(m = sa_memdup(map, sizeof(sa_channel_t) * s->pcm_attrs.nchannels))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_OOM; - } - - sa_free(s->pcm_attrs.channel_map); - s->pcm_attrs.channel_map = m; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_xrun_mode(sa_stream_t *s, sa_xrun_mode_t mode) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(mode == SA_XRUN_MODE_STOP || mode == SA_XRUN_MODE_SPIN, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - - s->xrun_mode = mode; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_non_interleaved(sa_stream_t *s, int enable) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - s->ni_enabled = !!enable; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_dynamic_rate(sa_stream_t *s, int enable) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - s->dynamic_rate_enabled = !!enable; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_driver(sa_stream_t *s, const char *driver) { - char *d; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(driver, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - - if (!(d = sa_strdup(driver))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_OOM; - } - - sa_free(s->driver); - s->driver = d; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_start_thread(sa_stream_t *s, sa_event_callback_t callback) { - int r; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(callback, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, !s->callback, SA_ERROR_STATE); - - r = driver_start_thread(s, callback); - - if (r == SA_SUCCESS) - s->callback = callback; - - sa_mutex_unlock(s->mutex); - return r; -} - -int sa_stream_stop_thread(sa_stream_t *s) { - int r; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->callback, SA_ERROR_STATE); - - r = driver_stop_thread(s); - - if (r == SA_SUCCESS) - s->callback = NULL; - - sa_mutex_unlock(s->mutex); - return r; -} - -int sa_stream_change_device(sa_stream_t *s, const char *device_name) { - char *d; - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(device_name, SA_ERROR_INVALID); - - if (!(d = sa_strdup(device_name))) - return SA_ERROR_OOM; - - sa_mutex_lock(s->mutex); - - ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_device(s, device_name); - - if (ret == SA_SUCCESS) { - sa_free(s->device); - s->device = d; - } else - sa_free(d); - - sa_mutex_unlock(s->mutex); - - return ret; -} - -int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned n) { - int *v, ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(vol, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, (!s->codec && n == s->pcm_attrs.nchannels) || s->pcm_attrs.nchannels == 1, SA_ERROR_INVALID); - - if (s->codec || s->pcm_attrs.nchannels == n) { - if (!(v = sa_newdup(int32_t, vol, n))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_OOM; - } - } else { - unsigned i; - - if (!(v = sa_new(int32_t, s->pcm_attrs.nchannels))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_OOM; - } - - for (i = 0; i < s->pcm_attrs.nchannels; i++) - v[i] = vol[0]; - } - - ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_read_volume(s, v); - - if (ret == SA_SUCCESS) { - sa_free(s->read_volume); - s->read_volume = v; - } else - sa_free(v); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned n) { - int *v, ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(vol, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, (!s->codec && n == s->pcm_attrs.nchannels) || s->pcm_attrs.nchannels == 1, SA_ERROR_INVALID); - - if (s->codec || s->pcm_attrs.nchannels == n) { - if (!(v = sa_newdup(int32_t, vol, n))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_OOM; - } - } else { - unsigned i; - - if (!(v = sa_new(int32_t, s->pcm_attrs.nchannels))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_OOM; - } - - for (i = 0; i < s->pcm_attrs.nchannels; i++) - v[i] = vol[0]; - } - - ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_write_volume(s, v); - - if (ret == SA_SUCCESS) { - sa_free(s->write_volume); - s->write_volume = v; - } else - sa_free(v); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_change_rate(sa_stream_t *s, unsigned rate) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(rate > 0, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->dynamic_rate_enabled || s->state == SA_STATE_INIT, SA_ERROR_STATE); - - ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_rate(s, rate); - - if (ret == SA_SUCCESS) - s->pcm_attrs.rate = rate; - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_change_user_data(sa_stream_t *s, const void *value) { - sa_return_val_if_fail(s->mutex, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - - s->user_data = (void*) value; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_adjust_rate(sa_stream_t *s, sa_adjust_t direction) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - - s->adjust_rate = direction; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_adjust_nchannels(sa_stream_t *s, sa_adjust_t direction) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - - s->adjust_rate = direction; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_adjust_pcm_format(sa_stream_t *s, sa_adjust_t direction) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - - s->adjust_pcm_format = direction; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_set_adjust_watermarks(sa_stream_t *s, sa_adjust_t direction) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE); - - s->adjust_watermarks = direction; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_state(sa_stream_t *s, sa_state_t *state) { - int ret; - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, state, SA_ERROR_INVALID); - - if (s->state == SA_STATE_INIT) { - *state = s->state; - ret = SA_SUCCESS; - } else - ret = driver_get_state(s, state); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_get_rate(sa_stream_t *s, unsigned *rate) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(rate, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - *rate = s->pcm_attrs.rate; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_nchannels(sa_stream_t *s, int *nchannels) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(nchannels, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - *nchannels = s->pcm_attrs.nchannels; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_pcm_format(sa_stream_t *s, sa_pcm_format_t *pcm_format) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(pcm_format, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - *pcm_format = s->pcm_attrs.format; - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_mode(sa_stream_t *s, sa_mode_t *access_mode) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(access_mode, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - - *access_mode = s->mode; - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_codec(sa_stream_t *s, char *codec, size_t *size) { - size_t n; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size && (*size == 0 || codec), SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->codec, SA_ERROR_STATE); - - n = strlen(s->codec)+1; - if (*size < n) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_SPACE; - } - - if (codec) - strcpy(codec, s->codec); - *size = n; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_write_lower_watermark(sa_stream_t *s, size_t *size) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - - *size = s->write_lower_watermark; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_read_lower_watermark(sa_stream_t *s, size_t *size) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - - *size = s->read_lower_watermark; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_write_upper_watermark(sa_stream_t *s, size_t *size) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - - *size = s->write_upper_watermark; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_read_upper_watermark(sa_stream_t *s, size_t *size) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - - *size = s->read_upper_watermark; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_channel_map(sa_stream_t *s, sa_channel_t *map, unsigned *n) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(n && (*n == 0 || map), SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - if (*n < s->pcm_attrs.nchannels) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_SPACE; - } - - if (map) - memcpy(map, s->pcm_attrs.channel_map, s->pcm_attrs.nchannels * sizeof(sa_channel_t)); - *n = s->pcm_attrs.nchannels; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_xrun_mode(sa_stream_t *s, sa_xrun_mode_t *mode) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(mode, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - - *mode = s->xrun_mode; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_non_interleaved(sa_stream_t *s, int *enabled) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(enabled, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - - *enabled = s->ni_enabled; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_dynamic_rate(sa_stream_t *s, int *enabled) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(enabled, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - - *enabled = s->dynamic_rate_enabled; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_driver(sa_stream_t *s, char *driver, size_t *size) { - size_t n; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size && (*size == 0 || driver), SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->driver, SA_ERROR_STATE); - - n = strlen(s->driver)+1; - if (*size < n) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_SPACE; - } - - if (driver) - strcpy(driver, s->driver); - *size = n; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_device(sa_stream_t *s, char *device, size_t *size) { - size_t n; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size && (*size == 0 || device), SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->device, SA_ERROR_STATE); - - n = strlen(s->device)+1; - if (*size < n) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_SPACE; - } - - if (device) - strcpy(device, s->device); - *size = n; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_read_volume(sa_stream_t *s, int32_t vol[], unsigned *n) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(n && (*n == 0 || vol), SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->read_volume, SA_ERROR_STATE); - - if (*n < s->pcm_attrs.nchannels) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_SPACE; - } - - if (vol) - memcpy(vol, s->read_volume, s->pcm_attrs.nchannels * sizeof(int32_t)); - *n = s->pcm_attrs.nchannels; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_write_volume(sa_stream_t *s, int32_t vol[], unsigned *n) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(n && (*n == 0 || vol), SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->write_volume, SA_ERROR_STATE); - - if (*n < s->pcm_attrs.nchannels) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_SPACE; - } - - if (vol) - memcpy(vol, s->write_volume, s->pcm_attrs.nchannels * sizeof(int32_t)); - *n = s->pcm_attrs.nchannels; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_adjust_rate(sa_stream_t *s, sa_adjust_t *direction) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(direction, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - *direction = s->adjust_rate; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_adjust_nchannels(sa_stream_t *s, sa_adjust_t *direction) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(direction, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - *direction = s->adjust_nchannels; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_adjust_pcm_format(sa_stream_t *s, sa_adjust_t *direction) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(direction, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - - *direction = s->adjust_pcm_format; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_adjust_watermarks(sa_stream_t *s, sa_adjust_t *direction) { - sa_return_val_if_fail_mutex(s->mutex, s, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, direction, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - - *direction = s->adjust_watermarks; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_user_data(sa_stream_t *s, void **value) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(value, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - - *value = s->user_data; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_event_error(sa_stream_t *s, sa_error_t *error) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(error, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->event == SA_EVENT_ERROR, SA_ERROR_STATE); - - *error = s->error; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_event_notify(sa_stream_t *s, sa_notify_t *notify) { - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(notify, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->event == SA_EVENT_NOTIFY, SA_ERROR_STATE); - - *notify = s->notify; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -int sa_stream_get_position(sa_stream_t *s, sa_position_t position, int64_t *pos) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(pos, SA_ERROR_INVALID); - sa_return_val_if_fail(position < _SA_POSITION_MAX, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_get_position(s, position, pos); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_read(sa_stream_t *s, void *data, size_t nbytes) { - int ret; - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(data, SA_ERROR_INVALID); - sa_return_val_if_fail(nbytes > 0, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->ni_enabled, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->codec || (nbytes % s->pcm_frame_size) == 0, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_read(s, data, nbytes); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_read_ni(sa_stream_t *s, unsigned channel, void *data, size_t nbytes) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(data, SA_ERROR_INVALID); - sa_return_val_if_fail(nbytes > 0, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, channel < s->pcm_attrs.nchannels, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, s->ni_enabled, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, (nbytes % s->pcm_sample_size) == 0, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_read_ni(s, channel, data, nbytes); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_write(sa_stream_t *s, const void *data, size_t nbytes) { - return sa_stream_pwrite(s, data, nbytes, 0, SA_SEEK_RELATIVE); -} - -int sa_stream_write_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes) { - return sa_stream_pwrite_ni(s, channel, data, nbytes, 0, SA_SEEK_RELATIVE); -} - -int sa_stream_pwrite(sa_stream_t *s, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(data, SA_ERROR_INVALID); - sa_return_val_if_fail(nbytes > 0, SA_ERROR_INVALID); - sa_return_val_if_fail(whence == SA_SEEK_RELATIVE || whence == SA_SEEK_ABSOLUTE || whence == SA_SEEK_RELATIVE_END, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->ni_enabled, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->codec || (nbytes % s->pcm_frame_size) == 0, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, s->codec || (offset % s->pcm_frame_size) == 0, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_pwrite(s, data, nbytes, offset, whence); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_pwrite_ni(sa_stream_t *s, unsigned channel, const void *data, size_t nbytes, int64_t offset, sa_seek_t whence) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(data, SA_ERROR_INVALID); - sa_return_val_if_fail(nbytes > 0, SA_ERROR_INVALID); - sa_return_val_if_fail(whence == SA_SEEK_RELATIVE || whence == SA_SEEK_ABSOLUTE || whence == SA_SEEK_RELATIVE_END, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, !s->codec, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, channel < s->pcm_attrs.nchannels, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, s->ni_enabled, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, (nbytes % s->pcm_sample_size) == 0, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, (offset % s->pcm_sample_size) == 0, SA_ERROR_INVALID); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_pwrite_ni(s, channel, data, nbytes, offset, whence); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_get_read_size(sa_stream_t *s, size_t *size) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_RDONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_get_read_size(s, size); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_get_write_size(sa_stream_t *s, size_t *size) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(size, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_get_write_size(s, size); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_resume(sa_stream_t *s) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_resume(s); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_pause(sa_stream_t *s) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_pause(s); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_drain(sa_stream_t *s) { - int ret; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, s->mode & SA_MODE_WRONLY, SA_ERROR_STATE); - sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE); - - ret = driver_drain(s); - - sa_mutex_unlock(s->mutex); - return ret; -} - -size_t sa_get_pcm_sample_size(sa_pcm_format_t f) { - - switch (f) { - case SA_PCM_FORMAT_U8: - case SA_PCM_FORMAT_ULAW: - case SA_PCM_FORMAT_ALAW: - return 1; - - case SA_PCM_FORMAT_S16_LE: - case SA_PCM_FORMAT_S16_BE: - return 2; - case SA_PCM_FORMAT_S24_LE: - case SA_PCM_FORMAT_S24_BE: - return 3; - - case SA_PCM_FORMAT_S32_LE: - case SA_PCM_FORMAT_S32_BE: - case SA_PCM_FORMAT_FLOAT32_LE: - case SA_PCM_FORMAT_FLOAT32_BE: - return 4; - - case _SA_PCM_FORMAT_MAX: - ; - } - - sa_assert_not_reached(); -} - -static int meta_check_png(const void *data, size_t size) { - static const uint8_t png_signature[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; - sa_assert(data); - - if (size < sizeof(png_signature)) - return 0; - - return memcmp(data, png_signature, 8) == 0; -} - -static int meta_check_utf8(const void *data, size_t size) { - int32_t idx; - - oil_utf8_validate(&idx, data, size); - - return (size_t) idx == size; -} - -static int meta_check_pid(const void *data, size_t size) { - long int pid; - char *t; - - if (size <= 0) - return 0; - - if (memchr(data, 0, size)) - return 0; - - if (!(t = sa_strndup(data, size))) - return 0; - - errno = 0; - pid = strtol(t, NULL, 10); - sa_free(t); - - if (errno != 0) - return 0; - - if (pid <= 1) - return 0; - - return 1; -} - -static int meta_check_icon_name(const void *data, size_t size) { - const char *t = data; - - if (size <= 0) - return 0; - - if (memchr(data, 0, size)) - return 0; - - if (size == 1 && t[0] == '.') - return 0; - - if (size == 2 && t[0] == '.' && t[1] == '.') - return 0; - - if (memchr(t, '/', size)) - return 0; - - return 1; -} - -static int meta_check_word(const void *data, size_t size) { - const char *t = data; - - for (; size > 0; size --, t++) - if (*t <= 32 || *t >= 127) - return 0; - - return 1; -} - -typedef int (*meta_check_func_t)(const void *data, size_t size); - -int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *data, size_t size) { - void *d = NULL; - const struct meta_name *m; - int ret; - - static const meta_check_func_t check_table[] = { - meta_check_utf8, - meta_check_pid, - meta_check_word, /* FIXME */ - meta_check_utf8, - meta_check_icon_name, - meta_check_png, - meta_check_word, /* FIXME */ - meta_check_word, /* FIXME */ - }; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(name, SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - sa_return_val_if_fail_mutex(s->mutex, data || size == 0, SA_ERROR_INVALID); - - if (!(m = sa_lookup_meta_name(name, strlen(name)))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_META; - } - - if (!check_table[m->idx](data, size)) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_INVALID; - } - - if (data) - if (!(d = sa_memdup(data, size))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_OOM; - } - - ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_meta_data(s, name, data, size); - - if (ret == SA_SUCCESS) { - sa_free(s->meta_data[m->idx]); - s->meta_data[m->idx] = d; - s->meta_data_size[m->idx] = size; - } else - sa_free(d); - - sa_mutex_unlock(s->mutex); - return ret; -} - -int sa_stream_get_meta_data(sa_stream_t *s, const char *name, void *data, size_t *size) { - const struct meta_name *m; - - sa_return_val_if_fail(s, SA_ERROR_INVALID); - sa_return_val_if_fail(name, SA_ERROR_INVALID); - sa_return_val_if_fail(size && (*size == 0 || data), SA_ERROR_INVALID); - sa_mutex_lock(s->mutex); - - if (!(m = sa_lookup_meta_name(name, strlen(name)))) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_META; - } - - if (!s->meta_data[m->idx]) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_DATA; - } - - if (*size < s->meta_data_size[m->idx]) { - sa_mutex_unlock(s->mutex); - return SA_ERROR_NO_SPACE; - } - - if (data) - memcpy(data, s->meta_data[m->idx], s->meta_data_size[m->idx]); - - *size = s->meta_data_size[m->idx]; - - sa_mutex_unlock(s->mutex); - return SA_SUCCESS; -} - -const char *sa_strerror(int code) { - const char * const error_table[-_SA_ERROR_MAX] = { - [-SA_SUCCESS] = "Success", - [-SA_ERROR_NOT_SUPPORTED] = "Operation not supported", - [-SA_ERROR_INVALID] = "Invalid argument", - [-SA_ERROR_STATE] = "Invalid state", - [-SA_ERROR_OOM] = "Out of memory", - [-SA_ERROR_NO_DEVICE] = "No such device", - [-SA_ERROR_NO_DRIVER] = "No such driver", - [-SA_ERROR_NO_CODEC] = "No such codec", - [-SA_ERROR_NO_PCM_FORMAT] = "No such PCM format", - [-SA_ERROR_SYSTEM] = "System error", - [-SA_ERROR_NO_INIT] = "Not initialized", - [-SA_ERROR_NO_META] = "No such meta name", - [-SA_ERROR_NO_DATA] = "No such data" - }; - - sa_return_val_if_fail(code <= 0, NULL); - sa_return_val_if_fail(code > _SA_ERROR_MAX, NULL); - - return error_table[-code]; -} -- cgit