转换音频格式

时间:2012-05-09 11:30:01

标签: java audio javasound

我在转换WAV文件的音频格式方面遇到了麻烦。

我正在录制麦克风的声音,声音按以下格式录制: PCM_SIGNED 44100.0 Hz,16位,单声道,2字节/帧

我想将上述格式转换为 ULAW 8000.0 Hz,8位,单声道,1字节/帧

我使用以下代码,

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

我收到以下错误,

java.lang.IllegalArgumentException:不支持的转换:ULAW 8000.0 Hz,8位,单声道,1个字节/帧,来自PCM_SIGNED 44100.0 Hz,16位,单声道,2个字节/帧,little-endian

有人可以帮我解决这个问题!!!

非常感谢!!!

2 个答案:

答案 0 :(得分:3)

您是否看过documentation

  

<强>抛出:   IllegalArgumentException - 如果不支持转换#see #getTargetEncodings(AudioFormat)

并非每个系统都会安装足够的编解码器来转换为您要求的特定格式。您已经认为自己有,但它会抛出异常,因为它无法转换为该格式。

您可以使用getTargetEncodings以编程方式检查给定格式的适用性,而不依赖于异常,然后如果您希望输出格式不可用,则可以采取适当的操作(例如,退回到另一个一,向用户提供这是不可能的反馈等。)。

答案 1 :(得分:0)

这门课可能对你有帮助。我发现它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;
  }
}