Music on Console with Armbian on an Orange Pi Zero
February 7, 2018
<-Spoken Weather Forecasts and Internet Radio on the Orange Pi Zero with Armbian Music on Console, ALSA, and Bluetooth on Raspbian Stretch->

In a previous post I lamented the presence of noticeable stuttering when playing "hifi" streams from France Musique with the Media Player Daemon. I mused about testing VLC to see if the problem would persist.

I was a bit recalcitrant about installing VLC which to me seemed like a huge package. This is understandable, given that it is a video player. Looking around the Web to see if there was a lighter version, I ran into MOC - Music On Console a "console audio player for Linux/UNIX". As I am writing this, the Orange Pi Zero is playing France Musique Classique Easy without any stuttering using this audio media player which I think will turn out to be a better choice than mpd.

Table of Contents

  1. Installing MOC
  2. Using the Console
  3. Setting up the MOC Server
  4. Using the MOC Server
  5. MOC in Ubuntu 17.10

  1. Installing MOC
  2. Before installing the moc package, which is available from the Debian repository, it is best to stop the Media Player Daemon if it is running.

    michel@opiz:~$ sudo systemctl status mpd* [sudo] password for michel: ● mpd.socket Loaded: loaded (/lib/systemd/system/mpd.socket; enabled; vendor preset: enabl Active: active (running) since Sun 2018-02-04 19:10:00 AST; 57s ago Listen: /run/mpd/socket (Stream) [::]:6600 (Stream) Feb 04 19:10:00 opiz systemd[1]: Listening on mpd.socket. ● mpd.service - Music Player Daemon Loaded: loaded (/lib/systemd/system/mpd.service; enabled; vendor preset: enab Active: active (running) since Sun 2018-02-04 19:10:02 AST; 55s ago Docs: man:mpd(1) man:mpd.conf(5) file:///usr/share/doc/mpd/user-manual.html Main PID: 534 (mpd) Tasks: 5 (limit: 4915) CGroup: /system.slice/mpd.service └─534 /usr/bin/mpd --no-daemon Feb 04 19:10:02 opiz systemd[1]: Started Music Player Daemon. (pvenv) michel@opiz:~/ptests$ sudo systemctl stop mpd*

    My starting point for installing moc was an excellent post by raspuser on the Raspberry Pi Graphics, sound and multimedia forum Headless Internet Radio and Audio Player (updated). The first five steps are not needed in Raspbian, although performing step 2, updating and upgrading the system is never a bad idea.

    michel@opiz:~$ sudo apt install moc moc-ffmpeg-plugin

    After the installation, a configuration file needs to be created in the hidden directory .moc, in the user home directory. If the directory does not exist, it can easily be created.

    michel@opiz:~/some-dir$ cd $home michel@opiz:~$ ls -a .moc if nothing displayed, the directory does not exist, so create it: michel@opiz:~$ mkdir .moc

    Luckily, a template is included in the documentation directory.

    michel@opiz:~$ gunzip -c /usr/share/doc/moc/examples/config.example.gz > .moc/config

    I used nano to change two things. First since there is only ALSA installed on the Orange Pi Zero there is no need to waste time looking for other drivers.

    michel@opiz:~$ nano .moc/config
    ... # Sound driver - OSS, ALSA, JACK, SNDIO (on OpenBSD) or null (only for # debugging). You can enter more than one driver as a colon-separated # list. The first working driver will be used. #SoundDriver = JACK:ALSA:OSS SoundDriver = ALSA ... # ALSA output settings. If you need to dump the audio produced by MOC # to a file for diagnostic purposes, the following setting of 'ALSADevice' # should do that: # # ALSADevice=tee:hw,'/tmp/out.wav',wav # #ALSADevice = default #ALSAMixer1 = PCM #ALSAMixer2 = Master ALSADevice = default ALSAMixer1 = "Line Out" ALSAMixer2 = DAC

    The second was a bit more problematic. In the end, all that needed to be done was to play a longish wav file with aplay in one terminal and to start up alsamixer in another terminal to find the names given to the "mixers" that controlled the volume.

    Just why there should be two mixers is not clear. In my experience, moc uses only one, ALSAMixer1, which could be "Line Out" or DAC. The other thing I noticed is that it was better to set the other control with alsamixer to a decent level say at around 80%. It's as if ALSA multiplies the two control levels (measure as fractions not as a percentage, of course) to set the final volume. Accordingly, with the values set as shown in the image above the output volume would be 0.55 (=0.63*0.87) or 55% of full volume.

  3. Using the Console
  4. As the name implies, mocp provide a text-based user interface to control playing. It is a great way to test if things are working. There will be a warning when starting.

    michel@opiz:~$ mocp Running the server... Trying ALSA... Warning: Your system may be vulnerable to stuttering audio. You should read the example configuration file comments for the 'ALSAStutterDefeat' option and set it accordingly. Setting the option will remove this warning.

    After a short delay, the play console came up. It was a simple matter of using the cursor key to navigate to the sound directory and the pressing the Enter to open that folder.

    Before launching the player, I had already copied some sound files and a couple of playlist files found on the web. I had also created a playlist file, FranceMusique.m3u, with some of the stations causing problems with mpd.
    #EXTM3U #EXTINF:-1, #1,1 France Musique Classique easy #EXTINF:-1, #1,2 France Musique Classique easy #EXTINF:-1, #2,1 France Musique Concerts Radio France #EXTINF:-1, #2,2 France Musique Concerts Radio France #EXTINF:-1, #3,1 France Musique La Jazz #EXTINF:-1, #3,2 France Musique La Jazz

    From what I can tell, there is no M3U standard. It is a text file containing a list of entries which can be paths to local media files (sound files, video files, image files, whatever) or URLs to a remote resource such as an Internet audio stream. In the so-called extended M3U format, which is what we have above, the first line must be a header: #EXTM3U. There can be optional information lines that begin with #EXTINF: followed by the play time of the media file (apparently -1 can be used to indicate that there is no fixed duration) and then the title of the media file. Comment lines beginning with # are ignored. Blank lines seem to cause problems for mocp.

    The above image shows that the M3U playlist is about to be opened by pressing Enter As soon as that is done, the playlist is displayed on the right-hand panel. I then pressed l (lower case L) to toggle the layout in order to see the names of the stations in the play list as shown below.

    Any one of the listed audio streams can be played by highlighting it using the up and down arrow keys and then pressing Enter.

    Use Tab to switch between the play list on the right and the file list on the left. To play a file or use another play list, it is necessary to "clear" the current list by pressing C (upper case C).

    Pressing h toggles the help screen on and off. Here is its content.

    q Detach MOC from the server ENTER Start playing at this file or go to this directory DOWN Move down in the menu UP Move up in the menu PAGE_DOWN Move one page down PAGE_UP Move one page up HOME Move to the first item in the menu END Move to the last item in the menu Q Quit s Stop n Play next file b Play previous file p SPACE Pause f Toggle ReadTags option S Toggle Shuffle R Toggle Repeat X Toggle AutoNext TAB Switch between playlist and file list l Switch between layouts ^p Switch on/off play time percentage a Add a file/directory to the playlist C Clear the playlist A Add a directory recursively to the playlist Y Remove playlist entries for non-existent files < Decrease volume by 1% > Increase volume by 1% , Decrease volume by 5% . Increase volume by 5% RIGHT Seek forward by n-s LEFT Seek backward by n-s h ? Show the help screen M Hide error/informative message ^r ^l Refresh the screen r Reread directory content H Toggle ShowHiddenFiles option m Go to the music directory (requires config option) d Delete an item from the playlist g / Search the menu V Save the playlist ^t Toggle ShowTime option ^f Toggle ShowFormat option o Play from the URL G Go to the currently playing file's directory i Go to a directory U Go to '..' ^x ESCAPE Exit from an entry ] Silent seek forward by 5s [ Silent seek backward by 5s M-1 Set volume to 10% M-2 Set volume to 20% M-3 Set volume to 30% M-4 Set volume to 40% M-5 Set volume to 50% M-6 Set volume to 60% M-7 Set volume to 70% M-8 Set volume to 80% M-9 Set volume to 90% ' Mark the start of a block " Mark the end of a block ! Go to a fast dir 1 @ Go to a fast dir 2 # Go to a fast dir 3 $ Go to a fast dir 4 % Go to a fast dir 5 ^ Go to a fast dir 6 & Go to a fast dir 7 * Go to a fast dir 8 ( Go to a fast dir 9 ) Go to a fast dir 10 UP Go to the previous entry in the history (entry) DOWN Go to the next entry in the history (entry) ^u Delete to start of line (entry) ^k Delete to end of line (entry) x Toggles the mixer channel w Toggles the software-mixer E Toggles the equalizer e Reload EQ-presets K Select previous equalizer-preset k Select next equalizer-preset J Toggle mono-mixing u Move playlist item up j Move playlist item down ^u Add a URL to the playlist using entry T Switch to the theme selection menu F1 Execute ExecCommand1 F2 Execute ExecCommand2 F3 Execute ExecCommand3 F4 Execute ExecCommand4 F5 Execute ExecCommand5 F6 Execute ExecCommand6 F7 Execute ExecCommand7 F8 Execute ExecCommand8 F9 Execute ExecCommand9 F10 Execute ExecCommand10 L Display lyrics of the current song (if available) P Toggle displaying full paths in the playlist z Add (or remove) a file to (from) queue Z Clear the queue

    I was pleased with this player and decided to use it instead of mpd.

  5. Setting up the MOC Server
  6. Before installing the moc "daemon", the mpd has to be disabled so that it will not be loaded on the next boot. I went further and removed the package along with all the dependencies

    michel@opiz:~$ sudo systemctl disable mpd* michel@opiz:~$ sudo apt-get remove --purge mpd* michel@opiz:~$ sudo apt-get autoremove michel@opiz:~$ sudo apt-get update && sudo apt-get upgrade

    By the way, mocp and mpd use a lot of the same libraries as one would expect. So installing the mpd with all its dependencies and with mpc on a fresh system uses 62.8 MB of additional disk space. The mocp moc-ffmpeg-plugin tandem comes in at 45.4 MB in the same conditions.

    In step 9 (labelled as a second step 7), raspuser shows a method to start the moc server and then to go on to play a particular sound resource when the host computer is booted. He uses bash profile file to do this. I would rather not start the player and only load the server in the usual manner with systemd. Of course raspuser script could also be used with a moc server loaded automatically by systemd; just remove the mocp -S line in the script.

    The archlinux Moc wiki contains the systemd service file that allows for the automatic installation of the moc server at system start up.

    michel@opiz:~$ sudo nano /etc/systemd/system/moc@.service
    [Unit] Description=MOC server ConditionPathExists=/usr/bin/mocp [Service] RemainAfterExit=yes User=%I ExecStart=/usr/bin/mocp -S ExecStop=/usr/bin/mocp -x WorkingDirectory=/home/%I/ [Install]

    The next three commands constitute the one time installation of the daemon service. The first line starts the server immediately. The second optionally checks that the server is running and the third, the enable command is the one that ensures the service will be started when the system boots.

    michel@opiz:~$ sudo systemctl start moc@michel michel@opiz:~$ sudo systemctl status moc* ● moc@michel.service - MOC server for michel Loaded: loaded (/etc/systemd/system/moc@.service; disabled; vendor preset: enabled) Active: active (exited) since Mon 2018-02-05 01:07:03 AST; 9s ago Process: 6376 ExecStop=/usr/bin/mocp -x (code=exited, status=0/SUCCESS) Process: 6387 ExecStart=/usr/bin/mocp -S (code=exited, status=0/SUCCESS) Main PID: 6387 (code=exited, status=0/SUCCESS) Tasks: 3 (limit: 4915) CGroup: /system.slice/system-moc.slice/moc@michel.service └─6388 /usr/bin/mocp -S Feb 05 01:07:03 opiz systemd[1]: Started MOC server for michel. Feb 05 01:07:04 opiz mocp[6387]: Warning: Your system may be vulnerable to stuttering audio. Feb 05 01:07:04 opiz mocp[6387]: You should read the example configuration file comments Feb 05 01:07:04 opiz mocp[6387]: for the 'ALSAStutterDefeat' option and set it accordingly. Feb 05 01:07:04 opiz mocp[6387]: Setting the option will remove this warning. Feb 05 01:07:09 opiz mocp[6387]: Running the server... Feb 05 01:07:09 opiz mocp[6387]: Trying ALSA... Feb 05 01:07:09 opiz mocp[6387]: Running the server... michel@opiz:~$ sudo systemctl enable moc@michel Created symlink /etc/systemd/system/ → /etc/systemd/system/moc@.service.

    I did not change the setting for ALSAStutterDefeat. Here is the full description about that setting as found in the ~/.moc/config file:

    # Under some circumstances on 32-bit systems, audio played continously # for long periods of time may begin to stutter. Setting this option to # 'yes' will force MOC to avoid ALSA's dmix resampling and prevent this # stutter. But it also has other implications: # # - You may experience unacceptably high CPU load. # - ALSA's resampler plug-ins will not be used. # - The resampling may be of lower quality than ALSA would provide. # - You may need to try different "ResampleMethod" option settings. # - The "ForceSampleRate" option may be ineffective. # - If libsamplerate is not configured, many audios may be unplayable. # #ALSAStutterDefeat = no

    It certainly does not look like I would ever want to set the directive to yes and so far I can be thankful that there is no noticeable problem. To get rid of this message, I will uncomment the last line.

    From now on, the mocp daemon is available. It can be seen among all loaded tasks listed with the top utility near the bottom as sleeps until it is invoked to play a file or a stream.

  7. Using the MOC Server
  8. Using the --help option when launching mocp gives a list of commands that can be used to control the server.

    michel@opiz:~$ mocp --help Music On Console (version 2.6-alpha3) ... Server commands: -P, --pause Pause -U, --unpause Unpause -G, --toggle-pause Toggle between playing and paused -s, --stop Stop playing -f, --next Play the next song -r, --previous Play the previous song -k, --seek=N Seek by N seconds (can be negative) -j, --jump=N{%,s} Jump to some position in the current track -v, --volume=[+,-]LEVEL Adjust the PCM volume -x, --exit Shutdown the server -a, --append Append the files/directories/playlists passed in the command line to playlist -e, --recursively Alias for --append -q, --enqueue Add the files given on command line to the queue -c, --clear Clear the playlist -p, --play Start playing from the first item on the playlist -l, --playit Play files given on command line without modifying the playlist -t, --toggle=CONTROL Toggle a control (shuffle, autonext, repeat) -o, --on=CONTROL Turn on a control (shuffle, autonext, repeat) -u, --off=CONTROL Turn off a control (shuffle, autonext, repeat) -i, --info Print information about the file currently playing -Q, --format=FORMAT Print formatted information about the file currently playing

    See the manual (man moc) for more information.

    The -l, -p, -U, and -s commands are sufficient to play Internet streams, or individual sound file for that matter. The -i, (or -Q %state, -Q %title etc. ) can be used to get feedback.

    Below, I am playing ICI Musique the "second" public radio channel in Canada broadcast across the country. This is the Acadie regional feed out of nearby Moncton.

    michel@opiz:~$ mocp -l michel@opiz:~$ mocp --info State: PLAY File: Title: Artist: SongTitle: Album: CurrentTime: 00:06 CurrentSec: 6 Bitrate: 0kbps AvgBitrate: 0kbps Rate: 44kHz

    When playing a radio station, up to about % of the CPU time is used by moc as can be seen from the listing from top.

    Some of the threads (kworker) found in the listing probably belong to mocp. Still playing music only occupies 22% of the CPU capacity.

    Like most internet radio streams, there is no information about what is playing. Some web radios do provide information. The few that I have found tend to broadcast music non stop such as Venice Classic Radio

    michel@opiz:~$ mocp -l michel@opiz:~$ mocp -i State: PLAY File: Title: Franz Schubert (1797-1828) - Sinfonia in re Maggiore No.3 D200 (23:07) {+info:} Artist: SongTitle: Franz Schubert (1797-1828) - Sinfonia in re Maggiore No.3 D200 (23:07) {+info:} Album: CurrentTime: 01:28 CurrentSec: 88 Bitrate: 0kbps AvgBitrate: 0kbps Rate: 44kHz

    As can be seen the Title and SongTitle fields carry the same information. Rather than dealing with all this information , which for the most part is not very useful, it is possible to get only desired information.

    michel@opiz:~$ mocp -Q '"%state", "%file", "%title"' "PLAY", "", "Franz Schubert (1797-1828) - Sinfonia in re Maggiore No.3 D200 (23:07) {+info:}"

    Playing can be paused and later be resumed or "unpaused". However when playing a stream, pausing and then resuming means that part of the stream will not be heard. However, just as with mpd when the server is suspended, the hardware is released and it is possible use it with another program.

    michel@opiz:~$ mocp -P michel@opiz:~$ mocp -Q '"%state", "%file", "%title"' "PAUSE", "", "" michel@opiz:~$ aplay "sound/test.wav" Playing WAVE 'sound/test.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo michel@opiz:~$ mocp -U michel@opiz:~$ mocp -Q '"%state", "%file", "%title"' "PLAY", "", "Cesar Franck (1822-1890) - Sonata per violoncello e pianoforte in la Maggiore (29:44) {+info:}"

    Stopping the player is very simple. And, of course, the server's state reflects that it is not playing anything.

    michel@opiz:~$ mocp -s michel@opiz:~$ mocp -Q '"%state", "%file", "%title"' "STOP", "", ""

    Finally, mocp will clearly indicate when the server is not running.

    michel@opiz:~$ sudo systemctl stop moc@michel michel@opiz:~$ mocp -l FATAL_ERROR: The server is not running! michel@opiz:~$ mocp -Q '"%state", "%file", "%title"' FATAL_ERROR: The server is not running!

    Python libraries that interface with the moc server are available: A Python library to control the MOC (music on console) audio player by Ken (kenjyco) which is based on the library Music On Console Python interface by Jonas Haag. However, using the server seems simple enough, so I decided this would be an opportunity to improve my limited knowledge of Python. When the rough edges are eased somewhat, I might decie to make my library available.

  9. MOC in Ubuntu 17.10
  10. To make things easier for myself, I installed Music on Console on a desktop running Ubuntu 17.10. This was even simpler than installing it on the Orange Pi. The console worked without even creating a configuration file.

    Unfortunately, there can be problems when the audio output device is changed after the moc daemon has already been launched. In that case, the sound output from moc may not be sent to the correct device. When the daemon is restarted, moc does send the sound to the correct device, but often the volume can no longer be controlled by the mocp, nor with alsamixer. Not even the system volume control will work.

    As there is already an application that handles internet radio and other audio media in Ubuntu 17.10 and using moc is only a temporary situation, I will not bother investigating the problem any further.

<-Spoken Weather Forecasts and Internet Radio on the Orange Pi Zero with Armbian Music on Console, ALSA, and Bluetooth on Raspbian Stretch->