[pulseaudio-commits] r1554 - /branches/lennart/src/modules/module-alsa-sink.c

svnmailer-noreply at 0pointer.de svnmailer-noreply at 0pointer.de
Sat Jul 28 12:30:11 PDT 2007


Author: lennart
Date: Sat Jul 28 21:30:10 2007
New Revision: 1554

URL: http://0pointer.de/cgi-bin/viewcvs.cgi?rev=3D1554&root=3Dpulseaudio&vi=
ew=3Drev
Log:
restore proper mixer volume control

Modified:
    branches/lennart/src/modules/module-alsa-sink.c

Modified: branches/lennart/src/modules/module-alsa-sink.c
URL: http://0pointer.de/cgi-bin/viewcvs.cgi/branches/lennart/src/modules/mo=
dule-alsa-sink.c?rev=3D1554&root=3Dpulseaudio&r1=3D1553&r2=3D1554&view=3Ddi=
ff
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D
--- branches/lennart/src/modules/module-alsa-sink.c (original)
+++ branches/lennart/src/modules/module-alsa-sink.c Sat Jul 28 21:30:10 2007
@@ -82,9 +82,10 @@
     =

     snd_pcm_t *pcm_handle;
 =

-/*     snd_mixer_t *mixer_handle; */
-/*     snd_mixer_elem_t *mixer_elem; */
-/* long hw_volume_max, hw_volume_min; */
+    pa_alsa_fdlist *mixer_fdl;
+    snd_mixer_t *mixer_handle;
+    snd_mixer_elem_t *mixer_elem;
+    long hw_volume_max, hw_volume_min;
 =

     size_t frame_size, fragment_size, hwbuf_size;
     unsigned nfragments;
@@ -283,6 +284,9 @@
         goto fail;
     }
 =

+    pa_sink_get_volume(u->sink);
+    pa_sink_get_mute(u->sink);
+
     u->first =3D 1;
                 =

     pa_log_debug("Resumed successfully...");
@@ -328,160 +332,133 @@
             }
             =

             break;
-
-/*         case PA_SINK_MESSAGE_SET_VOLUME: */
-
-/*             if (u->use_pcm_volume && u->fd >=3D 0) { */
-
-/*                 if (pa_oss_set_pcm_volume(u->fd, &u->sink->sample_spec,=
 ((pa_cvolume*) data)) < 0) { */
-/*                     pa_log_info("Device doesn't support setting mixer s=
ettings: %s", pa_cstrerror(errno)); */
-/*                     u->use_pcm_volume =3D 0; */
-/*                 } else */
-/*                     return 0; */
-/*             } */
-
-/*             break; */
-
-/*         case PA_SINK_MESSAGE_GET_VOLUME: */
-
-/*             if (u->use_pcm_volume && u->fd >=3D 0) { */
-
-/*                 if (pa_oss_get_pcm_volume(u->fd, &u->sink->sample_spec,=
 ((pa_cvolume*) data)) < 0) { */
-/*                     pa_log_info("Device doesn't support reading mixer s=
ettings: %s", pa_cstrerror(errno)); */
-/*                     u->use_pcm_volume =3D 0; */
-/*                 } else */
-/*                     return 0; */
-/*             } */
-
-/*             break; */
     }
 =

     return pa_sink_process_msg(o, code, data, chunk);
 }
 =

-
-/* static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) { =
*/
-/*     struct userdata *u =3D snd_mixer_elem_get_callback_private(elem); */
-
-/*     pa_assert(u && u->mixer_handle); */
-
-/*     if (mask =3D=3D SND_CTL_EVENT_MASK_REMOVE) */
-/*         return 0; */
-
-/*     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 int sink_get_hw_volume_cb(pa_sink *s) { */
-/*     struct userdata *u =3D s->userdata; */
-/*     int err; */
-/*     int i; */
-
-/*     pa_assert(u); */
-/*     pa_assert(u->mixer_elem); */
-
-/*     for (i =3D 0; i < s->hw_volume.channels; i++) { */
-/*         long set_vol, vol; */
-
-/*         pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i=
)); */
-
-/*         if ((err =3D snd_mixer_selem_get_playback_volume(u->mixer_elem,=
 i, &vol)) < 0) */
-/*             goto fail; */
-
-/*         set_vol =3D (long) roundf(((float) s->hw_volume.values[i] * (u-=
>hw_volume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; */
-
-/*         /\* Try to avoid superfluous volume changes *\/ */
-/*         if (set_vol !=3D vol) */
-/*             s->hw_volume.values[i] =3D (pa_volume_t) roundf(((float) (v=
ol - u->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume=
_min)); */
-/*     } */
-
-/*     return 0; */
-
-/* fail: */
-/*     pa_log_error("Unable to read volume: %s", snd_strerror(err)); */
-/*     s->get_hw_volume =3D NULL; */
-/*     s->set_hw_volume =3D NULL; */
-/*     return -1; */
-/* } */
-
-/* static int sink_set_hw_volume_cb(pa_sink *s) { */
-/*     struct userdata *u =3D s->userdata; */
-/*     int err; */
-/*     int i; */
-/*     pa_volume_t vol; */
-
-/*     pa_assert(u); */
-/*     pa_assert(u->mixer_elem); */
-
-/*     for (i =3D 0; i < s->hw_volume.channels; i++) { */
-/*         long alsa_vol; */
-
-/*         pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i=
)); */
-
-/*         vol =3D s->hw_volume.values[i]; */
-
-/*         if (vol > PA_VOLUME_NORM) */
-/*             vol =3D PA_VOLUME_NORM; */
-
-/*         alsa_vol =3D (long) roundf(((float) vol * (u->hw_volume_max - u=
->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min; */
-
-/*         if ((err =3D snd_mixer_selem_set_playback_volume(u->mixer_elem,=
 i, alsa_vol)) < 0) */
-/*             goto fail; */
-/*     } */
-
-/*     return 0; */
-
-/* fail: */
-/*     pa_log_error("Unable to set volume: %s", snd_strerror(err)); */
-/*     s->get_hw_volume =3D NULL; */
-/*     s->set_hw_volume =3D NULL; */
-/*     return -1; */
-/* } */
-
-/* static int sink_get_hw_mute_cb(pa_sink *s) { */
-/*     struct userdata *u =3D s->userdata; */
-/*     int err, sw; */
-
-/*     pa_assert(u && u->mixer_elem); */
-
-/*     err =3D snd_mixer_selem_get_playback_switch(u->mixer_elem, 0, &sw);=
 */
-/*     if (err) { */
-/*         pa_log_error("Unable to get switch: %s", snd_strerror(err)); */
-/*         s->get_hw_mute =3D NULL; */
-/*         s->set_hw_mute =3D NULL; */
-/*         return -1; */
-/*     } */
-
-/*     s->hw_muted =3D !sw; */
-
-/*     return 0; */
-/* } */
-
-/* static int sink_set_hw_mute_cb(pa_sink *s) { */
-/*     struct userdata *u =3D s->userdata; */
-/*     int err; */
-
-/*     pa_assert(u && u->mixer_elem); */
-
-/*     err =3D snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s->=
hw_muted); */
-/*     if (err) { */
-/*         pa_log_error("Unable to set switch: %s", snd_strerror(err)); */
-/*         s->get_hw_mute =3D NULL; */
-/*         s->set_hw_mute =3D NULL; */
-/*         return -1; */
-/*     } */
-
-/*     return 0; */
-/* } */
+static int mixer_callback(snd_mixer_elem_t *elem, unsigned int mask) {
+    struct userdata *u =3D snd_mixer_elem_get_callback_private(elem);
+
+    pa_assert(u);
+    pa_assert(u->mixer_handle);
+
+    if (mask =3D=3D SND_CTL_EVENT_MASK_REMOVE)
+        return 0;
+
+    if (mask & SND_CTL_EVENT_MASK_VALUE) {
+        pa_sink_get_volume(u->sink);
+        pa_sink_get_mute(u->sink);
+    }
+
+    return 0;
+}
+
+static int sink_get_volume_cb(pa_sink *s) {
+    struct userdata *u =3D s->userdata;
+    int err;
+    int i;
+
+    pa_assert(u);
+    pa_assert(u->mixer_elem);
+
+    for (i =3D 0; i < s->sample_spec.channels; i++) {
+        long set_vol, vol;
+
+        pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i));
+
+        if ((err =3D snd_mixer_selem_get_playback_volume(u->mixer_elem, i,=
 &vol)) < 0)
+            goto fail;
+
+        set_vol =3D (long) roundf(((float) s->volume.values[i] * (u->hw_vo=
lume_max - u->hw_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min;
+
+        /* Try to avoid superfluous volume changes */
+        if (set_vol !=3D vol)
+            s->volume.values[i] =3D (pa_volume_t) roundf(((float) (vol - u=
->hw_volume_min) * PA_VOLUME_NORM) / (u->hw_volume_max - u->hw_volume_min));
+    }
+
+    return 0;
+
+fail:
+    pa_log_error("Unable to read volume: %s", snd_strerror(err));
+    =

+    s->get_volume =3D NULL;
+    s->set_volume =3D NULL;
+    return -1;
+}
+
+static int sink_set_volume_cb(pa_sink *s) {
+    struct userdata *u =3D s->userdata;
+    int err;
+    int i;
+
+    pa_assert(u);
+    pa_assert(u->mixer_elem);
+
+    for (i =3D 0; i < s->sample_spec.channels; i++) {
+        long alsa_vol;
+        pa_volume_t vol;
+
+        pa_assert(snd_mixer_selem_has_playback_channel(u->mixer_elem, i));
+
+        vol =3D s->volume.values[i];
+
+        if (vol > PA_VOLUME_NORM)
+            vol =3D PA_VOLUME_NORM;
+
+        alsa_vol =3D (long) roundf(((float) vol * (u->hw_volume_max - u->h=
w_volume_min)) / PA_VOLUME_NORM) + u->hw_volume_min;
+
+        if ((err =3D snd_mixer_selem_set_playback_volume(u->mixer_elem, i,=
 alsa_vol)) < 0)
+            goto fail;
+    }
+
+    return 0;
+
+fail:
+    pa_log_error("Unable to set volume: %s", snd_strerror(err));
+    =

+    s->get_volume =3D NULL;
+    s->set_volume =3D NULL;
+    return -1;
+}
+
+static int sink_get_mute_cb(pa_sink *s) {
+    struct userdata *u =3D s->userdata;
+    int err, sw;
+
+    pa_assert(u);
+    pa_assert(u->mixer_elem);
+
+    if ((err =3D snd_mixer_selem_get_playback_switch(u->mixer_elem, 0, &sw=
)) < 0) {
+        pa_log_error("Unable to get switch: %s", snd_strerror(err));
+
+        s->get_mute =3D NULL;
+        s->set_mute =3D NULL;
+        return -1;
+    }
+
+    s->muted =3D !sw;
+
+    return 0;
+}
+
+static int sink_set_mute_cb(pa_sink *s) {
+    struct userdata *u =3D s->userdata;
+    int err;
+
+    pa_assert(u);
+    pa_assert(u->mixer_elem);
+
+    if ((err =3D snd_mixer_selem_set_playback_switch_all(u->mixer_elem, !s=
->muted)) < 0) {
+        pa_log_error("Unable to set switch: %s", snd_strerror(err));
+        =

+        s->get_mute =3D NULL;
+        s->set_mute =3D NULL;
+        return -1;
+    }
+
+    return 0;
+}
 =

 static void thread_func(void *userdata) {
     enum {
@@ -776,6 +753,9 @@
         u->use_mmap =3D use_mmap =3D b;
     }
 =

+    if (u->use_mmap)
+        pa_log_info("Successfully enabled mmap() mode.");
+
     /* ALSA might tweak the sample spec, so recalculate the frame size */
     frame_size =3D pa_frame_size(&ss);
 =

@@ -783,16 +763,17 @@
         /* Seems ALSA didn't like the channel number, so let's fix the cha=
nnel map */
         pa_channel_map_init_auto(&map, ss.channels, PA_CHANNEL_MAP_ALSA);
 =

-/*     if ((err =3D snd_mixer_open(&u->mixer_handle, 0)) < 0)  */
-/*         pa_log_warn("Error opening mixer: %s", snd_strerror(err)); */
-/*     else { */
-
-/*         if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) || */
-/*             !(u->mixer_elem =3D pa_alsa_find_elem(u->mixer_handle, "PCM=
", "Master"))) { */
-/*             snd_mixer_close(u->mixer_handle); */
-/*             u->mixer_handle =3D NULL; */
-/*         } */
-/*     } */
+    if ((err =3D snd_mixer_open(&u->mixer_handle, 0)) < 0)
+        pa_log_warn("Error opening mixer: %s", snd_strerror(err));
+    else {
+
+        if ((pa_alsa_prepare_mixer(u->mixer_handle, dev) < 0) ||
+            !(u->mixer_elem =3D pa_alsa_find_elem(u->mixer_handle, "PCM", =
"Master"))) {
+            =

+            snd_mixer_close(u->mixer_handle);
+            u->mixer_handle =3D NULL;
+        }
+    }
 =

     if ((name =3D pa_modargs_get_value(ma, "sink_name", NULL)))
         namereg_fail =3D 1;
@@ -821,41 +802,6 @@
     pa_xfree(t);
     =

     u->sink->is_hardware =3D 1;
-    =

-/*     if (u->mixer_handle) { */
-/*         pa_assert(u->mixer_elem); */
-/*         if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) { */
-/*             int i; */
-
-/*             for (i =3D 0;i < ss.channels;i++) { */
-/*                 if (!snd_mixer_selem_has_playback_channel(u->mixer_elem=
, i)) */
-/*                     break; */
-/*             } */
-
-/*             if (i =3D=3D ss.channels) { */
-/*                 u->sink->get_hw_volume =3D sink_get_hw_volume_cb; */
-/*                 u->sink->set_hw_volume =3D sink_set_hw_volume_cb; */
-/*                 snd_mixer_selem_get_playback_volume_range( */
-/*                     u->mixer_elem, &u->hw_volume_min, &u->hw_volume_max=
); */
-/*             } */
-/*         } */
-/*         if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) { */
-/*             u->sink->get_hw_mute =3D sink_get_hw_mute_cb; */
-/*             u->sink->set_hw_mute =3D sink_set_hw_mute_cb; */
-/*         } */
-/*     } */
-
-/*     if (u->mixer_handle) { */
-/*         u->mixer_fdl =3D pa_alsa_fdlist_new(); */
-/*         pa_assert(u->mixer_fdl); */
-/*         if (pa_alsa_fdlist_init_mixer(u->mixer_fdl, u->mixer_handle, c-=
>mainloop) < 0) { */
-/*             pa_log("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); */
-/*     } else */
-/*         u->mixer_fdl =3D NULL; */
 =

     u->frame_size =3D frame_size;
     u->fragment_size =3D period_size * frame_size;
@@ -865,6 +811,44 @@
     pa_log_info("Using %u fragments of size %lu bytes.", nfrags, (long uns=
igned) u->fragment_size);
 =

     pa_memchunk_reset(&u->memchunk);
+
+    if (u->mixer_handle) {
+        /* Initialize mixer code */
+        =

+        pa_assert(u->mixer_elem);
+        =

+        if (snd_mixer_selem_has_playback_volume(u->mixer_elem)) {
+            int i;
+
+            for (i =3D 0;i < ss.channels; i++) {
+                if (!snd_mixer_selem_has_playback_channel(u->mixer_elem, i=
))
+                    break;
+            }
+
+            if (i =3D=3D ss.channels) {
+                u->sink->get_volume =3D sink_get_volume_cb;
+                u->sink->set_volume =3D sink_set_volume_cb;
+                snd_mixer_selem_get_playback_volume_range(u->mixer_elem, &=
u->hw_volume_min, &u->hw_volume_max);
+            }
+        }
+        if (snd_mixer_selem_has_playback_switch(u->mixer_elem)) {
+            u->sink->get_mute =3D sink_get_mute_cb;
+            u->sink->set_mute =3D sink_set_mute_cb;
+        }
+
+        u->mixer_fdl =3D pa_alsa_fdlist_new();
+        pa_assert(u->mixer_fdl);
+
+        if (pa_alsa_fdlist_set_mixer(u->mixer_fdl, u->mixer_handle, c->mai=
nloop) < 0) {
+            pa_log("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);
+    } else
+        u->mixer_fdl =3D NULL;
+
 =

     if (!(u->thread =3D pa_thread_new(thread_func, u))) {
         pa_log("Failed to create thread.");
@@ -922,9 +906,12 @@
     =

     if (u->memchunk.memblock)
         pa_memblock_unref(u->memchunk.memblock);
-    =

-/*     if (u->mixer_handle) */
-/*         snd_mixer_close(u->mixer_handle); */
+
+    if (u->mixer_fdl)
+        pa_alsa_fdlist_free(u->mixer_fdl);
+    =

+    if (u->mixer_handle)
+        snd_mixer_close(u->mixer_handle);
 =

     if (u->pcm_handle) {
         snd_pcm_drop(u->pcm_handle);




More information about the pulseaudio-commits mailing list