Üç Boyutlu Ses

Üç boyutlu ses, kullanıcılarınızı hareketin merkezine yerleştirerek içeriğinizin kulağa daha gerçekçi görünmesini sağlayan etkileyici 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 arabadan gelen ses kullanıcının arkasından başlayıp ileri gidebilir ve sonra uzaklığa doğru kayabilir. Görüntülü sohbette sesler ayrılarak kullanıcının etrafına yerleştirilebilir, böylece konuşmacıların ayırt edilmesi kolaylaşır.

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

Özelliklerle ilgili sorgu

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

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

Spatializer öğesini aldıktan sonra, cihazın üç boyutlu ses çıkışı için doğru olması gereken dört koşulu kontrol edin:

Ölçütler Kontrol Et
Cihaz mekansallaştırmayı destekliyor mu? getImmersiveAudioLevel(), SPATIALIZER_IMMERSIVE_LEVEL_NONE değil
Mekanizasyon kullanılabilir mi?
Özelliğin kullanılabilirliği, mevcut ses çıkışı yönlendirmesiyle uyumluluğa bağlıdır.
isAvailable() değeri: true
Mekansallaştırma etkin mi? isEnabled() değeri: true
Verilen parametrelere sahip bir ses parçası üç boyutlu hale getirilebilir mi? canBeSpatialized() değeri: 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 mikrofonlu kulaklıklarda sesin konumunu kullanıcının baş konumuna göre ayarlayabilir. Mevcut ses çıkışı yönlendirmesi için mikrofonlu kulaklık olup olmadığını kontrol etmek için isHeadTrackerAvailable() numaralı telefonu arayı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öntemde AudioAttributes ve AudioFormat kullanılır. Bunların her ikisi de aşağıda daha ayrıntılı olarak açıklanmıştı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 kullanın.

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

İçeriğinizin üç boyutlu hale getirildiğini belirtmek için setIsContentSpatialized(true) numaralı telefonu arayarak sesin iki kez işlenmemesini sağlayın. Alternatif olarak, setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER) işlevini çağırarak mekansallaştırma davranışını uzamsallaştırmayı tamamen devre dışı bırakacak şekilde ayarlayabilirsiniz.

AudioFormat

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

canBeSpatialized()'e aktarılacak AudioFormat için örnek oluştururken kodlamayı, kod çözücüden beklenen çıkış biçimine 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 yardım için Varsayılan mekansallaştırma davranışı bölümüne bakın.

Spatializer ile ilgili değişiklikleri bekleyin

Spatializer öğesinin durumundaki değişiklikleri dinlemek için Spatializer.addOnSpatializerStateChangedListener() ile bir işleyici ekleyebilirsiniz. Benzer şekilde, kafa takip cihazının kullanılabilirliğiyle ilgili değişiklikleri öğrenmek için Spatializer.addOnHeadTrackerAvailableListener() numaralı telefonu arayın.

Bu, dinleyicinin geri çağırma özelliğini kullanarak oynatma sırasında 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ğırması, konumlandırıcı efektinin yeni ses çıkış yönlendirmesi için kullanılabilir olup olmadığını gösterir. Bu noktada, oynatıcınızın parça seçme 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 sesi kullanmayı kolaylaştırır. Bağımsız ExoPlayer kitaplığını (paket adı com.google.android.exoplayer2) kullanırsanız 2.17 sürümü, platformu üç boyutlu ses çıkışı yapacak şekilde yapılandırır ve sürüm 2.18'de ses kanalı sayısı kısıtlamaları uygulanır. Media3 kitaplığından ExoPlayer modülünü kullanıyorsanız (paket adı androidx.media3) 1.0.0-beta01 ve daha yeni 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 yalnızca uzamsal hale getirilebilen içerik 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 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, ses kanalı sayısı kısıtlamalarını devre dışı bırakmak için mevcut parça seçici 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 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ğine dair 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 otomatik olarak cihazın konumlandırıcısının özellikleriyle eşleşen bir ses parçası seçmez. Bunun yerine, oynatma öncesinde veya sırasında parça seçimi parametrelerini ayarlayarak ExoPlayer'ın parça seçme 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çimi 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 ortası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çme parametrelerini değiştirmenin 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 belgelerinin parça seçimi bölümünde bulabilirsiniz.

Varsayılan alanlaştırma davranışı

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

  • Yalnızca çok kanallı içerikler üç boyutlu hale getirilir, stereo içerikler kullanılmaz. ExoPlayer'ı kullanmıyorsanız çok kanallı ses içeriğinizin biçimine bağlı olarak, bir ses kod çözücünün çıkışını yüksek sayılara çıkarabilecek maksimum kanal sayısını yapılandırmanız gerekebilir. Bu, ses kod çözücünün platformun mekansalleşmesi için çok kanallı PCM çıkışını 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 uygulamasına göz atın. OEM özelleştirmesinden bağımsız olarak, mekansallaştırmayı kendiniz kapatmak için Üç boyutlu sesi devre dışı bırakma bölümüne bakın.

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

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

    Buna ek olarak, kod çözücüyü çok kanallı PCM çı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 kulaklıklarda Sistem ayarları > Ses ve titreşim > Üç boyutlu ses'e 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'in kullanılabilirliğini kontrol etmek için cihazınızda adb shell dumpsys audio komutunu çalıştırın. Oynatma özelliği etkinken çıkışta aşağıdaki parametreleri görürsünüz:

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