安卓PCM转为Ulaw编码的wav文件

6
我试图将原始的PCM数据编码为μ律来节省传输语音数据所需的带宽。
我发现了一个叫做 UlawEncoderInputStream 的类,可以在这个页面上找到,但没有文档!:(
构造函数接受输入流和最大的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来计算这个“max”值。问题是,我真的不明白我应该传递什么!我正在将原始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) {

我使用这段代码时遇到的另一个问题是,我不确定如何为μ律数据的标头写出哪些值。我该如何确定编码后的μ律数据减少了多少字节?
我用VLC媒体播放器(我唯一能尝试读取文件的播放器)听了我创建的(可能)μ律编码文件之一,它听起来很难听,断断续续并有杂音,但仍然能听出声音。
我正在使用类似于名为WaveHeader的类的代码编写我的波形标头,可以在这里找到!
如果有人对此有任何想法,我将非常感激听取他们的意见! :)
谢谢 Dexter

如果你正在创建一个.wav文件,请在开始时存储波形头文件,在录制结束时将其改回。通常情况下,您不会知道大小(记录数)直到到达结尾。您的最大值应该是0x7f。 - Ernest Laurentin
2个回答

4
构造函数中的max是PCM数据中的最大振幅。它用于在生成输出之前对输入进行缩放。如果输入很响亮,则需要较高的值,如果很安静,则需要较低的值。如果传入0,编码器将默认使用8192,这可能已经足够好了。
另一个方法中的length是您想要查找最大幅度的16位样本数。该类假定输入PCM数据始终以16位样本编码,这意味着每个样本跨越两个字节:如果您的输入长度为2000字节,则有1000个样本。
此类中的编码器为每个16位PCM样本产生一个8位µ-Law样本,因此字节大小减半。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接