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