• Disclaimer: This Vendor's Forum is a paid-for commercial area. Unlike the rest of diyAudio, the Vendor has complete control of what may or may not be posted in this forum. If you wish to discuss technical matters outside the bounds of what is permitted by the Vendor, please use the non-commercial areas of diyAudio to do so.

LADSPA filters for digital crossovers on the BBB

Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.
Member
Joined 2007
Paid Member
This thread concerns the implementation of LADSPA filters in linux on ARM-based player-platforms. My only experience is with the Beaglebone black fitted with Twisted Pear's Hermes and Cronus capes. Disclaimer - I am neither a hardware nor software guru - far from it! This is a thread for us 'trial-and-error' hobbyists and has three objectives:
1. Share working solutions - ALSA is not always intuitive, and advanced features are poorly documented.
2. Optimize for and compare results based on very similar platforms running the Botic kernel.
3. Improve and expand methods and working knowledge.

To start with, this will be split into 3 separate posts: a) this intro, b) the steps I used to create a two-way crossover (note update for generic 2-way and for a 3-way system), and c) a bit of discussion and a few perspectives. I have moved the ALSA code to GitHub for easier maintenance and distribution: https://github.com/francolargo/BBB-audio/tree/master

Intro:
Many LADSPA filter plugins are somewhat archaic, having been developed a decade (or more) ago for audio production methods that are now largely obsolete. But the filters still do their jobs and a number of them are theoretically applicable to digital crossovers for bi/multi-amped reproduction systems. Previously I used Jan Thuneau’s IIR filters in a PC, and was always pleased with the fine-tuning that was possible. LADSPA filters have been designed and optimized for different qualities. With the inexpensive and clean computing power now available in SoC development boards like BBB, I think LADSPA filters will see renewed interest.

A fairly recent linux filter implementation by Richard Taylor uses filters created for loudspeaker crossovers. This implementation employs the host ecasound to manage serial filter chains. I tried this approach with the BBB and was unable to achieve filtering that was always free of resampling. Ecasound is good software, but running in the background it forces any player (like MPD) to output at ecasound's single chosen frequency. Bit-perfect output, a primary design goal of the BBB/Hermes/Cronus, is defeated. In addition, the CPU demand of rate-resampling by MPD/Libasound caused data under-runs with files recorded at 96kHz - and that was for a simple two-way system.

The solution was to execute LADSPA filters in ALSA using plugins in the user space under the control of alsa configuration file(s). To this beginner, ALSA seems capricious and temperamental! Implementing plugins is a trial & error process, for sure. Sharing working configurations is a huge way to help each other. The next post details the steps I took for a two-way crossover that is sounding pretty good - even played through the little powered monitors i'm using for development (balanced, at least :p). There is certainly more work to be done, but best to put this out while the steps are fresh in memory.
 
Last edited:
Member
Joined 2007
Paid Member
Steps to implement 2-way LADSPA crossover on BBB

First, I'm not seasoned with Linux so there are probably better ways to do some of these things. Feel free to comment.

Overview of steps:
1. Start with a fresh Botic image on a uSD card and prepare the system to compile filters in C.
2. Install the filters
3. Create the needed alsa configuration file
4. Configure a compatible player
5. Test and hopefully enjoy!



1. Start with a fresh image of Botic on a uSD card and use it to boot the BBB - Download the bbb-botic-v4-1gb.img.gz, ungzip it and write to SD card [To write the image I use ‘dd’ in a terminal command line].
Boot the BBB from the card and login as root from a terminal
Execute commands one line at a time...
Expand the partition according to this
Code:
cd /
root@bbb:~# /opt/scripts/tools/grow_partition.sh
 ... (after a few seconds of extending)

 root@bbb:~# reboot
Login as root, set date and time and get build tools.

Code:
cd /
ntpdate pool.ntp.org
apt-get update
If security is old, add the following line to /etc/apt/apt.conf (create the file if it does not already exist):
Code:
Acquire::Check-Valid-Until "0";
If there were errors, now re-try
Code:
apt-get update

Once there are no errors in apt-get update
Code:
apt-get install build-essential
apt-get install ladspa-sdk
apt-get install cmt
2. Download RT filters: LADSPA Plugins for Active Loudspeakers | Richard's Stuff
Create a working directory - I chose:
Code:
cd /source 
mkdir /filter
ftp the file rt-plugins-0.0.3.tar into it - I use ‘fetch’ the mac ftp client with a graphical user interface - can also be done using command 'get'
Code:
cd /source/filter
tar -xvf rt-plugins-0.0.3.tar
cd /rt-plugins-0.0.3
Read and understand the README file

The default installation location is /usr/local/lib/ladspa.
Do ONE of these three things:
A.
Code:
export LADSPA_PATH=/usr/local/lib/ladspa:/usr/lib/ladspa
and add the same command into /etc/rc.local above the last line
or
B. [I prefer this option - to have all the filters in /usr/lib/ladspa.] Before compiling, edit the Makefile in /source/filter/rt-plugins-0.0.3 and adjust the path.

then regardless of your preference
Code:
make
make install

then option C is
manually copy from /usr/local/lib/ladspa to /usr/lib/ladspa using mv [original-path/filename] [destination-path/filename]

It is OK if the filters are in different directories (option 1), but only the ones in /usr/lib/ladspa will be available for the useful commands listplugins and analyseplugin


3. Now for ALSA...

create /etc/asound.conf and paste into it:

Code:
pcm.!default {
     type plug
     slave.pcm "filter"
}
ctl.!default {
     type hw
     card 0
}
pcm.filter {
     type ladspa
     slave.pcm delay           
     path "/usr/lib/ladspa"    # correct location of filters?
     channels 4
     plugins
     {
          0 {
               label RTlr4lowpass
               policy none
               input.bindings.0 "Input"
               output.bindings.1 "Output"
               input { controls [ 500 ] }   # 500Hz -3dB point
          }
          1 {
               label RTlr4hipass
               policy none
               input.bindings.0 "Input"
               output.bindings.0 "Output"
               input { controls [ 500 ] }
          }
          2 {
               label RTlr4lowpass
               policy none
               input.bindings.1 "Input"
               output.bindings.3 "Output"
               input { controls [ 500 ] }
          }
          3 {
               label RTlr4hipass
               policy none
               input.bindings.1 "Input"
               output.bindings.2 "Output"
               input { controls [ 500 ] }
          }
     }
}
pcm.delay {
     type ladspa
     slave.pcm speaker
     path "/usr/lib/ladspa"    # correct location of filters?
     channels 4
     plugins
     {
        0 {
               label delay_5s
               policy none
               input.bindings.1 "Input"
               output.bindings.1 "Output"
               input { controls [ 0.0012 1 ] }    # first parm = delay in seconds, second param = ‘wet/dry’
          }
        1 {
               label delay_5s
               policy none
               input.bindings.3 "Input"
               output.bindings.3 "Output"
               input { controls [ 0.0012 1 ] }
          }
        2 {
               label delay_5s
               policy none
               input.bindings.0 "Input"
               output.bindings.0 "Output"
               input { controls [ 0 0 ] }
          }
        3 {
               label delay_5s
               policy none
               input.bindings.2 "Input"
               output.bindings.2 "Output"
               input { controls [ 0 0 ] }
          }
     }
}

pcm.speaker {
    type plug
    slave {
     pcm "hw:0,0"
     channels 4
     }
}

4&5. Kill MPD and check that all plugins are incorporated into ALSA - at top of list: default, filter, delay, and speaker
Code:
pkill -f mpd

aplay -L
Use speaker-test for testing and to check channel alignment - difference in the white noise is obvious with cutoff frequency like 500Hz
Code:
speaker-test -c2
speaker-test -c4

Add music and play with SoX - still working?

NOTE: I have not been able to make the filters work with MPD - it remains an unresolved issue. I suggest to use squeezelite according to Kinku’s instructions p93 Botic support thread

Next post: Discussion
 
Last edited:
Member
Joined 2007
Paid Member
Squeezelite configuration

I forgot to mention above that your Squeezelite installation need not include the resample options.

Specifically, skip the instruction steps that acquire the SoX resampling code and when you compile Squeezelite, use:
Code:
make OPTS="-DDSD -DFFMPEG"

Then, to run Squeezelite simply execute:
Code:
squeezelite
  [or...]
squeezelite -o default

Probably the resample options don't hurt if they are built-in, but I excluded them and only know it works when set up that way... ;)
 
Member
Joined 2007
Paid Member
Using LADSPA filters in ALSA crossovers - brief discussion

Discussion:

Testing

Once your system is running, I trust you will find that the output is not resampled. Try playing a variety of file types and then:
Code:
 cat /proc/asound/Botic/pcm0p/sub0/hw_params

Note that the displayed results will be misleading based on the number of output channels. For example, below is the report while playing an 88.2kHz .wav file. The rate is off by a factor of channels/2.
Code:
root@botic:~# cat /proc/asound/Botic/pcm0p/sub0/hw_params
access: MMAP_INTERLEAVED
format: S32_LE
subformat: STD
channels: 4
rate: 176400 (176400/1)
period_size: 1764
buffer_size: 7056

Regarding testing, I don’t have any DSD files to test at the moment, so I’d be interested to learn or hear what happens when DSD hits the filters! Also, for less-characterized filters than the RT series, we should probably run frequency sweeps to confirm rolloff behavior. [I'm not set up for that right now.]

General configuration

Regarding the overall design of any crossover, I think simpler is better. Everybody will want to tweak, and the basis for a simple rig should be present in the asound.conf given above. For example, my speaker system is 3-way, but my mid driver output is flat way up, so I choose to use a passive single-pole filter on the nice tweeters. That protects them from user stupidity! The initial 500Hz XO point is good for hearing what is going on using the command speaker-test. Once all is in order, adjust frequencies for your drivers.

My woofer cabinets are separate from mid+tweets, so the delay filter gives me flexibility in locating the mid/tweeter cabinets relative to the woofers (which need slight delay). For drivers that are correctly aligned relative to one another, one could eliminate the entire ‘delay’ plugin. Simply delete that plug and slave the ‘filter’ plug directly to ‘speaker’ [i.e. slave.pcm delay -> slave.pcm speaker]. Re: positioning, inverse speed of sound is about 1ms/foot or 3ms/meter. As for fractional phase alignment among aligned drivers, I don’t know how many decimal places the simple delay (from ladspa-sdk) will use. There are other delay filters in the Computer Music Toolkit that you can try. (When a delay filter name includes the word ‘resonance’, I get suspicious!) Obviously, for a 3-way system, you need to add additional channels and mid-range band-pass filters.

It turns out that the channel output from the Cronus board running in Botic is, well, ‘unintuitive’. When setup for 2 channels, output from connector D2 gives a stereo pair. However, I run a second I2S signal from D3 into a separate DAC. In this case, D2 and D3 are not stereo pairs. Natively, channels 1 (right highpass) and 2 (left lowpass) are swapped. [I need the DACs to handle left-right stereo pairs because the I/V boards on the two DACs are not identical.] So pay attention to your channel alignments (using speaker-test with various number of channels [-cX]). In asound.conf, the corrective channel swap occurs between the “Input” and “Output” specs of each ‘filter’ plugin. Theoretically there are other ways to route channels, but I couldn’t get the type-ladspa plugins (filter and delay) to output through a type-route plugin. Typically a type-route plugin would be the preferred way to correct alignments and a good way to blend channels. Also, any kind of t.table in pcm.speaker (type-plug, but I’ve seen examples with that config) breaks the signal chain… …would like to figure out that quirk… For basic information about plugin types and syntax, see this reference.


CPU demands

For this simple setup, the BBB seems entirely up to the task! I monitored CPU use using the command top while playing different files using Squeezelite. Here are some results. They vary over time so I grabbed the screen when I saw %CPU near its upper bound:
Code:
idle after playing at 44.1/16

 PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND                                                                                                                                                                                                 
 1237 root      20   0 41640  39m  15m S  26.8  8.0   7:13.72 squeezelite                                                                                                                                                                                             
 1259 root      20   0  2680 1820 1408 R   0.7  0.4   0:01.44 top                     

play 44.1/16

 1237 root      20   0 41640  39m  15m S  29.4  8.0   6:03.24 squeezelite                                                                                                                                                                                             
 1259 root      20   0  2680 1820 1408 R   0.7  0.4   0:00.18 top                     

play 48/24

 1237 root      20   0 44196  42m  15m S  33.2  8.5  38:23.41 squeezelite                                                                                                                                                                                             
 1331 root      20   0  2680 1752 1340 R   0.7  0.3   0:00.14 top                                          

play 88.2/32

 1237 root      20   0 44248  42m  15m S  53.1  8.5  17:12.34 squeezelite                                                                                                                                                                                             
    7 root      20   0     0    0    0 S   0.3  0.0   0:00.54 rcu_preempt            

play 96/32

 1237 root      20   0 44256  42m  15m S  59.0  8.5  40:03.08 squeezelite                                                                                                                                                                                             
  114 root      20   0  239m 8296 7992 S   0.3  1.6   0:16.89 systemd-journal


I really can’t imagine using Squeezelite without ffmpeg support, but in this configuration the background CPU overhead is significant at about 25%. MPD seems more economical with CPU demands - too bad it doesn't see the alsa plugins. With Squeezelite, CPU headroom might get tight with 192kHz files - I currently have no source material for testing because, to my ears, 96kHz is a sweet spot between SQ and data density. In some cases, it may be necessary to find more efficient LADSPA filter plugins.

There is a new filter set for crossovers that may be more CPU efficient than the RT series. Written recently and detailed here, they are cleverly designed to be strung together serially and allow individual coefficients to be specified. This permits much more customization of the roll-off. Unfortunately, I was unable to get the shared objects running in ALSA plugins. They reportedly DO work on an Rpi-2 (armhf platform) running within ecasound. So I hope to get back and debug on the BBB, once my hardware situation is sorted and unfinished equipment is finally running. Meanwhile, sound with the RT series filters is a good, viable start. This thread would be a great place to compare and contrast the sound and BBB-CPU draw of other LADSPA filters that you may try. There are many! Here is a partial list, and another is referenced below.

Finally, this is just a modest beginning. This area of sound reproduction will surely become more viable with improved methods, OS platforms, and faster SoCs. And the ‘secret sauce’ in all of it is to retain as much "bit-perfection" as possible in processing the signals. To my ears, the IIR filters can be very transparent - especially compared to some of the sub-optimal passive crossovers I have used!

So as we move ahead, let’s keep our eyes on the prize - to feel, through a very high resolution auditory experience, a greater sympathy with the diverse emotions captured in our music.

Best regards,

Frank

A few additional references that may be useful:

SectionPage | Linux Survival
Introduction to Sound Programming with ALSA | Linux Journal
A close look at ALSA
ALSA project - the C library reference: PCM (digital audio) plugins
Linux ALSA sound notes
Linux Audio Plug-Ins: A Look Into LADSPA - O'Reilly Media
Writing an ALSA Driver
http://www.musicdsp.org/archive.php?classid=3#24
ALSA Multi-channel Audio mini-HOWTO
http://alsa.opensrc.org/Low-pass_filter_for_subwoofer_channel_(HOWTO)
https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture#Unmute_5.1.2F7.1_sound
alsa.opensrc.org
ecasound
 
Last edited:
MPD seems more economical with CPU demands - too bad it doesn't see the alsa plugins.

MPD uses the same alsa-lib as squeezelite. The configuration is read by alsa-lib. Provided your alsa plugins config is system-wide (/etc/asound.conf), it should see the same alsa devices. Again, mpd often runs under a different user "mpd", we have already discussed that (it was the case). It is possible this user does not have access to the plugin files (alsa-lib is just a library, running under the user under which the calling program runs).

Nothing against squeezelite, it is a very nice sw.
 
Member
Joined 2007
Paid Member
It is possible this user does not have access to the plugin files (alsa-lib is just a library, running under the user under which the calling program runs).

Thank you so much for your continued interest! It would be really great to solve the MPD problem...

True, by default mpd.conf specifies user as "mpd".

So, I tried changing that configuration line two different ways: a) I commented it out, and b) I made it active and changed "mpd" to "root" [even though that is specifically discouraged!]. Each time I remembered to kill and re-start mpd. in neither case did mpd play through the alsa plugs. I tried one other thing as well. I specified the user group in mpd.conf to be "audio" and then I added mpd to the audio group using cat /etc/group | grep audio. Reboot and... again, failure.

I wonder about permissions... Below are the permissions for /etc/asound.conf and /etc/mpd.conf. Should mpd.conf have the extra read permission that asound.conf has?

-rw-r--r-- 1 root root 2240 Jul 23 14:40 asound.conf
-rw-r----- 1 mpd audio 14397 Jul 21 19:33 mpd.conf

Your help is invaluable because this stuff is still over my head... :confused:
 
I would keep mpd running under mpd. Of course the mpd user must be in group audio, so that it has access to alsa sound devices in /dev/snd/* . Check their perms with ls -l /dev/snd/* to see what I mean.

Please post mpd conf here.

Then I would run mpd in debug mode to see logs. See Music Player Daemon HOWTO Troubleshoot - Music Player Daemon Community Wiki for details. It would be great to post the detailed log. If run in the daemon mode, it should be somewhere in /var/log/

Or run in non-daemon mode and redirect all output to a file:

# /usr/bin/mpd --stdout --no-daemon --verbose &> mpd.log

Post the mpd.log here so that we can have a look at the logs.
 
Member
Joined 2007
Paid Member
Please post mpd conf here.
Code:
# An example configuration file for MPD.
# Read the user manual for documentation: http://www.musicpd.org/doc/user/
# or /usr/share/doc/mpd/user-manual.html


# Files and directories #######################################################
#
# This setting controls the top directory which MPD will search to discover the
# available audio files and add them to the daemon's online database. This 
# setting defaults to the XDG directory, otherwise the music directory will be
# be disabled and audio files will only be accepted over ipc socket (using
# file:// protocol) or streaming files over an accepted protocol.
#
music_directory		"/data"
#
# This setting sets the MPD internal playlist directory. The purpose of this
# directory is storage for playlists created by MPD. The server will use 
# playlist files not created by the server but only if they are in the MPD
# format. This setting defaults to playlist saving being disabled.
#
playlist_directory		"/var/lib/mpd/playlists"
#
# This setting sets the location of the MPD database. This file is used to
# load the database at server start up and store the database while the 
# server is not up. This setting defaults to disabled which will allow
# MPD to accept files over ipc socket (using file:// protocol) or streaming
# files over an accepted protocol.
#
db_file			"/var/lib/mpd/tag_cache"
# 
# These settings are the locations for the daemon log files for the daemon.
# These logs are great for troubleshooting, depending on your log_level
# settings.
#
# The special value "syslog" makes MPD use the local syslog daemon. This
# setting defaults to logging to syslog, otherwise logging is disabled.
#
log_file			"/var/log/mpd/mpd.log"
#
# This setting sets the location of the file which stores the process ID
# for use of mpd --kill and some init scripts. This setting is disabled by
# default and the pid file will not be stored.
#
pid_file			"/run/mpd/pid"
#
# This setting sets the location of the file which contains information about
# most variables to get MPD back into the same general shape it was in before
# it was brought down. This setting is disabled by default and the server 
# state will be reset on server start up.
#
state_file			"/var/lib/mpd/state"
#
# The location of the sticker database.  This is a database which
# manages dynamic information attached to songs.
#
sticker_file                   "/var/lib/mpd/sticker.sql"
#
###############################################################################


# General music daemon options ################################################
#
# This setting specifies the user that MPD will run as. MPD should never run as
# root and you may use this setting to make MPD change its user ID after
# initialization. This setting is disabled by default and MPD is run as the
# current user.
#
user				"mpd"
#
# This setting specifies the group that MPD will run as. If not specified
# primary group of user specified with "user" setting will be used (if set).
# This is useful if MPD needs to be a member of group such as "audio" to
# have permission to use sound card.
#
group                          "audio"
#
# This setting sets the address for the daemon to listen on. Careful attention
# should be paid if this is assigned to anything other then the default, any.
# This setting can deny access to control of the daemon. Choose any if you want
# to have mpd listen on every address
#
# For network
bind_to_address		"localhost"
#
# And for Unix Socket
#bind_to_address		"/run/mpd/socket"
#
# This setting is the TCP port that is desired for the daemon to get assigned
# to.
#
#port				"6600"
#
# This setting controls the type of information which is logged. Available 
# setting arguments are "default", "secure" or "verbose". The "verbose" setting
# argument is recommended for troubleshooting, though can quickly stretch
# available resources on limited hardware storage.
#
#log_level			"default"
#
# If you have a problem with your MP3s ending abruptly it is recommended that 
# you set this argument to "no" to attempt to fix the problem. If this solves
# the problem, it is highly recommended to fix the MP3 files with vbrfix
# (available as vbrfix in the debian archive), at which
# point gapless MP3 playback can be enabled.
#
#gapless_mp3_playback			"yes"
#
# Setting "restore_paused" to "yes" puts MPD into pause mode instead
# of starting playback after startup.
#
#restore_paused "no"
#
# This setting enables MPD to create playlists in a format usable by other
# music players.
#
#save_absolute_paths_in_playlists	"no"
#
# This setting defines a list of tag types that will be extracted during the 
# audio file discovery process. The complete list of possible values can be
# found in the mpd.conf man page.
#metadata_to_use	"artist,album,title,track,name,genre,date,composer,performer,disc"
#
# This setting enables automatic update of MPD's database when files in 
# music_directory are changed.
#
#auto_update    "yes"
#
# Limit the depth of the directories being watched, 0 means only watch
# the music directory itself.  There is no limit by default.
#
#auto_update_depth "3"
#
###############################################################################


# Symbolic link behavior ######################################################
#
# If this setting is set to "yes", MPD will discover audio files by following 
# symbolic links outside of the configured music_directory.
#
#follow_outside_symlinks	"yes"
#
# If this setting is set to "yes", MPD will discover audio files by following
# symbolic links inside of the configured music_directory.
#
#follow_inside_symlinks		"yes"
#
###############################################################################


# Zeroconf / Avahi Service Discovery ##########################################
#
# If this setting is set to "yes", service information will be published with
# Zeroconf / Avahi.
#
#zeroconf_enabled		"yes"
#
# The argument to this setting will be the Zeroconf / Avahi unique name for
# this MPD server on the network.
#
#zeroconf_name			"Music Player"
#
###############################################################################


# Permissions #################################################################
#
# If this setting is set, MPD will require password authorization. The password
# can setting can be specified multiple times for different password profiles.
#
#password                        "password@read,add,control,admin"
#
# This setting specifies the permissions a user has who has not yet logged in. 
#
#default_permissions             "read,add,control,admin"
#
###############################################################################


# Database #######################################################################
#

#database {
#       plugin "proxy"
#       host "other.mpd.host"
#       port "6600"
#}

# Input #######################################################################
#

input {
        plugin "curl"
#       proxy "proxy.isp.com:8080"
#       proxy_user "user"
#       proxy_password "password"
}

#
###############################################################################

# Audio Output ################################################################
#
# MPD supports various audio output types, as well as playing through multiple 
# audio outputs at the same time, through multiple audio_output settings 
# blocks. Setting this block is optional, though the server will only attempt
# autodetection for one sound card.
#
# An example of an ALSA output:
#
audio_output {
	type		"alsa"
	name            "Botic"
	device          "plughw:0"
	format "*:32:1"
	dsd_usb         "no"
	dsd_native      "yes"
	dsd_native_type "3"
	priority        "FIFO:32"
        period_time     "1"
	mixer_type      "software"
#	mixer_device	"default"	# optional
#	mixer_control	"PCM"		# optional
#	mixer_index	"0"		# optional
}
#
# An example of an OSS output:

#audio_output {
#	type		"oss"
#	name		"My OSS Device"
#	device		"/dev/dsp"	# optional
#	mixer_type      "hardware"      # optional
#	mixer_device	"/dev/mixer"	# optional
#	mixer_control	"PCM"		# optional
#}
#
# An example of a shout output (for streaming to Icecast):
#
#audio_output {
#	type		"shout"
#	encoding	"ogg"			# optional
#	name		"My Shout Stream"
#	host		"localhost"
#	port		"8000"
#	mount		"/mpd.ogg"
#	password	"hackme"
#	quality		"5.0"
#	bitrate		"128"
#	format		"44100:16:1"
#	protocol	"icecast2"		# optional
#	user		"source"		# optional
#	description	"My Stream Description"	# optional
#	url             "http://example.com"    # optional
#	genre		"jazz"			# optional
#	public		"no"			# optional
#	timeout		"2"			# optional
#	mixer_type      "software"              # optional
#}
#
# An example of a recorder output:
#
#audio_output {
#       type            "recorder"
#       name            "My recorder"
#       encoder         "vorbis"                # optional, vorbis or lame
#       path            "/var/lib/mpd/recorder/mpd.ogg"
##      quality         "5.0"                   # do not define if bitrate is defined
#       bitrate         "128"                   # do not define if quality is defined
#       format          "44100:16:1"
#}
#
# An example of a httpd output (built-in HTTP streaming server):
#
#audio_output {
#	type		"httpd"
#	name		"My HTTP Stream"
#	encoder		"vorbis"		# optional, vorbis or lame
#	port		"8000"
#	bind_to_address "0.0.0.0"               # optional, IPv4 or IPv6
#	quality		"5.0"			# do not define if bitrate is defined
#	bitrate		"128"			# do not define if quality is defined
#	format		"44100:16:1"
#	max_clients     "0"                     # optional 0=no limit
#}
#
# An example of a pulseaudio output (streaming to a remote pulseaudio server)
# Please see README.Debian if you want mpd to play through the pulseaudio
# daemon started as part of your graphical desktop session!
#
#audio_output {
#	type		"pulse"
#	name		"My Pulse Output"
#	server		"remote_server"		# optional
#	sink		"remote_server_sink"	# optional
#}
#
# An example of a winmm output (Windows multimedia API).
#
#audio_output {
#	type		"winmm"
#	name		"My WinMM output"
#	device		"Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
#		or
#	device		"0"		# optional
#	mixer_type	"hardware"	# optional
#}
#
# An example of an openal output.
#
#audio_output {
#	type		"openal"
#	name		"My OpenAL output"
#	device		"Digital Audio (S/PDIF) (High Definition Audio Device)" # optional
#}
#
## Example "pipe" output:
#
#audio_output {
#	type		"pipe"
#	name		"my pipe"
#	command		"aplay -f cd 2>/dev/null"
## Or if you're want to use AudioCompress
#	command		"AudioCompress -m | aplay -f cd 2>/dev/null"
## Or to send raw PCM stream through PCM:
#	command		"nc example.org 8765"
#	format		"44100:16:2"
#}
#
## An example of a null output (for no audio output):
#
#audio_output {
#	type		"null"
#	name		"My Null Output"
#	mixer_type      "none"                  # optional
#}
#
# If MPD has been compiled with libsamplerate support, this setting specifies 
# the sample rate converter to use.  Possible values can be found in the 
# mpd.conf man page or the libsamplerate documentation. By default, this is
# setting is disabled.
#
#samplerate_converter		"Fastest Sinc Interpolator"
#
###############################################################################


# Normalization automatic volume adjustments ##################################
#
# This setting specifies the type of ReplayGain to use. This setting can have
# the argument "off", "album", "track" or "auto". "auto" is a special mode that
# chooses between "track" and "album" depending on the current state of
# random playback. If random playback is enabled then "track" mode is used.
# See <http://www.replaygain.org> for more details about ReplayGain.
# This setting is off by default.
#
#replaygain			"album"
#
# This setting sets the pre-amp used for files that have ReplayGain tags. By
# default this setting is disabled.
#
#replaygain_preamp		"0"
#
# This setting sets the pre-amp used for files that do NOT have ReplayGain tags.
# By default this setting is disabled.
#
#replaygain_missing_preamp	"0"
#
# This setting enables or disables ReplayGain limiting.
# MPD calculates actual amplification based on the ReplayGain tags
# and replaygain_preamp / replaygain_missing_preamp setting.
# If replaygain_limit is enabled MPD will never amplify audio signal
# above its original level. If replaygain_limit is disabled such amplification
# might occur. By default this setting is enabled.
#
#replaygain_limit		"yes"
#
# This setting enables on-the-fly normalization volume adjustment. This will
# result in the volume of all playing audio to be adjusted so the output has 
# equal "loudness". This setting is disabled by default.
#
#volume_normalization		"no"
#
###############################################################################


# Character Encoding ##########################################################
#
# If file or directory names do not display correctly for your locale then you 
# may need to modify this setting.
#
filesystem_charset		"UTF-8"
#
# This setting controls the encoding that ID3v1 tags should be converted from.
#
id3v1_encoding			"UTF-8"
#
###############################################################################


# SIDPlay decoder #############################################################
#
# songlength_database:
#  Location of your songlengths file, as distributed with the HVSC.
#  The sidplay plugin checks this for matching MD5 fingerprints.
#  See http://www.c64.org/HVSC/DOCUMENTS/Songlengths.faq
#
# default_songlength:
#  This is the default playing time in seconds for songs not in the
#  songlength database, or in case you're not using a database.
#  A value of 0 means play indefinitely.
#
# filter:
#  Turns the SID filter emulation on or off.
#
#decoder {
#       plugin                  "sidplay"
#       songlength_database     "/media/C64Music/DOCUMENTS/Songlengths.txt"
#       default_songlength      "120"
#       filter "true"
#}
#
###############################################################################

realtime_option {
	memlock                 "yes"
	stack_reserve           "1024"
	heap_reserve            "10240"
	main_priority           "OTHER:0"
	player_priority         "FIFO:32"
	decoder_priority        "FIFO:31"
	update_priority         "OTHER:0"
}
# /usr/bin/mpd --stdout --no-daemon --verbose &> mpd.log

Post the mpd.log here so that we can have a look at the logs.
Code:
config_file: loading file /etc/mpd.conf
rt_opt: realtime_option(set_parameter): memlock enable  stack_reserve : 1048576   heap_reserve : 10485760
rt_opt: realtime_option(set_parameter): main_priority  policy 0  priority 0
rt_opt: realtime_option(set_parameter): io_priority  policy -1  priority 0
rt_opt: realtime_option(set_parameter): player_priority  policy 1  priority 32
rt_opt: realtime_option(set_parameter): decoder_priority  policy 1  priority 31
rt_opt: realtime_option(set_parameter): update_priority  policy 0  priority 0
rt_opt: realtime_option(init_output_priority_tab): output priority name Botic policy 1  priority 32 timerslack 100
rt_opt: realtime_option(rtopt_change_priority): name main_priority   policy 0  priority 0
rt_opt: realtime_option(rtopt_change_thread_priority): name main_priority not changed
path: SetFSCharset: fs charset is: UTF-8
libsamplerate: libsamplerate converter 'Fastest Sinc Interpolator'
opus: libopus 1.1
wildmidi: configuration file does not exist: /etc/timidity/timidity.cfg
db: reading DB
curl: version 7.26.0
curl: with GnuTLS/2.12.20
soundcloud: disabling the soundcloud playlist plugin because API key is not set
daemon: opening pid file
daemon: writing pid file
avahi: Initializing interface
avahi: Client changed to state 101
avahi: Client is CONNECTING
state_file: Loading state file /var/lib/mpd/state
rt_opt: realtime_option(rtopt_change_priority): name player_priority   policy 1  priority 32
rt_opt: realtime_option(change_priority): name player_priority  policy 1   priority 32
rt_opt: realtime_option(rtopt_change_priority): name decoder_priority   policy 1  priority 31
rt_opt: realtime_option(change_priority): name decoder_priority  policy 1   priority 31
rt_opt: realtime_option(rtopt_change_output_priority): name Botic   policy 1  priority 32
rt_opt: realtime_option(rtopt_change_thread_priority): name Botic not changed
rt_opt: realtime_option(output_timerslack): name Botic   policy 1  timerslack 100
rt_opt: set timerslack 100 usec
rt_opt: output:Botic  timerslack 100
rt_opt: realtime_option(rtopt_memlock): stack_reserve 1048576
rt_opt: realtime_option(rtopt_memlock): heap_reserve 10485760
client: [0] opened from 127.0.0.1:54866
client: [0] process command "status"
client: [0] command returned 0

...snip...

client: [0] process command "status"
client: [0] command returned 0
state_file: Saving state file /var/lib/mpd/state
avahi: Shutting down interface
listen: listen_global_finish called
client: [0] closed
main: db_finish took 0.000000 seconds
 
Member
Joined 2007
Paid Member
You need to use the device "default" which uses your filter plugin setup.

The only 'device' settings that give any output to the DACs are "hw:0..." or "plughw:0...".

I have tried virtually every other possibility. With "default" specified the system behaves as if it is playing music but there is silence and the 'time played' indicator from mpc stays at 0:00. :scratch:
 
Last edited:
Member
Joined 2007
Paid Member
Oh yes, one other way to get sound from mpd: create an alsa loopback card, then set mpd output device to "hw:1,0". The alsa plugins still never see that data, but you can use hw:1 as an input to ecasound, and use hw:0,0 as the ecasound output. ...and just a reminder that the same behavior was found in the version of MPD that is included with Volumio 1.5...

I know the casual reader may not find this troubleshooting to be a riveting commentary, but getting MPD running as needed would be great! :D
 
Last edited:
OK, I see.

Let's have a look at the mpd alsa setup first.

Why is period_time = 1? This means asking the soundcard driver to provide notification period as close to 1 microsecond as possible. Is it needed? What happens if you remove the setting alltogether and let mpd setup buffer/period sizes on its own? What is corresponding setup in squeezelite? I did not see any mentioned in that post.

In your hw_params alsa dump (I assume running with squeezelite) alsa reports period_size = 1764 which is 10ms FramesPeriods - AlsaProject

I am not saying this will solve but is the first step in troubleshooting - figuring out the parameters.
 
Member
Joined 2007
Paid Member
Thanks for these suggestions! I tried greater period_time values and also commenting the line out. When the output 'device' is hw:0,0, all period times produce sound.

When 'device' is "default", no change - meaning no sound. However, period_time = 1 gave two different reports; it changed after a reboot:
at first - "playing"
Code:
root@botic:/# mpc play   # ...with period_time=1
Track4.aif
[playing] #1/3   0:00/5:03 (0%)
volume:100%   repeat: off   random: off   single: off   consume: off
root@botic:/# mpc stop
After changing period_time and then a reboot all the different period times (including "1" - and device="default") gave "paused"...
Code:
root@botic:/# mpc play
Track4.aif
[paused]  #1/3   0:00/5:03 (0%)
volume:100%   repeat: off   random: off   single: off   consume: off
ERROR: Failed to open audio output

root@botic:/# mpc outputs
Output 1 (Botic) is enabled
 
Member
Joined 2007
Paid Member
OK, I have some light to shed on this problem. In mpd.conf I changed 'device' to "default" and I commented-out 'period_time'. After I attempted to play music with mpc I saw the following in mpd.log:
Code:
Jul 27 05:02 : avahi: Initializing interface
Jul 27 05:02 : avahi: Client changed to state 101
Jul 27 05:02 : avahi: Client is CONNECTING
Jul 27 05:02 : state_file: Loading state file /var/lib/mpd/state
Jul 27 05:02 : rt_opt: realtime_option(rtopt_change_priority): name player_priority   policy 1  priority 32
Jul 27 05:02 : rt_opt: realtime_option(change_priority): name player_priority  policy 1   priority 32
Jul 27 05:02 : rt_opt: realtime_option(rtopt_change_priority): name decoder_priority   policy 1  priority 31
Jul 27 05:02 : rt_opt: realtime_option(rtopt_change_output_priority): name Botic   policy 1  priority 32
Jul 27 05:02 : rt_opt: realtime_option(rtopt_change_thread_priority): name Botic not changed
Jul 27 05:02 : rt_opt: realtime_option(output_timerslack): name Botic   policy 1  timerslack 100
Jul 27 05:02 : rt_opt: set timerslack 100 usec
Jul 27 05:02 : rt_opt: output:Botic  timerslack 100
Jul 27 05:02 : rt_opt: realtime_option(change_priority): name decoder_priority  policy 1   priority 31
Jul 27 05:02 : playlist: play 0:"Track4.aif"
Jul 27 05:02 : decoder_thread: probing plugin sndfile
Jul 27 05:02 : decoder: audio_format=44100:32:2, seekable=true
Jul 27 05:02 : alsa_output: opened default type=PLUG
Jul 27 05:02 : alsa_output: format=S32_LE (Signed 32 bit Little Endian)
Jul 27 05:02 : alsa_output: buffer: size=2..4096 time=45..92880
Jul 27 05:02 : alsa_output: period: size=0..2049 time=22..46440
Jul 27 05:02 : alsa_output: default period_time = buffer_time/4 = 92879/4 = 23219
Jul 27 05:02 : alsa_output: Failed to open "Botic" [alsa]: Error opening ALSA device "default" (snd_pcm_hw_params): Invalid argument
Jul 27 05:02 : output: Failed to open audio output
Jul 27 05:02 : player: problems opening audio device while playing "Track4.aif"
Jul 27 05:02 : alsa_output: opened default type=PLUG
Jul 27 05:02 : alsa_output: format=S32_LE (Signed 32 bit Little Endian)
Jul 27 05:02 : alsa_output: buffer: size=2..4096 time=45..92880
Jul 27 05:02 : alsa_output: period: size=0..2049 time=22..46440
Jul 27 05:02 : alsa_output: default period_time = buffer_time/4 = 92879/4 = 23219
Jul 27 05:02 : alsa_output: Failed to open "Botic" [alsa]: Error opening ALSA device "default" (snd_pcm_hw_params): Invalid argument
Jul 27 05:02 : output: Failed to open audio output
Jul 27 05:02 : rt_opt: realtime_option(rtopt_memlock): stack_reserve 4194304
Jul 27 05:02 : rt_opt: realtime_option(rtopt_memlock): heap_reserve 41943040
Jul 27 05:02 : playlist: queue song 1:"crazylove.wav"
Jul 27 05:02 : client: [0] opened from [::1]:35763
Jul 27 05:02 : client: [0] process command "status"
Jul 27 05:02 : client: [0] command returned 0
Jul 27 05:02 : client: [0] process command "status"
Jul 27 05:02 : client: [0] command returned 0
Jul 27 05:02 : client: [0] process command "currentsong"
Jul 27 05:02 : client: [0] command returned 0
Jul 27 05:02 : client: [0] process command "playlistinfo "1""
The (snd_pcm_hw_params) invalid argument made me suspicious, so I changed /etc/asound.conf so that the pcm!default plug slaved directly to the last output plug. Sound! ...meaning "default" was an acceptable output in mpd.conf, and the issue lies in part with the type-ladspa plugs. If I directed pcm!default only to the simple delay plug but set all the delay parameters at 0, still 'ERROR: Failed to open audio output'.

So I'm trying to learn what parameters SoX or squeezelite are using because they work with the type-ladspa plugins. But the search will have to continue in the AM.
 
In fact, "default" is the default name. If you did not specify any alsa device, the "default" would have been used. It always works that way.

The problem is with the chain not accepting your parameters.

Why do you have just 1 channel in your format (*:32:1)? Is it for mono chain only (testing)? Your asound.conf looks stereo (x2) though...

I would comment out the format line.

Also the dsd lines are a bit stinky in this setup. Look here https://github.com/lintweaker/mpd-dsd-018/blob/master/README-native-DSD Comment them out as well.

The automatically chosen period_time of 23 ms is sane now, unlike the minimum possible (probably just hundreds of microseconds) induced by the original period_size=1 option.

Please post verbose logs for the simplified mpd.conf.
 
Member
Joined 2007
Paid Member
Why do you have just 1 channel in your format (*:32:1)? Is it for mono chain only (testing)? Your asound.conf looks stereo (x2) though...

I would comment out the format line.

Done. I questioned the '1' but it is listed that way in Miero's documentation to force 32 bit output [SQ with volume control in software?].
Also the dsd lines are a bit stinky in this setup. Look here https://github.com/lintweaker/mpd-dsd-018/blob/master/README-native-DSD Comment them out as well.
Done. BTW, I see in the above github reference by lintweaker:
# BOTIC fixup: request the lowest period time
period_time "1"

That's probably the original source of that param... I like the approach to get PCM working first, then see what is happening with DSD. For now, same errors...
Please post verbose logs for the simplified mpd.conf.

Code:
Jul 27 15:23 : avahi: Initializing interface
Jul 27 15:23 : avahi: Client changed to state 101
Jul 27 15:23 : avahi: Client is CONNECTING
Jul 27 15:23 : state_file: Loading state file /var/lib/mpd/state
Jul 27 15:23 : rt_opt: realtime_option(rtopt_change_priority): name player_priority   policy 1  priority 32
Jul 27 15:23 : rt_opt: realtime_option(change_priority): name player_priority  policy 1   priority 32
Jul 27 15:23 : rt_opt: realtime_option(rtopt_change_priority): name decoder_priority   policy 1  priority 31
Jul 27 15:23 : rt_opt: realtime_option(rtopt_change_output_priority): name Botic   policy 1  priority 32
Jul 27 15:23 : rt_opt: realtime_option(rtopt_change_thread_priority): name Botic not changed
Jul 27 15:23 : rt_opt: realtime_option(output_timerslack): name Botic   policy 1  timerslack 100
Jul 27 15:23 : rt_opt: set timerslack 100 usec
Jul 27 15:23 : rt_opt: output:Botic  timerslack 100
Jul 27 15:23 : rt_opt: realtime_option(change_priority): name decoder_priority  policy 1   priority 31
Jul 27 15:23 : playlist: play 0:"Track4.aif"
Jul 27 15:23 : decoder_thread: probing plugin sndfile
Jul 27 15:23 : decoder: audio_format=44100:32:2, seekable=true
Jul 27 15:23 : alsa_output: opened default type=PLUG
Jul 27 15:23 : alsa_output: format=S32_LE (Signed 32 bit Little Endian)
Jul 27 15:23 : alsa_output: buffer: size=2..4096 time=45..92880
Jul 27 15:23 : alsa_output: period: size=0..2049 time=22..46440
Jul 27 15:23 : alsa_output: default period_time = buffer_time/4 = 92879/4 = 23219
Jul 27 15:23 : alsa_output: Failed to open "Botic" [alsa]: Error opening ALSA device "default" (snd_pcm_hw_params): Invalid argument
Jul 27 15:23 : output: Failed to open audio output
Jul 27 15:23 : player: problems opening audio device while playing "Track4.aif"
Jul 27 15:23 : alsa_output: opened default type=PLUG
Jul 27 15:23 : alsa_output: format=S32_LE (Signed 32 bit Little Endian)
Jul 27 15:23 : alsa_output: buffer: size=2..4096 time=45..92880
Jul 27 15:23 : alsa_output: period: size=0..2049 time=22..46440
Jul 27 15:23 : alsa_output: default period_time = buffer_time/4 = 92879/4 = 23219
Jul 27 15:23 : alsa_output: Failed to open "Botic" [alsa]: Error opening ALSA device "default" (snd_pcm_hw_params): Invalid argument
Jul 27 15:23 : output: Failed to open audio output
Jul 27 15:23 : rt_opt: realtime_option(rtopt_memlock): stack_reserve 1048576
Jul 27 15:23 : rt_opt: realtime_option(rtopt_memlock): heap_reserve 10485760
Jul 27 15:23 : playlist: queue song 1:"crazylove.wav"
Jul 27 15:23 : client: [0] opened from [::1]:55942
Jul 27 15:23 : client: [0] process command "status"
Jul 27 15:23 : client: [0] command returned 0
Jul 27 15:23 : client: [0] process command "status"
Jul 27 15:23 : client: [0] command returned 0
Jul 27 15:23 : client: [0] process command "currentsong"
Jul 27 15:23 : client: [0] command returned 0
Jul 27 15:23 : client: [0] process command "playlistinfo "1""
...and output section of mpd.conf:
Code:
audio_output {
        type            "alsa"
        name            "Botic"
        device          "default"
#       format          "*:32:2"
#       dsd_usb         "no"
#       dsd_native      "yes"
#       dsd_native_type "3"
        priority        "FIFO:32"
#        period_time     "1"
        mixer_type      "software"
#       mixer_device    "default"       # optional
#       mixer_control   "PCM"           # optional
#       mixer_index     "0"             # optional
}
 
Status
This old topic is closed. If you want to reopen this topic, contact a moderator using the "Report Post" button.