Rework the shuffle system to randomize playlist order instead of play index.
The previous shuffle behaviour was to jump to a new track with std::rand()
on every next track.
The new shuffle behaviour is:
- Tracks are always played in the playlist order.
- When shuffle is turned on, the playlist order is randomized once.
- If shuffle is on when "Play All" or "Append All" are used, the new tracks are randomized separately.
This fixes several issues:
- Previously, shuffle wasn't actually random, as it used the same seed every time. (Closes #45 (closed).)
- Previously, enabling shuffle broke the "Queue" feature, since the track would just jump around anyway. (Closes #46 (closed).)
- Previously, "Play All" would always create the exact same playlist order even if shuffle is on, and start at the top. While not a huge issue, always hearing the same default song at the start does get annoying.
- Previously, "Previous Track" was unaffected by/didn't make sense with shuffle. It just jumped to
i-1
, which is meaningless with shuffle on and not the inverse operation of "Next Track".
On my machine, reshuffling a playlist of over 2,000 tracks takes around 0.3 seconds in Playlist::shuffleRange
, of which around two thirds of the time is looped calls to m_model->update(track, i++)
. Visually, the UI pause feel like slightly more than that (maybe closer to 0.5s).
Overall, I think keeping a stable play order brings more benefits than drawbacks.
Due to the lack of an obvious canonical sort order, currently disabling shuffle does not undo the previous randomization of the playlist.