Nastavení zvuku na multiseatu

V dnešních počítačích je zvuková karta 5.1 skoro samozřejmostí. Pokud se ale zrovna nedíváte na film, tak jen málokdy využijete všech 5 kanálů – většinou si vystačíte jen se dvěma. Nabízí se proto otázka, jestli by nešlo nějak (softwarově) předstírat, že v počítači jsou 2 stereo zvukové karty a každý uživatel by pak mohl využít jeden z jejích výstupů.

S Linuxem – přesněji ALSou – to není problém. Rozdělení výstupu na přední a zadní je popsáno na ALSA wiki, já používám velmi podobné nastavení, jen jsem musel pár věcí upravit, protože toto řešení nepočítá s přístupem dvou různých uživatelů k témuž zařízení.

Navíc jsem jej musel uložit do globálního nastavení v /etc/alsa/ (konkrétní umístění se může lišit podle použité distribuce). Abych odstínil nastavení pro multiseat od normálního nastavení, vložil jsem jej do samostatného souboru (/etc/alsa/mul­tiseat.alsa.con­f) a ten je poté vložen do hlavního konfiguračního souboru (/etc/alsa/al­sa.conf) – v mé distribuci (Fedora) stačí přidat řádek s cestou do funkce load, která je hned na začátku konfiguračního souboru. Také jsem přidal načítání uživatelského souboru ~/.asound.mseat (o něm později):

#
#  ALSA library configuration file
#

# pre-load the configuration files

@hooks [
        {
                func load
                files [
                        "/etc/alsa/multiseat.alsa.conf"
                        "/etc/asound.conf"
                        "~/.asoundrc"
                        "~/.asound.mseat"
                ]
                errors false
        }
]

...

a takhle vypadá zmiňovaný multiseat.alsa­.conf (všimněte si přidání práv k danému zařízení – tím dovolíme více uživatelům používat totéž zařízení najednou):

pcm.dshare {
    type dmix
    ipc_key 2049
    ipc_key_add_uid false
    ipc_perm 0666
    slave {
        pcm "hw:0"
        rate 44100
        period_time 0
        period_size 1024
        buffer_size 8192
        channels 4
    }
    bindings {
        0 0
        1 1
        2 2
        3 3
    }
}
pcm.frontx {
    type plug
    slave {
        pcm "dshare"
        channels 4
    }
    ttable.0.0 1
    ttable.1.1 1
}
pcm.rearx {
    type plug
    slave {
        pcm "dshare"
        channels 4
    }
    ttable.0.2 1
    ttable.1.3 1
}

pcm.!default {
        type copy
        slave.pcm "frontx"
}

Nastavení programů (přehrávačů atd.)

Dobře, teď jsme tedy nastavili rozdělení zvukové karty, zbývá ale donutit programy, aby toto nastavení používaly. Některé programy umožňují vybrat zvukový výstup pomocí GUI (např. audacity) jiné pak při spuštění přidáním dodatečného parametru – např. mplayeru stačí přidat parametr -ao alsa:device=rearx a už posílá svůj výstup na zařízení rearx. To je sice hezké, ale běžný uživatel nebude chtít používat příkazovou řádku. Naštěstí ale lze určit defaultní výstupní zařízení – to je ostatně vidět v posledním bloku začínajícím pcm.!default. Stačí tedy tento kus zkopírovat do souborů ~/.asoundrc jednotlivých uživatelů (a popř. zaměnit frontx za rearx) a je hotovo. Tedy skoro.

Jak jsem si v praxi ověřil, dost často potřebuji mezi těmito nastaveními přepínat – pokud jsem u počítače sám, radši si pustím hudbu do reproduktorů (které mám napojené na frontx), pokud by to někoho rušilo, pustím si ji do sluchátek (které snáze napojím na rearx pomocí prodlužovacího kabelu). Ne že bych měl něco proti ručnímu editování konfiguračních souborů, ale přeci jenom je pohodlnější napsat jediný příkaz a nebo jenom kliknout na nějakou ikonku (a to nemluvím o uživatelích, kteří příkazovou řádku vůbec nepoužívají).

Takže jsem si napsal jednoduchý skript, který provede právě ono přepnutí výchozí výstupního zařízení a navíc prohledá GNOME panel a nastaví ovládání hlasitosti na tento výstup. Pro tento účel ukládá aktuální nastavení do souboru ~/.mseat a podle něj mění konfigurační soubor pro ALSu ~/.asound.mseat. (Ano, vím, že by stačil jeden soubor, ale takhle bylo skript snazší napsat).

Protože používám GNOME, tak nemám důvod zjišťovat, jestli by podobné přepnutí ovládání hlasitosti šlo provést i pro jiná prostředí – pokud se vám to pořadí, napište mi a já sem umístím aktualizovaný skript. Díky.

#!/bin/sh

# changes default ALSA output according to user current
# settings

# Available outputs
#  format: alsaname,Human-readable name,GNOME volume applet device name;alsaname2,...
ALSAOUTPUTS=";rearx,Rear,Surround;frontx,Front,Front";

# Configuration file locations
USERALSACONFIG="${HOME}/.asound.mseat";
USERCONFIG="${HOME}/.mseat";

# osd_cat font settings
OSDFONT='-adobe-helvetica-bold-r-*-*-34-*-*-*-*-*-*-*';


#############
# Lines below this typically do not have to be changed
#

usage() {
cat <<EOF_USAGE
Redirection of default ALSA output
Usage:
  $0 [-ovg] [--osd] [--verbose] [--gnome]
    -o  --osd      Display OSD-message after redirection
    -v  --verbose  Be verbose
    -g  --gnome    Change device in GNOME volume applet

EOF_USAGE
exit 1
}


# CL options
changeGnome=0;
ECHO=":";
osd=0;

opts="-o o,v,g -l osd,verbose,gnome";
getopt -Qq $opts -- "$@" || usage;
eval set -- `getopt -q $opts -- "$@"`;

while [ $# -gt 1 ]; do
    case $1 in
        -o|--osd) osd=1;;
        -v|--verbose) ECHO="echo";;
        -g|--gnome) changeGnome=1;;
        *) usage;;
    esac
    shift
done

# Easier searching
ALSAOUTPUTS=`echo "$ALSAOUTPUTS" | sed -e '/^;/!s#.#;&#;/;$/!s#.*#&;#'`

# Find current settings
[ -e "$USERCONFIG" ] && current=`sed -n '/^alsaredirect=/{s/[^=]*=\(.*\)/\1/;p;q}' <$USERCONFIG`;
if [ -z "$current" ]; then
    current=`echo "$ALSAOUTPUTS" | cut '-d;' -f 2 | cut '-d,' -f 1`;
    # to prevent failure when editing
    echo "alsaredirect=blabla" >> $USERCONFIG
fi

$ECHO "Current output is ${current}...";

# Find next in the list
new=`echo $ALSAOUTPUTS | sed 's#.*;'"$current"',[^;]*;\([^;]*\).*#\1#'`;
[ -z "$new" ] && new=`echo "$ALSAOUTPUTS" | cut '-d;' -f 2`;

# Get the names of the devices
deviceAlsa=`echo $new | cut '-d,' -f 1`;
deviceName=`echo $new | cut '-d,' -f 2`;
deviceGnome=`echo $new | cut '-d,' -f 3`;

$ECHO "Switching output to $deviceName [$deviceAlsa,$deviceGnome]";


# Save changes
printf 'pcm.!default {\n    type copy\n    slave.pcm "%s"\n   }\n\n' "$deviceAlsa" >$USERALSACONFIG
printf '/^alsaredirect=/\ns/=.*/=%s/\nw\nq\n' "$deviceAlsa" | ed $USERCONFIG &>/dev/null


# Change GNOME applet default device
[ $changeGnome -eq 1 ] && (
    $ECHO -n "About to change GNOME applet device...";
    for applet in `gconftool-2 --all-dirs '/apps/panel/applets'`; do
        iid=`gconftool-2 -g "$applet/bonobo_iid" 2>/dev/null`;
        if [ "$iid" = "OAFIID:GNOME_MixerApplet" ]; then
            # Found him (if it has inside a prefs dir)
            track=`gconftool-2 -g "$applet/prefs/active-track" 2>/dev/null`;
            if [ -n "$track" ]; then
                gconftool-2 --set "$applet/prefs/active-track" --type string "$deviceGnome" 2>/dev/null;
                $ECHO -n " ok";
            fi
        fi
    done
    $ECHO " ";
) &


# Here goes other applets changing (run them in background to
# enable possible parallelism)

wait


[ $osd -eq 1 ] && \
    printf "Default audio output redirected to %s\n" "$deviceName" | \
        osd_cat "--font=$OSDFONT" -c white -O 1 -u black \
        -p bottom -A center -d 5 &
exit

Stránka byla naposledy změněna 28. března 2008 v 21.06

Vytvořil Vojtěch HorkýXHTML & CSS platné •