Sleep timer fades instead of stopping abruptly. Volume staysat original setting instead of saving at 0.

This commit is contained in:
Storm Dragon
2025-10-22 12:13:13 -04:00
parent f4766b13f1
commit 33ae752333
3 changed files with 734 additions and 2 deletions

View File

@@ -12,6 +12,7 @@ import argparse
import threading
import gc
import os
import time
from pathlib import Path
import subprocess
@@ -184,6 +185,11 @@ class BookReader:
self.isRunning = False
self.isPlaying = False
# Sleep timer fade-out state
self.isFadingOut = False
self.fadeStartVolume = None
self.fadeStartTime = None
# Audio buffering for seamless playback
self.bufferedAudio = None # Pre-generated next paragraph
self.bufferThread = None
@@ -723,6 +729,28 @@ class BookReader:
# Explicitly delete event objects to help GC
del events
# Handle sleep timer fade-out (10 seconds before expiration)
if not self.isFadingOut and self.sleepTimerMenu.should_start_fadeout():
# Start fade-out
self.isFadingOut = True
self.fadeStartVolume = self.audioPlayer.get_volume()
self.fadeStartTime = time.time()
# Update volume during fade-out
if self.isFadingOut:
elapsed = time.time() - self.fadeStartTime
fadeProgress = elapsed / 10.0 # 10 second fade
if fadeProgress >= 1.0:
# Fade complete - stop at 25% volume
targetVolume = int(self.fadeStartVolume * 0.25)
self.audioPlayer.set_volume(targetVolume)
else:
# Calculate current volume (linear fade from start to 25%)
# Formula: startVolume - (startVolume * 0.75 * progress)
# This fades from 100% → 25% over 10 seconds
currentVolume = int(self.fadeStartVolume * (1.0 - 0.75 * fadeProgress))
self.audioPlayer.set_volume(currentVolume)
# Check if sleep timer has expired
if self.sleepTimerMenu.check_timer():
self.speechEngine.speak("Sleep timer expired. Goodbye.")
@@ -1775,7 +1803,13 @@ class BookReader:
# User selected "Quit now"
self.isRunning = False
self.isPlaying = False
# If shouldContinue is True, timer is set and reading continues
elif shouldContinue:
# New timer set - reset fade-out state and restore volume if needed
if self.isFadingOut and self.fadeStartVolume is not None:
self.audioPlayer.set_volume(self.fadeStartVolume)
self.isFadingOut = False
self.fadeStartVolume = None
self.fadeStartTime = None
elif event.key == pygame.K_ESCAPE:
self.speechEngine.speak("Cancelled")
self.sleepTimerMenu.exit_menu()
@@ -2491,7 +2525,11 @@ class BookReader:
isAudioBook = hasattr(self.book, 'isAudioBook') and self.book.isAudioBook
isPiperMode = self.config.get_reader_engine() == 'piper'
if isAudioBook or isPiperMode:
currentVolume = self.audioPlayer.get_volume()
# If we're fading out, save the original volume (not the faded volume)
if self.isFadingOut and self.fadeStartVolume is not None:
currentVolume = self.fadeStartVolume
else:
currentVolume = self.audioPlayer.get_volume()
self.config.set_volume(currentVolume)
self._cancel_buffer()