From 27d34dde886eb9d58db34caa721f5fc209f5d4c9 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Wed, 4 Jul 2018 18:43:45 +0200 Subject: [PATCH] introspect: improve introspection stream: set roles --- src/introspect.c | 75 +++++++++++++++++++++++++++++++++++++++++------- src/stream.c | 33 ++++++++++++++++++++- 2 files changed, 96 insertions(+), 12 deletions(-) diff --git a/src/introspect.c b/src/introspect.c index 36af7249d..91aca28e7 100644 --- a/src/introspect.c +++ b/src/introspect.c @@ -119,6 +119,24 @@ struct sink_data { struct global *global; }; +static pa_sink_state_t node_state_to_sink(enum pw_node_state s) +{ + switch(s) { + case PW_NODE_STATE_ERROR: + return PA_SINK_UNLINKED; + case PW_NODE_STATE_CREATING: + return PA_SINK_INIT; + case PW_NODE_STATE_SUSPENDED: + return PA_SINK_SUSPENDED; + case PW_NODE_STATE_IDLE: + return PA_SINK_IDLE; + case PW_NODE_STATE_RUNNING: + return PA_SINK_RUNNING; + default: + return PA_SINK_INVALID_STATE; + } +} + static void sink_callback(struct sink_data *d) { struct global *g = d->global; @@ -134,6 +152,7 @@ static void sink_callback(struct sink_data *d) i.proplist = pa_proplist_new_dict(info->props); i.owner_module = g->parent_id; i.base_volume = PA_VOLUME_NORM; + i.state = node_state_to_sink(info->state); i.n_volume_steps = PA_VOLUME_NORM+1; i.n_formats = 1; ii[0].encoding = PA_ENCODING_PCM; @@ -318,20 +337,45 @@ struct source_data { struct global *global; }; +static pa_source_state_t node_state_to_source(enum pw_node_state s) +{ + switch(s) { + case PW_NODE_STATE_ERROR: + return PA_SOURCE_UNLINKED; + case PW_NODE_STATE_CREATING: + return PA_SOURCE_INIT; + case PW_NODE_STATE_SUSPENDED: + return PA_SOURCE_SUSPENDED; + case PW_NODE_STATE_IDLE: + return PA_SOURCE_IDLE; + case PW_NODE_STATE_RUNNING: + return PA_SOURCE_RUNNING; + default: + return PA_SOURCE_INVALID_STATE; + } +} static void source_callback(struct source_data *d) { struct global *g = d->global; struct pw_node_info *info = g->info; pa_source_info i; + pa_format_info ii[1]; + pa_format_info *ip[1]; spa_zero(i); i.index = g->id; i.name = info->name; + i.description = info->name; i.proplist = pa_proplist_new_dict(info->props); i.owner_module = g->parent_id; i.base_volume = PA_VOLUME_NORM; + i.state = node_state_to_source(info->state); i.n_volume_steps = PA_VOLUME_NORM+1; - + i.n_formats = 1; + ii[0].encoding = PA_ENCODING_PCM; + ii[0].plist = pa_proplist_new(); + ip[0] = ii; + i.formats = ip; d->cb(d->context, &i, 0, d->userdata); } @@ -748,23 +792,32 @@ static void sink_input_callback(struct sink_input_data *d) spa_zero(i); i.index = g->id; i.name = info->name; - i.proplist = pa_proplist_new_dict(info->props); i.owner_module = g->parent_id; - ii[0].encoding = PA_ENCODING_PCM; - ii[0].plist = pa_proplist_new(); - i.format = ii; + i.client = PA_INVALID_INDEX; + i.sink = PA_INVALID_INDEX; + pa_cvolume_init(&i.volume); + if (s) { + i.sample_spec = s->sample_spec; + i.channel_map = s->channel_map; + pa_cvolume_set(&i.volume, 1, s->volume * PA_VOLUME_NORM); + i.format = s->format; + } + else { + pa_channel_map_init(&i.channel_map); + pa_sample_spec_init(&i.sample_spec); + ii[0].encoding = PA_ENCODING_PCM; + ii[0].plist = pa_proplist_new(); + i.format = ii; + } + i.buffer_usec = 0; + i.sink_usec = 0; i.resample_method = "PipeWire resampler"; i.driver = "PipeWire"; i.mute = false; + i.proplist = pa_proplist_new_dict(info->props); i.corked = false; i.has_volume = true; i.volume_writable = true; - i.volume.channels = 1; - if (s) - i.volume.values[0] = s->volume * PA_VOLUME_NORM; - else - i.volume.values[0] = PA_VOLUME_NORM; - d->cb(d->context, &i, 0, d->userdata); } diff --git a/src/stream.c b/src/stream.c index 6a6af3ee2..440ec6382 100644 --- a/src/stream.c +++ b/src/stream.c @@ -313,9 +313,11 @@ static void stream_format_changed(void *data, const struct spa_pod *format) s->sample_spec.rate = info.info.raw.rate; s->sample_spec.channels = info.info.raw.channels; + pa_channel_map_init_auto(&s->channel_map, info.info.raw.channels, PA_CHANNEL_MAP_ALSA); + if (s->format) pa_format_info_free(s->format); - s->format = pa_format_info_from_sample_spec(&s->sample_spec, NULL); + s->format = pa_format_info_from_sample_spec(&s->sample_spec, &s->channel_map); patch_buffer_attr(s, &s->buffer_attr, NULL); @@ -642,6 +644,7 @@ static int create_stream(pa_stream_direction_t direction, struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer)); struct pw_properties *props; uint32_t sample_rate = 0, stride = 0; + const char *str; spa_assert(s); spa_assert(s->refcount >= 1); @@ -705,6 +708,34 @@ static int create_stream(pa_stream_direction_t direction, props = (struct pw_properties *) pw_stream_get_properties(s->stream); pw_properties_setf(props, "node.latency", "%u/%u", s->buffer_attr.minreq / stride, sample_rate); + pw_properties_set(props, PW_NODE_PROP_MEDIA, "Audio"); + pw_properties_set(props, PW_NODE_PROP_CATEGORY, + direction == PA_STREAM_PLAYBACK ? + "Playback" : "Capture"); + + if ((str = pa_proplist_gets(s->proplist, PA_PROP_MEDIA_ROLE)) == NULL) + str = "Music"; + else if (strcmp(str, "video") == 0) + str = "Movie"; + else if (strcmp(str, "music") == 0) + str = "Music"; + else if (strcmp(str, "game") == 0) + str = "Game"; + else if (strcmp(str, "event") == 0) + str = "Notification"; + else if (strcmp(str, "phone") == 0) + str = "Communication"; + else if (strcmp(str, "animation") == 0) + str = "Movie"; + else if (strcmp(str, "production") == 0) + str = "Production"; + else if (strcmp(str, "a11y") == 0) + str = "Accessibility"; + else if (strcmp(str, "test") == 0) + str = "Test"; + else + str = "Music"; + pw_properties_set(props, PW_NODE_PROP_ROLE, str); res = pw_stream_connect(s->stream, direction == PA_STREAM_PLAYBACK ?