It's actually playing music.
authorTim Vaughan <timv@ughan.xyz>
Thu, 5 Dec 2019 22:21:36 +0000 (23:21 +0100)
committerTim Vaughan <timv@ughan.xyz>
Thu, 5 Dec 2019 22:21:36 +0000 (23:21 +0100)
emus.el

diff --git a/emus.el b/emus.el
index 616d183..eb3d566 100644 (file)
--- a/emus.el
+++ b/emus.el
@@ -3,7 +3,7 @@
 ;; Author: Tim Vaughan <timv@ughan.xyz>
 ;; Version: 1.0
 ;; Keywords: multimedia
-;; URL: http://github.com/tgvaughan/emus
+;; URL: https://thelambdalab.xyz/emus
 
 ;;; Commentary:
 
@@ -16,7 +16,7 @@
 ;;
 
 (defgroup emus nil
-  "Simple music player for Emacs inspired by CMUS."
+  "Simple music player for Emacs."
   :group 'multimedia)
 
 (defcustom emus-directory "~/Music/"
   "Get all mp3 files in main emus directory."
   (directory-files-recursively emus-directory ".*\\.mp3"))
 
-(defvar emus-tags nil)
+(defvar emus-records nil)
 
-(defun emus-update-tags ()
-  "Get ID3 tags for given filename"
+(defun emus-make-record (filename tagstr)
+  (let ((artist "")
+        (album "")
+        (title ""))
+    (dolist (line (split-string tagstr "\n"))
+      (let ((found-artist (elt (split-string line "@I ID3v2.artist:") 1))
+            (found-album (elt (split-string line "@I ID3v2.album:") 1))
+            (found-title (elt (split-string line "@I ID3v2.title:") 1)))
+        (cond
+         (found-artist (setq artist found-artist))
+         (found-album (setq album found-album))
+         (found-title (setq title found-title)))))
+    (list artist album title filename)))
+
+(defun emus-record-artist (record)
+  (elt record 0))
+
+(defun emus-record-album (record)
+  (elt record 1))
+
+(defun emus-record-title (record)
+  (elt record 2))
+
+(defun emus-record-file (record)
+  (elt record 3))
+
+(defun emus-update-records (then)
   (let ((proc (emus-get-process))
-        (depth 0)
         (tagstr "")
         (filenames (emus-get-audio-files)))
-    (setq emus-tags nil)
+    (setq emus-records nil)
     (set-process-filter proc (lambda (proc string)
                                (setq tagstr (concat tagstr string))
-                               (cond
-                                ((string-suffix-p "}\n" string) (setq depth (- depth 1)))
-                                ((string-suffix-p "{\n" string) (setq depth (+ depth 1))))
-                               (when (and (= depth 0) (string-suffix-p "\n" string))
-                                 (add-to-list 'emus-tags `(,(car filenames) ,tagstr))
+                               (when (string-suffix-p "@P 1\n" string)
+                                 (add-to-list 'emus-records
+                                              (emus-make-record (car filenames)
+                                                                tagstr))
                                  (setq tagstr "")
                                  (setq filenames (cdr filenames))
                                  (if filenames
                                      (emus-send-cmd "lp" (car filenames))
-                                   (set-process-filter proc nil)))))
+                                   (set-process-filter proc nil)
+                                   (funcall then)))))
     (emus-send-cmd "lp" (car filenames))))
 
+;;; mpg123 process
+;;
+
+(defvar emus-proc-in-use nil)
+
 (defun emus-get-process ()
   "Return current or new mpg123 process."
   (let* ((emus-process-raw (get-process "emus-process"))
                         (seq-reduce (lambda (s1 s2) (concat s1 " " s2)) args cmd)
                         "\n")))
 
+;;; Playback
+;;
+
+(defvar emus-currently-playing nil)
+
+(defun emus-play-record (record)
+  (setq emus-currently-playing record)
+  (emus-send-cmd "l" (emus-record-file record)))
+
+(defun emus-stop ()
+  (interactive)
+  (emus-send-cmd "s")
+  (setq emus-currently-playing nil))
+
+(defun emus-playpause ()
+  (interactive)
+  (emus-send-cmd "p"))
+
+
+(defun emus-volume (pct)
+  (emus-send-cmd "v" (number-to-string pct)))
+
+(defvar emus-current-volume 10)
+
+(defun emus-volume-delta (delta)
+  (setq emus-current-volume (max 0 (min 100 (+ emus-current-volume delta))))
+  (emus-volume emus-current-volume))
+
+(defun emus-volume-up ()
+  (interactive)
+  (emus-volume-delta 10))
+
+(defun emus-volume-down ()
+  (interactive)
+  (emus-volume-delta -10))
+
+
 ;;; Browser
 ;;
 
+(defun emus-render-record (record)
+   (insert-text-button
+    (concat
+     (propertize (format "%-20.20s" (emus-record-artist record))
+                 'face 'font-lock-keyword-face)
+     (propertize (format "%  -20.20s" (emus-record-album record))
+                 'face 'font-lock-function-name-face)
+     (propertize (format "  %s" (emus-record-title record))
+                 'face 'font-lock-string-face))
+    'action #'emus-click-record
+    'follow-link t
+    'emus-record record)
+  (insert "\n"))
+
+(defun emus-render-records ()
+  (with-current-buffer "*emus*"
+    (let ((inhibit-read-only t))
+      (save-excursion
+        (erase-buffer)
+        (goto-char (point-min))
+        (dolist (record emus-records)
+          (emus-render-record record))))))
+
+(defun emus-click-record (button)
+  (emus-play-record (button-get button 'emus-record)))
+
 (defun emus-browse ()
   "Switch to *emus* audio library browser."
   (interactive)
   (switch-to-buffer "*emus*")
-  (emus-mode))
+  (emus-mode)
+  (emus-volume emus-current-volume)
+  (if emus-records
+      (emus-render-records)
+    (emus-update-records #'emus-render-records)))
+
+(defvar emus-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map (kbd "SPC") 'emus-playpause)
+    (define-key map (kbd "o") 'emus-stop)
+    (define-key map (kbd "+") 'emus-volume-up)
+    (define-key map (kbd "=") 'emus-volume-up)
+    (define-key map (kbd "-") 'emus-volume-down)
+    (when (fboundp 'evil-define-key*)
+      (evil-define-key* 'motion map
+        (kbd "SPC") 'emus-playpause
+        (kbd "o") 'emus-stop
+        (kbd "+") 'emus-volume-up
+        (kbd "=") 'emus-volume-up
+        (kbd "-") 'emus-volume-down))
+    map)
+  "Keymap for emus.")
 
 (define-derived-mode emus-mode special-mode "Emus"
   "Major mode for EMUS music player.")
 
-;;; Debugging
-
-(defun emus-test ()
-  (message (emus-get-file-tags "/Users/vaughant/Music/Floex_-_Zorya/Floex - Zorya - 01 Ursa Major.mp3")))
-
-(defun emus-test-play ()
-  (emus-send-cmd "lp" "/Users/vaughant/Music/Floex_-_Zorya/Floex - Zorya - 01 Ursa Major.mp3")
-  (emus-send-cmd "silence")
-  (emus-send-cmd "p"))
+(when (fboundp 'evil-set-initial-state)
+  (evil-set-initial-state 'emus-mode 'motion))
 
+;;; Debugging
 
 ;;; emus.el ends here