diff --git a/spa/plugins/audioconvert/audioconvert.c b/spa/plugins/audioconvert/audioconvert.c index f201522f8..72ad5d792 100644 --- a/spa/plugins/audioconvert/audioconvert.c +++ b/spa/plugins/audioconvert/audioconvert.c @@ -4274,10 +4274,18 @@ impl_init(const struct spa_handle_factory *factory, this->direction = SPA_DIRECTION_INPUT; } else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { - if (s != NULL) - spa_audio_parse_position_n(s, strlen(s), - this->props.channel_map, SPA_N_ELEMENTS(this->props.channel_map), - &this->props.n_channels); + if (s == NULL) + continue; + spa_audio_parse_position_n(s, strlen(s), + this->props.channel_map, SPA_N_ELEMENTS(this->props.channel_map), + &this->props.n_channels); + } + else if (spa_streq(k, SPA_KEY_AUDIO_LAYOUT)) { + if (s == NULL) + continue; + spa_audio_parse_layout(s, + this->props.channel_map, SPA_N_ELEMENTS(this->props.channel_map), + &this->props.n_channels); } else if (spa_streq(k, SPA_KEY_PORT_IGNORE_LATENCY)) this->port_ignore_latency = spa_atob(s); diff --git a/spa/plugins/avb/avb-pcm.c b/spa/plugins/avb/avb-pcm.c index 0402b8c75..5585cb141 100644 --- a/spa/plugins/avb/avb-pcm.c +++ b/spa/plugins/avb/avb-pcm.c @@ -44,6 +44,11 @@ static int avb_set_param(struct state *state, const char *k, const char *s) SPA_N_ELEMENTS(state->default_pos.pos), &state->default_pos.channels); fmt_change++; + } else if (spa_streq(k, SPA_KEY_AUDIO_LAYOUT)) { + spa_audio_parse_layout(s, state->default_pos.pos, + SPA_N_ELEMENTS(state->default_pos.pos), + &state->default_pos.channels); + fmt_change++; } else if (spa_streq(k, SPA_KEY_AUDIO_ALLOWED_RATES)) { state->n_allowed_rates = spa_avb_parse_rates(state->allowed_rates, MAX_RATES, s, strlen(s)); diff --git a/spa/plugins/support/null-audio-sink.c b/spa/plugins/support/null-audio-sink.c index acaec6f7b..b804023b3 100644 --- a/spa/plugins/support/null-audio-sink.c +++ b/spa/plugins/support/null-audio-sink.c @@ -952,6 +952,9 @@ impl_init(const struct spa_handle_factory *factory, } else if (spa_streq(k, SPA_KEY_AUDIO_POSITION)) { spa_audio_parse_position_n(s, strlen(s), this->props.pos, SPA_N_ELEMENTS(this->props.pos), &this->props.channels); + } else if (spa_streq(k, SPA_KEY_AUDIO_LAYOUT)) { + spa_audio_parse_layout(s, this->props.pos, + SPA_N_ELEMENTS(this->props.pos), &this->props.channels); } else if (spa_streq(k, "clock.name")) { spa_scnprintf(this->props.clock_name, sizeof(this->props.clock_name), diff --git a/src/modules/module-combine-stream.c b/src/modules/module-combine-stream.c index 29f57cb50..453203ebb 100644 --- a/src/modules/module-combine-stream.c +++ b/src/modules/module-combine-stream.c @@ -64,6 +64,7 @@ * * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -76,9 +77,10 @@ * ## Stream options * * - `audio.position`: Set the stream channel map. By default this is the same channel - * map as the combine stream. + * map as the combine stream. You can also use audio.layout * - `combine.audio.position`: map the combine audio positions to the stream positions. * combine input channels are mapped one-by-one to stream output channels. + * You can also use combine.audio.layout. * * ## Example configuration * @@ -334,6 +336,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_DICT_ITEM(SPA_KEY_AUDIO_POSITION, DEFAULT_POSITION)), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -868,6 +871,9 @@ static int create_stream(struct stream_info *info) if ((str = pw_properties_get(info->stream_props, SPA_KEY_AUDIO_POSITION)) != NULL) spa_audio_parse_position_n(str, strlen(str), s->info.position, SPA_N_ELEMENTS(s->info.position), &s->info.channels); + if ((str = pw_properties_get(info->stream_props, SPA_KEY_AUDIO_LAYOUT)) != NULL) + spa_audio_parse_layout(str, s->info.position, + SPA_N_ELEMENTS(s->info.position), &s->info.channels); if (s->info.channels == 0) s->info = impl->info; @@ -875,6 +881,9 @@ static int create_stream(struct stream_info *info) if ((str = pw_properties_get(info->stream_props, "combine.audio.position")) != NULL) spa_audio_parse_position_n(str, strlen(str), remap_info.position, SPA_N_ELEMENTS(remap_info.position), &remap_info.channels); + if ((str = pw_properties_get(info->stream_props, "combine.audio.layout")) != NULL) + spa_audio_parse_layout(str, remap_info.position, + SPA_N_ELEMENTS(remap_info.position), &remap_info.channels); if (remap_info.channels == 0) remap_info = s->info; @@ -1627,6 +1636,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(props, impl->combine_props, PW_KEY_NODE_LOOP_NAME); copy_props(props, impl->combine_props, PW_KEY_AUDIO_CHANNELS); + copy_props(props, impl->combine_props, SPA_KEY_AUDIO_LAYOUT); copy_props(props, impl->combine_props, SPA_KEY_AUDIO_POSITION); copy_props(props, impl->combine_props, PW_KEY_NODE_NAME); copy_props(props, impl->combine_props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-echo-cancel.c b/src/modules/module-echo-cancel.c index 98efa35c5..390563db2 100644 --- a/src/modules/module-echo-cancel.c +++ b/src/modules/module-echo-cancel.c @@ -105,6 +105,7 @@ * * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_CLASS * - \ref PW_KEY_NODE_LATENCY @@ -1278,6 +1279,7 @@ static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_r &props->dict, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1416,6 +1418,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_NODE_LINK_GROUP); copy_props(impl, props, PW_KEY_NODE_VIRTUAL); copy_props(impl, props, SPA_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, "resample.prefill"); @@ -1442,21 +1445,38 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) spa_audio_parse_position_n(str, strlen(str), impl->capture_info.position, SPA_N_ELEMENTS(impl->capture_info.position), &impl->capture_info.channels); } + if ((str = pw_properties_get(impl->capture_props, SPA_KEY_AUDIO_LAYOUT)) != NULL) { + spa_audio_parse_layout(str, impl->capture_info.position, + SPA_N_ELEMENTS(impl->capture_info.position), &impl->capture_info.channels); + } if ((str = pw_properties_get(impl->source_props, SPA_KEY_AUDIO_POSITION)) != NULL) { spa_audio_parse_position_n(str, strlen(str), impl->source_info.position, SPA_N_ELEMENTS(impl->source_info.position), &impl->source_info.channels); } + if ((str = pw_properties_get(impl->source_props, SPA_KEY_AUDIO_LAYOUT)) != NULL) { + spa_audio_parse_layout(str, impl->source_info.position, + SPA_N_ELEMENTS(impl->source_info.position), &impl->source_info.channels); + } if ((str = pw_properties_get(impl->sink_props, SPA_KEY_AUDIO_POSITION)) != NULL) { spa_audio_parse_position_n(str, strlen(str), impl->sink_info.position, SPA_N_ELEMENTS(impl->sink_info.position), &impl->sink_info.channels); impl->playback_info = impl->sink_info; } + if ((str = pw_properties_get(impl->sink_props, SPA_KEY_AUDIO_LAYOUT)) != NULL) { + spa_audio_parse_layout(str, impl->sink_info.position, + SPA_N_ELEMENTS(impl->sink_info.position), &impl->sink_info.channels); + impl->playback_info = impl->sink_info; + } if ((str = pw_properties_get(impl->playback_props, SPA_KEY_AUDIO_POSITION)) != NULL) { spa_audio_parse_position_n(str, strlen(str), impl->playback_info.position, SPA_N_ELEMENTS(impl->playback_info.position), &impl->playback_info.channels); - if (impl->playback_info.channels != impl->sink_info.channels) - impl->playback_info = impl->sink_info; } + if ((str = pw_properties_get(impl->playback_props, SPA_KEY_AUDIO_LAYOUT)) != NULL) { + spa_audio_parse_layout(str, impl->playback_info.position, + SPA_N_ELEMENTS(impl->playback_info.position), &impl->playback_info.channels); + } + if (impl->playback_info.channels != impl->sink_info.channels) + impl->playback_info = impl->sink_info; if ((str = pw_properties_get(props, "aec.method")) != NULL) pw_log_warn("aec.method is not supported anymore use library.name"); diff --git a/src/modules/module-example-filter.c b/src/modules/module-example-filter.c index 60b6dda95..209a23eac 100644 --- a/src/modules/module-example-filter.c +++ b/src/modules/module-example-filter.c @@ -46,6 +46,7 @@ * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -476,6 +477,7 @@ static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_r &props->dict, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -548,6 +550,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); diff --git a/src/modules/module-example-sink.c b/src/modules/module-example-sink.c index 00b880175..fecee854d 100644 --- a/src/modules/module-example-sink.c +++ b/src/modules/module-example-sink.c @@ -52,6 +52,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -284,6 +285,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -387,6 +389,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-example-source.c b/src/modules/module-example-source.c index 20f296a17..21d3e34cc 100644 --- a/src/modules/module-example-source.c +++ b/src/modules/module-example-source.c @@ -52,6 +52,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -290,6 +291,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -393,6 +395,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-ffado-driver.c b/src/modules/module-ffado-driver.c index 7094feaf4..f6a76bed0 100644 --- a/src/modules/module-ffado-driver.c +++ b/src/modules/module-ffado-driver.c @@ -66,6 +66,7 @@ * Options with well-known behavior. * * - \ref PW_KEY_REMOTE_NAME + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -1437,6 +1438,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_DICT_ITEM(SPA_KEY_AUDIO_POSITION, DEFAULT_POSITION)), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } diff --git a/src/modules/module-filter-chain.c b/src/modules/module-filter-chain.c index a2d1f5361..2cf053ff8 100644 --- a/src/modules/module-filter-chain.c +++ b/src/modules/module-filter-chain.c @@ -995,6 +995,7 @@ extern struct spa_handle_factory spa_filter_graph_factory; * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -1840,6 +1841,7 @@ static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_r &props->dict, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1918,6 +1920,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); diff --git a/src/modules/module-jack-tunnel.c b/src/modules/module-jack-tunnel.c index 637001423..760da1669 100644 --- a/src/modules/module-jack-tunnel.c +++ b/src/modules/module-jack-tunnel.c @@ -72,6 +72,7 @@ * * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -1060,6 +1061,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_DICT_ITEM(SPA_KEY_AUDIO_POSITION, DEFAULT_POSITION)), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1169,6 +1171,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) pw_properties_update_string(impl->source.props, str, strlen(str)); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_ALWAYS_PROCESS); copy_props(impl, props, PW_KEY_NODE_GROUP); diff --git a/src/modules/module-loopback.c b/src/modules/module-loopback.c index e921cd701..5b34834ac 100644 --- a/src/modules/module-loopback.c +++ b/src/modules/module-loopback.c @@ -51,6 +51,7 @@ * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_NODE_LATENCY @@ -846,6 +847,7 @@ static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_r &props->dict, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -927,6 +929,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); copy_props(impl, props, PW_KEY_NODE_GROUP); diff --git a/src/modules/module-netjack2-driver.c b/src/modules/module-netjack2-driver.c index 485570064..07a756266 100644 --- a/src/modules/module-netjack2-driver.c +++ b/src/modules/module-netjack2-driver.c @@ -99,6 +99,7 @@ * * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -1225,6 +1226,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P")), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1329,6 +1331,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_NODE_LOOP_NAME); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_ALWAYS_PROCESS); copy_props(impl, props, PW_KEY_NODE_GROUP); diff --git a/src/modules/module-netjack2-manager.c b/src/modules/module-netjack2-manager.c index 615a4553b..0ff62d93b 100644 --- a/src/modules/module-netjack2-manager.c +++ b/src/modules/module-netjack2-manager.c @@ -94,6 +94,7 @@ * * - \ref PW_KEY_REMOTE_NAME * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -1299,6 +1300,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_DICT_ITEM(SPA_KEY_AUDIO_FORMAT, "F32P")), &props->dict, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1417,6 +1419,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_NODE_LOCK_QUANTUM); copy_props(impl, props, PW_KEY_NODE_LOCK_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, "audio.ports"); copy_props(impl, props, "midi.ports"); diff --git a/src/modules/module-parametric-equalizer.c b/src/modules/module-parametric-equalizer.c index a11398166..7eb89f7f5 100644 --- a/src/modules/module-parametric-equalizer.c +++ b/src/modules/module-parametric-equalizer.c @@ -70,6 +70,7 @@ * Options with well-known behaviour: * * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_REMOTE_NAME * diff --git a/src/modules/module-pipe-tunnel.c b/src/modules/module-pipe-tunnel.c index 2f66a9ed7..62de8717c 100644 --- a/src/modules/module-pipe-tunnel.c +++ b/src/modules/module-pipe-tunnel.c @@ -79,6 +79,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_NAME @@ -756,6 +757,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -886,6 +888,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-protocol-simple.c b/src/modules/module-protocol-simple.c index e1847577a..ffc225b98 100644 --- a/src/modules/module-protocol-simple.c +++ b/src/modules/module-protocol-simple.c @@ -72,6 +72,7 @@ * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_RATE @@ -831,6 +832,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL)) < 0) return res; @@ -888,6 +890,7 @@ static int parse_params(struct impl *impl) copy_props(impl, PW_KEY_AUDIO_FORMAT); copy_props(impl, PW_KEY_AUDIO_RATE); copy_props(impl, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, SPA_KEY_AUDIO_POSITION); copy_props(impl, PW_KEY_NODE_RATE); copy_props(impl, PW_KEY_NODE_NAME); diff --git a/src/modules/module-pulse-tunnel.c b/src/modules/module-pulse-tunnel.c index 4c4ab1a26..fe496fa33 100644 --- a/src/modules/module-pulse-tunnel.c +++ b/src/modules/module-pulse-tunnel.c @@ -72,6 +72,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_LATENCY * - \ref PW_KEY_NODE_NAME @@ -1059,6 +1060,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } @@ -1183,6 +1185,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c index accc2a9da..e217ff5b2 100644 --- a/src/modules/module-raop-sink.c +++ b/src/modules/module-raop-sink.c @@ -82,6 +82,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -1901,6 +1902,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_DEVICE_ICON_NAME); copy_props(impl, props, PW_KEY_NODE_NAME); diff --git a/src/modules/module-rtp-session.c b/src/modules/module-rtp-session.c index cd7ca7f4e..63470c539 100644 --- a/src/modules/module-rtp-session.c +++ b/src/modules/module-rtp-session.c @@ -82,6 +82,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -148,6 +149,7 @@ PW_LOG_TOPIC(mod_topic, "mod." NAME); "( audio.rate= ) " \ "( audio.channels= ) "\ "( audio.position= ) " \ + "( audio.layout= ) " \ "( stream.props= { key=value ... } ) " static const struct spa_dict_item module_info[] = { @@ -1329,6 +1331,12 @@ static struct service *make_service(struct impl *impl, const struct service_info } else if (spa_streq(key, "channels")) { k = PW_KEY_AUDIO_CHANNELS; mask |= 1<<3; + } else if (spa_streq(key, "position")) { + pw_properties_set(props, + SPA_KEY_AUDIO_POSITION, value); + } else if (spa_streq(key, "layout")) { + pw_properties_set(props, + SPA_KEY_AUDIO_LAYOUT, value); } else if (spa_streq(key, "channelnames")) { pw_properties_set(props, PW_KEY_NODE_CHANNELNAMES, value); @@ -1587,6 +1595,8 @@ static int make_announce(struct impl *impl) txt = avahi_string_list_add_pair(txt, "channels", str); if ((str = pw_properties_get(impl->stream_props, SPA_KEY_AUDIO_POSITION)) != NULL) txt = avahi_string_list_add_pair(txt, "position", str); + if ((str = pw_properties_get(impl->stream_props, SPA_KEY_AUDIO_LAYOUT)) != NULL) + txt = avahi_string_list_add_pair(txt, "layout", str); if ((str = pw_properties_get(impl->stream_props, PW_KEY_NODE_CHANNELNAMES)) != NULL) txt = avahi_string_list_add_pair(txt, "channelnames", str); if (impl->ts_refclk != NULL) { @@ -1702,6 +1712,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-rtp-sink.c b/src/modules/module-rtp-sink.c index cb21cb79a..c77fc067a 100644 --- a/src/modules/module-rtp-sink.c +++ b/src/modules/module-rtp-sink.c @@ -77,6 +77,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -150,6 +151,7 @@ PW_LOG_TOPIC(mod_topic, "mod." NAME); "( audio.rate= ) " \ "( audio.channels= ) " \ "( audio.position= ) " \ + "( audio.layout= ) " \ "( aes67.driver-group= ) " \ "( stream.props= { key=value ... } ) " @@ -578,6 +580,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-rtp-source.c b/src/modules/module-rtp-source.c index 5c3d1f05f..8e227b53b 100644 --- a/src/modules/module-rtp-source.c +++ b/src/modules/module-rtp-source.c @@ -72,6 +72,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_MEDIA_CLASS @@ -175,6 +176,7 @@ PW_LOG_TOPIC(mod_topic, "mod." NAME); "( audio.rate= ) " \ "( audio.channels= ) " \ "( audio.position= ) " \ + "( audio.layout= ) " \ "( stream.props= { key=value ... } ) " static const struct spa_dict_item module_info[] = { @@ -923,6 +925,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-rtp/stream.c b/src/modules/module-rtp/stream.c index fa055ce0c..e19d88a1f 100644 --- a/src/modules/module-rtp/stream.c +++ b/src/modules/module-rtp/stream.c @@ -581,6 +581,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); } diff --git a/src/modules/module-rtp/stream.h b/src/modules/module-rtp/stream.h index 095b8395c..2c6e6dea5 100644 --- a/src/modules/module-rtp/stream.h +++ b/src/modules/module-rtp/stream.h @@ -15,6 +15,7 @@ struct rtp_stream; #define DEFAULT_RATE 48000 #define DEFAULT_CHANNELS 2 #define DEFAULT_POSITION "[ FL FR ]" +#define DEFAULT_LAYOUT "Stereo" #define ERROR_MSEC 2.0f #define DEFAULT_SESS_LATENCY 100.0f diff --git a/src/modules/module-snapcast-discover.c b/src/modules/module-snapcast-discover.c index ec4eb3e25..596d5677b 100644 --- a/src/modules/module-snapcast-discover.c +++ b/src/modules/module-snapcast-discover.c @@ -516,6 +516,7 @@ static int parse_audio_info(struct pw_properties *props, struct spa_audio_info_r SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL)) < 0) return res; diff --git a/src/modules/module-vban-recv.c b/src/modules/module-vban-recv.c index 26dc7b507..2ee724305 100644 --- a/src/modules/module-vban-recv.c +++ b/src/modules/module-vban-recv.c @@ -75,6 +75,7 @@ * Options with well-known behavior: * * - \ref PW_KEY_REMOTE_NAME + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_MEDIA_NAME * - \ref PW_KEY_MEDIA_CLASS @@ -694,6 +695,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) pw_properties_update_string(stream_props, str, strlen(str)); copy_props(impl, props, PW_KEY_NODE_LOOP_NAME); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-vban-send.c b/src/modules/module-vban-send.c index 5fc6793a1..a3ea7c760 100644 --- a/src/modules/module-vban-send.c +++ b/src/modules/module-vban-send.c @@ -68,6 +68,7 @@ * - \ref PW_KEY_AUDIO_FORMAT * - \ref PW_KEY_AUDIO_RATE * - \ref PW_KEY_AUDIO_CHANNELS + * - \ref SPA_KEY_AUDIO_LAYOUT * - \ref SPA_KEY_AUDIO_POSITION * - \ref PW_KEY_NODE_NAME * - \ref PW_KEY_NODE_DESCRIPTION @@ -417,6 +418,7 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) copy_props(impl, props, PW_KEY_AUDIO_FORMAT); copy_props(impl, props, PW_KEY_AUDIO_RATE); copy_props(impl, props, PW_KEY_AUDIO_CHANNELS); + copy_props(impl, props, SPA_KEY_AUDIO_LAYOUT); copy_props(impl, props, SPA_KEY_AUDIO_POSITION); copy_props(impl, props, PW_KEY_NODE_NAME); copy_props(impl, props, PW_KEY_NODE_DESCRIPTION); diff --git a/src/modules/module-vban/stream.c b/src/modules/module-vban/stream.c index 941fa1acd..da3469583 100644 --- a/src/modules/module-vban/stream.c +++ b/src/modules/module-vban/stream.c @@ -196,6 +196,7 @@ static int parse_audio_info(const struct pw_properties *props, struct spa_audio_ SPA_KEY_AUDIO_FORMAT, SPA_KEY_AUDIO_RATE, SPA_KEY_AUDIO_CHANNELS, + SPA_KEY_AUDIO_LAYOUT, SPA_KEY_AUDIO_POSITION, NULL); }