Ses hata ayıklama

Bu makalede, Android sesinde hata ayıklamayla ilgili bazı ipuçları ve püf noktaları açıklanmaktadır.

Lavabo

"Tee sink", yalnızca özel derlemelerde kullanılabilen bir AudioFlinger hata ayıklama özelliğidir. Bu özellik, daha sonra analiz etmek üzere son sesin kısa bir parçasını saklar. Bu sayede, gerçekte oynatılan veya kaydedilen ile beklenen arasında karşılaştırma yapılabilir.

Gizlilik için tee alıcısı hem derleme hem de çalışma zamanında varsayılan olarak devre dışıdır. Tee sink'i kullanmak için yeniden derleyerek ve bir mülk ayarlayarak etkinleştirmeniz gerekir. Hata ayıklama işlemini tamamladıktan sonra bu özelliği devre dışı bıraktığınızdan emin olun. Tee sink, üretim derlemelerinde etkin bırakılmamalıdır.

Bu bölümdeki talimatlar Android 7.x ve sonraki sürümler içindir. Android 5.x ve 6.x için /data/misc/audioserver ifadesini /data/misc/media ile değiştirin. Ayrıca, userdebug veya eng derlemesi kullanmanız gerekir. userdebug derlemesi kullanıyorsanız Verity'yi şu şekilde devre dışı bırakın:

adb root && adb disable-verity && adb reboot

Derleme zamanı kurulumu

  1. cd frameworks/av/services/audioflinger
  2. Configuration.h öğesini düzenleyin.
  3. #define TEE_SINK için yorumu kaldırın.
  4. libaudioflinger.so'ü yeniden oluşturun.
  5. adb root
  6. adb remount
  7. Yeni libaudioflinger.so dosyasını cihazın /system/lib dosyasına gönderin veya senkronize edin.

Çalışma zamanı kurulumu

  1. adb shell getprop | grep ro.debuggable
    Çıkışın şu şekilde olduğunu onaylayın: [ro.debuggable]: [1]
  2. adb shell
  3. ls -ld /data/misc/audioserver

    Çıktının şu şekilde olduğunu onaylayın:

    drwx------ media media ... media
    

    Dizin yoksa aşağıdaki gibi oluşturun:

    mkdir /data/misc/audioserver
    chown media:media /data/misc/audioserver
    
  4. echo af.tee=# > /data/local.prop
    af.tee değeri aşağıda açıklanan bir sayıdır.
  5. chmod 644 /data/local.prop
  6. reboot

af.tee mülkünün değerleri

af.tee değeri, özellik başına bir tane olmak üzere birkaç bitin toplamını ifade eden 0 ile 7 arasında bir sayıdır. Her bitin kısa bir açıklamasını görmek için AudioFlinger.cpp dosyasının AudioFlinger::AudioFlinger() satırına bakın:

  • 1 = giriş
  • 2 = FastMixer çıkışı
  • 4 = Parça başına AudioRecord ve AudioTrack

Henüz derin arabelleğe alma veya normal karıştırıcı için bit yok ancak "4" değerini kullanarak benzer sonuçlar elde edebilirsiniz.

Verileri test etme ve edinme

  1. Ses testinizi çalıştırın.
  2. adb shell dumpsys media.audio_flinger
  3. dumpsys çıkışında şuna benzer bir satır arayın:
    tee copied to /data/misc/audioserver/20131010101147_2.wav
    Bu bir PCM .wav dosyasıdır.
  4. Ardından, ilgilendiğiniz adb pull /data/misc/audioserver/*.wav dosyaları; kanala özgü dökümü dosya adlarının dumpsys çıkışında görünmediğini ancak kanal kapatıldığında /data/misc/audioserver'a kaydedilmeye devam ettiğini unutmayın.
  5. Başkalarıyla paylaşmadan önce gizlilik sorunları açısından döküm dosyalarını inceleyin.

Öneriler

Daha faydalı sonuçlar için aşağıdaki fikirleri deneyin:

  • Test çıkışındaki kesintileri azaltmak için dokunma seslerini ve tuş tıklamalarını devre dışı bırakın.
  • Tüm sesleri en üst düzeye çıkarın.
  • Testinizle ilgili olmayan, ses çıkaran veya mikrofondan kayıt yapan uygulamaları devre dışı bırakın.
  • Parçaya özgü dökümler yalnızca parça kapatıldığında kaydedilir. Parçaya özgü verilerini dökmek için bir uygulamayı zorla kapatmanız gerekebilir.
  • dumpsys işlemini testten hemen sonra yapın. Kayıt alanı sınırlıdır.
  • Döküm dosyalarınızı kaybetmemek için düzenli olarak barındırıcınıza yükleyin. Yalnızca sınırlı sayıda dökümü dosya saklanır. Bu sınıra ulaşıldığında eski dökümler kaldırılır.

Geri yükle

Yukarıda belirtildiği gibi, T lavabo özelliği etkin bırakılmamalıdır. Derlemenizi ve cihazınızı aşağıdaki gibi geri yükleyin:

  1. Kaynak kodundaki değişiklikleri Configuration.h olarak geri alın.
  2. libaudioflinger.so'ü yeniden oluşturun.
  3. Restore edilen libaudioflinger.so'yi cihazın /system/lib ile senkronize edin veya cihaza gönderin.
  4. adb shell
  5. rm /data/local.prop
  6. rm /data/misc/audioserver/*.wav
  7. reboot

media.log

ALOGx makroları

Android SDK'sındaki standart Java dili günlük kaydı API'si android.util.Log'dur.

Android NDK'daki ilgili C dili API'si __android_log_print <android/log.h> içinde tanımlanmıştır.

Android çerçevesinin yerel bölümünde ALOGE, ALOGW, ALOGI, ALOGV vb. adlı makroları tercih ederiz. Bunlar <utils/Log.h> içinde tanımlanır ve bu makale kapsamında toplu olarak ALOGx olarak adlandırılır.

Bu API'lerin tümü kullanımı kolay ve iyi anlaşılır olduğu için Android platformunda yaygın olarak kullanılır. Özellikle AudioFlinger ses sunucusunu içeren mediaserver işlemi, ALOGx'yi yoğun şekilde kullanır.

Bununla birlikte, ALOGx ve arkadaşlarla ilgili bazı sınırlamalar vardır:

  • "Günlük spam'ine" karşı hassastırlar: Günlük arabelleği paylaşılan bir kaynak olduğundan, alakasız günlük girişleri nedeniyle kolayca taşabilir ve bu da bilgilerin kaçırılmasına neden olabilir. ALOGV varyantı varsayılan olarak derleme zamanında devre dışıdır. Ancak etkinleştirilirse günlük spam'e neden olabilir.
  • Temel çekirdek sistem çağrıları engellenebilir. Bu da öncelik tersine çevrilmesine ve dolayısıyla ölçüm kesintilerine ve yanlışlıklarına neden olabilir. Bu durum, FastMixer ve FastCapture gibi zaman açısından kritik olan mesaj dizileri için özellikle önemlidir.
  • Günlük spam'ini azaltmak için belirli bir günlük devre dışı bırakılırsa bu günlük tarafından yakalanacak tüm bilgiler kaybolur. Belirli bir günlüğün ilgi çekici olduğu anlaşıldıktan sonra günlüğü geriye dönük olarak etkinleştirmek mümkün değildir.

NBLOG, media.log ve MediaLogService

NBLOG API'leri ve ilişkili media.logişlemi ile MediaLogServicehizmeti birlikte medya için daha yeni bir günlük kaydı sistemi oluşturur ve özellikle yukarıdaki sorunları gidermek için tasarlanmıştır. Üçünü de belirtmek için "media.log" terimini gevşek bir şekilde kullanacağız ancak NBLOG, C++ günlük kaydı API'sidir, media.log bir Linux işlem adıdır ve MediaLogService, günlükleri incelemek için kullanılan bir Android bağlayıcı hizmetidir.

media.log "zaman çizelgesi", göreceli sıralaması korunan bir günlük girişi dizisidir. Her ileti dizisinin kendi zaman çizelgesini kullanması gerekir.

Avantajlar

media.log sisteminin avantajları şunlardır:

  • Gerekmediği sürece ana günlükte spam oluşturmaz.
  • mediaserver kilitlendiğinde veya donduğunda bile incelenebilir.
  • Zaman çizelgesi başına engelleme yapmaz.
  • Performans üzerinde daha az etki sunar. (Elbette hiçbir günlük kaydı şekli tamamen rahatsız edici değildir.)

Mimari

Aşağıdaki şemada, media.log kullanılmadan önce mediaserver sürecinin init süreciyle ilişkisi gösterilmektedir:

media.log öncesi mimari

Şekil 1. media.log öncesi mimari

Önemli noktalar:

  • init forks ve execs mediaserver.
  • init, mediaserver'un sona erdiğini algılar ve gerekirse yeniden çatallanır.
  • ALOGx günlük kaydı gösterilmiyor.

Aşağıdaki şemada, media.log mimariye eklendikten sonra bileşenlerin yeni ilişkisi gösterilmektedir:

media.log&#39;dan sonra mimari

Şekil 2. media.log'dan sonra mimari

Önemli değişiklikler:

  • İstemciler, günlük girişleri oluşturmak ve bunları paylaşılan bellekteki dairesel bir arabelleğe eklemek için NBLOG API'yi kullanır.
  • MediaLogService, dairesel arabelleğin içeriğini dilediğinde dökebilir.
  • Dairesel tampon, paylaşılan bellekte bozulma olması durumunda MediaLogService'ün kilitlenmemesi ve bozulmadan etkilenmeyen tamponun bir kısmını yine de dökmeye devam edebilmesi için tasarlanmıştır.
  • Dairesel arabellek, hem yeni girişler yazmak hem de mevcut girişleri okumak için engellenmez ve kilitlenmez.
  • Dairesel arabelleğe yazmak veya bu arabellekten okumak için çekirdek sistem çağrısı gerekmez (isteğe bağlı zaman damgalarından başka).

Kullanım yeri

Android 4.4'ten itibaren AudioFlinger'da media.log sistemini kullanan yalnızca birkaç günlük noktası vardır. Yeni API'lerin kullanımı ALOGx kadar kolay olmasa da çok da zor değildir. Yeni günlük kaydı sistemini, gerekli olduğu durumlarda kullanmanızı öneririz. Özellikle, FastMixer ve FastCapture gibi sık, düzenli olarak ve engellemeden çalışması gereken AudioFlinger iş parçacıkları için önerilir.

Nasıl kullanılır?

Günlük ekleme

Öncelikle kodunuza günlükler eklemeniz gerekir.

FastMixer ve FastCapture mesaj dizilerinde aşağıdaki gibi bir kod kullanın:

logWriter->log("string");
logWriter->logf("format", parameters);
logWriter->logTimestamp();

Bu NBLog zaman çizelgesi yalnızca FastMixer ve FastCapture ileti dizileri tarafından kullanıldığı için birbirini hariç tutma işlemine gerek yoktur.

Diğer AudioFlinger mesaj dizilerinde mNBLogWriter kullanın:

mNBLogWriter->log("string");
mNBLogWriter->logf("format", parameters);
mNBLogWriter->logTimestamp();

FastMixer ve FastCapture dışındaki mesaj dizileri için mesaj dizisinin NBLog zaman çizelgesi hem mesaj dizisi hem de bağlayıcı işlemleri tarafından kullanılabilir. NBLog::Writer, zaman çizelgesi başına herhangi bir gizli karşılıklı hariç tutma sağlamaz. Bu nedenle, tüm günlüklerin iş parçacığının mLock mutex'inin tutulduğu bir bağlamda gerçekleştiğinden emin olun.

Günlükleri ekledikten sonra AudioFlinger'ı yeniden derleyin.

Dikkat: Zaman çizelgeleri tasarım gereği kilitli mülkleri atladığından, zaman çizelgesi güvenliğini sağlamak için her iş parçacığı için ayrı bir NBLog::Writer zaman çizelgesi gerekir. Birden fazla iş parçacığının aynı zaman çizelgesini kullanmasını istiyorsanız mevcut bir mutex ile koruyabilirsiniz (mLock için yukarıda açıklandığı gibi). Alternatif olarak, NBLog::Writer yerine NBLog::LockedWriter sarmalayıcısını kullanabilirsiniz. Ancak bu, bu API'nin en önemli avantajını (engellemesiz davranışı) ortadan kaldırır.

NBLog API'sinin tamamını frameworks/av/include/media/nbaio/NBLog.h adresinde bulabilirsiniz.

media.log dosyasını etkinleştirme

media.log varsayılan olarak devre dışıdır. Yalnızca ro.test_harness mülkü 1 olduğunda etkindir. Bu özelliği şu şekilde etkinleştirebilirsiniz:

adb root
adb shell
echo ro.test_harness=1 > /data/local.prop
chmod 644 /data/local.prop
reboot

Yeniden başlatma sırasında bağlantı kesilir. Bu nedenle:

adb shell
ps media komutu artık iki işlem gösterir:
  • media.log
  • mediaserver

mediaserver işleminin kimliğini daha sonra kullanmak üzere not edin.

Zaman çizelgelerini görüntüleme

Dilediğiniz zaman manuel olarak günlük dökümü isteğinde bulunabilirsiniz. Bu komut, etkin ve son zaman çizelgelerindeki günlükleri gösterir ve ardından temizler:

dumpsys media.log

Zaman çizelgelerinin tasarım gereği bağımsız olduğunu ve zaman çizelgelerini birleştirme olanağı olmadığını unutmayın.

Mediaserver'ın kapanmasından sonra günlükleri kurtarma

Şimdi mediaserver işlemini sonlandırmayı deneyin: kill -9 #. #, daha önce not ettiğiniz işlem kimliğidir. Ana logcat bölümünde, kilitlenmeye yol açan tüm günlükleri gösteren media.logdump dosyasını görürsünüz.

dumpsys media.log