问题
In my Android app, I'm using the AudioTrack API to output audio bytes that I receive from a RFCOMM Bluetooth connection. The audio plays as expected and is very clear. However, the app occasionally crashes due to the following assertion in AudioTrackShared.cpp:
stepCount <= mUnreleased && mUnreleased <= mFrameCount
I'm not really sure of what this assertion entails, but does anyone have an idea of what could cause this issue? I can provide additional source code if needed:
My setup for AudioTrack:
int minSize = AudioTrack.getMinBufferSize(8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT);
mAudioPlayer = new AudioTrack(AudioManager.STREAM_MUSIC, 8000, AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_8BIT, minSize * 4, AudioTrack.MODE_STREAM);
回答1:
Make AudioTrack buffer size the same you get from minBufferSize. That could fix your issue.
回答2:
Hidden Bug
The error is not directly related to the audioBuffer size vs. minBufferSize. Assuming that these two must be identical is an API misunderstanding, if not misuse. (†)
The reason behind this apparent fix is that having identical sizes ensures that the audioBuffer is copied in full during mAudioPlayer.write(audioBuffer, 0, audioBuffer.length), each time, every time.
The actual reason for the crash is that audioBuffer, when larger than minBufferSize, may not have been copied in full, then discarded before mAudioPlayer.write(audioBuffer, 0, audioBuffer.length) had a chance to complete.
Solutions
- Check
audioBufferallocations and deallocations - In a multi-threaded or async environment, ensure that
audioBufferhas been consumed in between allocations.
(†)
AudioTrackbuffer size >audioBuffersize:
you may have many small packets arriving irregularly and can take advantage of theAudioTrackbuffering system to compensate for these irregularitiesAudioTrackbuffer size ==audioBuffersize:
1 to 1 match ;mAudioPlayer.writeis pretty much guaranteed to have copiedaudioBufferexactly intoAudioTrackbuffer when returningAudioTrackbuffer size <audioBuffersize:
the track will iterate through theaudioBufferas needed ;audioBufferlife cycle better lasts long enough
In all cases, audioBuffer must remain allocated until consumed, and a new buffer presented to mAudioPlayer.write before it runs out of data to avoid gaps in playback.
来源:https://stackoverflow.com/questions/35999854/understanding-audiotrack-assertion-in-android