mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
hook up some more control streams
This commit is contained in:
parent
cb3ccb7001
commit
5976beb149
4 changed files with 71 additions and 53 deletions
|
|
@ -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];
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue