2012-05-09 12 views
5

Tengo problemas para convertir el formato de audio de un archivo WAV.Conversión de formato de audio

estoy grabando sonido desde el micrófono y se registra el sonido en el siguiente formato: PCM_SIGNED 44100,0 Hz, 16 bits, mono, 2 bytes/marco

Quiero convertir el formato anterior a, ULAW 8000.0 Hz, 8 bits, mono, 1 bytes/marco

estoy usando el siguiente código,

InputStream is = request.getInputStream(); 
      AudioInputStream ais = AudioSystem.getAudioInputStream(is); 
      AudioFormat oldFormat = ais.getFormat(); 
      AudioFormat newFormat = new AudioFormat(AudioFormat.Encoding.ULAW, 8000, 8, 1, 1, 8000, false) ; 
AudioInputStream lowResAIS = AudioSystem.getAudioInputStream(newFormat, ais); //Getting the below Exception on this line 

Y yo estoy recibiendo el siguiente error,

java.lang.IllegalArgumentException: conversión Unsupported: ULAW 8000,0 Hz, 8 bits, mono, 1 bytes/marco, desde PCM_SIGNED 44100,0 Hz, 16 bits, mono, 2 bytes/trama, poco-endian

Puede alguien ¡ayúdame a resolver este problema!

Gracias a ton !!!

Respuesta

3

¿Echaste un vistazo al documentation?

Lanza: IllegalArgumentException - si la conversión no es compatible #getTargetEncodings #see (AudioFormat)

No todos los sistemas se han instalado los codecs suficientes para transformar al formato específico con lo solicitado para. Ha asumido que el suyo sí lo hace, pero arroja la excepción porque no puede transformarse a ese formato.

Puede consultar getTargetEncodings para verificar la idoneidad de un formato dado programáticamente, sin depender de una excepción, y luego puede tomar las medidas apropiadas si el formato de salida deseado no está disponible (por ejemplo, volver a otro, presentar al usuario con comentarios de que esto es imposible, etc.).

+0

Hey Andrzej! Gracias por la respuesta. He revisado parcialmente la documentación. Utilicé el método getTargetEncodings() de la siguiente manera 'code' Encoding [] encArr = AudioSystem.getTargetEncodings (oldFormat); \t \t \t \t for (int i = 0; i " + encArr [i]); \t \t \t \t} 'code' y me dieron el siguiente resultado: 0 -> PCM_SIGNED 1 -> PCM_UNSIGNED 2 -> ALAW 3 -> ULAW, ¿Qué tiene que decir acerca de esto? ¡¡Gracias!! –

+0

Como obtengo el resultado anterior, mi sistema tiene los códecs para transformar a un formato ULAW, supongo. ¿Cuál podría ser la otra razón para la excepción? ¿Alguna idea? –

+1

Es posible que no sea compatible con algún otro aspecto de la conversión, como la frecuencia de muestreo o el número de bits. No estoy totalmente al tanto de esto, pero el hecho de que seas "downsampling" levanta una bandera para mí. (pasando de 44100 a 8000).Eso suele ser difícil, ya que la información de datos con frecuencias entre 4000 y 22050 Hz será alias a menos que los filtren fuera de los datos. Así que supongo que no es una conversión compatible estándar. Pero apuesto a que podrías convertir a ULAW con 44100 Hz dada tu salida. (Mi mejor conjetura.) –

0

Esta clase puede ayudarlo. Lo encontré here:

package uk.co.mmscomputing.sound; 

import java.io.*; 

public class CompressInputStream extends FilterInputStream{ 

    /* 
    Convert mono PCM byte stream into A-Law u-Law byte stream 

    static AudioFormat alawformat= new AudioFormat(AudioFormat.Encoding.ALAW,8000,8,1,1,8000,false); 
    static AudioFormat ulawformat= new AudioFormat(AudioFormat.Encoding.ULAW,8000,8,1,1,8000,false); 

    PCM 8000.0 Hz, 16 bit, mono, SIGNED, little-endian 
    static AudioFormat pcmformat = new AudioFormat(8000,16,1,true,false); 

    */ 

    static private Compressor alawcompressor=new ALawCompressor(); 
    static private Compressor ulawcompressor=new uLawCompressor(); 

    private Compressor compressor=null; 

    public CompressInputStream(InputStream in, boolean useALaw)throws IOException{ 
    super(in); 
    compressor=(useALaw)?alawcompressor:ulawcompressor; 
    } 

    public int read()throws IOException{ 
    throw new IOException(getClass().getName()+".read() :\n\tDo not support simple read()."); 
    } 

    public int read(byte[] b)throws IOException{ 
    return read(b,0,b.length); 
    } 

    public int read(byte[] b, int off, int len)throws IOException{ 
    int  i,sample; 
    byte[] inb; 

    inb=new byte[len<<1];   // get 16bit PCM data 
    len=in.read(inb); 
    if(len==-1){return -1;}; 

    i=0; 
    while(i<len){ 
     sample = (inb[i++]&0x00FF); 
     sample |= (inb[i++]<<8); 
     b[off++]=(byte)compressor.compress((short)sample); 
    } 
    return len>>1; 
    } 
} 

abstract class Compressor{ 
    protected abstract int compress(short sample);  
} 

/* 
    Mathematical Tools in Signal Processing with C++ and Java Simulations 
     by Willi-Hans Steeb 
      International School for Scientific Computing 
*/ 

class ALawCompressor extends Compressor{ 

    static final int cClip = 32635; 

    static final int[] ALawCompressTable ={ 
    1,1,2,2,3,3,3,3, 
    4,4,4,4,4,4,4,4, 
    5,5,5,5,5,5,5,5, 
    5,5,5,5,5,5,5,5, 
    6,6,6,6,6,6,6,6, 
    6,6,6,6,6,6,6,6, 
    6,6,6,6,6,6,6,6, 
    6,6,6,6,6,6,6,6, 
    7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7 
    }; 

    protected int compress(short sample){ 
    int sign; 
    int exponent; 
    int mantissa; 
    int compressedByte; 

    sign = ((~sample) >> 8) & 0x80; 
    if(sign==0){ sample *= -1;} 
    if(sample > cClip){ sample = cClip; } 
    if(sample >= 256){ 
     exponent = ALawCompressTable[(sample >> 8) & 0x007F]; 
     mantissa = (sample >> (exponent + 3)) & 0x0F; 
     compressedByte = 0x007F & ((exponent << 4) | mantissa); 
    }else{ 
     compressedByte = 0x007F & (sample >> 4); 
    } 
    compressedByte ^= (sign^0x55); 
    return compressedByte; 
    } 
} 

class uLawCompressor extends Compressor{ 

    static final int cClip = 32635; 
    static final int cBias = 0x84; 

    int[] uLawCompressTable ={ 
    0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3, 
    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, 
    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 
    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 
    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 
    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 
    }; 

    protected int compress(short sample){ 
    int sign; 
    int exponent; 
    int mantissa; 
    int compressedByte; 

    sign = (sample >> 8) & 0x80; 
    if(sign!=0){ sample *= -1;} 
    if(sample > cClip){ sample = cClip; } 
    sample += cBias; 

    exponent = uLawCompressTable[(sample >> 7) & 0x00FF]; 
    mantissa = (sample >> (exponent + 3)) & 0x0F; 
    compressedByte = ~(sign | (exponent << 4) | mantissa); 
    return compressedByte&0x000000FF; 
    } 
} 
+0

¿Qué hace eso? ¿Me ayudará con el siguiente error? 'línea con formato PCM_SIGNED 44100.0 Hz, 16 bit, mono, 2 bytes/frame, little-endian no soportado' – trusktr

+0

No lo he usado, pero dice convertir" flujo de bytes PCM mono en A-Law u-Law stream de bytes " Eso se parece a lo que estás tratando de hacer. Parece que esta conversión no se admite directamente en Java, tiene que hacer su propia compresión (como hace esta clase). – 11101101b

+1

Resulta que mi error fue porque no pude usar una línea de datos que ya estaba siendo utilizada (por lo que el error es engañoso). Usar la biblioteca de sonidos de Beads resolvió todos mis problemas (http://beadsproject.net). – trusktr

Cuestiones relacionadas