AudioRecord类中的read方法问题

abc*_*abc 6 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.有什么问题?帮我.提前致谢.

Jes*_*don 14

更新: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()位置找到的native :

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()必须等待音频缓冲区被填充才能返回之前回调 - 所以重点是什么.

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

  • 嗨戈登,我正在开发一个必须知道硬件音频延迟的VoIP应用程序.问题是AudioRecord.read()是一种阻塞方法,所以我现在唯一能做的就是读取完整缓冲区以使其每次都被阻塞,并将延迟设置为阻塞时间.即假设AudioRecord.getMinBufSize()= 2048 Bytes,SampleRate = 16000Hz,channel = MONO,所以我每次都读取1024个样本,并假设它每次会阻塞1024/16 = 64ms,有时它可以工作,从56~65ms,但有时它阻止高达200多毫秒,这些136毫秒音频在哪里?怎么做得好?问候. (2认同)
  • 嗨BillHoo,我发现Android中的录音功能有问题.我不断深入挖掘源代码 - 首先是java,然后是底层的C++ - 直到我在我的脑海中.看起来回调不能按照他们应该的方式工作,并且Android开发者网站上已经有一两年已经存在漏洞,我有点放弃了.显然,阻止io现在已不合时宜了,从源代码中可以清楚地看出,作者希望我们能够编写非阻塞回调驱动的音频录制,但是它们没有用,而且它不起作用,除非 (2认同)

Ebo*_*ike 8

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

AudioRecord是一个连续的流,"不再有数据可用"的情况永远不会适用.