2014-01-17 3 views
2

Я создаю приложение, которое будет генерировать звук (на данный момент это в основном экспериментальный) и воспроизводить его на телефоне Android.Воспроизведение генеративного звука с помощью OpenSL

На данный момент я пытаюсь воспроизвести простой синусоидальный звук (440 Гц) и сначала попытался с помощью Audiotrack, но испытал некоторый перебор буфера. Поэтому я решил взглянуть на OpenSL.

Теперь я прочитал много учебников и сообщений в блоге об этом и, наконец, сделал свою собственную реализацию, используя OpenSL-модуль с простой буфером для Android.

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

Мой вопрос: что такое лучшая практика/архитектура для генерируемых звуков в OpenSL? Должен ли я заполнять буфер в альтернативном потоке (тогда нужен какой-то процесс синхронизации с обратным вызовом буфера)?

Я еще не нашел учебники по OpenSL ES для сгенерированных звуков (большинство из них воспроизводят аудиофайлы или перенаправляют аудио вход на аудиовыход).

+0

_ «Задержка намного хуже, чем звуковая дорожка (я слышу пробелы между буферами)» _. Звучит для меня так, как будто вы описываете переполнение буфера (буферы помещаются в очередь, не заполняя их полностью). Если вы не останавливаете и не перезапускаете свой игровой объект между каждым буфером, между буферами не должно быть задержек; только начальный при первом запуске объекта игрока. Что касается вашего вопроса; Я просто использую обратный вызов очереди буфера для размещения очередного буфера, но мне пришлось попробовать разные размеры буфера, прежде чем я нашел тот, который работал. – Michael

ответ

3

Что касается задержки: важно выбрать правильную частоту дискретизации и размер буфера для вашего устройства. Вы можете запросить устройство для рекомендуемых значений с использованием AudioManager в Android SDK (в PROPERTY_OUTPUT_SAMPLE_RATE и PROPERTY_OUTPUT_FRAMES_PER_BUFFER доступны только от уровня 17 API) и передавать значения на приложения НДК:

// getting the samplerate and buffer size 
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) 
{ 
    AudioManager am = (AudioManager) aContext.getSystemService(Context.AUDIO_SERVICE); 
    int sampleRate = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_SAMPLE_RATE)); 
    int bufferSize = Integer.parseInt(am.getProperty(AudioManager.PROPERTY_OUTPUT_FRAMES_PER_BUFFER)); 
} 

Важность получения частоты дискретизации правильно, если он отличается от предпочтительной частоты дискретизации устройств (некоторые используют 48 кГц, другие 44,1 кГц), звук прокладывается мимо системного повторного сэмплера до того, как он будет выводиться аппаратным обеспечением, добавив к общей задержке. Кроме того, важность получения правильного размера буфера заключается в том, чтобы исключить выборки/кадры после нескольких обратных вызовов буфера, что может привести к проблеме, которую вы описываете, где возникают пробелы/сбои между обратными вызовами. Вы можете использовать multiples (мощность 2) для уменьшения/увеличения размера буфера для экспериментов с более стабильным движком (более высокий размер буфера) и более быстрого ответа (более низкий размер буфера).

Создав несколько простых приложений для Android, выполняющих именно это, я написал небольшую рецензию, объясняющую приведенную выше рекомендацию, чуть более подробно, а также то, как можно было бы создать базовый механизм последовательности для музыкальных приложений, однако страница просто базовая схема архитектуры и может оказаться совершенно бесполезной в зависимости от ваших потребностей>Android audio engine in OpenSL

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

  • Нет связанных вопросов^_^