Üç Boyutlu Ses

Üç boyutlu ses, kullanıcılarınızı aksiyonun merkezine yerleştirerek içeriğinizin sesini daha gerçekçi hale getiren etkileyici bir ses deneyimidir. Ses, surround ses kurulumuna benzer bir çoklu hoparlör efekti oluşturmak için "üç boyutlu" hale getirilir 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 öne doğru ilerleyebilir ve uzaklaşarak kaybolabilir. Görüntülü sohbette sesler ayrıştırılıp kullanıcının etrafına yerleştirilebilir. Böylece konuşmacıları ayırt etmek kolaylaşır.

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

Yetenekleri sorgulama

Cihazın konumsal ses özelliklerini ve davranışını sorgulamak için Spatializer sınıfını kullanın. AudioManager sınıfından Spatializer örneğini alarak başlayın:

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

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

Ölçütler Çek
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ğa bağlıdır.
isAvailable(), true
Üç boyutlu ses 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 üç boyutlu ses kullanılamıyorsa veya ses çıkış cihazında tamamen devre dışı bırakılmışsa bu koşullar karşılanmayabilir.

Baş takibi

Desteklenen kulaklıklarda platform, sesin uzamsallaştırmasını kullanıcının başının konumuna göre ayarlayabilir. Mevcut ses çıkışı yönlendirmesi için baş takibinin kullanılabilir olup olmadığını kontrol etmek için isHeadTrackerAvailable() yöntemini çağırın.

Uyumlu içerik

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

AudioAttributes

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

canBeSpatialized() çağrılırken Player için ayarlanan AudioAttributes örneği kullanılmalıdır. Ö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) yöntemini çağırın. Böylece ses iki kez işlenmez. Alternatif olarak, setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER) yöntemini çağırarak uzamsallaştırmayı tamamen devre dışı bırakmak için uzamsallaştırma davranışını ayarlayın.

AudioFormat

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

canBeSpatialized() yöntemine iletilecek AudioFormat örneklendirilirken encoding parametresini, 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 konumsal ses davranışı bölümüne bakın.

Spatializer ile ilgili değişiklikleri dinleme

Spatializer durumundaki değişiklikleri dinlemek için Spatializer.addOnSpatializerStateChangedListener() ile bir dinleyici ekleyebilirsiniz. Benzer şekilde, baş takibinin kullanılabilirliğindeki değişiklikleri dinlemek için Spatializer.addOnHeadTrackerAvailableListener() yöntemini çağırın.

Bu, dinleyicinin geri çağırma işlevlerini kullanarak oynatma sırasında parça seçiminizi ayarlamak 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ı efektinin kullanılabilir olup olmadığını gösterir. Bu noktada, oynatıcınızın parça seçme mantığını cihazın yeni özelliklerine uyacak şekilde güncelleyebilirsiniz. ExoPlayer'ın parça seçme davranışı hakkında ayrıntılı bilgi için ExoPlayer ve üç boyutlu ses bölümüne bakın.

ExoPlayer ve üç boyutlu ses

ExoPlayer'ın son sürümleri, üç boyutlu ses özelliğini kullanmayı 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 üç boyutlu ses çıkışı verecek şekilde yapılandırır ve 2.18 sürümü, ses kanalı sayısı kısıtlamalarını kullanıma sunar. Media3 kitaplığındaki ExoPlayer modülünü (paket adı androidx.media3) kullanıyorsanız 1.0.0-beta01 ve daha yeni sürümler de aynı güncellemeleri içerir.

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 barındırması 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ça 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ıda parça seçimi parametrelerini aşağıdaki 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 gibi 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 yüksek kanal sayısına 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ğinizle 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 uzamsallaştırıcısının özellikleriyle eşleşen bir ses parçasını otomatik olarak seçmez. Bunun yerine, oynatmadan önce veya oynatma 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 örnek 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. Benzer şekilde, ExoPlayer'ın mevcut parametrelerini Player.getTrackSelectionParameters() ile 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çim parametrelerini değiştirmenin oynatmada kesintiye neden olabileceğini unutmayın. Oynatıcının parça seçim parametrelerini ayarlama hakkında daha fazla bilgiyi ExoPlayer belgelerinin parça seçimi bölümünde bulabilirsiniz.

Varsayılan üç boyutlu ses davranışı

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

  • Yalnızca çok kanallı içerikler üç boyutlu ses olarak çalınır, stereo içerikler çalınmaz. ExoPlayer kullanmıyorsanız çok kanallı ses içeriğinizin biçimine bağlı olarak, bir ses kod çözücünün çıkış yapabileceği maksimum kanal sayısını büyük bir sayıya yapılandırmanız gerekebilir. Bu sayede ses kod çözücü, platformun 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);

    Uygulamalı bir örnek için ExoPlayer'ın MediaCodecAudioRenderer.java sayfasına bakın. OEM özelleştirmesinden bağımsız olarak üç boyutlu ses özelliğini kendiniz devre dışı bırakmak için Üç boyutlu sesi devre dışı bırakma bölümüne bakın.

  • AudioAttributes: usage, USAGE_MEDIA veya USAGE_GAME olarak ayarlanırsa ses, üç boyutlu ses için uygundur.

  • AudioFormat: Sesin üç boyutlu ses için uygun olması amacıyla en az 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ılmıştır. Stereo ses parçası için AudioFormat.CHANNEL_OUT_STEREO değerini 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 mikrofonlu kulaklıklar için Sistem ayarları > Ses ve titreşim > Üç boyutlu ses'e gidin.
  • Kablosuz kulaklıklar için Sistem ayarları > Bağlı cihazlar > Kablosuz cihazınız için dişli simgesi > Üç boyutlu ses'e gidin.

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

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