Android PCM到Ulaw编码wav文件

时间:2011-11-03 10:42:47

标签: java android encoding pcm

我正在尝试将原始pcm数据编码为uLaw,以节省传输语音数据所需的带宽。

我在This page遇到了一个名为 UlawEncoderInputStream 的类,但没有文档! :(

构造函数接受输入流和max pcm值(无论是什么)。

  /**
     * 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) {

查看代码后,我怀疑我应该使用提供的函数计算这个“最大”值: maxAbsPcm 。问题是,我真的不明白我的意思是要传递给它!我正在将原始pcm录制到SD卡上的文件中,因此我没有一个连续的内存驻留数据集来传递给它。

  /**
     * 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) {

我使用此代码的另一个问题是我不确定要为uLaw数据的标头写出什么值。如何使用uLaw进行编码后确定字节数据少了多少?

我听过我在VLC媒体播放器中创建的(潜在的)uLaw编码文件之一(我唯一会尝试读取该文件的播放器),它的声音令人讨厌,破碎和点击但仍然可以看出来声音。

我正在使用类似于我发现的名为WaveHeader的类来编写我的wave标题,可以找到它Here

如果有人对此事有任何想法,我将非常感激听到他们!:)

非常感谢 德克斯特

2 个答案:

答案 0 :(得分:4)

构造函数中的max是PCM数据中的最大幅度。它用于在生成输出之前缩放输入。如果输入非常响亮,则需要更高的值,如果安静,则需要更低的值。如果您传入0,编码器默认会使用8192,这可能已经足够了。

另一种方法中的length是要从中找到最大幅度的16位样本数。此类假定输入PCM数据始终使用16位样本进行编码,这意味着每个样本跨越两个字节:如果输入为2000字节长,则有1000个样本。

此类编码器为每个16位PCM采样生成一个8位μ-Law样本,因此字节大小减半。

答案 1 :(得分:0)

这与你想要做的事情相反,但我认为这对某人有帮助。这是一个简单的方法,它将使用内置的Java方法将8位uLaw编码的二进制文件转换为16位WAV文件。

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();
    }
}