4

我正在使用 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 变量,我尝试过使用它,但它似乎没有任何影响。

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

4

1 回答 1

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

似乎没有办法将采样率传递给编码器。(gae 是本机句柄)使用此 api 至少将采样率硬编码为 8k

于 2011-08-31T09:17:09.673 回答