Üç Boyutlu Ses

Üç boyutlu ses, kullanıcılarınızı aksiyonun merkezine yerleştiren etkileyici bir ses deneyimidir. Böylece sesleriniz daha gerçekçi olur. Ses, surround ses ayarına benzer şekilde bir çoklu hoparlör efekti oluşturmak için "uzamsallaştırılır" ancak bunun yerine kulaklık kullanılır.

Örneğin, bir filmde arabanın sesi kullanıcının arkasından başlıyor, ileri doğru hareket ediyor ve patikayla uzaklaşıyor olabilir. Görüntülü sohbetlerde kullanıcının sesi ayrılıp kullanıcının etrafına yerleştirilebilir. Böylece konuşmacıların tanınması kolaylaşır.

İçeriğiniz desteklenen bir ses biçimi kullanıyorsa uygulamanıza Android 13 (API düzeyi 33) sürümünden itibaren üç boyutlu ses ekleyebilirsiniz.

Özellikler için sorgu

Cihazın mekansallaştırma özelliklerini ve davranışını sorgulamak için Spatializer sınıfını kullanın. AudioManager üzerinden Spatializer öğesinin bir örneğini alarak başlayın:

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

Spatializer aldıktan sonra, cihazın üç boyutlu ses çıkarması için geçerli olması gereken dört koşulu kontrol edin:

Ölçütler İndirme işlemi için
Cihaz mekansallaştırmayı destekliyor mu? getImmersiveAudioLevel(), SPATIALIZER_IMMERSIVE_LEVEL_NONE değil
Mekansallaştırma kullanılabilir mi?
Özelliğin kullanılabilirliği, mevcut ses çıkışı yönlendirmesiyle uyumluluğa bağlıdır.
isAvailable(): true
Mekansallaştırma etkinleştirildi mi? isEnabled(): true
Belirli parametrelere sahip bir ses parçası üç boyutlu hale getirilebilir mi? canBeSpatialized(): true

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

Kafa hareketi izleme

Desteklenen mikrofonlu kulaklıklarda platform, kullanıcının baş konumuna göre sesin farklılaşmasını ayarlayabilir. Mevcut ses çıkışı yönlendirmesiyle ilgili olarak baş izleyicinin kullanılıp kullanılamadığını öğrenmek için isHeadTrackerAvailable() numaralı telefonu arayın.

Uyumlu içerikler

Spatializer.canBeSpatialized(), belirtilen özelliklere sahip sesin geçerli çıkış cihazı yönlendirmesiyle üç boyutlu hale getirilip getirilmeyeceğini belirtir. Bu yöntem, bir AudioAttributes ve bir AudioFormat gerektirir. Her ikisi de aşağıda daha ayrıntılı olarak açıklanmıştır.

AudioAttributes

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

canBeSpatialized() yöntemini çağırırken Player için ayarladığınız AudioAttributes örneğini kullanın. Örneğin, Jetpack Media3 kitaplığı kullanıyorsanız ve AudioAttributes öğesini özelleştirmediyseniz AudioAttributes.DEFAULT değerini kullanın.

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

İçeriğinizin zaten üç boyutlu hâle getirildiğini belirtmek üzere sesin iki kez işlenmemesi için setIsContentSpatialized(true) çağrısı yapın. Alternatif olarak, setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER) yöntemini çağırarak mekansallaştırmayı tamamen devre dışı bırakmak için mekansallaştırma davranışını düzenleyin.

AudioFormat

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

AudioFormat öğesini canBeSpatialized() öğesine geçirmek için örnek oluştururken kodlama özelliğini, kod çözücüden beklenen çıkış biçimiyle aynı olacak şekilde ayarlayın. İç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 konumsallaştırma davranışı bölümüne bakın.

Spatializer öğesinde yapılan değişiklikleri dinleyin

Spatializer durumundaki değişiklikleri dinlemek için Spatializer.addOnSpatializerStateChangedListener() ile bir işleyici ekleyebilirsiniz. Benzer şekilde, ana takip cihazının kullanılabilirliğindeki değişiklikleri dinlemek için Spatializer.addOnHeadTrackerAvailableListener() numaralı telefonu arayın.

Bu, oynatma sırasında dinleyicinin geri çağırmalarını kullanarak parça seçiminizi düzenlemek isterseniz yararlı olabilir. Örneğin, bir kullanıcı mikrofonlu kulaklığını cihaza bağladığında veya bağlantısını kestiğinde onSpatializerAvailableChanged geri çağırma özelliği, yeni ses çıkışı yönlendirmesi için ses konumu belirleyici efektinin kullanılabilir olup olmadığını gösterir. Bu noktada, oynatıcınızın kanal seçim mantığını cihazın yeni özellikleriyle eşleşecek şekilde güncellemeyi düşünebilirsiniz. ExoPlayer'ın parça seçme davranışıyla ilgili ayrıntılar için ExoPlayer ve üç boyutlu ses bölümüne bakın.

ExoPlayer ve üç boyutlu ses

ExoPlayer'ın son sürümleri, üç boyutlu sese geçiş yapmayı kolaylaştırıyor. Bağımsız ExoPlayer kitaplığını (paket adı com.google.android.exoplayer2) kullanıyorsanız 2.17 sürümü, platformu üç boyutlu hale getirilmiş ses çıkışı için yapılandırır. 2.18 sürümünde ise ses kanalı sayısı kısıtlamaları bulunur. Media3 kitaplığındaki ExoPlayer modülünü kullanıyorsanız (paket adı androidx.media3) 1.0.0-beta01 ve daha yeni sürümler bu güncellemeleri içerir.

ExoPlayer bağımlılığınızı en son sürüme güncelledikten sonra, uygulamanızın yalnızca üç boyutlu hale getirilebilecek içerik barındırması gerekir.

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

Üç boyutlu ses için dört koşul da karşılandığında ExoPlayer çok kanallı bir ses parçası seçer. Aksi takdirde, ExoPlayer bunun yerine bir stereo parça seçer. Spatializer özellikleri değişirse ExoPlayer, mevcut özelliklerle eşleşen bir ses kanalı seçmek için yeni bir kanal seçimini 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ıda 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, ses kanalı sayısı kısıtlamalarını devre dışı bırakmak için mevcut bir parça seçicinin parametrelerini aşağıdaki şekilde güncelleyebilirsiniz:

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ışıyken, içerikte birden fazla ses parçası varsa ExoPlayer başlangıçta en yüksek sayıda kanala sahip olan ve cihazdan çalınabilen parçayı seçer. Örneğin, içerikte bir çok kanallı ses parçası ve bir stereo ses parçası varsa ve cihaz her ikisinin de oynatılmasını destekliyorsa ExoPlayer çok kanallı parçayı seçer. Bu davranışın nasıl özelleştirileceğiyle ilgili ayrıntılar 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 ses konumu belirleyicisinin ö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 parkur seçim mantığını özelleştirebilirsiniz. Varsayılan olarak ExoPlayer MIME türü (kodlama), kanal sayısı ve örnek hızı açısından ilk parçayla aynı olan ses parçalarını seçer.

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

ExoPlayer'ın parkur seçim parametrelerini değiştirmek için Player.setTrackSelectionParameters() işlevini kullanın. Benzer şekilde, ExoPlayer'ın mevcut parametrelerini Player.getTrackSelectionParameters() ile de 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()
);

Oynatma sırasında parça seçimi parametrelerinin değiştirilmesinin oynatmanın kesintiye uğramasına neden olabileceğini unutmayın. Oynatıcının parça seçim parametrelerini ayarlamayla ilgili daha fazla bilgiyi ExoPlayer belgelerinin parça seçimi bölümünde bulabilirsiniz.

Varsayılan konumsallaştırma davranışı

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

  • Yalnızca çok kanallı içerikler üç boyutlu hâle getirilir, stereo içerik kullanılmaz. ExoPlayer kullanmıyorsanız çok kanallı ses içeriğinizin biçimine bağlı olarak, bir ses kod çözücü tarafından çok sayıda çıkışa verilebilecek maksimum kanal sayısını yapılandırmanız gerekebilir. Böylece ses kod çözücü, platformun üç boyutlu hale getirilmesi için çok kanallı PCM çıkışı üretir.

    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);
    

    Örnek bir işlem için ExoPlayer'ın MediaCodecAudioRenderer.java dokümanına bakın. Üç boyutlu hâle getirme özelliğini, OEM özelleştirmesinden bağımsız olarak kendiniz kapatmak için Üç boyutlu sesi devre dışı bırakma başlıklı makaleyi inceleyin.

  • AudioAttributes: usage USAGE_MEDIA veya USAGE_GAME olarak ayarlanmışsa ses üç boyutlulaştırma için uygundur.

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

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

    Ayrıca, kod çözücüyü çok kanallı PCM'ye çıkış yapacak ş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 mikrofonlu kulaklıklarda Sistem ayarları > Ses ve titreşim > Üç boyutlu ses bölümüne gidin.
  • Kablosuz mikrofonlu kulaklıklarda Sistem ayarları > Bağlı cihazlar > Kablosuz cihazınızın Dişli simgesi > Üç boyutlu ses'e gidin.

Mevcut yönlendirme için Üç Boyutlu Ses kullanılabilirliğini kontrol etmek üzere cihazınızda adb shell dumpsys audio komutunu çalıştırın. Oynatma etkinken çıkışta aşağıdaki parametreleri görmeniz gerekir:

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