I am attempting to control my stereo from my Android phone, using mpd. I have an Ubuntu 16.04 box hooked up to the stereo system, via a USB -> Toslink -> DSP -> amps route. I am trying to drive jackd through the mpd daemon. . . and I am having some troubles.
So far I have been able to:
1) Get mpd to play music locally on my Ubuntu box. MPDroid (on my phone) works fine with mpd at this level, driving the music on my Ubuntu box.
2) Drive my stereo system through jack from the Ubuntu box, using jack-plumbing and mplayer.
I strongly suspect my problem is I do not understand what mpd.conf needs to drive jack.
Here is my current mpd.conf audio_output section:
audio_output {
type "jack"
name "my JACK device"
device "hw:1,0"
autostart "yes"
destination_ports "playback_9, playback_10"
}
I chose destination_ports 9 and 10 because this is producing a Toslink signal. But I strongly suspect that's what I've formatted incorrectly.
and the version that plays locally:
audio_output {
type "alsa"
name "My ALSA Device"
device "hw:0,0" # optional
mixer_type "hardware" # optional
mixer_device "default" # optional
mixer_control "PCM" # optional
mixer_index "0" # optional
}
Here are a few things that will likely help. jack-plumbing works fine for piping mplayer output to my usb-audio device. The .jack-plumbing file that works is:
(connect "MPlayer \[[0-9]+\]:out_0" "system:playback_9")
(connect "MPlayer \[[0-9]+\]:out_1" "system:playback_10")
aplay -l output:
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: ALC269VC Analog [ALC269VC Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: USBStreamer [USBStreamer], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 2: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2]
Subdevices: 1/1
Subdevice #0: subdevice #0
I've found the documentation available for mpd online a little difficult to read, and it tends to get a little vague when it comes to using it with jackd. Any advice? I imagine I'm making a pretty simple mistake. Thanks for any help.
edit: with the "jack" version of mpd.conf in /etc/mpd.conf, I get this as output to the "sudo systemctl status mpd" command:
● mpd.service - Music Player Daemon
Loaded: loaded (/lib/systemd/system/mpd.service; disabled; vendor preset: enabled)
Active: active (running) since Sun 2016-07-03 23:58:34 PDT; 52s ago
Main PID: 3651 (mpd)
CGroup: /system.slice/mpd.service
└─3651 /usr/bin/mpd --no-daemon
Jul 03 23:58:34 rybu-ThinkPad-W530 systemd[1]: Started Music Player Daemon.
Jul 03 23:58:38 rybu-ThinkPad-W530 pulseaudio[3665]: [pulseaudio] module-jackdbus-detect.c: Unable to contact D-Bus session bus: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
Jul 03 23:58:38 rybu-ThinkPad-W530 pulseaudio[3665]: [pulseaudio] module.c: Failed to load module "module-jackdbus-detect" (argument: "channels=2"): initialization failed.
Jul 03 23:58:38 rybu-ThinkPad-W530 pulseaudio[3665]: [pulseaudio] main.c: Module load failed.
Jul 03 23:58:38 rybu-ThinkPad-W530 pulseaudio[3665]: [pulseaudio] server-lookup.c: Unable to contact D-Bus: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
Jul 03 23:58:38 rybu-ThinkPad-W530 pulseaudio[3665]: [pulseaudio] main.c: Unable to contact D-Bus: org.freedesktop.DBus.Error.NotSupported: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
Jul 03 23:58:38 rybu-ThinkPad-W530 pulseaudio[3665]: [pulseaudio] bluez5-util.c: GetManagedObjects() failed: org.freedesktop.DBus.Error.AccessDenied: Rejected send message, 2 matched rules; type="method_call", sender=":1.177" (uid=122 pid=3665 comm="/usr/bin/pulseaudio --start --log-target=syslog ") interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" error name="(unset)" requested_reply="0" destination="org.bluez" (uid=0 pid=1018 comm="/usr/lib/bluetooth/bluetoothd ")
I suppose I should mention one other thing. After installing mpd, my system boot times have become significantly slower. Sometimes it looks like the computer is doing nothing, so I reboot the system again. Sometimes it takes 3 reboots before I can get to the login prompt.
edit 2: Perhaps I can solve this problem by avoiding jack entirely. Here is the /var/lib/alsa/asound.state file, the portion relevant to my usbaudio device:
state.USBStreamer {
control.1 {
iface PCM
name 'Playback Channel Map'
value.0 0
value.1 0
value.2 0
value.3 0
value.4 0
value.5 0
value.6 0
value.7 0
value.8 0
value.9 0
comment {
access read
type INTEGER
count 10
range '0 - 36'
}
}
control.2 {
iface PCM
name 'Capture Channel Map'
value.0 0
value.1 0
value.2 0
value.3 0
value.4 0
value.5 0
value.6 0
value.7 0
value.8 0
value.9 0
comment {
access read
type INTEGER
count 10
range '0 - 36'
}
}
control.3 {
iface MIXER
name 'USBStreamer Output Playback Switch'
value.0 true
value.1 true
value.2 true
value.3 true
value.4 true
value.5 true
value.6 true
value.7 true
value.8 true
value.9 true
comment {
access 'read write'
type BOOLEAN
count 10
}
}
control.4 {
iface MIXER
name 'USBStreamer Output Playback Switch'
index 1
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.5 {
iface MIXER
name 'USBStreamer Output Playback Volume'
value.0 255
value.1 255
value.2 255
value.3 255
value.4 255
value.5 255
value.6 255
value.7 255
value.8 255
value.9 255
comment {
access 'read write'
type INTEGER
count 10
range '0 - 255'
dbmin -12750
dbmax 0
dbvalue.0 0
dbvalue.1 0
dbvalue.2 0
dbvalue.3 0
dbvalue.4 0
dbvalue.5 0
dbvalue.6 0
dbvalue.7 0
dbvalue.8 0
dbvalue.9 0
}
}
control.6 {
iface MIXER
name 'USBStreamer Output Playback Volume'
index 1
value 152
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -12750
dbmax 0
dbvalue.0 -5150
}
}
control.7 {
iface MIXER
name 'USBStreamer Clock Selector'
value 'USBStreamer Internal Clock'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'USBStreamer Internal Clock'
item.1 'USBStreamer TOSLINK Clock'
}
}
control.8 {
iface MIXER
name 'Mic Capture Switch'
value.0 true
value.1 true
value.2 true
value.3 true
value.4 true
value.5 true
value.6 true
value.7 true
value.8 true
value.9 true
comment {
access 'read write'
type BOOLEAN
count 10
}
}
control.9 {
iface MIXER
name 'Mic Capture Switch'
index 1
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.10 {
iface MIXER
name 'Mic Capture Volume'
value.0 255
value.1 255
value.2 255
value.3 255
value.4 255
value.5 255
value.6 255
value.7 255
value.8 255
value.9 255
comment {
access 'read write'
type INTEGER
count 10
range '0 - 255'
dbmin -12750
dbmax 0
dbvalue.0 0
dbvalue.1 0
dbvalue.2 0
dbvalue.3 0
dbvalue.4 0
dbvalue.5 0
dbvalue.6 0
dbvalue.7 0
dbvalue.8 0
dbvalue.9 0
}
}
control.11 {
iface MIXER
name 'Mic Capture Volume'
index 1
value 255
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -12750
dbmax 0
dbvalue.0 0
}
}
If I'm reading that correctly it looks like perhaps the relevant audio output channels are muted? Channels 8 and 9 are the ones relevant for audio output over a Toslink cable, so I suspect I need to modify those values and perhaps I can do a direct ALSA output from mpd.
Strangely, if I delete asound.state and then re-create it with a "sudo alsactl store" command, the channel mapping is completely different:
state.USBStreamer {
control.1 {
iface PCM
name 'Playback Channel Map'
value.0 3
value.1 4
value.2 7
value.3 8
value.4 5
value.5 6
value.6 12
value.7 13
value.8 11
value.9 9
comment {
access read
type INTEGER
count 10
range '0 - 36'
}
}
But it still produces no sound.
Another thing I'm considering is that since JACK can play to my usbstreamer, and it is using ALSA, so perhaps I can just figure out what settings its using with ALSA, and duplicate them. The /proc/asound/card1 directory has the current settings for this card, so I start it playing with jack and mplayer, and read off the files.
stream0:
miniDSP USBStreamer at usb-0000:00:14.0-2, high speed : USB Audio
Playback:
Status: Running
Interface = 1
Altset = 1
Packet Size = 280
Momentary freq = 44100 Hz (0x5.8330)
Feedback Format = 16.16
Interface 1
Altset 1
Format: S32_LE
Channels: 10
Endpoint: 1 OUT (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000
Data packet interval: 125 us
Capture:
Status: Running
Interface = 2
Altset = 1
Packet Size = 280
Momentary freq = 44100 Hz (0x5.8333)
Interface 2
Altset 1
Format: S32_LE
Channels: 10
Endpoint: 2 IN (ASYNC)
Rates: 44100, 48000, 88200, 96000, 176400, 192000
Data packet interval: 125 us
usbbus:
003/005
usbmixer:
USB Mixer: usb_id=0x27520016, ctrlif=0, ctlerr=0
Card: miniDSP USBStreamer at usb-0000:00:14.0-2, high speed
Unit: 10
Control: name="USBStreamer Output Playback Volume", index=1
Info: id=10, control=2, cmask=0x0, channels=1, type="S16"
Volume: min=-32640, max=0, dBmin=-12750, dBmax=0
Unit: 10
Control: name="USBStreamer Output Playback Volume", index=0
Info: id=10, control=2, cmask=0x3ff, channels=10, type="S16"
Volume: min=-32640, max=0, dBmin=-12750, dBmax=0
Unit: 10
Control: name="USBStreamer Output Playback Switch", index=1
Info: id=10, control=1, cmask=0x0, channels=1, type="INV_BOOLEAN"
Volume: min=0, max=1, dBmin=0, dBmax=0
Unit: 10
Control: name="USBStreamer Output Playback Switch", index=0
Info: id=10, control=1, cmask=0x3ff, channels=10, type="INV_BOOLEAN"
Volume: min=0, max=1, dBmin=0, dBmax=0
Unit: 11
Control: name="Mic Capture Volume", index=1
Info: id=11, control=2, cmask=0x0, channels=1, type="S16"
Volume: min=-32640, max=0, dBmin=-12750, dBmax=0
Unit: 11
Control: name="Mic Capture Volume", index=0
Info: id=11, control=2, cmask=0x3ff, channels=10, type="S16"
Volume: min=-32640, max=0, dBmin=-12750, dBmax=0
Unit: 11
Control: name="Mic Capture Switch", index=1
Info: id=11, control=1, cmask=0x0, channels=1, type="INV_BOOLEAN"
Volume: min=0, max=1, dBmin=0, dBmax=0
Unit: 11
Control: name="Mic Capture Switch", index=0
Info: id=11, control=1, cmask=0x3ff, channels=10, type="INV_BOOLEAN"
Volume: min=0, max=1, dBmin=0, dBmax=0
Unit: 40
Control: name="USBStreamer Clock Selector", index=0
Info: id=40, control=1, cmask=0x0, channels=1, type="U8"
Volume: min=1, max=2, dBmin=0, dBmax=0
pcm0p/info:
card: 1
device: 0
subdevice: 0
stream: PLAYBACK
id: USB Audio
name: USB Audio
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 0
pcm0p/sub0/hw_params:
access: MMAP_INTERLEAVED
format: S32_LE
subformat: STD
channels: 10
rate: 44100 (44100/1)
period_size: 1024
buffer_size: 2048
pcm0p/sub0/info
card: 1
device: 0
subdevice: 0
stream: PLAYBACK
id: USB Audio
name: USB Audio
subname: subdevice #0
class: 0
subclass: 0
subdevices_count: 1
subdevices_avail: 0
pcm0p/sub0/status
state: RUNNING
owner_pid : 12545
trigger_time: 50245.966761737
tstamp : 0.000000000
delay : 2010
avail : 72
avail_max : 1029
-----
hw_ptr : 325870664
appl_ptr : 325872640
pcm0p/sub0/sw_params:
tstamp_mode: NONE
period_step: 1
avail_min: 1024
start_threshold: 0
stop_threshold: 2048
silence_threshold: 0
silence_size: 0
boundary: 4611686018427387904
Hmm, if the information on channels is in there, it's cleverly hidden!
Volker Schatz describes setting up an ALSA device to switch channels. It looks like it's done a different way than just playing around with the playback channel map:
http://www.volkerschatz.com/noise/alsa.html
The ttable appears to be a device for channel mixing, and if you use integer entries (0 and 1), for channel switching. Finally this is starting to make sense. The i.j notation are pairs coordinates, describing the entries of a square matrix.
edit: Some progress. The "aplay -L" command gives a list of device names. For this usbstreamer, it gives:
sysdefault:CARD=USBStreamer
USBStreamer, USB Audio
Default Audio Device
front:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
Front speakers
surround21:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
2.1 Surround output to Front and Subwoofer speakers
surround40:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
4.0 Surround output to Front and Rear speakers
surround41:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
4.1 Surround output to Front, Rear and Subwoofer speakers
surround50:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
5.0 Surround output to Front, Center and Rear speakers
surround51:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
5.1 Surround output to Front, Center, Rear and Subwoofer speakers
surround71:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
7.1 Surround output to Front, Center, Side, Rear and Woofer speakers
iec958:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
IEC958 (S/PDIF) Digital Audio Output
dmix:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
Direct sample mixing device
dsnoop:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
Direct sample snooping device
hw:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
Direct hardware device without any conversions
plughw:CARD=USBStreamer,DEV=0
USBStreamer, USB Audio
Hardware device with all software conversions
These device names are very handy, from here you can run the command:
speaker-test -c 10 -t sin -F S32_LE -D front:USBStreamer
which runs through all the speakers on that device. Channels 8 and 9 (as expected) produce the sin wave sound on the left and right speakers respectively.
So I think this means I should be able to get direct ALSA output to my speakers using a ttable construction in asound.state. I would imagine the Playback Channel Map might allow for this as well, but after quite a bit of fiddling-around with it, it's unclear to me how to make it work.
update:
I modified the control.1 portion of the asound.state file to be:
control.1 {
iface PCM
name 'Playback Channel Map'
value.0 0
value.1 0
value.2 0
value.3 0
value.4 0
value.5 0
value.6 0
value.7 0
value.8 3
value.9 4
comment {
access read
type INTEGER
count 10
range '0 - 36'
}
}
and it almost works. Mplayer will not play to alsa:device=hw=1.0 but the error message is that I'm sending the wrong format to the device. ALSA thinks the device only accepts S32LE. Technically, I think it's an S24LE device. I'll contact the manufacturer to clear this up.
So I add -format s32le to the mplayer command line and stuff comes out of the speakers! Only, it's a bit of a jumble. It's playing too fast and. . . something else is going on. There's some kind of frequency distortion. I suspect what's happening is it's sending s16le data as if it's s32le data, so there's a bit of a shuffling (temporally) of the data, and a pitch-shift, and it's playing too fast.
So now to get this working I need to know how to convers the s16le data to proper s24le, and then format it as s32le so the usb device is happy.
update:
speaker-test -c 10 -t sin -D plughw:USBStreamer
works fine, and converts S16_LE to S32_LE.
Unfortunately,
aplay -Dplughw:USBStreamer ./blah.wav
does not work. Perhaps the channel mapping is off for this device?
The Deadbeef software plays to the usbstreamer with little effort. I give it the hw:USBStreamer device, and tell it to do all 8->16->24 bit conversions and it works like a charm.
Problem solved.
pcm.usbSTR { type hw card USBStreamer device 0 } pcm.usbREMAP { type plug slave.pcm usbSTR ttable.0.8 1 ttable.1.9 1 } pcm.!default { type plug slave.pcm usbREMAP } ctl.!default { type plug slave.pcm usbREMAP }
Make the above the contents of /etc/asound.conf
This file (usually) does not exist in Ubuntu or LUbuntu, but if you create it, the usbstreamer becomes the default ALSA device and the channels are mapped appropriately.
This allows you to make the audio_output section of /etc/mpd.conf just the "type" and "name" fields, "alsa" and "whatever you want" respectively.