Re: [pulseaudio-discuss] Virtual source

2012-08-10 Thread Tanu Kaskinen
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

2012-08-10 Thread Tanu Kaskinen
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

2012-08-10 Thread Rémi Denis-Courmont
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

2012-08-10 Thread Geir Birkedal
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

2012-08-10 Thread Geir Birkedal
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

2012-08-10 Thread Damir Jelić
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

2012-08-10 Thread Damir Jelić
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

2012-08-10 Thread Damir Jelić
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.

2012-08-10 Thread Damir Jelić
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

2012-08-10 Thread Ansis Māliņš
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