Jack & Volumio over the network without PulseAudio

Jack often used in conjunction with, for example, Ardorwhile I would like to bypass the PulseAudio server supplied by default in many distributions in order to avoid unnecessary waste of processor power.

Two years ago, I also encountered incorrect collaboration between two sound servers (which led to periodic “crashes” of sound) and decided to get rid of PulseAudio once and for all in favor of pure Jack.

Since I have two low-power Raspberry Pi computers at home, I divided the tasks into two parts: on one computer I watch video, record sound, listen to the player, and on the second computer, next to the speaker system, there is a full-fledged audio server busy only stream output to DACthe sound is “transmitted” over the network.

On the Internet, of course, there are many ready-made solutions for “sound servers” and I settled on the following: upload an image to a memory card Volumiobut slightly finish it to connect via jackd.

Volumio does not support jackd2 out of the boxso I had to see what exactly is installed on Volumio, unzip the Volumio file system in Linux with utilities

$ unsquashfs volumio_current.sqsh

So Volumio is using the old version Debian Jessie with some Italian modifications. The bad news is that the old version of Debian 8 contains a package bug dbus, creating a problem with jackd2.

Volumio doesn’t use X11 so jackd2 won’t start without small dances with a tambourine. Among other things, there is no jackd2 package in Volumio.

However, all these problems are easily solved.

The jackd2 package is available from the Debian server and is called deb.jackd2 armhf Jessie, the installation is standard, the package is placed as an overlay. The good news is that Volumio already has all the packages to work with jackd2! No additional packages need to be installed.

Since we are using the old jackd2 with the “dbus” error, it will need to be “fixed”. You can fix it with a software patch and then compile, but it’s easier to do additional customization in a script. Since I was going to run the sound server remotely via ssh, I immediately wrote a script start-jackd.sh with the following commands.

#!/bin/bash
export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket
# Этой командой  мы исправляем ошибку dbus
driver="alsa"
port_max="4"
priority="95"
# Определяем приоритет, чтобы сервер сильно нагружал процессор
device="hw:0,0"
nperiods="3"
# Рекомендуемое значение для внешних USB карт
outchannels="2"
# Количество каналов воспроизведения
period="1024"
# По умолчанию  1024
rate="96000"
# Частота дискретизации по умолчанию 48000, я увеличил ее
inchannels="2"
#  Каналы захвата, например, для микрофонов
jackd -R -P $priority -d $driver  -P -o $outchannels -i $inchannels -s -n $nperiods -p $period -r $rate -d $device  &
# Запускаем сервер, затем запускаем сетевой менеджер
jack_load netmanager -i -c 
# Это сетевой менеджер

exit 0

Of course, the file needs to be made executable (chmod +x start-jackd.sh) and copy to the Volumio computer.

So, the server is configured, and Volumio, if you use two sound cards (like mine), will independently choose one or another card. Now the “sound server” jackd can be started automatically from .profile (in a different way) or using the ssh command. To make it convenient to manage Volumio, it is better to install the utility sshpass.

Then on the client computer, you need to configure the jackd2 output. It’s even easier here. First, install the jackd2 package using the standard apt command.

We look at the local network. This assumes that the Volumio server is on the local network 192.168.88.**.

$ nmap -sn 192.168.88.0/24

For the future, it is better to set up a permanent IP, I configured it with a binding to the MAC address in the router.

Setting up the client side jackd2.

Note. If you are a perfectionist, then it is better to immediately turn to transmission over the network using Zita Bridge. But I decided to limit myself to the settings for a 24-bit sound card with a sampling rate of 96000. (My old sound card does not support more powerful configurations.)

For convenience, we create a script that starts the server on the client side (if there is no desire to start the server automatically at boot). Let’s call the script, for example, remote_start.sh

#!/bin/bash

IP="192.168.88.249"
# Допустим, это адрес сервера Volumio
sshpass -f <(printf '%s\n' volumio)  ssh volumio@"$IP" 'if ps -A | grep "jackd"; then  echo " ";  fi;' > ~log
sleep 1
# Входим с помощью программы sshpass, чтобы не вводить пароль 
# Запускаем сервер, создаем лог

sshpass -f <(printf '%s\n' volumio) ssh volumio@"$IP" nohup ./start-jackd.sh & 
# Запускаем сервер

# sshpass -f <(printf '%s\n' volumio)  ssh volumio@"$IP" 'pkill jackd'
# Так можно "убить" сервер

exit 0

As written above, I do not connect a sound card to the client computer, so instead of sound card drivers, I installed a “virtual sound card”.

If you also want to output sound from other programs (for example, from the Chromium browser) to the Volumio server, then it’s best to also load the driver. This is a special kernel module, simulating a sound card.

The setup process is minimalist as the Raspberry Pi supports the module snd-aloop (link above).

The only thing that needs to be done is to write a file .asoundrc with support for the desired bitrate. Since we already have a sample rate of 96000 defined on the Jack server, .asoundrc should be synchronized (why the unnecessary resampling?).

Here is my .asoundrc file

# hardware 0,0 :  playback
pcm.loophw00 {
  type hw
  card Loopback
  device 0
  subdevice 0
  format S32_LE
  rate 96000
}

# playback PCM: loopback subdevice 0,0

pcm.amix {
  type dmix
  ipc_key 219345
  slave {
    pcm loophw00
    period_size 4096
    periods 2
  }
}

# Софтверный регулятор громкости
pcm.asoftvol {
  type softvol
  slave.pcm "amix"
  control { name PCM }
  min_dB -51.0
  max_dB   0.0
}

#  jack alsa_in
pcm.cloop {
  type hw
  card Loopback
  device 1
  subdevice 0
  format S32_LE
#  rate 48000
}
#  alsa_out
pcm.ploop {
  type hw
  card Loopback
  device 1
  subdevice 1
  format S32_LE
  rate 48000
}
# duplex device
pcm.aduplex {
  type asym
  playback.pcm "asoftvol"
  capture.pcm "loophw01"
}
# default device
pcm.!default {
  type plug
  slave.pcm aduplex
  hint {
       show on
       description "Duplex Loopback"
  }
}

Let’s write a script that starts Jack on the client side. You can add some zest, for example, embed support for a processor chip from “BAMF sound recipe»

Let’s call the script jack_start.sh

#!/bin/bash

amixer -q sset PCM 10%
# При запуске звук будет тихим, чтобы случайно не разбудить соседей

IP="192.168.88.249"

	if ps -A | grep "jackd"; then 
    echo -e "<<< A server is already running: jackd >>>";
    echo -e " <<< kill jackd... >>>";
    pkill jackd 
    sleep 1;
	fi
# "Убивает jackd, если он запущен, помогает перезагрузить звук

# Настройки jackd
# --input_ports	-С число входных каналов (захват)
# --output_ports -Р число выходных каналов (воспроизведение)
# --midi_in_ports -i число входных MIDI-каналов
# --midi_out_ports -о число выходных MIDI-каналов

    multicast_ip="225.3.19.154"
    udp_net_port="19000"
    mtu="1500"
    input_ports="0"
    output_ports="2"
    midi_in_ports="0"
    midi_out_ports="0"
    client_name="hostname"
    transport_sync="1"
    latency="5"
# Это настройки по умолчанию

    taskset 0x4  jackd -S -R  -d net -a $multicast_ip -p $udp_net_port -M $mtu -C $input_ports -P $output_ports -i  $midi_in_ports -o $midi_out_ports -l $latency  & 
# Запустим jackd на одном процессоре =)
    sleep 1

    sshpass -f <(printf '%s\n' volumio) ssh volumio@"$IP" jack_lsp
# Посмотрим соединения на стороне сервера
    sleep 1

# Если уже запущены alsa_in или alsa_out, то процессы уничтожаются
	if ps -A | grep "alsa_in"; then 
    echo -en "kill alsa_in...";
    pkill alsa_in
	fi
	if ps -A | grep "alsa_out"; then 
    echo -en "kill alsa_out...";
    pkill alsa_out
	fi

# Опции для cloop, воспроизведение.
# -j
    jack_client_name="cloop"  # (имя клиента jack)
# -d   
    alsa_device="cloop" # (устройcтво)
# -c   
    channels="2" # (количество каналов)
# -r  
    sample_rate="96000" # (выборка, программа пересчитывает при необходимости
# -p   
    period_size="1024" 
# Если частота дискретизация высокая, могут быть помехи,  опция поможет
# исправить их
# -n   
    num_period="6" # периоды, см. period_size
# -q    
    quality="0"  # "Качество" ресемплера от 0 до 4, ресемлер отключен
# -m  
    max_diff="1024" # значение, когда происходит  xrun
# -t   
    target_delay="2048" 
# задержка alsa_in, такая же как для max_diff. Но  настройка на основе -p и -n  обычно достаточна
# -s  
    smooth_array_size="2048" # параметр управляет размером массива сглаживания задержки 

taskset 0x3 /usr/bin/alsa_in -j $jack_client_name -d $alsa_device  -c $channels -n $num_period -p $period_size  -m $max_diff -s $smooth_array_size -t $target_delay -r $sample_rate -q $quality  2>&1 1> /dev/null &
# Запускаем на отдельном процессоре
sleep 1

    jack_connect cloop:capture_1 system:playback_1
    jack_connect cloop:capture_2 system:playback_2
# устанавливаем соединение

# /usr/bin/alsa_out -j ploop -dploop -r 44100 -q 1 2>&1 1> /dev/null &
# jack_connect system:capture_3 ploop:playback_1
# jack_connect system:capture_3 ploop:playback_2
# Если используется захват каналов для работы с микрофонами

# Проверяем работу 

	if ps -A | grep "jackd"; then 
    echo -en " jackd reading..."
    PID=`pgrep "jackd"`
    echo -en " <<<<<<< $PID >>>>>>>"
	fi

	if ps -A | grep "alsa_in"; then 
    echo -en " alsa_in reading..."
    PID=`pgrep "alsa_in"`
    echo -en " <<<<<<< $PID >>>>>>>"
	fi

exit 0

You can now play music on your Raspberry computer and stream over the network to your Volumio computer. In this case, the system volume control will work, which will allow you to control the volume from the tray.

Moreover, we have already written scripts to automate the server. I prefer to run them from a file .profile

To start the server on the Volumio side, you need to add the command remote_start.sh To connect the jack client, you need to call the script jack_start.sh

Joint operation of jack with a virtual card is very stable and almost never freezes. However, unpleasant audio dropouts are possible, especially if the processors are heavily loaded, in which case can be called again jack_start.sh script, which will reload the client side.

Thank you for your attention, I hope my little note will help someone.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *