Jack

    Installation

    Install jack2 package. For raspberry pi you need a special version compiled without --dbus, this allow jackd running without X11.

    wget -q -O - http://rpi.autostatic.com/autostatic.gpg.key | sudo apt-key add -
    sudo wget -q -O /etc/apt/sources.list.d/autostatic-audio-raspbian.list http://rpi.autostatic.com/autostatic-audio-raspbian.list
    sudo apt-get update
    

    Source

    Here are the packages ((without dbus/X11 requirement)) if they are no more availables: libjack-jackd2 jackd2

    Notes: jckd2 is dependent of libjack, so first install libjack. You could have some trouble for downgrade tour current version, in this case when you uninstall on your device your current jack, you take the risk of break program dependant of jack ((i had the problem with wireshark, gstreamer, espeak, and smplayer who depends of libjack)).

    Configuration

    Jack run on your current user ((for security reason)). But jack ask some privileges on memory, and priority ((to have sound on real time)).

    /etc/security/limits.conf

    #<domain>      <type>  <item>         <value>
    
    @audio          -       rtprio          99
    @audio          -       memlock         unlimited
    

    Note: Give privilege for audio group. You need to logout/login to take effects.

    Jack Client

    Better than pulseaudio for network.

    Send data through network

    Native method

    Disdvantage: The sender is like a server. So the client need to know ip/port of the daemon who run. See zita as alternative.

    jackd -R -d netone

    Note:

    • Replace netone by net if you use jack1

    • It's possible to specify a port with -I option

    • -r specify sample rate, useful when you've got some problem ((44100 for cd quality, or 48000)). If you specify this, specify also on other side((server)).

    • To start automatically at startup, add this command in .jackdrc file in home directory. Seems to be only before Debian Jessie.

    Zita

    Zita are going to use ~300ko/sec((2.17Mbit/s)). On website they said 50ko/sec, so i think it's possible to optimize if you need this constraint please update configuration and how to use.

    Package: zita-njbridge

    Advantage: Compare to native method, you could use through internet, and you can set the sender of sound as a client TCP and receiver as server.

    Run
    zita-j2n server_ip server_port
    

    Require jackd running ((run it with netone driver, if you take alsa instead of netone, you're going to create yourself the jack_connect. With netone, the jack_connect are done automatically when you start an application. I don't know why !? need to ask on IRC)).

    Note: j2n mean "jack to network".

    Run pulseaudio on jack

    Lot of OS have pulseaudio by default. This mean that all sound from different application (mplayer, vlc, mpg...) going directly on pulseaudio, and no on jack. So the sound not going to be played on network peripherals. To resolve this, you can say to pulseaudio to use jack.

    Installation

    Install pulseaudio-module-jack package.

    Configure

    ~/.pulse/default.pa

    load-module module-native-protocol-unix
    load-module module-jack-sink channels=2
    load-module module-jack-source channels=2
    load-module module-null-sink
    load-module module-stream-restore
    load-module module-rescue-streams
    load-module module-always-sink
    load-module module-suspend-on-idle
    set-default-sink jack_out
    set-default-source jack_in
    

    Note: Could also use /etc/pulse/default.pa file.

    ~/.pulse/daemon.conf

    default-sample-format = float32le
    default-sample-rate = 48000
    realtime-scheduling = yes
    exit-idle-time = -1
    

    Note: Could also use /etc/pulse/daemon.conf file.

    Source

    See other solution for pulseaudio : http://jackaudio.org/faq/pulseaudio_and_jack.html

    Jack Server

    Run jackd

    jackd -d alsa
    

    Note: On raspberry pi, due to unknown reason, you need specific options. See below.

    Raspberry pi

    jackd -p16 -d alsa -n 4
    

    Note: -n 3 minimum((buffer bigger than 2 by default)). You also need -p16 to avoid bus error and memory allocation problem.

    You can also optimize by remove some unused services:

    #!/bin/bash
    
    ## Stop the ntp service
    sudo service ntp stop
    
    ## Stop the triggerhappy service
    sudo service triggerhappy stop
    
    ## Stop the dbus service. Warning: this can cause unpredictable behaviour when running a desktop environment on the RPi
    sudo service dbus stop
    
    ## Stop the console-kit-daemon service. Warning: this can cause unpredictable behaviour when running a desktop environment on the RPi
    sudo killall console-kit-daemon
    
    ## Stop the polkitd service. Warning: this can cause unpredictable behaviour when running a desktop environment on the RPi
    sudo killall polkitd
    
    ## Only needed when Jack2 is compiled with D-Bus support (Jack2 in the AutoStatic RPi audio repo is compiled without D-Bus support)
    #export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/dbus/system_bus_socket
    
    ## Remount /dev/shm to prevent memory allocation errors
    sudo mount -o remount,size=128M /dev/shm
    
    ## Kill the usespace gnome virtual filesystem daemon. Warning: this can cause unpredictable behaviour when running a desktop environment on the RPi
    killall gvfsd
    
    ## Kill the userspace D-Bus daemon. Warning: this can cause unpredictable behaviour when running a desktop environment on the RPi
    killall dbus-daemon
    
    ## Kill the userspace dbus-launch daemon. Warning: this can cause unpredictable behaviour when running a desktop environment on the RPi
    killall dbus-launch
    
    ## Uncomment if you'd like to disable the network adapter completely
    #echo -n “1-1.1:1.0” | sudo tee /sys/bus/usb/drivers/smsc95xx/unbind
    ## In case the above line doesn't work try the following
    #echo -n “1-1.1” | sudo tee /sys/bus/usb/drivers/usb/unbind
    
    ## Set the CPU scaling governor to performance # WARNING: can cause audible glitches
    #echo -n performance | sudo tee /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
    
    ## And finally start JACK (here -dhw is for USB output)
    jackd -P70 -p16 -t2000 -d alsa -dhw:UA25 -p 128 -n 3 -r 44100 -s &
    
    exit
    

    Source

    Script init

    jackd-network-rp

    #!/bin/bash
    
    ### BEGIN INIT INFO
    # Provides:          jackd-network-rp
    
    # Required-Start:    $local_fs $remote_fs $network $syslog $named
    # Required-Stop:     $local_fs $remote_fs $network $syslog $named
    
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    
    # Short-Description: Start/stop jack daemon with network zita and connect speaker
    ### END INIT INFO
    
    
    NAME=jackd-network-rp
    SCRIPTNAME=/etc/init.d/$NAME
    PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    
    #	Permet d'afficher un message plus visible (en vert)
    
    #	@param $1 Le message
    function successMsg(){
        echo -e "\033[32m${1}\033[0m"
    }
    
    #	Permet d'afficher un message plus visible (en orange)
    
    #	@param $1 Le message
    function warningMsg(){
        echo -e "\033[33m${1}\033[0m"
    }
    
    #	Permet d'afficher un message plus visible (en rouge)
    
    #	Remarque : Cette fonction provoque l'arret du script
    #	@param $1 Le message
    
    function errorMsg(){
        echo -e "\033[31m${1}\033[0m"
        exit 1
    }
    
    #	Permet d'afficher un message plus visible (bleu)
    
    function boldMsg(){
          echo -e "\033[34m${1}\033[0m"
    }
    
    #	Permet un message a gauche avec un label a droite (vert)
    
    #	@param $1 Le message
    #	@param $2 (optionel) le label
    
    function labelSuccessMsg() {
        local msg="$1"
        local label="$2"
    
        local color=$(tput setaf 2)
        local normal=$(tput sgr0)
        local supp=""
        local cold=0
    
        if [ -n "$msg" ]
        then
        let cold=-1
        supp="${color}|${normal}"
        fi
    
        if [ -z "$label" ]
        then
        label="ok"
        fi
    
        let cold=$(tput cols)-${#msg}+${#color}+${#normal}+${cold}
    
        printf "%s%${cold}s" "${supp}${msg}" "[${color} ${label} ${normal}]"
    }
    
    #	Permet un message a gauche avec un label a droite (rouge)
    
    #	Remarque : arret du script
    #	@param $1 Le message
    
    #	@param $2 (optionel) le label
    function labelErrorMsg() {
        local msg="$1"
        local label="$2"
    
        local color=$(tput setaf 1)
        local normal=$(tput sgr0)
        local supp=""
        local cold=0
    
        if [ -n "$msg" ]
        then
        let cold=-1
        supp="${color}|${normal}"
        fi
    
        if [ -z "$label" ]
        then
        label="fail"
        fi
    
        let cold=$(tput cols)-${#msg}+${#color}+${#normal}+${cold}
    
        printf "%s%${cold}s" "${supp}${msg}" "[${color} ${label} ${normal}]"
    
        exit 1
    }
    
    #	Permet un message a gauche avec un label a droite (orange)
    
    #	@param $1 Le message
    #	@param $2 (optionel) le label
    
    function labelWarningMsg() {
        local msg="$1"
        local label="$2"
    
        local color=$(tput setaf 3)
        local normal=$(tput sgr0)
        local supp=""
        local cold=0
    
        if [ -n "$msg" ]
        then
        let cold=-1
        supp="${color}|${normal}"
        fi
    
        if [ -z "$label" ]
        then
        label="warn"
        fi
    
        let cold=$(tput cols)-${#msg}+${#color}+${#normal}+${cold}
    
        printf "%s%${cold}s" "${supp}${msg}" "[${color} ${label} ${normal}]"
    }
    
    
    #	Permet un message a gauche avec un label a droite (orange)
    
    #	@param $1 Le message
    #	@param $2 (optionel) le label
    
    function labelBoldMsg() {
        local msg="$1"
        local label="$2"
    
        local color=$(tput setaf 6)
        local normal=$(tput sgr0)
        local supp=""
        local cold=0
    
        if [ -n "$msg" ]
        then
        let cold=-1
        supp="${color}|${normal}"
        fi
    
        if [ -z "$label" ]
        then
        label="info"
        fi
    
        let cold=$(tput cols)-${#msg}+${#color}+${#normal}+${cold}
    
        printf "%s%${cold}s" "${supp}${msg}" "[${color} ${label} ${normal}]"
    }
    
    case $1 in
        start)
        echo "Starting jackd with driver netone "
        jackd -p 16 -d alsa -n 4 -s & # FIXME & is not the best way, see rtorrent
        sleep 4s # FIXME in future try another solution, zita need jackd running
    
        zita-n2j 192.168.2.30 1234 & # FIXME & is not the best way, see rtorrent
        sleep 4s # FIXME in future try another solution, jack_connect need zita
    
        jack_connect zita-n2j:out_1 system:playback_1
        jack_connect zita-n2j:out_2 system:playback_2
    
        # TODO check everthing has worked
        ;;
        stop)
        if [ "$(ps aux | grep -e 'zita-n2j' | grep -v grep -c)" != 0  ]
        then
          echo "Shutting down zita-n2j... "
          killall -r "zita-n2j"
    
          if [ $? == 0 ]
          then
            labelSuccessMsg "Shutdown zita-n2j" "down"
          else
            labelErrorMsg "Shutdown zita-n2j" "failed"
          fi
        fi
    
        if [ "$(ps aux | grep -e 'jackd' | grep -v grep -c)" != 0  ]
        then
          echo "Shutting down jackd... "
          killall -r "jackd"
    
          if [ $? == 0 ]
          then
            labelSuccessMsg "Shutdown jackd" "down"
          else
            labelErrorMsg "Shutdown jackd" "failed"
          fi
        else
          labelBoldMsg "jackd is not running"
        fi
        ;;
        status)
        if [ "$(ps aux | grep -e 'zita-n2j' | grep -v grep -c)" != 0  ]
        then
          labelSuccessMsg "zita-n2j running" "running"
        else
          labelBoldMsg "zita-n2j seems down"
        fi
    
        if [ "$(ps aux | grep -e 'jackd' | grep -v grep -c)" != 0  ] # FIXME don't seem to work
        then
          labelSuccessMsg "jackd running" "running"
        else
          labelBoldMsg "jackd doesnt running" "shutdown"
        fi
        ;;
    
    * )
        echo "Usage: $SCRIPTNAME {start|stop|status}" >&2
        exit 2
        ;;
    esac
    

    FIXME: currently not working, just jackd start, but no zinta, you need to connect on ssh to re-start.

    chmod +x /etc/init.d/jackd-network-rp
    update-rc.d jackd-network-rp defaults 99
    

    Receive data from network

    With netjack

    Disadvantage: need to access on ip/port of sender((sounds weird, but the "server"<=>receiver connect to the "client"<=>sender)). See zita as alternative.

    jack_netsource -H 192.168.2.30
    

    Require: jackd running.

    Note: You could specify a port with -p option.

    With zita

    zita-n2j 192.168.2.30 1234
    

    Require: jackd running and ''zita-njbridge'' package.

    Don't forget to connect what come from zita((out)), to speaker((playback))

    jack_connect zita-n2j:out_1 system:playback_1
    jack_connect zita-n2j:out_2 system:playback_2
    

    Note: n2j mean "network 2 jack".

    See jack_lsp to know what are input and output port availables.

    root@rp-master:~# jack_lsp
    system:playback_1
    system:playback_2
    zita-n2j:out_1
    zita-n2j:out_2