test-mixer: animate volume controls

Fix volume in audiomixer.
This commit is contained in:
Wim Taymans 2017-11-23 18:04:39 +01:00
parent cb3198c458
commit 7f4363d367
3 changed files with 52 additions and 18 deletions

View file

@ -823,19 +823,19 @@ add_port_data(struct impl *this, void *out, size_t outsize, struct port *port, i
} }
} }
else if (volume < 0.999 || volume > 1.001) { else if (volume < 0.999 || volume > 1.001) {
mix_func_t mix = layer == 0 ? this->copy : this->add;
mix(out, SPA_MEMBER(data, offset, void), len1);
if (len2 > 0)
mix(out + len1, data, len2);
}
else {
mix_scale_func_t mix = layer == 0 ? this->copy_scale : this->add_scale; mix_scale_func_t mix = layer == 0 ? this->copy_scale : this->add_scale;
mix(out, SPA_MEMBER(data, offset, void), volume, len1); mix(out, SPA_MEMBER(data, offset, void), volume, len1);
if (len2 > 0) if (len2 > 0)
mix(out + len1, data, volume, len2); mix(out + len1, data, volume, len2);
} }
else {
mix_func_t mix = layer == 0 ? this->copy : this->add;
mix(out, SPA_MEMBER(data, offset, void), len1);
if (len2 > 0)
mix(out + len1, data, len2);
}
port->queued_bytes -= outsize; port->queued_bytes -= outsize;

View file

@ -1,6 +1,6 @@
executable('test-mixer', 'test-mixer.c', executable('test-mixer', 'test-mixer.c',
include_directories : [spa_inc ], include_directories : [spa_inc ],
dependencies : [dl_lib, pthread_lib], dependencies : [dl_lib, pthread_lib, libm],
link_with : spalib, link_with : spalib,
install : false) install : false)
executable('test-ringbuffer', 'test-ringbuffer.c', executable('test-ringbuffer', 'test-ringbuffer.c',

View file

@ -17,6 +17,8 @@
* Boston, MA 02110-1301, USA. * Boston, MA 02110-1301, USA.
*/ */
#include <math.h>
#include <error.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -40,6 +42,8 @@
#define USE_GRAPH #define USE_GRAPH
#define M_PI_M2 ( M_PI + M_PI )
static SPA_TYPE_MAP_IMPL(default_map, 4096); static SPA_TYPE_MAP_IMPL(default_map, 4096);
static SPA_LOG_IMPL(default_log); static SPA_LOG_IMPL(default_log);
@ -57,6 +61,7 @@ struct type {
uint32_t props_volume; uint32_t props_volume;
uint32_t props_min_latency; uint32_t props_min_latency;
uint32_t props_live; uint32_t props_live;
uint32_t io_inprop_volume;
struct spa_type_io io; struct spa_type_io io;
struct spa_type_param param; struct spa_type_param param;
struct spa_type_meta meta; struct spa_type_meta meta;
@ -79,6 +84,7 @@ static inline void init_type(struct type *type, struct spa_type_map *map)
type->props_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume); type->props_volume = spa_type_map_get_id(map, SPA_TYPE_PROPS__volume);
type->props_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency); type->props_min_latency = spa_type_map_get_id(map, SPA_TYPE_PROPS__minLatency);
type->props_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live); type->props_live = spa_type_map_get_id(map, SPA_TYPE_PROPS__live);
type->io_inprop_volume = spa_type_map_get_id(map, SPA_TYPE_IO_INPUT_PROP_BASE "volume");
spa_type_io_map(map, &type->io); spa_type_io_map(map, &type->io);
spa_type_param_map(map, &type->param); spa_type_param_map(map, &type->param);
spa_type_meta_map(map, &type->meta); spa_type_meta_map(map, &type->meta);
@ -127,6 +133,8 @@ struct data {
uint32_t mix_ports[2]; uint32_t mix_ports[2];
struct spa_buffer *mix_buffers[1]; struct spa_buffer *mix_buffers[1];
struct buffer mix_buffer[1]; struct buffer mix_buffer[1];
struct spa_pod_double ctrl_volume[2];
double volume_accum;
struct spa_node *source1; struct spa_node *source1;
struct spa_io_buffers source1_mix_io[1]; struct spa_io_buffers source1_mix_io[1];
@ -247,9 +255,20 @@ static void on_sink_event(void *data, struct spa_event *event)
printf("got event %d\n", SPA_EVENT_TYPE(event)); printf("got event %d\n", SPA_EVENT_TYPE(event));
} }
static void update_props(struct data *data)
{
data->ctrl_volume[0].value = ((sin(data->volume_accum) + 1.0) * 0.5);
data->volume_accum += M_PI_M2 / 8800.0;
if (data->volume_accum >= M_PI_M2)
data->volume_accum -= M_PI_M2;
data->ctrl_volume[1].value = 1.0 - data->ctrl_volume[0].value;
}
static void on_sink_need_input(void *_data) static void on_sink_need_input(void *_data)
{ {
struct data *data = _data; struct data *data = _data;
#ifdef USE_GRAPH #ifdef USE_GRAPH
spa_graph_need_input(&data->graph, &data->sink_node); spa_graph_need_input(&data->graph, &data->sink_node);
#else #else
@ -283,6 +302,7 @@ static void on_sink_need_input(void *_data)
printf("got process_output error from mixer %d\n", res); printf("got process_output error from mixer %d\n", res);
} }
#endif #endif
update_props(data);
} }
static void static void
@ -350,7 +370,7 @@ static int make_nodes(struct data *data, const char *device)
":", data->type.props_min_latency, "i", MIN_LATENCY); ":", data->type.props_min_latency, "i", MIN_LATENCY);
if ((res = spa_node_set_param(data->sink, data->type.param.idProps, 0, props)) < 0) if ((res = spa_node_set_param(data->sink, data->type.param.idProps, 0, props)) < 0)
printf("got set_props error %d\n", res); error(0, -res, "set_param props");
if ((res = make_node(data, &data->mix, if ((res = make_node(data, &data->mix,
"build/spa/plugins/audiomixer/libspa-audiomixer.so", "build/spa/plugins/audiomixer/libspa-audiomixer.so",
@ -370,7 +390,7 @@ static int make_nodes(struct data *data, const char *device)
props = spa_pod_builder_object(&b, props = spa_pod_builder_object(&b,
0, data->type.props, 0, data->type.props,
":", data->type.props_freq, "d", 600.0, ":", data->type.props_freq, "d", 600.0,
":", data->type.props_volume, "d", 0.5, ":", data->type.props_volume, "d", 1.0,
":", data->type.props_live, "b", false); ":", data->type.props_live, "b", false);
if ((res = spa_node_set_param(data->source1, data->type.param.idProps, 0, props)) < 0) if ((res = spa_node_set_param(data->source1, data->type.param.idProps, 0, props)) < 0)
@ -387,7 +407,7 @@ static int make_nodes(struct data *data, const char *device)
props = spa_pod_builder_object(&b, props = spa_pod_builder_object(&b,
0, data->type.props, 0, data->type.props,
":", data->type.props_freq, "d", 440.0, ":", data->type.props_freq, "d", 440.0,
":", data->type.props_volume, "d", 0.5, ":", data->type.props_volume, "d", 1.0,
":", data->type.props_live, "b", false); ":", data->type.props_live, "b", false);
if ((res = spa_node_set_param(data->source2, data->type.param.idProps, 0, props)) < 0) if ((res = spa_node_set_param(data->source2, data->type.param.idProps, 0, props)) < 0)
@ -414,11 +434,11 @@ static int make_nodes(struct data *data, const char *device)
data->type.io.Buffers, data->type.io.Buffers,
&data->source2_mix_io[0], sizeof(data->source2_mix_io[0])); &data->source2_mix_io[0], sizeof(data->source2_mix_io[0]));
spa_node_port_set_io(data->mix, spa_node_port_set_io(data->mix,
SPA_DIRECTION_INPUT, 0, SPA_DIRECTION_INPUT, data->mix_ports[0],
data->type.io.Buffers, data->type.io.Buffers,
&data->source1_mix_io[0], sizeof(data->source1_mix_io[0])); &data->source1_mix_io[0], sizeof(data->source1_mix_io[0]));
spa_node_port_set_io(data->mix, spa_node_port_set_io(data->mix,
SPA_DIRECTION_INPUT, 1, SPA_DIRECTION_INPUT, data->mix_ports[1],
data->type.io.Buffers, data->type.io.Buffers,
&data->source2_mix_io[0], sizeof(data->source2_mix_io[0])); &data->source2_mix_io[0], sizeof(data->source2_mix_io[0]));
spa_node_port_set_io(data->mix, spa_node_port_set_io(data->mix,
@ -430,6 +450,22 @@ static int make_nodes(struct data *data, const char *device)
data->type.io.Buffers, data->type.io.Buffers,
&data->mix_sink_io[0], sizeof(data->mix_sink_io[0])); &data->mix_sink_io[0], sizeof(data->mix_sink_io[0]));
data->ctrl_volume[0] = SPA_POD_DOUBLE_INIT(0.5);
data->ctrl_volume[1] = SPA_POD_DOUBLE_INIT(0.5);
if ((res = spa_node_port_set_io(data->mix,
SPA_DIRECTION_INPUT, data->mix_ports[0],
data->type.io_inprop_volume,
&data->ctrl_volume[0], sizeof(data->ctrl_volume[0]))) < 0)
error(0, -res, "set_io volume 0");
if ((res = spa_node_port_set_io(data->mix,
SPA_DIRECTION_INPUT, data->mix_ports[1],
data->type.io_inprop_volume,
&data->ctrl_volume[1], sizeof(data->ctrl_volume[1]))) < 0)
error(0, -res, "set_io volume 1");
#ifdef USE_GRAPH #ifdef USE_GRAPH
spa_graph_node_init(&data->source1_node); spa_graph_node_init(&data->source1_node);
spa_graph_node_set_implementation(&data->source1_node, data->source1); spa_graph_node_set_implementation(&data->source1_node, data->source1);
@ -513,13 +549,11 @@ static int negotiate_formats(struct data *data)
spa_node_port_use_buffers(data->sink, SPA_DIRECTION_INPUT, 0, data->mix_buffers, spa_node_port_use_buffers(data->sink, SPA_DIRECTION_INPUT, 0, data->mix_buffers,
1)) < 0) 1)) < 0)
return res; return res;
if ((res = if ((res = spa_node_port_use_buffers(data->mix,
spa_node_port_use_buffers(data->mix, SPA_DIRECTION_OUTPUT, 0, data->mix_buffers, SPA_DIRECTION_OUTPUT, 0, data->mix_buffers, 1)) < 0)
1)) < 0)
return res; return res;
if ((res = if ((res = spa_node_port_set_param(data->mix,
spa_node_port_set_param(data->mix,
SPA_DIRECTION_INPUT, data->mix_ports[0], SPA_DIRECTION_INPUT, data->mix_ports[0],
data->type.param.idFormat, 0, data->type.param.idFormat, 0,
format)) < 0) format)) < 0)