aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi60
-rw-r--r--gnu/services/audio.scm85
2 files changed, 128 insertions, 17 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 7cc33c6e22..f6dcb2ac63 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -22394,9 +22394,69 @@ The port to run mpd on.
The address that mpd will bind to. To use a Unix domain socket,
an absolute path can be specified here.
+@item @code{outputs} (default: @code{"(list (mpd-output))"})
+The audio outputs that MPD can use. By default this is a single output using pulseaudio.
+
+@end table
+@end deftp
+
+@deftp {Data Type} mpd-output
+Data type representing an @command{mpd} audio output.
+
+@table @asis
+@item @code{name} (default: @code{"MPD"})
+The name of the audio output.
+
+@item @code{type} (default: @code{"pulse"})
+The type of audio output.
+
+@item @code{enabled?} (default: @code{#t})
+Specifies whether this audio output is enabled when MPD is started. By
+default, all audio outputs are enabled. This is just the default
+setting when there is no state file; with a state file, the previous
+state is restored.
+
+@item @code{tags?} (default: @code{#t})
+If set to @code{#f}, then MPD will not send tags to this output. This
+is only useful for output plugins that can receive tags, for example the
+@code{httpd} output plugin.
+
+@item @code{always-on?} (default: @code{#f})
+If set to @code{#t}, then MPD attempts to keep this audio output always
+open. This may be useful for streaming servers, when you don’t want to
+disconnect all listeners even when playback is accidentally stopped.
+
+@item @code{mixer-type}
+This field accepts a symbol that specifies which mixer should be used
+for this audio output: the @code{hardware} mixer, the @code{software}
+mixer, the @code{null} mixer (allows setting the volume, but with no
+effect; this can be used as a trick to implement an external mixer
+External Mixer) or no mixer (@code{none}).
+
+@item @code{extra-options} (default: @code{'()"})
+An association list of option symbols to string values to be appended to
+the audio output configuration.
+
@end table
@end deftp
+The following example shows a configuration of @code{mpd} that provides
+an HTTP audio streaming output.
+
+@lisp
+(service mpd-service-type
+ (mpd-configuration
+ (outputs
+ (list (mpd-output
+ (name "streaming")
+ (type "httpd")
+ (mixer-type 'null)
+ (extra-options
+ `((encoder . "vorbis")
+ (port . "8080"))))))))
+@end lisp
+
+
@node Virtualization Services
@subsection Virtualization services
diff --git a/gnu/services/audio.scm b/gnu/services/audio.scm
index ebfe05abd0..471c5fd95f 100644
--- a/gnu/services/audio.scm
+++ b/gnu/services/audio.scm
@@ -1,5 +1,6 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Peter Mikkelsen <petermikkelsen10@gmail.com>
+;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -23,7 +24,9 @@
#:use-module (gnu packages mpd)
#:use-module (guix records)
#:use-module (ice-9 match)
- #:export (mpd-configuration
+ #:export (mpd-output
+ mpd-output?
+ mpd-configuration
mpd-configuration?
mpd-service-type))
@@ -33,6 +36,25 @@
;;;
;;; Code:
+(define-record-type* <mpd-output>
+ mpd-output make-mpd-output
+ mpd-output?
+ (type mpd-output-type
+ (default "pulse"))
+ (name mpd-output-name
+ (default "MPD"))
+ (enabled? mpd-output-enabled?
+ (default #t))
+ (tags? mpd-output-tags?
+ (default #t))
+ (always-on? mpd-output-always-on?
+ (default #f))
+ (mixer-type mpd-output-mixer-type
+ ;; valid: hardware, software, null, none
+ (default #f))
+ (extra-options mpd-output-extra-options
+ (default '())))
+
(define-record-type* <mpd-configuration>
mpd-configuration make-mpd-configuration
mpd-configuration?
@@ -51,27 +73,56 @@
(port mpd-configuration-port
(default "6600"))
(address mpd-configuration-address
- (default "any")))
+ (default "any"))
+ (outputs mpd-configuration-outputs
+ (default (list (mpd-output)))))
+
+(define (mpd-output->string output)
+ "Convert the OUTPUT of type <mpd-output> to a configuration file snippet."
+ (let ((extra (string-join
+ (map (match-lambda
+ ((key . value)
+ (format #f " ~a \"~a\""
+ (string-map
+ (lambda (c) (if (char=? c #\-) #\_ c))
+ (symbol->string key))
+ value)))
+ (mpd-output-extra-options output))
+ "\n")))
+ (format #f "\
+audio_output {
+ type \"~a\"
+ name \"~a\"
+~:[ enabled \"no\"~%~;~]\
+~:[ tags \"no\"~%~;~]\
+~:[~; always_on \"yes\"~%~]\
+~@[ mixer_type \"~a\"~%~]\
+~a~%}~%"
+ (mpd-output-type output)
+ (mpd-output-name output)
+ (mpd-output-enabled? output)
+ (mpd-output-tags? output)
+ (mpd-output-always-on? output)
+ (mpd-output-mixer-type output)
+ extra)))
(define (mpd-config->file config)
(apply
mixed-text-file "mpd.conf"
- "audio_output {\n"
- " type \"pulse\"\n"
- " name \"MPD\"\n"
- "}\n"
"pid_file \"" (mpd-file-name config "pid") "\"\n"
- (map (match-lambda
- ((config-name config-val)
- (string-append config-name " \"" (config-val config) "\"\n")))
- `(("user" ,mpd-configuration-user)
- ("music_directory" ,mpd-configuration-music-dir)
- ("playlist_directory" ,mpd-configuration-playlist-dir)
- ("db_file" ,mpd-configuration-db-file)
- ("state_file" ,mpd-configuration-state-file)
- ("sticker_file" ,mpd-configuration-sticker-file)
- ("port" ,mpd-configuration-port)
- ("bind_to_address" ,mpd-configuration-address)))))
+ (append (map mpd-output->string
+ (mpd-configuration-outputs config))
+ (map (match-lambda
+ ((config-name config-val)
+ (string-append config-name " \"" (config-val config) "\"\n")))
+ `(("user" ,mpd-configuration-user)
+ ("music_directory" ,mpd-configuration-music-dir)
+ ("playlist_directory" ,mpd-configuration-playlist-dir)
+ ("db_file" ,mpd-configuration-db-file)
+ ("state_file" ,mpd-configuration-state-file)
+ ("sticker_file" ,mpd-configuration-sticker-file)
+ ("port" ,mpd-configuration-port)
+ ("bind_to_address" ,mpd-configuration-address))))))
(define (mpd-file-name config file)
"Return a path in /var/run/mpd/ that is writable