UYARI: OpenSL ES desteği sonlandırıldı. Geliştiriciler, GitHub'da bulunan açık kaynak Oboe kitaplığını kullanmalıdır. Oboe, AAudio'ya çok benzeyen bir API sağlayan bir C++ sarmalayıcıdır. Oboe, AAudio kullanılabilir olduğunda AAudio'yu çağırır ve AAudio kullanılamıyorsa OpenSL ES'ye geri döner.
Bu sayfada, OpenSL ESTM'nin NDK uygulamasının OpenSL ES 1.0.1'in referans spesifikasyonundan nasıl farklı olduğu hakkında ayrıntılı bilgi verilmektedir. Spesifikasyondaki örnek kodu kullanırken Android'de çalışacak şekilde değiştirmeniz gerekebilir.
Aksi belirtilmedikçe tüm özellikler Android 2.3 (API seviyesi 9) ve sonraki sürümlerde kullanılabilir. Bazı özellikler yalnızca Android 4.0 (API düzeyi 14) için kullanılabilir. Bu özellikler belirtilmiştir.
Not: Android Uyumluluk Tanımlama Belgesi (CDD), uyumlu bir Android cihazın donanım ve yazılım şartlarını belirtir. Genel uyumluluk programı hakkında daha fazla bilgi için Android Uyumluluğu'na, gerçek CDD belgesi için de CDD'ye bakın.
OpenSL ES, C++ kullanılarak da erişilebilen bir C dil arayüzü sağlar. Aşağıdaki Android Java API'lerinin ses bölümlerine benzer özellikler sunar:
Tüm Android Native Development Kit'te (NDK) olduğu gibi, Android için OpenSL ES'nin asıl amacı, Java Native Interface (JNI ) kullanılarak çağrılacak paylaşılan kitaplıkların uygulanmasını kolaylaştırmaktır. NDK, tam C/C++ uygulamaları yazmak için tasarlanmamıştır. Ancak OpenSL ES tam özellikli bir API'dir ve ses ihtiyaçlarınızın çoğunu Android çalışma zamanında çalışan koda çağrı göndermeden yalnızca bu API'yi kullanarak karşılayabilmenizi bekleriz.
Not: OpenSL ES'ye dayalı olsa da, Android yerel ses (yüksek performanslı ses) API'si hiçbir OpenSL ES 1.0.1 profiline uygun bir uygulama değildir (oyun, müzik veya telefon). Bunun nedeni, Android'in profillerden herhangi birinin gerektirdiği tüm özellikleri uygulamamasıdır. Android'in spesifikasyondan farklı davrandığı bilinen tüm durumlar Android uzantıları sayfasında açıklanmaktadır.
Referans spesifikasyonundan devralınan özellikler
OpenSL ES'nin Android NDK uygulaması, referans spesifikasyonundaki özelliklerin büyük bir kısmını belirli sınırlamalarla devralır.
Genel giriş noktaları
Android için OpenSL ES, Android spesifikasyonundaki tüm genel giriş noktalarını destekler. Bu giriş noktaları şunlardır:
slCreateEngine
slQueryNumSupportedEngineInterfaces
slQuerySupportedEngineInterfaces
Nesneler ve arayüzler
Aşağıdaki tabloda, OpenSL ES'in Android NDK uygulamasının desteklediği nesneler ve arayüzler gösterilmektedir. Hücrede Evet görünüyorsa özellik bu uygulamada kullanılabilir.
Özellik | Ses çalar | Ses kaydedici | Motor | Çıkış karması |
---|---|---|---|---|
Güçlü bas | Evet | Hayır | Hayır | Evet |
Arabellek sırası | Evet | Hayır | Hayır | Hayır |
Arabellek sırası veri bulma aracı | Evet: Kaynak | Hayır | Hayır | Hayır |
Dinamik arayüz yönetimi | Evet | Evet | Evet | Evet |
Efekt gönderme | Evet | Hayır | Hayır | Hayır |
Motor | Hayır | Hayır | Evet | Hayır |
Ortam yankısı | Hayır | Hayır | Hayır | Evet |
Ekolayzer | Evet | Hayır | Hayır | Evet |
G/Ç cihazı veri bulucu | Hayır | Evet: Kaynak | Hayır | Hayır |
Meta veri ayıklama | Evet: PCM olarak kod çözme | Hayır | Hayır | Hayır |
Tek kişinin sesini kapat | Evet | Hayır | Hayır | Hayır |
Nesne | Evet | Evet | Evet | Evet |
Çıkış karışımı bulucu | Evet: Lavabo | Hayır | Hayır | Hayır |
Oynat | Evet | Hayır | Hayır | Hayır |
Oynatma hızı | Evet | Hayır | Hayır | Hayır |
Ön getirme durumu | Evet | Hayır | Hayır | Hayır |
Hazır yankı | Hayır | Hayır | Hayır | Evet |
Kaydet | Hayır | Evet | Hayır | Hayır |
Ara | Evet | Hayır | Hayır | Hayır |
URI veri bulma aracı | Evet: Kaynak | Hayır | Hayır | Hayır |
Sanallaştırıcı | Evet | Hayır | Hayır | Evet |
Ses | Evet | Hayır | Hayır | Hayır |
Bu özelliklerin bazılarıyla ilgili sınırlamalar sonraki bölümde açıklanmıştır.
Sınırlamalar
Tablo 1'de yer alan özellikler için belirli sınırlamalar vardır. Bu sınırlamalar, referans spesifikasyondan kaynaklanan farklılıkları gösterir. Bu bölümün geri kalanında bu farklılıklar hakkında bilgi verilmektedir.
Dinamik arayüz yönetimi
Android için OpenSL ES, RemoveInterface
veya ResumeInterface
'ü desteklemez.
Efekt kombinasyonları: ortam yankısı ve hazır yankı
Aynı çıkış karışımında hem ortam yankısı hem de hazır ayar yankısı kullanamazsınız.
Platform, CPU yükünün çok yüksek olacağını tahmin ederse efekt isteklerini yoksayabilir.
Efekt gönderme
SetSendLevel()
, ses oynatıcı başına tek bir gönderme düzeyini destekler.
Ortam yankısı
Ortam yankısı, SLEnvironmentalReverbSettings
yapısını reflectionsDelay
, reflectionsLevel
veya reverbDelay
alanlarını desteklemez.
MIME veri biçimi
MIME veri biçimini yalnızca URI veri bulucuyla ve yalnızca ses çalar için kullanabilirsiniz. Bu veri biçimini ses kaydedici için kullanamazsınız.
OpenSL ES'in Android uygulamasında, mimeType
değerini NULL
veya geçerli bir UTF-8 dizesi olarak başlatmanız gerekir. Ayrıca containerType
değerini geçerli bir değerle başlatmanız gerekir.
Uygulamanın başlıktan tanımlayamadığı diğer uygulamalara veya içerik biçimlerine taşınabilirlik gibi başka bir durum söz konusu değilse mimeType
değerini NULL
, containerType
değerini ise SL_CONTAINERTYPE_UNSPECIFIED
olarak ayarlamanızı öneririz.
Android için OpenSL ES, Android platformu da desteklediği sürece aşağıdaki ses biçimlerini destekler:
- WAV PCM'dir.
- WAV alaw.
- WAV ulaw.
- MP3 Ogg Vorbis.
- AAC LC.
- HE-AACv1 (AAC+).
- HE-AACv2 (geliştirilmiş AAC+).
- AMR.
- FLAC.
Not: Android'in desteklediği ses biçimlerinin listesi için Desteklenen medya biçimleri bölümüne bakın.
OpenSL ES'nin bu uygulamasında bu ve diğer biçimlerin işlenmesinde aşağıdaki sınırlamalar geçerlidir:
- AAC biçimleri bir MP4 veya ADTS kapsayıcısında olmalıdır.
- Android için OpenSL ES, MIDI'yi desteklemez.
- WMA, AOSP'nin bir parçası değildir ve Android için OpenSL ES ile uyumluluğunu doğrulamadık.
- OpenSL ES'in Android NDK uygulaması, DRM veya şifrelenmiş içeriğin doğrudan oynatılmasını desteklemez. Korunan ses içeriğini oynatmak için oynatmadan önce uygulamanızda şifresini çözmeniz gerekir. Bu sırada uygulamanız DRM kısıtlamalarını uygular.
Nesnelerle ilgili yöntemler
Android için OpenSL ES, nesneleri değiştirmeyle ilgili aşağıdaki yöntemleri desteklemez:
Resume()
RegisterCallback()
AbortAsyncOperation()
SetPriority()
GetPriority()
SetLossOfControlInterfaces()
PCM veri biçimi
Arabellek sıralarıyla kullanabileceğiniz tek veri biçimi PCM'dir. Desteklenen PCM oynatma yapılandırmaları aşağıdaki özelliklere sahiptir:
- 8 bit imzasız veya 16 bit imzalı.
- Mono veya stereo.
- Küçük uç bayt sırası.
- Aşağıdaki örnek hızları:
- 8.000 Hz.
- 11.025 Hz.
- 12.000 Hz.
- 16.000 Hz.
- 22.050 Hz.
- 24.000 Hz.
- 32.000 Hz.
- 44.100 Hz.
- 48.000 Hz.
Android için OpenSL ES'nin kayıt için desteklediği yapılandırmalar cihaza bağlıdır. Genellikle 16.000 Hz mono/16 bit imzalı imzalı yapılandırmalar cihazdan bağımsız olarak kullanılabilir.
Yanıltıcı ada rağmen samplesPerSec
alanının değeri miliHz birimi cinsindendir. Yanlış değeri yanlışlıkla kullanmaktan kaçınmak için bu alanı, bu amaç için tanımlanan sembolik sabitlerden birini (ör. SL_SAMPLINGRATE_44_1
) kullanarak başlatmanızı öneririz.
Android 5.0 (API düzeyi 21) ve sonraki sürümler kayan noktalı verileri destekler.
Oynatma hızı
OpenSL ES oynatma hızı, bir nesnenin veri sunma hızını, normal hızın binde biri olarak veya binde bir ifadeyle belirtir. Örneğin, binde 1.000 oynatma hızı 1.000/1.000 veya normal hızdır. Hız aralığı, olası oynatma hızları aralığını ifade eden kapalı bir aralıktır.
Oynatma hızı aralıkları ve diğer özellikler için sağlanan destek, platform sürümüne ve uygulamaya bağlı olarak değişiklik gösterebilir. Uygulamanız, cihazı sorgulamak için PlaybackRate::GetRateRange()
veya PlaybackRate::GetCapabilitiesOfRate()
kullanarak bu özellikleri çalışma zamanında belirleyebilir.
Cihazlar genellikle PCM biçimindeki bir veri kaynağı için aynı hız aralığını ve diğer biçimler için 1.000 ila 1.000 mille arasında bir birlik hızı aralığını destekler. Yani birlik hızı aralığı aslında tek bir değerdir.
Kaydet
Android için OpenSL ES, SL_RECORDEVENT_HEADATLIMIT
veya SL_RECORDEVENT_HEADMOVING
etkinliklerini desteklemez.
Ara
SetLoop()
yöntemi, dosyanın tamamını döngü şeklinde oynatmayı sağlar. Döngüyü etkinleştirmek için startPos
parametresini 0, endPos
parametresini ise SL_TIME_UNKNOWN
olarak ayarlayın.
Arabellek sırası veri bulma aracı
Arabellek kuyruğu için veri bulucu içeren bir ses çalar veya kaydedici yalnızca PCM veri biçimini destekler.
G/Ç cihazı veri bulma aracı
Android için OpenSL ES, yalnızca Engine::CreateAudioRecorder()
için veri kaynağı olarak bulucuyu belirttiğinizde G/Ç cihaz veri bulucusunun kullanımını destekler.
Aşağıdaki kod snippet'inde yer alan değerleri kullanarak cihaz veri bulucusunu başlatın:
SLDataLocator_IODevice loc_dev = {SL_DATALOCATOR_IODEVICE, SL_IODEVICE_AUDIOINPUT, SL_DEFAULTDEVICEID_AUDIOINPUT, NULL};
URI veri bulma aracı
Android için OpenSL ES, URI veri bulucusunu yalnızca MIME veri biçimiyle ve yalnızca ses çalar için kullanabilir. Ses kaydedici için URI veri bulucu kullanamazsınız. URI'de yalnızca http:
ve file:
şemaları kullanılabilir. https:
, ftp:
veya content:
gibi diğer şemalara izin verilmez.
Android platformunda sesli rtsp:
desteğini doğrulamadık.
Veri yapıları
Android, aşağıdaki OpenSL ES 1.0.1 veri yapılarını destekler:
SLDataFormat_MIME
SLDataFormat_PCM
SLDataLocator_BufferQueue
SLDataLocator_IODevice
SLDataLocator_OutputMix
SLDataLocator_URI
SLDataSink
SLDataSource
SLEngineOption
SLEnvironmentalReverbSettings
SLInterfaceID
Platform yapılandırması
Android için OpenSL ES, çok iş parçacıklı uygulamalar için tasarlanmış ve iş parçacığı açısından güvenlidir. Uygulama başına tek bir motoru ve motor başına en fazla 32 nesneyi destekler. Kullanılabilir cihaz belleği ve CPU, kullanılabilir nesne sayısını daha da kısıtlayabilir.
Aşağıdaki motor seçenekleri tanınır ancak slCreateEngine
tarafından yoksayılır:
SL_ENGINEOPTION_THREADSAFE
SL_ENGINEOPTION_LOSSOFCONTROL
OpenMAX AL ve OpenSL ES aynı uygulamada birlikte kullanılabilir. Bu durumda, dahili olarak tek bir paylaşılan motor nesnesi vardır ve 32 nesne sınırı OpenMAX AL ile OpenSL ES arasında paylaşılır. Uygulama, her iki motoru da oluşturmalı, her iki motoru da kullanmalı ve sonunda her iki motoru da imha etmelidir. Uygulama, paylaşılan motorda bir referans sayısını tutarak ikinci kaldırma işlemi sırasında doğru şekilde yok edilmesini sağlar.
Programlama notları
OpenSL ES programlama notları, OpenSL ES'in doğru şekilde uygulanmasını sağlamak için ek bilgiler sağlar.
Not:
Size kolaylık sağlamak amacıyla, docs/opensles/OpenSL_ES_Specification_1.0.1.pdf
içinde NDK'nın yer aldığı OpenSL ES 1.0.1 spesifikasyonunun bir kopyasını ekledik.
Platform sorunları
Bu bölümde, bu API'leri destekleyen ilk platform sürümündeki bilinen sorunlar açıklanmaktadır.
Dinamik arayüz yönetimi
DynamicInterfaceManagement::AddInterface
çalışmıyor. Bunun yerine, çevresel yankı için örnek kodda gösterildiği gibi Create()
parametresine iletilen dizi içinde arayüzü belirtin.
OpenSL ES'in gelecekteki sürümleri için planlama yapma
Android yüksek performanslı ses API'leri Khronos Group OpenSL ES 1.0.1 çözümünü temel alır. Khronos, standardın düzeltilmiş 1.1 sürümünü yayınladı. Düzeltilmiş sürümde yeni özellikler, açıklamalar, yazım hatalarının düzeltmeleri ve bazı uyumsuzluklar yer alır. Beklenen uyumsuzlukların çoğu nispeten küçüktür veya Android'in desteklemediği OpenSL ES alanlarındadır.
Bu sürümle geliştirilen bir uygulama, aşağıdaki İkili uyumluluk için planlama bölümünde belirtilen yönergelere uymanız koşuluyla Android platformunun gelecekteki sürümlerinde çalışmalıdır.
Not: Gelecekte kaynak uyumluluğu hedefimiz değildir. Yani NDK'nın daha yeni bir sürümüne yükseltirseniz uygulama kaynak kodunuzu yeni API'ye uygun olacak şekilde değiştirmeniz gerekebilir. Bu tür değişikliklerin çoğunun küçük olmasını bekliyoruz. Ayrıntıları aşağıda bulabilirsiniz.
İkili program uyumluluğunu planlama
Gelecekteki ikili program uyumluluğunu iyileştirmek için uygulamanızın şu yönergelere uymasını öneririz:
- Yalnızca OpenSL ES 1.0.1 sürümünde Android tarafından desteklenen özelliklerin belgelenen alt kümesini kullanın.
- Başarısız bir işlem için belirli bir sonuç koduna güvenmeyin; farklı bir sonuç koduyla karşılaşmaya hazır olun.
- Uygulama geri çağırma işleyicileri genellikle kısıtlı bir bağlamda çalışır. Bu kişiler, işlerini hızlı bir şekilde tamamlayıp en kısa sürede geri dönecek şekilde yazılmalıdır. Geri çağırma işleyici içinde karmaşık işlemler çalıştırmayın. Örneğin, arabellek sırası tamamlama geri çağırması içinde başka bir arabelleği sıraya alabilir ancak ses çalar oluşturamazsınız.
- Geri çağırma işleyicileri, ek etkinlik türleri almak için daha az veya daha sık çağrılmaya hazır olmalı ve tanımadıkları etkinlik türlerini yoksaymalıdır. Etkin etkinlik türlerinden oluşan bir etkinlik maskesi ile yapılandırılmış geri çağırma işlevleri, aynı anda birden fazla etkinlik türü biti ayarlanmış şekilde çağrılmaya hazırlanmalıdır. Her etkinlik bitini test etmek için switch case yerine "&" kullanın.
- Önceden getirme durumunu ve geri çağırmaları ilerlemenin genel göstergesi olarak kullanın ancak sabit kodlu belirli dolgu düzeylerine veya geri çağırma sıralarına bağımlı kalmayın. Ön prefetch durum dolgu düzeyinin anlamı ve ön prefetch sırasında algılanan hataların davranışı değişebilir.
Not: Daha fazla bilgi için aşağıdaki Arabellek sırası davranışı bölümüne bakın.
Kaynak uyumluluğunu planlama
Belirtildiği gibi, Khronos Group'tan OpenSL ES'nin bir sonraki sürümünde kaynak kodu uyumsuzluklarının oluşması beklenmektedir. Değişiklik olasılığı olan alanlar şunlardır:
- Özellikle
BufferQueue::Enqueue
alanında,slBufferQueueCallback
parametre listesinde veSLBufferQueueState.playIndex
alanının adında olmak üzere arabellek aralığı arayüzünde önemli değişiklikler yapılması beklenmektedir. Uygulama kodunuzda bunun yerine Android basit arabellek kuyruklarını kullanmanızı öneririz. NDK ile birlikte sağlanan örnek kodda, bu nedenle oynatma için Android basit arabelleğe alma sıralarını kullandık. (PCM'ye kayıt ve kod çözme için Android basit arabellek sırasını da kullanırız. Bunun nedeni, standart OpenSL ES 1.0.1'in arabellek sırası veri alıcısına kayıt veya kod çözme işlemini desteklememesidir.) - Referans yoluyla iletilen giriş parametrelerine
const
ve giriş değeri olarak kullanılanSLchar *
struct alanlarına eklenecek. Bu işlem için kodunuzda herhangi bir değişiklik yapmanız gerekmez. - Şu anda imzalanmış olan bazı parametreler için imzasız türler kullanılacak.
Bir parametre türünü
SLint32
yerineSLuint32
veya benzeri bir türe değiştirmeniz ya da bir yayın eklemeniz gerekebilir. Equalizer::GetPresetName
, uygulama belleğine bir işaretçi döndürmek yerine dizeyi uygulama belleğine kopyalar. Bu önemli bir değişiklik olacağından bu yöntemi çağırmaktan kaçınmanızı veya kullanımını izole etmenizi öneririz.- Yapı türlerinde ek alanlar olacaktır. Çıkış parametrelerinde bu yeni alanlar yoksayılabilir ancak giriş parametreleri için yeni alanların başlatılması gerekir. Neyse ki bu alanların tümünün Android tarafından desteklenmeyen bölgelerde olması beklenir.
- Arayüz GUID'leri değişecek. Bağımlılık oluşturmamak için arayüzlere GUID yerine sembolik adla referans verin.
unsigned char
olanSLchar
fiyatıchar
olarak değiştirilecek. Bu, öncelikli olarak URI veri bulucuyu ve MIME veri biçimini etkiler.SLDataFormat_MIME.mimeType
,pMimeType
olarak,SLDataLocator_URI.URI
isepURI
olarak yeniden adlandırılacak. Kodunuzu bu değişiklikten korumak içinSLDataFormat_MIME
veSLDataLocator_URI
veri yapılarını, alan adına göre değil, parantez içine alınmış, virgül ile ayrılmış bir değer listesi kullanarak başlatmanızı öneririz. Bu teknik, örnek kodda kullanılmıştır.SL_DATAFORMAT_PCM
, uygulamanın verilerin gösterimini signed integer, unsigned integer veya floating-point olarak belirtmesine izin vermiyor. Android uygulamasında, 8 bit verilerin imzasız tam sayı, 16 bit verilerin ise imzalı tam sayı olduğu varsayılır. Ayrıca, gerçek birimler milili Hz olduğundansamplesPerSec
alanı yanlış bir addır. Bu sorunların, uygulamanın temsili açıkça belirtmesine izin veren ve alan adını düzelten yeni bir genişletilmiş PCM veri biçimi sunacak olan bir sonraki OpenSL ES sürümünde ele alınması bekleniyor. Bu yeni bir veri biçimi olacağından ve mevcut PCM veri biçimi yine kullanılabileceğinden (desteği sonlandırılmış olsa da) kodunuzda acil bir değişiklik yapmanız gerekmeyecektir.