I'm reading stereo audio data on Android from a USB-connected device using AAudio. Opening a stream (calling AAudioStreamBuilder_openStream) is taking 10-15 seconds. Can I reduce this?
I have adapted sample AAudio code to successfully record audio from the device. However, the startup time when opening a recording stream to the device takes 15 seconds on my Samsung S9 and 10 seconds on my Samsung S8. Since a user could open the app and immediately try to record, this is too long.
StreamBuilder AudioEngine::makeStreamBuilder()
{
AAudioStreamBuilder *builder = nullptr;
aaudio_result_t result = AAudio_createStreamBuilder(&builder);
if (result != AAUDIO_OK) {
__android_log_print(ANDROID_LOG_ERROR, __func__, "Failed to create stream builder %s (%d)",
AAudio_convertResultToText(result), result);
return StreamBuilder(nullptr, &AAudioStreamBuilder_delete);
}
return StreamBuilder(builder, &AAudioStreamBuilder_delete);
}
void AudioEngine::openRecordingDevice( int deviceId )
{
StreamBuilder recordingBuilder = makeStreamBuilder();
AAudioStreamBuilder_setDeviceId(recordingBuilder.get(), deviceId );
AAudioStreamBuilder_setDirection(recordingBuilder.get(), AAUDIO_DIRECTION_INPUT);
AAudioStreamBuilder_setPerformanceMode(recordingBuilder.get(), AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
AAudioStreamBuilder_setSharingMode(recordingBuilder.get(), AAUDIO_SHARING_MODE_EXCLUSIVE);
//AAudioStreamBuilder_setSharingMode(recordingBuilder.get(), AAUDIO_SHARING_MODE_SHARED);
AAudioStreamBuilder_setFormat(recordingBuilder.get(), AAUDIO_FORMAT_PCM_FLOAT);
AAudioStreamBuilder_setSampleRate(recordingBuilder.get(), 48000);
AAudioStreamBuilder_setChannelCount(recordingBuilder.get(), kChannelCountStereo);
AAudioStreamBuilder_setDataCallback(recordingBuilder.get(), ::recordingDataCallback, this);
AAudioStreamBuilder_setErrorCallback(recordingBuilder.get(), ::errorCallback, this);
struct timeval before, after, diff;
gettimeofday(&before, NULL);
result = AAudioStreamBuilder_openStream(recordingBuilder.get(), &mRecordingStream);
gettimeofday(&after, NULL);
timeval_subtract( &diff, &after, &before );
__android_log_print(ANDROID_LOG_DEBUG, "M2MAudioEngine", "open record stream took %ld", diff.tv_sec);
...
}
(BTW, the sample rate of 48000 is appropriate for this device.)
The timing code confirms how long I wait for the logcat output to continue.
On the S8 I see the following output:
2019-05-29 10:40:27.982 24011-24011/com.example.myapp D/AAudio: AudioStreamBuilder(): mmapPolicy = 1, mapExclusivePolicy = 1
2019-05-29 10:40:27.982 24011-24011/com.example.myapp W/AAudio: AudioStreamBuilder(): EXCLUSIVE sharing mode not supported. Use SHARED.
2019-05-29 10:40:27.982 24011-24011/com.example.myapp I/AAudio: AudioStream::open() rate = 48000, channels = 2, format = 2, sharing = 1, dir = INPUT
2019-05-29 10:40:27.982 24011-24011/com.example.myapp I/AAudio: AudioStream::open() device = 11, perfMode = 12, callbackFrames = 0
2019-05-29 10:40:27.982 24011-24011/com.example.myapp D/AAudio: AudioStreamRecord::open(), request notificationFrames = 0, frameCount = 0
2019-05-29 10:40:33.299 24011-24011/com.example.myapp W/AudioRecord: AUDIO_INPUT_FLAG_FAST denied by server; frameCount 0 -> 2880
2019-05-29 10:40:38.603 24011-24011/com.example.myapp W/AAudio: AudioStreamRecord::open() flags changed from 0x00000005 to 0x00000000
2019-05-29 10:40:38.603 24011-24011/com.example.myapp W/AAudio: AudioStreamRecord::open() perfMode changed from 12 to 10
2019-05-29 10:40:38.605 24011-24011/com.example.myapp D/AAudio: AAudioStreamBuilder_openStream() returns 0 = AAUDIO_OK for (0x73f1b2a480) ----
------------
2019-05-29 10:40:38.605 24011-24011/com.example.myapp D/M2MAudioEngine: open record stream took 10
On the S9 (which takes about 5s longer), there's additional output in the middle:
2019-05-15 10:58:49.714 1728-1728/com.example.myapp I/AAudioStream: open() rate = 48000, channels = 2, format = 2, sharing = EX, dir = INPUT
2019-05-15 10:58:49.714 1728-1728/com.example.myapp I/AAudioStream: open() device = 11, sessionId = 0, perfMode = 12, callback: ON with frames = 0
2019-05-15 10:58:49.714 1728-1728/com.example.myapp I/AAudioStream: open() usage = 1, contentType = 2, inputPreset = 6
2019-05-15 10:59:00.333 1728-1728/com.example.myapp E/AAudio: BpAAudioService::client OPEN_STREAM passed stream -889
2019-05-15 10:59:00.333 1728-1728/com.example.myapp E/AudioStreamInternal_Client: open - openStream() returned -889
2019-05-15 10:59:00.333 1728-1728/com.example.myapp D/AAudioStream: destroying 0x73bec83600, state = AAUDIO_STREAM_STATE_UNINITIALIZED
2019-05-15 10:59:00.334 1728-1728/com.example.myapp I/AAudioStream: open() rate = 48000, channels = 2, format = 2, sharing = EX, dir = INPUT
2019-05-15 10:59:00.334 1728-1728/com.example.myapp I/AAudioStream: open() device = 11, sessionId = 0, perfMode = 12, callback: ON with frames = 0
2019-05-15 10:59:00.334 1728-1728/com.example.myapp I/AAudioStream: open() usage = 1, contentType = 2, inputPreset = 6
2019-05-15 10:59:05.661 1728-1728/com.example.myapp I/AudioRecord: AUDIO_INPUT_FLAG_FAST successful; frameCount 0 -> 4096
2019-05-15 10:59:05.662 1728-1728/com.example.myapp D/AudioStreamRecord: open() setup I16>FLOAT conversion buffer with 240 frames
2019-05-15 10:59:05.662 1728-1728/com.example.myapp W/AudioStreamRecord: open() flags changed from 0x00000005 to 0x00000001
2019-05-15 10:59:05.663 1728-1728/com.example.myapp D/AAudio: AAudioStreamBuilder_openStream() returns 0 = AAUDIO_OK for (0x73b671fc80) ----------------
2019-05-15 10:59:05.663 1728-1728/com.example.myapp D/M2MAudioEngine: open record stream took 15
I understand from this issue with Oboe (which wraps AAudio) https://github.com/google/oboe/issues/155 that there is an attempt to open the device as 'MMAP' (memory-mapped) which times out. I don't know why this is happening on the S9 and not the S8. I'm using exactly the same external device.
My questions are: can I reduce the stream opening latency overall? How can I prevent the additional MMAP latency (which I know to be inapplicable)?
User contributions licensed under CC BY-SA 3.0