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

81 Views Asked by At

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

There are 1 best solutions below

0
Stephen C On

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.