Suckless music player
Sync mus_util.sh
Minor cosmetic changes
Fix SIGPIPE when sending a QUIT command

refs

master
browse log

clone

read-only
https://git.sr.ht/~q3cpma/mus
read/write
git@git.sr.ht:~q3cpma/mus

You can also use your local clone with git send-email.

                mus - A simple album playlist based music player
                ================================================

        Overview
        --------

A simple client/server music player consuming an editable plaintext album
playlist.
As I primarly made it for myself, it only supports FLAC, Vorbis and Opus (for
now) on GNU/Linux and {Free,Net,Dragonfly}BSD, out of the box. It can work on
OpenBSD/MacOS by installing a port for flock(1).

mus is formed of four independant parts:
    * mus_server:
        Play albums from a playlist via mus_player.

    * mus_client:
        Send commands to the player and receive its answers, read or modify the
        playlist.

    * mus_album_* and fair_shuf:
        Optional album tools for random but fair album picking. These assume
        that the music arborescence is structured so that albums are at depth 2.

        This is the structure I use, for reference. It includes ways to deal
        with duplicate artist names and same year releases; for example:
            Music
            ├── Black Sabbath
            │   ├── (1970-1) Black Sabbath
            │   └── (1970-2) Paranoid
            ├── Solstice
            │   └── (1995) Pray
            ├── Solstice (2)
            │   └── (1998) New Dark Age
            └── Uli Jon Roth
                └── (2000) Transcendental Sky Guitar
                    ├── Disc 1: The Phoenix
                    └── Disc 2: The Dragon

    * mus_player:
        The player doing all the job and answering to mus_client's commands.
        Supports replaygain and gapless playback. Limited to mono/stereo
        16 bits FLAC, Vorbis and Opus (support is optional at build time).

A lemonbar status script can be found at https://repo.or.cz/q3cpma-lemonbar.git.


        Dependencies and portability
        ----------------------------

In addition to everything specified by the latest POSIX, you'll need
the following for mus_player:
    * C11 compiler (build); gcc generates a faster binary than clang, here.
    * GNU Make (build)
    * gperf (build)
    * pthread
    * libao
    * libflac (build optional)
    * vorbisfile (build optional), often part of the libvorbis package
    * opusfile (build optional)

and some runtime dependencies:
    * GNU/Linux:
        ed(1) (POSIX requirement but often absent) and the util-linux package.

    * FreeBSD, NetBSD, DragonflyBSD:
        None.

    * OpenBSD:
        flock(1) from the port tree.

    * MacOS:
        flock(1) from somewhere (e.g. [1]) and a readlink implementation with
        the -f option (e.g. GNU readlink).

mus was tested on Gentoo GNU/Linux with:
    * /bin/awk -> busybox
        OK
    * /bin/awk -> mawk
        Works with mawk >= 20181114 (see [2]).
    * /bin/sh -> busybox
        OK
    * /bin/sh -> dash
        OK

[1] https://github.com/discoteq/flock
[2] https://github.com/ThomasDickey/original-mawk/issues/56


        Building and installation
        -------------------------

To install mus and, optionally, the mus album tools to PREFIX=/usr/local:
    $ make [USE_FLAC=no] [USE_OGG_VORBIS=yes] [USE_OGG_OPUS=yes]
    # make install
    # make albumtools_install

Adding -march=native to the CFLAGS really benefits some loops in
mus_player/filter.c that can be easily vectorized by modern compilers:
    $ CFLAGS=-march=native make

To uninstall:
    # make uninstall
    # make albumtools_uninstall


        Usage examples
        --------------

Launch the server:
    $ mus_server [OPTIONS] &

If using the album tools:
    $ mus_album_db_create [MUSIC_DIRECTORY...]
    $ printf '%s\n' album1/ album2/ | while IFS= read -r line; do readlink -f -- "$line"; done | tr '\n' '\0' | xargs -0 mus_album_pick | mus_client pl_append
    $ mus_album_rand [ALBUM_COUNT] | mus_client pl_append

otherwise:
    $ printf '%s\n' album1/ album2/ | while IFS= read -r line; do readlink -f -- "$line"; done | mus_client pl_append

Then you can issue commands via mus_client:
    $ mus_client pause_play
    $ mus_client album_next
    $ mus_client pl_edit
    ...


        Important environment variables
        -------------------------------

For mus:
    * MUS_PLAYLIST: defaults to $HOME/.config/mus/playlist

For the album tools:
    * MUS_DB: defaults to ${XDG_CONFIG_HOME:-$HOME/.config}/mus/album_db
    * MUS_MUSIC_DIR: defaults to ~/Music


        Audio configuration tips and trivia
        -----------------------------------

Setting a libao config file can solve some usual problems like
`Unknown PCM cards.pcm.front` from ALSA:
    $ cat /etc/libao.conf
    # Avoid trying pulseaudio
    default_driver=alsa
    # Avoid problems with front being tried first
    dev=default

The default linear resampling algorithm of ALSA's dmix should be changed for
something better as soon as possible, see [1]:
    $ cat /etc/asound.conf
    # Use speexrate_best for entirely transparent resampling
    defaults.pcm.!rate_converter "speexrate_medium"

Even with the best hardware, your room is probably the biggest sound factor,
which is why room compensation is almost mandatory.
See DRC-FIR [2] [3] and Brutefir [4] [5] to solve the problem with free (and
mostly suckless) software.

[1] https://wiki.archlinux.org/index.php/Talk:Advanced_Linux_Sound_Architecture#On_high_quality_resampling
[2] http://drc-fir.sourceforge.net
[3] http://drc-fir.sourceforge.net/doc/drc.html
[4] https://www.ludd.ltu.se/~torger/brutefir.html
[5] http://digitalroomcorrection.hk/http___www.digitalroomcorrection.hk_/BruteFIR.html