Re: [pulseaudio-discuss] Virtual source
On Sat, 2012-08-11 at 09:15 +0300, Tanu Kaskinen wrote: > On Fri, 2012-08-10 at 15:09 +0200, Geir Birkedal wrote: > > On Fri, 2012-08-10 at 15:41 +0300, Ansis Māliņš wrote: > > > You can play to a module-null-device and pipe its monitor source to > > > other applications. > > > > Thanks, but as mentioned I'd rather not use a monitor source, since our > > client's application is set to ignore monitors. > > Using a null sink and its monitor is the only way that I know to do > application-to-application routing. Rémi's idea about alsa's loopback > driver might work too, though - I have zero experience with that. > > I think this workaround would work too: load module-virtual-source on > top of the monitor source of the null sink. module-virtual-source > doesn't do much itself (it just copies the data from the master sink), I meant "master source", not "master sink". -- Tanu ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Virtual source
On Fri, 2012-08-10 at 15:09 +0200, Geir Birkedal wrote: > On Fri, 2012-08-10 at 15:41 +0300, Ansis Māliņš wrote: > > You can play to a module-null-device and pipe its monitor source to > > other applications. > > Thanks, but as mentioned I'd rather not use a monitor source, since our > client's application is set to ignore monitors. Using a null sink and its monitor is the only way that I know to do application-to-application routing. Rémi's idea about alsa's loopback driver might work too, though - I have zero experience with that. I think this workaround would work too: load module-virtual-source on top of the monitor source of the null sink. module-virtual-source doesn't do much itself (it just copies the data from the master sink), but it shouldn't appear as a monitor source so your client can use it. -- Tanu ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Virtual source
On Fri, 10 Aug 2012 14:38:56 +0200, Geir Birkedal wrote: > I am writing a program that produces an audio signal and currently plays > it back using the simple API. This works fine. > > My problem is, instead of playing the audio out, I want to pipe it to a > virtual input device, and use it as input to other applications. Did you consider using the loopback ALSA driver? The device should be visible to PulseAudio, shouldn't it? -- Rémi Denis-Courmont Sent from my collocated server ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Virtual source
On Fri, 2012-08-10 at 15:41 +0300, Ansis Māliņš wrote: > You can play to a module-null-device and pipe its monitor source to > other applications. Thanks, but as mentioned I'd rather not use a monitor source, since our client's application is set to ignore monitors. ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] Virtual source
Hello, I am writing a program that produces an audio signal and currently plays it back using the simple API. This works fine. My problem is, instead of playing the audio out, I want to pipe it to a virtual input device, and use it as input to other applications. - Can I do this programmatically using the simple or perhaps the asynchronous API? - I've seen a module called module-virtual-source. Can it be used for this purpose? And if so, is there a way to use that in pulseaudio version 0.9.21? - Is there another way of accomplishing this with some clever use of pacmd or pactl? I know it's possible to play to a null sink and use its monitor, but I don't want to use a monitor for this. I apologize if this is not the right forum for this kind of question, and I'll happily take any advice to take my question elsewhere. Thank you! Geir Birkedal ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH 3/3] pacmd: Add a funtion to handle the maximum volume
From: "poljar (Damir Jelić)" pacmd was extended to handle maximum volumes for ports. The maximum volume is printed with the card info in the port section. --- src/pulsecore/cli-command.c | 52 + src/pulsecore/cli-text.c| 10 +++-- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/pulsecore/cli-command.c b/src/pulsecore/cli-command.c index 130185a..71a17c8 100644 --- a/src/pulsecore/cli-command.c +++ b/src/pulsecore/cli-command.c @@ -136,6 +136,7 @@ static int pa_cli_command_card_profile(pa_core *c, pa_tokenizer *t, pa_strbuf *b static int pa_cli_command_sink_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail); static int pa_cli_command_source_port(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail); static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail); +static int pa_cli_command_port_max_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail); static int pa_cli_command_dump_volumes(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail); /* A method table for all available commands */ @@ -170,6 +171,7 @@ static const struct command commands[] = { { "set-sink-port", pa_cli_command_sink_port, "Change the port of a sink (args: index|name, port-name)", 3}, { "set-source-port", pa_cli_command_source_port,"Change the port of a source (args: index|name, port-name)", 3}, { "set-port-latency-offset", pa_cli_command_port_offset,"Change the latency of a port (args: card-index|card-name, port-name, latency-offset)", 4}, +{ "set-port-max-volume", pa_cli_command_port_max_volume,"Change the maximum volume of a port (args: card-index|card-name, port-name, max-volume)", 4}, { "suspend-sink",pa_cli_command_suspend_sink, "Suspend sink (args: index|name, bool)", 3}, { "suspend-source", pa_cli_command_suspend_source, "Suspend source (args: index|name, bool)", 3}, { "suspend", pa_cli_command_suspend,"Suspend all sinks and all sources (args: bool)", 2}, @@ -1771,6 +1773,56 @@ static int pa_cli_command_port_offset(pa_core *c, pa_tokenizer *t, pa_strbuf *bu return 0; } +static int pa_cli_command_port_max_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) { +const char *n, *v, *p; +pa_device_port *port; +pa_card *card; +pa_volume_t volume; + +pa_core_assert_ref(c); +pa_assert(t); +pa_assert(buf); +pa_assert(fail); + +if (!(n = pa_tokenizer_get(t, 1))) { +pa_strbuf_puts(buf, "You need to specify a card either by its name or its index.\n"); +return -1; +} + +if (!(p = pa_tokenizer_get(t, 2))) { +pa_strbuf_puts(buf, "You need to specify a port by its name.\n"); +return -1; +} + +if (!(v = pa_tokenizer_get(t, 3))) { +pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is no maximum, 0x1 is normal volume)\n"); +return -1; +} + +if (pa_atou(v, &volume) < 0) { +pa_strbuf_puts(buf, "Failed to parse volume.\n"); +return -1; +} + +if (!PA_VOLUME_IS_VALID(volume)) { +pa_strbuf_puts(buf, "Volume outside permissible range.\n"); +return -1; +} + +if (!(card = pa_namereg_get(c, n, PA_NAMEREG_CARD))) { +pa_strbuf_puts(buf, "No card found by this name or index.\n"); +return -1; +} + +if (!(port = pa_hashmap_get(card->ports, p))) { +pa_strbuf_puts(buf, "No port found by this name.\n"); +return -1; +} + +pa_device_port_set_max_volume(port, volume); +return 0; +} + static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, pa_bool_t *fail) { pa_module *m; pa_sink *sink; diff --git a/src/pulsecore/cli-text.c b/src/pulsecore/cli-text.c index 0df17e5..c0f1571 100644 --- a/src/pulsecore/cli-text.c +++ b/src/pulsecore/cli-text.c @@ -127,9 +127,15 @@ static void append_port_list(pa_strbuf *s, pa_hashmap *ports) pa_strbuf_puts(s, "\tports:\n"); PA_HASHMAP_FOREACH(p, ports, state) { +char v[PA_VOLUME_SNPRINT_MAX]; char *t = pa_proplist_to_string_sep(p->proplist, "\n\t\t\t\t"); -pa_strbuf_printf(s, "\t\t%s: %s (priority %u, latency offset %" PRId64 " usec, available: %s)\n", -p->name, p->description, p->priority, p->latency_offset, + +pa_volume_snprint(v, sizeof(v), p->max_volume); +if (pa_streq(v, "(invalid)")) +pa_strlcpy(v, "off", 4); + +pa_strbuf_printf(s, "\t\t%s: %s (priority %u, latency offset %" PRId64 " usec, max volume %s available: %s)\n", +p->name, p->description, p->priority, p->latency_offset, v, port_available_to_string(p->available)); pa_strbuf_printf(s, "\t\t\tproperties:\n\t\t\t\t%s\n", t); pa_xfree(t); -- 1.7.11.4
[pulseaudio-discuss] [PATCH 2/3] sink: Add a maximum volume which is inherited from the port
From: "poljar (Damir Jelić)" A maximum volume variable was added to the sink struct. Also a function was added to update the maximum volume and enforce it if it's needed. The maximum volume is automatically populated with the volume from the currently active port. --- src/pulsecore/device-port.c | 13 + src/pulsecore/sink.c| 24 ++-- src/pulsecore/sink.h| 4 +++- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c index c467a09..efe1d56 100644 --- a/src/pulsecore/device-port.c +++ b/src/pulsecore/device-port.c @@ -150,10 +150,23 @@ void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) { } void pa_device_port_set_max_volume(pa_device_port *p, pa_volume_t max) { +uint32_t state; +pa_core *core; + pa_assert(p); if (max == PA_VOLUME_MUTED) p->max_volume = PA_VOLUME_INVALID; else p->max_volume = max; + +if (p->is_output) { +pa_sink *sink; + +PA_IDXSET_FOREACH(sink, p->core->sinks, state) +if (sink->active_port == p) { +pa_sink_set_max_volume(sink, p->max_volume); +break; +} +} } diff --git a/src/pulsecore/sink.c b/src/pulsecore/sink.c index 3d72f55..e474821 100644 --- a/src/pulsecore/sink.c +++ b/src/pulsecore/sink.c @@ -309,10 +309,14 @@ pa_sink* pa_sink_new( s->active_port = p; } -if (s->active_port) +if (s->active_port) { s->latency_offset = s->active_port->latency_offset; -else +s->max_volume = s->active_port->max_volume; + +} else { s->latency_offset = 0; +s->max_volume = PA_VOLUME_INVALID; +} s->save_volume = data->save_volume; s->save_muted = data->save_muted; @@ -1967,6 +1971,13 @@ void pa_sink_set_volume( pa_cvolume_scale(&new_reference_volume, pa_cvolume_max(volume)); } +/* If we have a max_volume set enforce it if needed */ + +if (PA_VOLUME_IS_VALID(s->max_volume)) +for (unsigned i = 0; i < new_reference_volume.channels; i++) +if (new_reference_volume.values[i] > s->max_volume) +new_reference_volume.values[i] = s->max_volume; + pa_cvolume_remap(&new_reference_volume, &s->channel_map, &root_sink->channel_map); if (update_reference_volume(root_sink, &new_reference_volume, &root_sink->channel_map, save)) { @@ -3261,6 +3272,15 @@ void pa_sink_set_latency_offset(pa_sink *s, int64_t offset) { } /* Called from main context */ +void pa_sink_set_max_volume(pa_sink *s, pa_volume_t max) { +pa_sink_assert_ref(s); + +s->max_volume = max; + +pa_sink_set_volume(s, &s->reference_volume, TRUE, s->save_volume); +} + +/* Called from main context */ size_t pa_sink_get_max_rewind(pa_sink *s) { size_t r; pa_assert_ctl_context(); diff --git a/src/pulsecore/sink.h b/src/pulsecore/sink.h index 2c52348..6efeb46 100644 --- a/src/pulsecore/sink.h +++ b/src/pulsecore/sink.h @@ -113,8 +113,9 @@ struct pa_sink { pa_device_port *active_port; pa_atomic_t mixer_dirty; -/* The latency offset is inherited from the currently active port */ +/* The latency offset and the maximum volume are inherited from the currently active port */ int64_t latency_offset; +pa_volume_t max_volume; unsigned priority; @@ -411,6 +412,7 @@ unsigned pa_device_init_priority(pa_proplist *p); pa_bool_t pa_sink_update_rate(pa_sink *s, uint32_t rate, pa_bool_t passthrough); void pa_sink_set_latency_offset(pa_sink *s, int64_t offset); +void pa_sink_set_max_volume(pa_sink *s, pa_volume_t max); /* The returned value is supposed to be in the time domain of the sound card! */ pa_usec_t pa_sink_get_latency(pa_sink *s); -- 1.7.11.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH 1/3] device-port: Add a maximum volume variable to the port struct
From: "poljar (Damir Jelić)" A maximum volume variable was added to the port struct and a function to set the maximum volume. The maximum volume does nothing for now, it will be later added to the sink/source to enforce a maximum volume if the port is currently active. --- src/pulsecore/device-port.c | 10 ++ src/pulsecore/device-port.h | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/pulsecore/device-port.c b/src/pulsecore/device-port.c index 9ea54e3..c467a09 100644 --- a/src/pulsecore/device-port.c +++ b/src/pulsecore/device-port.c @@ -98,6 +98,7 @@ pa_device_port *pa_device_port_new(pa_core *c, const char *name, const char *des p->is_input = FALSE; p->is_output = FALSE; p->latency_offset = 0; +p->max_volume = PA_VOLUME_INVALID; p->proplist = pa_proplist_new(); return p; @@ -147,3 +148,12 @@ void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset) { if (p == pa_hashmap_get(card->ports, p->name)) pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CARD|PA_SUBSCRIPTION_EVENT_CHANGE, card->index); } + +void pa_device_port_set_max_volume(pa_device_port *p, pa_volume_t max) { +pa_assert(p); + +if (max == PA_VOLUME_MUTED) +p->max_volume = PA_VOLUME_INVALID; +else +p->max_volume = max; +} diff --git a/src/pulsecore/device-port.h b/src/pulsecore/device-port.h index a5c6420..b3ae261 100644 --- a/src/pulsecore/device-port.h +++ b/src/pulsecore/device-port.h @@ -52,6 +52,7 @@ struct pa_device_port { pa_bool_t is_input:1; pa_bool_t is_output:1; int64_t latency_offset; +pa_volume_t max_volume; /* .. followed by some implementation specific data */ }; @@ -70,4 +71,6 @@ void pa_device_port_set_available(pa_device_port *p, pa_port_available_t availab void pa_device_port_set_latency_offset(pa_device_port *p, int64_t offset); +void pa_device_port_set_max_volume(pa_device_port *p, pa_volume_t max); + #endif -- 1.7.11.4 ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
[pulseaudio-discuss] [PATCH 0/3] Add maximum volume enforcing.
This patch set adds maximum volume enforcing. A maximum volume was added to the ports. The max volume is then copied to the sink and is enforced if needed. Only pacmd can currently set the max volume. ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss
Re: [pulseaudio-discuss] Virtual source
You can play to a module-null-device and pipe its monitor source to other applications. ___ pulseaudio-discuss mailing list pulseaudio-discuss@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/pulseaudio-discuss