I have an issue with AudioTrack, this Android API is killing me. I come from no previous Android or Java experience, but I'm a very experienced coder (asm, C++, etc.. on a lot of platforms) and I never thought I was particularly dumb, like Android is certainly making me feel now.
What am I doing wrong? Apparently nothing:
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, minbufsizbytes*64, AudioTrack.MODE_STATIC);
audioTrack.write(Buffer, 0, numSamples);
audioTrack.play();
Actually sampleRate=8000 and minbufsizbytes=742, which (742*64 = 47488) is considerably bigger than the Buffer I'm writing (16000 16bit samples).
The audio plays just fine the first time. But... how do I play it more than once? (e.g. in response to an event, like e.g. a piano key pressed). If I invoke play() again, no new sound will be produced. So after days of frustration, here's what I came up:
for (i=0;;i++) {
SystemClock.sleep(3000L); // so the problem is NOT "fast, repeated attempts to replay sound", but looks like internal buffer overrun related (please see the Log'ed error below)
audioTrack.stop();
audioTrack.reloadStaticData();
audioTrack.setPlaybackHeadPosition(0);
audioTrack.play();
}
So it plays the sound a second OR(!) third time.. then NO AUDIO!! And the Log gets flooded by this error message:
05-18 13:03:16.785: ERROR/AudioFlinger(345): TrackBase::getBuffer buffer out of range:
05-18 13:03:16.785: ERROR/AudioFlinger(345): start: 0x404fb680, end 0x404fb7f2 , mBuffer 0x40507000 mBufferEnd 0x40512980
05-18 13:03:16.785: ERROR/AudioFlinger(345): server 0, serverBase 23744, user 47488, userBase 47488, channels 1
I then must reboot the phone (emulated or real) else the Log flood doesn't stop..
(mis)Behaves on my Galaxy 2.2.1, on my IDEOS 2.1 and on the emulator (various versions).. so it's not a phone bug issue.
If I make the internal buffer bigger (5th parameter in AudioTrack), it will play more times before it stops emitting sounds and starts flooding the Log, so I think it's like if an internal buffer was overran
P.S.: do you know if getMinBufferSize returns samples or bytes (even for PCM_16BIT), as some have reported?
Here is a sample of code that had run several times!! 'super' is an AudioTrack
public void play(){
switch (super.getPlayState()) {
case AudioTrack.PLAYSTATE_PAUSED:
super.stop();
super.reloadStaticData();
super.play();
break;
case AudioTrack.PLAYSTATE_PLAYING:
super.stop();
super.reloadStaticData();
super.play();
break;
case AudioTrack.PLAYSTATE_STOPPED:
super.reloadStaticData();
super.play();
break;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With