Ses

AAudio, Android O sürümünde kullanıma sunulan yeni bir Android C API'sidir. Düşük gecikme süresi gerektiren yüksek performanslı ses uygulamaları için tasarlanmıştır. Uygulamalar, verileri okuyup akışlara yazarak AAudio ile iletişim kurar.

AAudio API, tasarımı gereği çok azdır ve şu işlevleri gerçekleştirmez:

  • Ses cihazı numaralandırması
  • Ses uç noktaları arasında otomatik yönlendirme
  • Dosya G/Ç'si
  • Sıkıştırılmış sesin kodunu çözme
  • Tek bir geri aramada tüm girişlerin/akışların otomatik olarak sunulması.

Başlangıç

AAudio'yu C++ kodundan çağırabilirsiniz. Uygulamanıza AAudio özelliği eklemek için AAudio.h başlık dosyasını ekleyin:

#include <aaudio/AAudio.h>

Ses akışları

AAudio, uygulamanız ile Android cihazınızdaki ses giriş ve çıkışları arasında ses verilerini taşır. Uygulamanız, AAudioStream yapısıyla temsil edilen ses akışlarından okuma ve yazma yoluyla veri aktarır ve dışa aktarır. Okuma/yazma çağrıları engelliyor veya engellenmiyor olabilir.

Bir akış aşağıdaki şekilde tanımlanır:

  • Akıştaki verilerin kaynağı veya havuzu olan ses cihazı.
  • Bir yayının, normalde birden fazla yayın arasında paylaşılabilecek bir ses cihazına özel erişime sahip 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ı, kesintisiz bir 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ı (yerleşik 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 bilgileri döndürür.

Her ses cihazının Android cihazda 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 birincil cihazı seçmesine izin vererek kendi başınıza bir cihaz belirtmeyi tercih edebilirsiniz.

Bir akışa bağlı ses cihazı, yayının giriş mi yoksa çıkış için mi olduğunu belirler. Bir akış, verileri yalnızca tek bir yönde taşıyabilir. Bir akışı tanımlarken yönünü de ayarlarsınız. Bir yayın açtığınızda Android, ses cihazı ile yayın yönünün uyumlu olup olmadığını kontrol eder.

Paylaşım modu

Bir akışın paylaşım modu vardır:

  • AAUDIO_SHARING_MODE_EXCLUSIVE, yayının ses cihazına özel erişime sahip olduğu anlamına gelir ve cihaz başka herhangi bir ses akışı tarafından kullanılamaz. Ses cihazı 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 olabilir ancak bağlantıları kesilme ihtimali de daha yüksektir. Diğer uygulamaların cihaza erişebilmesi için özel akışları artık ihtiyacınız kalmadığında hemen kapatmalısınız. Ö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. AAudio, aynı cihaza atanmış tüm paylaşılan akışları karıştırır.

Paylaşım modunu, yayın oluştururken açıkça ayarlayabilirsiniz. Varsayılan olarak paylaşım modu SHARED şeklindedir.

Ses biçimi

Bir akıştan geçen veriler her zamanki dijital ses özelliklerine sahiptir. Bunlar aşağıdaki gibidir:

  • Örnek veri biçimi
  • Kanal sayısı (kare başına örnek)
  • Örnek hızı

AAudio şu örnek biçimlere izin verir:

ses_biçimi_t C veri türü Notlar
AAUDIO_FORMAT_PCM_I16 int16_t yaygın 16 bit örnekler, Q0.15 biçimi
AAUDIO_FORMAT_PCM_FLOAT kayan -1,0 - +1,0
AAUDIO_FORMAT_PCM_I24_PAKETLİ uint8_t (3'lü gruplar halinde) paketli 24 bit örnekler, Q0.23 biçimi
AAUDIO_FORMAT_PCM_I32 int32_t yaygın 32 bit örnekler, Q0.31 biçimi
SESLİ_FORMAT_IEC61937 uint8_t HDMI veya S/PDIF geçişi için IEC61937'ye sarmalanmış sıkıştırılmış ses

Belirli bir örnek biçim isterseniz akış, biçim cihaz için optimum olmasa bile bu biçimi kullanır. Bir örnek biçim belirtmezseniz AAudio en uygun biçimi seçer. Akış açıldıktan sonra örnek veri biçimini sorgulamanız ve gerekirse verileri dönüştürmeniz gerekir. Örnek:

aaudio_format_t dataFormat = AAudioStream_getDataFormat(stream);
//... later
if (dataFormat == AAUDIO_FORMAT_PCM_I16) {
     convertFloatToPcm16(...)
}

Ses akışı oluşturma

AAudio kitaplığı, geliştirici tasarım kalıbı uygular ve AAudioStreamBuilder sağlar.

  1. AAudioStreamBuilder oluşturun:

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

  2. Yayın parametrelerine karşılık gelen oluşturucu işlevlerini kullanarak ses akışı yapılandırmasını oluşturucuda ayarlayın. Şu isteğe bağlı ayarlama 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ğerler veya aralık dışında 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 ayarlayabilir veya parametreyi hiç belirtmeyerek ya da AAUDIO_UNSPECIFIED olarak ayarlayarak sistemin en uygun değeri atamasına izin verebilirsiniz.

    Güvenliğiniz için, aşağıdaki 4. adımda açıklandığı gibi oluşturduktan sonra ses akışının durumunu kontrol edin.

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

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

  4. Akışı oluşturduktan sonra yapılandırmasını doğrulayın. Örnek biçimi, örnek hızı veya kare başına örnekler belirtirseniz bunlar değişmez. Paylaşım modu veya arabellek kapasitesi belirttiyseniz yayının ses cihazının ve çalıştığı Android cihazın özelliklerine bağlı olarak bunlar değişebilir. İyi bir savunma programlaması söz konusu olduğunda, akışı kullanmadan önce yapılandırmasını kontrol etmeniz gerekir. Her bir oluşturucu ayarına karşılık gelen akış ayarını almak için çeşitli işlevler 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 kaydedip gelecekte daha fazla canlı yayın oluşturmak için yeniden kullanabilirsiniz. Ancak, artık kullanmayı düşünmüyorsanız hesabı silmelisiniz.

    AAudioStreamBuilder_delete(builder);
    

Ses akışı kullanma

Durum geçişleri

AAudio akışı genellikle beş sabit durumdan birindedir (Hata durumu, Bağlantı kesildi, bu bölümün sonunda açıklanmıştır):

  • Başlatıldı
  • Duraklatıldı
  • Kızarmış yüz
  • Durduruldu

Bir akıştan veri akışı yalnızca akış Başlatılmış durumdayken gerçekleşir. Bir akışı eyaletler arasında taşımak için eyalet geçişi isteyen 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);

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 hemen gerçekleşmez. Durum değişikliği isteğinde bulunduğunuzda akış karşılık gelen geçici durumlardan birini taşır:

  • Başlatılıyor
  • Duraklatma
  • Kızarmış yüz
  • Durduruluyor
  • Kapanma

Aşağıdaki durum şemasında sabit durumlar yuvarlatılmış dikdörtgenler, geçici durumlar da noktalı dikdörtgenler olarak gösterilmiştir. close() gösterilmiyor olsa da herhangi bir eyaletten sesli arama yapabilirsiniz

AAudio Yaşam Döngüsü

AAudio, durum değişiklikleri konusunda sizi uyarmak için geri çağırma sağlamaz. Özel bir işlev olan AAudioStream_waitForStateChange(stream, inputState, nextState, timeout), durum değişikliğini beklemek için kullanılabilir.

İşlev, kendi başına bir durum değişikliği algılamaz ve belirli bir durum için beklemez. Geçerli durum, belirttiğiniz inputState değerinden farklı olana kadar bekler.

Örneğin, duraklatma isteğinde bulunulduğunda, bir akış hemen Duraklatma geçici durumuna geçmeli ve bir süre sonra Duraklatılmış duruma gelmelidir. Ancak bunun garantisini veremeyiz. Duraklatılmış durumunu bekleyemeyeceğiniz için Duraklatma dışındaki herhangi bir durumu beklemek için waitForStateChange() öğesini kullanın. Bu işlem şu şekilde yapılır:

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 Duraklatma (çağrı sırasında geçerli durum olduğunu varsaydığımız inputState) değilse işlev hemen döndürülür. Aksi takdirde, durum "Duraklatma" durumuna geçene veya zaman aşımı süresi dolana kadar uygulama engellenir. İşlev döndüğünde, nextState parametresi akışın mevcut durumunu gösterir.

Aynı tekniği, istek başlatma, durdurma veya boşaltma işlemlerini çağırdıktan sonra, girdi durumu olarak ilgili geçici durumu kullanarak kullanabilirsiniz. Akış kapandıktan hemen sonra silineceğinden AAudioStream_close() çağrısından sonra waitForStateChange() çağrısı yapmayın. Ayrıca, waitForStateChange() başka bir iş parçacığında çalışırken AAudioStream_close() işlevini çağırmayın.

Bir ses akışında okuma ve yazma

Bir akış başlatıldıktan sonra verileri işlemenin iki yolu vardır:

Belirtilen sayıda kareyi aktaran engelleme okuma veya yazma için zaman aşımıNanos'u sıfırdan büyük bir değere ayarlayın. Engellemeyen bir çağrı için zaman aşımıNanos'u sıfır olarak ayarlayın. Bu durumda sonuç, aktarılan gerçek kare sayısıdır.

Girişi okurken, doğru kare sayısının okunduğunu doğrulamanız gerekir. Aksi takdirde arabellek, ses hatasına neden olabilecek bilinmeyen veriler içerebilir. Sessiz bir düşüş oluşturmak için tamponu 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 arabelleğe veri yazarak veya sessize alarak akış arabelleğini doldurabilirsiniz. Bu, zaman aşımıNanos değeri sıfır olarak ayarlanmış ve engellemeyen 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

Bir akışı kullanmayı bitirdiğinizde, akışı kapatın:

AAudioStream_close(stream);

Bir akışı kapattıktan sonra AAudio akış tabanlı herhangi bir işlevle kullanamazsınız.

Ses akışı kesildi

Aşağıdaki etkinliklerden biri gerçekleştiğinde ses akışının bağlantısı herhangi bir zamanda kesilebilir:

  • İlişkili ses cihazı artık bağlı değildir (örneğin, kulaklık takılı değilken).
  • Dahili olarak bir hata oluşur.
  • Ses cihazı artık birincil ses cihazı değildir.

Bir akışın bağlantısı kesildiğinde, durumu "Bağlantı kesildi" olarak değişir ve AAudioStream_write() veya başka 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 durdurup kapatmalısınız.

Veri geri çağırması kullanıyorsanız (doğrudan okuma/yazma yöntemlerinden birinin aksine) akışın bağlantısı kesildiğinde herhangi bir dönüş kodu almazsınız. Bu durumda bilgi almak için bir AAudioStream_errorCallback işlevi yazın ve AAudioStreamBuilder_setErrorCallback() yöntemini kullanarak kaydedin.

Bağlantının kesildiği bir hata geri çağırma iş parçacığında bildirilirse akışın durdurulması ve kapatılması başka bir iş parçacığından gerçekleştirilmelidir. Aksi takdirde, bir kilitlenme ile karşılaşabilirsiniz.

Yeni bir akış açarsanız bu akış orijinal akıştan farklı ayarlara sahip olabilir (örneğin, 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 yüksek öncelikli özel iş parçacıklarını kullanarak optimize edebilirsiniz.

Gecikmeyi en aza indirmek için arabellekleri ayarlama

AAudio, her ses cihazı için bir tane olmak üzere sakladığı dahili arabelleklere veri aktarır.

Tamponun kapasitesi, bir tamponun barındırabileceği toplam veri miktarıdır. Kapasiteyi ayarlamak için AAudioStreamBuilder_setBufferCapacityInFrames() numarasını arayabilirsiniz. Bu yöntem, atayabileceğiniz kapasiteyi cihazın izin verdiği maksimum değere sınırlar. Tamponun gerçek kapasitesini doğrulamak için AAudioStream_getBufferCapacityInFrames() kullanın.

Bir uygulamanın, tamponun kapasitesinin tamamını kullanması gerekmez. Ses, ayarlayabileceğiniz boyuta kadar bir arabelleği doldurur. Tamponun boyutu kapasitesinden 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ı belirleyebilir ve böylece gecikmeyi kontrol edebilirsiniz. Tampon boyutuyla çalışmak için AAudioStreamBuilder_setBufferSizeInFrames() ve AAudioStreamBuilder_getBufferSizeInFrames() yöntemlerini kullanın.

Bir uygulama ses çaldığında, bir arabelleğe yazar ve yazma işlemi tamamlanana kadar engeller. AAudio, arabelleğe parçalar halinde ayrı ayrı okur. Her seri çekim birden fazla sayıda ses karesi içerir ve genellikle okunan arabelleğin boyutundan daha küçüktür. Seri çekim boyutu ve hızı sistem tarafından kontrol edilir. Bu özellikler genellikle ses cihazının devresi tarafından belirlenir. Seri çekimin boyutunu veya seri çekim hızını değiştiremezsiniz ancak dahili arabelleğin boyutunu içerdiği seri işlem sayısına göre ayarlayabilirsiniz. Genellikle en düşük gecikme süresini, AAudioStream'inizin arabellek boyutu bildirilen seri işlem boyutunun katıysa elde edersiniz.

      Ses Arabelleğe Alma

Tampon boyutunu optimize etmenin bir yolu, büyük bir tamponla başlamak ve azalanlar başlayana kadar kademeli olarak azaltmak, ardından tekrar yukarı çekmektir. Alternatif olarak, küçük bir arabellek boyutuyla başlayabilirsiniz. Bu durum düşüşe neden olursa arabellek boyutunu çıktı tekrar temiz bir şekilde akışkan hale gelene kadar artırın.

Bu işlem çok hızlı bir şekilde, muhtemelen kullanıcı ilk sesi çalmadan önce gerçekleşebilir. İlk arabellek boyutlandırmasını ilk olarak sessiz modda yapmak isteyebilirsiniz, böylece kullanıcı herhangi bir ses hatası duymaz. Sistem performansı zaman içinde değişebilir (örneğin, kullanıcı uçak modunu kapatabilir). Arabellek ayarlama çok az ek yük getirdiğinden, uygulama bir akışa veri okurken veya veri yazarken uygulamanız bunu sürekli olarak yapabilir.

Aşağıda, tampon optimizasyon döngüsüne bir ö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);
        }
    }
}

Giriş akışı için arabellek boyutunu optimize etmek üzere bu tekniği kullanmanın hiçbir avantajı yoktur. Giriş akışları mümkün olduğunca hızlı çalışır. Arabelleğe alınan veri miktarını en düşük düzeyde tutmaya çalışır ve daha sonra uygulama devre dışı bırakıldığında dolar.

Yüksek öncelikli geri arama kullanma

Uygulamanız normal bir iş parçacığındaki ses verilerini okuyor veya yazıyorsa uygulama geçici olarak kesilmiş veya zamanlama dalgalanması yaşayabilir. Bu durum, seste bozulmalara neden olabilir. Daha büyük arabelleklerin kullanılması bu tür arızalara karşı koruma sağlayabilir, ancak büyük bir arabellek de daha uzun ses gecikmesine neden olur. Düşük gecikme gerektiren uygulamalarda, ses akışları, uygulamanızdan ve uygulamanızdan veri aktarmak için eşzamansız bir geri çağırma işlevi kullanabilir. AAudio, geri çağırmayı daha iyi performansa sahip, daha yüksek öncelikli bir iş parçacığında yürütür.

Geri çağırma işlevi aşağıdaki 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ış yapısını kullanın:

AAudioStreamBuilder_setDataCallback(builder, myCallback, myUserData);

En basit senaryoda akış, bir sonraki seri çekim için veri toplamak amacıyla geri çağırma işlevini periyodik olarak yürütür.

Geri çağırma işlevi, kendisini çağıran akış üzerinde bir okuma veya yazma işlemi gerçekleştirmemelidir. Geri çağırma bir giriş akışına aitse kodunuz, audioData arabelleğinde (üçüncü bağımsız değişken olarak belirtilir) sağlanan verileri işlemelidir. Geri çağırma bir çıkış akışına aitse kodunuz, verileri arabelleğe yerleştirmelidir.

Örneğin, sürekli olarak şunun gibi bir sinüs dalgası çıkışı oluşturmak için geri çağırmayı 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 kullanarak birden fazla akış işlenebilir. Bir akışı ana akış olarak kullanabilir ve kullanıcı verilerindeki diğer akışlara işaretçiler aktarabilirsiniz. Ana akış için bir geri çağırma kaydedin. Ardından diğer akışlarda engellemeyen G/Ç kullanın. Burada, bir giriş akışını çıkış akışına geçiren gidiş dönüş geri çağırma örneği gösterilmektedir. Ana çağrı akışı, çıkış akışıdır. Giriş akışı, kullanıcı verilerine dahil edilir.

Geri çağırma, verileri çıkış akışının arabelleğine yerleştiren giriş akışından engellenmeyen 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 düzgün şekilde işlediği sürece akışların biçimi uyumsuz olabilir.

Performans modunu ayarlama

Her AAudioStream'in, uygulamanızın davranışı üzerinde büyük etkisi olan bir performans modu vardır. Üç mod vardır:

  • AAUDIO_PERFORMANCE_MODE_NONE varsayılan moddur. Gecikme ve güç tasarruflarını dengeleyen temel bir akış kullanır.
  • AAUDIO_PERFORMANCE_MODE_LOW_LATENCY, gecikmenin azaltılması 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() çağrısı yaparak performans modunu seçebilir, getPerformanceMode() yöntemini çağırarak geçerli modu keşfedebilirsiniz.

Düşük gecikme, uygulamanızda güç tasarrufundan daha önemliyse AAUDIO_PERFORMANCE_MODE_LOW_LATENCY kullanın. Bu, oyunlar veya klavye sentezleyicileri gibi çok etkileşimli uygulamalar için yararlıdır.

Uygulamanızda düşük gecikme süresine kıyasla güç tasarrufu daha önemliyse AAUDIO_PERFORMANCE_MODE_POWER_SAVING kullanın. Bu durum, akışlı ses veya MIDI dosya oynatıcılar gibi önceden oluşturulmuş müzikleri çalan uygulamalar için sık karşılaşılan bir durumdur.

AAudio'nun mevcut sürümünde mümkün olan en düşük gecikmeyi elde etmek için yüksek öncelikli geri arama ile birlikte AAUDIO_PERFORMANCE_MODE_LOW_LATENCY performans modunu kullanmanız gerekir. Şu örneği izleyin:

// 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 açısından güvenli değildir. AAudio işlevlerinin bazılarını, bir defada birden fazla iş parçacığından eş zamanlı olarak çağıramazsınız. Bunun nedeni, AAudio'nun zaman eşitlemeleri kullanmaktan kaçınmasıdır. Bu durum, iş parçacığı öncelikli olarak bölünmesine ve sorunlara neden olabilir.

Güvenliğiniz için AAudioStream_waitForStateChange() adlı kişiyi aramayın veya iki farklı mesaj dizisinden aynı akışta okuma ya da yazma işlemi yapmayın. Benzer şekilde, bir ileti dizisindeki bir akışı, başka bir ileti dizisinde okurken veya yazarken kapatmayın.

AAudioStream_getSampleRate() ve AAudioStream_getChannelCount() gibi yayın ayarlarına geri dönen aramalar mesaj dizilerinde güvenlidir.

Şu aramalar da 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ü FAST parça kullanmadığından, yazma() işlevi engellenirken ses gecikmesi yüksektir. Gecikme süresini azaltmak için geri çağırma yöntemini kullanın.

Ek kaynaklar

Daha fazla bilgi edinmek için aşağıdaki kaynaklardan yararlanın:

API Referansı

Codelab uygulamaları

Videolar