Complete Computing Environment: Music and Podcasts with MPD

Table of Contents

(provide 'cce-music)

Playing Music

I run a remote MPD with an http output; I run this thing on a server that has full access to my NAS's music folders, and it streams out to any Ogg-capable client.

export MPD_PORT=6600

I used to use a piece of kit called mopidy which worked well when paired with Subsonic, but this setup is broken in Debian, and doesn't install cleanly in the Body Computing System, so I'm going to stop relying on it, plus having MPD streaming a random HTTP URL means that I can eventually wire it in to my home sound system quite easily.

- name: mpc and ogg123 installed
    state: installed
    - mpc
    - vorbis-tools
  when: ansible_pkg_mgr == "dnf"

- name: mpc and ogg123 installed
    state: installed
    - mpc
    - ncmpcpp
    - vorbis-tools
    - mpg123
    - mpg123-el
    - mpdris2
  when: ansible_pkg_mgr == "apt"

Mingus MPD frontend

Install Mingus, a neat little minimalist frontend for MPD. I don't use this much, but it's fairly nice to have around.

(add-to-list 'el-get-sources '(:name libmpdee
                               :type github
                               :pkgname "andyetitmoves/libmpdee"))
(add-to-list 'el-get-sources '(:name mingus
                               :type github
                               :pkgname "pft/mingus"))
(add-to-list 'cce/el-get-packages 'libmpdee)
(add-to-list 'cce/el-get-packages 'mingus)
(el-get 'sync cce/el-get-packages)

Hydra Controller

Mingus is a nifty little minimalist MPD frontend, but it doesn't ship with any keybindings out of the box. I'd like global MPD bindings, and this goes a long way to get there.

(defhydra hydra-mpd (global-map "C-c m" :columns 2)
  ("g" (progn (async-shell-command "mpv"
                                   (get-buffer-create "*ogg123*")))
   "Start stream")
  ("p" (progn (save-window-excursion
                (async-shell-command "mpc toggle" (get-buffer-create "*tmp*"))))
  ("/" mingus-search "Search")
  ("s" mingus "Show Mingus")
  ("<" (progn (require 'mpc) (mpc-prev)) "Previous")
  (">" (progn (require 'mpc) (mpc-next)) "Next")
  ("+" (async-shell-command "pactl set-sink-volume 10 -- +10%") "Louder")
  ("-" (async-shell-command "pactl set-sink-volume 10 -- -10%") "Quieter")
  ("n" (progn (ansi-term (executable-find "ncmpcpp")))
  ("q" nil "Quit"))

Making Music

I am trying to get back in to the creation of music. I used to carry around a Gameboy with LSDJ and should probably start doing that again. But I've also been looking at other ways of doing it – trackers are a good way of going about it, generally, but I am not to the point where I can just put together good melodies. Having something to "jam" on that fits on my person is where I am stuck right now until I become a better musician. As such, I've looked at a number of software synthesizers that support, for lack of a better term, jamming.

The first thing I've reached for is SunVox, a piece of software I have been enamoured with since I discovered the PalmOS version of it so long ago. It's great to use, and as of late, there is a Raspberry Pi version of it with some neat things added like being able to read filter values from the GPIO headers, allowing you to add physical interaction to your music pieces. Unfortunately, SunVox doesn't really have any sort of way to function without an X11 server running which means it works against my core system, a computer that can be used in a form factor without a screen, and eliminates my ability to fuck around in idle spaces.

This led me down the path of trying to find or build something that can work with Emacs and thus Emacspeak. It might seem unintuitive to use a voice control system to work with audio software, but it's quite nice. In my research I discovered Sonic Pi, a Ruby livecoding interface on top of Open Sound Control, which wonderfully contains a Emacs-Lisp interface. This is what I am using to fool around right now, eventually reaching towards the repl-electric stuff as a whole. It looks mad fun.

- name: sonic-pi installed
    name: sonic-pi
    state: installed
  when: ansible_hostname != "hypervisor01" and ansible_pkg_mgr == "apt"

- name: JACK installed
    state: installed
    - jackd2
    - alsa-utils
    - jack-tools
  when: ansible_hostname != "hypervisor01" and ansible_pkg_mgr == "apt"
(cce/with-any-domain '("tres-ebow" "kusanagi" "pocket")
                     (package-install 'highlight)
                     (package-install 'osc)
                     (package-install 'dash)
                     (install-pkgs '(osc sonic-pi))
                     (require 'sonic-pi)

                     (setq sonic-pi-path "/opt/sonic-pi/"))
(defun cce/sonic-pi-send-block ()
  "Send the block at point to the Sonic Pi server."

(add-hook 'sonic-pi-mode-hook
          (lambda ()
            (define-key ruby-mode-map (kbd "C-c C-d") 'cce/sonic-pi-send-block)
            (define-key ruby-mode-map "\C-c\C-b" 'sonic-pi-stop-all)))

Author: Ryan Rix

Created: 2019-05-07 Tue 11:12

Validate XHTML 1.0