AAudio, Android O sürümünde kullanıma sunulan yeni bir Android C API'dir. Düşük gecikme gerektiren yüksek performanslı ses uygulamaları için tasarlanmıştır. Uygulamalar, akışlara veri okuyup yazarak AAudio ile iletişim kurar.
AAudio API, tasarımı gereği minimum düzeydedir. şu işlevleri gerçekleştirmez:
- 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ş/akışların tek bir geri çağırmada otomatik olarak sunulması.
Başlarken
AAudio'yu C++ kodundan çağırabilirsiniz. AAudio özelliği grubunu uygulamanıza eklemek için AAudio.h başlık dosyasını ekleyin:
#include <aaudio/AAudio.h>
Ses yayınları
Ses, ses verilerini uygulamanız ile Android cihazınızdaki ses girişleri ve çıkışları arasında taşır. Uygulamanız, ses akışlarına okuma ve yazma işlemleri yaparak verileri içeri ve dışarı aktarır. Bu, AAudioStream yapısıyla temsil edilir. Okuma/yazma çağrıları, engelleyici veya engellemeyen olabilir.
Akış aşağıdakiler tarafından tanımlanır:
- Akıştaki verilerin kaynağı veya havuzu olan ses cihazı.
- Bir yayının, birden fazla canlı yayında paylaşılabilecek bir ses cihazına özel erişim sahibi olup olmadığını belirleyen paylaşım modu.
- Akıştaki ses verilerinin biçimi.
Ses sistemi
Her yayın tek bir ses cihazına bağlıdır.
Ses cihazı, sürekli dijital ses verisi akışı için kaynak veya havuz görevi gören bir donanım arayüzü veya sanal uç noktadır. Ses cihazlarının kafasını karıştırmayın (dahili mikrofon veya Bluetooth mikrofonlu kulaklık) uygulamanızı çalıştıran Android cihazla (telefon veya saat).
Android cihazınızda kullanılabilen ses sistemlerini keşfetmek için AudioManager
getDevices()
yöntemini kullanabilirsiniz. Bu yöntem, her cihazın type
ile ilgili bilgileri döndürür.
Her ses cihazının Android cihazda benzersiz bir kimliği vardır. Bu kimliği kullanarak ses akışını belirli bir ses cihazına bağlayabilirsiniz. Ancak çoğu durumda, kendiniz belirtmek yerine AAudio'nun varsayılan birincil cihazı seçmesine izin verebilirsiniz.
Bir akışa bağlı ses cihazı, yayının giriş için mi yoksa çıkış için mi olduğunu belirler. Akışta veriler yalnızca tek bir yönde taşınabilir. Bir akışı tanımlarken akış yönünü de ayarlamış olursunuz. Bir akışı açtığınızda Android, ses cihazı ve yayın yönünün uyumlu olduğundan emin olmak için kontrol gerçekleştirir.
Paylaşım modu
Bir yayının paylaşım modu vardır:
AAUDIO_SHARING_MODE_EXCLUSIVE
, yayının kendi ses cihazına özel erişimi olduğu anlamına gelir; cihaz başka bir ses yayını tarafından kullanılamaz. Ses sistemi zaten kullanılıyorsa yayının özel erişime sahip olması mümkün olmayabilir. Özel yayınların gecikme süresi daha düşük olsa da bağlantılarının kesilmesi de daha olasıdır. Diğer uygulamaların cihaza erişebilmesi için özel akışları artık ihtiyacınız kalmadığında kapatmanız gerekir. Özel yayınlar mümkün olan en düşük gecikmeyi sağlar.AAUDIO_SHARING_MODE_SHARED
, AAudio'nun sesi karıştırmasına izin verir. Ses, aynı cihaza atanmış paylaşılan tüm yayınları miksler.
Paylaşım modunu bir yayın oluştururken özel olarak ayarlayabilirsiniz. Varsayılan olarak
paylaşım modu SHARED
.
Ses biçimi
Bir akıştan aktarılan veriler her zamanki dijital ses özelliklerine sahiptir. Bu işlemler aşağıda açıklanmıştır:
- Örnek veri biçimi
- Kanal sayısı (kare başına örnek)
- Örnek hızı
AAudio şu örnek biçimlere izin verir:
aaudio_format_t | C veri türü | Notlar |
---|---|---|
ASES_FORMAT_PCM_I16 | int16_t | yaygın 16 bit örnekler, Q0.15 biçimi |
İŞİTSEL_FORMAT_PCM_KATILIM | kayan | -1,0 - +1,0 |
SES_FORMAT_PCM_I24_PAKETLİ | 3'lü gruplarda uint8_t | paketlenmiş 24 bit örnekler, Q0.23 biçimi |
ASES_FORMAT_PCM_I32 | tam32_t | yaygın 32 bit örnekler, Q0.31 biçimi |
İŞİTSEL_FORMAT_IEC61937 | uint8_t | HDMI veya S/PDIF geçişi için IEC61937 kapsamında sıkıştırılmış ses |
Belirli bir örnek biçim isterseniz akış bu biçimi kullanır. reklam biçimi, cihaz için optimum olmasa bile kullanılabilir. Örnek biçim belirtmezseniz AAudio optimum olan biçimi seçer. Akış açıldıktan sonra örnek veri biçimini sorgulamanız ve ardından aşağıdaki örnekte olduğu gibi, gerekirse verileri dönüştürün:
aaudio_format_t dataFormat = AAudioStream_getDataFormat(stream);
//... later
if (dataFormat == AAUDIO_FORMAT_PCM_I16) {
convertFloatToPcm16(...)
}
Ses yayını oluşturma
AAudio kitaplığı bir derleyici tasarım kalıbına göre çalışır ve AAudioStreamBuilder sağlar.
- AAudioStreamBuilder oluşturun:
AAudioStreamBuilder *builder; aaudio_result_t result = AAudio_createStreamBuilder(&builder);
- Yayın parametrelerine karşılık gelen oluşturucu işlevlerini kullanarak oluşturucuda ses yayını yapılandırmasını ayarlayın. Şu isteğe bağlı grup 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ış sabit değer veya aralık dışında değer gibi hataları bildirmediğini unutmayın.
deviceId'yi 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 ayarlayabilir veya parametreyi hiç belirtmeyerek veya
AAUDIO_UNSPECIFIED
konumuna gönderin.Güvenliğiniz için, aşağıdaki 4. adımda açıklandığı şekilde, oluşturduktan sonra ses akışının durumunu kontrol edin.
- AAudioStreamBuilder yapılandırıldığında, akış oluşturmak için bu komutu kullanın:
AAudioStream *stream; result = AAudioStreamBuilder_openStream(builder, &stream);
- Akışı oluşturduktan sonra yapılandırmasını doğrulayın. Örneğin örnek biçimini, örnek hızını veya kare başına örnek sayısını değiştirin. Paylaşım modu veya arabellek kapasitesi belirttiyseniz bunlar değişebilir. akışın ses cihazının ve cihazın özelliklerine bağlı olarak Uygulamanın çalıştığı Android cihaz. İyi bir savunma unsuru olarak kullanmadan önce akışın yapılandırmasını kontrol etmeniz gerekir. Her bir ayara karşılık gelen akış ayarını almak için kullanılan işlevler oluşturucu ayarı:
- Oluşturucuyu kaydedebilir ve gelecekte daha fazla canlı yayın oluşturmak için yeniden kullanabilirsiniz. Ancak artık kullanmayı düşünmüyorsanız silmeniz gerekir.
AAudioStreamBuilder_delete(builder);
Ses yayını kullanma
Durum geçişleri
Bir ses akışı genellikle beş sabit durumdan birindedir (Bağlantı kesildi hata durumu, bu bölümün sonunda açıklanmıştır):
- Aç
- Başladı
- Duraklatıldı
- Kızarmış yüz
- Durduruldu
Yalnızca akış Başlatıldı durumundayken bir akıştan veri akışı sağlanır. Alıcı: bir akışı durumlar arasında taşırken, durum isteğinde bulunan işlevlerden birini kullanın. geçiş:
aaudio_result_t result;
result = AAudioStream_requestStart(stream);
result = AAudioStream_requestStop(stream);
result = AAudioStream_requestPause(stream);
result = AAudioStream_requestFlush(stream);
Yalnızca çıkış akışında duraklatma veya temizleme isteğinde bulunabileceğinizi unutmayın:
Bu işlevler eşzamansızdır ve durum değişikliği gerçekleşmez hemen teslim edebilirsiniz. Durum değişikliği isteğinde bulunduğunuzda akış, durum ilgili geçici durumlar:
- Başlatılıyor
- Duraklatılıyor
- Kızarmış yüz
- Durduruluyor
- Kapanma
Aşağıdaki durum şemasında sabit durumlar yuvarlak dikdörtgenler, geçici durumlar ise noktalı dikdörtgenler olarak gösterilmektedir.
Bu numara gösterilmese de close()
öğesini herhangi bir eyaletten çağırabilirsiniz
AAudio, durum değişiklikleri konusunda sizi uyarmak için geri çağırma sağlamaz. Bir özel
işlevi,
AAudioStream_waitForStateChange(stream, inputState, nextState, timeout)
, durum değişikliğini beklemek için kullanılabilir.
İşlev, durum değişikliğini kendiliğinden algılamaz ve
görebilirsiniz. İşlemin geçerli durumuna gelene kadar bekler
belirttiğiniz inputState
değerinden farklı.
Örneğin, duraklatma isteğinde bulunduktan sonra akış hemen
Duraklatma geçici durumuna geçebilir ve bir süre sonra Duraklatılmış duruma gelirsiniz (ancak bunu garanti edemeyiz.)
Duraklatma durumunu bekleyemeyeceğiniz için waitForStateChange()
işlevini kullanarak herhangi bir durumu bekleyebilirsiniz
hariç tutmayı unutmayın. Bunu şu şekilde yapabilirsiniz:
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ışın durumu Duraklatılmıyorsa (inputState
bunun
geçerli duruma sahipse işlev hemen geri döner. Aksi halde
engelleme işlemi yapılır.
işlevi döndüğünde, nextState
parametresi
akış şeklinde gösterilir.
Aynı tekniği, istek başlatma, durdurma veya temizleme çağrısından sonra kullanabilirsiniz.
girdiState olarak karşılık gelen geçici durumu kullanın. Arama
Yayından bu yana AAudioStream_close()
aradıktan sonra waitForStateChange()
kapanmaz silinir. AAudioStream_close()
adlı kişiyi aramayın
ve waitForStateChange()
başka bir ileti dizisinde çalışırken.
Okuma ve ses akışına yazma
Bir akış başlatıldıktan sonra verileri işlemenin iki yolu vardır:
- Yüksek öncelikli geri arama kullanın.
AAudioStream_read(stream, buffer, numFrames, timeoutNanos)
işlevlerini kullanma veAAudioStream_write(stream, buffer, numFrames, timeoutNanos)
. okuması veya yazması gerekir.
Belirtilen sayıda kare aktaran bir engelleme okuma veya yazma işlemi için zaman aşımını sıfırdan büyük olarak ayarlayın. Engellemeyen bir çağrı için zaman aşımını sıfır olarak ayarlayın. Bu durumda sonuç, aktarılan karelerin gerçek sayısıdır.
Girişi okuduğunuzda her iki girişin de doğru kare okundu. Değilse arabellek, aksama. Tamponu sıfırlarla doldurarak sessiz ayrılma:
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 içine veri yazarak veya sessize alarak akışın arabelleğini hazırlayabilirsiniz. Bu, timeNanos değeri sıfıra ayarlanmış, engelleyici olmayan bir çağrıda yapılmalıdır.
Arabellekteki veriler, AAudioStream_getDataFormat()
tarafından döndürülen veri biçimiyle eşleşmelidir.
Ses akışını kapatma
İşiniz bittiğinde akışı kapatın:
AAudioStream_close(stream);
Kapattığınız bir akışı, AAudio akışına dayalı herhangi bir işlevle kullanamazsınız.
Ses yayını bağlantısı kesildi
Aşağıdaki etkinliklerden biri gerçekleşirse ses akışının bağlantısı herhangi bir zamanda kesilebilir:
- İlişkili ses cihazı artık bağlı değilse (örneğin, kulaklık fişe takılı değilken).
- Dahili bir hata oluştu.
- Ses sistemi artık birincil ses cihazı değil.
Bir akışın bağlantısı kesildiğinde "Bağlantı kesildi" durumu gösterilir. ve AAudioStream_Write() veya diğer işlevleri yürütme girişimleri hata döndürür. Hata kodundan bağımsız olarak, bağlantısı kesilen bir akışı her zaman durdurmanız ve kapatmanız gerekir.
Veri geri çağırması kullanıyorsanız (doğrudan okuma/yazma yöntemlerinden biri yerine) akışın bağlantısı kesildiğinde dönüş kodu almazsınız. Böyle bir durumda bilgi almak için AAudioStream_errorCallback yazın fonksiyonunu kullanmanız ve AAudioStreamBuilder_setErrorCallback().
Bağlantının kesildiği bir hata geri arama ileti dizisinde size bildirilirse durdurma ve kapatma adımlarının başka bir ileti dizisinden yapılması gerekir. Aksi takdirde bir kilitlenme yaşayabilirsiniz.
Yeni bir canlı yayın açtığınızda ayarların farklı olabileceğini unutmayın. (ö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
Bir ses uygulamasının performansını, dahili arabelleklerini ayarlayarak ve özel yüksek öncelikli ileti dizilerini kullanarak optimize edebilirsiniz.
Gecikmeyi en aza indirmek için arabellekleri ayarlama
Ses, her ses cihazı için bir tane olmak üzere verileri, tuttuğu dahili arabelleklerden içeri ve dışarı aktarır.
Arabelleğin kapasitesi, bir arabelleğin barındırabileceği toplam veri miktarıdır. Şu numarayı arayabilirsiniz:
AAudioStreamBuilder_setBufferCapacityInFrames()
kapasiteyi ayarlayın. Yöntem, ayırabileceğiniz kapasiteyi cihazın izin verdiği maksimum değerle sınırlandırır. Tekliflerinizi otomatikleştirmek ve optimize etmek için
AAudioStream_getBufferCapacityInFrames()
tamponun gerçek kapasitesini doğrulayın.
Bir uygulamanın, bir tamponun kapasitesinin tamamını kullanması gerekmez. Ses, arabelleği ayarlayabileceğiniz bir boyuta kadar doldurur. Tamponun boyutu kapasitesinden büyük olamaz ve genellikle daha küçüktür. Arabellek boyutunu kontrol ederek doldurması gereken seri çekim sayısını belirler, böylece gecikmeyi kontrol edersiniz. Yöntemleri kullanma AAudioStreamBuilder_setBufferSizeInFrames()
ve
AAudioStreamBuilder_getBufferSizeInFrames()
tampon boyutuyla çalışmaktır.
Bir uygulama ses çaldığında arabelleğe yazar ve yazma tamamlanana kadar bloke eder. Ses, arabellekteki verileri ayrı ayrı patlamalar halinde okur. Her seri çekim birden fazla sayıda ses karesi içerir ve genellikle okunmakta olan arabelleğin boyutundan küçüktür. Sistem, seri çekim boyutunu ve hızını kontrol eder. Bu özellikler genellikle ses cihazının devresi tarafından belirlenir. Bir seri çekimin boyutunu veya patlama hızını değiştiremeseniz de içindeki seri işlem sayısına göre dahili arabelleğin boyutunu ayarlayabilirsiniz. Genel olarak, AAudioStream'inizin arabellek boyutu, bildirilen seri işlem boyutunun katı olduğunda en düşük gecikmeyi elde edersiniz.
Tampon boyutunu optimize etmenin bir yolu, büyük bir tamponla başlamak, düşüşler başlayana kadar yavaş yavaş azaltmak ve sonra tekrar yukarı çekmektir. Alternatif olarak, küçük bir tampon boyutuyla başlayabilirsiniz. Bu durumda, gereğinden az çalışırsa çıktı tekrar sorunsuz bir şekilde akana kadar arabellek boyutunu artırın.
Bu işlem çok hızlı bir şekilde, muhtemelen kullanıcı ilk sesi çalmadan önce gerçekleştirilebilir. Kullanıcının herhangi bir ses arızası duymaması için önce sessizliği kullanarak başlangıçtaki arabellek boyutlandırmasını gerçekleştirmek isteyebilirsiniz. Sistem performansı zaman içinde değişebilir (örneğin, kullanıcı uçak modunu kapatabilir). Arabellek ayarlaması, çok az ek yük getirdiğinden uygulamanız uygulama bir akışa veri okurken veya yazarken bunu sürekli olarak yapabilir.
Aşağıda bir tampon optimizasyon döngüsü örneği 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);
}
}
}
Bu tekniği, giriş akışı için arabellek boyutunu optimize etmek amacıyla kullanmanın bir avantajı yoktur. Giriş akışları mümkün olduğunca hızlı ilerler ve giriş miktarını korumaya çalışır. arabelleğe alınmış veri miktarını en aza indirmek ve ardından uygulama geçici olarak kesildiğinde bu verileri doldurmak.
Yüksek öncelikli geri arama kullanma
Uygulamanız normal bir iş parçacığındaki ses verilerini okuyor veya yazıyorsa bu veriler geçici olarak kesilmiş olabilir veya zamanlamada dalgalanmalar yaşayabilirsiniz. Bu durum, ses kesintilerine yol açabilir. Daha büyük arabellekler kullanmak bu tür arızalara karşı koruma sağlayabilir ancak büyük bir arabellekte ses gecikmesi de daha uzun sürer. Düşük gecikme gerektiren uygulamalar için ses yayını, uygulamanıza ve uygulamanızdan veri aktarmak için eşzamansız geri çağırma işlevini kullanabilir. AAudio, geri çağırmayı daha iyi performansa sahip daha yüksek öncelikli bir ileti dizisinde yürütür.
Geri çağırma işlevinde şu prototip bulunur:
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ış belirli aralıklarla geri çağırma işlevini yürüterek sonraki seri işlem için verileri nasıl elde edeceğini sorar.
Geri çağırma işlevi, tarafından çağrılmıştır. Geri çağırma bir giriş akışına aitse kodunuz AudioData arabelleğinde sağlanan veriler (üçüncü ses kaynağı olarak belirtilir) bağımsız değişkeni) kaldırın. Geri çağırma bir çıkış akışına aitse kodunuz arabelleğe alır.
Örneğin, geri çağırma işlevini kullanarak sürekli bir sinüs dalgası çıkışı üretebilirsiniz aşağıdaki gibidir:
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 kullanarak birden fazla yayın işlenebilir. Bir akışı ana akış olarak kullanabilirsiniz. Kullanıcı verilerindeki diğer akışlara işaretçiler iletin. Ana akış için bir geri çağırma kaydedin. Ardından, diğer yayınlarda engellemeyen G/Ç kullanın. Burada, bir giriş akışını çıkış akışına geçiren bir gidiş dönüş geri çağırma örneği verilmiştir. Ana çağrı akışı, çıkış akışıdır. Giriş akışı, kullanıcı verilerine dahil edilir.
Geri çağırma, giriş akışından, verileri çıkış akışının arabelleğine yerleştirerek engellemeyen bir okuma yapar:
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ılmıştır. Kod, çevirileri doğru şekilde işlediği sürece akışların biçimi uyuşmayabilir.
Performans modu ayarlanıyor
Her AAudioStream'de, uygulamanızın davranışı üzerinde büyük etkisi olan bir performans modu bulunur. Üç mod vardır:
AAUDIO_PERFORMANCE_MODE_NONE
varsayılan moddur. Gecikme ve güç tasarrufunu dengeleyen temel bir akış kullanır.AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
, daha az gecikme için daha küçük arabellekler 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 telafi eden bir veri yolu kullanır.
setPerformanceMode() komutunu çağırarak performans modunu seçebilirsiniz. ve getPerformanceMode() çağrısı yaparak mevcut modu keşfedebilirsiniz.
Düşük gecikme, uygulamanızda 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.
Uygulamanızda güçten tasarruf etmek, düşük gecikmeden daha önemliyse AAUDIO_PERFORMANCE_MODE_POWER_SAVING
kullanın.
Bu durum, akışlı ses veya MIDI dosya çalar gibi önceden oluşturulmuş müzikleri oynatan uygulamalar için geçerlidir.
AAudio'nun geçerli sürümünde mümkün olan en düşük gecikmeyi elde etmek için yüksek öncelikli geri çağırma ile birlikte AAUDIO_PERFORMANCE_MODE_LOW_LATENCY
performans modunu kullanmanız gerekir. Aşağıdaki örneği uygulayı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);
İş parçacığı güvenliği
AAudio API tamamen ileti dizisi için güvenli değildir. AAudio işlevlerinden bazılarını, aynı anda birden fazla iş parçacığından aynı anda çağıramazsınız. Bunun nedeni, AAudio'nun, ileti dizilerinin engellenmesine ve arızalara neden olabilecek sessizlikler kullanmaktan kaçınmasıdır.
Güvenliğiniz için AAudioStream_waitForStateChange()
numaralı telefonu aramayın veya aynı akışı iki farklı ileti dizisinden okuyup yazmayın. Benzer şekilde, başka bir ileti dizisinde okurken veya ona yazarken bir ileti dizisindeki akışı kapatmayın.
AAudioStream_getSampleRate()
ve AAudioStream_getChannelCount()
gibi akış ayarlarını döndüren aramalar mesaj dizisi açısından güvenlidir.
Şu görüşmeler de mesaj dizisi açısından güvenlidir:
AAudio_convert*ToText()
AAudio_createStreamBuilder()
AAudioStream_getTimestamp()
hariçAAudioStream_get*()
Bilinen sorunlar
- Android O DP2 sürümü HIZLI kanal kullanmadığından Write() engelleme işleminde ses gecikmesi yüksektir. Daha düşük gecikme elde etmek için geri çağırma yapın.
Ek kaynaklar
Daha fazla bilgi edinmek için aşağıdaki kaynaklardan yararlanın: