Java 音频格式转换

Java 音频格式转换,java,audio,javasound,Java,Audio,Javasound,我在转换WAV文件的音频格式时遇到问题 我正在用麦克风录音,录音格式如下: PCM_签名44100.0 Hz,16位,单声道,2字节/帧 我想把上面的格式转换成, ULAW 8000.0 Hz,8位,单声道,1字节/帧 我正在使用以下代码 InputStream is = request.getInputStream(); AudioInputStream ais = AudioSystem.getAudioInputStream(is); Au

我在转换WAV文件的音频格式时遇到问题

我正在用麦克风录音,录音格式如下: PCM_签名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_签名的44100.0 Hz,16位,单声道,2字节/帧,小端

有人能帮我解决这个问题吗


非常感谢

你看了这张照片了吗

抛出: IllegalArgumentException-如果不支持转换,请参阅getTargetEncodings(AudioFormat)

并不是每个系统都会安装足够的编解码器来转换为您要求的特定格式。您假设您的是,但它抛出异常,因为它无法转换为该格式


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

此类可能会对您有所帮助。我发现它:

package uk.co.mmscuting.sound;
导入java.io.*;
公共类CompressInputStream扩展FilterInputStream{
/*
将单PCM字节流转换为A律u律字节流
静态AudioFormat alawformat=新的AudioFormat(AudioFormat.Encoding.ALAW,8000,8,1,18000,false);
静态AudioFormat ulawformat=新的AudioFormat(AudioFormat.Encoding.ULAW,8000,8,1,18000,false);
PCM 8000.0 Hz,16位,单声道,有符号,小端
静态音频格式pcmformat=新的音频格式(8000,16,1,真、假);
*/
静态专用压缩机alawcompressor=新的alawcompressor();
静态专用压缩机ulawcompressor=新ulawcompressor();
专用压缩机=空;
公共压缩InputStream(InputStream in,boolean useALaw)引发IOException{
超级(in),;
压缩机=(使用ALAW)?ALAW压缩机:ULAW压缩机;
}
public int read()引发IOException{
抛出新IOException(getClass().getName()+“.read():\n\t不支持简单读取()。”;
}
公共整数读取(字节[]b)引发IOException{
返回读取(b,0,b.长度);
}
公共整数读取(字节[]b,整数关闭,整数长度)引发IOException{
int i,样本;
字节[]inb;
inb=新字节[len cClip){sample=cClip;}
如果(样本>=256){
指数=ALawCompressTable[(样本>>8)&0x007F];
尾数=(样本>>(指数+3))&0x0F;
压缩字节=0x007F&(指数>4);
}
压缩字节^=(符号^0x55);
返回压缩字节;
}
}
类uLawCompressor扩展了压缩机{
静态最终int cClip=32635;
静态最终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
};
受保护的整数压缩(短样本){
整数符号;
整数指数;
整数尾数;
int压缩字节;
符号=(样本>>8)&0x80;
如果(符号!=0){sample*=-1;}
如果(sample>cClip){sample=cClip;}
样本+=cBias;
指数=uLawCompressTable[(样本>>7)&0x00FF];
尾数=(样本>>(指数+3))&0x0F;

compressedByte=~(sign |)(exponent Hey Andrzej!感谢您的回复。我已经部分阅读了文档。我使用getTargetEncodings()方法的方式如下(int i=0;iPCM_SIGNED 1-->PCM_UNSIGNED 2-->ALAW 3-->ULAW,对此您有何看法?谢谢!!我猜,由于我得到了上述输出,我的系统有编解码器可以转换为ULAW格式。出现异常的其他原因是什么?知道吗?它可能不支持转换的其他方面,例如采样率或者比特数。我不完全了解这一点,但你“下采样”的事实对我来说是一个标志。(从44100到8000)。这通常很棘手,因为频率在4000到22050 Hz之间的数据信息会产生别名,除非您将其从数据中过滤掉。因此,我猜这不是一个标准支持的转换。但我打赌,根据您的输出,您可以转换为44100 Hz的ULAW。(我的最佳猜测。)这有什么作用?它能帮我解决以下错误吗?
行格式PCM\u签名44100.0 Hz,16位,mono,2字节/帧,不支持little-endian
我没有使用它,但它声称将“mono-PCM字节流转换为A-Law u-Law字节流。”这看起来像是您正在尝试做的。Java中似乎不直接支持此转换,您必须自己进行压缩(就像这个类一样)。结果表明,我的错误是因为我无法使用已在使用的数据行(因此错误是误导性的)。使用Beads sound library解决了我的所有问题().这可能没有回答OP,但这对我相关的事情很有用。
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;
  }
}