summaryrefslogtreecommitdiffstats
path: root/common.c
diff options
context:
space:
mode:
Diffstat (limited to 'common.c')
-rw-r--r--common.c585
1 files changed, 436 insertions, 149 deletions
diff --git a/common.c b/common.c
index dfdde95..a08316c 100644
--- a/common.c
+++ b/common.c
@@ -7,6 +7,7 @@
#include "malloc.h"
#include "common.h"
#include "driver.h"
+#include "mutex.h"
/* contains code */
#include "meta-name-table.h"
@@ -19,6 +20,11 @@ static sa_stream_t *stream_alloc(void) {
/* 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;
}
@@ -48,7 +54,7 @@ int sa_stream_create_opaque(
oil_init();
if (client_name)
- if ((error = sa_stream_change_meta_data(*s, SA_META_CLIENT_NAME, client_name, strlen(client_name))) < 0)
+ if ((error = sa_stream_change_meta_data(*s, SA_META_CLIENT_NAME, client_name, strlen(client_name)+1)) < 0)
goto fail;
return SA_SUCCESS;
@@ -136,16 +142,19 @@ int sa_stream_open(sa_stream_t *s) {
int ret;
sa_return_val_if_fail(s, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
- sa_return_val_if_fail(s->codec || s->pcm_attrs.channel_map, SA_ERROR_NO_INIT);
- sa_return_val_if_fail(!(s->mode & SA_MODE_RDONLY) || (s->read_lower_watermark <= s->read_upper_watermark), SA_ERROR_INVALID);
- sa_return_val_if_fail(!(s->mode & SA_MODE_WRONLY) || (s->write_lower_watermark <= s->write_upper_watermark), SA_ERROR_INVALID);
- sa_return_val_if_fail(!(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(!(s->mode & SA_MODE_WRONLY) || !s->codec || (s->write_lower_watermark > 0 && s->write_upper_watermark > 0), SA_ERROR_NO_INIT);
+ 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;
}
@@ -153,7 +162,7 @@ int sa_stream_destroy(sa_stream_t *s) {
int ret;
unsigned u;
- sa_return_val_if_fail(s, SA_ERROR_INVALID);
+ sa_return_val_if_fail_mutex(s->mutex, s, SA_ERROR_INVALID);
ret = driver_destroy(s);
@@ -167,6 +176,7 @@ int sa_stream_destroy(sa_stream_t *s) {
for (u = 0; u < _META_NAMES_MAX; u++)
sa_free(s->meta_data[u]);
+ sa_mutex_free(s->mutex);
sa_free(s);
return ret;
}
@@ -175,10 +185,14 @@ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
- sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
+ 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;
}
@@ -186,10 +200,13 @@ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
- sa_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
+ 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;
}
@@ -197,10 +214,13 @@ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
- sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
+ 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;
}
@@ -208,10 +228,13 @@ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
- sa_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
+ 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;
}
@@ -221,47 +244,62 @@ int sa_stream_set_channel_map(sa_stream_t *s, const sa_channel_t *map, unsigned
sa_return_val_if_fail(s, SA_ERROR_INVALID);
sa_return_val_if_fail(map, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
- sa_return_val_if_fail(!s->codec, SA_ERROR_STATE);
- sa_return_val_if_fail(n == s->pcm_attrs.nchannels, 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)
+ 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)))
+ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
+ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_INVALID);
- sa_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_INVALID);
- sa_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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;
}
@@ -270,23 +308,33 @@ int sa_stream_set_driver(sa_stream_t *s, const char *driver) {
sa_return_val_if_fail(s, SA_ERROR_INVALID);
sa_return_val_if_fail(driver, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
+ 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)))
+ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
+ sa_mutex_lock(s->mutex);
+ sa_return_val_if_fail_mutex(s->mutex, s->state == SA_STATE_INIT, SA_ERROR_STATE);
- return driver_start_thread(s, callback);
+ r = driver_start_thread(s, callback);
+
+ sa_mutex_unlock(s->mutex);
+ return r;
}
int sa_stream_change_device(sa_stream_t *s, const char *device_name) {
@@ -299,6 +347,8 @@ int sa_stream_change_device(sa_stream_t *s, const char *device_name) {
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) {
@@ -307,6 +357,8 @@ int sa_stream_change_device(sa_stream_t *s, const char *device_name) {
} else
sa_free(d);
+ sa_mutex_unlock(s->mutex);
+
return ret;
}
@@ -315,17 +367,22 @@ int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned n
sa_return_val_if_fail(s, SA_ERROR_INVALID);
sa_return_val_if_fail(vol, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
- sa_return_val_if_fail((!s->codec && n == s->pcm_attrs.nchannels) || s->pcm_attrs.nchannels == 1, 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)))
+ 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)))
+ 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];
@@ -339,6 +396,7 @@ int sa_stream_change_read_volume(sa_stream_t *s, const int32_t vol[], unsigned n
} else
sa_free(v);
+ sa_mutex_unlock(s->mutex);
return ret;
}
@@ -347,17 +405,22 @@ int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned
sa_return_val_if_fail(s, SA_ERROR_INVALID);
sa_return_val_if_fail(vol, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
- sa_return_val_if_fail((!s->codec && n == s->pcm_attrs.nchannels) || s->pcm_attrs.nchannels == 1, 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)))
+ 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)))
+ 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];
@@ -371,6 +434,7 @@ int sa_stream_change_write_volume(sa_stream_t *s, const int32_t vol[], unsigned
} else
sa_free(v);
+ sa_mutex_unlock(s->mutex);
return ret;
}
@@ -379,285 +443,434 @@ int sa_stream_change_rate(sa_stream_t *s, unsigned rate) {
sa_return_val_if_fail(s, SA_ERROR_INVALID);
sa_return_val_if_fail(rate > 0, SA_ERROR_INVALID);
- sa_return_val_if_fail(!s->codec, SA_ERROR_STATE);
- sa_return_val_if_fail(s->dynamic_rate_enabled || s->state == SA_STATE_INIT, SA_ERROR_STATE);
+ 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, void *value) {
- sa_return_val_if_fail(s, SA_ERROR_INVALID);
-
- s->user_data = value;
+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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
+ 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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
+ 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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
+ 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_return_val_if_fail(s->state == SA_STATE_INIT, SA_ERROR_STATE);
+ 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_return_val_if_fail(state, SA_ERROR_INVALID);
+ sa_mutex_lock(s->mutex);
+ sa_return_val_if_fail_mutex(s->mutex, state, SA_ERROR_INVALID);
+
+ ret = driver_get_state(s, state);
- return 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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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, const char **codec) {
+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(codec, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->codec, SA_ERROR_STATE);
+ 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;
+ }
- *codec = s->codec;
+ 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_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
+ 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_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
+ 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_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
+ 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_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
+ 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, const sa_channel_t *map[]) {
+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(map, SA_ERROR_INVALID);
- sa_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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;
+ }
- *map = s->pcm_attrs.channel_map;
+ 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->ni_enabled;
+ *enabled = s->dynamic_rate_enabled;
+
+ sa_mutex_unlock(s->mutex);
return SA_SUCCESS;
}
-int sa_stream_get_driver(sa_stream_t *s, const char **driver) {
+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(driver, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->driver, SA_ERROR_STATE);
+ 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;
+ }
- *driver = s->driver;
+ 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, const char **device_name) {
+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(device_name, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->device, SA_ERROR_STATE);
+ 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;
+ }
- *device_name = s->device;
+ 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, const int32_t *vol[]) {
+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(vol, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->read_volume, SA_ERROR_STATE);
+ 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;
- *vol = s->read_volume;
+ sa_mutex_unlock(s->mutex);
return SA_SUCCESS;
}
-int sa_stream_get_write_volume(sa_stream_t *s, const int32_t *vol[]) {
+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(vol, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->write_volume, SA_ERROR_STATE);
+ 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;
- *vol = s->write_volume;
+ 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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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_return_val_if_fail(!s->codec, SA_ERROR_STATE);
+ 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(s, SA_ERROR_INVALID);
- sa_return_val_if_fail(direction, SA_ERROR_INVALID);
+ 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_return_val_if_fail(s->event == SA_EVENT_ERROR, SA_ERROR_STATE);
+ 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_return_val_if_fail(s->event == SA_EVENT_NOTIFY, SA_ERROR_STATE);
+ 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_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
+ 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);
- return 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) {
@@ -677,103 +890,157 @@ int sa_stream_write_ni(sa_stream_t *s, unsigned channel, const void *data, size_
}
int sa_stream_pread(sa_stream_t *s, 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_return_val_if_fail(!s->ni_enabled, SA_ERROR_STATE);
- sa_return_val_if_fail(s->codec || (nbytes % s->pcm_frame_size) == 0, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->codec || (offset % s->pcm_frame_size) == 0, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
+ 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_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);
- return driver_pread(s, data, nbytes, offset, whence);
+ ret = driver_pread(s, data, nbytes, offset, whence);
+
+ sa_mutex_unlock(s->mutex);
+ return ret;
}
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_return_val_if_fail(!s->ni_enabled, SA_ERROR_STATE);
- sa_return_val_if_fail(s->codec || (nbytes % s->pcm_frame_size) == 0, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->codec || (offset % s->pcm_frame_size) == 0, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
+ 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);
- return driver_pwrite(s, data, nbytes, offset, whence);
+ ret = driver_pwrite(s, data, nbytes, offset, whence);
+
+ sa_mutex_unlock(s->mutex);
+ return ret;
}
int sa_stream_pread_ni(sa_stream_t *s, unsigned channel, 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(!s->codec, SA_ERROR_STATE);
sa_return_val_if_fail(whence == SA_SEEK_RELATIVE || whence == SA_SEEK_ABSOLUTE || whence == SA_SEEK_RELATIVE_END, SA_ERROR_INVALID);
- sa_return_val_if_fail(channel < s->pcm_attrs.nchannels, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->ni_enabled, SA_ERROR_STATE);
- sa_return_val_if_fail((nbytes % s->pcm_sample_size) == 0, SA_ERROR_INVALID);
- sa_return_val_if_fail((offset % s->pcm_sample_size) == 0, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
-
- return driver_pread_ni(s, channel, data, nbytes, offset, whence);
+ 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_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_pread_ni(s, channel, 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(!s->codec, SA_ERROR_STATE);
sa_return_val_if_fail(whence == SA_SEEK_RELATIVE || whence == SA_SEEK_ABSOLUTE || whence == SA_SEEK_RELATIVE_END, SA_ERROR_INVALID);
- sa_return_val_if_fail(channel < s->pcm_attrs.nchannels, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->ni_enabled, SA_ERROR_STATE);
- sa_return_val_if_fail((nbytes % s->pcm_sample_size) == 0, SA_ERROR_INVALID);
- sa_return_val_if_fail((offset % s->pcm_sample_size) == 0, SA_ERROR_INVALID);
- sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
-
- return driver_pwrite_ni(s, channel, data, nbytes, offset, whence);
+ 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_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
+ 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);
- return driver_get_read_size(s, size);
+ 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_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
+ 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);
- return driver_get_write_size(s, size);
+ 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_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
+ 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);
- return driver_resume(s);
+ 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_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
+ 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);
- return 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_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
- sa_return_val_if_fail(s->state == SA_STATE_RUNNING || s->state == SA_STATE_STOPPED, SA_ERROR_STATE);
+ 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);
- return driver_drain(s);
+ sa_mutex_unlock(s->mutex);
+ return ret;
}
size_t get_pcm_sample_size(sa_pcm_format_t f) {
@@ -899,17 +1166,24 @@ int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *dat
sa_return_val_if_fail(s, SA_ERROR_INVALID);
sa_return_val_if_fail(name, SA_ERROR_INVALID);
- sa_return_val_if_fail(data || size == 0, SA_ERROR_INVALID);
+ sa_mutex_lock(s->mutex);
+ sa_return_val_if_fail_mutex(s->mutex, data || size == 0, SA_ERROR_INVALID);
- if (!(m = lookup_meta_name(name, strlen(name))))
+ if (!(m = lookup_meta_name(name, strlen(name)))) {
+ sa_mutex_unlock(s->mutex);
return SA_ERROR_NO_META;
+ }
- if (!check_table[m->idx](data, size))
+ if (!check_table[m->idx](data, size)) {
+ sa_mutex_unlock(s->mutex);
return SA_ERROR_INVALID;
+ }
if (data)
- if (!(d = sa_memdup(data, size)))
+ 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);
@@ -920,26 +1194,39 @@ int sa_stream_change_meta_data(sa_stream_t *s, const char *name, const void *dat
} else
sa_free(d);
+ sa_mutex_unlock(s->mutex);
return ret;
}
-int sa_stream_get_meta_data(sa_stream_t *s, const char *name, const void **data, size_t *size) {
+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(data, SA_ERROR_INVALID);
- sa_return_val_if_fail(size, SA_ERROR_INVALID);
+ sa_return_val_if_fail(size && (*size == 0 || data), SA_ERROR_INVALID);
+ sa_mutex_lock(s->mutex);
- if (!(m = lookup_meta_name(name, strlen(name))))
+ if (!(m = lookup_meta_name(name, strlen(name)))) {
+ sa_mutex_unlock(s->mutex);
return SA_ERROR_NO_META;
+ }
- if (!s->meta_data[m->idx])
+ 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]);
- *data = s->meta_data[m->idx];
*size = s->meta_data_size[m->idx];
+ sa_mutex_unlock(s->mutex);
return SA_SUCCESS;
}