[Slim-Checkins] r10274 - /trunk/server/Slim/Player/Player.pm
adrian at svn.slimdevices.com
adrian at svn.slimdevices.com
Tue Oct 10 13:58:35 PDT 2006
Author: adrian
Date: Tue Oct 10 13:58:32 2006
New Revision: 10274
URL: http://svn.slimdevices.com?rev=10274&view=rev
Log:
Bug: 4289 part
Description: reduce sensitivity of fade_volume to timer jitter. Full
solution for this bug requires firmware development.
Modified:
trunk/server/Slim/Player/Player.pm
Modified: trunk/server/Slim/Player/Player.pm
URL: http://svn.slimdevices.com/trunk/server/Slim/Player/Player.pm?rev=10274&r1=10273&r2=10274&view=diff
==============================================================================
--- trunk/server/Slim/Player/Player.pm (original)
+++ trunk/server/Slim/Player/Player.pm Tue Oct 10 13:58:32 2006
@@ -472,56 +472,47 @@
# fade the volume up or down
# $fade = number of seconds to fade 100% (positive to fade up, negative to fade down)
# $callback is function reference to be called when the fade is complete
-our %fvolume; # keep temporary fade volume for each client
sub fade_volume {
- my($client, $fade, $callback, $callbackargs) = @_;
-
- $::d_ui && msg("entering fade_volume: fade: $fade to $fvolume{$client}\n");
-
- my $faderate = 20; # how often do we send updated fade volume commands per second
-
- Slim::Utils::Timers::killTimers($client, \&fade_volume);
-
- my $vol = $client->prefGet("volume");
- my $mute = $client->prefGet("mute");
-
- if ($vol < 0) {
- # correct volume if mute volume is stored
- $vol = -$vol;
- }
-
- if (($fade == 0) ||
- ($vol < 0 && $fade < 0)) {
- # the volume is muted or fade is instantaneous, don't fade.
- $callback && (&$callback(@$callbackargs));
- return;
- }
-
- # on the first pass, set temporary fade volume
- if(!$fvolume{$client} && $fade > 0) {
- # fading up, start volume at 0
- $fvolume{$client} = 0;
- } elsif(!$fvolume{$client}) {
- # fading down, start volume at current volume
- $fvolume{$client} = $vol;
- }
-
- $fvolume{$client} += $client->maxVolume() * (1/$faderate) / $fade; # fade volume
-
- if ($fvolume{$client} < 0) { $fvolume{$client} = 0; };
- if ($fvolume{$client} > $vol) { $fvolume{$client} = $vol; };
-
- $client->volume($fvolume{$client},1); # set volume
-
- if (($fvolume{$client} == 0 && $fade < 0) || ($fvolume{$client} == $vol && $fade > 0)) {
- # done fading
- $::d_ui && msg("fade_volume done. fade: $fade to $fvolume{$client} (vol: $vol)\n");
- $fvolume{$client} = 0; # reset temporary fade volume
- $callback && (&$callback(@$callbackargs));
+ my ($client, $fade, $callback, $callbackargs) = @_;
+
+ my $int = 0.05; # interval between volume updates
+
+ my $vol = abs($client->prefGet("volume"));
+
+ Slim::Utils::Timers::killHighTimers($client, \&_fadeVolumeUpdate);
+
+ $client->_fadeVolumeUpdate( {
+ 'startVol' => ($fade > 0) ? 0 : $vol,
+ 'endVol' => ($fade > 0) ? $vol : 0,
+ 'startTime'=> Time::HiRes::time(),
+ 'int' => $int,
+ 'rate' => ($vol && $fade) ? $vol / $fade : 0,
+ 'cb' => $callback,
+ 'cbargs' => $callbackargs,
+ } );
+}
+
+sub _fadeVolumeUpdate {
+ my $client = shift;
+ my $f = shift;
+
+ my $now = Time::HiRes::time();
+
+ # new vol based on time since fade started to minise impact of timers firing late
+ $f->{'vol'} = $f->{'startVol'} + ($now - $f->{'startTime'}) * $f->{'rate'};
+
+ my $rate = $f->{'rate'};
+
+ if (!$rate || $rate < 0 && $f->{'vol'} < $f->{'endVol'} || $rate > 0 && $f->{'vol'} > $f->{'endVol'}) {
+ # reached end of fade
+ $client->volume($f->{'endVol'}, 1);
+ if ($f->{'cb'}) {
+ &{$f->{'cb'}}(@{$f->{'cbargs'}});
+ }
} else {
- $::d_ui && msg("fade_volume - setting volume to $fvolume{$client} (originally $vol)\n");
- Slim::Utils::Timers::setTimer($client, Time::HiRes::time()+ (1/$faderate), \&fade_volume, ($fade, $callback, $callbackargs));
+ $client->volume($f->{'vol'}, 1);
+ Slim::Utils::Timers::setHighTimer($client, $now + $f->{'int'}, \&_fadeVolumeUpdate, $f);
}
}
More information about the checkins
mailing list