7

公共 int 读取 (byte[] audioData, int offsetInBytes, int sizeInBytes)。

此方法从音频硬件读取音频数据以记录到缓冲区中。

它的参数是: audioData 写入录制的音频数据的数组。写入数据的 audioData 中的 offsetInBytes 索引,以字节表示。sizeInBytes 请求的字节数。

如果对象未正确初始化,则返回已读取的字节数或 ERROR_INVALID_OPERATION,如果参数未解析为有效数据和索引,则返回 ERROR_BAD_VALUE。字节数不会超过 sizeInBytes。

我在我的代码中这样写了这个方法: int num; 字节[] buf = 新字节[160];num = record.read(buf, 0, 160);

问题是即使数据不可用,它也总是返回不小于 160 的 160(即要读取的请求字节)。有什么问题?帮我。提前致谢。

4

2 回答 2

15

更新:Android 中的这个错误在 4.2.2 和 5.01 之前的某个地方得到了修复。在 5.01 中,回调的工作方式与文档中所说的完全一样。

read由于开发人员的一些短视,它看起来正在阻塞。

基本上,当录音机被初始化时,它会分配一种环形缓冲区,当它被告知时.start(),它开始录制到该缓冲区。

然后当.read()被调用时,它最多读取缓冲区大小的一半(或请求的大小,以较小者为准)并返回。

如果它要读取 1000 个样本而只有 900 个可用,则必须再等待 100 个样本才能返回。但是,如果有超过 1000 个样本,它会立即读取这些样本,然后立即返回。

理想情况下,它们要么提供非阻塞读取,以便返回任何可用的内容,要么提供一种方法来了解完整读取的数据何时可用,以便可以执行非阻塞读取。

我不认为他们支持第一个。他们似乎试图通过使用设置周期回调方法来支持第二个,但到目前为止,我无法在正确的时间获得该回调来进行快速的非阻塞读取。

我已经克隆了本机 C++ 源代码的完整源代码(8.5G 字节),并且我试图通过所有层来跟踪该功能,以了解它应该如何工作。

非阻塞的技巧.read(0)是仅在准备好完整读取的样本时才读取。但是确定该条件何时为真是我尚未弄清楚的。

参考资料:这是 .read() 的 java 代码,它调用原生 C++ 函数:

http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.3.4_r1/android/media/AudioRecord.java#AudioRecord.read%28java.nio.ByteBuffer% 2美分%29

上面的 read() 方法调用位于以下位置的本机native_read_in_direct_buffer()

http://pdroid.googlecode.com/svn/android-2.3.4_r1/trunk/frameworks/base/core/jni/android_media_AudioRecord.cpp

哪个调用或指向android_media_AudioRecord_readInByteArray()哪个依次调用AudioRecord.read()frameworks/base/media/libmedia/frameworks/base/media/libmedia/AudioRecord.cpp据我所知),看起来在这个函数中有一个 do/while 循环,它基本上阻塞,直到读取所需的字节数(或缓冲区大小的一半,以较小者为准。)

我试图让回调正常运行,但它们似乎只在 read() 必须等待音频缓冲区被填充才能返回时才回调——所以有什么意义。

我的下一个目标是尝试追踪通知回调源代码,这样我就可以准确猜测应该做什么以及何时执行。

于 2013-04-03T07:07:44.427 回答
8

read是一种阻塞方法。只有在读取了您告诉它读取的字节数,或者流已关闭,或者流指示没有更多可用数据(例如,在读取文件时)时,它才会返回。

AudioRecord 是一个连续流,“没有更多可用数据”的情况从不适用。

于 2011-01-01T05:09:36.680 回答