rockbox/firmware/test/wavey/README.playlists

85 lines
3.5 KiB
Text
Raw Normal View History

Playlists on the Rockbox
1. Demand-loading of Playlist Filenames from Disk
A playlist is simply a list of track names. These lists can either be
created dynamically by the user, or they can be predefined and placed
into a text file with an .m3u extension.
The 2048 KB of RAM is the reason we need to get this right. If an average
track name (i.e. \music\cure\disintegration\01-pictures_of_you.mp3)
is assumed to be 50 characters long, then:
A playlist of 15 tracks is 15 * 50 ~= 750 bytes
A playlist of 100 tracks is 100 * 50 ~= 5 kilobytes
A playlist of 3500 tracks is 3500 * 50 ~= 175 kilobytes
A playlist of 10000 tracks is 10000 * 50 ~= 1/4 megabyte
From these figures, it can be seen that for large playlists, storing
the entire list of track names in memory significantly reduces the
capacity available to the audio data buffer, which in turn has a negative
impact on the performance of the system.
One method of reducing the total memory consumption of a playlist is
to delay bringing the actual filenames into memory until needed. Instead,
the playlist text file can be scanned, and an in-memory array constructed
with one element for each track present in the text file. Progressing
through the playlist entails getting the appropriate entry from the array,
and using that to perform a lookup of the corresponding filename entry
from the playlist text file.
With this method, and given that an integer on the Rockbox's CPU is 4 bytes:
A playlist of 15 tracks is 15 * 4 ~= 60 bytes
A playlist of 100 tracks is 100 * 4 ~= 400 bytes
A playlist of 3500 tracks is 3500 * 4 ~= 13 kilobytes
A playlist of 10000 tracks is 10000 * 4 ~= 39 kilobytes
It is clear that these are substantial savings, albeit at the cost of
increased complexity and disk i/o. Prefetch strategies could improve
performance compared to demand-loading a single entry.
2. Implementation Options
Keeping the track names in a file on disk is easy enough for a predefined
m3u playlist, but for dynamically created playlists, where the user
browses the filesystem and adds tracks or entire directory hierarchies
at will, we will need to store the playlist track names in a dedicated
file. This will be called the Anonymous Playlist, the location of which
can be set by the user, but will default to \anonymous.m3u or somesuch.
The current contents of the Anonymous Playlist can be named and saved at
any time.
The data structure to support playlists would therefore be:
typedef struct
{
char filename[256] ; /* path name of m3u playlist on disk */
int *indices; /* array of indices into the playlist */
int index; /* index of current track within playlist */
} playlist_info_t;
So far, so good: we read from an existing m3u file, or we create an
anonymous one. But what do we do if we start with an existing m3u file,
and then the user wants to dynamically add tracks to it? A few options
exist:
a) we disallow playlist modification of existing m3u files, offering
instead to replace the current playlist with the new one.
b) we give the user the option of appending the new tracks to the
existing m3u file.
c) we copy the contents of the existing m3u playlist to the anonymous one,
and then append the new tracks to that. If the m3u playlist is large,
this could be wasteful and potentially time-consuming. However, choosing
this option would provide the facility to insert or append entire
existing m3u playlists 'into' one another, a feature missng from the
commercial firmware.