From Amarok Wiki
Contents |
Dynamic Playlists
We all agreed that the current Dynamic Playlist system is broken. It is not fundamentally broken because the UI is impossible to use, but rather fundamentally broken because it does not behave as the UI says it will. The user doesn't know what will happen, even though he gives meticulous commands to control the playlist compositon.
Frontend
This whiteboard is mostly useless and confusing. The only relevant part of this whiteboard is the "no percentages" line. In order to remove confusion, the slider bars in the new Dynamic Playlists UI should *not* have a percentage marking. Rather, they are only relative. Moving a slider to the left means "less of something" and moving it to the right will mean "more of something". The default position for the sliders will be right in the middle (which is the neutral position).
After discussing various ideas, we decided to keep the current UI (for the most part), but refactor the backend to actually work as advertised. Below are some sample use cases that we took into consideration:
The use-case list on the left is a sample of what we want to be possible with the new system. It is a good list of keep in mind---it is easy to design a system that makes more or more of these items impossible. The same UI should be able to be used to fit any of those cases. The system we have tried to design allows users to complete all of these tasks easily.
The main features of the new system:
- New UI will have sliders *with no percentages marked*
- Sliders will default to 50%, the left end will be marked "less", and the right end will be marked "more" (or some such words)
- Users will then "influence" the playlist by asking for more or less of each particular bias
- This allows a user to exclude a value as well.
This would look something like this: (ignore the summation, not relevant).
so this whiteboard shows a sample list of biases that the user has added. the last slider is *always* Random, and *always* exists. this lets the user control "how many random tracks he wants to put in the playlist---if it wants to exclude any random tracks and just allow tracks that fulfill one of the other conditions, he can slide the random slider all the way to the left.
the labels on each end of the slider are WRONG. we don't want to put [0] at the start and [100] at the end. remember, no percentages. rather, the labels would be more like "less" and "more".
Backend
What really needs to be overhauled, however, is the backend. Currently, as I have explained a few times to different people, each bias is completely independent---so it acts in ways that are completely unintuitive. If you have a 50% Jazz and 50% rock, you get some jazz, some rock, and some random tracks. So, we need a better system. Here is what we came up with.
1) There are 2 main types of biases:
- Modifiers (biases that modify the selection, e.g. similar artists, "hotness", "stuff i want to listen to", etc.
- Generators (modifiers that produce tracks)
- Scorers (modifiers that are value-based, hotness, popular, etc)
- Selectors (Meta:: fields, basically, so artist/album/genre/etc)
The types of biases are completely hidden from the user. From the user's point of view, a bias is a bias. But behind the scenes, it matters a lot which biases the user has added.
If the user has NOT added any modifier biases, the process is simple, and proceeds as follows:
The first step in the algorithm is always normalizing the biases. Although the user doesn't see any percentage markings in the sliders, the value of each slider is between 0 and 100 internally. So we need to convert all the biases to add up to 100. The numbers in parenthesis are the share of 10 tracks that each bias has. This assumes that each "run" of the bias solver generates 10 tracks, but that is just an assumption to make our description simpler. Any number (user-configurable) will be possible, and the code can use any number of tracks transparently.
Anyway, now we have a list of biases, and each has a number of tracks (X) that it needs. We go through each bias, and select X number of tracks from it. Repeat this for each bias.
Now we should have 10 (or the user-selected number) of tracks. This is the generated playlist! Nothing more needs to be done. We put the results into a cache, and can populate the playlist.
However, if there are any modifiers, the process is more complicated. For each Scorer bias, the following happens:
if the user has added a bias that is a Scorer bias (for example, "play more popular artists"), the process is different. A scorer bias assigns some value to a track---it can't generate tracks on its own, but it can rank a given tracklist and return some value (this is how Normal/Fuzzy biases currently work in the existing system).
What is required is a short iteration of a simulated annealing algorithm (http://en.wikipedia.org/wiki/Simulated_annealing). We want to maximize the "score" of a playlist. the scorer biases will give us the score value we are trying to maximize.
First, we run the algorithm that is described above. This will generate a cache of tracks that fit the Selector biases that the user has added.
1) Take (for example) 10 tracks from the generated cache. Run them through the Scorer biases, and get a score out.
2) Randomly insert <10 tracks from the generated cache, run them through the bias, and see if the score is higher or not. If it is higher, replace 10-track list with new list. If not, discard.
3) Repeat.
Do the above algorithm until we are "done"---we need do decide how do tell, maybe after a certain number of repetitions or when the variation between attempts has become very small. Doesn't really matter, can be decided later.
4) Replace generated cache with new tracklist that our algorithm generated.
And for each Generator bias, the following is done:
Here we deal with the case where the user has chosen a "Generator" bias. This is a bias like "Similar Artists" or "Similar Tracks to my playlist". These biases, given some tracks, *generate* new tracks, rather than scoring them. Hence they need a different workflow.
1) Once again, the first step is run, as outlined earlier. This will generate a pool of tracks (we'll call it the "seed") to work from.
2) Now, we pass the pool of tracks generated to each generator bias.
3) We only generate the number of tracks that we need from each bias---that is, given the slider value of the bias that we have normalized.
4) We now have a bunch of tracks (the pool). We combine the pool with the seed in the proper ratio (that the user has selected).
and, all done!.
UI Mockup
I've been using dynamic playlist since before using Amarok. I wrote perl scripts for mpd that automatically create playlists years ago. When I started to use Amarok I first didn't understand how the playlists work. I needed to read the code to appreciate how elegant the current design is (except the normal bias which is mostly useless. Who want's to have a playlist with normal distributed years?)
I agree however that even though the current design is cool, no normal user will understand it. So using the requirements above I made a new UI design for dynamic playlists.
The basic principle is that you only ever have one top bias. You can have a combinational bias though which could have sub-biases. Combinational biases are AND, OR and PARTITION (and NOT in principle however that one only can ever have one sub-bias)
The first picture shows a simple dynamic playlist with one normal bias.
The next picture shows the different options for a bias. "Simple match" is the former "normal bias". To fulfill the requirement of "track from around 1966" you can choose the "between" option as shown further below.
I think that this is what most people want. A playlist with one genre or artist. You can also see that the top menu doesn't have the choice between three very similar biases (global, custom and normal) as the current one has.
The next picture shows the NOT bias. Sub-biases are indented a little bit.
If you want something similar to the current global bias you need to select PARTITION and then add sub-biases. PARTITION is dumber than the previous normal bias. It works as described above. Also if one of the sliders is moved then the others one should also move so that the UI makes it clear that all parts together add up to 100%




