fade: Allow to set more than one channel in sleep mode.
authorAndre Noll <maan@systemlinux.org>
Wed, 11 Sep 2013 19:48:07 +0000 (19:48 +0000)
committerAndre Noll <maan@systemlinux.org>
Sat, 25 Jan 2014 20:08:37 +0000 (21:08 +0100)
This makes --ivol a string option which may be specified multiple
times, each with its own channel:value pair. The channel part is
optional, invalid channels are ignored.

This change retains backwards-compatibility, i.e. providing a single
value without "channel:" prefix still works as before.

Unfortunately the patch is a bit large since set_channel() had to be
moved to the top of fade.c. This function grew another argument to
specify the channel to set.

fade.c
m4/gengetopt/fade.m4

diff --git a/fade.c b/fade.c
index 8e9150f7d480df6f2032f334bb7575d48cc231f0..ed543d192c7e9f852265061bc1b93dfe687f282d 100644 (file)
--- a/fade.c
+++ b/fade.c
@@ -44,6 +44,23 @@ static __printf_2_3 void date_log(int ll, const char *fmt, ...)
 }
 __printf_2_3 void (*para_log)(int, const char*, ...) = date_log;
 
+static int set_channel(struct mixer *m, struct mixer_handle *h, const char *channel)
+{
+       char *channels;
+       int ret;
+
+       ret = m->set_channel(h, channel);
+       if (ret >= 0) {
+               PARA_NOTICE_LOG("using %s mixer channel\n",
+                       channel? channel : "default");
+               return ret;
+       }
+       channels = m->get_channels(h);
+       printf("Available channels: %s\n", channels);
+       free(channels);
+       return ret;
+}
+
 /* Fade to new volume in fade_time seconds. */
 static int fade(struct mixer *m, struct mixer_handle *h, int new_vol, int fade_time)
 {
@@ -55,11 +72,12 @@ static int fade(struct mixer *m, struct mixer_handle *h, int new_vol, int fade_t
        if (fade_time <= 0)
                return m->set(h, new_vol);
        secs = fade_time;
-       PARA_NOTICE_LOG("fading to %d in %d seconds\n", new_vol, secs);
        ret = m->get(h);
        if (ret < 0)
                goto out;
        vol = ret;
+       PARA_NOTICE_LOG("fading %s from %d to %d in %d seconds\n",
+               conf.mixer_channel_arg, vol, new_vol, secs);
        diff = new_vol - vol;
        if (!diff) {
                sleep(secs);
@@ -125,6 +143,44 @@ static void change_afs_mode_and_play(char *afs_mode)
        client_cmd("play");
 }
 
+static int set_initial_volume(struct mixer *m, struct mixer_handle *h)
+{
+       int i, ret;
+
+       for (i = 0; i < conf.ivol_given; i++) {
+               char *p, *ch, *arg = para_strdup(conf.ivol_arg[i]);
+               int32_t iv;
+               p = strchr(arg, ':');
+               if (p) {
+                       *p = '\0';
+                       p++;
+                       ch = arg;
+               } else {
+                       p = arg;
+                       ch = NULL;
+               }
+               ret = para_atoi32(p, &iv);
+               if (ret < 0) {
+                       free(arg);
+                       return ret;
+               }
+               ret = set_channel(m, h, ch);
+               if (!ch)
+                       ch = "default";
+               if (ret < 0) {
+                       PARA_WARNING_LOG("ignoring channel %s\n", ch);
+                       ret = 0;
+               } else {
+                       PARA_INFO_LOG("initial volume %s: %d\n", ch, iv);
+                       ret = m->set(h, iv);
+               }
+               free(arg);
+               if (ret < 0)
+                       return ret;
+       }
+       return 1;
+}
+
 static int sweet_dreams(struct mixer *m, struct mixer_handle *h)
 {
        time_t t1, wake_time_epoch;
@@ -138,7 +194,6 @@ static int sweet_dreams(struct mixer *m, struct mixer_handle *h)
        int fot = conf.fo_time_arg;
        int fiv = conf.fi_vol_arg;
        int fov = conf.fo_vol_arg;
-       int iv = conf.ivol_arg;
 
        /* calculate wake time */
        time(&t1);
@@ -162,11 +217,13 @@ static int sweet_dreams(struct mixer *m, struct mixer_handle *h)
        client_cmd("stop");
        sleep(1);
        if (fot) {
-               PARA_INFO_LOG("initial volume: %d\n", iv);
-               ret = m->set(h, iv);
+               ret = set_initial_volume(m, h);
                if (ret < 0)
                        return ret;
                change_afs_mode_and_play(fo_mood);
+               ret = set_channel(m, h, conf.mixer_channel_arg);
+               if (ret < 0)
+                       return ret;
                ret = fade(m, h, fov, fot);
                if (ret < 0)
                        return ret;
@@ -246,24 +303,6 @@ static void init_mixers(void)
        }
 }
 
-static int set_channel(struct mixer *m, struct mixer_handle *h)
-{
-       char *channels;
-       int ret;
-
-       ret = m->set_channel(h, conf.mixer_channel_arg);
-       if (ret >= 0) {
-               PARA_NOTICE_LOG("using %s mixer channel\n",
-                       conf.mixer_channel_arg?  conf.mixer_channel_arg
-                               : "default");
-               return ret;
-       }
-       channels = m->get_channels(h);
-       printf("Available channels: %s\n", channels);
-       free(channels);
-       return ret;
-}
-
 static int set_val(struct mixer *m, struct mixer_handle *h)
 {
        return m->set(h, conf.val_arg);
@@ -335,7 +374,7 @@ int main(int argc, char *argv[])
        ret = m->open(conf.mixer_device_arg, &h);
        if (ret < 0)
                goto out;
-       ret = set_channel(m, h);
+       ret = set_channel(m, h, conf.mixer_channel_arg);
        if (ret < 0)
                goto out;
        switch (conf.mode_arg) {
index ca99a398e812d5857107794ad0fa5e89b5195977..d0883c49618c45147080edfc3285653872448c79 100644 (file)
@@ -88,12 +88,15 @@ section "Options for sleep mode"
 option "ivol" -
 #~~~~~~~~~~~~~~
 "set initial volume"
-       int typestr = "volume"
+       string typestr = "[channel:]volume"
        default = "60"
        optional
+       multiple
        details = "
                Used as the start volume, before fading out to the
-               fade out volume.
+               fade out volume. The channel part may be omitted, in
+               which case the default channel is used. This option
+               may be given multiple times.
        "
 
 option "fo-mood" -