Üç Boyutlu Ses

Uzamsal ses, kullanıcılarınızı aksiyonun merkezine yerleştiren ve içeriğinizin daha gerçekçi duyulmasını sağlayan sürükleyici bir ses deneyimidir. Ses, surround ses kurulumuna benzer şekilde çoklu hoparlör efekti oluşturmak için "uzamsallaştırılır" ancak bu efekt kulaklıklar aracılığıyla sağlanır.

Örneğin, bir filmde araba sesi kullanıcının arkasından başlayıp ileri doğru hareket ederek uzaklaşabilir. Görüntülü sohbette sesler ayrılıp kullanıcının etrafına yerleştirilebilir. Böylece, konuşmacıları belirlemek kolaylaşır.

İçeriğinizde desteklenen bir ses biçimi kullanılıyorsa Android 13'ten (API düzeyi 33) itibaren uygulamanıza uzamsal ses ekleyebilirsiniz.

Özelliklerle ilgili sorgu

Cihazın uzamsallaştırma özelliklerini ve davranışını sorgulamak için Spatializer sınıfını kullanın. AudioManager'den Spatializer örneğini alarak başlayın:

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

Spatializer aldıktan sonra, cihazın uzamsallaştırılmış ses çıkışı yapabilmesi için geçerli olması gereken dört koşulu kontrol edin:

Ölçütler Kontrol Et
Cihaz, uzamsallaştırmayı destekliyor mu? getImmersiveAudioLevel(), SPATIALIZER_IMMERSIVE_LEVEL_NONE değil
Uzamsallaştırma özelliği var mı?
Kullanılabilirlik, mevcut ses çıkışı yönlendirmesiyle uyumluluğa bağlıdır.
isAvailable(): true
Üç boyutlu ses etkin mi? isEnabled(): true
Belirli parametrelere sahip bir ses parçası uzamsallaştırılabilir mi? canBeSpatialized(): true

Örneğin, mevcut ses parçası için uzamsallaştırma kullanılamıyorsa veya ses çıkışı cihazında tamamen devre dışı bırakılmışsa bu koşullar karşılanmayabilir.

Baş takibi

Desteklenen kulaklıklarla platform, kullanıcının kafa konumuna göre sesin uzamsallaştırılmasını ayarlayabilir. Mevcut ses çıkışı yönlendirmesi için kafa hareketi izleme cihazının kullanılıp kullanılamadığını kontrol etmek üzere isHeadTrackerAvailable() işlevini çağırın.

Uyumlu içerik

Spatializer.canBeSpatialized() Belirli özelliklere sahip sesin, mevcut çıkış cihazı yönlendirmesiyle uzamsallaştırılıp uzamsallaştırılamayacağını gösterir. Bu yöntemde, her ikisi de aşağıda daha ayrıntılı olarak açıklanan bir AudioAttributes ve bir AudioFormat kullanılır.

AudioAttributes

AudioAttributes nesnesi, bir ses akışının (ör. oyun sesi veya standart medya) kullanımını, oynatma davranışlarını ve içerik türünü açıklar.

canBeSpatialized()'ı ararken Player için ayarlanan AudioAttributes örneğini kullanın. Örneğin, Jetpack Media3 kitaplığını kullanıyorsanız ve AudioAttributes özelleştirmediyseniz AudioAttributes.DEFAULT kullanın.

Üç boyutlu sesi devre dışı bırakma

İçeriğinizin halihazırda uzamsallaştırıldığını belirtmek için setIsContentSpatialized(true) işlevini çağırın. Böylece ses iki kez işlenmez. Alternatif olarak, setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER) işlevini çağırarak uzamsallaştırma davranışını tamamen devre dışı bırakacak şekilde ayarlayın.

AudioFormat

AudioFormat nesnesi, ses parçasının biçimi ve kanal yapılandırmasıyla ilgili ayrıntıları açıklar.

canBeSpatialized()'a iletilecek AudioFormat öğesini oluştururken encoding'i, kod çözücüden beklenen çıkış biçimiyle aynı olacak şekilde ayarlayın. Ayrıca, içeriğinizin kanal yapılandırmasıyla eşleşen bir kanal maskesi de ayarlamanız gerekir. Kullanılacak belirli değerler hakkında bilgi edinmek için Varsayılan uzamsallaştırma davranışı bölümüne bakın.

Spatializer dosyasında yapılan değişiklikleri dinleme

Spatializer durumundaki değişiklikleri dinlemek için Spatializer.addOnSpatializerStateChangedListener() ile bir dinleyici ekleyebilirsiniz. Benzer şekilde, kafa hareketi izleyicinin kullanılabilirliğindeki değişiklikleri dinlemek için Spatializer.addOnHeadTrackerAvailableListener() işlevini çağırın.

Bu özellik, dinleyicilerin geri aramalarını kullanarak oynatma sırasında parça seçiminizi düzenlemek istediğinizde yararlı olabilir. Örneğin, bir kullanıcı kulaklığını cihaza bağladığında veya cihazdan çıkardığında onSpatializerAvailableChanged geri çağırma işlevi, yeni ses çıkışı yönlendirmesi için uzamsallaştırıcı efektin kullanılabilir olup olmadığını belirtir. Bu noktada, oynatıcınızın parça seçme mantığını cihazın yeni özelliklerine uyacak şekilde güncellemeyi düşünebilirsiniz. ExoPlayer'ın parça seçme davranışı hakkında ayrıntılı bilgi için ExoPlayer ve uzamsal ses bölümüne bakın.

ExoPlayer ve üç boyutlu ses

ExoPlayer'ın son sürümleri, üç boyutlu sesin kullanılmasını kolaylaştırır. Bağımsız ExoPlayer kitaplığını (paket adı com.google.android.exoplayer2) kullanıyorsanız 2.17 sürümü, platformu uzamsallaştırılmış ses çıkışı verecek şekilde yapılandırır. 2.18 sürümünde ise ses kanalı sayısı kısıtlamaları uygulanır. Media3 kitaplığındaki ExoPlayer modülünü (paket adı androidx.media3) kullanıyorsanız 1.0.0-beta01 ve sonraki sürümlerde bu güncellemeler yer alır.

ExoPlayer bağımlılığınızı en son sürüme güncelledikten sonra uygulamanızın yalnızca uzamsallaştırılabilen içerikler içermesi gerekir.

Ses kanalı sayısı kısıtlamaları

Üç boyutlu ses için dört koşulun tamamı karşılandığında ExoPlayer, çok kanallı bir ses parçası seçer. Aksi takdirde ExoPlayer, stereo parçayı seçer. Spatializer özellikleri değişirse ExoPlayer, mevcut özelliklerle eşleşen bir ses parçası seçmek için yeni bir parça seçimi tetikler. Bu yeni parça seçiminin kısa bir yeniden arabelleğe alma süresine neden olabileceğini unutmayın.

Ses kanalı sayısı kısıtlamalarını devre dışı bırakmak için oynatıcıdaki parça seçimi parametrelerini aşağıda gösterildiği gibi ayarlayın:

Kotlin

exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context)
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  new DefaultTrackSelector.Parameters.Builder(context)
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

Benzer şekilde, mevcut bir parça seçicinin parametrelerini güncelleyerek ses kanalı sayısı kısıtlamalarını aşağıdaki şekilde devre dışı bırakabilirsiniz:

Kotlin

val trackSelector = DefaultTrackSelector(context)
...
trackSelector.parameters = trackSelector.buildUponParameters()
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
...
trackSelector.setParameters(
  trackSelector
    .buildUponParameters()
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

Ses kanalı sayısı kısıtlamaları devre dışı bırakıldığında, içerikte birden fazla ses parçası varsa ExoPlayer başlangıçta en fazla kanala sahip olan ve cihazdan oynatılabilen parçayı seçer. Örneğin, içerikte çok kanallı bir ses parçası ve stereo ses parçası varsa ve cihaz her ikisinin de oynatılmasını destekliyorsa ExoPlayer çok kanallı parçayı seçer. Bu davranışı nasıl özelleştireceğiniz hakkında ayrıntılı bilgi için Ses parçası seçimi bölümüne bakın.

Ses parçası seçimi

ExoPlayer'ın ses kanalı sayısı kısıtlamaları davranışı devre dışı bırakıldığında ExoPlayer, cihazın uzamsallaştırıcısının özellikleriyle eşleşen bir ses parçasını otomatik olarak seçmez. Bunun yerine, oynatma öncesinde veya sırasında parça seçimi parametrelerini ayarlayarak ExoPlayer'ın parça seçimi mantığını özelleştirebilirsiniz. ExoPlayer, varsayılan olarak MIME türü (kodlama), kanal sayısı ve örnekleme hızı açısından ilk parçayla aynı olan ses parçalarını seçer.

Parça seçimi parametrelerini değiştirme

ExoPlayer'ın parça seçimi parametrelerini değiştirmek için Player.setTrackSelectionParameters() değerini kullanın. Aynı şekilde, Player.getTrackSelectionParameters() ile ExoPlayer'ın mevcut parametrelerini alabilirsiniz. Örneğin, oynatma sırasında stereo ses parçası seçmek için:

Kotlin

exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
  .buildUpon()
  .setMaxAudioChannelCount(2)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  exoPlayer.getTrackSelectionParameters()
    .buildUpon()
    .setMaxAudioChannelCount(2)
    .build()
);

Parça seçimi parametrelerinin oynatma sırasında değiştirilmesinin oynatmanın kesintiye uğramasına neden olabileceğini unutmayın. Oynatıcının parça seçimi parametrelerini ayarlama hakkında daha fazla bilgiyi ExoPlayer dokümanlarının parça seçimi bölümünde bulabilirsiniz.

Varsayılan uzamsallaştırma davranışı

Android'deki varsayılan uzamsallaştırma davranışı, OEM'ler tarafından özelleştirilebilen aşağıdaki davranışları içerir:

  • Stereo içerikler değil, yalnızca çok kanallı içerikler uzamsallaştırılır. ExoPlayer kullanmıyorsanız çok kanallı ses içeriğinizin biçimine bağlı olarak, ses kod çözücü tarafından çıkışı yapılabilecek maksimum kanal sayısını yüksek bir sayıya yapılandırmanız gerekebilir. Bu sayede, ses kod çözücü, platformun uzamsallaştırması için çok kanallı PCM çıkışı yapar.

    Kotlin

    val mediaFormat = MediaFormat()
    mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99)

    Java

    MediaFormat mediaFormat = new MediaFormat();
    mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);

    Çalışan bir örnek için ExoPlayer'ın MediaCodecAudioRenderer.java sayfasına bakın. Üç boyutlu ses özelliğini OEM özelleştirmesinden bağımsız olarak kendiniz devre dışı bırakmak için Üç boyutlu sesi devre dışı bırakma başlıklı makaleyi inceleyin.

  • AudioAttributes: usage, USAGE_MEDIA veya USAGE_GAME olarak ayarlanmışsa ses, üç boyutlu ses için uygundur.

  • AudioFormat: Sesin uzamsallaştırmaya uygun olması için en azından AudioFormat.CHANNEL_OUT_QUAD kanallarını (ön sol, ön sağ, arka sol ve arka sağ) içeren bir kanal maskesi kullanın. Aşağıdaki örnekte, 5.1 ses parçası için AudioFormat.CHANNEL_OUT_5POINT1 kullanıyoruz. Stereo ses parçası için AudioFormat.CHANNEL_OUT_STEREO simgesini kullanın.

    Media3 kullanıyorsanız kanal sayısını kanal maskesine dönüştürmek için Util.getAudioTrackChannelConfig(int channelCount) işlevini kullanabilirsiniz.

    Ayrıca, kod çözücüyü çok kanallı PCM çıkışı verecek şekilde yapılandırdıysanız kodlamayı AudioFormat.ENCODING_PCM_16BIT olarak ayarlayın.

    Kotlin

    val audioFormat = AudioFormat.Builder()
      .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
      .build()

    Java

    AudioFormat audioFormat = new AudioFormat.Builder()
      .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
      .build();

Üç boyutlu sesi test etme

Test cihazınızda üç boyutlu sesin etkinleştirildiğinden emin olun:

  • Kablolu kulaklıklar için Sistem ayarları > Ses ve titreşim > Uzamsal ses'e gidin.
  • Kablosuz kulaklıklar için Sistem ayarları > Bağlı cihazlar > Kablosuz cihazınızın dişli simgesi > Üç boyutlu ses'e gidin.

Mevcut yönlendirme için üç boyutlu ses özelliğinin kullanılabilirliğini kontrol etmek üzere cihazınızda adb shell dumpsys audio komutunu çalıştırın. Oynatma etkin durumdayken çıkışta aşağıdaki parametreleri görmeniz gerekir:

Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)