Codecs de Audio simples III : Binary Time constant (BTc)

By | 11.08.2017

Ya vimos el algoritmo DM, y que usando un integrador con perdidas, podíamos limitar el efecto de ruido en el medio de comunicación entre el codec y el decoder. También vimos que la descarga obedece la formula e^{\frac{-1}{\tau \cdot Fm}}. Esta tipo de formula debería de ser familiar para quien haya tenido unos mínimos estudios de electrónica. En particular, recuerda la formula de la tensión de descarga de un condensador en un circuito RC serie. También hemos observado que imitar este comportamiento, implicaba usar multiplicaciones en coma flotante, lo cual en principio es poco deseable para el tipo de dispositivos que estamos tratando. Y bueno… ¿No seria quizás posible usar un circuito RC para implementar el integrador con perdidas ? Pues la respuesta es que si, y además al paso actúa como conversor DACdel decoder, con lo que matamos dos pájaros de un tiro. Pues en esto se basa el algoritmo BTc. Es simplemente como tomar.

Repasemos un poco como carga/descarga un circuito RC serie. En la carga del condensador, la tensión entre los bornes del condensador, es regida por, donde  o constante de tiempo :

Carga Condensador

Podemos observar que en cada \tau  unidades de tiempo, el condensador se carga aproximadamente un 63.2% de lo que le falta para estar completamente cargado. La descarga es similar, pero en este caso, el condensador se queda con el 36.8% de la carga restante en cada \tau  unidades de tiempo. Esto esta bien, podemos enviarle pulsos de 1′s o 0′s al circuito RC, para que alcance el punto deseado de carga, y luego usar la tensión que tiene el condensador como salida analógica, siempre y cuando usemos algún amplificador con una entrada de alta impedancia, por ejemplo un Amplificador Operacional. El decoder se reduce simplemente a emitir 1′s y 0′s por una pata al circuito RC, lo cual es brillantemente sencillo.

Binary Time constant o BTc

Sin embargo, esto tiene una pega, y es que hemos complicado más aun el codec, ya que ahora hay que incrementar/decrementar el integrador usando en coma flotante, ya que el condensador aumenta su carga o la disminuye según un porcentaje que no es una fracción exacta.

Y si en vez de usar \tau = T_c = 1/ F_m , hacemos que R y C tengan unos valores tales que el tiempo 1/F_m  se cargue/descargue en un valor que sea una fracción exacta, tal como 1/2 por ejemplo.

Carga usando Tc distinto de Tau

Ahora nuestra Delta va a ser 1/2 de la distancia al valor máximo (si estamos cargando) o 1/2 al valor mínimo (si estamos descargando) en vez de ser el %63.8 de dicha distancia. Dividir por dos es trivial y rápido en aritmética entera, con lo cual acabamos de simplificar el codificador. En vez de 1/2 podemos usar otro valor tal como 1/16, 1/32, etc… A dicho valor, se le llama constante de suavizado. Tener un valor más pequeño o más grande, va a producir el mismo efecto que usar una Delta mayor o menor que en DM, además que también altera el valor de la constante ‘a‘. A mayor valor de la constante de suavizado, trabajamos como si tuviésemos una Delta menor y una constante a mayor. A efectos prácticos, es como trabajar siempre con la Delta ideal de la constante ‘a‘ que deseamos, fijando el valor máximo deseado a la tensión TTL (o CMOS).

Binary Time constant 1.0 con softness 1/21

Ficheros de ejemplo de como suena BTc 1.0 con softness de 21

  • FX, voz y música (Elements de Linsey Sterling y Overtura 1812) a 44,1KHz

Autor original del algoritmo : Roman Black

Código de ejemplo en Python 3.