summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2019-07-09 16:56:05 +0200
committerWim Taymans <wtaymans@redhat.com>2019-07-09 17:44:07 +0200
commitc7d7058896e93daa04923a99fe726231487dcc3c (patch)
treec9390839545cfc85a1223bc480b348ae7625341e /src
parent595dc0ab5ba83a74bda74014e70d1507ef287fc0 (diff)
Improve rate matching and clock slaving
Use a new rate_match io area to exhange rate matching info between sink/source and resampler. Compensate for the rate match delay when scheduling timeouts. Let the resampler notify the source of how many samples it needs to produce the desired quantum. Make sure we keep an extra buffer in the device to be able to make this possible. Let the adapter directly call the slave node process function.
Diffstat (limited to 'src')
-rw-r--r--src/examples/media-session.c2
-rw-r--r--src/modules/module-adapter/adapter.c34
2 files changed, 19 insertions, 17 deletions
diff --git a/src/examples/media-session.c b/src/examples/media-session.c
index 390d5cdd..14a3195b 100644
--- a/src/examples/media-session.c
+++ b/src/examples/media-session.c
@@ -1113,6 +1113,7 @@ do_link_profile:
peer->format.channels, node->format.channels,
audio_info.channels);
+ audio_info.rate = DEFAULT_SAMPLERATE;
node->profile_format = audio_info;
spa_pod_builder_init(&b, buf, sizeof(buf));
@@ -1190,6 +1191,7 @@ static void rescan_session(struct impl *impl, struct session *sess)
}
info = node->format;
+ info.rate = DEFAULT_SAMPLERATE;
props = pw_properties_new_dict(node->info->props);
if ((str = pw_properties_get(props, PW_KEY_DEVICE_NICK)) == NULL)
diff --git a/src/modules/module-adapter/adapter.c b/src/modules/module-adapter/adapter.c
index a084b04e..599971b7 100644
--- a/src/modules/module-adapter/adapter.c
+++ b/src/modules/module-adapter/adapter.c
@@ -140,7 +140,7 @@ struct impl {
uint32_t n_buffers;
struct pw_memblock *mem;
- uint8_t control_buffer[1024];
+ struct spa_io_rate_match rate_match;
};
/** \endcond */
@@ -213,17 +213,20 @@ static void try_link_controls(struct impl *impl)
pw_log_warn(NAME " %p: controls", impl);
+ spa_zero(impl->rate_match);
+ impl->rate_match.rate = 1.0;
+
if ((res = spa_node_port_set_io(impl->slave_node,
impl->direction, 0,
- SPA_IO_Notify,
- impl->control_buffer, sizeof(impl->control_buffer))) < 0) {
- pw_log_warn(NAME " %p: set Notify on slave failed %d %s", impl,
+ SPA_IO_RateMatch,
+ &impl->rate_match, sizeof(impl->rate_match))) < 0) {
+ pw_log_warn(NAME " %p: set RateMatch on slave failed %d %s", impl,
res, spa_strerror(res));
}
if ((res = spa_node_port_set_io(impl->adapter,
SPA_DIRECTION_REVERSE(impl->direction), 0,
- SPA_IO_Control,
- impl->control_buffer, sizeof(impl->control_buffer))) < 0) {
+ SPA_IO_RateMatch,
+ &impl->rate_match, sizeof(impl->rate_match))) < 0) {
pw_log_warn(NAME " %p: set Control on adapter failed %d %s", impl,
res, spa_strerror(res));
}
@@ -694,7 +697,7 @@ static int negotiate_buffers(struct impl *impl)
return res;
}
if (out_alloc) {
- if ((res = spa_node_port_alloc_buffers(impl->slave_port->mix,
+ if ((res = spa_node_port_alloc_buffers(impl->slave_node,
impl->direction, 0,
NULL, 0,
impl->buffers, &impl->n_buffers)) < 0) {
@@ -702,17 +705,10 @@ static int negotiate_buffers(struct impl *impl)
}
}
else {
- if ((res = spa_node_port_use_buffers(impl->slave_port->mix,
+ if ((res = spa_node_port_use_buffers(impl->slave_node,
impl->direction, 0,
impl->buffers, impl->n_buffers)) < 0) {
-
- if (res != -ENOTSUP)
- return res;
-
- if ((res = spa_node_port_use_buffers(impl->slave_port->node->node,
- impl->direction, 0,
- impl->buffers, impl->n_buffers)) < 0)
- return res;
+ return res;
}
}
@@ -894,8 +890,12 @@ static int impl_node_process(void *object)
status = SPA_STATUS_HAVE_BUFFER;
}
- impl->slave->rt.target.signal(impl->slave->rt.target.data);
+ status = spa_node_process(impl->slave_node);
+ if (impl->direction == SPA_DIRECTION_OUTPUT && !impl->this->master) {
+ if (impl->use_converter)
+ status = spa_node_process(impl->adapter);
+ }
return status;
}