【问题标题】:Endianness on Android when using AudioRecord with 16-bit PCM and reading into a byte array使用带有 16 位 PCM 的 AudioRecord 并读入字节数组时,Android 上的字节序
【发布时间】:2020-11-05 21:20:57
【问题描述】:

我目前正在研究一个使用 AudioRecord 以 16 位 PCM 格式录制音频的 Android 应用程序:

byte [] buffer = new byte[1600];
audioRecord.read(buffer, 0, 1600);

它将录制的音频存储到bufferdocumentation of this read function 描述了此功能应该仅用于 8 位 PCM。然而,Android 应用程序将它与 16 位 PCM 一起使用(而且它似乎可以正常工作;另一个使用字节数组的 overloaded read variant 也提到通过这种方法使用 16 位 PCM 是可能的,但已弃用)。

现在我不确定每个样本(由 2 个字节组成)是以小端格式还是大端格式存储的。 documentation section about the audio encoding 表示使用 ByteBuffer 而不是字节数组会产生本机字节序(而不是大字节序)。

我怀疑短片是以大端格式存储的,但我找不到这方面的证据。

【问题讨论】:

    标签: android audio-recording


    【解决方案1】:

    我最近的项目也有同样的情况。

    方法

    public int read (byte[] audioData, 
                int offsetInBytes, 
                int sizeInBytes)
    

    实际调用

    public int read (byte[] audioData, 
                int offsetInBytes, 
                int sizeInBytes, 
                int readMode)
    

    使用 AudioRecord.READ_BLOCKING 作为第四个参数。由于不推荐使用 16 位 PCM,我认为使用这种方法仍然可以。只是不推荐。

    read方法最终调用native方法native_read_in_byte_array来填充音频缓冲区。 Android 原生是 little-endian,所以 native_read_in_byte_array 在 C/C++ 层以 little-endian 存储音频数据,然后通过 JNI 将音频数据发送回 Java 层。

    我做了一个快速测试,发现通过 JNI 的字节缓冲区不会改变它存储字节的顺序。

    基本上,您以与 C/C++ jbyteArray 中相同的顺序获取 Java byte[]。所以原生的short在Java层还是以little endian的形式存储的。

    这就是我可以从我的测试中得出的结论。希望对您有所帮助,如果其中有问题,请告诉我。

    【讨论】:

    • btw 检查 cs.android.com 的本地方法 native_read_in_byte_array
    猜你喜欢
    • 2023-03-15
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-05
    • 1970-01-01
    相关资源
    最近更新 更多