summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common.c127
-rw-r--r--src/common.h5
-rw-r--r--src/driver.h4
-rw-r--r--src/dso.c20
-rw-r--r--src/null.c4
-rw-r--r--src/sydney.h9
6 files changed, 113 insertions, 56 deletions
diff --git a/src/common.c b/src/common.c
index 5a50f9e..0a7093d 100644
--- a/src/common.c
+++ b/src/common.c
@@ -50,7 +50,8 @@
*/
-#define DEFAULT_LATENCY_USEC (2000000ULL) /* 2s */
+#define DEFAULT_BUFFER_LATENCY_USEC (2000000ULL) /* 2s */
+#define DEFAULT_IMMUTABLE_LATENCY_USEC (500000ULL) /* 500ms */
#define DEFAULT_PROCESS_TIME_USEC (20000ULL) /* 20ms */
static int stream_alloc(sa_stream **_s) {
@@ -180,27 +181,50 @@ fail:
return ret;
}
-static int fix_latency(sa_stream *s, size_t *latency_nbytes, size_t *process_time_nbytes) {
+static int fix_latency(
+ sa_stream *s,
+ size_t *buffer_latency_nbytes,
+ size_t *immutable_latency_nbytes,
+ size_t *process_time_nbytes) {
sa_return_val_if_fail(s, SA_ERROR_INVALID);
- sa_return_val_if_fail(latency_nbytes, SA_ERROR_INVALID);
+ sa_return_val_if_fail(buffer_latency_nbytes, SA_ERROR_INVALID);
sa_return_val_if_fail(process_time_nbytes, SA_ERROR_INVALID);
- if (*latency_nbytes <= 0)
- *latency_nbytes = sa_stream_usec_to_bytes(s, DEFAULT_LATENCY_USEC, 0);
+ if (*buffer_latency_nbytes <= 0)
+ *buffer_latency_nbytes = sa_stream_usec_to_bytes(s, DEFAULT_BUFFER_LATENCY_USEC, 0);
- if (*process_time_nbytes <= 0) {
+ if (immutable_latency_nbytes && *immutable_latency_nbytes <= 0) {
size_t n, m;
- n = sa_stream_frames_to_bytes(s, sa_stream_bytes_to_frames(s, *latency_nbytes, 1)/2);
+ n = sa_stream_frames_to_bytes(s, sa_stream_bytes_to_frames(s, *buffer_latency_nbytes, 0)/2);
+ m = sa_stream_usec_to_bytes(s, DEFAULT_IMMUTABLE_LATENCY_USEC, 0);
+
+ *immutable_latency_nbytes = SA_MIN(n, m);
+ }
+
+ if (*process_time_nbytes <= 0) {
+ size_t l, n, m;
+
+ l = immutable_latency_nbytes ? *immutable_latency_nbytes : *buffer_latency_nbytes;
+
+ n = sa_stream_frames_to_bytes(s, sa_stream_bytes_to_frames(s, l, 1)/2);
m = sa_stream_usec_to_bytes(s, DEFAULT_PROCESS_TIME_USEC, 0);
*process_time_nbytes = SA_MIN(n, m);
}
- sa_return_val_if_fail(*latency_nbytes > 0, SA_ERROR_INVALID);
- sa_return_val_if_fail(*process_time_nbytes >= *latency_nbytes, SA_ERROR_INVALID);
- sa_return_val_if_fail(sa_stream_frame_aligned(s, (int64_t) *latency_nbytes), SA_ERROR_INVALID);
+ if (immutable_latency_nbytes) {
+ sa_return_val_if_fail(*immutable_latency_nbytes > 0, SA_ERROR_INVALID);
+ sa_return_val_if_fail(*immutable_latency_nbytes <= *buffer_latency_nbytes, SA_ERROR_INVALID);
+ sa_return_val_if_fail(*process_time_nbytes <= *immutable_latency_nbytes, SA_ERROR_INVALID);
+ sa_return_val_if_fail(sa_stream_frame_aligned(s, (int64_t) *immutable_latency_nbytes), SA_ERROR_INVALID);
+ }
+
+ sa_return_val_if_fail(*buffer_latency_nbytes > 0, SA_ERROR_INVALID);
+ sa_return_val_if_fail(*process_time_nbytes > 0, SA_ERROR_INVALID);
+ sa_return_val_if_fail(*process_time_nbytes <= *buffer_latency_nbytes, SA_ERROR_INVALID);
+ sa_return_val_if_fail(sa_stream_frame_aligned(s, (int64_t) *buffer_latency_nbytes), SA_ERROR_INVALID);
sa_return_val_if_fail(sa_stream_frame_aligned(s, (int64_t) *process_time_nbytes), SA_ERROR_INVALID);
return SA_SUCCESS;
@@ -219,11 +243,11 @@ static int stream_open_unlocked(sa_stream *s) {
return SA_SUCCESS;
if (s->mode & SA_MODE_RDONLY)
- if ((ret = fix_latency(s, &s->read_latency, &s->read_process_time)) < 0)
+ if ((ret = fix_latency(s, &s->read_overall_latency, NULL, &s->read_process_time)) < 0)
return ret;
if (s->mode & SA_MODE_WRONLY)
- if ((ret = fix_latency(s, &s->write_latency, &s->write_process_time)) < 0)
+ if ((ret = fix_latency(s, &s->write_overall_latency, &s->write_immutable_latency, &s->write_process_time)) < 0)
return ret;
if ((ret = driver_open(s)) == SA_SUCCESS)
@@ -276,22 +300,23 @@ int sa_stream_destroy(sa_stream *s) {
return ret;
}
-int sa_stream_change_write_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes) {
+int sa_stream_change_write_latency(sa_stream *s, size_t overall_latency_nbytes, size_t immutable_latency_nbytes, size_t process_time_nbytes) {
int ret;
sa_return_val_if_fail(s, SA_ERROR_INVALID);
sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
- if ((ret = fix_latency(s, &latency_nbytes, &process_time_nbytes)) < 0)
+ if ((ret = fix_latency(s, &overall_latency_nbytes, &immutable_latency_nbytes, &process_time_nbytes)) < 0)
return ret;
sa_mutex_lock(s->mutex);
sa_return_val_if_fail_unlock(s->state != SA_STATE_DEAD, SA_ERROR_STATE, s->mutex);
- ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_write_latency(s, &latency_nbytes, &process_time_nbytes);
+ ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_write_latency(s, &overall_latency_nbytes, &immutable_latency_nbytes, &process_time_nbytes);
if (ret == SA_SUCCESS) {
- s->write_latency = latency_nbytes;
+ s->write_overall_latency = overall_latency_nbytes;
+ s->write_immutable_latency = immutable_latency_nbytes;
s->write_process_time = process_time_nbytes;
}
@@ -300,22 +325,22 @@ int sa_stream_change_write_latency(sa_stream *s, size_t latency_nbytes, size_t p
return ret;
}
-int sa_stream_change_read_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes) {
+int sa_stream_change_read_latency(sa_stream *s, size_t overall_latency_nbytes, size_t process_time_nbytes) {
int ret;
sa_return_val_if_fail(s, SA_ERROR_INVALID);
sa_return_val_if_fail(s->mode & SA_MODE_RDONLY, SA_ERROR_STATE);
- if ((ret = fix_latency(s, &latency_nbytes, &process_time_nbytes)) < 0)
+ if ((ret = fix_latency(s, &overall_latency_nbytes, NULL, &process_time_nbytes)) < 0)
return ret;
sa_mutex_lock(s->mutex);
sa_return_val_if_fail_unlock(s->state != SA_STATE_DEAD, SA_ERROR_STATE, s->mutex);
- ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_read_latency(s, &latency_nbytes, &process_time_nbytes);
+ ret = s->state == SA_STATE_INIT ? SA_SUCCESS : driver_change_read_latency(s, &overall_latency_nbytes, &process_time_nbytes);
if (ret == SA_SUCCESS) {
- s->read_latency = latency_nbytes;
+ s->read_overall_latency = overall_latency_nbytes;
s->read_process_time = process_time_nbytes;
}
@@ -748,8 +773,8 @@ int sa_stream_get_codec(sa_stream *s, char **codec) {
return SA_SUCCESS;
}
-int sa_stream_get_write_latency(sa_stream *s, size_t *nbytes) {
- size_t latency, process_time;
+int sa_stream_get_write_overall_latency(sa_stream *s, size_t *nbytes) {
+ size_t overall_latency, immutable_latency, process_time;
int ret;
sa_return_val_if_fail(s, SA_ERROR_INVALID);
@@ -758,16 +783,17 @@ int sa_stream_get_write_latency(sa_stream *s, size_t *nbytes) {
sa_mutex_lock(s->mutex);
- latency = s->write_latency;
+ overall_latency = s->write_overall_latency;
+ immutable_latency = s->write_immutable_latency;
process_time = s->write_process_time;
/* In case the latency is not fixated yet, we calculate what it
* would be fixated to */
- if ((ret = fix_latency(s, &latency, &process_time)) < 0)
+ if ((ret = fix_latency(s, &overall_latency, &immutable_latency, &process_time)) < 0)
goto fail;
- *nbytes = latency;
+ *nbytes = overall_latency;
ret = SA_SUCCESS;
fail:
@@ -775,8 +801,8 @@ fail:
return ret;
}
-int sa_stream_get_read_latency(sa_stream *s, size_t *nbytes) {
- size_t latency, process_time;
+int sa_stream_get_read_overall_latency(sa_stream *s, size_t *nbytes) {
+ size_t overall_latency, process_time;
int ret;
sa_return_val_if_fail(s, SA_ERROR_INVALID);
@@ -785,16 +811,44 @@ int sa_stream_get_read_latency(sa_stream *s, size_t *nbytes) {
sa_mutex_lock(s->mutex);
- latency = s->read_latency;
+ overall_latency = s->read_overall_latency;
process_time = s->read_process_time;
/* In case the latency is not fixated yet, we calculate what it
* would be fixated to */
- if ((ret = fix_latency(s, &latency, &process_time)) < 0)
+ if ((ret = fix_latency(s, &overall_latency, NULL, &process_time)) < 0)
+ goto fail;
+
+ *nbytes = overall_latency;
+ ret = SA_SUCCESS;
+
+fail:
+ sa_mutex_unlock(s->mutex);
+ return ret;
+}
+
+int sa_stream_get_write_immutable_latency(sa_stream *s, size_t *nbytes) {
+ size_t overall_latency, immutable_latency, process_time;
+ int ret;
+
+ sa_return_val_if_fail(s, SA_ERROR_INVALID);
+ sa_return_val_if_fail(nbytes, SA_ERROR_INVALID);
+ sa_return_val_if_fail(s->mode & SA_MODE_WRONLY, SA_ERROR_STATE);
+
+ sa_mutex_lock(s->mutex);
+
+ overall_latency = s->write_overall_latency;
+ immutable_latency = s->write_immutable_latency;
+ process_time = s->write_process_time;
+
+ /* In case the latency is not fixated yet, we calculate what it
+ * would be fixated to */
+
+ if ((ret = fix_latency(s, &overall_latency, &immutable_latency, &process_time)) < 0)
goto fail;
- *nbytes = latency;
+ *nbytes = immutable_latency;
ret = SA_SUCCESS;
fail:
@@ -803,7 +857,7 @@ fail:
}
int sa_stream_get_write_process_time(sa_stream *s, size_t *nbytes) {
- size_t latency, process_time;
+ size_t overall_latency, immutable_latency, process_time;
int ret;
sa_return_val_if_fail(s, SA_ERROR_INVALID);
@@ -812,13 +866,14 @@ int sa_stream_get_write_process_time(sa_stream *s, size_t *nbytes) {
sa_mutex_lock(s->mutex);
- latency = s->write_latency;
+ overall_latency = s->write_overall_latency;
+ immutable_latency = s->write_immutable_latency;
process_time = s->write_process_time;
/* In case the latency is not fixated yet, we calculate what it
* would be fixated to */
- if ((ret = fix_latency(s, &latency, &process_time)) < 0)
+ if ((ret = fix_latency(s, &overall_latency, &immutable_latency, &process_time)) < 0)
goto fail;
*nbytes = process_time;
@@ -830,7 +885,7 @@ fail:
}
int sa_stream_get_read_process_time(sa_stream *s, size_t *nbytes) {
- size_t latency, process_time;
+ size_t overall_latency, process_time;
int ret;
sa_return_val_if_fail(s, SA_ERROR_INVALID);
@@ -839,13 +894,13 @@ int sa_stream_get_read_process_time(sa_stream *s, size_t *nbytes) {
sa_mutex_lock(s->mutex);
- latency = s->read_latency;
+ overall_latency = s->read_overall_latency;
process_time = s->read_process_time;
/* In case the latency is not fixated yet, we calculate what it
* would be fixated to */
- if ((ret = fix_latency(s, &latency, &process_time)) < 0)
+ if ((ret = fix_latency(s, &overall_latency, NULL, &process_time)) < 0)
goto fail;
*nbytes = process_time;
diff --git a/src/common.h b/src/common.h
index a89c55f..972bfca 100644
--- a/src/common.h
+++ b/src/common.h
@@ -49,9 +49,10 @@ struct sa_stream {
sa_proplist *props;
- size_t read_latency;
+ size_t read_overall_latency;
size_t read_process_time;
- size_t write_latency;
+ size_t write_overall_latency;
+ size_t write_immutable_latency;
size_t write_process_time;
sa_xrun_mode_t xrun_mode;
diff --git a/src/driver.h b/src/driver.h
index c49d534..554635b 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -26,8 +26,8 @@
int driver_open(sa_stream *s);
int driver_destroy(sa_stream *s);
-int driver_change_write_latency(sa_stream *s, size_t *latency, size_t *process_time);
-int driver_change_read_latency(sa_stream *s, size_t *latency, size_t *process_time);
+int driver_change_write_latency(sa_stream *s, size_t *overall_latency_nbytes, size_t *immutable_latency_nbytes, size_t *process_time);
+int driver_change_read_latency(sa_stream *s, size_t *overall_latency_nbytes, size_t *process_time);
int driver_change_device(sa_stream *s, const char *device_name);
int driver_change_read_volume(sa_stream *s, const int32_t vol[]);
diff --git a/src/dso.c b/src/dso.c
index 71c8fd7..3e8d585 100644
--- a/src/dso.c
+++ b/src/dso.c
@@ -39,8 +39,8 @@ struct private_dso {
int (*driver_destroy)(sa_stream *s);
- int (*driver_change_write_latency)(sa_stream *s, size_t *latency, size_t *process_time);
- int (*driver_change_read_latency)(sa_stream *s, size_t *latency, size_t *process_time);
+ int (*driver_change_write_latency)(sa_stream *s, size_t *overall_latency, size_t *immutable_latency, size_t *process_time);
+ int (*driver_change_read_latency)(sa_stream *s, size_t *overall_latency, size_t *process_time);
int (*driver_change_device)(sa_stream *s, const char *device);
int (*driver_change_read_volume)(sa_stream *s, const int32_t vol[]);
@@ -274,14 +274,14 @@ int driver_open(sa_stream *s) {
if (!(p->driver_open = GET_FUNC_PTR(p->module, driver, "driver_open", int, (sa_stream*))) ||
!(p->driver_destroy = GET_FUNC_PTR(p->module, driver, "driver_destroy", int, (sa_stream*))) ||
- !(p->driver_change_write_latency = GET_FUNC_PTR(p->module, driver, "driver_change_write_latency", int, (sa_stream *s, size_t *latency, size_t *process_time))) ||
- !(p->driver_change_read_latency = GET_FUNC_PTR(p->module, driver, "driver_change_read_latency", int, (sa_stream *s, size_t *latency, size_t *process_time))) ||
+ !(p->driver_change_write_latency = GET_FUNC_PTR(p->module, driver, "driver_change_write_latency", int, (sa_stream *, size_t *, size_t *, size_t *_time))) ||
+ !(p->driver_change_read_latency = GET_FUNC_PTR(p->module, driver, "driver_change_read_latency", int, (sa_stream *, size_t *, size_t *_time))) ||
!(p->driver_change_device = GET_FUNC_PTR(p->module, driver, "driver_change_device", int, (sa_stream*, const char *))) ||
- !(p->driver_change_read_volume = GET_FUNC_PTR(p->module, driver, "driver_change_read_volume", int, (sa_stream *s, const int32_t vol[]))) ||
- !(p->driver_change_write_volume = GET_FUNC_PTR(p->module, driver, "driver_change_write_volume", int, (sa_stream *s, const int32_t vol[]))) ||
- !(p->driver_change_pcm_rate = GET_FUNC_PTR(p->module, driver, "driver_change_pcm_rate", int, (sa_stream *s, unsigned rate))) ||
+ !(p->driver_change_read_volume = GET_FUNC_PTR(p->module, driver, "driver_change_read_volume", int, (sa_stream *s, const int32_t[]))) ||
+ !(p->driver_change_write_volume = GET_FUNC_PTR(p->module, driver, "driver_change_write_volume", int, (sa_stream *s, const int32_t[]))) ||
+ !(p->driver_change_pcm_rate = GET_FUNC_PTR(p->module, driver, "driver_change_pcm_rate", int, (sa_stream *, unsigned))) ||
!(p->driver_change_props = GET_FUNC_PTR(p->module, driver, "driver_change_props", int, (sa_stream *, sa_proplist *, sa_proplist *))) ||
- !(p->driver_get_state = GET_FUNC_PTR(p->module, driver, "driver_get_state", int, (sa_stream *s, sa_state_t *state))) ||
+ !(p->driver_get_state = GET_FUNC_PTR(p->module, driver, "driver_get_state", int, (sa_stream *, sa_state_t *))) ||
!(p->driver_get_position = GET_FUNC_PTR(p->module, driver, "driver_get_position", int, (sa_stream *s, sa_position_t position, int64_t *pos))) ||
!(p->driver_wait = GET_FUNC_PTR(p->module, driver, "driver_wait", int, (sa_stream *s))) ||
!(p->driver_read = GET_FUNC_PTR(p->module, driver, "driver_read", int, (sa_stream *s, void *data, size_t nbytes))) ||
@@ -336,7 +336,7 @@ int driver_destroy(sa_stream *s) {
return ret;
}
-int driver_change_write_latency(sa_stream *s, size_t *latency, size_t *process_time) {
+int driver_change_write_latency(sa_stream *s, size_t *overall_latency, size_t *immutable_latency, size_t *process_time) {
struct private_dso *p;
sa_return_val_if_fail(s, SA_ERROR_INVALID);
@@ -345,7 +345,7 @@ int driver_change_write_latency(sa_stream *s, size_t *latency, size_t *process_t
p = PRIVATE_DSO(s);
sa_return_val_if_fail(p->driver_change_write_latency, SA_ERROR_STATE);
- return p->driver_change_write_latency(s, latency, process_time);
+ return p->driver_change_write_latency(s, overall_latency, immutable_latency, process_time);
}
int driver_change_read_latency(sa_stream *s, size_t *latency, size_t *process_time) {
diff --git a/src/null.c b/src/null.c
index 7948be6..287f96e 100644
--- a/src/null.c
+++ b/src/null.c
@@ -34,11 +34,11 @@ int driver_destroy(sa_stream *s) {
return SA_ERROR_INVALID;
}
-int driver_change_write_latency(sa_stream *s, size_t *latency, size_t *process_time) {
+int driver_change_write_latency(sa_stream *s, size_t *overall_latency, size_t *immutable_latency, size_t *process_time) {
return SA_ERROR_INVALID;
}
-int driver_change_read_latency(sa_stream *s, size_t *latency, size_t *process_time) {
+int driver_change_read_latency(sa_stream *s, size_t *overall_latency, size_t *process_time) {
return SA_ERROR_INVALID;
}
diff --git a/src/sydney.h b/src/sydney.h
index cdc006c..c718299 100644
--- a/src/sydney.h
+++ b/src/sydney.h
@@ -544,8 +544,8 @@ int sa_stream_open(sa_stream *s);
int sa_stream_destroy(sa_stream *s);
/* Buffer params */
-int sa_stream_change_write_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes);
-int sa_stream_change_read_latency(sa_stream *s, size_t latency_nbytes, size_t process_time_nbytes);
+int sa_stream_change_write_latency(sa_stream *s, size_t overall_latency_nbytes, size_t immutable_latency_nbytes, size_t process_time_nbytes);
+int sa_stream_change_read_latency(sa_stream *s, size_t overall_latency_nbytes, size_t process_time_nbytes);
/** Set the mapping between channels and the loudspeakers */
int sa_stream_set_channel_map(sa_stream *s, const sa_channel_t map[], unsigned n);
@@ -595,9 +595,10 @@ int sa_stream_get_pcm_format(sa_stream *s, sa_pcm_format_t *format);
int sa_stream_get_pcm_rate(sa_stream *s, unsigned *rate);
int sa_stream_get_pcm_nchannels(sa_stream *s, unsigned *nchannels);
int sa_stream_get_user_data(sa_stream *s, void **value);
-int sa_stream_get_write_latency(sa_stream *s, size_t *nbytes);
+int sa_stream_get_write_overall_latency(sa_stream *s, size_t *nbytes);
+int sa_stream_get_write_immutable_latency(sa_stream *s, size_t *nbytes);
int sa_stream_get_write_process_time(sa_stream *s, size_t *nbytes);
-int sa_stream_get_read_latency(sa_stream *s, size_t *nbytes);
+int sa_stream_get_read_overall_latency(sa_stream *s, size_t *nbytes);
int sa_stream_get_read_process_time(sa_stream *s, size_t *nbytes);
int sa_stream_get_pcm_channel_map(sa_stream *s, sa_channel_t **map, unsigned *n);
int sa_stream_get_xrun_mode(sa_stream *s, sa_xrun_mode_t *mode);