2011-11-03 15 views
6

Estoy tratando de codificar datos pcm sin procesar como uLaw para ahorrar en el ancho de banda requerido para transmitir datos de voz.Android PCM a Ulaw codificación de archivo wav

Me he encontrado con una clase llamada UlawEncoderInputStream en This page pero no hay documentación! :(

El constructor toma un flujo de entrada y un valor máximo PCM (sea lo que sea).

/** 
    * Create an InputStream which takes 16 bit pcm data and produces ulaw data. 
    * @param in InputStream containing 16 bit pcm data. 
    * @param max pcm value corresponding to maximum ulaw value. 
    */ 
    public UlawEncoderInputStream(InputStream in, int max) { 

Después de mirar a través del código, sospecho que yo debería calcular este valor "max" utilizando un suministrado función: maxAbsPcm. ¡El problema es que realmente no entiendo lo que debo pasar! Estoy grabando mi pcm en bruto en un archivo en la tarjeta sd, así que no tengo una matriz de datos residente en memoria continua para pasar a este

/** 
    * Compute the maximum of the absolute value of the pcm samples. 
    * The return value can be used to set ulaw encoder scaling. 
    * @param pcmBuf array containing 16 bit pcm data. 
    * @param offset offset of start of 16 bit pcm data. 
    * @param length number of pcm samples (not number of input bytes) 
    * @return maximum abs of pcm data values 
    */ 
    public static int maxAbsPcm(byte[] pcmBuf, int offset, int length) { 

Otro problema que tengo al usar este código es que no estoy seguro de qué valores escribir para el encabezado de los datos de ley. ¿Cómo puedo determinar la cantidad de datos de bytes que hay después de la codificación con uLaw?

He escuchado uno de los archivos codificados (potencialmente) uLaw que he creado en el reproductor multimedia VLC (el único jugador que tengo que intentará leer el archivo) y sus sonidos son desagradables, rotos y clics, pero aún pueden la voz.

Estoy escribiendo mi encabezado de onda usando un código similar a una clase que encontré llamada WaveHeader que se puede encontrar Here!

Si alguien tiene alguna idea sobre este asunto estaría muy agradecidos a escucharlos! :)

Muchas gracias Dexter

+0

Si está creando un archivo .wav. Almacene el archivo de encabezado de onda al principio y cámbielo al final de su grabación. Normalmente, no sabrá el tamaño (cantidad de registros) hasta que llegue al final. Su máximo debe ser 0x7f de todos modos. –

Respuesta

4

El max en el constructor es la máxima amplitud en los datos PCM. Se usa para escalar la entrada antes de generar la salida. Si la entrada es muy fuerte, necesita un valor más alto; si es silencioso, necesita uno más bajo. Si pasa en 0, el codificador usará 8192 de manera predeterminada, lo que puede ser suficiente.

El length en el otro método es el número de muestras de 16 bits de las que desea encontrar la amplitud máxima. Esta clase asume que los datos PCM de entrada siempre están codificados con muestras de 16 bits, lo que significa que cada muestra abarca dos bytes: si su entrada es de 2000 bytes de longitud, tiene 1000 muestras.

El codificador de esta clase produce una muestra μ-Law de 8 bits para cada muestra PCM de 16 bits, por lo que el tamaño en bytes se reduce a la mitad.

+0

Muchas gracias Joni –

0

Esto es lo contrario de lo que estás tratando de hacer, pero pensé que podría ser útil para alguien. Aquí hay un método de ejemplo que convertirá un archivo binario codificado en uLaw de 8 bits en un archivo WAV de 16 bits utilizando los métodos integrados de Java.

public static void convertULawFileToWav(String filename) { 
    File file = new File(filename); 
    if (!file.exists()) 
     return; 
    try { 
     long fileSize = file.length(); 
     int frameSize = 160; 
     long numFrames = fileSize/frameSize; 
     AudioFormat audioFormat = new AudioFormat(Encoding.ULAW, 8000, 8, 1, frameSize, 50, true); 
     AudioInputStream audioInputStream = new AudioInputStream(new FileInputStream(file), audioFormat, numFrames); 
     AudioSystem.write(audioInputStream, Type.WAVE, new File("C:\\file.wav")); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 
Cuestiones relacionadas