AudioRecord的read()方法返回的字节数并不与sizeInBytes参数中请求的字节数相同。

huangapple go评论114阅读模式
英文:

AudioRecord read() does not return same amount of bytes as requested in sizeInBytes

问题

以下是翻译好的部分:

我在我的应用中添加了语音录制功能,并已经在生产环境中运行了几个月。从错误日志中,我发现有时AudioRecord中的read()方法返回的字节数与sizeInBytes参数中指定的不同。

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

以下是帮助更好理解的代码片段:

val audioRecordData = ByteArray(bufferSize)
val length = audioRecord.read(audioRecordData, 0, audioRecordData.size)
if (length == AudioRecord.ERROR_BAD_VALUE || length == AudioRecord.ERROR_INVALID_OPERATION || length != audioRecordData.size) {
    // 由于音频录制遇到致命异常,因此退出
    throw RuntimeException()
}

问题:即使audioRecord.read()返回的字节数不等于sizeInBytes,是否安全继续调用read()

英文:

I have built voice recording feature in my app and have launched it in production for few months. From error logs, I have found that sometimes, the read() method in AudioRecord will return different number of bytes than indicated in sizeInBytes argument.

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

Below is the code snippet to help understand better.

val audioRecordData = ByteArray(bufferSize)
val length = audioRecord.read(audioRecordData, 0, audioRecordData.size)
if (length == AudioRecord.ERROR_BAD_VALUE || length == AudioRecord.ERROR_INVALID_OPERATION || length != audioRecordData.size) {
    // Quitting because Audio record encountered fatal exception
    throw RuntimeException()
}

Question: Is it safe to continue calling read() even though the number of bytes returned by audioRecord.read() is not equal to the sizeInBytes?

答案1

得分: 1

是的。继续是安全的。

该方法的javadoc如下:

> 返回值:读取的字节数为零或正数,或以下错误代码之一。字节数不会超过 sizeInBytes
>
> ERROR_INVALID_OPERATION 如果对象未正确初始化
>
> ERROR_BAD_VALUE 如果参数不能解析为有效数据和索引
>
> ERROR_DEAD_OBJECT 如果对象不再有效,需要重新创建。如果成功传输了一些数据,则不会返回死对象错误代码。在这种情况下,错误将在下一个read()返回。
>
> ERROR 其他错误情况下

在您的示例中,我可以想到两种情况,结果将大于零但小于 audioRecordData.size

  1. 您接近音频文件的末尾,没有足够的未读字节来填充您提供的缓冲区。

  2. 您正在从设备或远程源以“实时”方式读取音频流... 并且read正提供了当前可用的所有音频字节。

基本上,当 read 返回比您请求的字节少时,您的应用程序需要采取适当的操作。

值得一提的是,ERROR* 值都小于零,因此结果的正确解释是:

  • result < 0 - 根据错误代码表示的错误
  • result == 0 - 流结束
  • result > 0 - 成功读取... 结果值是读入提供的数组或 ByteBuffer 的字节数(或 shorts)数。
英文:

Yes. It is safe to continue.

The javadoc for that method says:

> Returns: zero or the positive number of bytes that were read, or one of the following error codes. The number of bytes will not exceed sizeInBytes.
>
> ERROR_INVALID_OPERATION if the object isn't properly initialized
>
> ERROR_BAD_VALUE if the parameters don't resolve to valid data and indexes
>
> ERROR_DEAD_OBJECT if the object is not valid anymore and needs to be recreated. The dead object error code is not returned if some data was successfully transferred. In this case, the error is returned at the next read()
>
> ERROR in case of other error

In your example, I can think of two scenarios where the result will be greater than zero and less than audioRecordData.size.

  1. You are close to the end of an audio file, and there aren't enough unread bytes left to fill the buffer you provided.

  2. You are reading an audio stream from a device or a remote source in "real time" ... and the read is delivering all of the audio bytes available right now.

Basically, your application needs to act appropriately when read returns fewer bytes than you asked for.

For what it is worth, the ERROR* values are all less than zero, so the correct interpretation of the result is:

  • result < 0 - an error as indicated by the error code
  • result == 0 - end of stream
  • result > 0 - a successful read ... and the result value is the number of bytes (or shorts) read into the supplied array or ByteBuffer.

huangapple
  • 本文由 发表于 2023年8月9日 18:43:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76866990.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定