Stejný zvuk na HDMI a S/PDIF


Tento víkend jsem po chvilkách věnoval na první pohled jednoduchému úkolu. Potřeboval jsem, aby z mého HTPC výcházel tentýž zvuk, ze všech jeho digitálních výstupů. Jednalo o HDMI a S/PDIF (Optical Out). Pomocí ALSA nemožné, pánbůh zaplať za PulseAudio

Pořídíl jsem si domácí kino PHILIPS HTS3551/12, tedy taky DTS/AC3 receiver, který podporuje HDMI 1.4 ARC, tj kanál zpětného audia z televize. Propojením HDMI 1.4 kabelem s televizí se dá docílit možnosti zobrazovat přehrávané BD/DVD na televizi a zároveň, když náhodou sleduju televizi, zvuk vychází z bedýnek kina (zpětným kanálem) a ne z chrchláků televize. Moje HTPC mám připojené k televizi dalším HDMI kabelem. Obrázek ukazuje zapojení názorněji.

Pokud svoje HTPC používám ke sledování seriálů nebo fílmů je vše v pořádku. Z HTPC jde po HDMI zvuk i obraz, televize zobrazí obraz a zvuk pošle přes HDMI 1.4 ARC do kina.  Co když ale poslouchám hudbu? V takovém případě se zvuk který vychází z domácího kina stává závislý na běhu televize. Obraz ale k poslechu nepotřebuji, hodilo by se televizi vypnout úplně. Propojil jsem tedy HTPC a domácí kino navíc ještě optickým kabelem (Optical Out).  A tady přichází potřeba stejného výstupu z S/PDIF a HDMI. Pokud tedy pomineme variantu, kdy před vypnutím televize přenastavím přehráváč, aby posílal zvuk na S/PDIF, a před díváním se na obraz to vracel zpátky.

Toto jsou moje zvukové výstupy  na mojí desce  ZOTAC ION ITX A-E

yymc ~ # aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: NVidia [HDA NVidia], device 0: ALC662 rev1 Analog [ALC662 rev1 Analog]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 1: ALC662 rev1 Digital [ALC662 rev1 Digital]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
Subdevices: 0/1
Subdevice #0: subdevice #0

Analogový výstup nás v tuto chvíli nezajímá. Potřebujeme aby přehrávač (XBMC nebo jakákoliv jiná aplikace) byl schopen zasílat zvuk zároveň  na výstupy card 0: device 1 a card 0: device 3.

Zabil jsem spoustu času kouzlením v souboru .asoundrc a pokusem vytvořit určité virtuální zvukové rozhraní, které by rozesílalo signál na HDMI a S/PDIF. Tím signálem mám na mysli 6 kanálů. S ALSA, jsem byl schopen docílit kopírování 2 kanálů na obě rozhraní. To je sice dobrý pokus, ale v okamžiku, se dívám na film, jehož zvuk má více než 2 kanály, přicházel bych o zážitek a tím i popřel důvod, proč jsem se pro domácí kino vůbec rozhodl.

Po chvíli jsem to s ALSA vzdal a zkoušel hledat dál. PulseAudio připadalo jako řešení. Existuje plugin module-combine-sink, který dělá přesně to, co potřebuji. Stačí přidat tyto 3 kouzelné řádky na konec souboru /etc/pulse/default.pa

load-module module-alsa-sink device=hw:0, sink_name=SPDIF sink_properties=device.description=SPDIF 
load-module module-alsa-sink device=hw:0, sink_name=HDMI sink_properties=device.description=HDMI
load-module module-combine-sink slaves=SPDIF,HDMI sink_name=Combined resample_method=copy sink_properties=device.description=Combined

Ve výchozí konfiguraci PulseAudio detekovalo pouze analogový výstup (card 0, device 0 nebo-li hw:0,0), což nám nestačí. První 2 řádky tedy říkají: “Hele, PulseAudio, mám výstupy na ALSA zařízeních hw:0,1 a hw:0,3, začni s nima pracovat!” Vstupy jsou rozumně pojmenovány, abychom je byli schopni v aplikacích nebo XBMC odlišit. Třetí řádek vytvoří nový sink (sink je audio výstup), který bude duplikovat zvukový stream do 2 sinků, které začali existovat díky předchozím 2 řádkům.  Direktivu resample_method=copy jsem použil, protože výchozí byla docela náročná na CPU a začlo se lehce trhat přerhávání filmů.

Pozn: Pro PulseAudio verze nižší než 1.0 použijte module-combine namísto module-combine-sink

To není všechno, nový sink je fuknční, ale je naneštěstí pouze dvoukanálový, to jsem si od ALSA řešení moc nepomohl. Naštěstí se v případě PulseAudio nejedná o neřešielnou situaci, naopak, je pouze nutné přepsat výchozí hodnoty se kterými se vytvářejí nové sinky. Do /etc/pulse/daemon.conf přidáme následující:

default-sample-channels = 6
default-channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe

Voilà 🙂 Zbývá jen nastavit XBMC, aby použilo správný (kombinovaný) PulseAudio sink. Na domácím kině můžu přepínat vsup mezi HDMI-ARC a OPT-IN a hudba hraje. Když nechám kino přehrávat vstup OPT-IN, můžu televizi vypnout.