hook up some more control streams

This commit is contained in:
Wim Taymans 2018-08-29 12:43:31 +02:00
parent cb3ccb7001
commit 5976beb149
4 changed files with 71 additions and 53 deletions

View file

@ -28,6 +28,7 @@
#include <spa/param/audio/format-utils.h> #include <spa/param/audio/format-utils.h>
#include <spa/param/param.h> #include <spa/param/param.h>
#include <spa/pod/filter.h> #include <spa/pod/filter.h>
#include <spa/control/control.h>
#define NAME "channelmix" #define NAME "channelmix"
@ -57,18 +58,13 @@ struct buffer {
struct spa_meta_header *h; struct spa_meta_header *h;
}; };
struct control {
struct spa_pod_float *volume;
};
struct port { struct port {
uint32_t id; uint32_t id;
struct spa_io_buffers *io; struct spa_io_buffers *io;
struct spa_io_sequence *control;
struct spa_port_info info; struct spa_port_info info;
struct control control;
bool have_format; bool have_format;
struct spa_audio_info format; struct spa_audio_info format;
uint32_t stride; 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_id, "I", SPA_IO_Buffers,
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers)); ":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
break; 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: default:
return 0; return 0;
} }
@ -654,13 +656,16 @@ impl_node_port_set_io(struct spa_node *node,
port = GET_PORT(this, direction, port_id); port = GET_PORT(this, direction, port_id);
if (id == SPA_IO_Buffers) switch (id) {
case SPA_IO_Buffers:
port->io = data; port->io = data;
// else if (id == t->io_prop_volume) break;
// port->control.volume = data; case SPA_IO_Control:
else port->control = data;
break;
default:
return -ENOENT; return -ENOENT;
}
return 0; return 0;
} }
@ -715,6 +720,34 @@ impl_node_port_send_command(struct spa_node *node,
return -ENOTSUP; 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) static int impl_node_process(struct spa_node *node)
{ {
struct impl *this; 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); 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) if (outio->status == SPA_STATUS_HAVE_BUFFER)
goto done; goto done;
@ -755,13 +791,6 @@ static int impl_node_process(struct spa_node *node)
if ((dbuf = dequeue_buffer(this, outport)) == NULL) if ((dbuf = dequeue_buffer(this, outport)) == NULL)
return outio->status = -EPIPE; 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]; sbuf = &inport->buffers[inio->buffer_id];
{ {

View file

@ -440,6 +440,12 @@ impl_node_port_enum_params(struct spa_node *node,
":", SPA_PARAM_IO_id, "I", SPA_IO_Buffers, ":", SPA_PARAM_IO_id, "I", SPA_IO_Buffers,
":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers)); ":", SPA_PARAM_IO_size, "i", sizeof(struct spa_io_buffers));
break; 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: default:
return 0; return 0;
} }

View file

@ -904,18 +904,18 @@ impl_node_port_send_command(struct spa_node *node,
return -ENOTSUP; 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; struct spa_pod_control *c;
SPA_POD_SEQUENCE_FOREACH(&control->sequence, c) { SPA_POD_SEQUENCE_FOREACH(sequence, c) {
switch (c->type) { switch (c->type) {
case SPA_CONTROL_properties: case SPA_CONTROL_properties:
{ {
struct props *p = &this->props; struct props *p = &this->props;
spa_pod_object_parse(&c->value, spa_pod_object_parse(&c->value,
":",SPA_PROP_frequency, "?d", &p->freq, ":", SPA_PROP_frequency, "?d", &p->freq,
":",SPA_PROP_volume, "?d", &p->volume, ":", SPA_PROP_volume, "?d", &p->volume,
NULL); NULL);
break; break;
} }
@ -938,7 +938,7 @@ static int impl_node_process(struct spa_node *node)
spa_return_val_if_fail(io != NULL, -EIO); spa_return_val_if_fail(io != NULL, -EIO);
if (this->io_control) 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) if (io->status == SPA_STATUS_HAVE_BUFFER)
return SPA_STATUS_HAVE_BUFFER; return SPA_STATUS_HAVE_BUFFER;

View file

@ -82,17 +82,10 @@ static void reset_props(struct props *props)
props->volume = DEFAULT_VOLUME; props->volume = DEFAULT_VOLUME;
} }
#define DEFAULT_VOLUME 1.0
struct control {
struct spa_pod_float *volume;
};
struct stream { struct stream {
struct pw_stream this; struct pw_stream this;
struct props props; struct props props;
struct control control;
const char *path; const char *path;
@ -111,6 +104,7 @@ struct stream {
const struct spa_node_callbacks *callbacks; const struct spa_node_callbacks *callbacks;
void *callbacks_data; void *callbacks_data;
struct spa_io_buffers *io; struct spa_io_buffers *io;
struct spa_io_control *io_control;
struct pw_array params; 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) uint32_t id, void *data, size_t size)
{ {
struct stream *impl = SPA_CONTAINER_OF(node, struct stream, impl_node); 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, pw_log_debug("stream %p: set io %s %p %zd", impl,
spa_debug_type_find_name(spa_debug_types, id), data, size); 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)) if (data && size >= sizeof(struct spa_io_buffers))
impl->io = data; impl->io = data;
else else
impl->io = NULL; impl->io = NULL;
} break;
#if 0 case SPA_IO_Control:
else if (id == impl->type.io_prop_volume) { if (data && size >= sizeof(struct spa_io_sequence))
if (data && size >= sizeof(struct spa_pod_float)) { impl->io_control = data;
impl->control.volume = data;
impl->control.volume->value = impl->props.volume;
}
else else
impl->control.volume = NULL; impl->io_control = NULL;
break;
default:
return -ENOENT;
} }
#endif return 0;
else
res = -ENOENT;
return res;
} }
static int impl_port_get_info(struct spa_node *node, enum spa_direction direction, uint32_t port_id, 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) { if (strcmp(name, PW_STREAM_CONTROL_VOLUME) == 0) {
impl->props.volume = value; impl->props.volume = value;
if (stream->state >= PW_STREAM_STATE_READY) {
if (impl->control.volume == NULL)
return -ENODEV;
impl->control.volume->value = value;
}
} }
else else
return -ENOTSUP; 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); struct stream *impl = SPA_CONTAINER_OF(stream, struct stream, this);
if (strcmp(name, PW_STREAM_CONTROL_VOLUME) == 0) { if (strcmp(name, PW_STREAM_CONTROL_VOLUME) == 0) {
if (impl->control.volume == NULL) *value = impl->props.volume;
return -ENODEV;
*value = impl->control.volume->value;
} }
else else
return -ENOTSUP; return -ENOTSUP;