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.