diff options
| -rw-r--r-- | NEWS | 2 | ||||
| -rw-r--r-- | doc/emms.texinfo | 4 | ||||
| -rw-r--r-- | lisp/emms-volume-pulse.el | 113 | ||||
| -rw-r--r-- | lisp/emms-volume.el | 1 | 
4 files changed, 118 insertions, 2 deletions
@@ -4,6 +4,8 @@ News since version 4.0:    - Covers can have several extensions.  See      `emms-browser-covers-file-extensions'.    - Libre.fm login details can, and should, be stored in authinfo now. +  - Possible to set volume via PulseAudio pactl via +    emms-volume-pulse.el.  News since version 3.0: diff --git a/doc/emms.texinfo b/doc/emms.texinfo index 40bb6f1..26bb10f 100644 --- a/doc/emms.texinfo +++ b/doc/emms.texinfo @@ -2425,8 +2425,8 @@ value. So instead of pressing @kbd{C-c +} six times to increase volume  by six steps of @code{emms-volume-change-amount}, you would simply type  @kbd{C-c + + + + + +}. - - +EMMS can change volume with amixer, mpd, PulseAudio out of the box, see +@var{emms-volume-change-function}.  @node Streaming Audio  @chapter Streaming Audio diff --git a/lisp/emms-volume-pulse.el b/lisp/emms-volume-pulse.el new file mode 100644 index 0000000..8d95e30 --- /dev/null +++ b/lisp/emms-volume-pulse.el @@ -0,0 +1,113 @@ +;;; emms-volume-pulse.el --- a mode for changing volume using PulseAudio pactl + +;; Copyright (C) 2015 Free Software Foundation, Inc. + +;; Author: Rasmus Pank Roulund <emacs@pank.eu> + +;; This file is part of EMMS. + +;; EMMS is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation; either version 3, or (at your option) +;; any later version. +;; +;; EMMS is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +;; GNU General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with EMMS; see the file COPYING.  If not, write to the +;; Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, +;; Boston, MA 02110-1301, USA. + +;;; Commentary: + +;; This file defines a few simple functions to raise or lower the volume +;; using pactl. It can be used stand-alone, though it's meant for usage +;; with EMMS, particularly with emms-volume.el. +;; +;; To use add the following to your EMMS configuration +;;     (setq emms-volume-change-function 'emms-volume-pulse-change) + +;;; History: + +;; Marts 2015: First release.  Partly based on emms-volume-amixer.el + +;;; Todo: + +;; There probably needs to be more configurability, which may in turn +;; mean adding some more functions. +;; Some of this could benefit from adding customize interfaces. + +;;; Code: + +(eval-when-compile (require 'cl)) + +;; TODO: it would be great if custom could have +;; choices based on pactl list short sinks | cut -f1-2 + +(defcustom emms-volume-pulse-sink 0 +  "The sink to use for volume adjustment. + +See full list of devices on your system by running +    pactl list short sinks" +  :type '(choice (number :tag "Sink number") +                 (string :tag "Sink symbolic name")) +  :group 'emms-volume) + +(defcustom emms-volume-pulse-max-volume 150 +  "The sink to use for volume adjustment. + +See full list of devices on your system by running +    pactl list short sinks" +  :type '(choice (number :tag "Sink number") +                 (string :tag "Sink symbolic name")) +  :group 'emms-volume) + + +(defun emms-volume--pulse-get-volume () +  "Return `emms-volume-pulse-sink' volume." +  (let ((sink-number-p (numberp emms-volume-pulse-sink)) +        (start 0) +        (output +         (shell-command-to-string +          (concat "pactl list sinks" "|" +                  "grep -E -e 'Sink' -e 'Name' -e  '^[^a-zA-Z]*Volume'")))) +    (string-to-number +     (car +      (reverse +       (funcall +        (if sink-number-p 'assq 'assoc) +        emms-volume-pulse-sink +        (mapcar (if sink-number-p 'identity 'cdr) +                (loop while +                      (string-match +                       (mapconcat 'identity +                                  '(".*Sink[ \t]+\\#\\([0-9]\\)" +                                    ".*Name:[ \t]\\([^\n]+\\)" +                                    ".*Volume:.*?\\([0-9]+\\)%.*\n?") +                                  "\n") +                       output) +                      collect (list (string-to-number (match-string 1 output)) +                                    (match-string 2 output) +                                    (match-string 3 output)) +                      do (setq output (replace-match "" nil nil output)))))))))) + + +;;;###autoload +(defun emms-volume-pulse-change (amount) +  "Change amixer master volume by AMOUNT." +  (message "Volume is %s%%" +           (let ((pactl (or (executable-find "pactl") +                            (error "pactl is not in PATH"))) +                 (next-vol (min (+ (emms-volume--pulse-get-volume) amount) +                                emms-volume-pulse-max-volume))) +             (when (zerop (shell-command +                           (format "%s set-sink-volume %s %s%%" +                                   pactl emms-volume-pulse-sink next-vol))) +               next-vol)))) + +(provide 'emms-volume-pulse) + +;;; emms-volume-pulse.el ends here diff --git a/lisp/emms-volume.el b/lisp/emms-volume.el index 846cd30..cca8d77 100644 --- a/lisp/emms-volume.el +++ b/lisp/emms-volume.el @@ -61,6 +61,7 @@  If you have your own functions for changing volume, set this."    :type '(choice (const :tag "Amixer" emms-volume-amixer-change)                   (const :tag "MPD" emms-volume-mpd-change) +                 (const :tag "Pulseaudio" emms-volume-pule-change)                   (function :tag "Lisp function"))    :group 'emms-volume)  | 
