使用AmrInputStream将PCM-16转换为AMR

时间:2011-08-31 02:47:42

标签: android audio pcm amr

我正在使用AmrInputStream进行从PCM-16到AMR的转换。有关AmrInputStream的详细信息,请访问http://hi-android.info/src/android/media/AmrInputStream.java.html

在谈论使用JNI和其他内容时,我对编程很新,我不知道JNI是什么,我不认为这是讨论所必需的。上面的AmrInputStream显然也没有在SDK和NDK中找到,但我已经能够使用它了。

我一直在互联网上搜索如何使用该流,但没有找到任何示例。最后,我进行了实验,发现它与任何InputStream类似。这是一段代码片段

InputStream inStream;
    inStream = new FileInputStream("abc.wav");
    AmrInputStream aStream = new AmrInputStream(inStream);

    File file = new File("xyz.amr");        
    file.createNewFile();
    OutputStream out = new FileOutputStream(file); 

    byte[] x = new byte[1024];
    int len;
    while ((len=aStream.read(x)) > 0) {
        out.write(x,0,len);
    }

    out.close();

我已经测试了它并且它已经工作(需要将#!AMR \ n标签添加到输出文件中进行播放。)(编辑:AMR标签必须是#!AMR \ n)。

我的问题是,我只是设法将其用于以8000Hz采样的PCM-16文件。用于原始PCM-16文件的任何(更高)频率都会产生(欠采样)输出。 AmrInputStream.java文件中有一个SAMPLES_PER_FRAME变量,我尝试过该变量,但似乎没有任何影响。

欢迎任何建议或相关讨论!

1 个答案:

答案 0 :(得分:3)

SAMPLES_PER_FRAME是amrencoder一次性操作的数据块(映射到20毫秒的音频)。

来自amr编码器函数的签名(位于http://hi-android.info/src/android/media/AmrInputStream.java.html的底部)

private static native int GsmAmrEncoderNew();

private static native void GsmAmrEncoderInitialize(int gae);

private static native int GsmAmrEncoderEncode(int gae,
        byte[] pcm, int pcmOffset, byte[] amr, int amrOffset) throws IOException;

private static native void GsmAmrEncoderCleanup(int gae);

private static native void GsmAmrEncoderDelete(int gae);

似乎没有办法将samplerate传递给编码器。(gae是原生句柄) 采样速率硬编码至8k至少这个api