Steven
Steven6 min čítania

Chyba slúchadiel do uší: keď druhá osoba zmizla z nášho prepisu

Dvojkanálový prepis fungoval bezchybne na reproduktoroch notebooku aj na náhlavných slúchadlách. Potom niekto zapojil slúchadlá do uší a osoba, s ktorou sa rozprával, jednoducho zmizla z prepisu — pretože Chromium potichu stlmilo naše audio v okamihu, keď prehovorila. Jedenásť opráv zlyhalo. Dvanásta zmenila celú architektúru.

Inžinierstvo
Audio
Prepis
Vydania GeekBye
Chyba slúchadiel do uší: keď druhá osoba zmizla z nášho prepisu

GeekBye prepisuje dve strany rozhovoru: tvoj mikrofón na jednom kanáli, audio druhej osoby (to, čo prehráva tvoj počítač) na druhom. Fungovalo to bezchybne na reproduktoroch notebooku. Fungovalo na náhlavných slúchadlách. Potom používateľ zapojil slúchadlá do uší a osoba, s ktorou sa rozprával, zmizla z prepisu. Nie skomolená. Nie zle priradená. Preč.

Toto je príbeh GeekBye v1.6.12, chyby, ktorá si vyžiadala jedenásť neúspešných opráv, a okamihu, keď sme si uvedomili, že bojujeme s prehliadačom namiesto toho, aby sme s ním spolupracovali.

Stopa, ktorá bola živá a prázdna

Príznak bol desivý. Spustil si stretnutie, všetko vyzeralo dobre, povedal si jedno slovo — a od tej chvíle prešiel audio kanál druhej osoby do čistého digitálneho ticha. Zmerali sme to: signál systémového audia sedel na normálnej úrovni energie (RMS okolo 0.03–0.06) a v okamihu, keď mikrofón zachytil tvoj hlas, klesol na 0.0000 a zostal tam po zvyšok relácie.

Tu je časť, ktorá nás stála dni. Každé API prehliadača trvalo na tom, že audio stopa je dokonale zdravá. readyState: live. enabled: true. muted: false. Podľa každej stavovej vlajky, ktorú platforma vystavovala, bol prúd v poriadku. Boli to vzorky, ktoré boli mŕtve — živá rúra nesúca samé nuly. Dlho sme neverili vlastnému meraču energie, pretože oficiálna verzia hovorila, že stopa funguje.

Spúšťač bol špecifický pre slúchadlá do uší a dôvod je fyzikálny: slúchadlo do ucha je jedno zariadenie, ktoré je súčasne tvojím mikrofónnym vstupom aj audio výstupom. Reproduktory notebooku a náhlavné slúchadlá to oddeľujú — výstup ide na jedno miesto, mikrofón je inde. Ale keď sú vstup a výstup to isté zariadenie, máš z definície spätnoväzbovú cestu. Naša silná dedukcia (toto žije v útrobách prehliadača, takže nemôžeme citovať kapitolu a verš) je, že Chromium zistí tento tvar mikrofón-plus-reproduktor-na-jednom-zariadení, rozhodne, že je to spätnoväzbová slučka pred zapiskaním, a ochranne stlmí zachytávanie — potichu, bez toho, aby to aplikácii povedalo cez akúkoľvek vlajku, ktorú si aplikácia môže prečítať.

Jedenásť opráv, viaceré horšie

Zaútočili sme na to najprv zjavnými spôsobmi a každý pokus sme si zapísali. Vypnúť potlačenie echa, potlačenie šumu a automatické zosilnenie na oboch prúdoch. Spúšťať oba prúdy postupne s oneskorením namiesto naraz. Dať každému prúdu vlastnú vzorkovaciu frekvenciu. Pridať tichý uzol zosilnenia. Poslať všetko cez jeden zdieľaný audio kontext. Prejsť na AudioWorklet. Klesnúť až k surovému procesoru stopy WebCodecs.

Jedenásť prístupov. Nielenže zlyhali — viaceré to zhoršili. Jeden zaviedol 30-sekundové oneskorenie. Iný spôsobil, že prepis tvojho mikrofónu sa objavil označený ako druhá osoba. Boli sme hlboko v burine, liečili sme každý príznak a chyba sa stále presúvala.

Prelomom bolo preformulovanie: každá doterajšia oprava sa snažila udržať dva samostatné prúdy zdravé. Ale dva samostatné prúdy boli presne to, čo spätnoväzbová heuristika Chromia mohla vidieť a stlmiť. Čo ak by nebolo čo porovnávať?

Oprava: daj prehliadaču jeden prúd, nie dva

v1.6.12 prestal bojovať a zmenil architektúru. Namiesto posielania mikrofónu a systémového audia ako dvoch nezávislých prúdov ich zmixuje do jedného mono prúdu na klientovi, skôr než čokoľvek opustí aplikáciu. Keď oba zdroje tečú cez jeden potrubie, stopy nemôžu zomrieť nezávisle — už neexistuje dvojzariadenkový spätnoväzbový tvar, ktorý by prehliadač mohol zistiť a stlmiť. Spúšťacia podmienka jednoducho prestane existovať.

Bol tu aj lahodný bonus. Dva prúdy znamenali dva WebSockety klient-k-backendu a dve pripojenia backend-k-poskytovateľovi; jeden zmixovaný prúd to zvinul na jedno a jedno. Oprava chyby slúchadiel do uší znížila náš náklad na prepis o polovicu ako vedľajší efekt.

Ale mono mixovanie má zjavný problém: ak zleješ obe osoby do jedného kanála, ako stále vieš, kto čo povedal? Zahodil si presne to oddelenie, ktoré ti to hovorilo.

Prebudovanie „kto hovoril" z energie

Odpoveďou bolo zmerať hlasitosť každého zdroja pred ich zmixovaním a pripojiť ku každému kúsku audia nápovedu hovoriacu, ktorý zdroj dominoval — mikrofón, systém alebo ticho. Hlasnejší zdroj vyhráva. Dosť jednoduché na reproduktoroch.

Slúchadlá do uší si vyžiadali ešte jednu vrstvu a tu sa echo vracia do príbehu — namierené opačne, než by si hádal. Na slúchadlách do uší hlas druhej osoby uniká zo slúchadla späť do mikrofónu. Takže bez opatrnosti sa jej echo, prichádzajúce na tvoj mikrofónny kanál, priradí tebe. Opravou je sada na echo citlivých prahov: keď systémové audio hrá nad malou podlahou, latka, ktorú musí tvoj mikrofón prekročiť, aby sa rátal ako „ty hovoríš", vyskočí vysoko hore — z normálnych 0.015 na 0.1. Inými slovami: kým druhá osoba hovorí, tvoj mikrofón musí byť jasne, jednoznačne hlasnejší než jej echo, než slová pripíšeme tebe. Nejednoznačné snímky idú predvolene do „systému" za predpokladu, že sú echom. Je to zámerné vychýlenie, ktoré trafí priradenie správne presne v tej situácii, ktorá ho kedysi mýlila.

Tento proof-of-concept — mono mixovanie plus na energii založené, na echo citlivé rozpoznávanie hlasu — je predkom systému priradenia, na ktorom GeekBye beží dnes. Lešenie sa vytrhlo v tom istom vydaní, len čo sa osvedčilo, a matematika energie neskôr stvrdla do poriadne otestovaného modulu. Ale v1.6.12 je miesto, kde sa myšlienka zrodila, pod tlakom, vďaka používateľovi so slúchadlami do uší.

Tri veci, ktoré chyba slúchadiel do uší naučila

  1. Zdravá rukoväť môže niesť mŕtve dáta. Celé vyšetrovanie sa točilo okolo dôvery nášmu meraču energie nad stavovými vlajkami platformy — live, enabled, unmuted, všetky klamúce, kým vzorky boli nuly. Monitoruj obsah, nie sebahodnotenie API. Ak prúd tvrdí, že je v poriadku, zmeraj, či naozaj je.
  2. Keď platforma bojuje s tvojou architektúrou, zmeň architektúru — nie platformu. Nemohli sme prehádať spätnoväzbovú ochranu Chromia a každý pokus vypnúť ju po okrajoch zlyhal alebo sa vypomstil. Odstránenie pozorovateľnej podmienky — dva prúdy stávajúce sa jedným — spôsobilo, že celý problém zmizol. Takmer vždy je lacnejšie odstrániť spúšťač než vyhrať boj s prehliadačom.
  3. Keď zvinieš kanály kvôli robustnosti, musíš prebudovať to, čo si zničil. Mixovanie do mono zabilo oddelenie kanálov, ktoré nieslo „kto hovoril". Tú informáciu bolo treba odvodiť nanovo z energie pred mixom a na echo citlivých prahov. Kompenzujúca logika nie je dodatkom k oprave — ona je polovicou opravy.

Toto je štvrtá kapitola príbehu o spoľahlivosti, ktorý sa stáva GeekBye v2. Pre predchádzajúcu kapitolu pozri zrušené spojenie by nemalo zhodiť celú tvoju aplikáciu (v1.6.8); pre prepísanie potrubia, na ktorom táto práca s audiom stavala, zmazali sme 5000 riadkov audio kódu (v1.6.0); a pre celý oblúk, anatómiu dodávania softvéru k dokonalosti.