Improve EMMS randomness
I sometimes make Emacs play music for me (using emms, org-roam, mpv and YouTube).
When I need a bit of spice, I tell EMMS to play tracks at random. And know what? Sometimes tracks repeat!
I don't like that and since Emacs can change super easily, I opened a scratch buffer and modified EMMS like this:
(defvar emms-random-playlist-seen-indeces nil)
(defun emms-playlist-select-random ()
"Select a random track in the current buffer."
(emms-playlist-ensure-playlist-buffer)
;; FIXME: This is rather inefficient.
(save-excursion
(let ((track-indices nil) next)
(goto-char (point-min))
(emms-walk-tracks
(setq track-indices (cons (point)
track-indices)))
(setq track-indices (vconcat
(seq-difference
track-indices
emms-random-playlist-seen-indeces)))
(if (equal track-indices [])
(progn
(emms-stop)
(setq emms-random-playlist-seen-indeces nil)
(message "Emms; Playlist finished"))
(setq next (aref track-indices
(random (length track-indices))))
(add-to-list 'emms-random-playlist-seen-indeces next)
(emms-playlist-select next)))))
Essentially this just makes EMMS record tracks you have already heard
on random selection (see seq-difference bit). This is good enough
for me and hopefully the EMMS developers will improve the original
function over time.
Happy listening!
P.S.: The diff from the original is:
*** /tmp/ediffN6IKmX Sat Mar 2 23:56:04 2024
--- /tmp/ediffnO7kjS Sat Mar 2 23:56:04 2024
***************
*** 1,13 ****
(defun emms-playlist-select-random ()
"Select a random track in the current buffer."
(emms-playlist-ensure-playlist-buffer)
;; FIXME: This is rather inefficient.
(save-excursion
! (let ((track-indices nil))
(goto-char (point-min))
(emms-walk-tracks
(setq track-indices (cons (point)
track-indices)))
! (setq track-indices (vconcat track-indices))
! (emms-playlist-select (aref track-indices
! (random (length track-indices)))))))
--- 1,25 ----
+ (defvar emms-random-playlist-seen-indeces nil)
+
(defun emms-playlist-select-random ()
"Select a random track in the current buffer."
(emms-playlist-ensure-playlist-buffer)
;; FIXME: This is rather inefficient.
(save-excursion
! (let ((track-indices nil) next)
(goto-char (point-min))
(emms-walk-tracks
(setq track-indices (cons (point)
track-indices)))
! (setq track-indices (vconcat
! (seq-difference
! track-indices
! emms-random-playlist-seen-indeces)))
! (if (equal track-indices [])
! (progn
! (emms-stop)
! (setq emms-random-playlist-seen-indeces nil)
! (message "Emms; Playlist finished"))
! (setq next (aref track-indices
! (random (length track-indices))))
! (add-to-list 'emms-random-playlist-seen-indeces next)
! (emms-playlist-select next)))))
\ No newline at end of file