From 5976beb14949d4f7e7cd6d9c7327b9838586c4e6 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 29 Aug 2018 12:43:31 +0200 Subject: [PATCH] hook up some more control streams --- spa/plugins/audioconvert/channelmix.c | 65 ++++++++++++++++++------- spa/plugins/audioconvert/resample.c | 6 +++ spa/plugins/audiotestsrc/audiotestsrc.c | 10 ++-- src/pipewire/stream.c | 43 +++++----------- 4 files changed, 71 insertions(+), 53 deletions(-) diff --git a/spa/plugins/audioconvert/channelmix.c b/spa/plugins/audioconvert/channelmix.c index 46aa3faae..bee9fbabe 100644 --- a/spa/plugins/audioconvert/channelmix.c +++ b/spa/plugins/audioconvert/channelmix.c @@ -28,6 +28,7 @@ #include #include #include +#include #define NAME "channelmix" @@ -57,18 +58,13 @@ struct buffer { struct spa_meta_header *h; }; -struct control { - struct spa_pod_float *volume; -}; - struct port { uint32_t id; struct spa_io_buffers *io; + struct spa_io_sequence *control; struct spa_port_info info; - struct control control; - bool have_format; struct spa_audio_info format; uint32_t stride; @@ -472,6 +468,12 @@ impl_node_port_enum_params(struct spa_node *node, ":", SPA_PARAM_IO_id, "I", SPA_IO_Buffers, ":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers)); break; + case 1: + param = spa_pod_builder_object(&b, + SPA_TYPE_OBJECT_ParamIO, id, + ":", SPA_PARAM_IO_id, "I", SPA_IO_Control, + ":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_sequence)); + break; default: return 0; } @@ -654,13 +656,16 @@ impl_node_port_set_io(struct spa_node *node, port = GET_PORT(this, direction, port_id); - if (id == SPA_IO_Buffers) + switch (id) { + case SPA_IO_Buffers: port->io = data; -// else if (id == t->io_prop_volume) -// port->control.volume = data; - else + break; + case SPA_IO_Control: + port->control = data; + break; + default: return -ENOENT; - + } return 0; } @@ -715,6 +720,34 @@ impl_node_port_send_command(struct spa_node *node, return -ENOTSUP; } +static int process_control(struct impl *this, struct port *port, struct spa_pod_sequence *sequence) +{ + struct spa_pod_control *c; + + SPA_POD_SEQUENCE_FOREACH(sequence, c) { + switch (c->type) { + case SPA_CONTROL_properties: + { + struct props *p = &this->props; + float volume = p->volume; + + spa_pod_object_parse(&c->value, + ":", SPA_PROP_volume, "?f", &volume, + NULL); + + if (volume != p->volume) { + p->volume = volume; + setup_matrix(this, &GET_IN_PORT(this, 0)->format, &GET_OUT_PORT(this, 0)->format); + } + break; + } + default: + break; + } + } + return 0; +} + static int impl_node_process(struct spa_node *node) { struct impl *this; @@ -737,6 +770,9 @@ static int impl_node_process(struct spa_node *node) spa_log_trace(this->log, NAME " %p: status %d %d", this, inio->status, outio->status); + if (outport->control) + process_control(this, outport, &outport->control->sequence); + if (outio->status == SPA_STATUS_HAVE_BUFFER) goto done; @@ -755,13 +791,6 @@ static int impl_node_process(struct spa_node *node) if ((dbuf = dequeue_buffer(this, outport)) == NULL) return outio->status = -EPIPE; - if (outport->control.volume && outport->control.volume->value != this->props.volume) { - this->props.volume = outport->control.volume->value; - setup_matrix(this, - &GET_IN_PORT(this, 0)->format, - &GET_OUT_PORT(this, 0)->format); - } - sbuf = &inport->buffers[inio->buffer_id]; { diff --git a/spa/plugins/audioconvert/resample.c b/spa/plugins/audioconvert/resample.c index 9e8f9177f..be863c470 100644 --- a/spa/plugins/audioconvert/resample.c +++ b/spa/plugins/audioconvert/resample.c @@ -440,6 +440,12 @@ impl_node_port_enum_params(struct spa_node *node, ":", SPA_PARAM_IO_id, "I", SPA_IO_Buffers, ":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers)); break; + case 1: + param = spa_pod_builder_object(&b, + SPA_TYPE_OBJECT_ParamIO, id, + ":", SPA_PARAM_IO_id, "I", SPA_IO_Range, + ":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_range)); + break; default: return 0; } diff --git a/spa/plugins/audiotestsrc/audiotestsrc.c b/spa/plugins/audiotestsrc/audiotestsrc.c index ca19dc164..39a008ef3 100644 --- a/spa/plugins/audiotestsrc/audiotestsrc.c +++ b/spa/plugins/audiotestsrc/audiotestsrc.c @@ -904,18 +904,18 @@ impl_node_port_send_command(struct spa_node *node, return -ENOTSUP; } -static int impl_node_process_control(struct impl *this, struct spa_io_sequence *control) +static int process_control(struct impl *this, struct spa_pod_sequence *sequence) { struct spa_pod_control *c; - SPA_POD_SEQUENCE_FOREACH(&control->sequence, c) { + SPA_POD_SEQUENCE_FOREACH(sequence, c) { switch (c->type) { case SPA_CONTROL_properties: { struct props *p = &this->props; spa_pod_object_parse(&c->value, - ":",SPA_PROP_frequency, "?d", &p->freq, - ":",SPA_PROP_volume, "?d", &p->volume, + ":", SPA_PROP_frequency, "?d", &p->freq, + ":", SPA_PROP_volume, "?d", &p->volume, NULL); break; } @@ -938,7 +938,7 @@ static int impl_node_process(struct spa_node *node) spa_return_val_if_fail(io != NULL, -EIO); if (this->io_control) - impl_node_process_control(this, this->io_control); + process_control(this, &this->io_control->sequence); if (io->status == SPA_STATUS_HAVE_BUFFER) return SPA_STATUS_HAVE_BUFFER; diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 21ee7dab6..94de68267 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -82,17 +82,10 @@ static void reset_props(struct props *props) props->volume = DEFAULT_VOLUME; } -#define DEFAULT_VOLUME 1.0 - -struct control { - struct spa_pod_float *volume; -}; - struct stream { struct pw_stream this; struct props props; - struct control control; const char *path; @@ -111,6 +104,7 @@ struct stream { const struct spa_node_callbacks *callbacks; void *callbacks_data; struct spa_io_buffers *io; + struct spa_io_control *io_control; struct pw_array params; @@ -331,31 +325,27 @@ static int impl_port_set_io(struct spa_node *node, enum spa_direction direction, uint32_t id, void *data, size_t size) { struct stream *impl = SPA_CONTAINER_OF(node, struct stream, impl_node); - int res = 0; pw_log_debug("stream %p: set io %s %p %zd", impl, spa_debug_type_find_name(spa_debug_types, id), data, size); - if (id == SPA_IO_Buffers) { + switch (id) { + case SPA_IO_Buffers: if (data && size >= sizeof(struct spa_io_buffers)) impl->io = data; else impl->io = NULL; - } -#if 0 - else if (id == impl->type.io_prop_volume) { - if (data && size >= sizeof(struct spa_pod_float)) { - impl->control.volume = data; - impl->control.volume->value = impl->props.volume; - } + break; + case SPA_IO_Control: + if (data && size >= sizeof(struct spa_io_sequence)) + impl->io_control = data; else - impl->control.volume = NULL; + impl->io_control = NULL; + break; + default: + return -ENOENT; } -#endif - else - res = -ENOENT; - - return res; + return 0; } static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id, @@ -1068,11 +1058,6 @@ int pw_stream_set_control(struct pw_stream *stream, if (strcmp(name, PW_STREAM_CONTROL_VOLUME) == 0) { impl->props.volume = value; - if (stream->state >= PW_STREAM_STATE_READY) { - if (impl->control.volume == NULL) - return -ENODEV; - impl->control.volume->value = value; - } } else return -ENOTSUP; @@ -1086,9 +1071,7 @@ int pw_stream_get_control(struct pw_stream *stream, struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this); if (strcmp(name, PW_STREAM_CONTROL_VOLUME) == 0) { - if (impl->control.volume == NULL) - return -ENODEV; - *value = impl->control.volume->value; + *value = impl->props.volume; } else return -ENOTSUP;