File: mpfade

package info (click to toggle)
mpdtoys 0.25.1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 104 kB
  • sloc: perl: 844; sh: 58; makefile: 19
file content (118 lines) | stat: -rwxr-xr-x 2,692 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/perl
use strict;
use warnings;
use Audio::MPD q{0.19.0};

=head1 NAME

mpfade - fade mpd volume in or out

=head1 SYNOPSIS

mpfade [minutes] [max|min] [host]

=head1 DESCRIPTION

B<mpfade> behaves differently depending on whether mpd is playing or not.

If mpd is not playing (or is paused), it starts it playing at a low volume,
and gradually cranks the volume up to the specified B<max> value (default
50) over the specified number of minutes (default 10).

If mpd is already playing, it works in reverse, reducing the volume over
time until it's a the specified B<min> (defaults to a tenth of what it was
at the start). Then it stops playing.

B<mpfade> tries to interact well with manual volume changes you make. If
the volume is fading up, and you change the volume manually, it stops. This
is intended to be useful when used as an alarm clock. If the volume is
fading down, changes you make to the volume will be noticed, and the fade
down will continue from that point.

The B<minutes> value can be a floating point value. If the hostname is
omitted, the MPD_HOST environment variable will be used.

=head1 AUTHOR

Copyright 2007 Joey Hess <joey@kitenet.net>

Licensed under the GNU GPL version 2 or higher.

http://kitenet.net/~joey/code/mpdtoys

=cut

my $seconds=60 * 10;
if (@ARGV && $ARGV[0] =~ /^[0-9.]+$/) {
	$seconds=60 * shift;
}
my $endpoint;
if (@ARGV && $ARGV[0] =~ /^[0-9.]+$/) {
	$endpoint=shift;
}

if (@ARGV) {
	$ENV{MPD_HOST}=shift;
}

my $mpd=Audio::MPD->new(conntype => "reuse");
my $vol=$mpd->status->volume;
if ($mpd->status->state eq 'play') {
	if (defined $endpoint) {
		if ($endpoint >= $vol) {
			die "error: min ($endpoint) is not less than current volume ($vol)\n";
		}
	}
	else {
		$endpoint=int($vol / 10);
	}
	print "fading down from $vol to $endpoint over $seconds seconds\n";
	fade($endpoint, $seconds);
	$mpd->stop;
}
else {
	if (! defined $endpoint) {
		$endpoint=50;
	}
	$mpd->volume($vol=0);
	print "fading up from $vol to $endpoint over $seconds seconds\n";
	$mpd->play;
	fade($endpoint, $seconds);
}

sub fade {
	my $endpoint=shift;
	my $seconds=shift;

	if ($seconds < 1) {
		$mpd->volume($endpoint);
		return;
	}

	my $span=$endpoint - $vol;
	my $oldvol=$vol;
	my $curvol;

	# TODO calculate how long to optimally sleep

	while (sleep 1) {
		$curvol=$mpd->status->volume;
		if ($curvol != $oldvol) {
			if ($span > 0) {
				print "manual volume change, aborting fade up\n";
				return;
			}
			else {
				print "manual volume change\n";
				$vol=$curvol;
			}
		}

		$vol=$vol + ($span / $seconds);
		last if abs($vol - $endpoint) <= 1;
		if (abs(int($vol - $oldvol)) > 1) {
			$mpd->volume(int($vol));
			$oldvol=int($vol);
		}
	}
}