[pulseaudio-discuss] [PATCH v2 14/18] stream: Add pa_stream_set_volume_channel_map()
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Wed Dec 18 09:28:19 PST 2013
The purpose is explained in the function documentation in stream.h.
---
src/map-file | 1 +
src/pulse/internal.h | 1 +
src/pulse/stream.c | 28 +++++++++++++++++++++++++---
src/pulse/stream.h | 31 +++++++++++++++++++++++++++++++
4 files changed, 58 insertions(+), 3 deletions(-)
diff --git a/src/map-file b/src/map-file
index fbad1a4..8283a03 100644
--- a/src/map-file
+++ b/src/map-file
@@ -321,6 +321,7 @@ pa_stream_set_started_callback;
pa_stream_set_state_callback;
pa_stream_set_suspended_callback;
pa_stream_set_underflow_callback;
+pa_stream_set_volume_channel_map;
pa_stream_set_write_callback;
pa_stream_trigger;
pa_stream_unref;
diff --git a/src/pulse/internal.h b/src/pulse/internal.h
index c5084d5..1577e8c 100644
--- a/src/pulse/internal.h
+++ b/src/pulse/internal.h
@@ -144,6 +144,7 @@ struct pa_stream {
pa_sample_spec sample_spec;
pa_channel_map channel_map;
+ bool channel_map_is_set;
uint8_t n_formats;
pa_format_info *req_formats[PA_MAX_FORMATS];
pa_format_info *format;
diff --git a/src/pulse/stream.c b/src/pulse/stream.c
index 8e35c29..5b0cce7 100644
--- a/src/pulse/stream.c
+++ b/src/pulse/stream.c
@@ -102,7 +102,7 @@ static pa_stream *pa_stream_new_with_proplist_internal(
PA_CHECK_VALIDITY_RETURN_NULL(c, !pa_detect_fork(), PA_ERR_FORKED);
PA_CHECK_VALIDITY_RETURN_NULL(c, name || (p && pa_proplist_contains(p, PA_PROP_MEDIA_NAME)), PA_ERR_INVALID);
- s = pa_xnew(pa_stream, 1);
+ s = pa_xnew0(pa_stream, 1);
PA_REFCNT_INIT(s);
s->context = c;
s->mainloop = c->mainloop;
@@ -116,9 +116,10 @@ static pa_stream *pa_stream_new_with_proplist_internal(
else
pa_sample_spec_init(&s->sample_spec);
- if (map)
+ if (map) {
s->channel_map = *map;
- else
+ s->channel_map_is_set = true;
+ } else
pa_channel_map_init(&s->channel_map);
s->n_formats = 0;
@@ -913,6 +914,27 @@ finish:
pa_context_unref(c);
}
+int pa_stream_set_volume_channel_map(pa_stream *s, const pa_channel_map *map) {
+ pa_assert(s);
+ pa_assert(map);
+ pa_assert(pa_channel_map_valid(map));
+
+ if (s->state != PA_STREAM_UNCONNECTED) {
+ pa_log_debug("Stream state is not unconnected.");
+ return -PA_ERR_BADSTATE;
+ }
+
+ if (s->channel_map_is_set && !pa_channel_map_equal(map, &s->channel_map)) {
+ pa_log_debug("Channel map is already set for the stream, changing it is not allowed.");
+ return -PA_ERR_INVALID;
+ }
+
+ s->channel_map = *map;
+ s->channel_map_is_set = true;
+
+ return 0;
+}
+
static void invalidate_indexes(pa_stream *s, bool r, bool w) {
pa_assert(s);
pa_assert(PA_REFCNT_VALUE(s) >= 1);
diff --git a/src/pulse/stream.h b/src/pulse/stream.h
index a6785ec..9821ab8 100644
--- a/src/pulse/stream.h
+++ b/src/pulse/stream.h
@@ -418,6 +418,37 @@ int pa_stream_is_suspended(pa_stream *s);
* not, and a negative value on error. \since 0.9.11 */
int pa_stream_is_corked(pa_stream *s);
+/** Set the volume channel map. The stream volume is passed to
+ * pa_stream_connect_playback() or pa_stream_connect_record(), but those
+ * functions don't have a parameter for specifying the channel map for the
+ * volume. That's usually not an issue, because normally when creating the
+ * stream object, the stream channel map is passed already at that time.
+ * However, with pa_stream_new_extended() it's possible that no channel map is
+ * specified, in case the client wants the server to decide the stream channel
+ * map. In that situation the server still needs to know how the client
+ * intended the volume to be interpreted, i.e. the server needs a channel map
+ * for the volume (unless the volume has only one channel, in which case that
+ * volume is applied to all channels and no channel map information is needed
+ * from the client).
+ *
+ * This function exists to handle the specific case where all these conditions
+ * apply (in other cases this function does not need to be called):
+ *
+ * 1) The client creates the stream using pa_stream_new_extended().
+ * 2) The client doesn't specify a channel map for the stream (so the server
+ * will decide the stream channel map).
+ * 3) The client specifies a volume for the stream.
+ * 4) The specified volume has more than one channel.
+ *
+ * This function must be called before calling pa_stream_connect_playback() or
+ * pa_stream_connect_record(). Returns a negative error code on failure.
+ *
+ * \since 5.0 */
+int pa_stream_set_volume_channel_map(
+ pa_stream *s, /**< The stream for which to set the volume channel map. */
+ const pa_channel_map *map /**< The volume channel map. */
+);
+
/** Connect the stream to a sink. It is strongly recommended to pass
* NULL in both \a dev and \a volume and not to set either
* PA_STREAM_START_MUTED nor PA_STREAM_START_UNMUTED -- unless these
--
1.8.3.1
More information about the pulseaudio-discuss
mailing list