diff --git a/modules/module-pipewire/algorithms.c b/modules/module-pipewire/algorithms.c index fd5e522ea32f4e8b66e6ca1d96a01346a9c95f98..53d3ebd29c9f12b279d366bc7640865f1c6ca3da 100644 --- a/modules/module-pipewire/algorithms.c +++ b/modules/module-pipewire/algorithms.c @@ -284,7 +284,7 @@ select_rate (WpSpaPod *value) } static gint -select_channels (WpSpaPod *value) +select_channels (WpSpaPod *value, gint preference) { gint ret = 0; @@ -307,10 +307,13 @@ select_channels (WpSpaPod *value) /* choose the most channels */ g_autoptr (WpIterator) it = wp_spa_pod_iterator_new (value); GValue next = G_VALUE_INIT; + gint diff = SPA_AUDIO_MAX_CHANNELS; while (wp_iterator_next (it, &next)) { gint *channel = (gint *) g_value_get_pointer (&next); - if (*channel > ret) + if (abs (*channel - preference) < diff) { + diff = abs (*channel - preference); ret = *channel; + } g_value_unset (&next); } } @@ -329,8 +332,8 @@ select_channels (WpSpaPod *value) g_value_unset (&next); i++; } - ret = SPA_MAX (vals[1], vals[2]); - ret = SPA_MIN (ret, SPA_AUDIO_MAX_CHANNELS); + ret = SPA_MAX (vals[1], preference); + ret = SPA_MIN (ret, vals[2]); } return ret; @@ -338,7 +341,7 @@ select_channels (WpSpaPod *value) gboolean choose_sensible_raw_audio_format (GPtrArray *formats, - struct spa_audio_info_raw *result) + gint channels_preference, struct spa_audio_info_raw *result) { guint i, most_channels = 0; struct spa_audio_info_raw *raw; @@ -392,7 +395,7 @@ choose_sensible_raw_audio_format (GPtrArray *formats, /* channels */ else if (g_strcmp0 (key, "channels") == 0) { - raw[i].channels = select_channels (value); + raw[i].channels = select_channels (value, channels_preference); } /* position */ diff --git a/modules/module-pipewire/algorithms.h b/modules/module-pipewire/algorithms.h index 4d76d5a67517f3ce652929c74740c50db479908e..8c3b1d9b2530529a3bf579466ddf2054349d9cec 100644 --- a/modules/module-pipewire/algorithms.h +++ b/modules/module-pipewire/algorithms.h @@ -12,4 +12,4 @@ gboolean multiport_link_create (GVariant * src_data, GVariant * sink_data, struct spa_audio_info_raw; gboolean choose_sensible_raw_audio_format (GPtrArray *formats, - struct spa_audio_info_raw *result); + gint channels_preference, struct spa_audio_info_raw *result); diff --git a/modules/module-pipewire/audio-softdsp-endpoint/adapter.c b/modules/module-pipewire/audio-softdsp-endpoint/adapter.c index 206301e312a6abd75474720e05d1f9163771fe8c..8ef138d06f97fe260be06e4f2ef6f3758dc1f97d 100644 --- a/modules/module-pipewire/audio-softdsp-endpoint/adapter.c +++ b/modules/module-pipewire/audio-softdsp-endpoint/adapter.c @@ -87,7 +87,7 @@ on_proxy_enum_format_done (WpProxy *proxy, GAsyncResult *res, return; } - if (!choose_sensible_raw_audio_format (formats, &self->format)) { + if (!choose_sensible_raw_audio_format (formats, 34, &self->format)) { uint32_t media_type, media_subtype; g_warning ("WpAudioAdapter:%p failed to choose a sensible audio format", diff --git a/modules/module-si-adapter.c b/modules/module-si-adapter.c index 1d93d7e83606356698a43ba3b9c188bd1d8063a7..2d1128869b1b5c094ffb92259638495de367bbf2 100644 --- a/modules/module-si-adapter.c +++ b/modules/module-si-adapter.c @@ -207,7 +207,7 @@ on_node_enum_format_done (WpProxy *proxy, GAsyncResult *res, return; } - if (!choose_sensible_raw_audio_format (formats, &self->format)) { + if (!choose_sensible_raw_audio_format (formats, 34, &self->format)) { wp_warning_object (self, "failed to choose a sensible audio format"); wp_transition_return_error (transition, g_error_new (WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, diff --git a/tests/modules/algorithms.c b/tests/modules/algorithms.c index 9a7908f3d0ffbbc60c3469216a20d6944ec46ec1..1c554c005e3937e551ac6cddd6a1d46aca97ec64 100644 --- a/tests/modules/algorithms.c +++ b/tests/modules/algorithms.c @@ -28,68 +28,92 @@ test_choose_sensible_raw_audio_format (void) g_autoptr (GPtrArray) formats = g_ptr_array_new_with_free_func ((GDestroyNotify) wp_spa_pod_unref); - /* test 1 */ - g_ptr_array_remove_range (formats, 0, formats->len); - g_autoptr (WpSpaPod) param1 = wp_spa_pod_new_object ( - "Format", "Format", - "mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio), - "mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - "format", SPA_POD_CHOICE_ENUM_Id(3, - SPA_AUDIO_FORMAT_F32_OE, - SPA_AUDIO_FORMAT_S16, - SPA_AUDIO_FORMAT_S20), - "rate", SPA_POD_CHOICE_RANGE_Int(22000, 44100, 8000), - "channels", SPA_POD_CHOICE_RANGE_Int(2, 1, 8), - NULL); - g_assert_nonnull (param1); - g_ptr_array_add (formats, g_steal_pointer (¶m1)); - g_assert_true (choose_sensible_raw_audio_format (formats, &info)); - g_assert_cmpint (info.format, ==, SPA_AUDIO_FORMAT_S16); - g_assert_cmpint (info.rate, ==, 44100); - g_assert_cmpint (info.channels, ==, 8); - g_assert_cmpint (info.flags, ==, SPA_AUDIO_FLAG_UNPOSITIONED); + { + g_ptr_array_remove_range (formats, 0, formats->len); + g_autoptr (WpSpaPod) param1 = wp_spa_pod_new_object ( + "Format", "Format", + "mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio), + "mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + "format", SPA_POD_CHOICE_ENUM_Id(3, + SPA_AUDIO_FORMAT_F32_OE, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S20), + "rate", SPA_POD_CHOICE_RANGE_Int(22000, 44100, 8000), + "channels", SPA_POD_CHOICE_RANGE_Int(2, 1, 8), + NULL); + g_assert_nonnull (param1); + g_ptr_array_add (formats, g_steal_pointer (¶m1)); + g_assert_true (choose_sensible_raw_audio_format (formats, 34, &info)); + g_assert_cmpint (info.format, ==, SPA_AUDIO_FORMAT_S16); + g_assert_cmpint (info.rate, ==, 44100); + g_assert_cmpint (info.channels, ==, 8); + g_assert_cmpint (info.flags, ==, SPA_AUDIO_FLAG_UNPOSITIONED); + } - /* test 2 */ - g_ptr_array_remove_range (formats, 0, formats->len); - g_autoptr (WpSpaPod) param2 = wp_spa_pod_new_object ( - "Format", "Format", - "mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio), - "mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - "format", SPA_POD_CHOICE_ENUM_Id(3, - SPA_AUDIO_FORMAT_S32, - SPA_AUDIO_FORMAT_U8, - SPA_AUDIO_FORMAT_F32), - "rate", SPA_POD_CHOICE_RANGE_Int(56000, 44100, 96000), - "channels", SPA_POD_Int(2), - "position", SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, 2, layout), - NULL); - g_assert_nonnull (param2); - g_ptr_array_add (formats, g_steal_pointer (¶m2)); - g_autoptr (WpSpaPod) param3 = wp_spa_pod_new_object ( - "Format", "Format", - "mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio), - "mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), - "format", SPA_POD_CHOICE_ENUM_Id(3, - SPA_AUDIO_FORMAT_S32, - SPA_AUDIO_FORMAT_U8, - SPA_AUDIO_FORMAT_F32), - "rate", SPA_POD_CHOICE_RANGE_Int(56000, 44100, 96000), - "channels", SPA_POD_Int(5), - "position", SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, 5, layout), - NULL); - g_assert_nonnull (param3); - g_ptr_array_add (formats, g_steal_pointer (¶m3)); - g_assert_true (choose_sensible_raw_audio_format (formats, &info)); - g_assert_cmpint (info.format, ==, SPA_AUDIO_FORMAT_F32); - g_assert_cmpint (info.rate, ==, 48000); - g_assert_cmpint (info.channels, ==, 5); - g_assert_cmpint (info.flags, ==, SPA_AUDIO_FLAG_NONE); - g_assert_cmpint (info.position[0], ==, layout[0]); - g_assert_cmpint (info.position[1], ==, layout[1]); - g_assert_cmpint (info.position[2], ==, layout[2]); - g_assert_cmpint (info.position[3], ==, layout[3]); - g_assert_cmpint (info.position[4], ==, layout[4]); - g_assert_cmpint (info.position[5], ==, 0); + { + g_ptr_array_remove_range (formats, 0, formats->len); + g_autoptr (WpSpaPod) param1 = wp_spa_pod_new_object ( + "Format", "Format", + "mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio), + "mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + "format", SPA_POD_CHOICE_ENUM_Id(3, + SPA_AUDIO_FORMAT_F32_OE, + SPA_AUDIO_FORMAT_S16, + SPA_AUDIO_FORMAT_S20), + "rate", SPA_POD_CHOICE_RANGE_Int(22000, 44100, 8000), + "channels", SPA_POD_CHOICE_RANGE_Int(2, 1, 8), + NULL); + g_assert_nonnull (param1); + g_ptr_array_add (formats, g_steal_pointer (¶m1)); + g_assert_true (choose_sensible_raw_audio_format (formats, 2, &info)); + g_assert_cmpint (info.format, ==, SPA_AUDIO_FORMAT_S16); + g_assert_cmpint (info.rate, ==, 44100); + g_assert_cmpint (info.channels, ==, 2); + g_assert_cmpint (info.flags, ==, SPA_AUDIO_FLAG_UNPOSITIONED); + } + + { + g_ptr_array_remove_range (formats, 0, formats->len); + g_autoptr (WpSpaPod) param2 = wp_spa_pod_new_object ( + "Format", "Format", + "mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio), + "mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + "format", SPA_POD_CHOICE_ENUM_Id(3, + SPA_AUDIO_FORMAT_S32, + SPA_AUDIO_FORMAT_U8, + SPA_AUDIO_FORMAT_F32), + "rate", SPA_POD_CHOICE_RANGE_Int(56000, 44100, 96000), + "channels", SPA_POD_Int(2), + "position", SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, 2, layout), + NULL); + g_assert_nonnull (param2); + g_ptr_array_add (formats, g_steal_pointer (¶m2)); + g_autoptr (WpSpaPod) param3 = wp_spa_pod_new_object ( + "Format", "Format", + "mediaType", SPA_POD_Id(SPA_MEDIA_TYPE_audio), + "mediaSubtype", SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw), + "format", SPA_POD_CHOICE_ENUM_Id(3, + SPA_AUDIO_FORMAT_S32, + SPA_AUDIO_FORMAT_U8, + SPA_AUDIO_FORMAT_F32), + "rate", SPA_POD_CHOICE_RANGE_Int(56000, 44100, 96000), + "channels", SPA_POD_Int(5), + "position", SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, 5, layout), + NULL); + g_assert_nonnull (param3); + g_ptr_array_add (formats, g_steal_pointer (¶m3)); + g_assert_true (choose_sensible_raw_audio_format (formats, 34, &info)); + g_assert_cmpint (info.format, ==, SPA_AUDIO_FORMAT_F32); + g_assert_cmpint (info.rate, ==, 48000); + g_assert_cmpint (info.channels, ==, 5); + g_assert_cmpint (info.flags, ==, SPA_AUDIO_FLAG_NONE); + g_assert_cmpint (info.position[0], ==, layout[0]); + g_assert_cmpint (info.position[1], ==, layout[1]); + g_assert_cmpint (info.position[2], ==, layout[2]); + g_assert_cmpint (info.position[3], ==, layout[3]); + g_assert_cmpint (info.position[4], ==, layout[4]); + g_assert_cmpint (info.position[5], ==, 0); + } wp_spa_type_deinit (); }