У меня проблема с 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), как некоторые сообщали?