开发者

Android's AudioTrack MODE_STATIC replay issues

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 do开发者_Go百科esn'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;
    }

}

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜