Egy kedves történet a Pulseaudioval

A hétvégén rendberaktam a gépem hangját; átgondoltam, hogy mi ad ki hangot, mik az igényeim és nyélbe vágtam az egészet Pulseaudioval.

Hozzászólások

Szia!

Mivel látom, hogy Te értesz ( nálam biztos jobban ) a PulseAudiohoz kérdezhetnék egy-két dolgot?

1. Miért kell a Pulseaudio, ha van Alsa? Mit add pluszba?
2. Hogyan lehet megadni a default 'hangkártyát', ha több is van ? Ha menet közben bedugok egy USB-s hangadaptert vagy jack headset-et akkor automatikusan átáll arra a hang?

Tud, ha a hangkártya nem tudja hardveresen, akkor betölti a dmix plugint az alap konfigja. A PulseAudio elterjedése előtt simán működött ez is, évekig használtam anélkül, hogy tudtam volna a létezéséről.

A PulseAudio hátránya pont ez (mellesleg Win Vista óta a win-eknek is), hogy nem tud hardveres mixelést és effekteket használni. Mondjuk egy mai CPU röhögve számolja ezeket, de anno P3-P4 idején (előtte meg pláne) még észrevehető volt a teljesítmény-vesztés játékok alatt.
Az effektek viszont hiányoznak, de ez a rohadék hangkártya-gyártó cégek (elsősorban a Creative) hibája.

Nem azért. Az OSS nem volt a kernel része, és fejlesztők nem is akarták azzá tenni. A felépítése és az API-ja is eléggé szar volt az OSSv4-es előtt. Az ALSA azért jött létre, hogy legyen egy modern API a linux kernelben.

20 éve pedig az alaplapi hangkártyák még csak elkezdtek elterjedni (AC'97 Codec ugyebár), de az elterjedt diszkrét kártyák nagy része sem tudott hardveresen mixelni (régi SoundBlaster és klónjai, stb)

Logokat kell olvasni. Amúgy ebben az a rossz, hogy ha a pulseaudio recseg, az ALSA nem, az még lehet az ALSA hibája. Azért, mert a pulseaudio használ olyan függvényeket az alsa API-ból, amelyet amúgy senki soha, s lehet, hogy az implementáció el van szúrva, vagy trehányul van megcsinálva az ALSA-ban. A pulseaudio meg nem használ workaround-ot, ha visszakap egy értéket a függvénytől, azt szentül elhiszi, azzal számol, lesz is belőle baj.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Nem hozzám jött a kérdés, de erre reagálok.

Miért kell a Pulseaudio, ha van Alsa?

Nekem a router-embe van dugva USB-s „hangkártya”. Oda kell stream-elnem a hangot akár a nagy gépemről, akár a notebook-omról. Bónusz nehezítés, hogy VoIP alkalmazás esetén kell visszhang elnyomás is.

Ezt hogyan oldanád meg Alsa-val? Amúgy komolyan érdekel, mert a router alkalmazásai mind alsa interface-szel rendelkeznek, de nekem így még nem sikerült ezt megoldanom. Pulseaudio-val viszont megy. Kár, hogy egyes hanganyagok kétszer járják meg most a router-t: egyszer tömörítve, egyszer tömörítetlenül.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

1. Nem ismerem alaposan az ALSA-t, de szerintem abban nem lehet megoldani a stream átdobását másik kimenetre anélkül, hogy az alkalmazás támogatná.

2. Parancssorból valahogy így (erre a PA mixerek is képesek GUI-n):


$ pactl list sinks short
$ pactl set-default-sink {output_sink_name}

Új USB adapter esetén nem áll át automatikusan, de van megoldás: udev konfiggal el tudod lőni a scripted ami átdobja az összes streamet az adapterre. Egyébként a Plasma desktop is képes erre, a Hardware / Multimedia / Audio Volume / Advanced fül alatt lehet bekapcsolni (Automatically switch all running streams when a new output becomes available).
A jack dugós váltásnak állítólag automatikusan kéne működnie ha az ALSA driver támogatja - én sose próbáltam.

Azt a null-sink-es, loopback-es részt nem értem. Miért így kell?

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

A null-sink csak arra jó, hogy létrejön egy virtuális output és hozzá a monitor source. Minden ráküldött stream megjelenik a monitoron, majd megy a devnullba. Itt segít a loopback, aminek megadhatsz egy source-t (monitor) és egy sinket (a valódi output device) amire átküldi - így tud megszólalni a null sink.

Még mindig nem értem. Közvetlenül a default sink-be nem mehetne a hang? Minek a semmibe küldeni, amit azért mégis felszedsz, hogy aztán a kimenetre küldd? Van ennek sima memória másolgatáson túl valami szerepe? Az miért jó, ha buffereket másolgatunk?

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Ha a default sinket használná minden app, nem tudnám elnémítani az összeset úgy, hogy közben a bejövő hívás ne legyen néma.

KMix-ben beállítottam a "Media" sinket mint "Master channel", így a multimédia billentyűk a loopback device hangerejét állítják és vele együtt az összes média appot, miközben a VoIP appok hangerejét nem bántják.

Én már értem. Valamivel be kell nyeletni a hangot, de az nem lehet hardware, valódi hangkártya. Csak azért kell, hogy legyen neve, hivatkozni lehessen rá, s így állíthatóvá váljék a hangereje illetve némítani lehessen. Ha a defaulttal csinálja, akkor minden állítódik, de ő úgy akarta, hogy a VoIP hangereje ne változzék, csak a multimédiás alkalmazásoké.

Szerk.: a második kérdésedre pedig az a válasz, hogy a loopback source-t köt sinkre, s a source itt a null-sink monitora, ha jól értem.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

locsemege jól mondja, de megpróbálom még egyszerűbben megfogalmazni;
A null és a loopback együtt alkalmas egy virtualis hangkártya létrehozására: a null kvázi egy sink-source alagút, a loopback pedig source-sink alagút. Mindkettő kell, hogy létrejöjjön a virtuális sink ami aztán egy létező eszközön meg is szólal.

Valójában azt hiányolom, hogy pusztán attól, hogy a defaul.pa - vagy system.pa - file-ban leírja az ember, milyen modult milyen paraméterrel töltsön be a pulseaudio, még cseppet sem látszik világosan a topológia. Olyan leíró nyelv kellene, amelyben vannak dobozok, a doboznak vannak bemenetei, kimenetei, s ezek között valósít meg függvénykapcsolatot. A keverés is az, a szintszabályozás is, a visszhang elnyomás, vagy a route-olás, meg persze az equalizer is. Aztán ezen dobozok be- és kimeneteit lehetne valahogyan összekötözni.

Szerintem ilyen topológiát konfig file-ban látványosan leíró nyelvet nem túl nehéz kitalálni.

Jelen esetben a pulseaudio-nál sokszor az is gondot okoz nekem, hogy a sink, source megnevezésből lássam a jel útját - jó, beszédes az elnevezés -, mert kérdés, honnan nézve az. Meg egy protokoll esetén is kipottyan a hang például a hálózaton, de ott már nem beszélnek erről, hallgatólagosan van csak ez ott. Nem teljességgel érthetetlen, de zavaró a konfigfile nyelvezete, ráadásul vannak nem a topológiát leíró modulok is közé vegyítve, hogy áttekinthetetlenebb legyen az egész.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Bonyolult a topológia, nem lehet egyszerű fa struktúrába rendezni, inkább irányított körmentes gráffal lehet leírni. Erre szerintem nincs szép megoldás text fájlban. Viszont semmi nem akadályoz meg abban, hogy kommentben megszámozd a sorokat és rajzolj egy DAG-ot pl Dia-val amivel átlátható lesz az egész.

A jelölés nem tetszik. Például itt van a module-native-protocol-tcp, amiből nem derül ki, hogy azon beesik hang, azon kimegy hang, sőt, akár vezérlés is, ha client.conf-ban úgy akarom - bár az lehet, menne akkor is, ha ezt a modult nem tölteném be. Szóval nem egyértelmű. Itt nem látom, hogy source, sink, pedig kimegy a dobozból, hisz látom, most is folyamatosan kb. 192 kB/s-mal.

Tehát ne komment legyen, hanem a tényleges konfig, az a lényeg. Az, hogy valamit kommentben rajzolok, csak magam szórakoztatása, de attól nem fog úgy is működni.

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

Amúgy miért ne lehetne?

mixer (in1, in2, out1) {
out1=f(in1, in2);
}

volume (in1, vol, out1) {
out1=g(in1, vol);
}

connect (volume.out1, mixer.in1);

Valami ilyesmit el bírnék képzelni, s látnám, mi hova van kötve. Az f() és g() függvényeket nem definiáltam, ezekre lehetne a hangszervernek kész belső függvényrendszere, amelyet az ember felhasznál kedve szerint. De felőlem lehetne egyszerűsíteni is akár:

main.out=mixer(volume(in1, vol), in2);

tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE

- Nekem ez a szintaxis sem elég intuitív, legszívesebben ezt is inkább lerajzolnám, kommentelném.
- A PA dinamikus szemléletű, rugalmasan újrakonfigurálhatóak a láncok. Egy leírónyelv mellett ott a kérdőjel, hogy a változások hogy kezelhetőek könnyen, állapotvesztés és hiccup nélkül (realtime adatfeldolgozásról van szó).
- A PA scope-ja a tömegigény, miközben tökéletesen illeszthető a JACK-hez aminek célja épp a bonyolult feldolgozási láncok kezelése: users are enabled to build powerful systems for signal processing. Simán ki tudod küldeni a streamed JACK-re akár GUI-ról konfigurált feldolgozásra, majd onnan vissza PA-ba. A PA eszközei ezen a területen egyébként is jóval szerényebbek.

Én nem vagyok meggyőzve hogy a PA-nak szüksége van egy leírónyelvre, a juzerek 98%-a szerintem azt se tudja hogy van konfig fájlja.