Re: [Musicpd-dev-team] State of the pulse mixer

2009-03-31 Thread David Guibert
Hi,

From Max Kellermann:
 there have been lots of problems with the pulse mixer code since it
 was merged, and a good bunch of bug reports are still open.  Please
 tell me what is being done to fix the remaining bugs, and when I will
 receive patches.

Yes, Avuton has reported a lot of isssues. Unfortunately the steps are
missing to reproduce here.

I'm trying to clone the code from the xmms-pulse plugin [1] to fix the code.

1. In the open, this should better work with the mainloop lock/unlock
   issues.
   
   One question about this:
What is the current state of a mixer when the output is not
available?
As an example, the pulse output associated with
a not connected bluetooth headset can't obtained a valid mixer.
what should 'mpc volume' returns?
The answer can close the issue 0002214.

2. The pulse community has pointed that we should lock the mainloop when
   getting the volume.
   The patch is done waiting Point 1.
 
3. The same lock/unlock stuff has to been done when we set the volume.

 These bugs must be fixed before the 0.15 release, or we will have to
 remove it.

When do you plan the next release? In the next few days, I expect to send
patches.

[1] git://git.0pointer.de/xmms-pulse.git
-- 
David

--
___
Musicpd-dev-team mailing list
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team


[Musicpd-dev-team] [PATCH] pulse_mixer: close

2009-03-16 Thread David Guibert
when the mixer is closed,
- the mainloop is stopped.
- the context is disconnected.
- then the mainloop is freed.

Signed-off-by: David Guibert david.guib...@gmail.com

---
 src/mixer/pulse_mixer.c |   15 ++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/src/mixer/pulse_mixer.c b/src/mixer/pulse_mixer.c
index 481fec2..a300a29 100644
--- a/src/mixer/pulse_mixer.c
+++ b/src/mixer/pulse_mixer.c
@@ -237,7 +237,20 @@ pulse_mixer_open(G_GNUC_UNUSED struct mixer *data)
 static void
 pulse_mixer_close(G_GNUC_UNUSED struct mixer *data)
 {
-   return;
+   struct pulse_mixer *pm=(struct pulse_mixer *) data;
+   if (pm-mainloop)
+   pa_threaded_mainloop_stop(pm-mainloop);
+
+   if (pm-context) {
+   pa_context_disconnect(pm-context);
+   pa_context_unref(pm-context);
+   pm-context = NULL;
+   }
+
+   if (pm-mainloop) {
+   pa_threaded_mainloop_free(pm-mainloop);
+   pm-mainloop = NULL;
+   }
 }
 
 static int
-- 
tg: (b4de244..) t/pulse_mixer_close (depends on: t/offline-only-removed-sink)

--
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM)based development
software that enables intelligent coding and step-through debugging.
Download the free 60 day trial. http://p.sf.net/sfu/www-adobe-com
___
Musicpd-dev-team mailing list
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team


[Musicpd-dev-team] [PATCH] pulse_mixer: clarify debug messages.

2009-03-16 Thread David Guibert
Signed-off-by: David Guibert david.guib...@gmail.com
---
Avuton,

I hope this help to find which part clearly fails.
It should give me more information about bugs
- 2136
- 2138
- 2139

Regards

 src/mixer/pulse_mixer.c |   45 ++---
 1 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/src/mixer/pulse_mixer.c b/src/mixer/pulse_mixer.c
index a300a29..7f2651a 100644
--- a/src/mixer/pulse_mixer.c
+++ b/src/mixer/pulse_mixer.c
@@ -48,22 +48,19 @@ sink_input_cb(G_GNUC_UNUSED pa_context *context, const 
pa_sink_input_info *i,
 {
 
struct pulse_mixer *pm = userdata;
-   if (eol) {
-   g_debug(eol error sink_input_cb);
+   if (eol)
return;
-   }
 
if (!i) {
g_debug(Sink input callback failure);
return;
}
-   g_debug(sink input cb %s, index %d ,i-name,i-index);
-   if(strcmp(i-name,pm-output_name)==0) {
-   pm-index=i-index;
-   pm-online=true;
-   *pm-volume=i-volume;
-   } else
-   g_debug(bad name);
+   if(strcmp(i-name,pm-output_name) == 0) {
+   g_debug(Sink input cb %s, index %d,i-name,i-index);
+   pm-index   = i-index;
+   pm-online  = true;
+   *pm-volume = i-volume;
+   }
 }
 
 static void
@@ -72,21 +69,19 @@ sink_input_vol(G_GNUC_UNUSED pa_context *context, const 
pa_sink_input_info *i,
 {
 
struct pulse_mixer *pm = userdata;
-   if (eol) {
-   g_debug(eol error sink_input_vol);
+   if (eol)
return;
-   }
 
if (!i) {
-   g_debug(Sink input callback failure);
+   g_debug(Sink input volume failure);
return;
}
-   g_debug(sink input vol %s, index %d , i-name, i-index);
-   *pm-volume=i-volume;
+   g_debug(Sink input vol %s, index %d, i-name, i-index);
+   *pm-volume = i-volume;
 }
 
 static void
-subscribe_cb(G_GNUC_UNUSED pa_context *c, pa_subscription_event_type_t t,
+subscribe_cb(pa_context *context, pa_subscription_event_type_t t,
 uint32_t idx, void *userdata)
 {
 
@@ -101,7 +96,7 @@ subscribe_cb(G_GNUC_UNUSED pa_context *c, 
pa_subscription_event_type_t t,
else {
pa_operation *o;
 
-   if (!(o = pa_context_get_sink_input_info(pm-context, 
idx, sink_input_cb, pm))) {
+   if (!(o = pa_context_get_sink_input_info(context, idx, 
sink_input_cb, pm))) {
g_debug(pa_context_get_sink_input_info() 
failed);
return;
}
@@ -202,8 +197,9 @@ pulse_mixer_open(G_GNUC_UNUSED struct mixer *data)
return false;
}
 
+   pa_threaded_mainloop_lock(pm-mainloop);
if(!(pm-context = 
pa_context_new(pa_threaded_mainloop_get_api(pm-mainloop),
- Mixer mpd))) {
+ Mixer MPD))) {
g_debug(failed context);
return false;
}
@@ -212,20 +208,21 @@ pulse_mixer_open(G_GNUC_UNUSED struct mixer *data)
 
if (pa_context_connect(pm-context, pm-server,
   (pa_context_flags_t)0, NULL)  0) {
-   g_debug(context server fail);
+   g_warning(Failed to connect to server: %s, 
pa_strerror(pa_context_errno(pm-context)));
return false;
}
 
-   pa_threaded_mainloop_lock(pm-mainloop);
if (pa_threaded_mainloop_start(pm-mainloop)  0) {
-   g_debug(error start mainloop);
+   g_warning(Failed to start main loop);
return false;
}
 
+   /* Wait until the context is ready */
pa_threaded_mainloop_wait(pm-mainloop);
 
if (pa_context_get_state(pm-context) != PA_CONTEXT_READY) {
-   g_debug(error context not ready);
+   g_warning(Failed to connect to server: %s, 
pa_strerror(pa_context_errno(pm-context)));
+   pa_threaded_mainloop_unlock(pm-mainloop);
return false;
}
 
@@ -283,6 +280,8 @@ pulse_mixer_set_volume(struct mixer *mixer, unsigned volume)
 {
struct pulse_mixer *pm=(struct pulse_mixer *) mixer;
pa_operation *o;
+   g_debug(set_volume %s %d,
+   pm-online == TRUE ? online : offline, volume);
if (pm-online) {
pa_cvolume_set(pm-volume, (pm-volume)-channels,
(pa_volume_t)(volume)*PA_VOLUME_NORM/100+0.5);
-- 
tg: (8137a4f..) t/debug-messages (depends on: t/pulse_mixer_close)

--
Apps built with the Adobe(R) Flex(R) framework and Flex Builder(TM) are
powering Web 2.0 with engaging, cross-platform capabilities. Quickly and
easily build your RIAs with Flex Builder, the Eclipse(TM

[Musicpd-dev-team] [PATCH] pulse mixer

2009-03-06 Thread David Guibert
This patch introduces the mixer for the pulse output.

Technically speaking, the pulse index is needed to get or set
the volume. You must define callback fonctions to get this index since
the pulse output in mpd is done using the simpe api. The pulse simple api
does not provide the index of the newly defined output.

So callback fonctions are associated to the pulse context.
The list of all the sink input is then retreived.
Then we select the name of the mpd pulse output and control
its volume by its associated index number.

Signed-off-by: Patrice Linel patnathan...@gmail.com
Signed-off-by: David Guibert david.guib...@gmail.com

---
 Makefile.am   |1 +
 src/main.c|3 +-
 src/mixer/pulse_mixer.c   |  284 +
 src/mixer_api.h   |1 +
 src/output/pulse_plugin.c |   16 +++
 5 files changed, 303 insertions(+), 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 25478f8..2511680 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -489,6 +489,7 @@ endif
 
 if HAVE_PULSE
 OUTPUT_SRC += src/output/pulse_plugin.c
+MIXER_SRC  += src/mixer/pulse_mixer.c
 endif
 
 if HAVE_SHOUT
diff --git a/src/main.c b/src/main.c
index a3f613d..2889933 100644
--- a/src/main.c
+++ b/src/main.c
@@ -259,6 +259,7 @@ int main(int argc, char *argv[])
 
command_init();
initialize_decoder_and_player();
+   daemonize(options.daemon);
volume_init();
initAudioConfig();
audio_output_all_init();
@@ -267,8 +268,6 @@ int main(int argc, char *argv[])
initNormalization();
input_stream_global_init();
 
-   daemonize(options.daemon);
-
setup_log_output(options.stdOutput);
 
initSigHandlers();
diff --git a/src/mixer/pulse_mixer.c b/src/mixer/pulse_mixer.c
new file mode 100644
index 000..78b77c0
--- /dev/null
+++ b/src/mixer/pulse_mixer.c
@@ -0,0 +1,284 @@
+#include ../output_api.h
+#include ../mixer_api.h
+
+#include glib.h
+#include pulse/volume.h
+#include pulse/pulseaudio.h
+
+struct pulse_mixer {
+   struct mixer base;
+   char *server;
+   char *sink;
+   char *output_name;
+   uint32_t index;
+   boolonline;
+   struct pa_context *context;
+   struct pa_threaded_mainloop *mainloop;
+   struct pa_cvolume *volume;
+
+};
+
+
+
+static void sink_input_cb(G_GNUC_UNUSED pa_context *context, const 
pa_sink_input_info *i, int eol, void *userdata)
+{
+
+   struct pulse_mixer *pm = userdata;
+   if (eol) {
+   g_debug(eol error sink_input_cb\n);
+   return;
+   }
+
+   if (!i) {
+   g_debug(Sink input callback failure\n);
+   return;
+   }
+   g_debug(sink input cb %s, index %d \n,i-name,i-index);
+   if(strcmp(i-name,pm-output_name)==0)
+   { 
+   pm-index=i-index;
+   pm-online=true;
+   *pm-volume=i-volume;
+   }
+   else g_debug(bad name\n);
+}
+
+static void sink_input_vol(G_GNUC_UNUSED pa_context *context, const 
pa_sink_input_info *i, int eol, void *userdata) 
+{
+
+   struct pulse_mixer *pm = userdata;
+   if (eol) {
+   g_debug(eol error sink_input_vol\n);
+   return;
+   }
+
+   if (!i) {
+   g_debug(Sink input callback failure\n);
+   return;
+   }
+   g_debug(sink input vol %s, index %d \n,i-name,i-index);
+   *pm-volume=i-volume;
+}
+
+static void 
+subscribe_cb(G_GNUC_UNUSED pa_context *c, pa_subscription_event_type_t t, 
uint32_t idx, void *userdata) 
+{
+
+   struct pulse_mixer *pm = userdata;
+   g_debug(pulse_mixer: subscribe call back\n);
+   switch (t  PA_SUBSCRIPTION_EVENT_FACILITY_MASK) 
+   {
+
+   case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
+   if ((t  PA_SUBSCRIPTION_EVENT_TYPE_MASK) == 
+   PA_SUBSCRIPTION_EVENT_REMOVE)
+   pm-online =false;
+   else 
+   {
+   pa_operation *o;
+
+   if (!(o = 
pa_context_get_sink_input_info(pm-context, idx, sink_input_cb, pm))) 
+   {
+   g_debug(pulse_mixer: 
pa_context_get_sink_input_info() failed\n);
+   return;
+   }
+   pa_operation_unref(o);
+   }
+   break;
+   }
+}
+
+static void
+context_state_cb(pa_context *context, void *userdata) 
+{
+   struct pulse_mixer *pm = userdata;
+   switch (pa_context_get_state(context)) 
+   {
+   case PA_CONTEXT_READY: 
+   {
+   pa_operation *o;
+
+   pa_context_set_subscribe_callback(context, 
subscribe_cb, pm);
+
+   if (!(o = pa_context_subscribe(context

[Musicpd-dev-team] [PATCH] pulse mixer

2009-03-06 Thread David Guibert
Sorry. I forgot to do the make after minor changes...

I resend the patch wich compiles cleanly.

--
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
___
Musicpd-dev-team mailing list
Musicpd-dev-team@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/musicpd-dev-team


[Musicpd-dev-team] [PATCH] pulse mixer

2009-03-06 Thread David Guibert
This patch introduces the mixer for the pulse output.

Technically speaking, the pulse index is needed to get or set
the volume. You must define callback fonctions to get this index since
the pulse output in mpd is done using the simpe api. The pulse simple api
does not provide the index of the newly defined output.

So callback fonctions are associated to the pulse context.
The list of all the sink input is then retreived.
Then we select the name of the mpd pulse output and control
its volume by its associated index number.

Signed-off-by: Patrice Linel patnathan...@gmail.com
Signed-off-by: David Guibert david.guib...@gmail.com

---
 Makefile.am   |1 +
 src/main.c|3 +-
 src/mixer/pulse_mixer.c   |  284 +
 src/mixer_api.h   |1 +
 src/output/pulse_plugin.c |   16 +++
 5 files changed, 303 insertions(+), 2 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 25478f8..2511680 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -489,6 +489,7 @@ endif
 
 if HAVE_PULSE
 OUTPUT_SRC += src/output/pulse_plugin.c
+MIXER_SRC  += src/mixer/pulse_mixer.c
 endif
 
 if HAVE_SHOUT
diff --git a/src/main.c b/src/main.c
index a3f613d..2889933 100644
--- a/src/main.c
+++ b/src/main.c
@@ -259,6 +259,7 @@ int main(int argc, char *argv[])
 
command_init();
initialize_decoder_and_player();
+   daemonize(options.daemon);
volume_init();
initAudioConfig();
audio_output_all_init();
@@ -267,8 +268,6 @@ int main(int argc, char *argv[])
initNormalization();
input_stream_global_init();
 
-   daemonize(options.daemon);
-
setup_log_output(options.stdOutput);
 
initSigHandlers();
diff --git a/src/mixer/pulse_mixer.c b/src/mixer/pulse_mixer.c
new file mode 100644
index 000..e12a844
--- /dev/null
+++ b/src/mixer/pulse_mixer.c
@@ -0,0 +1,284 @@
+#include ../output_api.h
+#include ../mixer_api.h
+
+#include glib.h
+#include pulse/volume.h
+#include pulse/pulseaudio.h
+
+struct pulse_mixer {
+   struct mixer base;
+   char *server;
+   char *sink;
+   char *output_name;
+   uint32_t index;
+   boolonline;
+   struct pa_context *context;
+   struct pa_threaded_mainloop *mainloop;
+   struct pa_cvolume *volume;
+
+};
+
+
+
+static void sink_input_cb(G_GNUC_UNUSED pa_context *context, const 
pa_sink_input_info *i, int eol, void *userdata)
+{
+
+   struct pulse_mixer *pm = userdata;
+   if (eol) {
+   g_debug(eol error sink_input_cb\n);
+   return;
+   }
+
+   if (!i) {
+   g_debug(Sink input callback failure\n);
+   return;
+   }
+   g_debug(sink input cb %s, index %d \n,i-name,i-index);
+   if(strcmp(i-name,pm-output_name)==0)
+   { 
+   pm-index=i-index;
+   pm-online=true;
+   *pm-volume=i-volume;
+   }
+   else g_debug(bad name\n);
+}
+
+static void sink_input_vol(G_GNUC_UNUSED pa_context *context, const 
pa_sink_input_info *i, int eol, void *userdata) 
+{
+
+   struct pulse_mixer *pm = userdata;
+   if (eol) {
+   g_debug(eol error sink_input_vol\n);
+   return;
+   }
+
+   if (!i) {
+   g_debug(Sink input callback failure\n);
+   return;
+   }
+   g_debug(sink input vol %s, index %d \n,i-name,i-index);
+   *pm-volume=i-volume;
+}
+
+static void 
+subscribe_cb(G_GNUC_UNUSED pa_context *c, pa_subscription_event_type_t t, 
uint32_t idx, void *userdata) 
+{
+
+   struct pulse_mixer *pm = userdata;
+   g_debug(pulse_mixer: subscribe call back\n);
+   switch (t  PA_SUBSCRIPTION_EVENT_FACILITY_MASK) 
+   {
+
+   case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
+   if ((t  PA_SUBSCRIPTION_EVENT_TYPE_MASK) == 
+   PA_SUBSCRIPTION_EVENT_REMOVE)
+   pm-online =false;
+   else 
+   {
+   pa_operation *o;
+
+   if (!(o = 
pa_context_get_sink_input_info(pm-context, idx, sink_input_cb, pm))) 
+   {
+   g_debug(pulse_mixer: 
pa_context_get_sink_input_info() failed\n);
+   return;
+   }
+   pa_operation_unref(o);
+   }
+   break;
+   }
+}
+
+static void
+context_state_cb(pa_context *context, void *userdata) 
+{
+   struct pulse_mixer *pm = userdata;
+   switch (pa_context_get_state(context)) 
+   {
+   case PA_CONTEXT_READY: 
+   {
+   pa_operation *o;
+
+   pa_context_set_subscribe_callback(context, 
subscribe_cb, pm);
+
+   if (!(o = pa_context_subscribe(context