From ff019936a70262c176a4bd950bc80ab84d2a71b0 Mon Sep 17 00:00:00 2001
From: George Kiagiadakis <george.kiagiadakis@collabora.com>
Date: Tue, 22 Jun 2021 13:23:22 +0300
Subject: [PATCH] alsa plugin: allow specifying a media.role on the virtual
 device name

So that we can do:
  aplay -D pipewire:ROLE=Music music.wav
  aplay -D pipewire:ROLE=Notification notice.wav

Upstream-Status: Backport [from master/0.3.31]
---
 pipewire-alsa/alsa-plugins/pcm_pipewire.c | 14 +++++++++++++-
 pipewire-alsa/conf/50-pipewire.conf       | 11 ++++++++++-
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/pipewire-alsa/alsa-plugins/pcm_pipewire.c b/pipewire-alsa/alsa-plugins/pcm_pipewire.c
index 86792d2c7..6ace1b689 100644
--- a/pipewire-alsa/alsa-plugins/pcm_pipewire.c
+++ b/pipewire-alsa/alsa-plugins/pcm_pipewire.c
@@ -59,6 +59,7 @@ typedef struct {
 
 	char *node_name;
 	char *target;
+	char *role;
 
 	int fd;
 	int error;
@@ -509,6 +510,9 @@ static int snd_pcm_pipewire_prepare(snd_pcm_ioplug_t *io)
 		pw_properties_set(props, PW_KEY_MEDIA_CATEGORY,
 				io->stream == SND_PCM_STREAM_PLAYBACK ?
 				"Playback" : "Capture");
+	if (pw->role != NULL &&
+		pw_properties_get(props, PW_KEY_MEDIA_ROLE) == NULL)
+		pw_properties_setf(props, PW_KEY_MEDIA_ROLE, "%s", pw->role);
 
 	pw->stream = pw_stream_new(pw->core, pw->node_name, props);
 	if (pw->stream == NULL)
@@ -958,6 +962,7 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name,
 				const char *server_name,
 				const char *playback_node,
 				const char *capture_node,
+				const char *role,
 				snd_pcm_stream_t stream,
 				int mode,
 				uint32_t flags,
@@ -1013,6 +1018,8 @@ static int snd_pcm_pipewire_open(snd_pcm_t **pcmp, const char *name,
 			pw->target = capture_node ? strdup(capture_node) : NULL;
 	}
 
+	pw->role = (role && *role) ? strdup(role) : NULL;
+
 	pw->main_loop = pw_thread_loop_new("alsa-pipewire", NULL);
 	if (pw->main_loop == NULL) {
 		err = -errno;
@@ -1091,6 +1098,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pipewire)
 	const char *server_name = NULL;
 	const char *playback_node = NULL;
 	const char *capture_node = NULL;
+	const char *role = NULL;
 	snd_pcm_format_t format = SND_PCM_FORMAT_UNKNOWN;
 	int rate = 0;
 	int channels = 0;
@@ -1125,6 +1133,10 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pipewire)
 			snd_config_get_string(n, &capture_node);
 			continue;
 		}
+		if (spa_streq(id, "role")) {
+			snd_config_get_string(n, &role);
+			continue;
+		}
 		if (spa_streq(id, "exclusive")) {
 			if (snd_config_get_bool(n))
 				flags |= PW_STREAM_FLAG_EXCLUSIVE;
@@ -1174,7 +1186,7 @@ SND_PCM_PLUGIN_DEFINE_FUNC(pipewire)
 	}
 
 	err = snd_pcm_pipewire_open(pcmp, name, node_name, server_name, playback_node,
-			capture_node, stream, mode, flags, rate, format,
+			capture_node, role, stream, mode, flags, rate, format,
 			channels, period_bytes);
 
 	return err;
diff --git a/pipewire-alsa/conf/50-pipewire.conf b/pipewire-alsa/conf/50-pipewire.conf
index 2c6f2d259..f7e58472b 100644
--- a/pipewire-alsa/conf/50-pipewire.conf
+++ b/pipewire-alsa/conf/50-pipewire.conf
@@ -3,9 +3,10 @@
 defaults.pipewire.server "pipewire-0"
 defaults.pipewire.node "-1"
 defaults.pipewire.exclusive false
+defaults.pipewire.role ""
 
 pcm.pipewire {
-	@args [ SERVER NODE EXCLUSIVE ]
+	@args [ SERVER NODE EXCLUSIVE ROLE ]
 	@args.SERVER {
 		type string
 		default {
@@ -27,6 +28,13 @@ pcm.pipewire {
 			name defaults.pipewire.exclusive
 		}
 	}
+	@args.ROLE {
+		type string
+		default {
+			@func refer
+			name defaults.pipewire.role
+		}
+	}
 
 
 	type pipewire
@@ -34,6 +42,7 @@ pcm.pipewire {
 	playback_node $NODE
 	capture_node $NODE
 	exclusive $EXCLUSIVE
+	role $ROLE
 	hint {
 		show on
 		description "PipeWire Sound Server"
-- 
2.30.2

