Üç Boyutlu Ses

Üç boyutlu ses, kullanıcılarınızın aksiyona ortak olmasını sağlayan ve içeriğinizin daha gerçekçi ses vermesini sağlayan sürükleyici bir ses deneyimidir. Ses, surround ses sistemine benzer bir şekilde çoklu hoparlör efekti oluşturmak için "üç boyutlu hale getirilir", ancak bunun yerine kulaklıkla kullanılır.

Örneğin, bir filmde arabanın sesi kullanıcının arkasından başlayıp öne doğru ilerleyebilir ve uzaklaşabilir. Görüntülü sohbette sesler ayrılabilir ve kullanıcının etrafına yerleştirilebilir. Böylece, konuşmacıları daha kolay tanıyabilirsiniz.

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

Yetenekler için sorgu

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

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

Spatializer değerini aldıktan sonra, cihazın uzamsal ses çıkarması 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
Üç boyutlu ses kullanılabilir mi?
Kullanılabilirlik, mevcut ses çıkışı yönlendirmesiyle uyumluluğu etkiler.
isAvailable(): true
Mekansallaştırma etkin mi? isEnabled(): true
Belirtilen parametrelere sahip bir ses parçası üç boyutlu hale getirilebilir mi? canBeSpatialized(): true

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

Baş takibi

Platform, desteklenen kulaklıklarda sesin uzamsallığını kullanıcının kafa konumuna göre ayarlayabilir. Mevcut ses çıkışı yönlendirmesi için bir kafa hareketi izleyicinin kullanılıp kullanılamayacağını kontrol etmek üzere isHeadTrackerAvailable() çağrısı yapın.

Uyumlu içerik

Spatializer.canBeSpatialized(), belirtilen özelliklere sahip sesin geçerli çıkış cihazı yönlendirmesiyle mekansallaştırılıp ayarlanamayacağını gösterir. Bu yöntem, aşağıda daha ayrıntılı olarak açıklanan bir AudioAttributes ve bir AudioFormat alır.

AudioAttributes

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

canBeSpatialized() çağrısı yaparken Player için ayarlananla aynı AudioAttributes örneğini kullanın. Örneğin, Jetpack Media3 kitaplığını kullanıyorsanız ve AudioAttributes öğesini özelleştirmediyseniz AudioAttributes.DEFAULT öğesini kullanın.

Üç boyutlu ses devre dışı bırakılıyor

İçeriğinizin zaten uzamsallaştırıldığını belirtmek için setIsContentSpatialized(true) çağrısı yaparak sesin iki kez işlenmesini önleyin. Alternatif olarak, setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER) çağrısını yaparak uzamsallaştırma davranışını uzamsallaştırmayı 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.

AudioFormat öğesini canBeSpatialized() öğesine aktarmak için örneklendirirken kodlama özelliğini, 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ğerlerle ilgili bilgi için Varsayılan uzamsallaştırma davranışı bölümüne bakın.

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

Spatializer'ün durumundaki değişiklikleri dinlemek için Spatializer.addOnSpatializerStateChangedListener() ile bir dinleyici ekleyebilirsiniz. Benzer şekilde, bir kafa hareketi izleyicinin stok durumuyla ilgili değişiklikleri dinlemek için Spatializer.addOnHeadTrackerAvailableListener() numaralı telefonu arayın.

Bu, dinleyicinin geri çağırma özelliğini kullanarak oynatma sırasında parça seçiminizi ayarlamak isterseniz 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ılıp kullanılamayacağını belirtir. Bu noktada, oynatıcının parça seçim mantığını cihazın yeni özellikleriyle eşleşecek şekilde güncelleyebilirsiniz. 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 sesi kullanmayı kolaylaştırır. Bağımsız ExoPlayer kitaplığını (com.google.android.exoplayer2 paket adı) kullanıyorsanız 2.17 sürümü platformu uzamsal ses çıkışı verecek şekilde yapılandırır ve 2.18 sürümü ses kanalı sayısı kısıtlamaları sunar. Media3 kitaplığındaki ExoPlayer modülünü (paket adı androidx.media3) kullanıyorsanız 1.0.0-beta01 ve sonraki sürümler aynı güncellemeleri içerir.

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

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 bunun yerine bir stereo parça seçer. Spatializer özellikleri değişirse ExoPlayer, geçerli özelliklerle eşleşen bir ses parçası seçmek için yeni bir parça seçimi tetikler. Bu yeni kanal 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ı 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ışıyken, içerikte birden fazla ses parçası varsa ExoPlayer başlangıçta en yüksek kanal sayısına sahip olan ve cihazdan çalınabilen parçayı seçer. Örneğin, içerikte hem çok kanallı ses parçası hem de 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ği 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 işleminden önce veya oynatma sırasında parça seçimi parametrelerini ayarlayarak ExoPlayer'ın parça seçimi 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.

Kanal seçimi parametrelerini değiştirme

ExoPlayer'ın parça seçim parametrelerini değiştirmek için Player.setTrackSelectionParameters() değerini kullanın. Benzer ş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 oynatmada kesintiye 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, bir ses kod çözücüsü tarafından çıkarılabilecek maksimum kanal sayısını büyük bir sayıya yapılandırmanız gerekebilir. Bu sayede ses kodlayıcı, platformun sesleri uzamsallaştırması için çok kanallı PCM çıkışı sağlar.

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

    Kullanım örneği için ExoPlayer'ın MediaCodecAudioRenderer.java sayfasına bakın. Üretici özelleştirmesinden bağımsız olarak Üç Boyutlu Ses özelliğini 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 üç boyutlu hale getirilebilir.

  • AudioFormat: Sesin uzamsallaştırmaya uygun olması için en azından AudioFormat.CHANNEL_OUT_QUAD kanallarını (sol ön, sağ ön, sol arka 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 simgesini kullanın.

    Media3 kullanıyorsanız kanal sayısını kanal maskesine dönüştürmek için Util.getAudioTrackChannelConfig(int channelCount) 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ıklarda Sistem ayarları > Ses ve titreşim > Üç boyutlu 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'in kullanılabilir olup olmadığını kontrol etmek üzere cihazınızda adb shell dumpsys audio komutunu çalıştırın. Oynatma etkinken çıkışta aşağıdaki parametreleri görürsünüz:

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