+
+;;; Global variables
+
+(defvar emus--proc-in-use nil
+ "If non-nil, disables `emus-send-cmd'.
+Used to prevent commands from interfering with library construction.")
+
+(defvar emus-tracks nil
+ "Emus audio library.")
+
+(defvar emus-current-track nil
+ "Currently-selected emus track.")
+
+(defvar emus-state 'stopped
+ "Current playback state.")
+
+(defvar emus-continuous-playback t
+ "If non-nil, emus will automatically play the next track when the current track is finished.")
+
+(defvar emus-current-volume 100
+ "The current playback volume.")
+
+(defvar emus-current-progress ""
+ "String describing the progress through the current track.")
+
+(defvar emus-progress-enabled t
+ "Current state of progress tracking.
+
+To enable or disable progress tracking, using `emus-toggle-progress-tracking'.
+(Changing the value of this variable will not affect anything.)")
+
+;;; mpg123 process
+;;
+
+
+(defun emus-get-process ()
+ "Return current or new mpg123 process."
+ (let* ((emus-process-raw (get-process "emus-process"))
+ (emus-process (if emus-process-raw
+ (if (process-live-p emus-process-raw)
+ emus-process-raw
+ (kill-process emus-process-raw)
+ nil))))
+ (if emus-process
+ emus-process
+ (let ((proc
+ (make-process :name "emus-process"
+ :command `(,emus-mpg123-program
+ ,@emus-mpg123-args
+ "-R"))))
+ (set-process-query-on-exit-flag proc nil)
+ (unless emus-progress-enabled
+ (process-send-string proc "silence\n"))
+ proc))))
+
+(defun emus--send-cmd-raw (cmd &rest args)
+ "Send a command CMD with args ARGS to the mpg123 process.
+This procedure does not respect `emus--proc-in-use' and thus should only
+be used by `emus--load-library'."
+ (process-send-string (emus-get-process)
+ (concat
+ (seq-reduce (lambda (s1 s2) (concat s1 " " s2)) args cmd)
+ "\n")))
+
+(defun emus-send-cmd (cmd &rest args)
+ "Send a command CMD with args ARGS to the mpg123 process."
+ (unless emus--proc-in-use
+ (apply #'emus--send-cmd-raw cmd args)))
+
+(defun emus-kill-process ()
+ "Kill any existing mpg123 process."
+ (let ((emus-process (get-process "emus-process")))
+ (if emus-process
+ (kill-process emus-process))
+ (setq emus-state 'stopped
+ emus--proc-in-use nil
+ emus-tracks nil)))
+