Rockbox Development > Feature Ideas

more advanced sleep timer

(1/5) > >>

tdb:
Hi

I have been using rockbox for many years almost daily and am very pleased with it. Use it mainly for listening to podcasts and audiobooks and appreciate the tons of features and settings (especially the bookmarking features).

I also use the sleeptimer function often as an aid to go to sleep with a podcast or audiobook. I usually need 15 minutes to go to sleep and that works fine most of the times, but it can happen that a podcast or audiobook wakes me up within that time frame due to some louder recorded sound/voice or sudden change of voice / speaker etc.
For that reason there are only a few podcasts I have chosen to 'talk me into sleep' and keep the sound level low but even then, it sometimes happens I wake up again before sleeptimer shuts down the device. 

A solution for this 'problem' might be to add a fade out feature for sleeptimer that takes a couple of minutes (preferably something that can be set by the user)
In practice that could mean I would change the length of the sleeptimer from 15 minutes to 20 or 25 minutes and starts very gradually to fade out after 10 minutes and it takes 10-15 minutes to reach volume 0 and shuts down.

That would make the sleeptimer an even more useful tool as a sleeping aid. I am pretty sure lots of folks are already using it as a sleeping aid, but a feature like this takes it to another level imo.
Maybe there is already something like this possible but I couldn't find it. The fade on stop option is too short and not specific for the sleep timer so that doesn't really help. 


 





Bilgus:
Here is a lua script that should do what you want, feel free to tweak it to your hearts desire

set your sleep timer and start your songs
copy into a file called Slow_fade.lua or something like that and run it from the file browser
choose a timeout and it will reduce the volume over the span you selected
when it hits the minimum volume playback will stop


--- Code: -----Bilgus 12-2016
require "actions"
require "buttons"
TIMEOUT = 0
SOUND_VOLUME = 0
function say_msg(message, timeout)
    rb.splash(1, message)
    rb.sleep(timeout * rb.HZ)
end

function say_value(value,message,timeout)
  local message = string.format(message .. "%d", value)
  say_msg(message, timeout)
end

function cfg_num_setting(str_name)
local file = io.open(rb.ROCKBOX_DIR .. "/config.cfg", "r")
    if not file then
        return nil
    end
local value = nil
local contents = file:read("*all")

    i, j = string.find(contents, str_name .. ":")
    if j ~= nil then
        file:seek ("set", rb.atoi(j))
        value = file:read ("*num")
    end
    file:close() -- GC takes care of this if you would've forgotten it
    return value
end

function cfg_str_setting(str_name)
local file = io.open(rb.ROCKBOX_DIR .. "/config.cfg", "r")
    if not file then
        return nil
    end
local str = nil
local contents = file:read("*all")

    i, j = string.find(contents, str_name .. ":")
    if j ~= nil then
        file:seek ("set", rb.atoi(j))
        str = file:read ("*line")
        str = string.gsub(str, "%s", "")
    else
        str ="!"
    end
    file:close() -- GC takes care of this if you would've forgotten it
    return str
end

function ShowMainMenu() -- we invoke this function every time we want to display the main menu of the script
local s = 0
local mult = 1
local unit = " Minutes"


    while s == 0 or s == 5 do -- don't exit of program until user selects Exit
        if mult < 1 then
            mult = 1
            s = 0
        end
        mainmenu = {"More", mult * 1 .. unit, mult * 5 .. unit, mult * 10 .. unit, mult * 15 .. unit, "Less", "Exit"} -- define the items of the menu
        s = rb.do_menu("Reduce volume over", mainmenu, s, false) -- actually tell Rockbox to draw the menu

        -- In the line above: "Test" is the title of the menu, mainmenu is an array with the items
        -- of the menu, nil is a null value that needs to be there, and the last parameter is
        -- whether the theme should be drawn on the menu or not.
        -- the variable s will hold the index of the selected item on the menu.
        -- the index is zero based. This means that the first item is 0, the second one is 1, etc.
        if     s == 0 then mult = mult + 1
        elseif s == 1 then TIMEOUT = mult
        elseif s == 2 then TIMEOUT = mult * 5
        elseif s == 3 then TIMEOUT = mult * 10
        elseif s == 4 then TIMEOUT = mult * 15
        elseif s == 5 then mult = mult - 1 -- User selected to exit
        elseif s == 6 then os.exit() -- User selected to exit
        elseif s == -2 then os.exit() -- -2 index is returned from do_menu() when user presses the key to exit the menu (on iPods, it's the left key).
                                      -- In this case, user probably wants to exit (or go back to last menu).
        else rb.splash(2 * rb.HZ, "Error! Selected index: " .. s) -- something strange happened. The program shows this message when
                                                                  -- the selected item is not on the index from 0 to 3 (in this case), and displays
                                                                  -- the selected index. Having this type of error handling is not
                                                                  -- required, but it might be nice to have Especially while you're still
                                                                  -- developing the plugin.
        end
    end
end





ShowMainMenu()
rb.lcd_clear_display()
rb.lcd_update()

--if rb.strcasecmp(cfg_str_setting("keypress restarts sleeptimer"),"on") == 0 then
--say_msg("keypress restarts timer", 1)
--end

local volume = cfg_num_setting("volume")
    if volume == nil then
        volume = rb.sound_default(SOUND_VOLUME)
    end


local vol_min = rb.sound_min(SOUND_VOLUME)
local volsteps = -(vol_min - volume)
local seconds = (TIMEOUT * 60) / volsteps
local sec_left = (TIMEOUT * 60)
local hb = 0
local action = rb.get_action(rb.contexts.CONTEXT_STD, 0)
    if rb.pcm_is_playing() then
        while ((volume > vol_min) and (action ~= rb.actions.ACTION_STD_CANCEL)) do
            rb.lcd_clear_display()
            say_value(volume,sec_left .. " Sec, Volume: ", 1)
            local i = seconds * 2
            while ((i > 0) and (action ~= rb.actions.ACTION_STD_CANCEL)) do
                i = i - 1
                rb.lcd_drawline(hb, 1, hb, 1)
                rb.lcd_update()
                if hb >= rb.LCD_WIDTH then
                    hb = 0
                    rb.lcd_clear_display()
                    say_value(volume,sec_left .. " Sec, Volume: ", 1)
                end
                hb = hb + 1
                rb.sleep(rb.HZ / 2)
                action = rb.get_action(rb.contexts.CONTEXT_STD, 0)
                rb.yield()
            end
            volume = volume - 1
            rb.sound_set(SOUND_VOLUME, volume);
            sec_left = sec_left - seconds

        end
        rb.audio_stop()
        rb.lcd_clear_display()
        rb.lcd_update()

        say_msg("Playback Stopped", 5)
        os.exit()

    else
        rb.lcd_clear_display()
        rb.lcd_update()

        say_msg("Nothing is playing", 2)
        os.exit()
    end

--- End code ---

tdb:
Awesome, thanks a lot!

Searching the internet yesterday I found a similar solution someone made for itunes with applescript http://www.jonathanlaliberte.com/2010/03/15/itunes-sleep-timer-with-fade-out-applescript/

Tried your script and added the lua script to my Sleeptimer shortcuts. Works like a charm.

[shortcut]
name: Start Sleep Timer
type: time
data: sleep 25

[shortcut]
name: Stop Sleep Timer
type: time
data: sleep 0

[shortcut]
type: browse
data: /Slow_fade.lua
name: Slow Fade

Will experiment with the script and probably try to optimize the 'fade out curve' a bit to make it work best for me. I think I understand the most important parts of the script so it is very nice to be able to adjust it myself :)

Bilgus:
No Problem, Once you get something awesome post it here for the next guy  :D

tdb:
Hi Bilgus - I have tried the scripts on 3 of my Sansa Clip+ players and work fine but my old Sansa Clip hangs immediately after I start the script.
Has the first Clip some limitations the Clip+ doesn't have? Unfortunately it is the only Clip I have, so I am not able to check on another Clip. Not a big problem. I will also test the script on my e200's and C200 later (I got a bunch of Sansa players :) )

Updated them all to the latest dev build (b772782).

BTW - I am not planning on doing anything fancy with your script. Tested it today a couple of  times and I think the linear volume decrease is just working as gradually as I was hoping for. Maybe only change the default setting from 1 - 5 - 10 - 15 minutes to 10 - 15 - 20. 

Navigation

[0] Message Index

[#] Next page

Go to full version