AudioRecord类中的read方法问题

时间:2010-12-31 10:02:04

标签: android android-audiorecord

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

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

其参数是:   audioData记录的音频数据写入的数组。   audioIn中的offsetInBytes索引,从中写入数据以字节为单位表示。   sizeInBytes请求的字节数。

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

我在我的代码中编写了这个方法,如下所示: int num; byte [] buf = new byte [160]; num = record.read(buf,0,160);

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

2 个答案:

答案 0 :(得分:13)

更新: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%2Cint%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中的{{1}}(尽我所知),看起来在这个函数中有一个do / while循环基本上阻塞,直到读取了所需的字节数(或缓冲区大小的一半,以较小者为准)。

我试图让回调运行得很好但是它们似乎只在read()必须等待音频缓冲区被填充才能返回之前回调 - 所以重点是什么。

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

答案 1 :(得分:8)

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

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