Tecnología de audio inalámbrica Bluetooth: ¿cuál es mejor?


Con el desarrollo de la tecnología, los tan conocidos auriculares analógicos "tube" pasan a la historia: son cada vez más suplantados por sus homólogos inalámbricos Bluetooth.

Los teléfonos inteligentes modernos se ven privados del conector habitual en aras de la protección contra la humedad y el polvo.

Los desarrolladores lanzan todas las nuevas versiones del protocolo Bluetooth y todas las nuevas versiones de códecs, prometiendo "más rápido, más alto, más fuerte" - menos demoras en la reproducción y mejor calidad.

¿Está todo tan bien? A ver

Introduccion


No profundizaré en la implementación técnica de los protocolos, así como en las aburridas especificaciones. Estimado ValdikSS , quien en gran medida actuó como inspiración e incluso como consultor científico en este artículo, está preparando material completo sobre códecs, y todo se presentará allí con mucho más detalle y técnicamente correcto.

Quiero contar más sobre la experiencia personal. Bueno, un poco entretenido (¿aburrido?) Práctica.

Hace un año y medio, me entusiasmó la idea de aptX. Sí, leí muchas críticas como esta y creí en todos estos giros y vueltas técnicos. Nació un niño, y realmente quería ver programas con auriculares por la noche con mi esposa, sin hacer ruido y sin despertar a nadie en la casa.

¿En qué resultó?

Calidad


Comencemos con números y hechos (¡hola, Wikipedia!)

SBC es un buen códec antiguo, que cumple con el estándar A2DP. El códec es el resultado del trabajo de Frans de Bont (F. de Bont, M. Groenewegen y W. Oomen, "Un sistema de codificación de audio de alta calidad a 128 kb / s", 98ª Convención AES, 25-28 de febrero de 1995) y uso Los algoritmos descritos en la patente EP-0400755B1 . Es de destacar que los autores de la patente permiten el uso gratuito de SBC solo en la aplicación Bluetooth, sin embargo, la patente expiró el 2 de junio de 2010. Dado que el estándar A2DP es muy común, es extremadamente difícil encontrar auriculares o altavoces que no sean compatibles con SBC.

El códec proporciona una frecuencia de muestreo de 16, 32, 44.1, 48 kHz con una velocidad de flujo de 10-1500 kbit / s. Sí, escuchaste bien. Hasta 1500 kbps. Simplemente no hay límite de velocidad de bits en el códec. Pero más sobre eso más tarde.

El códec aptX se desarrolló en 1988 en la Queen's University Belfast . Sí, antes de Bluetooth todavía había alrededor de una docena de años, por lo que el códec se usó en equipos de audio profesionales. Qualcomm actualmente posee los derechos y, por lo tanto, el uso requiere licencias y regalías. A partir de 2014, el costo es aproximadamente el siguiente: un pago único de $ 6,000 y ≈ $ 1 por cada dispositivo lanzado para grupos de hasta 10,000 dispositivos. Por esta razón, muchos dispositivos con Snapdragon 835, 845, 821, 820, 810, 805, 801, 800, 650, 615, 410 chips son bastante posibles y admiten aptX, pero no se activa allí, porque la licencia no se compró. Sobre eso, también a continuación.

Con una profundidad de 16 bits y una frecuencia de muestreo de 48 kHz, el códec puede proporcionar una velocidad de bits de 384 kbit / s (doble canal).

Lista de productos que admiten oficialmente aptX . Puede encontrar una gran cantidad de sistemas desconocidos con soporte aptX en Aliexpress, pero esté preparado para el hecho de que, de hecho, habrá el mismo SBC viejo y bueno, y nada más.

aptX HD : el mismo códec, pero con un perfil de codificación diferente, tiene una velocidad de transmisión de 576 kbit / s, soporte para frecuencias de muestreo de hasta 48 kHz y profundidad de bits de hasta 24 bits. Algunas personas llaman a este códec aptX Lossless, pero esto no tiene sentido, aunque solo sea porque en este momento es imposible alcanzar el valor de una secuencia que pueda transportar datos sin pérdidas. Una ventaja particular de este códec es un retardo de codificación ajustable, que puede reducirse a 1 ms a una frecuencia de muestreo de 48 kHz. Además, el códec es extremadamente ventajoso desde el punto de vista de la carga del procesador, lo que expresa una ventaja en comparación con MP3 y AAS.

Lista de productos que admiten oficialmente aptX HD . Él es lo suficientemente pequeño.

aptX Low latency (o LL) es una versión especial del códec que le permite reducir el tiempo de retraso del sonido a menos de 40 ms. Lista de productos que admiten oficialmente aptX LL .

imagen

Ahí está ella. Fue esta foto la que alguna vez me compró con menudillos. Retrasos! Después de todo, ¿quién quiere escuchar el sonido de una explosión en una película de acción, el grito de un monstruo en una película de terror o el rugido de una multitud en un partido de fútbol cuando todo termina?

¿Pero es todo esto realmente así?

Por desgracia no.

Como con cualquier material de marketing, los números son exagerados. El retraso depende en gran medida del almacenamiento en búfer en el sistema y la implementación del códec. Por lo tanto, el retraso con SBC puede ser inferior a 40 ms, lo cual, dados los estándares de transmisión de televisión (+40 ms ... −60 ms), es perfectamente aceptable.

En resumen:

  1. Ningún códec existente puede ser mejor que la tecnología cableada, ya que ningún códec puede lograr una verdadera compresión sin pérdidas.
  2. El códec más popular es SBC. Es el más flexible en entornos. Y a pesar del hecho de que aptX se lanzó antes, no pudo superar la popularidad de SBC, aparentemente debido a que este último es gratuito.
  3. La calidad del sonido depende en gran medida de la implementación del códec, así como del rendimiento del hardware de los auriculares / altavoces en general: si el altavoz en sí es débil, ningún códec puede mejorar la calidad. Por lo tanto, en el futuro, comparando la calidad, hablaremos sobre reproducir el mismo contenido de la misma fuente en los mismos altavoces / auriculares, pero con diferentes códecs.

Resultados prácticos y muy subjetivos.




La información se basa en la experiencia de un año y medio ya mencionada en la operación, comparación y atracción de oyentes externos.

La experiencia se basa en escuchar sin pérdidas en el reproductor SONY Walkman NWZ-A17, donde se puede seleccionar el códec, así como en ver varios programas con salida de audio a través de Avantree Priva III.

Había tres auriculares: Sennheiser PMX 60, Koss Porta Pro y Koss UR-20.

Se utilizaron Jabra BT3030 (SBC) y Avantree Clipper Pro (aptX) como receptores de señal inalámbrica.

También se utilizaron un altavoz Voombox Outdoor (SBC) y auriculares de conducción ósea Aftershokz Trekz Titanium (aptX).

Todos los ecualizadores y potenciadores se desactivaron, y esto es importante.

Total:

  1. La calidad del sonido que se reproduce con una conexión por cable siempre es mejor. Esto es sin lugar a dudas.
  2. La diferencia entre SBC y aptX es extremadamente difícil de escuchar, y solo en el caso de algunos tipos de música. Por ejemplo, el autor del artículo escuchó claramente la diferencia en los solos de violonchelo en las composiciones clásicas, mientras que para el violín y los instrumentos de baja frecuencia la diferencia era menos perceptible. En los géneros modernos, pop, música electrónica y rock, la diferencia no se escucha. En algunos casos, subjetivamente parecía que SBC transmite el sonido mejor que aptX.
  3. El retraso entre SBC y aptX se puede ver solo si se conecta a la misma fuente e inserta diferentes receptores en diferentes oídos (bueno, el canal izquierdo es SBC y el derecho es aptX, por ejemplo). Es casi imposible ver el retraso con la imagen, pero porque la historia de que aptX está destinado a escenas dinámicas y contenido es un mito.
  4. La sorpresa fue causada por la calidad del sonido en el Voombox Outdoor bastante barato y "no famoso". Aparentemente, esta es la implementación exitosa de SBC, que se mencionó anteriormente.
  5. La implementación de aptX en auriculares con conducción ósea es completamente incomprensible: la tecnología es muy específica y, por lo tanto, la pérdida de calidad es significativa debido a la tecnología en sí misma. Teniendo en cuenta el pequeño rango del "rango" de la operación del dispositivo, la implementación extremadamente pobre del emparejamiento con dos dispositivos, puedo decir que Aftershokz es una compañía que invierte más en marketing que en desarrollo.


No estoy argumentando que si conecta todo tipo de analizadores espectrales, etc., puede y debe ver la diferencia. Pero el oído humano, y lo que es peor, el oído humano promedio, no es un dispositivo espectral y, por lo tanto, no escucha todos estos matices.

Práctica: arreglar lo que se puede arreglar


Parte 1. Encienda aptX


Como ya se mencionó, en algunos dispositivos el uso de aptX está desactivado, probablemente para evitar enjuiciamientos de patentes.

Este problema se puede resolver simplemente deslizando el dispositivo de la biblioteca para implementar el códec y escribiendo la capacidad de trabajar con este códec en build.prop.

En Internet hay una gran cantidad de soluciones de esta naturaleza. Me tomé la libertad de combinarlos en uno, y me di cuenta como un módulo para Magisk. Sí, realmente me gusta este proyecto y creo que implementar cambios en el sistema en forma de módulos Magisk es una solución mejor y más segura con la capacidad de guardar el sistema en su forma original y de una manera fácil de retroceder.

El módulo se puede descargar desde aquí . Sí, sé sobre github. Y no, hasta que tenga tiempo de ponerlo allí.

Las entradas en build.prop, incluidos aptX y, si es posible, aptX HD, serán emuladas automáticamente por el módulo.



Parte 2. Aumentar la tasa de bits de SBC


Como se informó anteriormente, el códec SBC básicamente no tiene restricciones de velocidad de bits. Sin embargo, los fabricantes suelen establecer un límite de 342 kbit / s para mono y 345 kbit / s para estéreo para garantizar un funcionamiento confiable con todo tipo de dispositivos receptores.

Al mismo tiempo, la especificación A2DP v1.2, que estuvo activa de 2007 a 2015, requiere que todos los dispositivos de decodificación funcionen correctamente con velocidades de bits de hasta 320 kbit / s para mono y 512 kbit / s en el caso de una señal estéreo.

En la nueva versión de la especificación, no hay límite de velocidad de bits. Se supone que los auriculares modernos lanzados después de 2015 y que admiten EDR pueden admitir velocidades de bits de hasta 730 kbps.

De hecho, este ciertamente no es el caso. En un extenso estudio realizado por ValdikSS , se descubrió que casi todos los dispositivos receptores funcionan de manera confiable con velocidades de bits de 454 kbit / s, y un número bastante grande con una velocidad de bits de 507 kbit / s.

En su investigación, ValdikSS también demostró que, contrariamente a la creencia popular sobre la calidad del códec aptX, puede producir peores resultados en algunos archivos que SBC con una velocidad de bits estándar de 328 kbps, y cambiar a un SBC de alta velocidad de bits producirá un sonido que a menudo excede aptX, en cualquier auricular.

En base a estos datos, ValdikSS envió comentarios a los desarrolladores de Lineage OS y Google, pero hasta ahora no ha habido reacción.

Por lo tanto, solo podemos realizar modificaciones manualmente en la pila Bluetooth.

Necesitamos un IDA Pro con la capacidad de descompilar ARM, cualquier editor HEX (utilicé WinHEX) y el archivo bluetooth.default.so de nuestro dispositivo. Por lo general, se encuentra en la ruta / sistema / lib / hw y con menos frecuencia, también en la ruta / sistema / lib64 / hw (definitivamente se necesita acceso a la raíz).

Entonces, abra el archivo bluetooth.default.so. Las operaciones y modificaciones que se describen a continuación se aplican solo a la pila original de Android (bluedroid). Si ve la línea "Biblioteca necesaria 'com.qualcomm.qti.bluetooth_audio@1.0.so'" o similar en IDA Pro, con alta probabilidad esta instrucción no lo ayudará.



Nuestra primera tarea es reemplazar Joint Stereo con Dual Channel en una configuración estándar.

Trabajaremos con la función bta_av_build_src_cfg .

Para encontrar este procedimiento en la IDA, utilizaremos la búsqueda de línea para un mensaje característico en el registro de depuración "No se puede analizar src cap ret =% d" :





Como resultado, encontramos rápidamente la función en forma de código:



Nuestra tarea es reemplazar la estructura original de los cheques

if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_JOINT) pref_cap.ch_mode = A2D_SBC_IE_CH_MD_JOINT; else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_STEREO) pref_cap.ch_mode = A2D_SBC_IE_CH_MD_STEREO; else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_DUAL) pref_cap.ch_mode = A2D_SBC_IE_CH_MD_DUAL; else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_MONO) pref_cap.ch_mode = A2D_SBC_IE_CH_MD_MONO;</code>  <code> if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_DUAL) pref_cap.ch_mode = A2D_SBC_IE_CH_MD_DUAL; else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_STEREO) pref_cap.ch_mode = A2D_SBC_IE_CH_MD_STEREO; else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_DUAL) pref_cap.ch_mode = A2D_SBC_IE_CH_MD_DUAL; else if (src_cap.ch_mode & A2D_SBC_IE_CH_MD_MONO) pref_cap.ch_mode = A2D_SBC_IE_CH_MD_MONO; 

Hay varias formas de hacer esto.

El primero es el reemplazo de las instrucciones TST.W R0, # 1 con TST.W R0, # 4 y MOVS R0, # 1 con MOVS R0, # 4 en la secuencia de verificaciones:



En bytecode, este es el reemplazo de x01 a x04. Es importante tener en cuenta la secuencia característica de bytes mediante la cual se puede encontrar este patrón. Sin profundizar en los detalles, diré que en esencia es una búsqueda de secuencia

 10 20 8D F8 04 00 9D F8 0D 00 10 F0 01 0F ?? ?? 10 F0 02 0F ?? ?? 10 F0 04 0F ?? ?? 10 F0 08 0F ?? ?? 08 20 ?? ?? 01 20 ?? ?? 02 20 ?? ?? 04 20 

y su reemplazo por

 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 04 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 04 ?? ?? ?? ?? ?? ?? ?? ?? ?? 

Sin embargo, este método tiene desventajas.

Varios compiladores cambian la secuencia de ejecución de comandos dependiendo de la optimización. Y en este caso, no es posible encontrar el patrón deseado, y a veces el mecanismo de verificación en la estructura generalmente se introduce en el código en línea. Por lo tanto, es más confiable cambiar la constante btif_av_sbc_default_config .

Para empezar, encuéntrala. Ella está al comienzo de nuestra función, porque

 void bta_av_build_src_cfg (UINT8 *p_pref_cfg, UINT8 *p_src_cap) { tA2D_SBC_CIE src_cap; tA2D_SBC_CIE pref_cap; UINT8 status = 0; /* initialize it to default SBC configuration */ A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &btif_av_sbc_default_config, p_pref_cfg); /* now try to build a preferred one */ /* parse configuration */ if ((status = A2D_ParsSbcInfo(&src_cap, p_src_cap, TRUE)) != 0) { APPL_TRACE_DEBUG(" Cant parse src cap ret = %d", status); 

Y aquí está ella:





Se puede ver que btif_av_sbc_default_config es una secuencia de bytes 20 01 10 04 01 35 02, mientras que el primer byte codifica la frecuencia de muestreo y puede ser 10 (48 kHz) y 20 (44 kHz), y por lo tanto no es específico. Por lo tanto, nuestra tarea es reemplazar la secuencia
01 10 04 01 35 02
en
04 ?? ?? ?? ?? ??

Esto le permitirá cambiar la lógica de la estructura de manera similar, pero al mismo tiempo, la optimización del compilador no causará problemas.

En algunos casos, los auriculares o altavoces inician la conexión. En este caso, el modo está determinado por la función bta_av_co_audio_init .

La función se caracteriza por la línea "bta_av_co_audio_init:% d" y se busca fácilmente en el código:


La enumeración de los posibles modos de conexión se realiza en el siguiente comando:

  switch (index) { case BTIF_SV_AV_AA_SBC_INDEX: /* Set up for SBC codec for SRC*/ *p_codec_type = BTA_AV_CODEC_SBC; /* This should not fail because we are using constants for parameters */ A2D_BldSbcInfo(AVDT_MEDIA_AUDIO, (tA2D_SBC_CIE *) &bta_av_co_sbc_caps, p_codec_info); /* Codec is valid */ return TRUE; 

La constante bta_av_co_sbc_caps tiene la siguiente estructura :

 const tA2D_SBC_CIE bta_av_co_sbc_caps = { (A2D_SBC_IE_SAMP_FREQ_44), /* samp_freq */ (A2D_SBC_IE_CH_MD_MONO | A2D_SBC_IE_CH_MD_STEREO | A2D_SBC_IE_CH_MD_JOINT | A2D_SBC_IE_CH_MD_DUAL), /* ch_mode */ (A2D_SBC_IE_BLOCKS_16 | A2D_SBC_IE_BLOCKS_12 | A2D_SBC_IE_BLOCKS_8 | A2D_SBC_IE_BLOCKS_4), /* block_len */ (A2D_SBC_IE_SUBBAND_4 | A2D_SBC_IE_SUBBAND_8), /* num_subbands */ (A2D_SBC_IE_ALLOC_MD_L | A2D_SBC_IE_ALLOC_MD_S), /* alloc_mthd */ BTA_AV_CO_SBC_MAX_BITPOOL, /* max_bitpool */ A2D_SBC_IE_MIN_BITPOOL /* min_bitpool */ }; 

La constante se encuentra fácilmente en el código, en mi caso es 20 0F F0 0C 03 35 02:



Preste atención al byte 0F : proporciona la capacidad de conectarse con cualquiera de los modos válidos, ya que

 x0F = A2D_SBC_IE_CH_MD_MONO | A2D_SBC_IE_CH_MD_STEREO | A2D_SBC_IE_CH_MD_JOINT | A2D_SBC_IE_CH_MD_DUAL = x08 | x02 | x01 | x04 

Nuestra tarea es cambiar este valor de la siguiente manera:

 x0F = A2D_SBC_IE_CH_MD_DUAL = x04 

Por lo tanto, es necesario reemplazar

?? 0F F0 0C 03 35 02
en
?? 04 ?? ?? ?? ?? ??

Entonces, hicimos que la pila se conectara en modo de doble canal tanto en el caso de iniciar una conexión por el dispositivo, como en el caso de iniciar una conexión por el lado receptor de la señal.

Ahora necesita eliminar las restricciones en bitrate o aumentar su umbral superior.

Necesita manejar btif_media_task_get_sbc_rate . De manera similar, para buscar la línea característica "se detectó un sumidero a2dp no edr, restringir la tasa a% d", buscamos la función en el código:


El límite de velocidad de bits se expresa en una cadena
UINT16 rate = DEFAULT_SBC_BITRATE (que a su vez es 328 kbps )

En el código, esto es así:



Cambie este valor a 454 kbit / s: es más alto que el estándar y funciona con la gran mayoría de los receptores. Para hacer esto, reemplace los bytes

B1 4F F4 A4 74 ?? E0
en
?? ?? ?? E3 ?? ?? ??

También debe buscar por patrón.

E0 4F F4 A4 74 ?? E0
y reemplazarlo con
?? ?? ?? E3 ?? ?? ??
- Esto es necesario para varios dispositivos.

El valor de E3 puede ser diferente dependiendo de la velocidad de bits máxima deseada:

  • E3 - 454 kbps
  • F1 - 482 kbps
  • F3 - 486 kbps
  • 10 - 576 kbps
  • 48 - sin límite

En general, esto está determinado por el código de bytes de la operación MOV.W R4, XXX.

En la práctica, vale la pena experimentar y elegir el valor máximo en el que todos sus dispositivos receptores reciben una recepción de señal estable, no hay grietas, interrupciones o distorsiones.

En todos los receptores en mi experimento (los indiqué anteriormente), este valor era 576 kbps, el teléfono Xiaomi Redmi 4x MIUI10 Android 7.1 era la fuente de la señal.

Según las acciones descritas, se creó un parche genérico que encuentra los patrones especificados en Bluetooth.default.so y los reemplaza. incluido el modo forzado de doble canal y establecer el límite de velocidad de bits a 454 kbps. Si es necesario, el valor límite puede cambiarse fácilmente en función de la búsqueda y el reemplazo del byte correspondiente; un lector atento lo hará sin dificultad.

Destaco: el parche solo funciona en el caso de la pila de bluedroid y lo más probable es que no tenga éxito en el caso de la pila de flúor y la versión de Android 8 y posteriores.

El parche se puede descargar desde aquí .

Se recomienda encarecidamente que reemplace el archivo original como módulos Magisk, por mí mismo hice esto de la siguiente manera . Tenga en cuenta que estos módulos fueron creados por mí para el teléfono Xiaomi Redmi 4x 3/32 GB con el firmware MIUI 10 estable global actual en el momento de la escritura. En su caso, el archivo bluetooth.default.so tendrá que ser reemplazado por el suyo, parcheado, como se describió anteriormente. También es posible que el archivo deba duplicarse a lo largo de la ruta / system / lib64 / hw; depende del modelo y la versión de firmware de su teléfono.

Este enfoque que utiliza módulos Magisk facilita el cambio de la tasa de bits máxima y, en general, deshabilita los cambios si resulta que algunos de los dispositivos receptores no son compatibles con Dual Channel.

Conclusión


En este momento, en la búsqueda de ventas, muchas compañías están presentando algunas innovaciones tecnológicas como justificación para un precio más alto.

En la práctica, resulta que las tecnologías más baratas existentes no están completamente desarrolladas y las innovaciones tecnológicas no están completamente implementadas, lo que afecta significativamente la calidad.

Muy a menudo, los usuarios experimentan el "efecto placebo", convenciéndose de la perfección de un producto solo porque se presenta más nuevo o más colorido. De hecho, esta cualidad es imaginaria.

A pesar del deterioro obvio en la calidad de la transmisión de audio inalámbrica en comparación con la versión con cable, parece que los fabricantes de dispositivos modernos apuntan a una transición completa a las tecnologías inalámbricas. Al mismo tiempo, los trucos de marketing se utilizan para justificar el aumento de precios: protección contra la inmersión del teléfono en el agua (¿cómo se puede hablar bajo el agua? ¿Por qué tirar el dispositivo al agua?), Uso de códecs más caros, etc. Al mismo tiempo, el potencial del popular códec SBC existente no se utiliza por completo.

No pudimos obtener ninguna aclaración de Google con respecto al límite de velocidad de bits de 328 kbps, ni eliminar este límite y agregar la opción para habilitar Dual Channel en el menú Bluetooth de los desarrolladores de Lineage OS.

¡Gracias a todos los que leyeron hasta el final!

Alguna continuación causada por la discusión en los comentarios y un espacio con respecto al códec LDAC está aquí .

Source: https://habr.com/ru/post/es433502/


All Articles