14.1 audioop -- Manipula datos de audio en bruto

El audioop contiene operaciones útiles sobre fragmentos de sonido. Opera en fragmentos de sonido consistentes en muestras (enteros con signo) de 8, 16 ó 32 bits de tamaño, almacenadas en cadenas de Python. Es el mismo formato empleado por los módulos al y sunaudiodev. Todos los elementos escalares son enteros, a menos que se indique lo contrario.

Este módulo proporciona soporte para las codificaciones u-LAW e Intel/DVI ADPCM.

Algunas (pocas) de las operaciones más complejas emplean muestras de 16 bit, el resto emplean muestras cuyo tamaño es siempre un parámetro de la operación.

El módulo define las siguientes variables y funciones:

error
Esta excepción se lanza en todos los errores, por ejemplo, ante un número desconocido de bytes por muestra, etc.

add (fragment1, fragment2, width)
Devuelve un fragmento compuesto por la suma de las dos muestras pasadas como parámetros. La variable width es la amplitud de la muestra en bytes, ya sea 1, 2 o 4. Los dos fragmentos han de tener la misma longitud.

adpcm2lin (adpcmfragment, width, state)
Descodifica un fragmento codificado con Intel/DVI ADPCM en otro fragmento lineal. Véase la descripción de la función lin2adpcm() para obtener detalles sobre la codificación ADPCM. Devuelve una tupla (sample, newstate) donde la muestra tiene la amplitud especificada en width.

adpcm32lin (adpcmfragment, width, state)
Descodifica un código alternativo ADPCM de 3 bits. Véase la función lin2adpcm3() para más detalles.

avg (fragment, width)
Devuelve la media de todas las muestras del fragmento.

avgpp (fragment, width)
Devuelve la distancia media entre picos de todas las muestras del fragmento. No se emplea filtro alguno, por lo que la utilidad de esta rutina es cuestionable.

bias (fragment, width, bias)
Devuelve el fragmento original con un desplazamiento añadido a cada muestra.

cross (fragment, width)
Devuelve el número de cruces por cero del fragmento pasado como argumento.

findfactor (fragment, reference)
Devuelve un factor F que minimiza rms(add(fragment, mul(reference, -F))); por ejemplo, devuelve el factor por el que debería multiplicarse reference para que concuerde lo mejor posible con fragment. Ambos fragmentos deben contener muestras de 2 bytes.

El tiempo empleado por esta rutina es proporcional a len(fragment).

findfit (fragment, reference)
Intenta encajar reference a una sección de fragment (que ha de ser el fragmento más largo). Hacer esto supone (conceptualmente) partir fragment en trozos, emplear la función findfactor() para calcular la mejor concordancia, y minimizar el resultado. Los fragmentos deben contener muestras de 2 bytes. Devuelve una tupla (offset, factor) en la que offset es el desplazamiento (entero) dentro de fragment donde comienza la concordancia óptima y factor es el factor (coma flotante) descrito en findfactor().

findmax (fragment, length)
Busca un fragmento en fragment cuyo tamaño tenga length muestras (no bytes) con la máxima potencia; por ejemplo, devuelve i donde rms(fragment[i*2:(i+length)*2]) es máximo. Ambos fragmentos deben contener muestras de 2 bytes.

El tiempo empleado por esta rutina es proporcional a len(fragment).

getsample (fragment, width, index)
Devuelve el valor de la muestra index del fragmento.

lin2lin (fragment, width, newwidth)
Convierte muestras entre formatos de 1, 2 y 4 bytes.

lin2adpcm (fragment, width, state)
Convierte muestras al formato de codificación Intel/DVI ADPCM de 4 bit. La codificación ADPCM es un esquema de codificación adaptable, en el que cada número de 4 bits es la diferencia entre una muestra y la siguiente, dividido por un paso variable. Se ha seleccionado el algoritmo Intel/DVI ADPCM para el IMA, así que puede llegar a convertirse en un estándar.

La variable state es una tupla que contiene el estado del codificador. El codificador devuelve una tupla (adpcmfrag, newstate), que newstate debe pasarse a la siguiente llamada de lin2adpcm(). En la llamada inicial, se puede pasar None como estado. adpcmfrag es el fragmento codificado con ADPCM empaquetado con 2 valores de 4 bits por byte.

lin2adpcm3 (fragment, width, state)
Éste es un codificador ADPCM alternativo que usa sólo 3 bits por muestra. No es compatible con el codificador Intel/DVI ADPCM y su salida no está empaquetada (debido a la pereza del autor). Su uso no se recomienda.

lin2ulaw (fragment, width)
Convierte muestras del fragmento de audio a la codificación u-LAW y lo devuelve como una cadena de Python. u-LAW es un formato de codificación de audio en el que se obtiene un rango dinámico de alrededor de 14 bits usando sólo muestras de 8 bits. Lo emplean los dispositivos de audio de Sun, entre otros.

minmax (fragment, width)
Devuelve una tupla que consiste en los valores mínimo y máximo de todas las muestras del fragmento de sonido.

max (fragment, width)
Devuelve el mayor valor absoluto de todas las muestras en un fragmento.

maxpp (fragment, width)
Devuelve el valor máximo entre picos del fragmento de sonido.

mul (fragment, width, factor)
Devuelve un fragmento que tiene todas las muestras del fragmento original multiplicadas por el valor en coma flotante de factor. El desbordamiento se ignora de forma silenciosa.

ratecv (fragment, width, nchannels, inrate, outrate, state[, weightA[, weightB]])
Convierte la frecuencia de muestreo del fragmento de entrada. state es una tupla que contiene el estado del conversor. El conversor devuelve una tupla (newfragment, newstate); se debe pasar newstate a la siguiente llamda de la función ratecv().

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

reverse (fragment, width)
Invierte las muestras de un fragmento y devuelve el fragmento modificado.

rms (fragment, width)
Devuelve la raíz cuadrada de la media del fragmento, por ejemplo:


Es una medida de la potencia de una señal de audio.

tomono (fragment, width, lfactor, rfactor)
Convierte un fragmento estéreo en uno mono. El canal izquierdo se multiplica por lfactor y el canal derecho por rfactor antes de sumar los dos canales para entregar una señal mono.

tostereo (fragment, width, lfactor, rfactor)
Genera un fragmento estéreo de uno mono. Cada par de muestras Cada par de muestras en el fragmento estéreo proviene de la muestra mono, donde las muestras del canal izquierdo se multiplican por lfactor y las del canal derecho por rfactor.

ulaw2lin (fragment, width)
Convierte los fragmentos codificados en u-LAW a fragmentos de sonido codificados linealmente. La codificación u-LAW siempre usa muestras de 8 bits, por lo que width se refiere sólo a la amplitud de la muestra del fragmento de salida.

Nótese que operaciones tales como mul() o max() no distinguen entre fragmentos mono y estéreo, todas las muestras se tratan igual. Si esto es un inconveniente, el fragmento estéreo se debe dividir previamente en dos fragmentos mono y combinarlos después. Un ejemplo:

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

Si se usa el codificador ADPCM para crear paquetes de red y se quiere que el protocolo sea independiente del estado (por ejemplo, que pueda tolerar la pérdida de paquetes) es necesario transmitir, además de los datos, el estado. Nótese que se debe enviar el estado initial (el que se pasó a lin2adpcm()) al descodificador, no el estado final (que devuelve el codificador). Si se quiere usar la función struct.struct() para almacenar el estado en formato binario se puede codificar el primer elemento (el valor previsto) con 16 bits y el segundo (el índice delta) con 8.

Los codificadores ADPCM nunca han sido verificados contra otros (des)codificadores ADPCM, sólo contra sí mismos. Puede haber ocurrido que hayamos malinterpretado los estándares, en cuyo caso no serán compatibles con los respectivos estándares.

Las rutinas find*() pueden parecer chocantes al principio. Se han previsto principalmente para cancelar el eco. Una forma rápida de hacerlo es elegir la pieza más potente de la muestra de salida, localizarla en la muestra de entrada y restar el total de la muestra de salida de la muestra de entrada:

def echocancel(outputdata, inputdata):
    pos = audioop.findmax(outputdata, 800)    # una décima de segundo
    out_test = outputdata[pos*2:]
    in_test = inputdata[pos*2:]
    ipos, factor = audioop.findfit(in_test, out_test)
    # Opcional (mejora la cancelación):
    # 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)

Ver Sobre este documento... para obtener información sobre sugerencias.