Proposal: generalize playlist concept

Pavel Shved pavel.shved at gmail.com
Sun Jan 11 02:34:07 UTC 2009


Hi.

This proposal is quite long and even divided into sections.  It is hard
to explain what i mean without working prototype but after my attempts
to implement it i realized that i can't do it all alone.  So, instead of
prototype, you get a long description.

I tried to be more comprehensive instead of being shorter.  Sorry, but i
don't see any way to shorten my proposal but to skip section 0 and stop
reading after section 3 or 4.


0. DISCLAIMER

Sorry again, i only started trying to contribute to amarok a couple of
weeks ago, so i dont know whether this proposal is new to amarok's pile
of proposals. I also don't know whether some kind of this was
implemented in other music players so please, let me refer to is as to a
`new' feature, can i? :-)

If such proposal has already been encountered then i hope i contributed
someting to it at least.

It was inspired by dynamic playlist.  After i saw dynamic playlists, i
first thought you will do it the way i propose, but, after i saw queue
implementation, i realized that it was wrong, thinking that.


1. PROBLEM

I would like to start description from the problem, but it so happens
that there's no problem. :-)  It's just an improvement, uncommon and
unclear to users (when described verbally), but the end result may occur
nice.

Okay, here's my view.

The thing is that playlist in modern music players utilizes two
functions at once:

a) keep manually selected (with automatic filling capabilities, such as
`add directory', `drag from collection') array of tracks; and

b) visualize iteration over that playlist with selection of one track,
queue markers etc.

Time passes and ways of iterating through the playlist keeps improving
from straightforward track-by-track playing: random movement, queuing
and dynamic appending tracks to it (called in Amarok dynamic playlist).

But what is the playlist: an array (random-access), a list, a stream or
a set?  The playlist container switches its nature when different type
of iteration is selected.

I can't call it a problem, but i can definitely say that the lack of
logic means that something can be improved.

2. PROPOSAL

I noticed one thing.  Whatever track picking procedure we use, the
result of it is a mere `stream' of tracks being picked from playlist,
collection -- i.e. from lists that utilize (a) concept.  If we start
writing tracks, that are actually played, in a list, we will get a
simple playlist (possibly infinite) which contents are played consequently.

If something utilizes (a) concept, it shouldn't necessarily utilize (b)
concept: colleciton, for example, can't be iterated through (in amarok
2.0, and it's right!).  We call such objects a `set' (of tracks).  Of
course, if something utilizes both (like usual playlist with
straightforward iteration)

Let's call such stream a `generalized playlist' (in order not to mix
with radio streams etc.).  It contains manually selected tracks (like
usual playlist) along with special tracks (i'll call them `factories').
  The factories feed the gen.playlist with new tracks when the iterator
meets them.

The tracks being fed are selected, according to the rules the factory
comprise (they may be different), from a set or, if the rules allow,
from another genlist.

After factory has produced all tracks it should, it disappears from
genlist and the iterator proceeds to (generalized) tracks after it.

(for those who's involved in development, more simple terms.
Generalized playlist is a playlist where all tracks are
PlaylistNavigators, some of which yield one item (alias for usual Track)).

`Ah, just a geeky feature', you say, `most users do not need playlist
programming'.  And you are right.  But in this model simple tasks can be
simply achieved and nicely visualized.  The following section tries to
convince you in it.


3. EXISTING FEATURES IN NEW TERMS

All iteration features currently provided by amarok are generalized by
the genlist concept and have better visual representation.  Check it out:

  *  Usual consequent playlist.
     A marker that just iterates playlist consequently is added into
invisible genlist.  Playlist window still contains plain old playlist.
All usual playlist operations are supported but playing silently affects
genlist.

  *  Random iteration over playlist.
     A genlist contains factory that is tuned to randomly select tracks
from other list.  A tiny genlist appears in the topright corner of
the screen which will show--like in tetris game--the next track that
will be played after it.

  *  Queueing tracks in random playlist.
     A track is simply dragged from main playlist to genlist, right after
the track currentlry played.  Genlist will first iterate to the enqueued
track and then proceed to factory which will keep yielding random tracks.
     IMHO that's a much better visualization and interface for queue than
the numbers near playlist entries.

  *  Dynamic playlist
     That's also simple: dynamic playlist by its nature is a genlist with
one factory that contains biased rules.  A new bias can be introduced:
you can select 50% of tracks from entire collection (1st bias) and 50%
from the main playlist (2nd bias).  Geeks can use the secret feature and
add a generalized item to main playlist which will allow construction of
complex biases without any additional coding.

  *  Repeat on/off
     That merely affects whether factory produces infinite number of
tracks or memorizes its choices (as RandomTrackNavigator does).

  *  Stop after...
     A factory that looks like `POLICE LINE - DO NOT CROSS' is inserted
to genlist via context menu and may be dragged.  It yields no track and
makes playing stop upon iterator reaches it.


4. NEW FEATURES THE CONCEPT PROVIDES

Not only expresses the genlist old features better, but it also
introduces more interesting features

  *  Several playlists support
     Now playlist is not a singleton -- i.e. there can be more than one
playlist that only contains tracks but isn't iterated through (i'll
remind, that's called a `set' in this document).  Only main genlist is a
singleton.  A special factory that iterates the playlist in its native
order is used to implement it.

  *  Advanced mixing with dynamic playlists
     I sometimes miss feature that allows me to apply dynamic playlist
rule to manually picked set of tracks that can't be expressed in bias
terms.  That's one feature.
     Another feature was already mentioned - mixing different playlists
into one.  That's called `party mode' in other proposals.  Several sets
contain manually selected tracks or even factories, one set per user.
These sets are mixed proportionally into main genlist via factory that
implements dynamic playlist.

Too few?  Well, these govern at least one separate proposal.  And more
importantly, simple and sound (i.e. `non-contradictive') rules allow
programmers to _discover_ new features and implement it with little
effort.  Vice versa, my experience shows that if feature is useful and
sound it also fits a good logical system.


5. HOW IT AFFECTS GUI

Screenshots would be nice, but i didn't fake them  If your responce show
that i failed to explain my thoughts, i'll paint them and post scans
and/or implement genlist class hierarchy and show a little prototype.

So the playlist windown in meantime looks like a usual playlist.  It's a
genlist, but it looks like playlist.  Bottom bat provides factories that
can be dragged into it.

Old-style mode switching (turning on `random' or `dynamic' or `repeat')
splits a window into two, where the upper one is our generalized
playlist is set according to one of patterns described in section 3.
And all tracks are copied into the bottom genlist (if necessary).

Sometimes (when `repeat' is turned on) it's not necesary to even show
the genlist, but just to keep in invisible and play tracks from it.

Interaction with a set (double-click) that's not a main genlist just
appends track to genlist after the one being played and causes
triggering of `next' pressing.

Several playlists are implemented as tabbed view. Main genlist isn't
tabbed -- it's a singletone.  The tab currently selected is a current
playlist. It is the current playlist, into which tracks are inserted
when user drags them from collection to specific zone of central widget.

Many other special cases are all governed with GENERAL RULE:  one main
genlist, that handles pressing of NEXT and PREV buttons; it is shown on
demand only or when user triggers some of the patterns in section 3.
And several other genlists inside a tabbed view.


6. HOW IT CAN BE IMPLEMENTED

I examined amarok source code and didn't find severe restrictions that
would prevent it from being patched properly.  First, a working model of
  factories and genlists must be implemented and tested in separate
application.  Then it must be imbued into playlist model, overriding
Item class with GeneralizedItem.

A new widget that draws factories must be created and the toolbar to add
them to playlist are needed.

All playlist management features like dragging, highliting of current
tracks are implemented already).  A bias editor for factories is already
implemented, it's just needed to add some features into it.

The most complex thing to do is desingletonization of PlaylistModel
class.   I think it was created as singleton but developers errorneously
used it as singleton even in cases where it's not required (the most
obvious case is using Model::instance() in TrackNavigators instead of
passing the reference to model to navigator's constructor).

What else?  Uhm, if i missed something, it's not that big i suppose.

Some key concepts will be touched, though i think that it's possible to
keep source compatibility.  More careful study needed but ---
implementation question should arise after design ones anyway.


7. WHY I WROTE IT?

I was going to implement it on my own, but first i'd love to know
whether you like the idea.  After i wrote some code i realized that the
amount of work is too big to risk that you won't accept it. :-)


Whith hope you'll reach this line,

Pavel Shved
<pavel.shved at gmail.com>.



More information about the Amarok mailing list