Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package wireplumber for openSUSE:Factory checked in at 2022-10-11 18:01:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/wireplumber (Old) and /work/SRC/openSUSE:Factory/.wireplumber.new.2275 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "wireplumber" Tue Oct 11 18:01:41 2022 rev:18 rq:1007947 version:0.4.12 Changes: -------- --- /work/SRC/openSUSE:Factory/wireplumber/wireplumber.changes 2022-08-10 17:13:40.737767340 +0200 +++ /work/SRC/openSUSE:Factory/.wireplumber.new.2275/wireplumber.changes 2022-10-11 18:04:04.057941045 +0200 @@ -1,0 +2,45 @@ +Tue Oct 4 13:01:17 UTC 2022 - Alexei Sorokin <sor.ale...@meowr.ru> + +- Update to version 0.4.12: + * Changes + - WirePlumber now maintains a stack of previously configured + default nodes and prioritises to one of those when the + actively configured default node becomes unavailable, before + calculating the next default using priorities. + - Updated bluetooth scripts to support the name changes that + happened in PipeWire 0.3.59 and also support the experimental + Bluetooth LE functionality. + - Changed the naming of bluetooth nodes to not include the + profile in it; this allows maintaining existing links when + switching between a2dp and hfp. + - The default volume for new outputs has changed to be 40% in + cubic scale (= -24 dB) instead of linear + (= 74% cubic / -8 dB) that it was before. + - The default volume for new inputs has changed to be 100% + rather than following the default for outputs. + - Added ``--version`` flag on the wireplumber executable. + - Added ``--limit`` flag on ``wpctl set-volume`` to limit the + higher volume that can be set (useful when incrementing + volume with a keyboard shortcut that calls into wpctl). + - The properties of the alsa midi node can now be set in the + config files. + * Fixes + - Fixed a crash in lua code that would happen when running in a + VM. + - Fixed a crash that would happen when re-connecting to D-Bus. + - Fixed a mistake in the code that would cause device + reservation not to work properly. + - Fixed ``wpctl clear-default`` to accept 0 as a valid setting ID. + - Fixed the logic of choosing the best profile after the active + profile of a device becomes unavailable + - Fixed a regression that would cause PulseAudio "corked" + streams to not properly link and cause busy loops. + - Fixed an issue parsing spa-json objects that have a nested + object as the value of their last property. +- Rebase reduce-meson-required-version.patch +- Drop patches already upstream: + * fix-alsa.patch + * 0001-dbus-fix-crash-when-trying-to-reconnect.patch + * 398.patch + +------------------------------------------------------------------- Old: ---- 0001-dbus-fix-crash-when-trying-to-reconnect.patch 398.patch _servicedata fix-alsa.patch wireplumber-0.4.11.obscpio New: ---- wireplumber-0.4.12.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ wireplumber.spec ++++++ --- /var/tmp/diff_new_pack.kTQ3O7/_old 2022-10-11 18:04:04.629941970 +0200 +++ /var/tmp/diff_new_pack.kTQ3O7/_new 2022-10-11 18:04:04.633941976 +0200 @@ -22,7 +22,7 @@ %define sover 0 %define libwireplumber libwireplumber-%{apiver_str}-%{sover} Name: wireplumber -Version: 0.4.11 +Version: 0.4.12 Release: 0 Summary: Session / policy manager implementation for PipeWire License: MIT @@ -32,17 +32,13 @@ Source1: split-config-file.py # PATCH-FIX-OPENSUSE reduce-meson-required-version.patch Patch0: reduce-meson-required-version.patch -# PATCH-FIX-UPSTREAM -Patch1: fix-alsa.patch -Patch2: 0001-dbus-fix-crash-when-trying-to-reconnect.patch -Patch3: https://gitlab.freedesktop.org/pipewire/wireplumber/-/merge_requests/398.patch # docs BuildRequires: doxygen BuildRequires: graphviz # /docs BuildRequires: cmake BuildRequires: fdupes -%if 0%{?sle_version} == 150300 +%if 0%{?sle_version} <= 150300 BuildRequires: meson >= 0.54.0 %else BuildRequires: meson >= 0.59.0 @@ -141,12 +137,9 @@ %prep %autosetup -N -%if 0%{?sle_version} == 150300 +%if 0%{?sle_version} <= 150300 %patch0 -p1 %endif -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 pushd src/config/main.lua.d python3 %{SOURCE1} ++++++ _service ++++++ --- /var/tmp/diff_new_pack.kTQ3O7/_old 2022-10-11 18:04:04.665942028 +0200 +++ /var/tmp/diff_new_pack.kTQ3O7/_new 2022-10-11 18:04:04.669942034 +0200 @@ -3,7 +3,7 @@ <service name="obs_scm" mode="disabled"> <param name="scm">git</param> <param name="url">https://gitlab.freedesktop.org/pipewire/wireplumber.git</param> - <param name="revision">0.4.11</param> + <param name="revision">0.4.12</param> <param name="versionformat">@PARENT_TAG@</param> <!-- <param name="revision">master</param> ++++++ reduce-meson-required-version.patch ++++++ --- /var/tmp/diff_new_pack.kTQ3O7/_old 2022-10-11 18:04:04.681942054 +0200 +++ /var/tmp/diff_new_pack.kTQ3O7/_new 2022-10-11 18:04:04.685942060 +0200 @@ -4,41 +4,71 @@ With this, we can build wireplumber in SLE 15 SP3/Leap 15.3 which only have meson 0.54 -Index: wireplumber-0.4.11/meson.build +Index: wireplumber-0.4.12/meson.build =================================================================== ---- wireplumber-0.4.11.orig/meson.build -+++ wireplumber-0.4.11/meson.build +--- wireplumber-0.4.12.orig/meson.build ++++ wireplumber-0.4.12/meson.build @@ -1,7 +1,7 @@ project('wireplumber', ['c'], - version : '0.4.11', + version : '0.4.12', license : 'MIT', - meson_version : '>= 0.59.0', + meson_version : '>= 0.54.0', default_options : [ 'warning_level=1', 'buildtype=debugoptimized', -@@ -42,7 +42,11 @@ spa_dep = dependency('libspa-0.2', versi +@@ -42,7 +42,17 @@ spa_dep = dependency('libspa-0.2', versi pipewire_dep = dependency('libpipewire-0.3', version: '>= 0.3.52') mathlib = cc.find_library('m') threads_dep = dependency('threads') -libintl_dep = dependency('intl') -+libintl_dep = dependency('', required: false) + -+if not cc.has_function('ngettext') -+ libintl_dep = cc.find_library('intl') ++ ++if meson.version().version_compare('>= 0.59') ++ libintl_dep = dependency('intl') ++else ++ libintl_dep = dependency('', required: false) ++ ++ if not cc.has_function('ngettext') ++ libintl_dep = cc.find_library('intl') ++ endif +endif system_lua = get_option('system-lua') if system_lua -@@ -131,8 +135,8 @@ endif +@@ -129,8 +139,13 @@ if get_option('tests') + subdir('tests') + endif + +-builddir = meson.project_build_root() +-srcdir = meson.project_source_root() ++if meson.version().version_compare('>= 0.56') ++ builddir = meson.project_build_root() ++ srcdir = meson.project_source_root() ++else ++ builddir = meson.build_root() ++ srcdir = meson.source_root() ++endif conf_uninstalled = configuration_data() conf_uninstalled.set('MESON', '') --conf_uninstalled.set('MESON_SOURCE_ROOT', meson.project_source_root()) --conf_uninstalled.set('MESON_BUILD_ROOT', meson.project_build_root()) -+conf_uninstalled.set('MESON_SOURCE_ROOT', meson.source_root()) -+conf_uninstalled.set('MESON_BUILD_ROOT', meson.build_root()) +@@ -150,10 +165,12 @@ wireplumber_uninstalled = custom_target( + command : ['cp', '@INPUT@', '@OUTPUT@'], + ) + +-devenv = environment({ +- 'WIREPLUMBER_MODULE_DIR': builddir / 'modules', +- 'WIREPLUMBER_CONFIG_DIR': srcdir / 'src' / 'config', +- 'WIREPLUMBER_DATA_DIR': srcdir / 'src', +-}) ++if meson.version().version_compare('>= 0.58') ++ devenv = environment({ ++ 'WIREPLUMBER_MODULE_DIR': builddir / 'modules', ++ 'WIREPLUMBER_CONFIG_DIR': srcdir / 'src' / 'config', ++ 'WIREPLUMBER_DATA_DIR': srcdir / 'src', ++ }) - wp_uninstalled = configure_file( - input : 'wp-uninstalled.sh', +-meson.add_devenv(devenv) ++ meson.add_devenv(devenv) ++endif ++++++ wireplumber-0.4.11.obscpio -> wireplumber-0.4.12.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/.gitlab-ci.yml new/wireplumber-0.4.12/.gitlab-ci.yml --- old/wireplumber-0.4.11/.gitlab-ci.yml 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/.gitlab-ci.yml 2022-10-04 15:25:09.000000000 +0200 @@ -27,13 +27,13 @@ .fedora: variables: # Update this tag when you want to trigger a rebuild - FDO_DISTRIBUTION_TAG: '2022-02-16.0' + FDO_DISTRIBUTION_TAG: '2022-10-03.0' FDO_DISTRIBUTION_VERSION: '35' # findutils: used by the .build script below # dbus-devel: required by pipewire # dbus-daemon: required by GDBus unit tests # pip, doxygen: required for documentation - # ShellCheck: required by the CI + # ShellCheck, diffutils: required by the CI FDO_DISTRIBUTION_PACKAGES: >- findutils gcc @@ -47,6 +47,7 @@ python3-pip doxygen ShellCheck + diffutils # install Sphinx and Breathe to generate documentation # also install glib2-doc (required to make documentation links to GLib work) # manually, to remove the 'tsflags=nodocs' flag that is enabled by default @@ -282,6 +283,19 @@ script: - shellcheck $(git grep -l "#\!/.*bin/.*sh") +linguas_check: + extends: + - .fedora + - .not_coverity + - .fdo.distribution-image@fedora + stage: analysis + script: + - cd po + - cat LINGUAS | sort > LINGUAS.sorted + - ls *.po | sed s/.po//g | sort > LINGUAS.new + - diff -u LINGUAS.sorted LINGUAS.new + - rm -f LINGUAS.* + pages: extends: - .not_coverity diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/NEWS.rst new/wireplumber-0.4.12/NEWS.rst --- old/wireplumber-0.4.11/NEWS.rst 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/NEWS.rst 2022-10-04 15:25:09.000000000 +0200 @@ -1,8 +1,61 @@ -WirePlumber 0.4.11 +WirePlumber 0.4.12 ~~~~~~~~~~~~~~~~~~ Changes: + - WirePlumber now maintains a stack of previously configured default nodes and + prioritizes to one of those when the actively configured default node + becomes unavailable, before calculating the next default using priorities + (see !396) + + - Updated bluetooth scripts to support the name changes that happened in + PipeWire 0.3.59 and also support the experimental Bluetooth LE functionality + + - Changed the naming of bluetooth nodes to not include the profile in it; + this allows maintaining existing links when switching between a2dp and hfp + + - The default volume for new outputs has changed to be 40% in cubic scale + (= -24 dB) instead of linear (= 74% cubic / -8 dB) that it was before + + - The default volume for new inputs has changed to be 100% rather than + following the default for outputs + + - Added ``--version`` flag on the wireplumber executable (#317) + + - Added ``--limit`` flag on ``wpctl set-volume`` to limit the higher volume + that can be set (useful when incrementing volume with a keyboard shortcut + that calls into wpctl) + + - The properties of the alsa midi node can now be set in the config files + +Fixes: + + - Fixed a crash in lua code that would happen when running in a VM (#303) + + - Fixed a crash that would happen when re-connecting to D-Bus (#305) + + - Fixed a mistake in the code that would cause device reservation not to + work properly + + - Fixed ``wpctl clear-default`` to accept 0 as a valid setting ID + + - Fixed the logic of choosing the best profile after the active profile + of a device becomes unavailable (#329) + + - Fixed a regression that would cause PulseAudio "corked" streams to not + properly link and cause busy loops + + - Fixed an issue parsing spa-json objects that have a nested object as the + value of their last property + +Past releases +~~~~~~~~~~~~~ + +WirePlumber 0.4.11 +.................. + +Changes: + - The libcamera monitor is now enabled by default, so if the libcamera source is enabled in PipeWire, cameras discovered with the libcamera API will be available out of the box. This is safe to use alongside V4L2, as long as @@ -81,9 +134,6 @@ - The Lua subproject was bumped to version 5.4.4 -Past releases -~~~~~~~~~~~~~ - WirePlumber 0.4.10 .................. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/lib/wp/dbus.c new/wireplumber-0.4.12/lib/wp/dbus.c --- old/wireplumber-0.4.11/lib/wp/dbus.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/lib/wp/dbus.c 2022-10-04 15:25:09.000000000 +0200 @@ -58,14 +58,26 @@ static void on_got_bus (GObject * obj, GAsyncResult * res, gpointer data) { - WpTransition *transition = WP_TRANSITION (data); - WpDbus *self = wp_transition_get_source_object (transition); + WpTransition *transition; + WpDbus *self; g_autoptr (GError) error = NULL; + if (WP_IS_TRANSITION (data)) { + // coming from wp_dbus_enable + transition = WP_TRANSITION (data); + self = wp_transition_get_source_object (transition); + } else { + // coming from on_sync_reconnect + transition = NULL; + self = WP_DBUS (data); + } + self->connection = g_dbus_connection_new_for_address_finish (res, &error); if (!self->connection) { - g_prefix_error (&error, "Failed to connect to bus: "); - wp_transition_return_error (transition, g_steal_pointer (&error)); + if (transition) { + g_prefix_error (&error, "Failed to connect to bus: "); + wp_transition_return_error (transition, g_steal_pointer (&error)); + } return; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/lib/wp/spa-json.c new/wireplumber-0.4.12/lib/wp/spa-json.c --- old/wireplumber-0.4.11/lib/wp/spa-json.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/lib/wp/spa-json.c 2022-10-04 15:25:09.000000000 +0200 @@ -1246,7 +1246,7 @@ check_nested_size (struct spa_json *parent, const gchar *data, int size) { const gchar *nested_data; - int nested_size, last_sub_size = 0; + int nested_size; struct spa_json nested[2]; /* only arrays and objects are considered nested data */ @@ -1259,16 +1259,15 @@ /* recursively advance */ while ((nested_size = spa_json_next (&nested[1], &nested_data)) > 0) { - last_sub_size = check_nested_size (&nested[1], nested_data, nested_size); - if (last_sub_size < 0) + if (check_nested_size (&nested[1], nested_data, nested_size) < 0) return -1; } if (nested_size < 0) return -1; - /* if last sub size, advance one more time to reach end of nested data */ - if (last_sub_size > 0 && spa_json_next (&nested[1], &nested_data) < 0) - return -1; + /* advance one more time to reach end of nested data */ + if (spa_json_next (&nested[1], &nested_data) < 0) + return -1; return nested_data - data; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/lib/wp/wp.c new/wireplumber-0.4.12/lib/wp/wp.c --- old/wireplumber-0.4.11/lib/wp/wp.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/lib/wp/wp.c 2022-10-04 15:25:09.000000000 +0200 @@ -68,6 +68,26 @@ } /*! + * \brief Gets the WirePlumber library version + * \returns WirePlumber library version + */ +const char * +wp_get_library_version (void) +{ + return WIREPLUMBER_VERSION; +} + +/*! + * \brief Gets the WirePlumber library API version + * \returns WirePlumber library API version + */ +const char * +wp_get_library_api_version (void) +{ + return WIREPLUMBER_API_VERSION; +} + +/*! * \brief Gets the WirePlumber module directory * \returns WirePlumber's module directory */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/lib/wp/wp.h new/wireplumber-0.4.12/lib/wp/wp.h --- old/wireplumber-0.4.11/lib/wp/wp.h 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/lib/wp/wp.h 2022-10-04 15:25:09.000000000 +0200 @@ -67,6 +67,12 @@ void wp_init (WpInitFlags flags); WP_API +const char * wp_get_library_version (void); + +WP_API +const char * wp_get_library_api_version (void); + +WP_API const gchar * wp_get_module_dir (void); WP_API diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/meson.build new/wireplumber-0.4.12/meson.build --- old/wireplumber-0.4.11/meson.build 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/meson.build 2022-10-04 15:25:09.000000000 +0200 @@ -1,5 +1,5 @@ project('wireplumber', ['c'], - version : '0.4.11', + version : '0.4.12', license : 'MIT', meson_version : '>= 0.59.0', default_options : [ @@ -129,10 +129,13 @@ subdir('tests') endif +builddir = meson.project_build_root() +srcdir = meson.project_source_root() + conf_uninstalled = configuration_data() conf_uninstalled.set('MESON', '') -conf_uninstalled.set('MESON_SOURCE_ROOT', meson.project_source_root()) -conf_uninstalled.set('MESON_BUILD_ROOT', meson.project_build_root()) +conf_uninstalled.set('MESON_SOURCE_ROOT', srcdir) +conf_uninstalled.set('MESON_BUILD_ROOT', builddir) wp_uninstalled = configure_file( input : 'wp-uninstalled.sh', @@ -147,15 +150,10 @@ command : ['cp', '@INPUT@', '@OUTPUT@'], ) -if meson.version().version_compare('>= 0.58') - builddir = meson.project_build_root() - srcdir = meson.project_source_root() - - devenv = environment({ - 'WIREPLUMBER_MODULE_DIR': builddir / 'modules', - 'WIREPLUMBER_CONFIG_DIR': srcdir / 'src' / 'config', - 'WIREPLUMBER_DATA_DIR': srcdir / 'src', - }) +devenv = environment({ + 'WIREPLUMBER_MODULE_DIR': builddir / 'modules', + 'WIREPLUMBER_CONFIG_DIR': srcdir / 'src' / 'config', + 'WIREPLUMBER_DATA_DIR': srcdir / 'src', +}) - meson.add_devenv(devenv) -endif +meson.add_devenv(devenv) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/modules/module-default-nodes.c new/wireplumber-0.4.12/modules/module-default-nodes.c --- old/wireplumber-0.4.11/modules/module-default-nodes.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/modules/module-default-nodes.c 2022-10-04 15:25:09.000000000 +0200 @@ -19,6 +19,7 @@ #define DEFAULT_AUTO_ECHO_CANCEL TRUE #define DEFAULT_ECHO_CANCEL_SINK_NAME "echo-cancel-sink" #define DEFAULT_ECHO_CANCEL_SOURCE_NAME "echo-cancel-source" +#define N_PREV_CONFIGS 16 enum { PROP_0, @@ -34,6 +35,7 @@ { gchar *value; gchar *config_value; + gchar *prev_config_value[N_PREV_CONFIGS]; }; struct _WpDefaultNodes @@ -63,12 +65,48 @@ } static void +update_prev_config_values (WpDefaultNode *def) +{ + gint pos = N_PREV_CONFIGS - 1; + + if (!def->config_value) + return; + + /* Find if the current configured value is already in the stack */ + for (gint i = 0; i < N_PREV_CONFIGS; ++i) { + if (!g_strcmp0(def->config_value, def->prev_config_value[i])) { + pos = i; + break; + } + } + + if (pos == 0) + return; + + /* Insert on top position */ + g_clear_pointer (&def->prev_config_value[pos], g_free); + + for (gint i = pos; i > 0; --i) + def->prev_config_value[i] = def->prev_config_value[i-1]; + + def->prev_config_value[0] = g_strdup(def->config_value); +} + +static void load_state (WpDefaultNodes * self) { g_autoptr (WpProperties) props = wp_state_load (self->state); for (gint i = 0; i < N_DEFAULT_NODES; i++) { const gchar *value = wp_properties_get (props, DEFAULT_CONFIG_KEY[i]); + self->defaults[i].config_value = g_strdup (value); + + for (gint j = 0; j < N_PREV_CONFIGS; ++j) { + g_autofree gchar *key = g_strdup_printf("%s.%d", DEFAULT_CONFIG_KEY[i], j); + + value = wp_properties_get (props, key); + self->defaults[i].prev_config_value[j] = g_strdup(value); + } } } @@ -82,6 +120,12 @@ if (self->defaults[i].config_value) wp_properties_set (props, DEFAULT_CONFIG_KEY[i], self->defaults[i].config_value); + + for (gint j = 0; j < N_PREV_CONFIGS; ++j) { + g_autofree gchar *key = g_strdup_printf("%s.%d", DEFAULT_CONFIG_KEY[i], j); + + wp_properties_set (props, key, self->defaults[i].prev_config_value[j]); + } } if (!wp_state_save (self->state, props, &error)) @@ -209,7 +253,7 @@ static WpNode * find_best_media_class_node (WpDefaultNodes * self, const gchar *media_class, - const gchar *node_name, WpDirection direction, gint *priority) + const WpDefaultNode *def, WpDirection direction, gint *priority) { g_autoptr (WpIterator) it = NULL; g_auto (GValue) val = G_VALUE_INIT; @@ -243,8 +287,20 @@ if (self->auto_echo_cancel && is_echo_cancel_node (self, node, direction)) prio += 10000; - if (name && node_name && g_strcmp0 (name, node_name) == 0) - prio += 20000; + if (name && def->config_value && g_strcmp0 (name, def->config_value) == 0) { + prio += 20000 * (N_PREV_CONFIGS + 1); + } else if (name) { + for (gint i = 0; i < N_PREV_CONFIGS; ++i) { + if (!def->prev_config_value[i]) + continue; + + /* Match by name */ + if (g_strcmp0 (name, def->prev_config_value[i]) == 0) { + prio += (N_PREV_CONFIGS - i) * 20000; + break; + } + } + } if (prio > highest_prio || res == NULL) { highest_prio = prio; @@ -260,14 +316,14 @@ static WpNode * find_best_media_classes_node (WpDefaultNodes * self, - const gchar **media_classes, const gchar *node_name, WpDirection direction) + const gchar **media_classes, const WpDefaultNode *def, WpDirection direction) { gint highest_prio = -1; WpNode *res = NULL; for (guint i = 0; media_classes[i]; i++) { gint prio = -1; WpNode *node = find_best_media_class_node (self, media_classes[i], - node_name, direction, &prio); + def, direction, &prio); if (node && (!res || prio > highest_prio)) { highest_prio = prio; res = node; @@ -279,7 +335,7 @@ static WpNode * find_best_node (WpDefaultNodes * self, gint node_t) { - const gchar *name = self->defaults[node_t].config_value; + const WpDefaultNode *def = &self->defaults[node_t]; switch (node_t) { case AUDIO_SINK: { @@ -287,7 +343,7 @@ "Audio/Sink", "Audio/Duplex", NULL}; - return find_best_media_classes_node (self, media_classes, name, + return find_best_media_classes_node (self, media_classes, def, WP_DIRECTION_INPUT); } case AUDIO_SOURCE: { @@ -297,7 +353,7 @@ "Audio/Duplex", "Audio/Sink", NULL}; - return find_best_media_classes_node (self, media_classes, name, + return find_best_media_classes_node (self, media_classes, def, WP_DIRECTION_OUTPUT); } case VIDEO_SOURCE: { @@ -305,7 +361,7 @@ "Video/Source", "Video/Source/Virtual", NULL}; - return find_best_media_classes_node (self, media_classes, name, + return find_best_media_classes_node (self, media_classes, def, WP_DIRECTION_OUTPUT); } default: @@ -408,6 +464,8 @@ self->defaults[node_t].config_value = g_strdup (name); } + update_prev_config_values (&self->defaults[node_t]); + wp_debug_object (m, "changed '%s' -> '%s'", key, self->defaults[node_t].config_value); @@ -507,6 +565,9 @@ for (guint i = 0; i < N_DEFAULT_NODES; i++) { g_clear_pointer (&self->defaults[i].value, g_free); g_clear_pointer (&self->defaults[i].config_value, g_free); + + for (guint j = 0; j < N_PREV_CONFIGS; j++) + g_clear_pointer (&self->defaults[i].prev_config_value[j], g_free); } g_clear_object (&self->metadata_om); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/modules/module-portal-permissionstore/plugin.h new/wireplumber-0.4.12/modules/module-portal-permissionstore/plugin.h --- old/wireplumber-0.4.11/modules/module-portal-permissionstore/plugin.h 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/modules/module-portal-permissionstore/plugin.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,31 +0,0 @@ -/* WirePlumber - * - * Copyright ?? 2021 Collabora Ltd. - * @author Julian Bouzas <julian.bou...@collabora.com> - * - * SPDX-License-Identifier: MIT - */ - -#ifndef __WIREPLUMBER_PORTAL_PERMISSIONSTORE_PLUGIN_H__ -#define __WIREPLUMBER_PORTAL_PERMISSIONSTORE_PLUGIN_H__ - -#include <wp/wp.h> - -G_BEGIN_DECLS - -G_DECLARE_FINAL_TYPE (WpPortalPermissionStorePlugin, - wp_portal_permissionstore_plugin, WP, PORTAL_PERMISSIONSTORE_PLUGIN, - WpPlugin) - -struct _WpPortalPermissionStorePlugin -{ - WpPlugin parent; - - WpDbus *dbus; - - guint signal_id; -}; - -G_END_DECLS - -#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/modules/module-reserve-device/plugin.c new/wireplumber-0.4.12/modules/module-reserve-device/plugin.c --- old/wireplumber-0.4.11/modules/module-reserve-device/plugin.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/modules/module-reserve-device/plugin.c 2022-10-04 15:25:09.000000000 +0200 @@ -21,12 +21,6 @@ LAST_SIGNAL }; -enum -{ - PROP_0, - PROP_STATE, -}; - static guint signals[LAST_SIGNAL] = { 0 }; static void diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/modules/module-si-standard-link.c new/wireplumber-0.4.12/modules/module-si-standard-link.c --- old/wireplumber-0.4.11/modules/module-si-standard-link.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/modules/module-si-standard-link.c 2022-10-04 15:25:09.000000000 +0200 @@ -133,6 +133,27 @@ } static void +request_destroy_link (gpointer data, gpointer user_data) +{ + WpLink *link = WP_LINK (data); + + wp_global_proxy_request_destroy (WP_GLOBAL_PROXY (link)); +} + +static void +clear_node_links (GPtrArray **node_links_p) +{ + /* + * Something else (eg. object managers) may be keeping the WpLink + * objects alive. Deactive the links now, to destroy the PW objects. + */ + if (*node_links_p) + g_ptr_array_foreach (*node_links_p, request_destroy_link, NULL); + + g_clear_pointer (node_links_p, g_ptr_array_unref); +} + +static void si_standard_link_disable_active (WpSessionItem *si) { WpSiStandardLink *self = WP_SI_STANDARD_LINK (si); @@ -154,7 +175,8 @@ WP_SI_LINKABLE (si_in)); } - g_clear_pointer (&self->node_links, g_ptr_array_unref); + clear_node_links (&self->node_links); + self->n_active_links = 0; self->n_failed_links = 0; self->n_async_ops_wait = 0; @@ -168,7 +190,7 @@ WpTransition * transition) { WpSiStandardLink *self = wp_transition_get_source_object (transition); - guint len = self->node_links->len; + guint len = self->node_links ? self->node_links->len : 0; /* Count the number of failed and active links */ if (wp_object_activate_finish (proxy, res, NULL)) @@ -182,7 +204,7 @@ /* We only active feature if all links activated successfully */ if (self->n_failed_links > 0) { - g_clear_pointer (&self->node_links, g_ptr_array_unref); + clear_node_links (&self->node_links); wp_transition_return_error (transition, g_error_new ( WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_OPERATION_FAILED, "%d of %d PipeWire links failed to activate", @@ -251,7 +273,7 @@ /* Clear old links if any */ self->n_active_links = 0; self->n_failed_links = 0; - g_clear_pointer (&self->node_links, g_ptr_array_unref); + clear_node_links (&self->node_links); /* tuple format: uint32 node_id; @@ -327,7 +349,7 @@ /* activate to ensure it is created without errors */ wp_object_activate_closure (WP_OBJECT (link), - WP_OBJECT_FEATURES_ALL, NULL, + WP_OBJECT_FEATURES_ALL & ~WP_LINK_FEATURE_ESTABLISHED, NULL, g_cclosure_new_object ( (GCallback) on_link_activated, G_OBJECT (transition))); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/po/LINGUAS new/wireplumber-0.4.12/po/LINGUAS --- old/wireplumber-0.4.11/po/LINGUAS 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/po/LINGUAS 2022-10-04 15:25:09.000000000 +0200 @@ -6,9 +6,10 @@ ca cs da -de_CH de +de_CH el +eo es fa fi @@ -22,6 +23,7 @@ id it ja +ka kk kn ko @@ -35,13 +37,14 @@ or pa pl -pt_BR pt +pt_BR ro ru +si sk -sr@latin sr +sr@latin sv ta te @@ -49,5 +52,3 @@ uk zh_CN zh_TW -eo -si diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/po/ca.po new/wireplumber-0.4.12/po/ca.po --- old/wireplumber-0.4.11/po/ca.po 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/po/ca.po 2022-10-04 15:25:09.000000000 +0200 @@ -22,15 +22,15 @@ # Wim Taymans <wim.taym...@gmail.com>, 2016. #zanata # Robert Antoni Buj Gelonch <r...@fedoraproject.org>, 2017. #zanata # Robert Antoni Buj Gelonch <r...@fedoraproject.org>, 2019. #zanata +# Jordi Mas i Hern??ndez <j...@softcatala.org>, 2022 # msgid "" msgstr "" "Project-Id-Version: pipewire\n" -"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/wireplumber/" -"issues/new\n" -"POT-Creation-Date: 2022-04-09 15:19+0300\n" -"PO-Revision-Date: 2012-01-30 09:52+0000\n" -"Last-Translator: Josep Torn?? Llavall <josep.to...@gmail.com>\n" +"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues\n" +"POT-Creation-Date: 2022-07-08 03:32+0000\n" +"PO-Revision-Date: 2022-09-12 09:52+0000\n" +"Last-Translator: Jordi Mas i Hern??ndez <j...@softcatala.org>\n" "Language-Team: Catalan <fed...@softcatala.net>\n" "Language: ca\n" "MIME-Version: 1.0\n" @@ -38,13 +38,12 @@ "Content-Transfer-Encoding: 8bit\n" #. WirePlumber -#. #. Copyright ?? 2021 Collabora Ltd. #. @author George Kiagiadakis <george.kiagiada...@collabora.com> -#. #. SPDX-License-Identifier: MIT #. Receive script arguments from config.lua #. ensure config.properties is not nil +#. unique device/node name tables #. preprocess rules and create Interest objects #. applies properties from config.rules when asked to #. set the device id and spa factory name; REQUIRED, do not change @@ -60,15 +59,63 @@ #. ensure the node has a description #. also sanitize description, replace ':' with ' ' #. add api.alsa.card.* properties for rule matching purposes +#. apply VM overrides #. apply properties from config.rules #. create the node #. ensure the device has an appropriate name #. deduplicate devices with the same name #. ensure the device has a description -#: src/scripts/monitors/alsa.lua:222 +#: src/scripts/monitors/alsa.lua:228 msgid "Built-in Audio" msgstr "??udio intern" -#: src/scripts/monitors/alsa.lua:224 +#: src/scripts/monitors/alsa.lua:230 msgid "Modem" msgstr "M??dem" + +#. ensure the device has a nick +#. set the icon name +#. form factor -> icon +#. apply properties from config.rules +#. override the device factory to use ACP +#. use device reservation, if available +#. unlike pipewire-media-session, this logic here keeps the device +#. acquired at all times and destroys it if someone else acquires +#. create the device +#. attempt to acquire again +#. destroy the device +#. TODO enable the jack device +#. TODO disable the jack device +#. create the device +#. handle create-object to prepare device +#. handle object-removed to destroy device reservations and recycle device +#. name +#. reset the name tables to make sure names are recycled +#. activate monitor +#. create the JACK device (for PipeWire to act as client to a JACK server) +#. enable device reservation if requested +#. if the reserve-device plugin is enabled, at the point of script execution +#. it is expected to be connected. if it is not, assume the d-bus connection +#. has failed and continue without it +#. handle rd_plugin state changes to destroy and re-create the ALSA monitor in +#. case D-Bus service is restarted +#. create the monitor +#. WirePlumber +#. Copyright ?? 2021 Collabora Ltd. +#. @author George Kiagiadakis <george.kiagiada...@collabora.com> +#. SPDX-License-Identifier: MIT +#. preprocess rules and create Interest objects +#. applies properties from config.rules when asked to +#. set the device id and spa factory name; REQUIRED, do not change +#. set the default pause-on-idle setting +#. set the node name +#. sanitize name +#. deduplicate nodes with the same name +#. set the node description +#: src/scripts/monitors/libcamera.lua:88 +msgid "Built-in Front Camera" +msgstr "C??mera frontal integrada" + +#: src/scripts/monitors/libcamera.lua:90 +msgid "Built-in Back Camera" +msgstr "C??mera posterior integrada" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/po/fa.po new/wireplumber-0.4.12/po/fa.po --- old/wireplumber-0.4.11/po/fa.po 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/po/fa.po 2022-10-04 15:25:09.000000000 +0200 @@ -8,15 +8,15 @@ "Project-Id-Version: WirePlumber master\n" "Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/wireplumber/-/" "issues\n" -"POT-Creation-Date: 2022-06-01 03:31+0000\n" -"PO-Revision-Date: 2022-06-01 17:41+0430\n" +"POT-Creation-Date: 2022-07-08 03:32+0000\n" +"PO-Revision-Date: 2022-08-07 04:59+0430\n" "Last-Translator: Danial Behzadi <dani.be...@ubuntu.com>\n" "Language-Team: Persian <f...@li.org>\n" "Language: fa\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.0.1\n" +"X-Generator: Poedit 3.1.1\n" #. WirePlumber #. @@ -42,15 +42,64 @@ #. ensure the node has a description #. also sanitize description, replace ':' with ' ' #. add api.alsa.card.* properties for rule matching purposes +#. apply VM overrides #. apply properties from config.rules #. create the node #. ensure the device has an appropriate name #. deduplicate devices with the same name #. ensure the device has a description -#: src/scripts/monitors/alsa.lua:220 +#: src/scripts/monitors/alsa.lua:228 msgid "Built-in Audio" msgstr "???????? ??????????" -#: src/scripts/monitors/alsa.lua:222 +#: src/scripts/monitors/alsa.lua:230 msgid "Modem" msgstr "????????" + +#. ensure the device has a nick +#. set the icon name +#. form factor -> icon +#. apply properties from config.rules +#. override the device factory to use ACP +#. use device reservation, if available +#. unlike pipewire-media-session, this logic here keeps the device +#. acquired at all times and destroys it if someone else acquires +#. create the device +#. attempt to acquire again +#. destroy the device +#. TODO enable the jack device +#. TODO disable the jack device +#. create the device +#. handle create-object to prepare device +#. handle object-removed to destroy device reservations and recycle device name +#. reset the name tables to make sure names are recycled +#. activate monitor +#. create the JACK device (for PipeWire to act as client to a JACK server) +#. enable device reservation if requested +#. if the reserve-device plugin is enabled, at the point of script execution +#. it is expected to be connected. if it is not, assume the d-bus connection +#. has failed and continue without it +#. handle rd_plugin state changes to destroy and re-create the ALSA monitor in +#. case D-Bus service is restarted +#. create the monitor +#. WirePlumber +#. +#. Copyright ?? 2021 Collabora Ltd. +#. @author George Kiagiadakis <george.kiagiada...@collabora.com> +#. +#. SPDX-License-Identifier: MIT +#. preprocess rules and create Interest objects +#. applies properties from config.rules when asked to +#. set the device id and spa factory name; REQUIRED, do not change +#. set the default pause-on-idle setting +#. set the node name +#. sanitize name +#. deduplicate nodes with the same name +#. set the node description +#: src/scripts/monitors/libcamera.lua:88 +msgid "Built-in Front Camera" +msgstr "???????????? ???????? ??????????" + +#: src/scripts/monitors/libcamera.lua:90 +msgid "Built-in Back Camera" +msgstr "???????????? ?????? ??????????" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/po/hu.po new/wireplumber-0.4.12/po/hu.po --- old/wireplumber-0.4.11/po/hu.po 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/po/hu.po 2022-10-04 15:25:09.000000000 +0200 @@ -1,26 +1,26 @@ -# Hungarian translation of PipeWire +# Hungarian translation for PipeWire. # Copyright (C) 2012, 2016. Free Software Foundation, Inc. # This file is distributed under the same license as the PipeWire package. # -# KAMI <kami...@gmail.com>, 2012. +# KAMI <kami911 at gmail dot com>, 2012. # Gabor Kelemen <kelemeng at ubuntu dot com>, 2016. -# Bal??zs ??r <urbalazs at gmail dot com>, 2016. +# Bal??zs ??r <ur.balazs at fsf dot hu>, 2016, 2022. msgid "" msgstr "" "Project-Id-Version: PipeWire master\n" -"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/wireplumber/" -"issues/new\n" -"POT-Creation-Date: 2022-04-09 15:19+0300\n" -"PO-Revision-Date: 2020-07-21 15:29+0000\n" -"Last-Translator: Bal??zs Mesk?? <meskobal...@mailbox.org>\n" -"Language-Team: Hungarian <https://translate.fedoraproject.org/projects/" -"pipewire/pipewire/hu/>\n" +"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/wireplumber/-/is" +"sues\n" +"POT-Creation-Date: 2022-07-08 03:32+0000\n" +"PO-Revision-Date: 2022-09-21 07:31+0200\n" +"Last-Translator: Bal??zs ??r <ur.balazs at fsf dot hu>\n" +"Language-Team: Hungarian <https://translate.fedoraproject.org/projects/pipewir" +"e/pipewire/hu/>\n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.1.1\n" +"X-Generator: Lokalize 19.12.3\n" "X-Poedit-Language: Hungarian\n" "X-Poedit-Country: HUNGARY\n" "X-Poedit-SourceCharset: utf-8\n" @@ -33,6 +33,7 @@ #. SPDX-License-Identifier: MIT #. Receive script arguments from config.lua #. ensure config.properties is not nil +#. unique device/node name tables #. preprocess rules and create Interest objects #. applies properties from config.rules when asked to #. set the device id and spa factory name; REQUIRED, do not change @@ -48,15 +49,64 @@ #. ensure the node has a description #. also sanitize description, replace ':' with ' ' #. add api.alsa.card.* properties for rule matching purposes +#. apply VM overrides #. apply properties from config.rules #. create the node #. ensure the device has an appropriate name #. deduplicate devices with the same name #. ensure the device has a description -#: src/scripts/monitors/alsa.lua:222 +#: src/scripts/monitors/alsa.lua:228 msgid "Built-in Audio" msgstr "Bels?? hangforr??s" -#: src/scripts/monitors/alsa.lua:224 +#: src/scripts/monitors/alsa.lua:230 msgid "Modem" msgstr "Modem" + +#. ensure the device has a nick +#. set the icon name +#. form factor -> icon +#. apply properties from config.rules +#. override the device factory to use ACP +#. use device reservation, if available +#. unlike pipewire-media-session, this logic here keeps the device +#. acquired at all times and destroys it if someone else acquires +#. create the device +#. attempt to acquire again +#. destroy the device +#. TODO enable the jack device +#. TODO disable the jack device +#. create the device +#. handle create-object to prepare device +#. handle object-removed to destroy device reservations and recycle device name +#. reset the name tables to make sure names are recycled +#. activate monitor +#. create the JACK device (for PipeWire to act as client to a JACK server) +#. enable device reservation if requested +#. if the reserve-device plugin is enabled, at the point of script execution +#. it is expected to be connected. if it is not, assume the d-bus connection +#. has failed and continue without it +#. handle rd_plugin state changes to destroy and re-create the ALSA monitor in +#. case D-Bus service is restarted +#. create the monitor +#. WirePlumber +#. +#. Copyright ?? 2021 Collabora Ltd. +#. @author George Kiagiadakis <george.kiagiada...@collabora.com> +#. +#. SPDX-License-Identifier: MIT +#. preprocess rules and create Interest objects +#. applies properties from config.rules when asked to +#. set the device id and spa factory name; REQUIRED, do not change +#. set the default pause-on-idle setting +#. set the node name +#. sanitize name +#. deduplicate nodes with the same name +#. set the node description +#: src/scripts/monitors/libcamera.lua:88 +msgid "Built-in Front Camera" +msgstr "Be??p??tett el??ls?? kamera" + +#: src/scripts/monitors/libcamera.lua:90 +msgid "Built-in Back Camera" +msgstr "Be??p??tett h??ts?? kamera" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/po/ka.po new/wireplumber-0.4.12/po/ka.po --- old/wireplumber-0.4.11/po/ka.po 1970-01-01 01:00:00.000000000 +0100 +++ new/wireplumber-0.4.12/po/ka.po 2022-10-04 15:25:09.000000000 +0200 @@ -0,0 +1,104 @@ +# Georgian translation for pipewire. +# Copyright ?? 2008-2022 Free Software Foundation, Inc. +# This file is distributed under the same license as the pipewire package. +# Temuri Doghonadze <temuri.doghona...@gmail.com>, 2022. +msgid "" +msgstr "" +"Project-Id-Version: pipewire\n" +"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/pipewire/wireplumber/-/" +"issues\n" +"POT-Creation-Date: 2022-06-15 15:30+0000\n" +"PO-Revision-Date: 2022-07-25 13:53+0200\n" +"Last-Translator: Temuri Doghonadze <temuri.doghona...@gmail.com>\n" +"Language-Team: Georgian <(nothing)>\n" +"Language: ka\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.1.1\n" + +#. WirePlumber +#. +#. Copyright ?? 2021 Collabora Ltd. +#. @author George Kiagiadakis <george.kiagiada...@collabora.com> +#. +#. SPDX-License-Identifier: MIT +#. Receive script arguments from config.lua +#. ensure config.properties is not nil +#. unique device/node name tables +#. preprocess rules and create Interest objects +#. applies properties from config.rules when asked to +#. set the device id and spa factory name; REQUIRED, do not change +#. set the default pause-on-idle setting +#. try to negotiate the max ammount of channels +#. set priority +#. ensure the node has a media class +#. ensure the node has a name +#. sanitize name +#. deduplicate nodes with the same name +#. and a nick +#. also sanitize nick, replace ':' with ' ' +#. ensure the node has a description +#. also sanitize description, replace ':' with ' ' +#. add api.alsa.card.* properties for rule matching purposes +#. apply properties from config.rules +#. create the node +#. ensure the device has an appropriate name +#. deduplicate devices with the same name +#. ensure the device has a description +#: src/scripts/monitors/alsa.lua:220 +msgid "Built-in Audio" +msgstr "?????????????????????????????? ???????????????" + +#: src/scripts/monitors/alsa.lua:222 +msgid "Modem" +msgstr "??????????????????" + +#. ensure the device has a nick +#. set the icon name +#. form factor -> icon +#. apply properties from config.rules +#. override the device factory to use ACP +#. use device reservation, if available +#. unlike pipewire-media-session, this logic here keeps the device +#. acquired at all times and destroys it if someone else acquires +#. create the device +#. attempt to acquire again +#. destroy the device +#. TODO enable the jack device +#. TODO disable the jack device +#. create the device +#. handle create-object to prepare device +#. handle object-removed to destroy device reservations and recycle device name +#. reset the name tables to make sure names are recycled +#. activate monitor +#. create the JACK device (for PipeWire to act as client to a JACK server) +#. enable device reservation if requested +#. if the reserve-device plugin is enabled, at the point of script execution +#. it is expected to be connected. if it is not, assume the d-bus connection +#. has failed and continue without it +#. handle rd_plugin state changes to destroy and re-create the ALSA monitor in +#. case D-Bus service is restarted +#. create the monitor +#. WirePlumber +#. +#. Copyright ?? 2021 Collabora Ltd. +#. @author George Kiagiadakis <george.kiagiada...@collabora.com> +#. +#. SPDX-License-Identifier: MIT +#. preprocess rules and create Interest objects +#. applies properties from config.rules when asked to +#. set the device id and spa factory name; REQUIRED, do not change +#. set the default pause-on-idle setting +#. set the node name +#. sanitize name +#. deduplicate nodes with the same name +#. set the node description +#: src/scripts/monitors/libcamera.lua:88 +msgid "Built-in Front Camera" +msgstr "?????????????????????????????? ???????????? ??????????????????" + +#: src/scripts/monitors/libcamera.lua:90 +msgid "Built-in Back Camera" +msgstr "?????????????????????????????? ??????????????? ??????????????????" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/config/bluetooth.lua.d/50-bluez-config.lua new/wireplumber-0.4.12/src/config/bluetooth.lua.d/50-bluez-config.lua --- old/wireplumber-0.4.11/src/config/bluetooth.lua.d/50-bluez-config.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/config/bluetooth.lua.d/50-bluez-config.lua 2022-10-04 15:25:09.000000000 +0200 @@ -37,6 +37,18 @@ -- Disable if you are running mpris-proxy or equivalent. --["bluez5.dummy-avrcp-player"] = true, + -- Opus Pro Audio mode settings + --["bluez5.a2dp.opus.pro.channels"] = 3, -- no. channels + --["bluez5.a2dp.opus.pro.coupled-streams"] = 1, -- no. joint stereo pairs, see RFC 7845 Sec. 5.1.1 + --["bluez5.a2dp.opus.pro.locations"] = "FL,FR,LFE", -- audio locations + --["bluez5.a2dp.opus.pro.max-bitrate"] = 600000, + --["bluez5.a2dp.opus.pro.frame-dms"] = 50, -- frame duration in 1/10 ms: 25, 50, 100, 200, 400 + --["bluez5.a2dp.opus.pro.bidi.channels"] = 1, -- same settings for the return direction + --["bluez5.a2dp.opus.pro.bidi.coupled-streams"] = 0, + --["bluez5.a2dp.opus.pro.bidi.locations"] = "FC", + --["bluez5.a2dp.opus.pro.bidi.max-bitrate"] = 160000, + --["bluez5.a2dp.opus.pro.bidi.frame-dms"] = 400, + -- Enable the logind module, which arbitrates which user will be allowed -- to have bluetooth audio enabled at any given time (particularly useful -- if you are using GDM as a display manager, as the gdm user also launches @@ -83,6 +95,10 @@ -- Profile connected first -- Available values: a2dp-sink (default), headset-head-unit --["device.profile"] = "a2dp-sink", + + -- Opus Pro Audio encoding mode: audio, voip, lowdelay + --["bluez5.a2dp.opus.pro.application"] = "audio", + --["bluez5.a2dp.opus.pro.bidi.application"] = "audio", }, }, { @@ -107,10 +123,10 @@ --["session.suspend-timeout-seconds"] = 5, -- 0 disables suspend --["monitor.channel-volumes"] = false, - -- A2DP source role, "input" or "playback" + -- Media source role, "input" or "playback" -- Defaults to "playback", playing stream to speakers -- Set to "input" to use as an input for apps - --["bluez5.a2dp-source-role"] = "input", + --["bluez5.media-source-role"] = "input", }, }, } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/config/main.lua.d/40-device-defaults.lua new/wireplumber-0.4.12/src/config/main.lua.d/40-device-defaults.lua --- old/wireplumber-0.4.11/src/config/main.lua.d/40-device-defaults.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/config/main.lua.d/40-device-defaults.lua 2022-10-04 15:25:09.000000000 +0200 @@ -7,8 +7,9 @@ -- their priorities and any runtime changes do not persist after restart ["use-persistent-storage"] = true, - -- the default volume to apply to ACP device nodes, in the linear scale - --["default-volume"] = 0.4, + -- the default volumes to apply to ACP device nodes, in the linear scale + --["default-volume"] = 0.064, + --["default-input-volume"] = 1.0, -- Whether to auto-switch to echo cancel sink and source nodes or not ["auto-echo-cancel"] = true, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/config/main.lua.d/50-alsa-config.lua new/wireplumber-0.4.12/src/config/main.lua.d/50-alsa-config.lua --- old/wireplumber-0.4.11/src/config/main.lua.d/50-alsa-config.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/config/main.lua.d/50-alsa-config.lua 2022-10-04 15:25:09.000000000 +0200 @@ -20,6 +20,14 @@ -- Enables monitoring of alsa MIDI devices ["alsa.midi.monitoring"] = true, + -- MIDI bridge node properties + ["alsa.midi.node-properties"] = { + -- Name set for the node with ALSA MIDI ports + ["node.name"] = "Midi-Bridge", + -- Removes longname/number from MIDI port names + --["api.alsa.disable-longname"] = true, + }, + -- These properties override node defaults when running in a virtual machine. -- The rules below still override those. ["vm.node.defaults"] = { @@ -124,6 +132,7 @@ --["channelmix.hilbert-taps"] = 0, --["channelmix.disable"] = false, --["dither.noise"] = 0, + --["dither.method"] = "none", -- "rectangular", "triangular" or "shaped5" --["audio.channels"] = 2, --["audio.format"] = "S16LE", --["audio.rate"] = 44100, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/config/policy.lua.d/10-default-policy.lua new/wireplumber-0.4.12/src/config/policy.lua.d/10-default-policy.lua --- old/wireplumber-0.4.11/src/config/policy.lua.d/10-default-policy.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/config/policy.lua.d/10-default-policy.lua 2022-10-04 15:25:09.000000000 +0200 @@ -34,7 +34,12 @@ -- Application names correspond to application.name in stream properties. -- Applications which do not set media.role but which should be considered -- for role based profile switching can be specified here. - ["media-role.applications"] = { "Firefox", "Chromium input", "Google Chrome input", "Brave input", "Microsoft Edge input", "Vivaldi input", "ZOOM VoiceEngine", "Telegram Desktop", "telegram-desktop", "linphone", "Mumble" }, + ["media-role.applications"] = { + "Firefox", "Chromium input", "Google Chrome input", "Brave input", + "Microsoft Edge input", "Vivaldi input", "ZOOM VoiceEngine", + "Telegram Desktop", "telegram-desktop", "linphone", "Mumble", + "WEBRTC VoiceEngine", "Skype" + }, } function default_policy.enable() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/main.c new/wireplumber-0.4.12/src/main.c --- old/wireplumber-0.4.11/src/main.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/main.c 2022-10-04 15:25:09.000000000 +0200 @@ -24,10 +24,13 @@ WP_EXIT_CONFIG = 78, /* configuration error */ }; +static gboolean show_version = FALSE; static gchar * config_file = NULL; static GOptionEntry entries[] = { + { "version", 'v', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &show_version, + "Show version", NULL }, { "config-file", 'c', G_OPTION_FLAG_NONE, G_OPTION_ARG_STRING, &config_file, "The context configuration file", NULL }, { NULL } @@ -427,6 +430,16 @@ return WP_EXIT_USAGE; } + if (show_version) { + g_print ("%s\n" + "Compiled with libwireplumber %s\n" + "Linked with libwireplumber %s\n", + argv[0], + WIREPLUMBER_VERSION, + wp_get_library_version()); + return WP_EXIT_OK; + } + if (!config_file) config_file = "wireplumber.conf"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/scripts/monitors/alsa-midi.lua new/wireplumber-0.4.12/src/scripts/monitors/alsa-midi.lua --- old/wireplumber-0.4.11/src/scripts/monitors/alsa-midi.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/scripts/monitors/alsa-midi.lua 2022-10-04 15:25:09.000000000 +0200 @@ -21,8 +21,11 @@ function CreateMidiNode () -- Midi properties local props = {} + if type(config.properties["alsa.midi.node-properties"]) == "table" then + props = config.properties["alsa.midi.node-properties"] + end props["factory.name"] = "api.alsa.seq.bridge" - props["node.name"] = "Midi-Bridge" + props["node.name"] = props["node.name"] or "Midi-Bridge" -- create the midi node local node = Node("spa-node-factory", props) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/scripts/monitors/alsa.lua new/wireplumber-0.4.12/src/scripts/monitors/alsa.lua --- old/wireplumber-0.4.11/src/scripts/monitors/alsa.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/scripts/monitors/alsa.lua 2022-10-04 15:25:09.000000000 +0200 @@ -49,7 +49,7 @@ return str ~= "" and str or nil end -function createNode(parent, id, type, factory, properties) +function createNode(parent, id, obj_type, factory, properties) local dev_props = parent.properties -- set the device id and spa factory name; REQUIRED, do not change @@ -199,7 +199,7 @@ end end -function prepareDevice(parent, id, type, factory, properties) +function prepareDevice(parent, id, obj_type, factory, properties) -- ensure the device has an appropriate name local name = "alsa_card." .. (properties["device.name"] or @@ -385,7 +385,7 @@ -- if the reserve-device plugin is enabled, at the point of script execution -- it is expected to be connected. if it is not, assume the d-bus connection -- has failed and continue without it -if rd_plugin and rd_plugin["state"] ~= "connected" then +if rd_plugin and rd_plugin:call("get-dbus")["state"] ~= "connected" then Log.message("reserve-device plugin is not connected to D-Bus, " .. "disabling device reservation") rd_plugin = nil diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/scripts/monitors/bluez.lua new/wireplumber-0.4.12/src/scripts/monitors/bluez.lua --- old/wireplumber-0.4.11/src/scripts/monitors/bluez.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/scripts/monitors/bluez.lua 2022-10-04 15:25:09.000000000 +0200 @@ -62,7 +62,7 @@ ((factory:find("sink") and "bluez_output") or (factory:find("source") and "bluez_input" or factory)) .. "." .. (properties["api.bluez5.address"] or dev_props["device.name"]) .. "." .. - (properties["api.bluez5.profile"] or "unknown") + tostring(id) -- sanitize name properties["node.name"] = name:gsub("([^%w_%-%.])", "_") @@ -75,7 +75,8 @@ -- autoconnect if it's a stream if properties["api.bluez5.profile"] == "headset-audio-gateway" or - factory:find("a2dp.source") then + properties["api.bluez5.profile"] == "bap-sink" or + factory:find("a2dp.source") or factory:find("media.source") then properties["node.autoconnect"] = true end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/scripts/policy-device-profile.lua new/wireplumber-0.4.12/src/scripts/policy-device-profile.lua --- old/wireplumber-0.4.11/src/scripts/policy-device-profile.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/scripts/policy-device-profile.lua 2022-10-04 15:25:09.000000000 +0200 @@ -9,7 +9,6 @@ self.config = ... or {} self.config.persistent = self.config.persistent or {} self.active_profiles = {} -self.best_profiles = {} self.default_profile_plugin = Plugin.find("default-profile") -- Preprocess persisten profiles and create Interest objects @@ -123,25 +122,6 @@ return nil end -function handleBestProfile (device, dev_id, dev_name) - -- Find best profile - local profile = findBestProfile (device) - if profile == nil then - Log.info ("Cannot find best profile for device " .. dev_name) - return false - end - - -- Update if it has changed - if self.best_profiles[dev_id] == nil or - self.best_profiles[dev_id].index ~= profile.index then - self.best_profiles[dev_id] = profile - Log.info ("Best profile changed to " .. profile.name .. " in " .. dev_name) - return true - end - - return false -end - function handleProfiles (device, new_device) local dev_id = device["bound-id"] local dev_name = device.properties["device.name"] @@ -172,13 +152,10 @@ Log.info ("Default profile not found for " .. dev_name) end - -- Otherwise just set the best profile if changed - local best_changed = handleBestProfile (device, dev_id, dev_name) - local best_profile = self.best_profiles[dev_id] - if best_changed and best_profile ~= nil then + local best_profile = findBestProfile (device) + if best_profile ~= nil then + Log.info ("Found best profile " .. best_profile.name .. " for " .. dev_name) setDeviceProfile (device, dev_id, dev_name, best_profile) - elseif best_profile ~= nil then - Log.info ("Best profile " .. best_profile.name .. " did not change on " .. dev_name) else Log.info ("Best profile not found on " .. dev_name) end @@ -205,7 +182,6 @@ self.om:connect("object-removed", function (_, device) local dev_id = device["bound-id"] self.active_profiles[dev_id] = nil - self.best_profiles[dev_id] = nil end) self.om:activate() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/scripts/policy-device-routes.lua new/wireplumber-0.4.12/src/scripts/policy-device-routes.lua --- old/wireplumber-0.4.11/src/scripts/policy-device-routes.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/scripts/policy-device-routes.lua 2022-10-04 15:25:09.000000000 +0200 @@ -14,7 +14,8 @@ use_persistent_storage = config["use-persistent-storage"] or false -- the default volume to apply -default_volume = tonumber(config["default-volume"] or 0.4) +default_volume = tonumber(config["default-volume"] or 0.4^3) +default_input_volume = tonumber(config["default-input-volume"] or 1.0) -- table of device info dev_infos = {} @@ -133,10 +134,15 @@ -- default props local props = { "Spa:Pod:Object:Param:Props", "Route", - channelVolumes = { default_volume }, mute = false, } + if route.direction == "Input" then + props.channelVolumes = { default_input_volume } + else + props.channelVolumes = { default_volume } + end + -- restore props from persistent storage if use_persistent_storage then local key_base = dev_info.name .. ":" .. @@ -252,7 +258,9 @@ -- spr needs to be the array returned from getStoredProfileRoutes() function findSavedRoute(dev_info, device_id, spr) for idx, ri in pairs(dev_info.route_infos) do - if arrayContains(ri.devices, device_id) and arrayContains(spr, ri.name) then + if arrayContains(ri.devices, device_id) and + (ri.profiles == nil or arrayContains(ri.profiles, dev_info.active_profile)) and + arrayContains(spr, ri.name) then return ri end end @@ -264,7 +272,8 @@ local best_avail = nil local best_unk = nil for idx, ri in pairs(dev_info.route_infos) do - if arrayContains(ri.devices, device_id) then + if arrayContains(ri.devices, device_id) and + (ri.profiles == nil or arrayContains(ri.profiles, dev_info.active_profile)) then if ri.available == "yes" or ri.available == "unknown" then if ri.direction == "Output" and ri.available ~= ri.prev_available then best_avail = ri @@ -337,6 +346,7 @@ name = route.name, direction = route.direction, devices = route.devices or {}, + profiles = route.profiles, priority = route.priority or 0, available = route.available or "unknown", prev_available = route.available or "unknown", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/scripts/policy-node.lua new/wireplumber-0.4.12/src/scripts/policy-node.lua --- old/wireplumber-0.4.11/src/scripts/policy-node.lua 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/scripts/policy-node.lua 2022-10-04 15:25:09.000000000 +0200 @@ -694,16 +694,15 @@ local link = lookupLink (si_id, si_flags[si_id].peer_id) if reconnect then if link ~= nil then - -- remove old link if active, otherwise schedule rescan - if ((link:get_active_features() & Feature.SessionItem.ACTIVE) ~= 0) then - si_flags[si_id].peer_id = nil - link:remove () - Log.info (si, "... moving to new target") - else - scheduleRescan() - Log.info (si, "... scheduled rescan") - return + -- remove old link + if ((link:get_active_features() & Feature.SessionItem.ACTIVE) == 0) then + -- remove also not yet activated links: they might never become active, + -- and we should not loop waiting for them + Log.warning (link, "Link was not activated before removing") end + si_flags[si_id].peer_id = nil + link:remove () + Log.info (si, "... moving to new target") end else if link ~= nil then diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/src/tools/wpctl.c new/wireplumber-0.4.12/src/tools/wpctl.c --- old/wireplumber-0.4.11/src/tools/wpctl.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/src/tools/wpctl.c 2022-10-04 15:25:09.000000000 +0200 @@ -44,6 +44,7 @@ struct { guint64 id; gfloat volume; + gdouble limit; gboolean is_pid; gchar type; } set_volume; @@ -935,6 +936,11 @@ if (cmdline.set_volume.volume < 0) { cmdline.set_volume.volume = 0.0; } + if (cmdline.set_volume.limit > 0) { + if (cmdline.set_volume.volume > cmdline.set_volume.limit) { + cmdline.set_volume.volume = cmdline.set_volume.limit; + } + } g_variant_builder_add (&b, "{sv}", "volume", g_variant_new_double (cmdline.set_volume.volume)); @@ -1180,11 +1186,19 @@ clear_default_parse_positional (gint argc, gchar ** argv, GError **error) { if (argc >= 3) { - return parse_id (true, true, argv[2], &cmdline.clear_default.id, error); + long id = strtol (argv[2], NULL, 10); + if (id < 0 || id >= (long)G_N_ELEMENTS (DEFAULT_NODE_MEDIA_CLASSES)) { + g_set_error (error, wpctl_error_domain_quark(), 0, + "The setting ID value must be between 0 and %ld inclusive", + G_N_ELEMENTS (DEFAULT_NODE_MEDIA_CLASSES) - 1); + return FALSE; + } + cmdline.clear_default.id = id; } else { cmdline.clear_default.id = SPA_ID_INVALID; - return TRUE; } + + return TRUE; } static gboolean @@ -1198,7 +1212,6 @@ { g_autoptr (WpPlugin) def_nodes_api = NULL; g_autoptr (GError) error = NULL; - guint32 id; gboolean res = FALSE; def_nodes_api = wp_plugin_find (self->core, "default-nodes-api"); @@ -1207,13 +1220,8 @@ goto out; } - if (!translate_id (def_nodes_api, cmdline.clear_default.id, &id, &error)) { - fprintf(stderr, "Translate ID error: %s\n\n", error->message); - goto out; - } - /* clear all defaults if id was not given */ - if (id == SPA_ID_INVALID) { + if (cmdline.clear_default.id == SPA_ID_INVALID) { for (guint i = 0; i < G_N_ELEMENTS (DEFAULT_NODE_MEDIA_CLASSES); i++) { g_signal_emit_by_name (def_nodes_api, "set-default-configured-node-name", DEFAULT_NODE_MEDIA_CLASSES[i], NULL, &res); @@ -1224,16 +1232,11 @@ } } } else { - if (id < G_N_ELEMENTS (DEFAULT_NODE_MEDIA_CLASSES)) { - g_signal_emit_by_name (def_nodes_api, "set-default-configured-node-name", - DEFAULT_NODE_MEDIA_CLASSES[id], NULL, &res); - if (!res) { - fprintf (stderr, "failed to clear default configured node (%s)\n", - DEFAULT_NODE_MEDIA_CLASSES[id]); - goto out; - } - } else { - fprintf (stderr, "Id %d is not a valid default node Id\n", id); + g_signal_emit_by_name (def_nodes_api, "set-default-configured-node-name", + DEFAULT_NODE_MEDIA_CLASSES[cmdline.clear_default.id], NULL, &res); + if (!res) { + fprintf (stderr, "failed to clear default configured node (%s)\n", + DEFAULT_NODE_MEDIA_CLASSES[cmdline.clear_default.id]); goto out; } } @@ -1327,6 +1330,9 @@ { "pid", 'p', G_OPTION_FLAG_NONE, G_OPTION_ARG_NONE, &cmdline.set_volume.is_pid, "Selects all nodes associated to the given PID number", NULL }, + { "limit", 'l', G_OPTION_FLAG_NONE, G_OPTION_ARG_DOUBLE, + &cmdline.set_volume.limit, + "Limits the final volume percentage to below this value. (floating point, 1.0 is 100%)", NULL }, { NULL } }, .parse_positional = set_volume_parse_positional, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/wireplumber-0.4.11/tests/wp/spa-json.c new/wireplumber-0.4.12/tests/wp/spa-json.c --- old/wireplumber-0.4.11/tests/wp/spa-json.c 2022-07-05 15:22:15.000000000 +0200 +++ new/wireplumber-0.4.12/tests/wp/spa-json.c 2022-10-04 15:25:09.000000000 +0200 @@ -910,6 +910,40 @@ } static void +test_spa_json_nested3 (void) +{ + const gchar json_str[] = + "{ test-setting-json3: { key1: \"value\", key2: 2, key3: true } }"; + g_autoptr (WpSpaJson) json = wp_spa_json_new_from_string (json_str); + g_assert_nonnull (json); + g_assert_true (wp_spa_json_is_object (json)); + + g_autoptr (WpIterator) it = wp_spa_json_new_iterator (json); + g_assert_nonnull (it); + + { + GValue next = G_VALUE_INIT; + g_assert_true (wp_iterator_next (it, &next)); + WpSpaJson *j = g_value_get_boxed (&next); + g_assert_nonnull (j); + g_autofree gchar *v = wp_spa_json_parse_string (j); + g_assert_cmpstr (v, ==, "test-setting-json3"); + g_value_unset (&next); + } + + { + GValue next = G_VALUE_INIT; + g_assert_true (wp_iterator_next (it, &next)); + WpSpaJson *j = g_value_get_boxed (&next); + g_assert_nonnull (j); + g_assert_true (wp_spa_json_is_object (j)); + g_autofree gchar *v = wp_spa_json_to_string (j); + g_assert_cmpstr (v, ==, "{ key1: \"value\", key2: 2, key3: true }"); + g_value_unset (&next); + } +} + +static void test_spa_json_ownership (void) { g_autoptr (WpSpaJson) json = NULL; @@ -1161,6 +1195,7 @@ test_spa_json_object_builder_parser_iterator); g_test_add_func ("/wp/spa-json/nested", test_spa_json_nested); g_test_add_func ("/wp/spa-json/nested2", test_spa_json_nested2); + g_test_add_func ("/wp/spa-json/nested3", test_spa_json_nested3); g_test_add_func ("/wp/spa-json/ownership", test_spa_json_ownership); g_test_add_func ("/wp/spa-json/spa-format", test_spa_json_spa_format); g_test_add_func ("/wp/spa-json/to-string", test_spa_json_to_string); ++++++ wireplumber.obsinfo ++++++ --- /var/tmp/diff_new_pack.kTQ3O7/_old 2022-10-11 18:04:05.021942604 +0200 +++ /var/tmp/diff_new_pack.kTQ3O7/_new 2022-10-11 18:04:05.025942610 +0200 @@ -1,5 +1,5 @@ name: wireplumber -version: 0.4.11 -mtime: 1657027335 -commit: 80b3559963f0ad40a7bfa6c23b0098275c0b5ebe +version: 0.4.12 +mtime: 1664889909 +commit: 6f6e5df9c1b223907efa8dcbfcd538821d0dabc4