Redirect SPDIF-INPUT to Hifiberry

Hi!
A few months ago I bought a HiFiBerry DAC - RCA+ in order to get some decent quality audio when watching on Kodi.
Today I bought a Sweex 7.1 USB Soundcard with SPDIF-Input. This one: http://www.sweex.com/nl/computer/audio/geluidskaart-usb-71-550512283

Now I want to configure the Raspberry Pi (which is running OSMC) to forward the USB SPDIF-Input to the HifiBerry.

The reason is I want to connect my TV (which has SPDIF output) to the Raspberry Pi so I can have decent audio while watching cable TV (or actually, netflix through chromecast).

Can anyone help with this configuration?

I can probably use the Sweex soundcard for everything but the Hifiberry has (should have) better audio

That sounds like a challenge. Kodi/OSMC isn’t really set up to deal with audio-in ports, except for playing optical discs. It should be possible using just ALSA, the crudest way would be to pipe the stream from arecord to aplay, perhaps using a FIFO.

Then there’s pulseaudio and jack which can handle routing audio from one device to another. If you manage to get it going, let us know!

All commands are to be run as the osmc user!

You have to change the device-names to your system!

sudo apt-get install pulseaudio
reboot

(This installs pulseaudio v10 as of 1March 2020. See below how to install PA v13. Recommended if you feel comfortable)

Debugtip (“No PulseAudio daemon runni…”)

Fix pacmd “No PulseAudio daemon running, or not running as session daemon” error by locating the runtime folder in /home/osmc/.config/pulse/.....-runtime/ And set the proper PULSE_RUNTIME_PATH environment variableexport PULSE_RUNTIME_PATH="/home/osmc/.config/pulse/ad878236c70e4d039bd7de40dbff260a-runtime/"

If this doesn’t work. Verify that pulse is actually run:
ps aux | grep pulse
If it isn’t, try starting pulseaudio in verbose mode to figure out the problem:
pulseaudio -vvvvv
Good luck…!

pacmd should now work.

List output sources:

pacmd list-sinks

List input sources:

pacmd list-sources
Note that iec958 / SPDIF is not listed as a possible input!. But first, we shall:

Set Hifiberry as default sink (audio output)

sudo nano /etc/pulse/default.pa
Add at the end:

set-default-sink alsa_output.platform-soc_sound.analog-stereo

Restart OSMC/Kodi to reinit:
sudo systemctl restart mediacenter

To test; just use Kodi. Make sure Kodi’s Audio output device is set to “ALSA Playback/recording through the PulseAudio sound server”. Alternatively, wget a sound-file from http://www.pacdv.com/sounds/voices-1.html and play it with:
aplay hi-1.wav

ENABLE iec958-stereo (SPDIF-INPUT) profile

source: PulseAudio/Troubleshooting - ArchWiki

Source 2: Recording S/PDIF (SPDIF) under Linux - LinuxMusicians

Edit March 2020:
For my CM106-compatible USB set; I had to configure my CM106 to go into SPDIF-mode.

amixer -c Device scontrols  # See available controls
amixer -c Device get 'PCM Capture Source' # Get current and availble settings for 'PCM Capture Source'
amixer -c Device set 'PCM Capture Source' 'IEC958 In' # Set it to IEC958 In (aka spdif)
alsactl store # permanently store alsamixer configuration

After, configure pulseaudio to use iec958:

pacmd list-cards | less

Look for card-name. We want to enable the input:iec958-stereo profile

sudo nano /etc/pulse/default.pa
add line:

set-card-profile alsa_card.usb-0d8c_USB_Sound_Device-00 input:iec958-stereo

(or set-card-profile alsa_card.usb-0d8c_USB_Sound_Device-00 input:analog-stereo for mic-in)
I also had to change the chosen port for analog input. pacmd list-sinks is your friend:

set-source-port alsa_input.usb-0d8c_USB_Sound_Device-00.analog-stereo iec958-stereo-input

Then restart OSMC/Kodi to reinitialize pulseaudio:
sudo systemctl restart mediacenter

Forward the source to the sink

module-loopback options: Modules
load-module module-loopback source_dont_move="true" latency_msec=40 max_latency_msec=300 fast_adjust_threshold_msec=100 source=alsa_input.usb-0d8c_USB_Sound_Device-00.iec958-stereo

Finally…

restart kodi again. It should work :slight_smile:
sudo systemctl restart mediacenter

tl,dr; my /etc/pulse/default looks like:

set-default-sink alsa_output.platform-soc_sound.stereo-fallback

set-card-profile alsa_card.usb-0d8c_USB_Sound_Device-00 input:iec958-stereo
set-default-source alsa_input.usb-0d8c_USB_Sound_Device-00.iec958-stereo
# max_latency_msec=1000  fast_adjust_threshold_msec=100
load-module module-loopback source_dont_move="true" latency_msec=40 max_latency_msec=300  fast_adjust_threshold_msec=100 source=alsa_input.usb-0d8c_USB_Sound_Device-00.iec958-stereo

If you experience audio crackling. This may be due to timing issues, also read this: PulseAudio - Official Kodi Wiki

Fix audio crackling

This fixed it for me:
sudo nano /etc/pulse/daemon.conf
Add the line, at the end:

resample-method = speex-float-5

I’m not sure why it needs to resample though. Just make sure that pacmd list-sources | grep "sample spec" and pacmd list-sinks | grep "sample spec" show the same values and that it matches with what Kodi outputs… And all should be fine without resampling AFAIK…

Second crackling fix

Ok, so that actually didn’t fix audio crackling. It just made it less worse.
I now also tried setting the volume of the sink lower;
pactl set-sink-volume 0 95%
(remember, pactl list sinks is your friend)

I also forced Kodi to output on 44100hZ -only-, to prevent remixing.
Anyway, it seems i am not the only one with audio crackling/stuttering and pulseaudio… -sigh-

And now I’ve also tried editting /etc/pulse/daemon.conf and setting realtime-scheduling = no

Fix audio crackling II

I have changed the latency_msec=1 option to latency_msec=200 for module-loopback after i saw that pulseaudio was running into constant buffer underruns (pulseaudio -vvvvvv). That fixed about 99% of the crackling.

The remaining crackling appears to be resolved by setting the default-sample-rate to 48000. Additionally, I made sure that osmc can run processes with a nice level of -11.

I have modified /etc/pulse/daemon.conf to enable the following settings:

default-sample-format = s24le
high-priority = yes
nice-level = -11
exit-idle-time = -1
flat-volumes = yes
;default-sample-rate = 44100
default-sample-rate = 48000
;alternate-sample-rate = 44100

;resample-method = speex-fixed-10
resample-method = speex-float-10

default-fragments = 3
default-fragment-size-msec = 7

avoid-resampling = yes

Additionally, I modified /etc/security/limits.d/osmc.conf to allow osmc to set its nice level to -11;

* - nice -1
osmc - nice -11

Make sure to reboot the PC after making these changes; a restart of the mediacenter service will not suffice.

Volume-fix

My TV doesn’t let me control audio volume anymore, and kodi doesn’t control the volume either for some reason… Which is kinda annoying. Im still searching for a fix for this one. (found it, scroll below for IR)

Oh, my install still uses PulseAudio 10, but PA11 has a feature I want to try out; Option to avoid resampling more often)

No working SPDIF-IN

March 2020. Got it working. If you’re experience a lot of audio lag, make sure everything is running at 48000hZ. Lastly, make sure you’re running PA13 or build it from scratch, as it has a lot of nice improvements.
If you’re building PA13 on your ARM device, run the bootstrapsh, and afterwards again run configure:
CFLAGS="-g -O0 -fomit-frame-pointer" ./configure --enable-force-preopen --enable-bluez5

2 Likes

Using above solution I was able to succesfully use my raspberry pi as a cheap receiver: my TV spdif output was connected to my raspberry pi spdif input. Pulseaudio, also supporting bluetooth, is now playing for osmc+bluetouth+tv.
One major thing missing though was remote volume control. Couldnt find any android app for that, so I decided to use pulseaudio instead. It was a struggle, but here are instructions how to configure OSMC to use a simple IR remote to manage pulseaudio volume:

First, install the IR-receiver. That’s out of scope for this document.

Second, stop all IR-consuming services:
systemctl stop mediacenter eventlircd

Then, you have to create a mapping-file like:

$ cat /lib/udev/rc_keymaps/cheapchinaremote
# table cheapchinaremote, type: NEC
0x15 KEY_VOLUMEUP
0x07 KEY_VOLUMEDOWN

This maps a hexcode to a linux ui-event.
See the hexcode of a remotecontrol button use (you may have to use other protocol then nec):
$ ir-keytable -t -p nec
List of event codes: linux/input-event-codes.h at master · torvalds/linux · GitHub

If you’ve mapped the remote control button presses to event-code, you have to make sure the file is loaded upon boot. Append the following line to /etc/rc_maps.cfg :

$ tail -n 1 /etc/rc_maps.cfg
*   *     cheapchinaremote

Next, create /etc/lirc/lircrc :

begin
   prog = PulseAudio
   remote = *
   button = KEY_VOLUMEUP
   config = volume-up
   repeat = 5
end

begin
   prog = PulseAudio
   remote = *
   button = KEY_VOLUMEDOWN
   config = volume-down
   repeat = 5
end

begin
   prog = PulseAudio
   remote = *
   button = KEY_MUTE
   config = mute-toggle
end

And load the module-lirc pulseaudio module:

$ tail -n 1 /etc/pulse/system.pa
load-module module-lirc config=/etc/lirc/lircrc

(system.pa if you run PA in system-mode,otherwise default.pa)

last but not least; make sure kodi doesnt do anything for the presses:

$ cat /home/osmc/.kodi/userdata/keymaps/remote.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- More documentation on keymaps can be found on http://kodi.wiki/view/keymaps          -->
<keymap>
 <global>
   <remote>
     <volumeplus>noop</volumeplus>
     <volumeminus>noop</volumeminus>
     <mute>noop</mute>
   </remote>
 </global>
</keymap>

Reboot, and it should work!