"audioop" --- Manipula datos de audio sin procesar
**************************************************

======================================================================

El módulo "audioop" contiene algunas operaciones útiles sobre
fragmentos de sonido. Opera en fragmentos de sonido que consisten en
muestras de enteros de 8, 16, 24, o 32 bits, guardados en *objetos
parecidos a bytes*. Todos los elementos escalares son enteros, a menos
que se especifique lo contrario.

Distinto en la versión 3.4: La compatibilidad para muestras de 24-bit
fue añadida. Todas las funciones ahora aceptan cualquier *bytes-like
object*. La entrada de cadenas de caracteres ahora resulta en un error
inmediato.

Este módulo proporciona compatibilidad con las codificaciones a-LAW,
u-LAW e Intel/DVI ADPCM.

Algunas de las operaciones más complicadas sólo toman muestras de
16-bit, si no, el tamaño de la entrada (en bytes) siempre es un
parámetro de la operación.

El módulo define las siguientes variables y funciones:

exception audioop.error

   Esta excepción es lanzada en todos los errores, tal como números
   desconocidos de bytes por entrada, etc.

audioop.add(fragment1, fragment2, width)

   Retorna un fragmento que es la adición de dos entradas pasadas como
   parámetros. *width* es la longitud de la muestra en bytes, o "1",
   "2", "3", o "4". Ambos fragmentos deben tener la misma longitud.
   Las muestras son truncadas en caso de desbordamiento.

audioop.adpcm2lin(adpcmfragment, width, state)

   Decodifica un fragmento codificado con Intel/DVI ADPCM en un
   fragmento lineal.  Véase la descripción de "lin2adpcm()" por
   detalles sobre la codificación ADPCM. Retorna una tupla "(sample,
   newstate)" donde la entrada tiene la longitud especificada en
   *width*.

audioop.alaw2lin(fragment, width)

   Convierte los fragmentos de sonido codificados con a-LAW en
   fragmentos de sonido linealmente codificados. La codificación a-LAW
   siempre usa muestras de 8 bits, por lo que *width* hace referencia
   sólo a la longitud de la entrada del fragmento de salida aquí.

audioop.avg(fragment, width)

   Retorna el promedio de todas las muestras en el fragmento.

audioop.avgpp(fragment, width)

   Retorna el promedio del valor de pico a pico de todas las muestras
   en el fragmento. No se hace ningún filtrado, por lo que la utilidad
   de esta rutina es cuestionable.

audioop.bias(fragment, width, bias)

   Retorna un fragmento que es el fragmento original con un *bias*
   añadido a cada muestra.  Las muestras se envuelven en caso de
   desbordamiento.

audioop.byteswap(fragment, width)

   Intercambia los bytes ("Byteswap") de todas las muestras en un
   fragmento y retorna el fragmento modificado. Convierte muestras
   *big-endian* en *little-endian* y viceversa.

   Nuevo en la versión 3.4.

audioop.cross(fragment, width)

   Retorna el número de cruces por 0 en el fragmento pasado como un
   argumento.

audioop.findfactor(fragment, reference)

   Retorna un factor *F* tal que "rms(add(fragment, mul(reference,
   -F)))" sea minimal, i.e., retorna el factor con el cual debes
   multiplicar la *reference* para hacerlo coincidir tanto como sea
   posible a *fragment*.  Los fragmentos deben contener muestras de
   2-byte.

   El tiempo tomado por esta rutina es proporcional a "len(fragment".

audioop.findfit(fragment, reference)

   Intenta hacer coincidir *reference* tanto bien como sea posible a
   un *fragment* (que debe ser el fragmento más largo).  Esto es
   (conceptualmente) hecho al tomar segmentos de *fragment*, usando
   "findfactor()" para computar la mejor coincidencia, y minimizando
   el resultado.  Los fragmentos deben contener muestras de 2-byte.
   Retorna una tupla "(offset, factor)" donde *offset* (entero) es el
   *offset* en *fragment* donde la coincidencia más óptima empezó y
   *factor* es el (número flotante) factor según "findfactor()".

audioop.findmax(fragment, length)

   Inspecciona *fragment* por un segmento de longitud *length*
   muestras (¡no bytes!) con la energía máxima, i.e., retorna *i* por
   el cual "rms(fragment[i*2:(i+length)*2])" es maximal.  Los
   fragmentos deben contener muestras de 2 bytes.

   La rutina tarda proporcionalmente a "len(fragment)".

audioop.getsample(fragment, width, index)

   Retorna el valor de la muestra *index* del fragmento.

audioop.lin2adpcm(fragment, width, state)

   Convierte las muestras en codificaciones Indel/DVI ADPCM de 4 bits.
   La codificación ADPCM es un esquema de codificación adaptativo a
   través del cual cada número de 4 bits es la diferencia entre una
   muestra y la siguiente, dividido por un paso (inconsistente). El
   algoritmo de Intel/DVI ADPCM ha sido seleccionado para su uso por
   el *IMA*, por lo que bien puede convertirse en un estándar.

   *state* is a tuple containing the state of the coder.  The coder
   returns a tuple "(adpcmfrag, newstate)", and the *newstate* should
   be passed to the next call of "lin2adpcm()".  In the initial call,
   "None" can be passed as the state. *adpcmfrag* is the ADPCM coded
   fragment packed 2 4-bit values per byte.

audioop.lin2alaw(fragment, width)

   Convierte las muestras en el fragmento de audio en una codificación
   a-LAW y los retorna como un objeto de bytes. a-LAW es un formato de
   codificación de audio a través del cual obtienes un rango dinámico
   de cerca de 13 bits usando sólo muestras de 8 bits. Es usado por el
   hardware de audio Sun, entre otros.

audioop.lin2lin(fragment, width, newwidth)

   Convierte muestras entre formatos de 1, 2, 3, y 4 bytes.

   Nota:

     En algunos formatos de audio, como archivos .WAV, las entradas de
     16, 24, y 32 bits tienen signo, pero las entradas de 8 bits no
     tienen signo. Por lo que cuando se convierta en entradas de 8
     bits  para estas entradas, también necesitas añadir 128 al
     resultado:

        new_frames = audioop.lin2lin(frames, old_width, 1)
        new_frames = audioop.bias(new_frames, 1, 128)

     Lo mismo, al revés, tiene que ser aplicado cuando se convierta
     muestras de 8 bits en muestras de 16, 24, o 32 bits.

audioop.lin2ulaw(fragment, width)

   Convierte muestras en el fragmento de audio en codificaciones u-LAW
   y lo retorna como un objeto de bytes.  u-LAW es un formato de
   codificación de audio a través del cual obtienes un rango dinámico
   de cerca de 14 bits usando sólo muestras de 8 bits.  Es usado por
   el hardware de audio Sun, entre otros.

audioop.max(fragment, width)

   Retorna el máximo de los *valores absolutos* de las entradas en un
   fragmento.

audioop.maxpp(fragment, width)

   Retorna el valor de pico a pico máximo en el fragmento de sonido.

audioop.minmax(fragment, width)

   Retorna una tupla que consiste de los valores mínimos y máximos de
   todas las entradas en el fragmento de sonido.

audioop.mul(fragment, width, factor)

   Retorna un fragmento que tiene todas las entradas en el fragmento
   original multiplicado por el valor de punto flotante *factor*.  Las
   muestras son truncadas en caso de desbordamiento.

audioop.ratecv(fragment, width, nchannels, inrate, outrate, state[, weightA[, weightB]])

   Convierte el ratio de fotogramas del fragmento de entrada.

   *state* es una tupla que contiene el estado del convertidor.  El
   convertidor retorna una tupla "(newfragment, newstate)", y
   *newstate* debe ser pasado a la siguiente llamada de "ratecv()".
   La llamada inicial debe pasar "None" como el estado.

   Los argumentos *weightA* y *weightB* son parámetros para un filtro
   digital simple y sus valores por defecto son "1" y "0"
   respectivamente.

audioop.reverse(fragment, width)

   Invierte las entradas en un fragmento y retorna el fragmento
   modificado.

audioop.rms(fragment, width)

   Retorna la media cuadrática del fragmento, i.e.
   "sqrt(sum(S_i^2)/n)".

   Este es una medida del poder en una señal de audio.

audioop.tomono(fragment, width, lfactor, rfactor)

   Convierte un fragmento estéreo en una fragmento mono. El canal
   izquierdo es multiplicado por *Ifactor* y el derecho por *rfactor*
   antes de añadir los dos canales para dar una señal mono.

audioop.tostereo(fragment, width, lfactor, rfactor)

   Genera un fragmento estéreo de un fragmento mono.  Cada par de
   muestras en el fragmento estéreo son computados de la entrada mono,
   a través del cual las muestras del canal izquierdo son
   multiplicadas por *Ifactor* y del canal derecho por *rfactor*.

audioop.ulaw2lin(fragment, width)

   Convierte los fragmentos de sonido en codificaciones u-LAW en
   fragmentos de sonidos linealmente codificados.  Las codificaciones
   u-LAW siempre usan muestras de 8 bits, por lo que *width* hace
   referencia  a la longitud de la muestra del fragmento de salida
   aquí.

Note que operaciones tales como "mul()" o "max()" no hacen distinción
entre fragmentos mono y estéreo, i.e. todas las muestras son tratadas
iguales.  Si este es un problema, el fragmento estéreo debe ser
dividido en dos fragmentos mono primero y recombinado después.  Aquí
hay un ejemplo de como hacerlo:

   def mul_stereo(sample, width, lfactor, rfactor):
       lsample = audioop.tomono(sample, width, 1, 0)
       rsample = audioop.tomono(sample, width, 0, 1)
       lsample = audioop.mul(lsample, width, lfactor)
       rsample = audioop.mul(rsample, width, rfactor)
       lsample = audioop.tostereo(lsample, width, 1, 0)
       rsample = audioop.tostereo(rsample, width, 0, 1)
       return audioop.add(lsample, rsample, width)

Si usas el codificador ADPCM para construir paquetes de redes y
quieres que tu protocolo no tenga estado (*stateless*) (i.e. para ser
capaz de tolerar pérdida de paquetes) no sólo debes transmitir los
datos pero también el estado. Note que debes enviar el estado inicial
(*initial*) (el que pasas a "lin2adpcm()") junto con el decodificador,
no el estado final (como es retornado por el codificador).  Si quieres
usar un "struct.Struct" para almacenar el estado en binario puedes
codificar el primer elemento (el valor predicho) en 16 bits y el
segundo (el índice delta) en 8.

Los codificadores ADPCM nunca se han probado en contra de otros
codificadores ADPCM, sólo contra ellos mismos. Bien puede ser que
malinterpreté los estándares en cuyo caso ellos no serán
interoperables con los estándares respectivos.

La rutinas "find*()" pueden parecer un poco raras a primera vista.
Sirven principalmente para hacer echo de la cancelación.  Una manera
razonablemente rápida para hacerlo es coger la pieza más energética de
la muestra de la salida, localizarla en la muestra de la entrada y
substraer la muestra de la salida completa de la muestra de entrada:

   def echocancel(outputdata, inputdata):
       pos = audioop.findmax(outputdata, 800)    # one tenth second
       out_test = outputdata[pos*2:]
       in_test = inputdata[pos*2:]
       ipos, factor = audioop.findfit(in_test, out_test)
       # Optional (for better cancellation):
       # factor = audioop.findfactor(in_test[ipos*2:ipos*2+len(out_test)],
       #              out_test)
       prefill = '\0'*(pos+ipos)*2
       postfill = '\0'*(len(inputdata)-len(prefill)-len(outputdata))
       outputdata = prefill + audioop.mul(outputdata, 2, -factor) + postfill
       return audioop.add(inputdata, outputdata, 2)
