[polypaudio-commits] r607 - in /trunk/src/modules: alsa-util.c alsa-util.h module-alsa-sink.c module-alsa-source.c

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Sun Feb 26 13:50:56 PST 2006


Author: ossman
Date: Sun Feb 26 22:50:55 2006
New Revision: 607

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=607&root=polypaudio&view=rev
Log:
Get notifications about mixer changes from ALSA.

Modified:
    trunk/src/modules/alsa-util.c
    trunk/src/modules/alsa-util.h
    trunk/src/modules/module-alsa-sink.c
    trunk/src/modules/module-alsa-source.c

Modified: trunk/src/modules/alsa-util.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/alsa-util.c?rev=607&root=polypaudio&r1=606&r2=607&view=diff
==============================================================================
--- trunk/src/modules/alsa-util.c (original)
+++ trunk/src/modules/alsa-util.c Sun Feb 26 22:50:55 2006
@@ -39,6 +39,7 @@
     struct pollfd *work_fds;
 
     snd_pcm_t *pcm;
+    snd_mixer_t *mixer;
 
     pa_mainloop_api *m;
     pa_defer_event *defer;
@@ -55,7 +56,7 @@
     int err, i;
     unsigned short revents;
 
-    assert(a && fdl && fdl->pcm);
+    assert(a && fdl && (fdl->pcm || fdl->mixer) && fdl->fds && fdl->work_fds);
 
     if (fdl->polled)
         return;
@@ -80,7 +81,11 @@
 
     assert(i != fdl->num_fds);
 
-    err = snd_pcm_poll_descriptors_revents(fdl->pcm, fdl->work_fds, fdl->num_fds, &revents);
+    if (fdl->pcm)
+        err = snd_pcm_poll_descriptors_revents(fdl->pcm, fdl->work_fds, fdl->num_fds, &revents);
+    else
+        err = snd_mixer_poll_descriptors_revents(fdl->mixer, fdl->work_fds, fdl->num_fds, &revents);
+
     if (err < 0) {
         pa_log_error(__FILE__": Unable to get poll revent: %s",
             snd_strerror(err));
@@ -88,8 +93,12 @@
         return;
     }
 
-    if (revents)
-        fdl->cb(fdl->userdata);
+    if (revents) {
+        if (fdl->pcm)
+            fdl->cb(fdl->userdata);
+        else
+            snd_mixer_handle_events(fdl->mixer);
+    }
 }
 
 static void defer_cb(pa_mainloop_api*a, pa_defer_event* e, void *userdata) {
@@ -97,9 +106,12 @@
     int num_fds, i, err;
     struct pollfd *temp;
 
-    assert(a && fdl && fdl->pcm);
-
-    num_fds = snd_pcm_poll_descriptors_count(fdl->pcm);
+    assert(a && fdl && (fdl->pcm || fdl->mixer));
+
+    if (fdl->pcm)
+        num_fds = snd_pcm_poll_descriptors_count(fdl->pcm);
+    else
+        num_fds = snd_mixer_poll_descriptors_count(fdl->mixer);
     assert(num_fds > 0);
 
     if (num_fds != fdl->num_fds) {
@@ -112,7 +124,12 @@
     }
 
     memset(fdl->work_fds, 0, sizeof(struct pollfd) * num_fds);
-    err = snd_pcm_poll_descriptors(fdl->pcm, fdl->work_fds, num_fds);
+
+    if (fdl->pcm)
+        err = snd_pcm_poll_descriptors(fdl->pcm, fdl->work_fds, num_fds);
+    else
+        err = snd_mixer_poll_descriptors(fdl->mixer, fdl->work_fds, num_fds);
+
     if (err < 0) {
         pa_log_error(__FILE__": Unable to get poll descriptors: %s",
             snd_strerror(err));
@@ -165,6 +182,7 @@
     fdl->work_fds = NULL;
 
     fdl->pcm = NULL;
+    fdl->mixer = NULL;
 
     fdl->m = NULL;
     fdl->defer = NULL;
@@ -210,6 +228,18 @@
 
     fdl->cb = cb;
     fdl->userdata = userdata;
+
+    return 0;
+}
+
+int pa_alsa_fdlist_init_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m) {
+    assert(fdl && mixer_handle && m && !fdl->m);
+
+    fdl->mixer = mixer_handle;
+    fdl->m = m;
+
+    fdl->defer = m->defer_new(m, defer_cb, fdl);
+    assert(fdl->defer);
 
     return 0;
 }

Modified: trunk/src/modules/alsa-util.h
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/alsa-util.h?rev=607&root=polypaudio&r1=606&r2=607&view=diff
==============================================================================
--- trunk/src/modules/alsa-util.h (original)
+++ trunk/src/modules/alsa-util.h Sun Feb 26 22:50:55 2006
@@ -33,6 +33,7 @@
 void pa_alsa_fdlist_free(struct pa_alsa_fdlist *fdl);
 
 int pa_alsa_fdlist_init_pcm(struct pa_alsa_fdlist *fdl, snd_pcm_t *pcm_handle, pa_mainloop_api* m, void (*cb)(void *userdata), void *userdata);
+int pa_alsa_fdlist_init_mixer(struct pa_alsa_fdlist *fdl, snd_mixer_t *mixer_handle, pa_mainloop_api* m);
 
 int pa_alsa_set_hw_params(snd_pcm_t *pcm_handle, const pa_sample_spec *ss, uint32_t *periods, snd_pcm_uframes_t *period_size);
 

Modified: trunk/src/modules/module-alsa-sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-alsa-sink.c?rev=607&root=polypaudio&r1=606&r2=607&view=diff
==============================================================================
--- trunk/src/modules/module-alsa-sink.c (original)
+++ trunk/src/modules/module-alsa-sink.c Sun Feb 26 22:50:55 2006
@@ -57,7 +57,8 @@
     snd_mixer_t *mixer_handle;
     snd_mixer_elem_t *mixer_elem;
     pa_sink *sink;
-    struct pa_alsa_fdlist *fdl;
+    struct pa_alsa_fdlist *pcm_fdl;
+    struct pa_alsa_fdlist *mixer_fdl;
     long hw_volume_max, hw_volume_min;
 
     size_t frame_size, fragment_size;
@@ -153,6 +154,24 @@
     do_write(u);
 }
 
+static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
+    struct userdata *u = snd_mixer_elem_get_callback_private(elem);
+
+    assert(u && u->mixer_handle);
+
+    if (mask & SND_CTL_EVENT_MASK_VALUE) {
+        if (u->sink->get_hw_volume)
+            u->sink->get_hw_volume(u->sink);
+        if (u->sink->get_hw_mute)
+            u->sink->get_hw_mute(u->sink);
+        pa_subscription_post(u->sink->core,
+            PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE,
+            u->sink->index);
+    }
+
+    return 0;
+}
+
 static pa_usec_t sink_get_latency_cb(pa_sink *s) {
     pa_usec_t r = 0;
     struct userdata *u = s->userdata;
@@ -358,11 +377,22 @@
     pa_sink_set_owner(u->sink, m);
     u->sink->description = pa_sprintf_malloc("Advanced Linux Sound Architecture PCM on '%s'", dev);
 
-    u->fdl = pa_alsa_fdlist_new();
-    assert(u->fdl);
-    if (pa_alsa_fdlist_init_pcm(u->fdl, u->pcm_handle, c->mainloop, fdl_callback, u) < 0) {
+    u->pcm_fdl = pa_alsa_fdlist_new();
+    assert(u->pcm_fdl);
+    if (pa_alsa_fdlist_init_pcm(u->pcm_fdl, u->pcm_handle, c->mainloop, fdl_callback, u) < 0) {
         pa_log(__FILE__": failed to initialise file descriptor monitoring");
         goto fail;
+    }
+
+    if (u->mixer_handle) {
+        u->mixer_fdl = pa_alsa_fdlist_new();
+        assert(u->mixer_fdl);
+        if (pa_alsa_fdlist_init_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) {
+            pa_log(__FILE__": failed to initialise file descriptor monitoring");
+            goto fail;
+        }
+        snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback);
+        snd_mixer_elem_set_callback_private(u->mixer_elem, u);
     }
     
     u->frame_size = frame_size;
@@ -412,8 +442,10 @@
         pa_sink_unref(u->sink);
     }
     
-    if (u->fdl)
-        pa_alsa_fdlist_free(u->fdl);
+    if (u->pcm_fdl)
+        pa_alsa_fdlist_free(u->pcm_fdl);
+    if (u->mixer_fdl)
+        pa_alsa_fdlist_free(u->mixer_fdl);
     
     if (u->mixer_handle)
         snd_mixer_close(u->mixer_handle);

Modified: trunk/src/modules/module-alsa-source.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/trunk/src/modules/module-alsa-source.c?rev=607&root=polypaudio&r1=606&r2=607&view=diff
==============================================================================
--- trunk/src/modules/module-alsa-source.c (original)
+++ trunk/src/modules/module-alsa-source.c Sun Feb 26 22:50:55 2006
@@ -57,7 +57,8 @@
     snd_mixer_t *mixer_handle;
     snd_mixer_elem_t *mixer_elem;
     pa_source *source;
-    struct pa_alsa_fdlist *fdl;
+    struct pa_alsa_fdlist *pcm_fdl;
+    struct pa_alsa_fdlist *mixer_fdl;
     long hw_volume_max, hw_volume_min;
 
     size_t frame_size, fragment_size;
@@ -153,6 +154,24 @@
     do_read(u);
 }
 
+static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
+    struct userdata *u = snd_mixer_elem_get_callback_private(elem);
+
+    assert(u && u->mixer_handle);
+
+    if (mask & SND_CTL_EVENT_MASK_VALUE) {
+        if (u->source->get_hw_volume)
+            u->source->get_hw_volume(u->source);
+        if (u->source->get_hw_mute)
+            u->source->get_hw_mute(u->source);
+        pa_subscription_post(u->source->core,
+            PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE,
+            u->source->index);
+    }
+
+    return 0;
+}
+
 static pa_usec_t source_get_latency_cb(pa_source *s) {
     struct userdata *u = s->userdata;
     snd_pcm_sframes_t frames;
@@ -349,11 +368,22 @@
     pa_source_set_owner(u->source, m);
     u->source->description = pa_sprintf_malloc("Advanced Linux Sound Architecture PCM on '%s'", dev);
 
-    u->fdl = pa_alsa_fdlist_new();
-    assert(u->fdl);
-    if (pa_alsa_fdlist_init_pcm(u->fdl, u->pcm_handle, c->mainloop, fdl_callback, u) < 0) {
+    u->pcm_fdl = pa_alsa_fdlist_new();
+    assert(u->pcm_fdl);
+    if (pa_alsa_fdlist_init_pcm(u->pcm_fdl, u->pcm_handle, c->mainloop, fdl_callback, u) < 0) {
         pa_log(__FILE__": failed to initialise file descriptor monitoring");
         goto fail;
+    }
+
+    if (u->mixer_handle) {
+        u->mixer_fdl = pa_alsa_fdlist_new();
+        assert(u->mixer_fdl);
+        if (pa_alsa_fdlist_init_mixer(u->mixer_fdl, u->mixer_handle, c->mainloop) < 0) {
+            pa_log(__FILE__": failed to initialise file descriptor monitoring");
+            goto fail;
+        }
+        snd_mixer_elem_set_callback(u->mixer_elem, mixer_callback);
+        snd_mixer_elem_set_callback_private(u->mixer_elem, u);
     }
 
     u->frame_size = frame_size;
@@ -400,8 +430,10 @@
         pa_source_unref(u->source);
     }
     
-    if (u->fdl)
-        pa_alsa_fdlist_free(u->fdl);
+    if (u->pcm_fdl)
+        pa_alsa_fdlist_free(u->pcm_fdl);
+    if (u->mixer_fdl)
+        pa_alsa_fdlist_free(u->mixer_fdl);
 
     if (u->mixer_handle)
         snd_mixer_close(u->mixer_handle);




More information about the pulseaudio-commits mailing list