2016-09-28 3 views
0

AudioTrack.write(). Документация для Android гласит, чтоAndroid AudioTrack.write() возвращается после воспроизведения всего буфера

В режиме потоковой записи запись будет обычно блокироваться до тех пор, пока все данные не будут выставлены в очередь для воспроизведения, и вернет полный счетчик передачи.

Однако в моем коде метод write(), кажется, ждет, пока весь буфер не будет воспроизводиться до тех пор, пока из громкоговорителя не будет. Поэтому, например, вызов метода stop() впоследствии или заполнение большего количества данных невозможно.

AudioTrack инициализируется:

int mBufferSize = AudioTrack.getMinBufferSize(44100, 
     AudioFormat.CHANNEL_OUT_MONO, 
     AudioFormat.ENCODING_PCM_8BIT); 
AudioTrack mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, 44100, 
     AudioFormat.CHANNEL_OUT_MONO, AudioFormat.ENCODING_PCM_16BIT, 
     mBufferSize, AudioTrack.MODE_STREAM); 
int duration = 44100*5; 
short[] mBuffer = new short[duration]; 

В OnCreate:

for (int i = 0; i < wavelength; i++) { 
     waveform[i] = Math.sin(((double) i)/wavelength * 2 * Math.PI - Math.PI); 
} 
mAudioTrack.play(); 

На нажатие кнопки, это называется:

private void playSound(double frequency, int duration) { 
    int idx = 0; 
    for (int i = 0; i < duration-1; i++) { 
     idx = idx + (int) Math.ceil(frequency); 
     if (idx > wavelength-1) 
      idx = idx % wavelength; 
     mBuffer[i] = (short) (waveform[idx] * Short.MAX_VALUE); 
    } 
    long startTime = System.currentTimeMillis(); 
    ret = mAudioTrack.write(mBuffer, 0, mBuffer.length); 
    long runtime = System.currentTimeMillis() - startTime; 
    debugText.setText(Long.toString(runtime)); 
} 

Отметка показывает, что запись () занимает ровно 5 секунд, это длина аудиоклипа, и я не думаю, что время передачи будет b e точно так же. Я хочу генерировать больше данных для воспроизведения (возможно, с другой частотой), пока предыдущие данные все еще воспроизводятся. Я знаю, что некоторые разработчики используют несколько потоков (и у меня нет опыта в потоковом оборудовании, поэтому я не знаю, как это сделать), но документация указывает, что это будет возможно и таким образом ...

+0

Какова ценность mBufferSize? – JustATrick

+0

Отладчик говорит, что это 1764. Я действительно не знаю точно, что делает этот размер буфера. Я пытался сделать его больше, но он разбился. – Anton

+0

1764 байт достаточно для всего 20 мс моно, 16 бит, 44,1 кГц аудио. Понимание этого буфера является ключом к пониманию вашей проблемы. Не знаю, как произошла авария, может быть, это другая проблема? (PS Я предполагаю, что AudioFormat.ENCODING_PCM_8BIT в вызове getMinBufferSize является опечаткой) – JustATrick

ответ

1

Звонок AudioTrack.write(...) блокирует, пока все предоставленные данные не будут скопированы в потоковый буфер AudioTrack. Размер буфера AudioTrack (mBufferSize выше) установлен в AudioTrack.getMinBufferSize(...), и, следовательно, он явно мал, конечно, достаточно лишь на долю секунды аудио.

5 секунд аудиоданных, которые вы хотите ввести в очередь, очевидно, не помещается в такой небольшой буфер. Таким образом, AudioTrack.write(...) должен повторно заполнять этот буфер, когда он сливается при воспроизведении. Прежде чем он сможет вернуться, он должен вставить в очередь последнюю часть ваших аудиоданных. И прежде чем он сможет это сделать, он должен ждать, по крайней мере, до тех пор, пока не будут воспроизведены все, кроме последних mBufferSize аудиоданных.

Если вы увеличиваете mBufferSize различными суммами, вы должны начать просмотр блокировки вызовов за меньшее время.

Смежные вопросы