[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