Проблемы с воспроизведением в Android AudioTrack MODE_STATIC - PullRequest
6 голосов
/ 18 мая 2011

У меня проблема с AudioTrack, этот Android API убивает меня. У меня нет опыта работы с Android или Java, но я очень опытный программист (asm, C ++ и т. Д. На многих платформах), и я никогда не думал, что я настолько глуп, как будто Android, безусловно, заставляет меня чувствовать себя сейчас.

Что я делаю не так? Видимо ничего:

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();

На самом деле sampleRate = 8000 и minbufsizbytes = 742, что (742 * 64 = 47488) значительно больше, чем Буфер, который я пишу (16000 16-битных семплов).

Звук воспроизводится очень хорошо с первого раза. Но ... как мне играть в нее не раз? (например, в ответ на событие, например нажатие клавиши пианино). Если я снова вызову play (), новый звук не будет воспроизводиться. Итак, после нескольких дней разочарования, вот что я придумал:

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();
}

Так что он воспроизводит звук второй раз ИЛИ (!) В третий раз ... тогда НЕТ АУДИО! И журнал заполняется этим сообщением об ошибке:

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

Затем я должен перезагрузить телефон (эмулированный или реальный), иначе флуд не прекращается ..

(mis) ведет себя на моем Galaxy 2.2.1, на моем IDEOS 2.1 и на эмуляторе (различные версии) ... так что это не проблема с телефоном.

Если я увеличу внутренний буфер (5-й параметр в AudioTrack), он будет проигрываться больше раз, прежде чем перестанет издавать звуки и начнет заполнять журнал, поэтому я думаю, что это похоже на переполнение внутреннего буфера

P.S .: Знаете ли вы, если getMinBufferSize возвращает сэмплы или байты (даже для PCM_16BIT), как некоторые сообщали?

1 Ответ

5 голосов
/ 20 ноября 2011

Вот пример кода, который запускался несколько раз !!'super' - это 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;
    }

}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...