Ses

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.

  1. AAudioStreamBuilder oluşturun:

    AAudioStreamBuilder *builder;
    aaudio_result_t result = AAudio_createStreamBuilder(&builder);
    

  2. 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.

  3. AAudioStreamBuilder yapılandırıldığında bir akış oluşturmak için kullanın:

    AAudioStream *stream;
    result = AAudioStreamBuilder_openStream(builder, &stream);
    

  4. 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:

    AAudioStreamBuilder_setDeviceId() AAudioStream_getDeviceId()
    AAudioStreamBuilder_setDirection() AAudioStream_getDirection()
    AAudioStreamBuilder_setSharingMode() AAudioStream_getSharingMode()
    AAudioStreamBuilder_setSampleRate() AAudioStream_getSampleRate()
    AAudioStreamBuilder_setChannelCount() AAudioStream_getChannelCount()
    AAudioStreamBuilder_setFormat() AAudioStream_getFormat()
    AAudioStreamBuilder_setBufferCapacityInFrames() AAudioStream_getBufferCapacityInFrames()

  5. 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):

  • 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

Sesli Ses Yaşam Döngüsü

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:

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.

      Ses Arabelleğe Alma

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:

API Referansı

Codelab'ler

Videolar