Rockbox Technical Forums
Support and General Use => Audio Playback, Database and Playlists => Topic started by: aaronamm on November 18, 2021, 12:38:49 AM
-
Hello everyone.
I want to use my iRiver iHP120 with Rockbox as a music source for recording MD discs.
The problem is an MD player needs at least 2 seconds of silence before starting a new song to create an auto-tracking correctly.
However, I could not find any existing setting or plugin to create at least two seconds gap between each song when playing with Rockbox.
Therefore, please could you suggest to me how to configure Rockbox, an existing plugin, or an idea to develop a plugin/code example to delay the amount of time before starting a new song.
Thank you so much.
-
You could fake it with a playlist that had a bunch of short silent tracks between real tracks or else write your own plugin to add a pause between tracks, but I don't think there is a built in way to do this.
Also recording MD? What year is it :)
-
Hello @saratoga
Thanks for your suggestion. It is a nice tip. However, I only wonder if we have a way to automate a process.
I would be glad if you could point me to a code example which controls/interrupts playing of a song.
Then I can use it in a custom plugin code.
Thank you.
-
https://github.com/Rockbox/rockbox/blob/master/apps/plugins/lua_scripts/playback.lua#L352
this should get you started..
local function create_playlist(startdir, file_search, maxfiles)
--In lua you can define a function (locally) within another function
--find file function is passed to the get_files() fn
-- it allows us to do things with the match (accept or reject)
function f_filedir_(name)
if name:len() <= 2 and (name == "." or name == "..") then
return false --reject
end
if name:find(file_search) ~= nil then
maxfiles = maxfiles -1
if maxfiles < 1 then
action_set_quit(true)
return true
end
return true --accept
else
return false --reject
end
end
local norecurse = false -- don't enter subdirs
local f_finddir = nil
local f_findfile = f_filedir_
local files = {}
local dirs = {}
local max_depth = 3
dirs, files = get_files(startdir, norecurse, f_finddir, f_findfile, nil, max_depth, dirs, files)
if #files > 0 then
-- rb.audio("stop") -- for the pb example
rb.playlist("create", scrpath .. "/", "playback.m3u8")
end
for i = 1, #files do
if(i > 1) then
rb.playlist("insert_track", "/yourtransition_file.mp3" or "?") -- might need to check if exist first...
end
rb.playlist("insert_track", string.match(files[i], "[^;]+") or "?")
end
if #files > 0 then
rb.playlist("start", 0, 0, 0) --start playing it
end
for i=1, #dirs do dirs[i] = nil end -- empty table
for i=1, #files do files[i] = nil end -- empty table
--action_set_quit(false) -- for the pb example
end -- create_playlist
-
@Bilgus
Thanks for your code example, I appreciate it.
This must be fun but it haven't done with Lua script before.
It's time for me to start learning Lua.
Thanks.
-
@Bilgus
I have tried your code but I wonder if can solve a problem without a playlist with silent/transition song.
I tested the following code block but it doesn't show any message when playing a music.
function playback_event(id, event_data)
rb.splash(0, id)
rb.sleep(5 * rb.HZ)
end
local evp = rockev.register("playback", playback_event)
Could you please give me a code block to register an event when playing a music?
Here is my idea:
function playback_event(id, event_data)
-- if ending track event fired, pause playing for 2 seconds.
end
local evp = rockev.register("playback", playback_event)
Thank you.
-
Hey thats a pretty good plan!
The issue is that you need to keep the script running to process the events
you can increase the sleep to save power at the cost of waiting longer when you go to exit
here is the basic framework of what you are looking for
require("actions")
local evt -- Timer handle
function playback_event(id, event_data)
if id == rb.PLAYBACK_EVENT_CUR_TRACK_READY then
rb.splash(0, "Track Ready")
elseif id == rb.PLAYBACK_EVENT_TRACK_SKIP then
rb.splash(0, "Track Skip")
elseif id == rb.PLAYBACK_EVENT_TRACK_BUFFER then
rb.splash(0, "Track Buffered")
elseif id == rb.PLAYBACK_EVENT_TRACK_CHANGE then
rb.splash(0, "Track Change")
rb.audio("pause")
evt = rockev.register("timer", tmr_function, rb.HZ * 2)
elseif id == rb.PLAYBACK_EVENT_START_PLAYBACK then
rb.splash(0, "Start Playback")
elseif id == rb.PLAYBACK_EVENT_TRACK_FINISH then
rb.splash(0, "Track Finished")
elseif id == rb.PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE then
rb.splash(0, "Next Track Id3 Available")
else
rb.splash(0, "unknown id " .. id)
end
end
function tmr_function(id, data)
rockev.unregister(evt) -- remove timer
rb.audio("resume")
rb.splash(rb.HZ * 2, "Timer Fired")
rb.lcd_clear_display()
rb.lcd_update()
rb.splash(0, "Waiting...")
end
do
local act = rb.actions
local quit = false
function action_event(action)
local event
if action == act.PLA_EXIT or action == act.PLA_CANCEL then
quit = true
end
end
function action_set_quit(bQuit)
quit = bQuit
end
function action_quit()
return quit
end
end
local function main()
local TRACK_CHANGE = 16
local TRACK_BUFFER = 2
local eva = rockev.register("action", action_event)
--local evp = rockev.register("playback", playback_event)
--local evp = rockev.register("playback", playback_event, bit.bor(TRACK_CHANGE, TRACK_BUFFER ))
local evp = rockev.register("playback", playback_event, TRACK_CHANGE)
rb.lcd_clear_display()
rb.lcd_update()
rb.splash(0, "Waiting...")
while not action_quit() do
rb.sleep(rb.HZ / 2)
end
rb.splash(100, "Goodbye")
end
main()
my concern would be that sometimes you might get an event too late and the next song has started playing then paused for 2 seconds
you might be able to use the buffer event but thats probably too early..
-
if you do have issues you could probably set Single Mode _> Track and then it will auto pause after every track unconditionally and the script will resume it
Settings>Playback Settings>Single Mode>Track
-
Here is a version that sets single mode when started and restores the previous playback mode on exit
Works Well!
require("actions")
require("settings")
-- Functions for reading / writing settings
local var = {offset = 1, size = 2, type = 3, fields = 3}
local function get_var_fields(s_var)
-- converts member string into table
-- var = {offset, size, "type"}
s_var = s_var or ""
local o, s, t = string.match(s_var, "(0x%x+),%s*(%d+),%s*(.+)")
local tvar = {o, s, t}
return #tvar == var.fields and tvar or nil
end
local function bytesLE_n(str)
str = str or ""
local tbyte={str:byte(1, -1)}
local bpos, num = 1, 0
for k = 1,#tbyte do -- (k = #t, 1, -1 for BE)
num = num + tbyte[k] * bpos
bpos = bpos * 256 --1<<8
end
return num
end
--
local evt -- Timer handle
function playback_event(id, event_data)
if id == rb.PLAYBACK_EVENT_CUR_TRACK_READY then
rb.splash(0, "Track Ready")
elseif id == rb.PLAYBACK_EVENT_TRACK_SKIP then
rb.splash(0, "Track Skip")
elseif id == rb.PLAYBACK_EVENT_TRACK_BUFFER then
rb.splash(0, "Track Buffered")
elseif id == rb.PLAYBACK_EVENT_TRACK_CHANGE then
rb.splash(0, "Track Change")
--rb.audio("pause")
evt = rockev.register("timer", tmr_function, rb.HZ * 2)
elseif id == rb.PLAYBACK_EVENT_START_PLAYBACK then
rb.splash(0, "Start Playback")
elseif id == rb.PLAYBACK_EVENT_TRACK_FINISH then
rb.splash(0, "Track Finished")
elseif id == rb.PLAYBACK_EVENT_NEXTTRACKID3_AVAILABLE then
rb.splash(0, "Next Track Id3 Available")
else
rb.splash(0, "unknown id " .. id)
end
end
function tmr_function(id, data)
rockev.unregister(evt) -- remove timer
rb.audio("resume")
rb.splash(rb.HZ * 2, "Timer Fired")
rb.lcd_clear_display()
rb.lcd_update()
rb.splash(0, "Waiting...")
end
do
local act = rb.actions
local quit = false
function action_event(action)
local event
if action == act.PLA_EXIT or action == act.PLA_CANCEL then
quit = true
end
end
function action_set_quit(bQuit)
quit = bQuit
end
function action_quit()
return quit
end
end
local function main()
local pbmode = nil;
local tvar = get_var_fields(rb.system.global_settings.single_mode)
local voffset, vsize, vtype = tvar[var.offset], tvar[var.size], tvar[var.type]
if (tvar ~= nil) then
local singlemode = 1
pbmode = bytesLE_n(rb.global_settings(voffset, vsize))
if (pbmode ~= nil and pbmode >= 0) then
-- set single mode
rb.global_settings(voffset, vsize, singlemode)
end
end
local TRACK_CHANGE = 16
local TRACK_BUFFER = 2
local eva = rockev.register("action", action_event)
local evp = rockev.register("playback", playback_event, TRACK_CHANGE)
rb.lcd_clear_display()
rb.lcd_update()
rb.splash(0, "Waiting...")
while not action_quit() do
rb.sleep(rb.HZ / 2)
end
--restore pbmode
if (pbmode ~= nil and pbmode >= 0) then
rb.global_settings(voffset, vsize, pbmode)
end
rb.splash(100, "Goodbye")
end
main()
-
@Bilgus
Thank you so much for a working Lua script.
It is very useful and works as I expected.
I have tested with my iRiver iHP120 and it worked like a charm.
Really appreciate your help.
-
@Bilgus
I have created a new Gist for syntax highlight and add credit message to you at the top of the script.
https://gist.github.com/aaronamm/41dbf6f46ea3063e383666cda8f0d998
Thanks again.
-
@aaronamm I'm glad it worked for you!