AAudio, Android O sürümünde sunulan yeni bir Android C API'dir. Düşük gecikme gerektiren yüksek performanslı ses uygulamaları için tasarlanmıştır. Uygulamalar, akışlarda veri okuyup yazarak AAudio ile iletişim kurar.
AAudio API'sı tasarım gereği minimum düzeydedir ve aşağıdaki işlevleri yerine getirmez:
- Ses cihazı numaralandırması
- Ses uç noktaları arasında otomatik yönlendirme
- Dosya G/Ç
- Sıkıştırılmış sesin kodunu çözme
- Tüm girişlerin/akışların tek bir geri çağırmada otomatik olarak sunumu.
Başlarken
A+ numarasını C++ kodundan arayabilirsiniz. Uygulamanıza AAudio özelliğini eklemek için AAudio.h üstbilgi dosyasını ekleyin:
#include <aaudio/AAudio.h>
Ses akışları
AAudio, ses verilerini uygulamanız ile Android cihazınızdaki ses giriş ve çıkışları arasında taşır. Uygulamanız, AAudioStream yapısıyla temsil edilen ses akışlarından okuyup yazarak veri aktarır. Okuma/yazma çağrıları engelleniyor veya engellenmiyor olabilir.
Akış aşağıdaki şekilde tanımlanır:
- Akıştaki verilerin kaynağı veya havuzu olan ses cihazı.
- Bir yayının, birden fazla yayın arasında paylaşılabilecek bir ses cihazına özel erişimi olup olmadığını belirleyen paylaşım modu.
- Akıştaki ses verilerinin biçimi.
Ses cihazı
Her yayın tek bir ses cihazına bağlıdır.
Ses cihazı, sürekli bir dijital ses verisi akışı kaynağı veya havuzu olarak kullanılan bir donanım arayüzü veya sanal uç noktadır. Bir ses cihazını (yerleşik bir mikrofon veya Bluetooth mikrofonlu kulaklık), uygulamanızı çalıştıran Android cihazla (telefon veya saat) karıştırmayın.
Android cihazınızda kullanılabilen ses cihazlarını keşfetmek için AudioManager
yöntemini getDevices()
kullanabilirsiniz. Yöntem, her cihazın type
hakkında bilgi döndürür.
Her ses cihazının Android cihazında benzersiz bir kimliği vardır. Bir ses akışını belirli bir ses cihazına bağlamak için kimliği kullanabilirsiniz. Ancak çoğu durumda AAudio'nun varsayılan cihazı kendiniz belirtmek yerine seçmesine izin verebilirsiniz.
Bir akışa bağlı ses cihazı, yayının giriş mi yoksa çıkış mı olduğunu belirler. Bir akış, verileri yalnızca bir yönde taşıyabilir. Bir akış tanımlarken yönü de belirlersiniz. Bir yayını açtığınızda Android, ses cihazının ve yayın yönünün uyumlu olup olmadığını kontrol eder.
Paylaşım modu
Bir yayının paylaşım modu vardır:
AAUDIO_SHARING_MODE_EXCLUSIVE
, akışın ses cihazına özel erişimi olduğu anlamına gelir. Cihaz başka bir ses akışı tarafından kullanılamaz. Ses cihazı zaten kullanılıyorsa yayının özel erişimi olmayabilir. Özel yayınların gecikme olasılığı daha düşüktür ancak bunların bağlantıları da kesilebilir. Diğer uygulamaların cihaza erişebilmesi için özel yayınları artık ihtiyacınız olmadığında kapatmalısınız. Özel akışlar, mümkün olan en düşük gecikmeyi sağlar.AAUDIO_SHARING_MODE_SHARED
, AAudio'nun sesleri karıştırmasına olanak tanır. AAudio, aynı cihaza atanan tüm paylaşılan akışları karıştırır.
Canlı yayın oluştururken paylaşım modunu açıkça ayarlayabilirsiniz. Varsayılan olarak paylaşım modu SHARED
şeklindedir.
Ses biçimi
Bir akıştan iletilen veriler, her zamanki dijital ses özelliklerine sahiptir. Bunlar aşağıdaki gibidir:
- Örnek veri biçimi
- Kanal sayısı (kare başına örnek sayısı)
- Örnek hızı
AAudio aşağıdaki örnek biçimlere izin verir:
aaudio_biçim_t | C veri türü | Notlar |
---|---|---|
AUD__FORMAT_PCM_I16 | int16_t | Yaygın 16 bit örnekler, Q0.15 biçimi |
AUDIO_FORMAT_PCM_FLOAT | kayan | -1,0 ile +1,0 |
AAUDIO_FORMAT_PCM_I24_HAZIR | 3'lü gruplarda uint8_t | paketlenmiş 24 bit örnekler, 0,23 biçiminde |
AUDIO_FORMAT_PCM_I32 | int32_t | Yaygın 32 bit örnekler, Q0.31 biçimi |
AUDIO_FORMAT_IEC61937 | kullanıcı8_t | HDMI veya S/PDIF geçişi için IEC61937'de sarmalanmış sıkıştırılmış ses |
Belirli bir örnek biçim isterseniz akış cihaz için en uygun biçim olmasa bile bu biçimi kullanır. Örnek biçim belirtmezseniz AAudio en uygun biçimi seçer. Akış açıldıktan sonra örnek veri biçimini sorgulamanız ve gerekirse aşağıdaki örnekte olduğu gibi verileri dönüştürmeniz gerekir:
aaudio_format_t dataFormat = AAudioStream_getDataFormat(stream);
//... later
if (dataFormat == AAUDIO_FORMAT_PCM_I16) {
convertFloatToPcm16(...)
}
Ses akışı oluşturma
AAudio kitaplığı, derleyici tasarım kalıbı uygular ve AAudioStreamBuilder'ı sunar.
- AAudioStreamBuilder oluşturun:
AAudioStreamBuilder *builder; aaudio_result_t result = AAudio_createStreamBuilder(&builder);
- Akış parametrelerine karşılık gelen oluşturucu işlevlerini kullanarak oluşturucuda ses akışı yapılandırmasını ayarlayın. Aşağıdaki isteğe bağlı set işlevleri kullanılabilir:
AAudioStreamBuilder_setDeviceId(builder, deviceId); AAudioStreamBuilder_setDirection(builder, direction); AAudioStreamBuilder_setSharingMode(builder, mode); AAudioStreamBuilder_setSampleRate(builder, sampleRate); AAudioStreamBuilder_setChannelCount(builder, channelCount); AAudioStreamBuilder_setFormat(builder, format); AAudioStreamBuilder_setBufferCapacityInFrames(builder, frames);
Bu yöntemlerin, tanımlanmamış bir sabit değer veya aralık dışında bir değer gibi hataları bildirmediğini unutmayın.
deviceId belirtmezseniz varsayılan olarak birincil çıkış cihazı kullanılır. Akış yönünü belirtmezseniz varsayılan olarak çıkış akışı kullanılır. Diğer tüm parametreler için açıkça bir değer belirleyebilir veya parametreyi hiç belirtmeyerek ya da değeri
AAUDIO_UNSPECIFIED
olarak ayarlayarak sistemin en uygun değeri atamasına izin verebilirsiniz.Ses parçasını oluşturduktan sonra, güvenli bir şekilde oluşturmanızın ardından aşağıdaki 4. adımda açıklandığı gibi ses akışının durumunu kontrol edin.
- AAudioStreamBuilder yapılandırıldığında bir akış oluşturmak için kullanın:
AAudioStream *stream; result = AAudioStreamBuilder_openStream(builder, &stream);
- Yayını oluşturduktan sonra yapılandırmasını doğrulayın. Örnek biçimini, örnek hızını veya kare başına örnek sayısını belirttiyseniz bunlar değişmez. Paylaşım modunu veya arabellek kapasitesini belirttiyseniz bunlar, akışın ses cihazının ve çalıştığı Android cihazın özelliklerine bağlı olarak değişebilir. İyi bir savunma programı kapsamında kullanmadan önce yayın yapılandırmasını kontrol etmeniz gerekir. Her derleme ayarına karşılık gelen akış ayarını alma işlevleri vardır:
- Oluşturucuyu kaydedebilir ve daha fazla akış yapmak için gelecekte yeniden kullanabilirsiniz. Ancak, artık kullanmayı düşünmüyorsanız planı silmeniz gerekir.
AAudioStreamBuilder_delete(builder);
Ses akışı kullanma
Eyalet geçişleri
AAudio akışı genellikle beş kararlı durumdan birinde olur (Bağlantı kesildi hata durumu bu bölümün sonunda açıklanmıştır):
- Aç
- Başlatıldı
- Duraklatıldı
- Kızarmış-yüz
- Durduruldu
Bir akışa yalnızca veri Başlatıldı durumundayken veri akışı sağlanır. Bir akışı eyaletler arasında taşımak için durum geçişi isteğinde bulunan işlevlerden birini kullanın:
aaudio_result_t result;
result = AAudioStream_requestStart(stream);
result = AAudioStream_requestStop(stream);
result = AAudioStream_requestPause(stream);
result = AAudioStream_requestFlush(stream);
Çıkış akışını yalnızca duraklatma veya boşaltma isteğinde bulunabileceğinizi unutmayın:
Bu işlevler eşzamansız olarak kullanılır ve durum değişikliği hemen gerçekleşmez. Bir durum değişikliği isteğinde bulunduğunuzda akış, karşılık gelen geçici durumlardan birini taşır:
- Başlatılıyor
- Duraklatılıyor
- Kızarmış-yüz
- Durduruluyor
- Kapanma
Aşağıdaki durum şemasında, stabil durumlar yuvarlak dikdörtgenler, geçici durumlar ise noktalı dikdörtgenler gösterilmektedir.
Gösterilmese de herhangi bir eyaletten close()
numarasını arayabilirsiniz
AAudio, yapılan değişiklikler konusunda sizi uyarmak için geri çağırmalar sağlamaz. Özel işlevlerden biri olan AAudioStream_waitForStateChange(stream, inputState, nextState, timeout)
, durum değişikliğini beklemek için kullanılabilir.
İşlev, durum değişikliğini kendi başına algılamaz ve belirli bir durumu beklemez. Mevcut durum, belirttiğiniz inputState
öğesinden farklı olana kadar bekler.
Örneğin, bir akış duraklatılmasını talep ettikten sonra geçici akışın Duraklatma durumuna hemen girmesi ve daha sonra Duraklatılmış duruma gelmesi gerekir. Ancak bu, garanti edilmez.
Duraklatma durumunu bekleyemezsiniz. Bu nedenle, Duraklatma dışında herhangi bir durumu beklemek için waitForStateChange()
tuşunu kullanın. Bunun için aşağıdaki adımları uygulayın:
aaudio_stream_state_t inputState = AAUDIO_STREAM_STATE_PAUSING;
aaudio_stream_state_t nextState = AAUDIO_STREAM_STATE_UNINITIALIZED;
int64_t timeoutNanos = 100 * AAUDIO_NANOS_PER_MILLISECOND;
result = AAudioStream_requestPause(stream);
result = AAudioStream_waitForStateChange(stream, inputState, &nextState, timeoutNanos);
Akış durumu duraklatılmıyorsa (çağrıda geçerli durum olduğunu varsaydığımız inputState
) işlev hemen döndürülür. Aksi takdirde, durum artık Duraklatılana veya zaman aşımı süresi dolana kadar engellenir. İşlev geri döndüğünde, nextState
parametresi akışın mevcut durumunu gösterir.
Aynı tekniği, istek başlatma, durdurma veya boşaltma çağrısından sonra ilgili StateState'i kullanarak karşılık gelen geçici durumu kullanarak kullanabilirsiniz. Yayın kapatıldıktan hemen sonra silineceğinden AAudioStream_close()
adını aradıktan sonra waitForStateChange()
yöntemini çağırmayın. waitForStateChange()
başka bir ileti dizisinde çalışırken AAudioStream_close()
yöntemini çağırmayın.
Ses akışları okuma ve yazma
Bir akıştaki veriler başlatıldıktan sonra iki şekilde işlenebilir:
- Yüksek öncelikli bir geri arama kullanın.
AAudioStream_read(stream, buffer, numFrames, timeoutNanos)
veAAudioStream_write(stream, buffer, numFrames, timeoutNanos)
işlevlerini kullanın. okumanız veya yazmanız gerekir.
Belirtilen sayıda kareyi aktaran bir engelleme okuma veya yazma işlemi içinTimeoutNanos değerini sıfırdan büyük olarak ayarlayın. Engellemeyen bir görüşme içinTimeoutNanos değerini sıfır olarak ayarlayın. Bu durumda sonuç, aktarılan gerçek kare sayısı olur.
Girişi okurken doğru kare sayısının okunduğunu doğrulamanız gerekir. Aksi takdirde, arabellek bir ses arızasına neden olabilecek bilinmeyen veriler içerebilir. Sessiz bir düşüş oluşturmak için arabelleği sıfırlarla doldurabilirsiniz:
aaudio_result_t result =
AAudioStream_read(stream, audioData, numFrames, timeout);
if (result < 0) {
// Error!
}
if (result != numFrames) {
// pad the buffer with zeros
memset(static_cast<sample_type*>(audioData) + result * samplesPerFrame, 0,
sizeof(sample_type) * (numFrames - result) * samplesPerFrame);
}
Akışı başlatmadan önce veri yazarak veya sessize alarak akışın arabelleğe alınmasını sağlayabilirsiniz. Bu işlemin, zaman aşımı değeri sıfır olarak ayarlanmış ve engellemeyen bir çağrıda yapılması gerekir.
Arabellekteki veriler, AAudioStream_getDataFormat()
tarafından döndürülen veri biçimiyle eşleşmelidir.
Ses akışını kapatma
Bir canlı yayını kullanmayı bitirdiğinizde kapatın:
AAudioStream_close(stream);
Bir akışı kapattıktan sonra herhangi bir AAudio akışına dayalı işlevle kullanamazsınız.
Ses akışı bağlantısı kesildi
Aşağıdaki etkinliklerden biri gerçekleşirse ses akışının bağlantısı herhangi bir zamanda kesilebilir:
- İlişkilendirilmiş ses cihazı artık bağlı değil (örneğin, kulaklık takılı değilken).
- Dahili bir hata oluştu.
- Ses cihazı artık birincil ses cihazı değil.
Bir bağlantının bağlantısı kesildiğinde "Bağlantı kesildi" durumuna sahip olur ve AAudioStream_write() veya diğer işlevleri yürütme girişimleri bir hata döndürür. Bağlantısı kesilen bir akışı hata kodundan bağımsız olarak her zaman durdurmanız ve kapatmanız gerekir.
Doğrudan okuma/yazma yöntemlerinden biri yerine bir veri geri çağırması kullanıyorsanız akışın bağlantısı kesildiğinde döndürme kodu almazsınız. Böyle bir durumda bilgilendirilmek için bir AAudioStream_errorCallback işlevi yazın ve AAudioStreamBuilder_setErrorCallback() işlevini kullanarak kaydedin.
Hatalı bir geri çağırma ileti dizisinde bağlantının kesildiğine dair bildirim alırsanız akışı durdurma ve kapatma işlemi başka bir ileti dizisinden yapılmalıdır. Aksi takdirde bir kilitlenmeniz olabilir.
Yeni bir akış açarsanız orijinal yayından farklı ayarlara sahip olabileceğini (ör. framePerBurst):
void errorCallback(AAudioStream *stream,
void *userData,
aaudio_result_t error) {
// Launch a new thread to handle the disconnect.
std::thread myThread(my_error_thread_proc, stream, userData);
myThread.detach(); // Don't wait for the thread to finish.
}
Performansı optimize etme
Dahili arabellekleri düzenleyerek ve özel yüksek öncelikli mesaj dizileri kullanarak bir ses uygulamasının performansını optimize edebilirsiniz.
Gecikmeyi en aza indirmek için arabellekleri ayarlama
AAudio, her bir ses cihazı için bir tane olmak üzere, dahili arabelleklere veri aktarır.
Arabelleğin kapasitesi, bir arabelleğin bulundurabileceği toplam veri miktarıdır. Kapasiteyi ayarlamak için AAudioStreamBuilder_setBufferCapacityInFrames()
numaralı telefonu arayabilirsiniz. Yöntem, cihazın izin verdiği maksimum değere ayırabileceğiniz kapasiteyi sınırlar. Arabelleğin gerçek kapasitesini doğrulamak için AAudioStream_getBufferCapacityInFrames()
değerini kullanın.
Uygulamanın bir arabellek kapasitesinin tamamını kullanması gerekmez. Ses, ayarlayabileceğiniz bir boyuta kadar bir arabellek doldurur. Tamponların boyutu, kapasitesinden daha büyük olamaz ve genellikle daha küçüktür. Arabellek boyutunu kontrol ederek, alanı doldurmak için gereken seri işlem sayısını ve gecikmeyi kontrol edersiniz. Arabellek boyutuyla çalışmak için AAudioStreamBuilder_setBufferSizeInFrames()
ve
AAudioStreamBuilder_getBufferSizeInFrames()
yöntemlerini kullanın.
Uygulama, ses çaldığında yazma işlemini bir arabelleğe alır ve yazma işlemi tamamlanana kadar engeller. İşitsel, arabellekte farklı patlamalar halinde okunur. Her seri çekim birden fazla ses çerçevesi içerir ve genellikle okunan arabelleğin boyutundan küçük olur. Sistem, seri çekim boyutunu ve hızını kontrol eder. Bu özellikler genellikle ses cihazının devresine göre belirlenir. Seri çekimin boyutunu veya seri çekim hızını değiştiremezsiniz ancak dahili arabelleklerin boyutunu, içereceği seri işlem sayısına göre ayarlayabilirsiniz. Genel olarak, AAudioStream'inizin arabellek boyutu rapor edilen seri çekim boyutunun katıysa en düşük gecikmeyi alırsınız.
Arabellek boyutunu optimize etmenin bir yolu, büyük bir arabellekle başlamak ve geçersiz kılmalar başlayana kadar kademeli olarak azaltmak ve daha sonra tekrar düzeltmektir. Alternatif olarak, küçük bir arabellek boyutuyla başlayabilir ve bu değer gereğinden fazla olursa çıkış tekrar temiz bir şekilde akmaya başlayana kadar arabellek boyutunu artırabilirsiniz.
Bu işlem çok hızlı bir şekilde, muhtemelen kullanıcı ilk sesi çalmadan önce yapılabilir. İlk olarak arabellek boyutlandırmayı sessiz yapmak isteyebilirsiniz. Böylece kullanıcı, seste ani bir kesinti olmaz. Sistem performansı zaman içinde değişebilir (örneğin, kullanıcı uçak modunu kapatabilir). Arabellek ayarı çok az ek yük getirdiğinden uygulamanız bunu bir akışta veri okurken veya yazarken devamlı olarak yapabilir.
Aşağıda, bir arabellek optimizasyonu döngüsüne örnek verilmiştir:
int32_t previousUnderrunCount = 0;
int32_t framesPerBurst = AAudioStream_getFramesPerBurst(stream);
int32_t bufferSize = AAudioStream_getBufferSizeInFrames(stream);
int32_t bufferCapacity = AAudioStream_getBufferCapacityInFrames(stream);
while (go) {
result = writeSomeData();
if (result < 0) break;
// Are we getting underruns?
if (bufferSize < bufferCapacity) {
int32_t underrunCount = AAudioStream_getXRunCount(stream);
if (underrunCount > previousUnderrunCount) {
previousUnderrunCount = underrunCount;
// Try increasing the buffer size by one burst
bufferSize += framesPerBurst;
bufferSize = AAudioStream_setBufferSize(stream, bufferSize);
}
}
}
Bir giriş akışı için arabellek boyutunu optimize etmek amacıyla bu tekniği kullanmanın herhangi bir avantajı yoktur. Giriş akışları olabildiğince hızlı çalışır, arabelleğe alınmış veri miktarını en aza indirmeye çalışır ve ardından uygulama geçici olarak kapatıldığında doldurulur.
Yüksek öncelikli bir geri arama kullanma
Uygulamanız normal bir ileti dizisindeki ses verilerini okur veya yazıyorsa bu veriler geçici olarak kesilebilir veya zamanlamada dalgalanma yaşanabilir. Bu, seste aksamalara neden olabilir. Daha büyük arabellekler kullanmak bu tür aksamalara karşı koruma sağlayabilir, ancak büyük bir arabellek daha uzun bir ses gecikmesi de sağlar. Düşük akış gerektiren uygulamalarda bir ses akışı, uygulamanıza ve buradan veri aktarmak için eşzamansız bir geri çağırma işlevi kullanabilir. Audio, geri çağırmayı daha iyi performansa sahip daha yüksek öncelikli bir ileti dizisinde çalıştırır.
Geri çağırma işlevi şu prototipe sahiptir:
typedef aaudio_data_callback_result_t (*AAudioStream_dataCallback)(
AAudioStream *stream,
void *userData,
void *audioData,
int32_t numFrames);
Geri çağırmayı kaydetmek için akış derlemesini kullanın:
AAudioStreamBuilder_setDataCallback(builder, myCallback, myUserData);
En basit şekilde, akış düzenli olarak bir sonraki seri çekim için veri almak üzere geri çağırma işlevini yürütür.
Geri çağırma işlevi, çağrıda bulunan akışta okuma veya yazma işlemi yapmamalıdır. Geri çağırma, bir giriş akışına aitse kodunuz, AudioData arabelleğinde sağlanan verileri (üçüncü bağımsız değişken olarak belirtilir) işlemelidir. Geri çağırma bir çıkış akışına aitse kodunuz, arabelleğe veri yerleştirmelidir.
Örneğin, aşağıdaki gibi bir sinüs dalgası çıkışını sürekli olarak oluşturmak için bir geri çağırma kullanabilirsiniz:
aaudio_data_callback_result_t myCallback(
AAudioStream *stream,
void *userData,
void *audioData,
int32_t numFrames) {
int64_t timeout = 0;
// Write samples directly into the audioData array.
generateSineWave(static_cast<float *>(audioData), numFrames);
return AAUDIO_CALLABCK_RESULT_CONTINUE;
}
AAudio'yu kullanarak birden çok akış işlenebilir. Bir akışı ana akış olarak kullanabilir ve işaretçileri kullanıcı verilerindeki diğer akışlara yönlendirebilirsiniz. Ana yayın için bir geri çağırma kaydedin. Ardından, diğer akışlarda engelleyici olmayan G/Ç kullanın. Giriş akışını çıkış akışına geçiren bir gidiş dönüş geri çağırma örneğini burada bulabilirsiniz. Ana arama akışı, çıkış akışıdır. Giriş akışı, kullanıcı verilerine dahil edilir.
Geri çağırma, verileri çıkış akışının arabelleğine yerleştirerek giriş akışından engelleyici olmayan bir okuma işlemi gerçekleştirir:
aaudio_data_callback_result_t myCallback(
AAudioStream *stream,
void *userData,
void *audioData,
int32_t numFrames) {
AAudioStream *inputStream = (AAudioStream *) userData;
int64_t timeout = 0;
aaudio_result_t result =
AAudioStream_read(inputStream, audioData, numFrames, timeout);
if (result == numFrames)
return AAUDIO_CALLABCK_RESULT_CONTINUE;
if (result >= 0) {
memset(static_cast<sample_type*>(audioData) + result * samplesPerFrame, 0,
sizeof(sample_type) * (numFrames - result) * samplesPerFrame);
return AAUDIO_CALLBACK_RESULT_CONTINUE;
}
return AAUDIO_CALLBACK_RESULT_STOP;
}
Bu örnekte, giriş ve çıkış akışlarının aynı sayıda kanala, biçime ve örnek hızına sahip olduğu varsayılır. Kodlar çevirileri doğru şekilde işlediği sürece akışların biçimi uyuşmuyor olabilir.
Performans modu ayarlanıyor
Her Ses Akışının bir performans modu vardır ve bu mod, uygulamanızın davranışı üzerinde büyük bir etkiye sahiptir. Üç mod vardır:
AAUDIO_PERFORMANCE_MODE_NONE
varsayılan moddur. Gecikme ve güç tasarrufu arasında denge sağlayan bir temel akış kullanır.AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
, daha az gecikme süresi için daha az arabellek ve optimize edilmiş bir veri yolu kullanır.AAUDIO_PERFORMANCE_MODE_POWER_SAVING
daha büyük dahili arabellekler ve daha düşük güç için gecikmeyi ortadan kaldıran bir veri yolu kullanır.
setPerformanceMode() yöntemini çağırarak performans modunu seçebilir, getPerformanceMode() yöntemini çağırarak geçerli modu keşfedebilirsiniz.
Düşük gecikme, uygulamanızdaki güç tasarrufundan daha önemliyse AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
özelliğini kullanın.
Bu, oyunlar veya klavye sentezleyiciler gibi çok etkileşimli uygulamalar için yararlıdır.
Güç tasarrufu, uygulamanızdaki düşük gecikme süresinden daha önemliyse AAUDIO_PERFORMANCE_MODE_POWER_SAVING
özelliğini kullanın.
Bu durum, genellikle, ses akışı veya MIDI dosya oynatıcıları gibi önceden oluşturulmuş müziği çalan uygulamalar için geçerlidir.
AAudio'nun mevcut sürümünde, mümkün olan en düşük gecikmeyi elde etmek için AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
performans modunu ve yüksek öncelikli bir geri çağırma kullanmanız gerekir. Aşağıdaki örneğe bakın:
// Create a stream builder
AAudioStreamBuilder *streamBuilder;
AAudio_createStreamBuilder(&streamBuilder);
AAudioStreamBuilder_setDataCallback(streamBuilder, dataCallback, nullptr);
AAudioStreamBuilder_setPerformanceMode(streamBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
// Use it to create the stream
AAudioStream *stream;
AAudioStreamBuilder_openStream(streamBuilder, &stream);
İleti dizisi güvenliği
AAudio API'sı tamamen iş parçacığı açısından güvenli değildir. Bazı AAudio işlevlerini aynı anda birden fazla ileti dizisinden aynı anda çağıramazsınız. Bunun nedeni, AAudio'nun ileti dizisi önceden kullanılamaz hale gelmesine ve arızalanmasına neden olabilecek mikrofonu kapatma işlevinden kaçınmasıdır.
Güvenliğiniz için AAudioStream_waitForStateChange()
adresini aramayın veya iki farklı ileti dizisinden aynı yayına okumayın ya da yazmayın. Benzer şekilde, bir ileti dizisindeki akışı başka bir ileti dizisinde okurken veya ona yazarken kapatmayın.
AAudioStream_getSampleRate()
ve AAudioStream_getChannelCount()
gibi akış ayarlarını döndüren aramalar ileti dizisi açısından güvenlidir.
Bu aramalar da mesaj dizisi biçiminde güvenlidir:
AAudio_convert*ToText()
AAudio_createStreamBuilder()
AAudioStream_getTimestamp()
hariçAAudioStream_get*()
Bilinen sorunlar
- Android O DP2 sürümü bir FAST kanalı kullanmadığı için yazma gecikmesi, ses gecikmesi kadar yüksektir. Daha düşük gecikme süresi için geri çağırma kullanın.
Ek kaynaklar
Daha fazla bilgi için aşağıdaki kaynaklardan yararlanın: