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;
}
#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
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 \
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"), \
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)
{
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);
exit(EXIT_FAILURE);
}
-static void change_afs_mode_and_play(char *afs_mode)
+static void change_afs_mode(char *afs_mode)
{
char *cmd;
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)
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);
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;
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)
(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;
}
}
-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)
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) {
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;
#~~~~~~~~~~~~~~
"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
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.
"
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" -
int typestr = "seconds"
default = "5"
optional
+
+section "Options for set mode"
+##############################
+
+option "val" -
+"value to set"
+ int typestr = "value"
+ default = "0"
+ optional
+
</qu>