AAudio ve MMAP

AAudio, Android 8.0 sürümünde kullanıma sunulan bir ses API'sidir. Android 8.1 sürümde bir HAL ile birlikte kullanıldığında gecikmeyi azaltacak geliştirmeler bulunmaktadır. sürücü ve MMAP'yi destekleyen bir sürücü. Bu dokümanda donanım soyutlaması açıklanmaktadır AAudio'nun MMAP özelliğinin desteklenmesi için gereken sürücü değişikliklerini ve Android

AAudio MMAP desteği için gerekenler:

  • HAL'nin MMAP özelliklerini raporlamak
  • HAL’ye yeni işlevlerin uygulanması
  • isteğe bağlı olarak ÖZEL mod arabelleği için özel bir ioctl() uygulama
  • ek bir donanım veri yolu sağlar
  • MMAP özelliğini etkinleştiren sistem özelliklerini ayarlama
ziyaret edin.

Aaudio mimarisi

Ses Open SL ES'ye alternatif sağlayan yeni bir yerel C API'dir. Bir Ses yayını oluşturmaya yönelik tasarım deseni.

AAudio, düşük gecikmeli bir veri yolu sağlar. ÖZEL modda, istemci uygulama kodunun doğrudan bellek eşlenmiş bir arabelleğe yazmasını sağlar bu dosya ALSA sürücüsüyle paylaşılır. SHARED modunda, MMAP arabelleği şu kullanıcı tarafından kullanılır: Ses Sunucusu'nda çalışan bir mikser. ÖZEL modda gecikme daha az olacaktır. Çünkü veriler mikseri atladığı için.

ÖZEL modda hizmet, HAL'den MMAP arabelleğini ister ve kaynaklar. MMAP arabelleği NOIRQ modunda çalıştığından paylaşılan öğe yok. arabelleğe erişimi yönetmek için okuma/yazma sayaçları sunar. Bunun yerine donanımın zamanlama modelini korur ve arabelleğin ne zaman okuyun.

Aşağıdaki diyagramda, nabız kodu modülasyonu (PCM) veri akışını kullanarak ALSA sürücüsüne taşıyabilir. Zaman damgaları düzenli aralıklarla AAudio hizmeti tarafından istenir ve ardından istemcinin zamanlama modeline geçirilir. atomik mesaj kuyruğu aracılığıyla çalışır.

PCM veri akışı diyagramı.
Şekil 1. FIFO'dan ALSA'ya PCM veri akışı
'nı inceleyin.

SHARED modunda, bir zamanlama modeli de kullanılır ancak bu model AAudioService içinde barındırılır.

Ses yakalama için benzer bir model kullanılır, ancak PCM verileri ters yönde.

HAL değişiklikleri

tinyALSA için bkz.:

external/tinyalsa/include/tinyalsa/asoundlib.h
external/tinyalsa/include/tinyalsa/pcm.c
int pcm_start(struct pcm *pcm);
int pcm_stop(struct pcm *pcm);
int pcm_mmap_begin(struct pcm *pcm, void **areas,
           unsigned int *offset,
           unsigned int *frames);
int pcm_get_poll_fd(struct pcm *pcm);
int pcm_mmap_commit(struct pcm *pcm, unsigned int offset,
           unsigned int frames);
int pcm_mmap_get_hw_ptr(struct pcm* pcm, unsigned int *hw_ptr,
           struct timespec *tstamp);

Eski HAL için:

hardware/libhardware/include/hardware/audio.h
hardware/qcom/audio/hal/audio_hw.c
int start(const struct audio_stream_out* stream);
int stop(const struct audio_stream_out* stream);
int create_mmap_buffer(const struct audio_stream_out *stream,
                        int32_t min_size_frames,
                        struct audio_mmap_buffer_info *info);
int get_mmap_position(const struct audio_stream_out *stream,
                        struct audio_mmap_position *position);

HIDL ses HAL için:

hardware/interfaces/audio/2.0/IStream.hal
hardware/interfaces/audio/2.0/types.hal
hardware/interfaces/audio/2.0/default/Stream.h
start() generates (Result retval);
stop() generates (Result retval) ;
createMmapBuffer(int32_t minSizeFrames)
       generates (Result retval, MmapBufferInfo info);
getMmapPosition()
       generates (Result retval, MmapPosition position);

MMAP desteğini bildirme

"aaudio.mmap_policy" sistem özelliği 2 (AAUDIO_POLICY_O) olarak ayarlanmalıdır, böylece ses çerçevesi, MMAP modunun ses HAL'si tarafından desteklendiğini bilir. (bkz. "AAudio MMAP Veri Yolunu Etkinleştirme" below.)

audio_policy_configuration.xml dosyası ayrıca bir çıkış ve giriş içermelidir MMAP/NO IRQ moduna özel bir profille MMAP istemcileri oluşturulduğunda hangi akışın açılacağını:

<mixPort name="mmap_no_irq_out" role="source"
            flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_MMAP_NOIRQ">
            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                                samplingRates="48000"
                                channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
</mixPort>

<mixPort name="mmap_no_irq_in" role="sink" flags="AUDIO_INPUT_FLAG_MMAP_NOIRQ">
            <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                                samplingRates="48000"
                                channelMasks="AUDIO_CHANNEL_IN_STEREO"/>
</mixPort>

Bir MMAP akışını açma ve kapatma

createMmapBuffer(int32_t minSizeFrames)
            generates (Result retval, MmapBufferInfo info);

MMAP akışı, Tinyalsa işlevleri çağırılarak açılıp kapatılabilir.

Sorgu MMAP konumu

Zamanlama Modeline geri gönderilen zaman damgası, bir kare konumu ve bir Nanosaniye cinsinden MONOTONİK zaman:

getMmapPosition()
        generates (Result retval, MmapPosition position);

HAL, bu bilgileri ALSA sürücüsünden, yeni bir Tinyalsa işlevi:

int pcm_mmap_get_hw_ptr(struct pcm* pcm,
                        unsigned int *hw_ptr,
                        struct timespec *tstamp);

Paylaşılan bellek için dosya tanımlayıcıları

AAudio MMAP veri yolu, donanım ve ses hizmeti. Paylaşılan belleğe bir dosya açıklayıcı kullanılarak başvuruda bulunuluyor ALSA sürücüsü tarafından oluşturulan bir dosya oluşturulur.

Çekirdek değişiklikleri

Dosya tanımlayıcı, /dev/snd/ sürücü dosyasını kaydederse AAudio hizmeti tarafından SHARED modu. Ancak tanımlayıcı, ÖZEL mod. /dev/snd/ dosyası açıklayıcısı da sağlar erişim kapsamını genişletmez. Dolayısıyla SELinux tarafından engellenir.

ÖZEL modunu desteklemek için, Bir anon_inode:dmabuf dosyası için /dev/snd/ tanımlayıcısı açıklayıcıdır. SELinux, bu dosya tanımlayıcısının istemciye aktarılmasına izin verir. Google AAudioService tarafından da kullanılabilir.

anon_inode:dmabuf dosyası tanımlayıcısı, Android Ion bellek kitaplığı.

Daha fazla bilgi için şu harici kaynakları inceleyin:

  1. "Android ION bellek ayırıcı" https://lwn.net/Articles/480055/
  2. "Android ION'a genel bakış" https://wiki.linaro.org/BenjaminGaignard/ion
  3. "ION bellek ayırıcısını entegre etme" https://lwn.net/Articles/565469/

HAL değişiklikleri

AAudio hizmeti, bu anon_inode:dmabuf cihazının şu olup olmadığını bilmesi gerekir: desteklenir. Android 10.0'dan önce bunu yapmanın tek yolu MMAP'nin boyutunu iletmekti. negatif bir sayı olarak tampon, ör. Destekleniyorsa 2048 yerine -2048. Android 10.0 ve sonraki sürümlerde AUDIO_MMAP_APPLICATION_SHAREABLE işaretini ayarlayabilirsiniz.

mmapBufferInfo |= AUDIO_MMAP_APPLICATION_SHAREABLE;

Ses alt sistem değişiklikleri

AAudio, ses parçasının ses kullanıcı arabiriminde ek bir veri yolu gerektirir orijinal AudioFlinger yoluyla paralel çalışabilmesi için bir alt sistemdir. Bu eski yol, diğer tüm sistem sesleri ve uygulama sesleri için kullanılır. Bu işlev, TTP'deki bir yazılım mikseriyle veya bir donanımla sağlanabilir. fonksiyonlarının lansmanını yapıyor.

AAudio MMAP veri yolunu etkinleştir

MMAP desteklenmiyorsa veya AAudio, eski AudioFlinger veri yolunu kullanır bir akışı açamıyor. AAudio uyumlu olmayan bir ses sistemiyle çalışır. MMAP/NOIRQ yolunu destekler.

AAudio için MMAP desteğini test ederken aslında MMAP veri yolunu veya yalnızca eski veri yolunu test etmektir. İlgili içeriği oluşturmak için kullanılan Aşağıda, belirli veri yollarının nasıl etkinleştirileceği veya zorunlu kılınacağı ve bir akışın kullandığı yoldur.

Sistem özellikleri

MMAP politikasını sistem özellikleri aracılığıyla ayarlayabilirsiniz:

  • 1 = AAUDIO_POLICY_NEVER - Yalnızca eski yolu kullan. MMAP'yi kullanmayı bile denemeyin.
  • 2 = AAUDIO_POLICY_OT - MMAP kullanmayı deneyin. Bu yöntem başarısız olursa veya kullanılamıyorsa ardından eski yolu kullanın.
  • 3 = AAUDIO_POLICY_ALWAYS - Yalnızca MMAP yolunu kullan. Eskiye dönme yol'a dokunun.

Bunlar, cihazların Makefile'ında şu şekilde ayarlanabilir:

# Enable AAudio MMAP/NOIRQ data path.
# 2 is AAUDIO_POLICY_AUTO so it will try MMAP then fallback to Legacy path.
PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_policy=2
# Allow EXCLUSIVE then fall back to SHARED.
PRODUCT_PROPERTY_OVERRIDES += aaudio.mmap_exclusive_policy=2

Bu değerleri cihaz başlatıldıktan sonra da geçersiz kılabilirsiniz. Değişikliğin geçerli olması için ses sunucusunu yeniden başlatmanız gerekir. Örneğin, MMAP için OTO modunu etkinleştirmek üzere:

adb root
adb shell setprop aaudio.mmap_policy 2
adb shell killall audioserver

Şurada sağlanan işlevler: Şunları yapmanıza olanak tanıyan ndk/sysroot/usr/include/aaudio/AAudioTesting.h: MMAP yolunu kullanmaya ilişkin politikayı geçersiz kıl:

aaudio_result_t AAudio_setMMapPolicy(aaudio_policy_t policy);

Bir akışın MMAP yolu kullanıp kullanmadığını öğrenmek için şu çağrıyı yapın:

bool AAudioStream_isMMapUsed(AAudioStream* stream);