Android uzantıları

Android için OpenSL ES, referans OpenSL ES spesifikasyonunun kapsamını Android ile uyumlu hale getirmek ve Android platformunun gücünden ve esnekliğinden yararlanmak için genişletmiştir.

Android uzantıları için API'nin tanımı OpenSLES_Android.h içinde ve içerdiği başlık dosyalarında yer alır. Bu uzantılar hakkında ayrıntılı bilgi için OpenSLES_Android.h adresini ziyaret edin. Bu dosya, yükleme kök dizininizin altında, sysroot/usr/include/SLES dizininde bulunur. Aksi belirtilmedikçe tüm arayüzler açıktır.

Bu uzantılar, Android'e özel oldukları için uygulamanızın diğer OpenSL ES uygulamalarıyla taşınabilirliğini sınırlar. Uzantıları kullanmaktan kaçınarak veya derleme sırasında hariç tutmak için #ifdef kullanarak bu sorunu azaltabilirsiniz.

Aşağıdaki tabloda, Android OpenSL ES'nin her nesne türü için desteklediği Android'e özel arayüzler ve veri bulucular gösterilmektedir. Hücrelerdeki Yes (Evet) değerleri, her nesne türü için kullanılabilen arayüzleri ve veri bulucuları belirtir.

Öne Çıkarın Ses çalar Ses kaydedici Motor Çıkış karışımı
Android arabellek sırası Evet: Kaynak (kod çözme) Hayır Hayır Hayır
Android yapılandırması Evet Evet Hayır Hayır
Android efekti Evet Hayır Hayır Evet
Android efekt özellikleri Hayır Hayır Evet Hayır
Android efekti gönderme Evet Hayır Hayır Hayır
Android basit arabellek sırası Evet: Kaynak (oynatma) veya havuz (kod çözme) Evet Hayır Hayır
Android arabellek sırası veri bulucu Evet: Kaynak (kod çözme) Hayır Hayır Hayır
Android dosya tanımlayıcı veri bulucu Evet: Kaynak Hayır Hayır Hayır
Android basit arabellek sırası veri bulucu Evet: Kaynak (oynatma) veya havuz (kod çözme) Evet: Lavabo Hayır Hayır

Android yapılandırma arayüzü

Android yapılandırma arayüzü, nesneler için platforma özgü parametreleri ayarlamak amacıyla bir araç sunar. Bu arayüz, diğer OpenSL ES 1.0.1 arayüzlerinden farklıdır. Bu arayüz, karşılık gelen nesneyi örneklendirmeden önce uygulamanız tarafından kullanılabilir. Bu nedenle, nesneyi örneklendirmeden önce yapılandırabilirsiniz. /sysroot/usr/include/SLES konumunda bulunan OpenSLES_AndroidConfiguration.h üst bilgi dosyası, aşağıdaki kullanılabilir yapılandırma anahtarlarını ve değerlerini belgeler:

  • Ses çalarlar için yayın türü (varsayılan SL_ANDROID_STREAM_MEDIA).
  • Ses kaydediciler için profili kaydet (varsayılan değer: SL_ANDROID_RECORDING_PRESET_GENERIC).

Aşağıdaki kod snippet'inde, bir ses çalarda Android ses yayını türünün nasıl ayarlanacağına dair bir örnek gösterilmektedir:

// CreateAudioPlayer and specify SL_IID_ANDROIDCONFIGURATION
// in the required interface ID array. Do not realize player yet.
// ...
SLAndroidConfigurationItf playerConfig;
result = (*playerObject)->GetInterface(playerObject,
    SL_IID_ANDROIDCONFIGURATION, &playerConfig);
assert(SL_RESULT_SUCCESS == result);
SLint32 streamType = SL_ANDROID_STREAM_ALARM;
result = (*playerConfig)->SetConfiguration(playerConfig,
    SL_ANDROID_KEY_STREAM_TYPE, &streamType, sizeof(SLint32));
assert(SL_RESULT_SUCCESS == result);
// ...
// Now realize the player here.

Ses kaydedicinin hazır ayarını yapılandırmak için benzer bir kod kullanabilirsiniz:

// ... obtain the configuration interface as the first four lines above, then:
SLuint32 presetValue = SL_ANDROID_RECORDING_PRESET_VOICE_RECOGNITION;
result = (*playerConfig)->SetConfiguration(playerConfig,
    RECORDING_PRESET, &presetValue, sizeof(SLuint32));

Android efekt arayüzleri

Android'in efekt, efekt gönderme ve efekt yetenekleri arayüzleri, bir uygulamanın cihaza özel ses efektlerini sorgulaması ve kullanması için genel bir mekanizma sağlar. Cihaz üreticileri, sağladıkları cihaza özel mevcut ses efektlerini belgelemelidir.

Taşınabilir uygulamalar, ses efektleri için Android efekti uzantıları yerine OpenSL ES 1.0.1 API'larını kullanmalıdır.

Android dosya tanımlayıcı veri bulucu

Android dosya tanımlayıcı veri bulucu, bir ses çaların kaynağını okuma erişimi olan bir açık dosya tanımlayıcı olarak belirtmenize olanak tanır. Veri biçimi MIME olmalıdır.

Uygulama, APK'daki öğeleri dosya tanımlayıcı aracılığıyla okuduğundan bu uzantı özellikle yerel öğe yöneticisi ile birlikte yararlıdır.

Android basit arabellek sırası veri konum bulucusu ve arayüzü

OpenSL ES 1.0.1 referans spesifikasyonunda, arabellek sıraları yalnızca ses çalarlar için kullanılabilir ve PCM ve diğer veri biçimleriyle uyumludur. Android basit arabellek sırası veri bulucu ve arayüz özellikleri, iki istisna dışında referans spesifikasyonuyla aynıdır:

  • Android basit arabellek sıralarını ses kaydediciler ve ses çalarlarla kullanabilirsiniz.
  • Bu sıralarla yalnızca PCM veri biçimini kullanabilirsiniz.

Kayıt için uygulamanız boş arabellekleri kuyruğa almalıdır. Kayıtlı bir geri çağırma, sistemin arabelleğe veri yazmayı tamamladığına dair bildirim gönderdiğinde uygulama bu arabelleğe alabilir.

Oynatma da aynı şekilde çalışır. Ancak gelecekteki kaynak kodu uyumluluğu için uygulamaların OpenSL ES 1.0.1 arabellek sıraları yerine Android basit arabellek sıraları kullanmasını öneririz.

Arabellek sırası davranışı

Android uygulaması, oynatma SL_PLAYSTATE_STOPPED durumuna girdiğinde oynatma imlecinin oynatılan arabelleğin başına geri dönmesi için referans spesifikasyonuna ilişkin şartı içermez. Bu uygulama, söz konusu davranışa uygun olabilir veya oynatma imlecinin konumunu değiştirebilir. Sonuç olarak, uygulamanız iki davranışın da gerçekleştiğini varsayamaz. Bu nedenle, SL_PLAYSTATE_STOPPED'e geçiş yaptıktan sonra BufferQueue::Clear() yöntemini açıkça çağırmanız gerekir. Bu işlem, arabellek sırasını bilinen bir duruma ayarlar.

Benzer şekilde, arabellek sırası geri çağırma tetikleyicisinin SL_PLAYSTATE_STOPPED öğesine geçiş mi yoksa BufferQueue::Clear() yürütülmesi mi olacağını belirleyen bir spesifikasyon yoktur. Bu nedenle, ikisinden birine bağımlılık oluşturmamanızı öneririz. Bunun yerine uygulamanız her ikisini de işleyebilir.

Nesne oluşturulurken dinamik arayüzler

Kolaylık sağlaması açısından, OpenSL ES 1.0.1'in Android'de uygulanması, uygulamanızın bir nesneyi somutlaştırırken dinamik arayüzler belirtmesine izin verir. Bu, örneklendirmeden sonra bu arayüzleri eklemek için DynamicInterfaceManagement::AddInterface() kullanımına bir alternatiftir.

Uzantıları raporlama

Platformun Android uzantılarını destekleyip desteklemediğini sorgulamanın üç yöntemi vardır. Bu yöntemler şunlardır:

  • Engine::QueryNumSupportedExtensions()
  • Engine::QuerySupportedExtension()
  • Engine::IsExtensionSupported()

Bu yöntemlerden herhangi biri ANDROID_SDK_LEVEL_<API-level> değerini döndürür. Burada API-level, platform API düzeyidir (örneğin, ANDROID_SDK_LEVEL_23). API düzeyinin 9 veya daha yüksek olması, platformun uzantıları desteklediği anlamına gelir.

Sesin kodunu PCM'ye çözün

Bu bölümde, kodlanmış bir akışın kodunu hemen oynatmadan PCM'ye çözmek için desteği sonlandırılmış OpenSL ES 1.0.1 uzantısı açıklanmaktadır. Aşağıdaki tabloda, bu uzantının kullanımı ve alternatifleri hakkında öneriler verilmiştir.

API seviyesi Alternatifler
15 ve altı Uygun lisansa sahip açık kaynaklı bir codec
16 - 20 MediaCodec sınıfı veya uygun bir lisansa sahip açık kaynaklı bir codec
21 ve üzeri <media/NdkMedia*.h> başlık dosyalarında, MediaCodec sınıfında veya uygun lisansa sahip açık kaynaklı bir codec'te NDK MediaCodec

Not: Şu anda MediaCodec API'nin NDK sürümü için herhangi bir belge bulunmamaktadır. Ancak örnek için native-codec örnek koduna bakabilirsiniz.

Standart bir ses çalar, çıkış miksini veri havuzu olarak belirterek bir ses cihazına çalar. Android uzantısı, uygulama, veri kaynağını URI veya MIME veri biçimi kullanılarak açıklanan bir Android dosyası tanımlayıcı veri bulucu olarak belirttiyse ses çaların kod çözücü olarak çalışmasıyla farklıdır. Böyle bir durumda veri havuzu, PCM veri biçimini kullanan, Android'in basit bir arabellek sırası veri bulucusudur.

Bu özellik, esas olarak SoundPool sınıfının sağladığı işlevlere benzer şekilde, oyunların yeni bir oyun düzeyine geçiş yaparken ses öğelerini önceden yüklemesi için tasarlanmıştır.

Uygulama başlangıçta Android basit arabellek sırasında bir dizi boş arabelleği kuyruğa almalıdır. Sonrasında uygulama arabellekleri PCM verileriyle doldurur. Android basit arabellek sırası geri çağırma, her tampon doldurulduktan sonra tetiklenir. Geri çağırma işleyici, PCM verilerini işler, şu anda boş olan arabelleği yeniden sıraya koyar ve sonra geri döner. Uygulama, kodu çözülmüş arabelleklerin kaydını tutmaktan sorumludur. Geri çağırma parametresi listesi, veri içeren tamponu veya daha sonra sıraya alınması gereken arabelleği belirtmek için yeterli bilgi içermez.

Veri kaynağı, akışın sonunda bir SL_PLAYEVENT_HEADATEND etkinliği sunarak akış sonunu (EOS) dolaylı yoldan bildirir. Uygulama, aldığı tüm verilerin kodunu çözdükten sonra, Android basit arabellek sırası geri çağırmaya başka çağrı yapmaz.

Havuzun PCM veri biçimi genellikle örnek hızı, kanal sayısı ve bit derinliğine göre kodlanmış veri kaynağının biçimiyle eşleşir. Ancak farklı bir örnek hızı, kanal sayısı veya bit derinliği için kodu çözebilirsiniz. Gerçek PCM biçiminin algılanmasına yönelik temel hazırlık hakkında daha fazla bilgi için bkz. Meta veriler aracılığıyla kodu çözülmüş PCM verilerinin biçimini belirleme.

Android'in PCM kod çözme özelliği için OpenSL ES, duraklatma ve ilk sarmayı destekler; ses kontrolünü, efektleri, döngüyü veya oynatma hızını desteklemez.

Platform uygulamasına bağlı olarak, kod çözme işlemi boşta bırakılamayan kaynaklar gerektirebilir. Bu nedenle, yeterli sayıda boş PCM arabelleği sağlamanızı öneririz. Aksi takdirde kod çözücü çok yorulur. Örneğin uygulamanız, başka bir boş arabellek sıraya koymadan Android basit arabellek sırası geri çağırma işleminden geri dönüyorsa bu durum yaşanabilir. Kod çözücü açlığının sonucu tanımlanmamıştır ancak bu sonuç şunları içerebilir: kodu çözülmüş PCM verilerini bırakma, kod çözme işlemini duraklatma veya kod çözücüyü tamamen sonlandırma.

Not: Kodlanmış akışın kodunu PCM'de çözmek ancak hemen oynatmamak için Android 4.x (API düzeyi 16-20) üzerinde çalışan uygulamalarda MediaCodec sınıfını kullanmanızı öneririz. Android 5.0 (API düzeyi 21) veya sonraki sürümleri üzerinde çalışan yeni uygulamalar için NDK eşdeğeri olan <NdkMedia*.h> kullanılmasını öneririz. Bu üst bilgi dosyaları, yükleme kök dizininizin altındaki media/ dizininde bulunur.

ADTS AAC'den PCM'ye akışının kodunu çözme

Veri kaynağı, MIME veri biçimini kullanan bir Android arabellek sırası veri bulucusuysa ve veri havuzu, PCM veri biçimini kullanan Android basit arabellek sırası veri bulucusuysa ses çalar, akışlı kod çözücü görevi görür. MIME veri biçimini aşağıdaki gibi yapılandırın:

  • Kapsayıcı: SL_CONTAINERTYPE_RAW
  • MIME türü dizesi: SL_ANDROID_MIME_AACADTS

Bu özellik temel olarak AAC sesi ile anlaşma yapan ancak çalmadan önce özel ses işleme gerçekleştirmesi gereken medya akışı uygulamaları için tasarlanmıştır. Ses kodunu PCM'ye çözmesi gereken çoğu uygulama, Ses kodunu PCM'ye çözme'de açıklanan yöntemi kullanmalıdır. Bu yöntem daha basittir ve daha fazla ses biçimini işler. Burada açıklanan teknik, yalnızca şu koşulların her ikisinin de geçerli olması durumunda kullanılacak daha özel bir yaklaşımdır:

  • Sıkıştırılmış ses kaynağı, ADTS başlıklarında bulunan AAC karelerinin akışıdır.
  • Bu akışı uygulama yönetir. Veriler, tanımlayıcısı URI olan bir ağ kaynağında veya tanımlayıcısı dosya tanımlayıcı olan bir yerel dosyanın içinde yer almaz.

Uygulama başlangıçta Android arabellek sırasında bir dizi doldurulmuş arabelleği kuyruğa almalıdır. Her arabellek, bir veya daha fazla tamamlanmış ADTS AAC çerçevesi içerir. Her arabellek boşaltıldıktan sonra Android arabellek sırası geri çağırma etkinleşir. Geri çağırma işleyici, arabelleği yeniden doldurup yeniden sıraya koymalı ve ardından geri dönmelidir. Uygulamanın, kodlanmış arabellekleri takip etmesi gerekmez. Geri çağırma parametresi listesi, daha sonra sıraya alınması gereken arabelleği belirtmek için yeterli bilgi içerir. Yayının sonu, bir EOS öğesi sıraya konularak açıkça işaretlenir. EOS süresi sona erdikten sonra, sıraya daha fazla izin verilmez.

Kod çözücüde sorun yaşamamak için ADTS AAC arabelleklerini tam olarak sağladığınızdan emin olmanızı öneririz. Örneğin, uygulamanız başka bir tam arabellek sıraya koymadan Android arabellek sırası geri çağırma işleminden geri dönüyorsa bu durum yaşanabilir. Kod çözücü açlığının sonucu belirtilmemiştir.

Veri kaynağı hariç tüm açılardan, akış kodu çözme yöntemi Ses kodunu çözme yöntemi'nin tanımladığı yöntemle aynıdır.

Adlar benzer olsa da Android arabellek sırası, Android basit arabellek sırası ile aynı değildir. Akış kod çözücü her iki tür arabellek sırası kullanır: ADTS veri kaynağı için bir Android arabellek sırası ve PCM veri havuzu için Android basit arabellek sırası. Android basit arabellek sırası API'si hakkında daha fazla bilgi için Android basit arabellek sırası veri bulucu ve arayüzü konusuna bakın. Android arabellek sırası API'si hakkında daha fazla bilgi için yükleme kök dizininin altındaki docs/Additional_library_docs/openmaxal/ dizininde yer alan index.html dosyasına bakın.

Meta veriler aracılığıyla kodu çözülmüş PCM verilerinin biçimini belirleme

SLMetadataExtractionItf arayüzü, referans spesifikasyonunun bir parçasıdır. Bununla birlikte, kodu çözülmüş PCM verilerinin gerçek biçimini gösteren meta veri anahtarları Android'e özgüdür. Bu meta veri anahtarlarını OpenSLES_AndroidMetadata.h başlık dosyası tanımlar. Bu üst bilgi dosyası, yükleme kök dizininizin altında, /sysroot/usr/include/SLES dizininde bulunur.

Meta veri anahtarı dizinleri, Object::Realize() yönteminin yürütmesi bittikten hemen sonra kullanılabilir. Ancak, uygulama ilk kodlanmış verinin kodunu çözene kadar ilişkili değerler kullanılamaz. İyi bir uygulama, Object::Realize yöntemini çağırdıktan sonra ana iş parçacığındaki anahtar dizinleri sorgulamak ve ilk kez çağrırken Android basit arabellek sırası geri çağırma işleyicideki PCM biçimi meta veri değerlerini okumaktır. Bu arayüzle çalışmaya ilişkin örnekler için NDK paketindeki örnek koda bakın.

Meta veri anahtar adları sabittir ancak anahtar dizinler belgelenmez ve değişebilir. Bir uygulama, dizinlerin farklı yürütme çalıştırmalarında kalıcı olduğunu ve birden fazla nesne örneğinin aynı çalıştırmada dizinleri paylaştığını varsaymamalıdır.

Kayan nokta verileri

Android 5.0 (API düzeyi 21) ve sonraki sürümleri üzerinde çalışan bir uygulama, AudioPlayer'a tek duyarlıklı, kayan nokta biçiminde veri sağlayabilir.

Aşağıdaki örnek kodda Engine::CreateAudioPlayer() yöntemi, kayan nokta verileri kullanan bir ses çalar oluşturur:

#include <SLES/OpenSLES_Android.h>
...
SLAndroidDataFormat_PCM_EX pcm;
pcm.formatType = SL_ANDROID_DATAFORMAT_PCM_EX;
pcm.numChannels = 2;
pcm.sampleRate = SL_SAMPLINGRATE_44_1;
pcm.bitsPerSample = 32;
pcm.containerSize = 32;
pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
pcm.endianness = SL_BYTEORDER_LITTLEENDIAN;
pcm.representation = SL_ANDROID_PCM_REPRESENTATION_FLOAT;
...
SLDataSource audiosrc;
audiosrc.pLocator = ...
audiosrc.pFormat = &pcm;
Örnekleme sesi sayfasından kayan nokta ses hakkında daha fazla bilgi edinebilirsiniz.