dev builds
themes manual
device status forums
mailing lists
IRC bugs
dev guide

Rockbox mail archive

Subject: Re: new rockbox playlist format

Re: new rockbox playlist format

From: Ray Lambert <>
Date: Sun, 11 Dec 2005 14:28:49 -0500

Martin Borus wrote:

>These three are needed for this:
>>- loop structure (Example: Loop 20 {pick one random from current hits
>>directory; pick one random from alltimefavorites-playlist } )
>>Your example might be implemented as such:
>> ! config shuffle: on
>> ! match recursive shuffle count=20 /current-hits
>> ! match shuffle count=20 /playlists/alltimefavorites.m3u
>Will this make sure that no two current hits get played in a row?
Martin, I read the thread you referenced and I understand a little
better now what you're trying to accomplish.

To answer your question: no, my example will not do exactly what you
want. It's probably the next best thing, but it will not prevent two
categories from being played in a row.

At the moment, the only method I can think of to do what you're asking
for is some variation on the loop that you described earlier. The
problem with this method is that it would be fairly difficult to do with
limited resources on the rockbox. Implementing that on a PC would be
much easier, as you would have much more memory to work with (and
virtual memory to boot). You could simply cache the contents of each
referenced playlist in memory and track what the next song to be
selected is. It would not be possible to implement it this way on the
rockbox though.

I have come up with a method however, that might work and might be
fairly easy enough to implement. The concept involves the creation of
'groups', which are essentially temporary sub-playlists with contents
selected from one or more sources. These would be stored in temporary
files and the next song to be selected is tracked using a file offset.
Doing this with disk files is, of course, a bit slower, but I suspect
that's a price that you wouldn't mind paying to get this functionality.

Anyway, I'll first describe the changes to the .BOX spec and then show
an example.

First, I've decided to merge the "! match" and "! select" directives,
seeing as I was never certain they needed to be separate anyway and
merging them may make it easier to share code between them (and is also
probably less confusing to users). I'll dump "! match". Database
queries now use "! select query <db-query>". Disk/playlist queries will
now use "! select filesystem" and "! select playlist" directives
(respectively) a separate "pattern=<regexp>" in order to avoid any
ambiguity about what constitutes a pattern as well as avoiding the
awkward syntax that would have been required to use a regexp with a
playlist (which would have been something like:
/subdir/playlist.m3u/pattern"). I've also dropped the "shuffle" option
because it doesn't appear to be useful. Lastly, I'm adding a "! select
group" directive (more below).

Next, I'll introduce 'blocks' which are delineated with "! begin" and "!
end" directives. They'll be used to define groups and implement
looping. Groups are defined with the "group" keyword, as such:

  ! begin group hits [shuffle] [keep filename=hits.m3u]
  ! select
  ! end

...where "hits" is the group name (which can be referenced elsewhere
within the .BOX); "shuffle" directs the final group contents to be
randomized; "keep" is an option that directs the temporary playlist to
be preserved after executing the .BOX (by default temporary playlists
are deleted); and "filename=" specifies the filename to 'keep'. The
contents of the group can be defined using any song selection mechanism.

Once you've defined your groups, you use a loop to build the playlist.
I'll support one loop construct initially which repeats a fixed number
of times (n), written as such:

  ! begin repeat <n>
  ! end

Within this loop you can then use "! select group <group-name> [next]
[count=n]" directives to generate output; where the "next" option
selects the next unused song in the group and "count=n" directs (n)
songs total to be selected (default = 1).

So, here's a simple example to achieve what you're trying to do:

  ! begin group hits shuffle
  ! select /subdir/hits.m3u
  ! end

  ! begin group oldies shuffle
  ! select /subdir/oldies.m3u
  ! end

  ! begin repeat 500
  ! select group hits next
  ! select group oldies next count=2
  ! end

So, using your notation, if the hits group is A and the oldies group is
B, this generates a sequence of A B B repeated 500 times. Each song
selection from each group will be random with no repeats.

The functional aspect of the group construct allows me to formally
set-up the proper caching and tracking mechanism for each group. It
also provides a more powerful interface for the user seeing as each
group can be assembled from multiple sources using multiple selection
mechanisms (thus, this isn't just a matter of forcing the user to do
some of the work of the computer).

Note that the repeat block can also use any song selection mechanism in
addition to (or instead of) the 'select group' that is shown in this
example. You can also get rockbox to shuffle the entire final result
using "! config shuffle: on".

I suspect that this grouping mechanism will only see narrow and somewhat
rare use (except for you, of course!) and, although it does represent a
bit of extra work, I don't think it's that bad because the ability to
construct and process temporary sub-playlists is really the core
functionality of all the select commands anyway. The only difference
really (besides the parsing) is keeping track of the groups and
remembering the next song to be drawn from each (this is done with just
a file position; I can even close the file between accesses if I need to).

So, what do you think about that?

Also, I'd like to encourage everyone again to submit your thoughts on this.


PS: Lastly, here's version 3 of the .BOX spec:

Proposed Rockbox Playlist Format (version 3):

    - filename extension: .BOX

    - # comment

    - ! config config-statement[; config-statement]

    - ! config load <any config file>

    - ! include /path/playlist<.BOX|.M3U>

    - [/][path/][filename.ext]

    - ! begin group <group-name> [shuffle] [keep filename=<filename.m3u>]
    - ! end

    - ! begin repeat <number_of_iterations>
    - ! end

    - ! select filesystem /path/dirname [recursive] [count=n]

    - ! select playlist /path/dirname/<playlist.m3u> [count=n]

    - ! select query <db-query-TBD> [count=n]

    - ! select group <group-name> [next] [count=n] [pattern=<regexp>]

    - ! filename <playlist.m3u>

    - ! generate-only

    - ! auto-cleanup

    - ! windows-drive-letter <A-Z>


    - The 'shuffle' option on the '! begin group' directive
      causes the resulting group to be randomized. To randomize
      the entire final playlist use the shuffle config option:
      "! config shuffle: on".

    - The 'keep' option on the '! begin group' directive causes
      the temporary playlist file to be preserved. The
      'filename=' option specifies the name of this file. By
      default, these files are deleted.

    - The 'count=n' option on the various 'select' directives
      causes the resulting list of songs to be truncated to 'n'
      number of songs.

    - 'filename' is used to override the default output (M3U)
      file name, which is derived from the .BOX file name

    - 'generate-only' tells the .BOX player to only generate an
      M3U and not to play it.

    - 'auto-cleanup' tells the .BOX player to automatically delete
      the generated M3U file when it finishes playing. (This may
      prove difficult or impossible to implement.)

    - 'windows-drive-letter' indicates which drive letter to write
      to the M3U file. Default is none.

 "The music business is a cruel and shallow money trench, a long
 plastic hallway where thieves and pimps run free, and good men
 die like dogs ....... There's also a negative side."
   -- Hunter S. Thompson
Received on 2005-12-11

Page template was last modified "Tue Sep 7 00:00:02 2021" The Rockbox Crew -- Privacy Policy