[pulseaudio-discuss] [PATCH 29/30] pacat: Add --routing
Tanu Kaskinen
tanu.kaskinen at linux.intel.com
Thu Jan 16 07:02:55 PST 2014
---
man/pacat.1.xml.in | 26 ++++++++++++++++++++++++++
src/utils/pacat.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/man/pacat.1.xml.in b/man/pacat.1.xml.in
index 1c5a6c0..c546246 100644
--- a/man/pacat.1.xml.in
+++ b/man/pacat.1.xml.in
@@ -84,6 +84,32 @@ USA.
</option>
<option>
+ <p><opt>--routing</opt><arg>=NODES</arg></p>
+
+ <optdesc><p>Specify how the stream should be routed. The argument is
+ a comma-separated list of node names. The possibility to specify multiple
+ nodes exists so that the stream can be played to multiple devices
+ simultaneously. As of version 6.0, the server doesn't yet support this,
+ however.</p>
+
+ <p>The --device and --monitor-stream options also control the routing,
+ and to avoid confusion, it's not possible to use --routing together with
+ --device and --monitor-stream. Which option is "better", then? --routing
+ is the most recent addition, and it sort of supersedes both the --device
+ and --monitor-stream options, but sometimes it may be more convenient to
+ use the old options. Choose whichever option suits you best.</p>
+
+ <p>As of PulseAudio 6.0, there is one significant drawback with --routing
+ compared to --device: the node names for devices are not "stable", which
+ means that the node name of a device can be different after a reboot or
+ after the device has been removed and added back to the system. Sink and
+ source names, which are used with the --device option, tend to stay the
+ same for longer times (ideally forever, but we can't really promise
+ that). This problem with node names will hopefully go away eventually.
+ </p></optdesc>
+ </option>
+
+ <option>
<p><opt>--monitor-stream</opt><arg>=INDEX</arg></p>
<optdesc><p>Record from the sink input with index INDEX.</p></optdesc>
diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index e1abc31..ea68236 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -41,6 +41,7 @@
#include <pulse/rtclock.h>
#include <pulsecore/core-util.h>
+#include <pulsecore/dynarray.h>
#include <pulsecore/i18n.h>
#include <pulsecore/log.h>
#include <pulsecore/macro.h>
@@ -67,6 +68,7 @@ static pa_io_event* stdio_event = NULL;
static pa_proplist *proplist = NULL;
static char *device = NULL;
+static pa_dynarray *routing = NULL;
static SNDFILE* sndfile = NULL;
@@ -449,6 +451,8 @@ static void stream_event_callback(pa_stream *s, const char *name, pa_proplist *p
/* This is called whenever the context status changes */
static void context_state_callback(pa_context *c, void *userdata) {
+ int r;
+
pa_assert(c);
switch (pa_context_get_state(c)) {
@@ -482,6 +486,15 @@ static void context_state_callback(pa_context *c, void *userdata) {
pa_stream_set_event_callback(stream, stream_event_callback, NULL);
pa_stream_set_buffer_attr_callback(stream, stream_buffer_attr_callback, NULL);
+ if (pa_dynarray_size(routing) > 0) {
+ r = pa_stream_set_initial_routing(stream, (const char * const *) pa_dynarray_get_raw_array(routing),
+ pa_dynarray_size(routing));
+ if (r < 0) {
+ pa_log("pa_stream_set_initial_routing() failed: %s", pa_strerror(r));
+ goto fail;
+ }
+ }
+
pa_zero(buffer_attr);
buffer_attr.maxlength = (uint32_t) -1;
buffer_attr.prebuf = (uint32_t) -1;
@@ -677,6 +690,7 @@ static void help(const char *argv0) {
" -v, --verbose Enable verbose operations\n\n"
" -s, --server=SERVER The name of the server to connect to\n"
" -d, --device=DEVICE The name of the sink/source to connect to\n"
+ " --routing=NODES Comma-separated list of node names\n"
" -n, --client-name=NAME How to call this client on the server\n"
" --stream-name=NAME How to call this stream on the server\n"
" --volume=VOLUME Specify the initial (linear) volume in range 0...65536\n"
@@ -710,6 +724,7 @@ static void help(const char *argv0) {
enum {
ARG_VERSION = 256,
+ ARG_ROUTING,
ARG_STREAM_NAME,
ARG_VOLUME,
ARG_SAMPLERATE,
@@ -746,6 +761,7 @@ int main(int argc, char *argv[]) {
{"record", 0, NULL, 'r'},
{"playback", 0, NULL, 'p'},
{"device", 1, NULL, 'd'},
+ {"routing", 1, NULL, ARG_ROUTING},
{"server", 1, NULL, 's'},
{"client-name", 1, NULL, 'n'},
{"stream-name", 1, NULL, ARG_STREAM_NAME},
@@ -797,6 +813,7 @@ int main(int argc, char *argv[]) {
}
proplist = pa_proplist_new();
+ routing = pa_dynarray_new(pa_xfree);
while ((c = getopt_long(argc, argv, "rpd:s:n:hv", long_options, NULL)) != -1) {
@@ -829,6 +846,21 @@ int main(int argc, char *argv[]) {
device = pa_xstrdup(optarg);
break;
+ case ARG_ROUTING: {
+ char *node_name;
+ const char *split_state = NULL;
+
+ if (!*optarg) {
+ pa_log(_("Invalid value passed to --routing: empty string."));
+ goto quit;
+ }
+
+ while ((node_name = pa_split(optarg, ",", &split_state)))
+ pa_dynarray_append(routing, node_name);
+
+ break;
+ }
+
case 's':
pa_xfree(server);
server = pa_xstrdup(optarg);
@@ -1003,6 +1035,16 @@ int main(int argc, char *argv[]) {
goto quit;
}
+ if (device && pa_dynarray_size(routing) > 0) {
+ pa_log(_("--device and --routing are mutually exclusive options."));
+ goto quit;
+ }
+
+ if (monitor_stream != PA_INVALID_INDEX && pa_dynarray_size(routing) > 0) {
+ pa_log(_("--monitor-stream and --routing are mutually exclusive options."));
+ goto quit;
+ }
+
if (optind+1 == argc) {
int fd;
@@ -1226,6 +1268,10 @@ quit:
pa_xfree(buffer);
pa_xfree(server);
+
+ if (routing)
+ pa_dynarray_free(routing);
+
pa_xfree(device);
if (sndfile)
--
1.8.3.1
More information about the pulseaudio-discuss
mailing list