Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

A causa de la producció massiva de telèfons intel·ligents sense presa d'àudio de 3.5 mm, els auriculars Bluetooth sense fil s'han convertit en la principal manera per a molts d'escoltar música i comunicar-se en mode d'auriculars.
Els fabricants de dispositius sense fil no sempre escriuen especificacions detallades del producte i els articles sobre àudio Bluetooth a Internet són contradictoris, de vegades incorrectes, no parlen de totes les característiques i sovint copien la mateixa informació que no es correspon amb la realitat.
Intentem entendre el protocol, les capacitats de les piles del sistema operatiu Bluetooth, els auriculars i els altaveus, els còdecs Bluetooth per a la música i la parla, esbrineu què afecta la qualitat del so i la latència transmesa, apreneu a recopilar i descodificar informació sobre els còdecs compatibles i altres dispositius. capacitats.

TL; DR:

  • SBC - còdec normal
  • Els auriculars tenen el seu propi equalitzador i postprocessament per a cada còdec per separat
  • aptX no és tan bo com s'anuncia
  • LDAC és una merda de màrqueting
  • La qualitat de les trucades encara és baixa
  • Podeu inserir codificadors d'àudio C al vostre navegador compilant-los a WebAssembly mitjançant emscripten, i no s'alentiran gaire.

Música mitjançant Bluetooth

El component funcional de Bluetooth està determinat pels perfils: especificacions de funcions específiques. La transmissió de música Bluetooth utilitza un perfil de transmissió d'àudio unidireccional A2DP d'alta qualitat. L'estàndard A2DP es va adoptar el 2003 i no ha canviat significativament des de llavors.
Dins del perfil, s'estandarditza 1 còdec obligatori de baixa complexitat computacional SBC, creat específicament per a Bluetooth, i 3 addicionals. També és possible utilitzar còdecs no documentats de la vostra pròpia implementació.

Des de juny de 2019 estem al còmic xkcd amb 14 còdecs A2DP:

  • SBC ← estandarditzat en A2DP, compatible amb tots els dispositius
  • MPEG-1/2 Layer 1/2/3 ← estandarditzat en A2DP: conegut MP3, utilitzat a la televisió digital MP2, i desconegut MP1
  • MPEG-2/4 AAC ← estandarditzat en A2DP
  • ATRAC ← còdec antic de Sony, estandarditzat en A2DP
  • LDAC ← nou còdec de Sony
  • APTX ← còdec de 1988
  • APTX HD ← igual que aptX, només amb opcions de codificació diferents
  • aptX Baixa latència ← còdec completament diferent, sense implementació de programari
  • aptX Adaptive ← un altre còdec de Qualcomm
  • FastStream ← pseudo còdec, modificació SBC bidireccional
  • HWA LHDC ← nou còdec de Huawei
  • Samsung HD ← compatible amb 2 dispositius
  • Samsung escalable ← compatible amb 2 dispositius
  • Samsung UHQ-BT ← compatible amb 3 dispositius

Per què necessitem còdecs, us pregunteu, quan el Bluetooth té EDR, que us permet transferir dades a velocitats de 2 i 3 Mbit/s, i per a PCM de 16 bits de dos canals sense comprimir, n'hi ha prou amb 1.4 Mbit/s?

Transferència de dades mitjançant Bluetooth

Hi ha dos tipus de transferència de dades a Bluetooth: Asynchronous Connection Less (ACL) per a la transferència asíncrona sense establiment de connexió, i Synchronous Connection Oriented (SCO), per a la transferència síncrona amb negociació de connexió preliminar.
La transmissió es realitza mitjançant un esquema de divisió de temps i seleccionant un canal de transmissió per a cada paquet per separat (Frequency-Hop/Time-Division-Duplex, FH/TDD), per al qual el temps es divideix en intervals de 625 microsegons anomenats ranures. Un dels dispositius transmet en ranures de nombre parell, l'altre en ranures de nombre senar. El paquet transmès pot ocupar 1, 3 o 5 ranures, depenent de la mida de les dades i del tipus de transmissió establert, en aquest cas, la transmissió per un dispositiu es realitza en ranures parells i senars fins al final de la transmissió. En total, es poden rebre i enviar fins a 1600 paquets per segon, si cadascun d'ells ocupa 1 ranura, i tots dos dispositius transmeten i reben alguna cosa sense aturar-se.

2 i 3 Mbit/s per a EDR, que es poden trobar als anuncis i al lloc web de Bluetooth, són la velocitat màxima de transferència del canal de totes les dades en total (incloses les capçaleres tècniques de tots els protocols en què les dades s'han d'encapsular), en dues direccions simultàniament. La velocitat real de transferència de dades variarà molt.

Per transmetre música s'utilitza un mètode asíncron, gairebé sempre utilitzant paquets com 2-DH5 i 3-DH5, que porten una quantitat màxima de dades en mode EDR de 2 Mbit/s i 3 Mbit/s, respectivament, i ocupen 5 temps. -Compartir espais.

Representació esquemàtica de la transmissió utilitzant 5 ranures per un dispositiu i 1 ranura per un altre (DH5/DH1):
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

A causa del principi de divisió temporal de les ones, ens veiem obligats a esperar una franja horària de 625 microsegons després de transmetre un paquet si el segon dispositiu no ens transmet res o transmet un petit paquet, i més temps si el segon dispositiu transmet en grans paquets. Si hi ha més d'un dispositiu connectat al telèfon (per exemple, auriculars, rellotges i una polsera de fitness), el temps de transferència es comparteix entre tots.

La necessitat d'encapsular l'àudio en protocols de transport especials L2CAP i AVDTP pren 16 bytes de la quantitat màxima possible de càrrega útil d'àudio transmesa.

Tipus de paquet
Nombre de ranures
Màx. nombre de bytes del paquet
Màx. nombre de bytes de càrrega útil A2DP
Màx. Velocitat de bits de càrrega útil A2DP

2-DH3
3
367
351
936 kbps

3-DH3
3
552
536
1429 kbps

2-DH5
5
679
663
1414 kbps

3-DH5
5
1021
1005
2143 kbps

1414 i 1429 kbps definitivament no són suficients per transmetre àudio sense comprimir en condicions reals, amb el sorollós rang de 2.4 GHz i la necessitat de transmetre dades de servei. L'EDR 3 Mbit/s exigeix ​​la potència de transmissió i el soroll a l'aire, per tant, fins i tot en el mode 3-DH5, la transmissió PCM còmoda és impossible, sempre hi haurà interrupcions a curt termini i tot només funcionarà a una distància d'un un parell de metres.
A la pràctica, fins i tot un flux d'àudio de 990 kbit/s (LDAC 990 kbit/s) és difícil de transmetre.

Tornem als còdecs.

SBC

Còdec necessari per a tots els dispositius que admeten l'estàndard A2DP. El millor i el pitjor còdec alhora.

Freqüència de mostreig
Profunditat de bits
Taxa de bits
Suport a la codificació
Suport a la descodificació

16, 32, 44.1, 48 kHz
16 bit
10-1500 kbps
Tots els dispositius
Tots els dispositius

SBC és un còdec senzill i computacionalment ràpid, amb un model psicoacústic primitiu (només s'aplica l'emmascarament de sons tranquils), que utilitza modulació de codi de pols adaptatiu (APCM).
L'especificació A2DP recomana dos perfils d'ús: qualitat mitjana i qualitat alta.
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

El còdec té molts paràmetres que permeten controlar el retard algorítmic, el nombre de mostres en un bloc, l'algoritme de distribució de bits, però gairebé a tot arreu s'utilitzen els mateixos paràmetres recomanats a l'especificació: estèreo conjunt, 8 bandes de freqüència, 16 blocs en un marc d'àudio, mètode de distribució de bits de sonoritat.
SBC admet el canvi dinàmic del paràmetre Bitpool, que afecta directament la taxa de bits. Si les ones d'aire estan obstruïdes, es perden paquets o els dispositius es troben a grans distàncies, la font d'àudio pot reduir el Bitpool fins que la comunicació torni a la normalitat.

La majoria dels fabricants d'auriculars estableixen el valor màxim de Bitpool a 53, la qual cosa limita la taxa de bits a 328 kilobits per segon quan s'utilitza el perfil recomanat.
Fins i tot si el fabricant dels auriculars ha establert el valor màxim de Bitpool per sobre de 53 (es troben aquests models, per exemple: Beats Solo³, JBL Everest Elite 750NC, Apple AirPods, que també es troben en alguns receptors i unitats de capçalera del cotxe), la majoria de sistemes operatius no ho permetran. l'ús de velocitats de bits augmentades a causa del límit de valor intern establert a les piles Bluetooth.
A més, alguns fabricants configuren el valor màxim de Bitpool a baix per a alguns dispositius. Per exemple, per a Bluedio T és de 39, per a Samsung Gear IconX és de 37, la qual cosa dóna una mala qualitat de so.

Les restriccions artificials per part dels desenvolupadors de piles Bluetooth probablement van sorgir a causa de la incompatibilitat d'alguns dispositius amb grans valors de Bitpool o perfils atípics, fins i tot si van informar de suport per a ells, i proves insuficients durant la certificació. Va ser més fàcil per als autors de les piles Bluetooth limitar-se a acordar el perfil recomanat, en lloc de crear bases de dades de dispositius incorrectes (tot i que ara ho fan per a altres funcions que funcionen incorrectament).

SBC assigna dinàmicament bits de quantificació a bandes de freqüència de manera baixa a alta, amb diferents pesos. Si s'ha utilitzat tota la taxa de bits per a les freqüències baixes i mitjanes, les freqüències altes es "tallaran" (en canvi hi haurà silenci).

Exemple SBC 328 kbps. A la part superior hi ha l'original, a la part inferior hi ha l'SBC, canviant periòdicament entre les pistes. L'àudio del fitxer de vídeo utilitza el còdec de compressió sense pèrdues FLAC. L'ús de FLAC en un contenidor mp4 no està estandarditzat oficialment, de manera que no es garanteix que el vostre navegador el reprodueixi, però hauria de funcionar a les últimes versions de Chrome i Firefox d'escriptori. Si no teniu so, podeu descarregar el fitxer i obrir-lo en un reproductor de vídeo complet.
ZZ Top - Home vestit afilat

L'espectrograma mostra el moment de la commutació: SBC talla periòdicament els sons tranquils per sobre de 17.5 kHz i no assigna cap bit per a la banda superior a 20 kHz. L'espectrograma complet està disponible fent clic (1.7 MB).
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

No escolto cap diferència entre l'original i SBC en aquesta pista.

Prenguem alguna cosa més nou i simulem l'àudio que s'obtindria amb els auriculars Samsung Gear IconX amb Bitpool 37 (a dalt - el senyal original, a sota - SBC 239 kbps, àudio en FLAC).
Mindless Self Indulgence - Testimoni

Sento un cruixent, menys efecte estèreo i un so desagradable de "ronc" a les altes freqüències de les veus.

Tot i que SBC és un còdec molt flexible, es pot configurar per a una baixa latència, proporciona una excel·lent qualitat d'àudio a altes velocitats de bits (452+ kbps) i és força bo per a la majoria de la gent amb una alta qualitat estàndard (328 kbps), a causa del fet que això l'estàndard A2DP no especifica perfils fixos (però només dóna recomanacions), els desenvolupadors de pila han establert restriccions artificials a Bitpool, els paràmetres de l'àudio transmès no es mostren a la interfície d'usuari i els fabricants d'auriculars poden establir la seva pròpia configuració i mai. indiqueu el valor de Bitpool a les especificacions tècniques del producte, el còdec es va fer famós per la seva baixa qualitat de so, tot i que això no és un problema amb el còdec com a tal.
El paràmetre Bitpool afecta directament la taxa de bits només dins d'un perfil. El mateix valor de Bitpool 53 pot donar tant una taxa de bits de 328 kbps amb el perfil d'alta qualitat recomanat com de 1212 kbps amb canal dual i 4 bandes de freqüència, per això els autors del sistema operatiu, a més de les restriccions a Bitpool, estableixen un límit i activat. Taxa de bits. Tal com veig, aquesta situació va sorgir a causa d'una falla en l'estàndard A2DP: calia negociar la taxa de bits, no Bitpool.

Taula de suport per a les capacitats SBC en diferents SO:

SO
Taxes de mostreig admeses
Límit màx. Bitpool
Límit màx. Taxa de bits
Taxa de bits típica
Ajust dinàmic de Bitpool

Windows 10
44.1 кГц
53
512 kbps
328 kbps
✓*

Linux (BlueZ + PulseAudio)
16, 32, 44.1, 48 kHz
64 (per a connexions entrants), 53 (per a connexions sortints)
Sense límit
328 kbps
✓*

MacOS High Sierra
44.1 кГц
64, per defecte 53***
Desconegut
328 kbps

Android 4.4-9
44.1/48 kHz**
53
328 kbps
328 kbps

Android 4.1-4.3.1
44.1, 48 kHz**
53
229 kbps
229 kbps

Blackberry OS 10
48 кГц
53
Sense límit
328 kbps

* Bitpool només disminueix, però no augmenta automàticament, si les condicions de transferència milloren. Per restaurar Bitpool, heu d'aturar la reproducció, esperar un parell de segons i tornar a iniciar l'àudio.
** El valor predeterminat depèn de la configuració de pila especificada en compilar el microprogramari. A Android 8/8.1 la freqüència és només de 44.1 kHz o 48 kHz, depenent de la configuració durant la compilació, en altres versions s'admeten 44.1 kHz i 48 kHz simultàniament.
*** El valor de Bitpool es pot augmentar al programa Bluetooth Explorer.

aptX i aptX HD

aptX és un còdec senzill i computacionalment ràpid, sense psicoacústica, que utilitza modulació de codi de pols diferencial adaptatiu (ADPCM). Va aparèixer al voltant de 1988 (data de presentació patent amb data de febrer de 1988), abans de Bluetooth, s'utilitzava principalment en equips d'àudio sense fil professionals. Actualment propietat de Qualcomm, requereix llicència i drets d'autor. A partir del 2014: 6000 $ únics i ≈ 1 $ per dispositiu, per a lots de fins a 10000 dispositius (font, pàg. 16).
aptX i aptX HD són el mateix còdec, amb diferents perfils de codificació.

El còdec només té un paràmetre: seleccionar la freqüència de mostreig. Hi ha, però, una selecció del nombre/mode de canals, però en tots els dispositius coneguts per mi (70 peces o més) només s'admet l'estèreo.

Còdec
Freqüència de mostreig
Profunditat de bits
Taxa de bits
Suport a la codificació
Suport a la descodificació

APTX
16, 32, 44.1, 48 kHz
16 bit
128/256/352/384 kbps (segons la freqüència de mostreig)
Windows 10 (escriptori i mòbil), macOS, Android 4.4+/7*, Blackberry OS 10
Àmplia gamma de dispositius d'àudio (maquinari)

* Les versions fins a 7 requereixen la modificació de la pila Bluetooth. El còdec només és compatible si el fabricant del dispositiu Android té llicència per al còdec de Qualcomm (si el sistema operatiu té biblioteques de codificació).

aptX divideix l'àudio en 4 bandes de freqüència i les quantifica amb el mateix nombre de bits constantment: 8 bits per a 0-5.5 kHz, 4 bits per a 5.5-11 kHz, 2 bits per a 11-16.5 kHz, 2 bits per a 16.5-22 kHz ( xifres per a la freqüència de mostreig 44.1 kHz).

Exemple d'àudio aptX (a la part superior - el senyal original, a la part inferior - aptX, espectrogrames només dels canals esquerre, so en FLAC):

Els màxims es van tornar una mica més vermells, però no es podia sentir la diferència.

A causa de la distribució fixa dels bits de quantificació, el còdec no pot "desplaçar els bits" a les freqüències que més els necessiten. A diferència de SBC, aptX no "tallarà" les freqüències, sinó que hi afegirà soroll de quantificació, reduint el rang dinàmic de l'àudio.

No s'ha de suposar que utilitzar, per exemple, 2 bits per banda redueix el rang dinàmic a 12 dB: ADPCM permet fins a 96 dB de rang dinàmic fins i tot quan s'utilitzen 2 bits de quantificació, però només per a un determinat senyal.
ADPCM emmagatzema la diferència numèrica entre la mostra actual i la següent, en lloc d'emmagatzemar el valor absolut com en PCM. Això us permet reduir els requisits del nombre de bits necessaris per emmagatzemar la mateixa informació (sense pèrdua) o gairebé la mateixa (amb un error d'arrodoniment relativament petit). Per reduir els errors d'arrodoniment, s'utilitzen taules de coeficients.
Quan van crear el còdec, els autors van calcular els coeficients ADPCM en un conjunt de fitxers d'àudio de música. Com més a prop estigui el senyal d'àudio del conjunt de música sobre el qual es van construir les taules, menys errors de quantificació (soroll) crea aptX.

Per això, les proves sintètiques sempre donaran pitjors resultats que la música. Vaig fer un exemple sintètic especial en què aptX mostra resultats pobres: una ona sinusoïdal amb una freqüència de 12.4 kHz (a dalt - el senyal original, a sota - aptX. Àudio en FLAC. Baixeu el volum!):

Gràfic d'espectre:
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Els sorolls són clarament audibles.

Tanmateix, si genereu una ona sinusoïdal amb una amplitud més petita perquè sigui més silenciosa, el soroll també es farà més silenciós, indicant un ampli rang dinàmic:

Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Per escoltar la diferència entre la pista de música original i la comprimida, podeu invertir un dels senyals i afegir les pistes canal per canal. Aquest enfocament és, en general, incorrecte i no donaria resultats sensats amb còdecs més complexos, però específicament per a ADPCM és bastant adequat.
Diferència entre original i aptX
La diferència quadrada mitjana dels senyals és al nivell de -37.4 dB, que no és gaire per a una música tan comprimida.

APTX HD

aptX HD no és un còdec autònom, sinó que és un perfil de codificació millorat del còdec aptX. Els canvis van afectar el nombre de bits assignats per a la codificació dels intervals de freqüències: 10 bits per a 0-5.5 kHz, 6 bits per a 5.5-11 kHz, 4 bits per a 11-16.5 kHz, 4 bits per a 16.5-22 kHz (dígits per a 44.1 kHz) .

Còdec
Freqüència de mostreig
Profunditat de bits
Taxa de bits
Suport a la codificació
Suport a la descodificació

APTX HD
16, 32, 44.1, 48 kHz
24 bits
192/384/529/576 kbps (segons la freqüència de mostreig)
Android 8+*
Alguns dispositius d'àudio (maquinari)

* Les versions fins a 7 requereixen la modificació de la pila Bluetooth. El còdec només és compatible si el fabricant del dispositiu Android té llicència per al còdec de Qualcomm (si el sistema operatiu té biblioteques de codificació).

Menys comú que aptX: aparentment requereix una llicència independent de Qualcomm i tarifes de llicència separades.

Repetim l'exemple amb una ona sinusoïdal a 12.4 kHz:
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Molt millor que aptX, però encara una mica sorollós.

aptX Baixa latència

Un còdec de Qualcomm que no té res en comú amb aptX i aptX HD estàndard, a jutjar per la informació limitada de les persones implicades en el seu desenvolupament. Dissenyat per a la transmissió d'àudio interactiva de baixa latència (pel·lícules, jocs), on el programari no pot ajustar el retard d'àudio. No hi ha implementacions de programari conegudes de codificadors i descodificadors, que són compatibles exclusivament amb transmissors, receptors, auriculars i altaveus, però no per telèfons intel·ligents i ordinadors.

Freqüència de mostreig
Taxa de bits
Suport a la codificació
Suport a la descodificació

44.1 кГц
276/420 kbps
Alguns transmissors (maquinari)
Alguns dispositius d'àudio (maquinari)

AAC

AAC, o Advanced Audio Coding, és un còdec computacionalment complex amb un model psicoacústic seriós. Àmpliament utilitzat per a àudio a Internet, segon en popularitat després de MP3. Requereix llicència i drets d'autor: 15000 dòlars únics (o 1000 dòlars per a empreses amb menys de 15 empleats) + 0.98 dòlars per als primers 500000 dispositius (font).
El còdec està estandarditzat dins de les especificacions MPEG-2 i MPEG-4 i, contràriament a la idea errònia comuna, no pertany a Apple.

Freqüència de mostreig
Taxa de bits
Suport a la codificació
Suport a la descodificació

8 - 96 kHz
8 - 576 kbps (per a estèreo), 256 - 320 kbps (típic per a Bluetooth)
macOS, Android 7+*, iOS
Àmplia gamma de dispositius d'àudio (maquinari)

* només en dispositius els fabricants dels quals hagin pagat tarifes de llicència

iOS i macOS utilitzen el millor codificador AAC actual d'Apple per oferir la màxima qualitat d'àudio possible. Android utilitza el segon codificador Fraunhofer FDK AAC de qualitat més alta, però pot utilitzar diversos maquinari integrat a la plataforma (SoC) amb una qualitat de codificació desconeguda. Segons proves recents al lloc web de SoundGuys, la qualitat de codificació AAC de diferents telèfons Android varia molt:
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

La majoria dels dispositius d'àudio sense fil tenen una taxa de bits màxima de 320 kbps per a AAC, alguns només admeten 256 kbps. Altres bitrates són extremadament rars.
L'AAC ofereix una qualitat excel·lent a velocitats de bits de 320 i 256 kbps, però està subjecte a pèrdua de la codificació seqüencial del contingut ja comprimit, però, és difícil escoltar qualsevol diferència amb l'original a iOS a una velocitat de bits de 256 kbps fins i tot amb diverses codificacions seqüencials amb una codificació única, per exemple, MP3 320 kbps a AAC 256 kbps, es poden descuidar les pèrdues.
Igual que amb altres còdecs Bluetooth, qualsevol música es descodifica primer i després el codifica. Quan escolteu música en format AAC, el sistema operatiu primer la descodifica i després la torna a codificar en AAC per a la transmissió mitjançant Bluetooth. Això és necessari per barrejar múltiples fluxos d'àudio, com ara música i notificacions de missatges nous. iOS no és una excepció. A Internet podeu trobar moltes afirmacions que a iOS la música en format AAC no es transcodifica quan es transmet per Bluetooth, la qual cosa no és cert.

MP1/2/3

Els còdecs de la família MPEG-1/2 Part 3 consisteixen en el conegut i àmpliament utilitzat MP3, el menys comú MP2 (utilitzat principalment a la televisió i la ràdio digital) i el MP1 completament desconegut.

Els vells còdecs MP1 i MP2 no són compatibles en absolut: no he trobat cap auricular o pila Bluetooth que els codificés o descodís.
La descodificació MP3 és compatible amb alguns auriculars, però la codificació no és compatible amb cap pila de sistema operatiu modern. Sembla que la pila BlueSoleil per a Windows de tercers pot codificar a MP3 si canvieu manualment el fitxer de configuració, però per mi la instal·lació porta a BSoD a Windows 10. Conclusió: el còdec en realitat no es pot utilitzar per a l'àudio Bluetooth.
Anteriorment, el 2006-2008, abans de la difusió de l'estàndard A2DP als dispositius, la gent escoltava música MP3 als auriculars Nokia BH-501 mitjançant el programa MSI BluePlayer, que estava disponible a Symbian i Windows Mobile. En aquell moment, l'arquitectura del sistema operatiu dels telèfons intel·ligents permetia l'accés a moltes funcions de baix nivell, i a Windows Mobile fins i tot era possible instal·lar piles de Bluetooth de tercers.

L'última patent del còdec MP3 ha caducat, l'ús del còdec no requereix tarifes de llicència des del 23 d'abril de 2017.

Si es pren com a mesura la patent de més llarga durada esmentada a les referències esmentades, aleshores la tecnologia MP3 va quedar lliure de patents als Estats Units el 16 d'abril de 2017 quan va caducar la patent nord-americana 6,009,399, en poder i administrada per Technicolor.

Font: www.iis.fraunhofer.de/en/ff/amm/prod/audiocodec/audiocodecs/mp3.html

Freqüència de mostreig
Taxa de bits
Suport a la codificació
Suport a la descodificació

16 - 48 kHz
8 - 320 kbps
No s'admet enlloc
Alguns dispositius d'àudio (maquinari)

LDAC

Un còdec "Hi-Res" nou i promogut activament de Sony, que admet velocitats de mostreig de fins a 96 kHz i velocitat de bits de 24 bits, amb velocitats de bits de fins a 990 kbps. S'anuncia com un còdec per a audiòfils, com a reemplaçament dels còdecs Bluetooth existents. Té la funció d'ajustar la taxa de bits adaptativa, depenent de les condicions de transmissió de ràdio.

codificador LDAC (libdac) s'inclou al paquet estàndard d'Android, de manera que la codificació és compatible amb qualsevol telèfon intel·ligent Android a partir de la versió 8 del sistema operatiu. No hi ha descodificadors de programari lliurement disponibles, l'especificació del còdec no està disponible per al públic en general, però, a primera vista al codificador, l'estructura interna del còdec és similar a ATRAC9 - Còdec de Sony utilitzat a la PlayStation 4 i la Vita: tots dos funcionen en el domini de la freqüència, utilitzen una transformada de cosinus discreta modificada (MDCT) i compressió mitjançant l'algoritme de Huffman.

El suport LDAC el proporcionen gairebé exclusivament els auriculars de Sony. La capacitat de descodificar LDAC de vegades es troba en auriculars i DAC d'altres fabricants, però molt poques vegades.

Freqüència de mostreig
Taxa de bits
Suport a la codificació
Suport a la descodificació

44.1 - 96 kHz
303/606/909 kbit/s (per a 44.1 i 88.2 kHz), 330/660/990 kbit/s (per a 48 i 96 kHz)
Android 8 +
Alguns auriculars de Sony i alguns dispositius d'altres fabricants (maquinari)

La comercialització de LDAC com a còdec d'alta resolució perjudica el seu component tècnic: és estúpid gastar la taxa de bits en transmetre freqüències inaudibles per a l'oïda humana i augmentar la profunditat de bits, mentre que no n'hi ha prou amb transmetre la qualitat de CD (44.1/16) sense pèrdua. . Afortunadament, el còdec té dos modes de funcionament: transmissió d'àudio CD i transmissió d'àudio d'alta resolució. En el primer cas, només es transmeten 44.1 kHz/16 bits per aire.

Com que un descodificador LDAC de programari no està disponible gratuïtament, és impossible provar el còdec sense dispositius addicionals que descodifiquen LDAC. Segons els resultats de la prova LDAC en un DAC amb el seu suport, que els enginyers de SoundGuys.com van connectar mitjançant una sortida digital i van gravar el so de sortida en senyals de prova, LDAC 660 i 990 kbps en mode de qualitat de CD proporciona un senyal a relació de soroll lleugerament millor que la d'aptX HD.

Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius
Font: www.soundguys.com/ldac-ultimate-bluetooth-guide-20026

LDAC també admet velocitats de bits dinàmiques fora dels perfils establerts, de 138 kbps a 990 kbps, però pel que puc dir, Android només utilitza els perfils estandarditzats 303/606/909 i 330/660/990 kbps.

Altres còdecs

Altres còdecs A2DP no s'utilitzen àmpliament. El seu suport està gairebé completament absent o només està disponible en determinats models d'auriculars i telèfons intel·ligents.
El còdec ATRAC estandarditzat a A2DP mai s'ha utilitzat com a còdec Bluetooth ni tan sols pels mateixos Sony, els còdecs Samsung HD, Samsung Scalable i Samsung UHQ-BT tenen un suport molt limitat per als dispositius de transmissió i recepció, i HWA LHDC és massa nou i només admet tres. (?) dispositius.

Suport de còdec per a dispositius d'àudio

No tots els fabricants publiquen informació precisa sobre els còdecs compatibles amb determinats auriculars, altaveus, receptors o transmissors sense fil. De vegades passa que el suport per a un determinat còdec només és per a la transmissió, però no per a la recepció (rellevant per a transmissors-receptors combinats), encara que el fabricant simplement declara "suport", sense notes (supose que la llicència separada de codificadors i descodificadors d'alguns els còdecs són els culpables d'això). Als dispositius més barats, és possible que no trobeu el suport aptX declarat.

Malauradament, les interfícies de la majoria de sistemes operatius no mostren el còdec utilitzat enlloc. La informació sobre això només està disponible a Android, a partir de la versió 8, i a macOS. Tanmateix, fins i tot en aquests sistemes operatius, només es mostraran els còdecs compatibles tant amb el telèfon/ordinador com amb els auriculars.

Com podeu esbrinar quins còdecs admet el vostre dispositiu? Enregistreu i analitzeu l'abocament de trànsit amb els paràmetres de negociació A2DP!
Això es pot fer a Linux, macOS i Android. A Linux podeu utilitzar Wireshark o hcidump, a macOS podeu utilitzar Bluetooth Explorer i a Android podeu utilitzar la funció estàndard d'estalvi d'abocament de Bluetooth HCI, que està disponible a les eines de desenvolupament. Rebràs un abocador en format btsnoop, que es pot carregar a l'analitzador Wireshark.
Preste atenció: només es pot obtenir un abocament correcte connectant-vos des del vostre telèfon/ordinador a auriculars/altaveus (per molt divertit que sembli)! Els auriculars poden establir de manera independent una connexió amb el telèfon, en aquest cas sol·licitaran una llista de còdecs des del telèfon, i no viceversa. Per assegurar-vos que s'enregistra l'abocament correcte, primer desvinculeu el dispositiu i, a continuació, sincronitzeu el telèfon amb els auriculars mentre enregistreu l'abocament.

Utilitzeu el filtre de visualització següent per filtrar el trànsit irrellevant:

btavdtp.signal_id

Com a resultat, hauríeu de veure alguna cosa semblant a això:
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Podeu fer clic a cada element de l'ordre GetCapabilities per veure les característiques detallades del còdec.
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Wireshark no coneix tots els identificadors de còdecs, de manera que alguns còdecs s'hauran de desxifrar manualment, mirant la taula d'identificadors següent:

Mandatory:
0x00 - SBC

Optional:
0x01 - MPEG-1,2 (aka MP3)
0x02 - MPEG-2,4 (aka AAC)
0x04 - ATRAC

Vendor specific:
0xFF 0x004F 0x01   - aptX
0xFF 0x00D7 0x24   - aptX HD
0xFF 0x000A 0x02   - aptX Low Latency
0xFF 0x00D7 0x02   - aptX Low Latency
0xFF 0x000A 0x01   - FastStream
0xFF 0x012D 0xAA   - LDAC
0xFF 0x0075 0x0102 - Samsung HD
0xFF 0x0075 0x0103 - Samsung Scalable Codec
0xFF 0x053A 0x484C - Savitech LHDC

0xFF 0x000A 0x0104 - The CSR True Wireless Stereo v3 Codec ID for AAC
0xFF 0x000A 0x0105 - The CSR True Wireless Stereo v3 Codec ID for MP3
0xFF 0x000A 0x0106 - The CSR True Wireless Stereo v3 Codec ID for aptX

Per no analitzar els abocadors manualment, vaig fer un servei que ho analitzarà tot automàticament: btcodecs.valdikss.org.ru

Comparació de còdecs. Quin còdec és millor?

Cada còdec té els seus propis avantatges i desavantatges.
aptX i aptX HD utilitzen perfils codificats en dur que no es poden canviar sense modificar el codificador i el descodificador. Ni el fabricant del telèfon ni el fabricant dels auriculars poden canviar la taxa de bits o els factors de codificació aptX. El propietari del còdec, Qualcomm, proporciona un codificador de referència en forma de biblioteca. Aquests fets són la força d'aptX: ja sabeu per endavant quina qualitat de so obtindreu, sense cap "peròs".

SBC, en canvi, té molts paràmetres configurables, taxa de bits dinàmica (el codificador pot reduir el paràmetre de bitpool si les ones estan ocupades) i no té perfils codificats, només els recomanats de "qualitat mitjana" i "alta qualitat" afegit a l'especificació A2DP l'any 2003. L'"alta qualitat" ja no és tan alta per als estàndards actuals, i la majoria de les piles Bluetooth no us permeten utilitzar paràmetres millor que el perfil "alta qualitat", tot i que no hi ha restriccions tècniques per a això.
Bluetooth SIG no té un codificador SBC de referència com a biblioteca i els fabricants ho implementen ells mateixos.
Aquestes són les debilitats de l'SBC: mai està clar per endavant quina qualitat de so cal esperar d'un dispositiu en particular. SBC pot produir àudio de baixa i molt alta qualitat, però aquest últim és inassolible sense desactivar o obviar les limitacions artificials de les piles Bluetooth.

La situació amb AAC és ambigua: d'una banda, teòricament el còdec hauria de produir una qualitat indistingible de l'original, però a la pràctica, a jutjar per les proves del laboratori SoundGuys en diferents dispositius Android, això no està confirmat. El més probable és que la culpa és dels codificadors d'àudio de maquinari de baixa qualitat integrats en diversos chipsets de telèfon. Té sentit utilitzar AAC només en dispositius Apple i a Android per limitar-lo a aptX i LDAC.

El maquinari que admet còdecs alternatius tendeix a ser de major qualitat, simplement perquè per a dispositius molt barats i de baixa qualitat, no té sentit pagar les tarifes de llicència per utilitzar aquests còdecs. A les meves proves, SBC sona molt bé en equips de qualitat.

Vaig fer un servei web que codifica l'àudio a SBC, aptX i aptX HD en temps real, directament al navegador. Amb ell, podeu provar aquests còdecs d'àudio sense transmetre l'àudio mitjançant Bluetooth, a qualsevol auricular amb cable, altaveus i la vostra música preferida, i també canviar els paràmetres de codificació directament mentre reproduïu l'àudio:
btcodecs.valdikss.org.ru/sbc-encoder
El servei utilitza les biblioteques de codificació SBC del projecte BlueZ i libopenaptx de ffmpeg, que es compilen a WebAssembly i JavaScript des de C, mitjançant emscripten, per executar-se al navegador. Qui podria somiar amb un futur així!

Això és el que sembla:

Observeu com canvia el nivell de soroll després de 20 kHz per a diferents còdecs. El fitxer MP3 original no conté freqüències superiors a 20 kHz.

Proveu de canviar els còdecs i comproveu si escolteu la diferència entre l'original, SBC 53 Joint Stereo (el perfil estàndard i més comú) i aptX/aptX HD.

Puc escoltar la diferència entre els còdecs als auriculars!

Les persones que no escolten la diferència entre els còdecs durant les proves mitjançant un servei web afirmen que la senten quan escolten música amb auriculars sense fil. Per desgràcia, això no és una broma ni un efecte placebo: la diferència és realment audible, però no és causada per diferències. còdecs.

La gran majoria dels chipsets d'àudio Bluetooth utilitzats en dispositius receptors sense fil estan equipats amb un processador de senyal digital (DSP), que implementa un equalitzador, un compressor, un expansor estèreo i altres coses dissenyades per millorar (o canviar) el so. Els fabricants d'equips Bluetooth poden configurar DSP per a cada còdec per separat, i en canviar entre còdecs, l'oient pensarà que està escoltant una diferència en el funcionament dels còdecs, quan en realitat està escoltant diferents configuracions de DSP.

Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius
Conducte de processament d'àudio DSP Kalimba en xips fabricats per CSR/Qualcomm

Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius
Activeu diferents funcions DSP per a cada còdec i sortiu per separat

Alguns dispositius premium inclouen programari que us permet personalitzar la configuració de DSP, però la majoria dels auriculars més barats no ho fan i els usuaris no poden desactivar el postprocessament d'àudio manualment.

Característiques funcionals dels dispositius

La versió moderna de l'estàndard A2DP té funció de "control de volum absolut". — Control de volum del dispositiu mitjançant ordres especials del protocol AVRCP, que regula el guany de l'etapa de sortida, en lloc de reduir programadament el volum del flux d'àudio. Si quan canvieu el volum dels vostres auriculars, el canvi no es sincronitza amb el volum del vostre telèfon, aleshores els vostres auriculars o telèfon no admeten aquesta funció. En aquest cas, té sentit escoltar música sempre amb el màxim volum al telèfon, ajustant el volum real amb els botons dels auriculars; en aquest cas, la relació senyal-soroll serà millor i la qualitat de l'àudio. hauria de ser a sobre.
En realitat, hi ha situacions tristes. Als meus auriculars RealForce OverDrive D1 per a SBC, s'activa un potent compander i augmentar el volum comporta un augment del nivell de sons tranquils, mentre que el volum dels sons forts no canvia (el senyal es comprimeix). Per això, heu de configurar el volum de l'ordinador a la meitat aproximadament, en aquest cas pràcticament no hi ha efecte de compressió.
Segons les meves observacions, tots els auriculars amb còdecs addicionals admeten la funció de control de volum absolut, sembla que aquest és un dels requisits per a la certificació del còdec.

Admet alguns auriculars connectar dos dispositius alhora. Això us permet, per exemple, escoltar música des del vostre ordinador i rebre trucades des del vostre telèfon. Tanmateix, heu de tenir en compte que en aquest mode els còdecs alternatius estan desactivats i només s'utilitza SBC.

AVDTP 1.3 Funció d'informes de retard permet que els auriculars comuniquin el retard al dispositiu de transmissió en què es reprodueix realment el so. Això us permet ajustar la sincronització de l'àudio amb el vídeo mentre visualitzeu fitxers de vídeo: si hi ha problemes amb la transmissió de ràdio, l'àudio no quedarà enrere del vídeo, sinó que, al contrari, el reproductor de vídeo alentirà el vídeo fins que L'àudio i el vídeo es tornen a sincronitzar.
La funció és compatible amb molts auriculars, Android 9+ i Linux amb PulseAudio 12.0+. No tinc coneixement del suport per a aquesta funció a altres plataformes.

Comunicació bidireccional mitjançant Bluetooth. Transmissió de veu.

Per a la transmissió de veu en Bluetooth, s'utilitza Synchronous Connection Oriented (SCO) - transmissió síncrona amb negociació preliminar de la connexió. El mode permet transmetre so i veu estrictament en ordre, amb velocitats d'enviament i recepció simètriques, sense esperar la confirmació de la transmissió i reenviament de paquets. Això redueix el retard general de la transmissió d'àudio a través del canal de ràdio, però imposa greus restriccions a la quantitat de dades transmeses per unitat de temps i afecta negativament la qualitat.
Quan s'utilitza aquest mode, tant la veu com l'àudio es transmeten amb la mateixa qualitat.
Malauradament, a partir del 2019, la qualitat de la veu per Bluetooth encara és deficient i no està clar per què el Bluetooth SIG no hi fa res.

CVSD

El còdec de veu bàsic CVSD es va estandarditzar l'any 2002 i és compatible amb tots els dispositius de comunicació Bluetooth bidireccionals. Proporciona transmissió d'àudio amb una freqüència de mostreig de 8 kHz, que correspon a la qualitat de la telefonia per cable convencional.

Un exemple d'enregistrament en aquest còdec.

mSBC

El còdec mSBC addicional es va estandarditzar el 2009 i el 2010 ja van aparèixer xips que l'utilitzaven per a la transmissió de veu. mSBC és àmpliament compatible amb diversos dispositius.
No es tracta d'un còdec independent, sinó d'un SBC normal de l'estàndard A2DP, amb un perfil de codificació fix: 16 kHz, mono, bitpool 26.

Un exemple d'enregistrament en aquest còdec.

No és genial, però molt millor que CVSD, però encara és molest utilitzar-lo per a la comunicació en línia, sobretot quan feu servir auriculars per comunicar-vos dins del joc: l'àudio del joc també es transmetrà a una freqüència de mostreig de 16 kHz.

L'empresa FastStreamCSR va decidir desenvolupar la idea d'utilitzar SBC. Per evitar les limitacions del protocol SCO i utilitzar velocitats de bits més altes, CSR va seguir una ruta diferent: van introduir suport per a àudio SBC bidireccional a l'estàndard de transmissió d'àudio unidireccional A2DP, perfils de codificació estandarditzats i el van anomenar "FastStream".

FastStream transmet àudio estèreo a 44.1 o 48 kHz amb una taxa de bits de 212 kbps als altaveus, i mono, 16 kHz, amb una taxa de bits de 72 kbps s'utilitza per transmetre àudio des del micròfon (una mica millor que mSBC). Aquests paràmetres són molt més adequats per a la comunicació en jocs en línia: el so del joc i els interlocutors seran d'alta qualitat.

Un exemple d'enregistrament en aquest còdec (+ so del micròfon, igual que mSBC).

L'empresa va crear una crossa interessant, però a causa del fet que contradiu l'estàndard A2DP, només s'admet en alguns dels transmissors de l'empresa (que funcionen com a targeta d'àudio USB, no com a dispositiu Bluetooth), però no ho fa. rebre suport a les piles Bluetooth encara que el nombre d'auriculars amb suport FastStream no és tan petit.

De moment, només hi ha suport FastStream al sistema operatiu com a pedaç per a Linux PulseAudio del desenvolupador Pali Rohár, que no està inclòs a la branca principal del programa.

aptX Baixa latència

Per a la vostra sorpresa, aptX Low Latency també admet àudio bidireccional, implementant el mateix principi que FastStream.
No és possible utilitzar aquesta funció del còdec enlloc: no hi ha suport per a la descodificació de baixa latència en cap sistema operatiu ni en cap pila Bluetooth que jo conegui.

Bluetooth 5, clàssic i de baix consum

Hi ha hagut molta confusió al voltant de les especificacions i versions de Bluetooth a causa de la presència de dos estàndards incompatibles sota la mateixa marca, tots dos s'utilitzen àmpliament amb finalitats diferents.

Hi ha dos protocols Bluetooth diferents i incompatibles: Bluetooth Classic i Bluetooth Low Energy (LE, també conegut com Bluetooth Smart). També hi ha un tercer protocol, Bluetooth High Speed, però no està molt estès i no s'utilitza en dispositius domèstics.

A partir de Bluetooth 4.0, els canvis en l'especificació es refereixen principalment a Bluetooth Low Energy i la versió clàssica només van rebre millores menors.

Llista de canvis entre Bluetooth 4.2 i Bluetooth 5:

9 CANVIS DE LA v4.2 A LA 5.0

9.1 NOVES CARACTERÍSTIQUES

S'introdueixen diverses funcions noves a la versió 5.0 de l'especificació principal de Bluetooth. Les principals àrees de millora són:
• Màscara de disponibilitat de ranures (SAM)
• 2 Msym/s PHY per LE
•LE Long Range
• Publicitat no connectable d'alt cicle de treball
• LE Advertising Extensions
• Algoritme de selecció de canal LE #2
9.1.1 Característiques afegides a CSA5 - Integrades a la v5.0
•Major potència de sortida

Font: www.bluetooth.org/docman/handlers/DownloadDoc.ashx?doc_id=421043 (pàgina 291)

Només un canvi va afectar la versió Classic en el marc de l'especificació Bluetooth 5: van afegir suport per a la tecnologia Slot Availability Mask (SAM), dissenyada per millorar la separació de les emissions de ràdio. Tots els altres canvis només afecten Bluetooth LE (i també una potència de sortida més alta).

Tots Els dispositius d'àudio només utilitzen Bluetooth Classic. És impossible connectar auriculars i altaveus mitjançant Bluetooth Low Energy: no hi ha cap estàndard per transmetre àudio mitjançant LE. L'estàndard A2DP, utilitzat per transmetre àudio d'alta qualitat, només funciona mitjançant Bluetooth Classic i no hi ha cap analògic a LE.

Conclusió: comprar dispositius d'àudio amb Bluetooth 5 només a causa de la nova versió del protocol no té sentit. Bluetooth 4.0/4.1/4.2 en el context de la transmissió d'àudio funcionarà exactament igual.
Si l'anunci de nous auriculars esmenta un rang de funcionament duplicat i un consum d'energia reduït gràcies al Bluetooth 5, heu de saber que ells mateixos no ho entenen o us enganyen. No és d'estranyar, perquè fins i tot els fabricants de xips Bluetooth en els seus anuncis estan confosos sobre les diferències entre la nova versió de l'estàndard, i alguns xips Bluetooth 5 només admeten la cinquena versió per a LE i utilitzen 4.2 per a Classic.

Retard de transmissió d'àudio

La quantitat de retard (retard) a l'àudio depèn de molts factors: la mida de la memòria intermèdia a la pila d'àudio, a la pila Bluetooth i al propi dispositiu de reproducció sense fil, i el retard algorítmic del còdec.

La latència de còdecs simples com SBC, aptX i aptX HD és molt petita, de 3 a 6 ms, cosa que es pot descuidar, però els còdecs complexos com AAC i LDAC poden causar un retard notable. La latència algorítmica AAC per a 44.1 kHz és de 60 ms. LDAC: uns 30 ms (basat en una anàlisi aproximada del codi font. Podria estar equivocat, però no gaire).

La latència resultant depèn en gran mesura del dispositiu de reproducció, el seu chipset i el buffer. Durant les proves, vaig rebre una propagació de 150 a 250 ms en diferents dispositius (amb el còdec SBC). Si suposem que els dispositius que admeten còdecs addicionals aptX, AAC i LDAC utilitzen components d'alta qualitat i una mida de memòria intermèdia petita, obtenim les següents latències típiques:

SBC: 150-250 ms
aptX: 130-180 ms
AAC: 190-240 ms
LDAC: 160-210 ms

Permeteu-me que us recordi: aptX Low Latency no és compatible amb els sistemes operatius, per això només es pot obtenir una latència més baixa amb una combinació transmissor+receptor o transmissor+auriculars/altaveu, i tots els dispositius han de ser compatibles amb aquest còdec.

Problemes amb el dispositiu Bluetooth, la certificació i el logotip

Com distingir un dispositiu d'àudio d'alta qualitat d'una embarcació barata? En aparença, primer de tot!

Per a auriculars, altaveus i receptors xinesos barats:

  1. Falta la paraula "Bluetooth" a la caixa i al dispositiu, "Sense fil" i "BT" s'utilitzen amb més freqüència
  2. Falta el logotip de Bluetooth Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius a la caixa o dispositiu
  3. Cap LED blau parpellejant

L'absència d'aquests elements indica que el dispositiu no ha estat certificat, la qual cosa significa que és potencialment de baixa qualitat i problemàtic. Per exemple, els auriculars Bluedio no estan certificats per Bluetooth i no compleixen totalment l'especificació A2DP. No haurien aprovat la certificació.

Considerem diversos dispositius i caixes d'ells:
Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Àudio mitjançant Bluetooth: el màxim de detall possible sobre perfils, còdecs i dispositius

Tots aquests són dispositius no certificats. Les instruccions poden contenir un logotip i el nom de la tecnologia Bluetooth, però el més important és que estiguin a la caixa i/o al propi dispositiu.

Si els vostres auriculars o altaveus diuen "Ze bluetooth dewise s'ha connectat correctament", això tampoc indica la seva qualitat:

Conclusió

El Bluetooth pot substituir completament els auriculars i els auriculars amb cable? És capaç, però a costa d'una mala qualitat de trucada, una major latència d'àudio que pot ser molesta als jocs i una gran quantitat de còdecs propietaris que requereixen tarifes de llicència i augmenten el cost final tant dels telèfons intel·ligents com dels auriculars.

El màrqueting de còdecs alternatius és molt fort: aptX i LDAC es presenten com un substitut molt esperat de l'SBC "obsolet i dolent", que no és tan dolent com la gent pensa que és.

Com va resultar, es poden obviar les limitacions artificials de les piles Bluetooth a la taxa de bits SBC, de manera que l'SBC no serà inferior a aptX HD. Vaig prendre la iniciativa a les meves pròpies mans i vaig fer un pedaç per al firmware LineageOS: Modificació de la pila Bluetooth per millorar el so dels auriculars sense còdecs AAC, aptX i LDAC

Podeu trobar més informació a les webs Nois de so и Expert en so.

Bonus: Codificador de referència SBC, informació de flux de bits A2DP i fitxers de prova. Aquest fitxer abans es publicava públicament al lloc web de Bluetooth, però ara només està disponible per als membres del Bluetooth SIG.

Font: www.habr.com

Afegeix comentari