Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: Shuffle better (a problem/partial proposal) (Read 1478 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Shuffle better (a problem/partial proposal)

This is basically a continuation of the topic odyssey began last month in this thread. I think I have a solution, but I'd need assistance from someone with better code writing skills than mine.

The problem is that shuffling/randomizing algorithms are extremely poor at dealing with media libraries that include high numbers of albums and tracks by a small number of artists.  They get locked into a cycle of randomly selecting a title from a playlist to play, and then repeating the process over and over (tho' it's nice that FB2K does make sure none are repeated). 

I love to set a playlist with my entire library to shuffle and play tracks.  But inevitably I end up hearing the artists with the most albums and titles over and over.  This has frustrated me in media players since Winamp v1.x way back.

What I'd like to see is an algorithm that doesn't repeat playing titles by one artist until one title from every other artist on a playlist has been played.  This was touched on by odyssey, Flappyraccoon, and rouge in a short thread back in 2006 where it was suggested that the FB2K SDK at the time would prohibit writing code that could address the issue.  And that it would require Foosion to make the necessary SDK changes. 

I'm still struggling with basic FB2K title formatting, and am not familiar with the FB2K SDK or Visional C++ at all.  I have written some Pearl and WordBasic scripts eons ago, but I really lack familiarity with terms common to the programming community, so my choice of words here will probably sound odd.  Bear with me if you would. 

Here's how I'd like to see a playlist processed.  Maybe someone familiar with the current SDK and writing component code could review this and see if it's feasible:
  • Create variable and set to 0: 'Artist Count'
  • Create variable and set to 0: 'Cycle Count'

    • Count the number of artists and set that value to 'Artist Count' variable.
    • Choose random artist >  choose random album by artist > choose random track from album
    • Flag the artist, flag the album, and flag the track so they can be skipped in the next cycle
    • Play title
    • Increment the 'Cycle Count' variable by 1
    • If 'Cycle Count' ≠ 'Artist Count', restart search and skip all flagged artists
Once ‘'Cycle Count' = 'Artist Count', a track from each artist has been played. At that point all artist and album flags are then cleared, and a 'new' broader cycle is created that repeats until 'Cycle Count' = ‘'Artist Count' again.

If subsequent searches land on a flagged title, the search resets and repeats resetting again and again until it lands on an un-flagged title.

Eventually all titles by one artist will be flagged.  At that point a new 'Exclude Artist' flag can be set.  So even though the artist flag for that one artist will still be cleared in subsequent cycles, with the artist's 'Exclude Artist' flag set, the program will prevent subsequent searches for that artists titles.

When an 'Exclude Artist' flag is set, the 'Artist Count' variable is de-incremented by 1.

As artists are eliminated from the selection process, titles by the same artists are played more frequently.  In the end only tracks by one artist will be left to play.

When the 'Exclude Artist' flag for every artist in the playlist has been set, the program and playback would stop.

I've been trying to sort this all out over the past few days.  Here's the general idea of how I think the code could be written:

Code: [Select]
Variable: 'Artist Count' > Initialized to 0
Variable: 'Cycle Count' > Initialized to 0
Assumed: Some general random search algorithm                
Assumed: Database (Unsure if FB2K SDK will support)

01 Load playlist
02 Parse data from each track into 3 database fields from file metadata: %artist%, %album%
  & %title%
03 Create 4 extra fields in the database to hold flag values for the following:
   * 3 flags fields: 'Artist Flag', 'Album Flag' & 'Title Flag' to be set after each has been
     processed.
   * 1 'Exclude Artist' flag field to be set when all album and titles for given artist have
     been played.
04 Count the number of artists in the playlist and set that value to an 'Artist Count' variable.
05 Run a random search algorithm on the database to select an artist.
06 Check the selected artist's 'Exclude Artist' flag.
07 If the flag is set, de-increment the 'Artist Count' variable by 1 and check the subsequent
   artists in the database sequentially until one is found un-flagged (looping back to top of
   database if necessary)
09 If all 'Exclude Artist' flags are set, goto END
10 Check the 'Artist Flag' for the chosen artist.
11 If flagged, keep going to the next artist in the database until one is found un-flagged.
12 Set the 'Artist Flag' to indicate its having been chosen.
13 After random artist selection, run a similar random search to select an album by that artist.
14 Check the 'Album Flag' for the chosen album.
15 If flagged, scan artist's next albums in the database until one is found un-flagged.
16 Set the 'Album Flag' to indicate its having been chosen.
17 After artist/album selection, run a similar random search to select a title in the album.
18 Check the 'Title Flag' for the chosen title.
19 If flagged, keep going to the album's next titles in the database until one is found un-flagged.
20 If after reaching the end of all of an artist's albums and titles, all have been found to be
   flagged, set the artist's 'Exclude Artist'’flag and goto 05
20 Set the 'Title Flag' to indicate its having been chosen.
21 Play the selected title
22 Increment a 'Cycle Count' variable by 1 from an initial default of 0.  
23 Compare the 'Cycle Count' variable to the 'Artist Count' variable.
24 If 'Cycle Count' is ≠ 'Artist Count', goto 05 and repeat artist/album/title search.
25 If 'Cycle Count' is = 'Artist Count', reset 'Cycle Count' to 0
26 Clear all artist and album flags and goto 05
END Halt Program

Towards the end of the process, this will result in playing more and more titles by the same artist as the pools of titles from other artists are depleted.  It would be possible to introduce an option to start replaying titles at a specified point.  For very long playlists, the repetition wouldn’t be as noticeable.

If playback is stopped before all playlist titles have been played, an option could also be set to create a ‘bookmark’ where playback was stopped.  Play could then be resumed where it left off in the last session.  If there’s an option to replay titles previously played (as I suggested above), the repetition would hardly be noticed for large playlists.

The code could be extended to add support for considering track length, date, genre, rating, as well as adding options for each, and options to set a level of priority for each as I've read about in the thread about foo_random_pools.

If this can't be supported from within FB2K, it would seem simple enough to write to a program to process and create replacement M3U files externally.  Then FB2K could just import the newly created M3U.

I'm uncertain/unfamiliar with how database can be set up and parsed in this manner.  Hopefully someone with a lot of coding experience can sort that out, or tell me if what I'm proposing here just isn't feasible.

Thanks for any interest.

TS

EDIT: I see an issue where 'Artist [Album Name] Count'’and 'Cycle [Album Name] Count' variables would have to be added if I wanted to prevent titles from the same album from being selected for play before titles from any given artists other albums are played..
Geopoliticus Child Watching the Birth of the New Man