]> git.tuebingen.mpg.de Git - paraslash.git/commitdiff
Merge branch 't/fade_improvements'
authorAndre Noll <maan@systemlinux.org>
Sun, 23 Mar 2014 18:21:37 +0000 (19:21 +0100)
committerAndre Noll <maan@systemlinux.org>
Sun, 23 Mar 2014 18:23:56 +0000 (19:23 +0100)
Cooking since 2014-02-08.

* t/fade_improvements:
  fade: Improve error diagnostics.
  fade: Switch to the fade-in mood *before* sleeping.
  fade: Allow to set more than one channel in sleep mode.
  fade: Implement new mode "set".
  fade: Log to stderr.

Conflicts:
error.h

NEWS
alsa_mix.c
error.h
fade.c
m4/gengetopt/fade.m4
oss_mix.c

diff --git a/NEWS b/NEWS
index 84a420584242f6a7e2f6a1b2306c4c0000fb8065..787bdde64d7cd797d93b73131256a9530be363bf 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ network code are the highlights of this release.
          are necessary, and a client linked against openssl can
          speak with a server linked against libgcrypt and vice versa.
        - Major cleanup of the networking subsystem.
+       - Improvements to para_fade: the new set mode, multi-channal
+         initial volumes, better error logging.
        - Improved user manual.
        - Minor fixes to avoid clang warnings.
 
index 01f1c51260a7b6753ba8b14aac0c255120b4b331..c5daebc2682b13eb0d6e2a12b9956ae5b77ff4b8 100644 (file)
@@ -141,19 +141,19 @@ static int alsa_mix_set_channel(struct mixer_handle *h,
                PARA_NOTICE_LOG("unable to find simple control '%s',%i\n",
                        snd_mixer_selem_id_get_name(sid),
                        snd_mixer_selem_id_get_index(sid));
-               return -E_ALSA_MIX_BAD_ELEM;
+               return -E_BAD_CHANNEL;
        }
        ret = snd_mixer_selem_get_playback_volume_range(h->elem,
                &h->pmin, &h->pmax);
        if (ret < 0) {
                PARA_NOTICE_LOG("unable to get %s range (%s): %s\n",
                        mixer_channel, h->card, snd_strerror(ret));
-               return -E_ALSA_MIX_BAD_ELEM;
+               return -E_ALSA_MIX_RANGE;
        }
        if (h->pmin < 0 || h->pmax < 0 || h->pmin >= h->pmax) {
                PARA_NOTICE_LOG("alsa reported %s range %ld-%ld (%s)\n",
                        mixer_channel, h->pmin, h->pmax, h->card);
-               return -E_ALSA_MIX_BAD_ELEM;
+               return -E_ALSA_MIX_RANGE;
        }
        return 1;
 }
diff --git a/error.h b/error.h
index 08b309ce398d8375c334eb420d6e94408a223189..3b57680b92e2c2c057c55d9ef148fe8bb51d25c3 100644 (file)
--- a/error.h
+++ b/error.h
@@ -28,7 +28,7 @@ DEFINE_ERRLIST_OBJECT_ENUM;
 #define GGO_ERRORS
 #define COLOR_ERRORS
 #define SIGNAL_ERRORS
-#define FADE_ERRORS
+#define OSS_MIX_ERRORS
 #define STDOUT_ERRORS
 #define FILE_WRITE_ERRORS
 #define STDIN_ERRORS
@@ -44,15 +44,11 @@ extern const char **para_errlist[];
        PARA_ERROR(SYNC_COMPLETE, "all buddies in sync"), \
        PARA_ERROR(SYNC_LISTEN_FD, "no fd to listen on"), \
 
-#define OSS_MIX_ERRORS \
-       PARA_ERROR(OSS_MIXER_CHANNEL, "invalid mixer channel"), \
-
-
 #define ALSA_MIX_ERRORS \
        PARA_ERROR(ALSA_MIX_OPEN, "could not open mixer"), \
-       PARA_ERROR(ALSA_MIX_BAD_ELEM, "invalid/unsupported control element"), \
        PARA_ERROR(ALSA_MIX_GET_VAL, "could not read control element state"), \
        PARA_ERROR(ALSA_MIX_SET_VAL, "could not set control element state"), \
+       PARA_ERROR(ALSA_MIX_RANGE, "value control element out of range"), \
 
 
 #define RESAMPLE_FILTER_ERRORS \
@@ -83,6 +79,8 @@ extern const char **para_errlist[];
        PARA_ERROR(NO_VALID_FILES, "no valid file found in playlist"), \
        PARA_ERROR(BAD_PLAY_CMD, "invalid command"), \
 
+#define FADE_ERRORS \
+       PARA_ERROR(BAD_CHANNEL, "invalid channel"), \
 
 #define FLACDEC_FILTER_ERRORS \
        PARA_ERROR(FLACDEC_DECODER_ALLOC, "could not allocate stream decoder"), \
diff --git a/fade.c b/fade.c
index a8424d67a5db24ea2967670ee6eb90ccaf284100..0a3ccebb844326267f421044d998d77c27096356 100644 (file)
--- a/fade.c
+++ b/fade.c
@@ -37,13 +37,21 @@ static __printf_2_3 void date_log(int ll, const char *fmt, ...)
                return;
        time(&t1);
        tm = localtime(&t1);
-       printf("%d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec);
+       fprintf(stderr, "%d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec);
        va_start(argp, fmt);
        vprintf(fmt, argp);
        va_end(argp);
 }
 __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)
+{
+
+       PARA_NOTICE_LOG("using %s mixer channel\n", channel?
+               channel : "default");
+       return m->set_channel(h, channel);
+}
+
 /* 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 +63,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);
@@ -112,7 +121,7 @@ fail:
        exit(EXIT_FAILURE);
 }
 
-static void change_afs_mode_and_play(char *afs_mode)
+static void change_afs_mode(char *afs_mode)
 {
        char *cmd;
 
@@ -122,7 +131,44 @@ static void change_afs_mode_and_play(char *afs_mode)
        cmd = make_message("select %s", afs_mode);
        client_cmd(cmd);
        free(cmd);
-       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)
@@ -138,7 +184,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 +207,14 @@ 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(fo_mood);
+               client_cmd("play");
+               ret = set_channel(m, h, conf.mixer_channel_arg);
                if (ret < 0)
                        return ret;
-               change_afs_mode_and_play(fo_mood);
                ret = fade(m, h, fov, fot);
                if (ret < 0)
                        return ret;
@@ -175,12 +223,14 @@ static int sweet_dreams(struct mixer *m, struct mixer_handle *h)
                if (ret < 0)
                        return ret;
        }
-       if (conf.sleep_mood_given)
-               change_afs_mode_and_play(sleep_mood);
-       else
+       if (conf.sleep_mood_given) {
+               change_afs_mode(sleep_mood);
+               client_cmd("play");
+       } else
                client_cmd("stop");
        if (!fit)
                return 1;
+       change_afs_mode(fi_mood);
        for (;;) {
                time(&t1);
                if (wake_time_epoch <= t1 + fit)
@@ -191,7 +241,7 @@ static int sweet_dreams(struct mixer *m, struct mixer_handle *h)
                        (delay % 3600) / 60);
                sleep(delay);
        }
-       change_afs_mode_and_play(fi_mood);
+       client_cmd("play");
        ret = fade(m, h, fiv, fit);
        PARA_INFO_LOG("fade complete, returning\n");
        return ret;
@@ -246,22 +296,9 @@ static void init_mixers(void)
        }
 }
 
-static int set_channel(struct mixer *m, struct mixer_handle *h)
+static int set_val(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;
+       return m->set(h, conf.val_arg);
 }
 
 static struct mixer *get_mixer_or_die(void)
@@ -330,7 +367,12 @@ 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 == -E_BAD_CHANNEL) {
+               char *channels = m->get_channels(h);
+               printf("Available channels: %s\n", channels);
+               free(channels);
+       }
        if (ret < 0)
                goto out;
        switch (conf.mode_arg) {
@@ -340,6 +382,9 @@ int main(int argc, char *argv[])
        case mode_arg_snooze:
                ret = snooze(m, h);
                break;
+       case mode_arg_set:
+               ret = set_val(m, h);
+               break;
        default: /* sleep mode */
                ret = sweet_dreams(m, h);
                break;
index 7c731c2b6ec1cdf15322131827fe99add0917e09..d0883c49618c45147080edfc3285653872448c79 100644 (file)
@@ -17,11 +17,11 @@ option "mode" o
 #~~~~~~~~~~~~~~
 "how to fade volume"
        enum typestr = "mode"
-       values = "sleep", "snooze", "fade"
+       values = "sleep", "fade", "set", "snooze"
        default = "sleep"
        optional
        details="
-               para_fade knows three different fading modes:
+               para_fade knows the following modes:
 
                sleep mode: Change to the initial volume and select
                the initial afs mood/playlist. Then fade out until
@@ -33,6 +33,8 @@ option "mode" o
                fade: Fade the volume to the given value in the
                given time.
 
+               set: Just set the value and exit.
+
                snooze: Fade out, sleep a bit and fade in.
 "
 
@@ -86,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" -
@@ -228,4 +233,14 @@ option "fade-time" t
        int typestr = "seconds"
        default = "5"
        optional
+
+section "Options for set mode"
+##############################
+
+option "val" -
+"value to set"
+       int typestr = "value"
+       default = "0"
+       optional
+
 </qu>
index 5182ad238b81f706ebac2f6abdcaec3859b809dc..7e19fcbe3f9e7dd473f49f20f15442683dfff32d 100644 (file)
--- a/oss_mix.c
+++ b/oss_mix.c
@@ -98,7 +98,7 @@ static int oss_mix_set_channel(struct mixer_handle *handle,
                handle->id = i;
                return 1;
        }
-       return -E_OSS_MIXER_CHANNEL;
+       return -E_BAD_CHANNEL;
 }
 
 static int oss_mix_get(struct mixer_handle *handle)