Os recursos de áudio espacial no Jetpack SceneCore permitem criar experiências de áudio imersivas nos seus aplicativos Android XR.
O áudio espacial simula como os usuários percebem o som em um ambiente 3D. Ele cria a sensação de som que emana de todas as direções, incluindo acima e abaixo do usuário. O sistema faz isso simulando um ou mais "alto-falantes virtuais" em locais específicos no espaço 3D.
Os apps que não foram projetados ou modificados para o Android XR têm o áudio espacializado automaticamente no Android XR. À medida que o usuário se move pelo espaço, todo o áudio do app é emitido pelo painel em que a interface do app é renderizada. Por exemplo, se um timer de um app de relógio for acionado, o áudio vai parecer que está vindo da posição do painel do app. O Android XR altera automaticamente o som para realismo posicional. Por exemplo, a distância percebida entre o painel do app e o usuário vai afetar sutilmente o volume do áudio para uma maior sensação de realismo.
Para mais informações sobre como os apps atuais renderizam áudio espacial, leia Adicionar som estéreo e surround ao seu app nesta página.
Se você estiver otimizando seu app para XR, o Jetpack SceneCore oferece ferramentas para personalização avançada de áudio espacial. É possível posicionar sons com precisão no ambiente 3D, usar áudio ambisônico para campos de som realistas e aproveitar a integração de som surround integrada.
Tipos de áudio espacial disponíveis no Android XR
O Android XR oferece suporte a áudio posicional, estéreo, surround e ambisônico.
Áudio posicional
Um áudio posicional pode ser posicionado para ser reproduzido em um ponto específico no espaço 3D. Por exemplo, você pode ter um modelo 3D de um cachorro latindo no canto do seu ambiente virtual. É possível ter várias entidades emitindo som de cada uma das respectivas posições. Para renderizar áudio posicional, os arquivos precisam ser mono ou estéreo.
Som estéreo e surround espacializado
Todos os formatos de mídia do Android têm suporte para som posicional, estéreo e surround.
O áudio estéreo se refere a formatos de áudio com dois canais, e o som surround se refere a formatos de áudio com mais de dois canais, como som surround 5.1 ou som surround 7.1. Os dados de som de cada canal são associados a um alto-falante. Por exemplo, ao tocar música em estéreo, o canal do alto-falante esquerdo pode emitir faixas de instrumentos diferentes do direito.
O som surround é usado com frequência em filmes e programas de TV para melhorar o realismo e a imersão usando vários canais de alto-falantes. Por exemplo, o diálogo geralmente é reproduzido em um canal de alto-falante central, enquanto o som de um helicóptero em voo pode usar canais diferentes em sequência para dar a sensação de que o helicóptero está voando ao redor do seu espaço 3D.
Áudio ambisônico
O áudio ambisônico (ou ambisônicos) é como um skybox para áudio,
oferecendo um ambiente sonoro imersivo para seus usuários. Use ambisônicos para sons de fundo
ambientais ou outros cenários em que você quer replicar um
campo de som esférico que envolve o ouvinte. O Android XR oferece suporte ao formato de áudio ambissônico
AmbiX em ambissônicos de primeira, segunda e terceira ordem. Recomendamos os tipos de arquivo Opus (.ogg
) e
PCM/Wave (.wav
).
Usar áudio espacial com o Jetpack SceneCore
A implementação do áudio espacial com o Jetpack SceneCore envolve a verificação de recursos espaciais e a escolha de uma API para carregar áudio espacial.
Verificar os recursos espaciais
Antes de usar os recursos de áudio espacial, verifique se o Session
oferece suporte
a esse recurso. Em todos os snippets de código nas seções a seguir,
os recursos são verificados antes de tentar reproduzir o áudio espacializado.
Carregar áudio espacial
Você pode usar qualquer uma das APIs abaixo para carregar áudio espacial para uso no Jetpack SceneCore.
SoundPool
: ideal para efeitos sonoros curtos com menos de 1 MB de tamanho, que são carregados com antecedência e podem ser usados repetidamente. Essa é uma ótima maneira de carregar áudio para áudio posicional.ExoPlayer
: ideal para carregar conteúdo estéreo e de som surround, como música e vídeo. Também permite a reprodução de mídia em segundo plano.MediaPlayer
: oferece a maneira mais simples de carregar áudio ambisônico.AudioTrack
: oferece o maior controle sobre como carregar dados de áudio. Permite gravar buffers de áudio diretamente ou se você sintetizou ou decodou seus próprios arquivos de áudio.
Adicionar áudio posicional ao app
As fontes de som posicional são definidas por
PointSourceAttributes
e uma
Entity
associada. A posição e a orientação do Entity
determinam onde o PointSourceAttribute
é renderizado no espaço 3D.
Exemplo de áudio posicional
O exemplo a seguir carrega um arquivo de áudio de efeito sonoro em um conjunto de sons e
o reproduz na posição do Entity
.
// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
// The session has spatial audio capabilities
val maxVolume = 1F
val lowPriority = 0
val infiniteLoop = -1
val normalSpeed = 1F
val soundPool = SoundPool.Builder()
.setAudioAttributes(
AudioAttributes.Builder()
.setContentType(CONTENT_TYPE_SONIFICATION)
.setUsage(USAGE_ASSISTANCE_SONIFICATION)
.build()
)
.build()
val pointSource = PointSourceAttributes(entity)
val soundEffect = appContext.assets.openFd("sounds/tiger_16db.mp3")
val pointSoundId = soundPool.load(soundEffect, lowPriority)
soundPool.setOnLoadCompleteListener{ soundPool, sampleId, status ->
//wait for the sound file to be loaded into the soundPool
if (status == 0){
SpatialSoundPool.play(
session = xrSession,
soundPool = soundPool,
soundID = pointSoundId,
attributes = pointSource,
volume = maxVolume,
priority = lowPriority,
loop = infiniteLoop,
rate = normalSpeed
)
}
}
} else {
// The session does not have spatial audio capabilities
}
Pontos principais sobre o código
- A primeira etapa é verificar se os recursos de áudio espacial estão disponíveis
usando
getSpatialCapabilities()
. - Definir contentType como
CONTENT_TYPE_SONIFICATION
e usage comoUSAGE_ASSISTANCE_SONIFICATION
permite que o sistema trate esse arquivo de áudio como um efeito sonoro. - O exemplo anterior carrega o arquivo de áudio no pool imediatamente antes de usá-lo para manter o código junto para simplificar. O ideal é carregar todos os efeitos sonoros de forma assíncrona ao carregar o app para que todos os arquivos de áudio estejam disponíveis no pool quando você precisar.
Adicionar som estéreo e surround ao app
A maneira recomendada de adicionar som estéreo e surround ao seu app é usando
Exoplayer
. Para mais informações sobre como usar o áudio espacial com Exoplayer
,
consulte o guia de áudio espacial.
Posicionamento de alto-falantes estéreo e de som surround
Com o posicionamento de alto-falantes de som surround, os alto-falantes de som surround virtual são posicionados e orientados em relação a um alto-falante central, ao redor do usuário em uma configuração ITU padrão.
Por padrão, o alto-falante do canal central é colocado no
mainPanelEntity
do app. Isso inclui apps para dispositivos móveis que têm
o áudio espacializado automaticamente pelo Android XR.
Para o estéreo, a colocação dos alto-falantes é semelhante ao som surround, exceto com apenas os canais esquerdo e direito posicionados no lado esquerdo e direito do painel, respectivamente.
Se você tiver vários painéis e quiser escolher qual deles emite áudio ou
se quiser que o áudio estéreo ou surround seja renderizado em relação a outro Entity
,
use o PointSourceAttributes
para definir o
local do canal central. Os canais restantes serão colocados como
mencionado anteriormente. Nessas situações, também é necessário usar
MediaPlayer
.
À medida que o usuário se move pelo espaço, os alto-falantes virtuais de som estéreo e surround se movem e se ajustam para garantir que estejam sempre na posição ideal.
Se você tiver configurado o MediaPlayer
ou o ExoPlayer
para continuar
reproduzindo som estéreo ou surround em segundo plano, o posicionamento do alto-falante
virtual será alterado quando o app estiver em segundo plano. Como não há
painel ou outro ponto no espaço para ancorar o som, o áudio espacial se move
com o usuário. Em outras palavras, ele é "travado na cabeça".
Exemplo de som surround
O exemplo a seguir carrega um arquivo de áudio 5.1 usando MediaPlayer
e define o
canal central do arquivo como um Entity
.
// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
// The session has spatial audio capabilities
val pointSourceAttributes = PointSourceAttributes(xrSession.mainPanelEntity)
val mediaPlayer = MediaPlayer()
val fivePointOneAudio = appContext.assets.openFd("sounds/aac_51.ogg")
mediaPlayer.reset()
mediaPlayer.setDataSource(fivePointOneAudio)
val audioAttributes =
AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
SpatialMediaPlayer.setPointSourceAttributes(
xrSession,
mediaPlayer,
pointSourceAttributes)
mediaPlayer.setAudioAttributes(audioAttributes)
mediaPlayer.prepare()
mediaPlayer.start()
} else {
// The session does not have spatial audio capabilities
}
Pontos principais sobre o código
- Como no exemplo de áudio posicional, a primeira
etapa é verificar se os recursos de áudio não posicional estão disponíveis no momento
usando
getSpatialCapabilities()
. - Definir contentType como CONTENT_TYPE_MUSIC e usage como USAGE_MEDIA permite que o sistema trate esse arquivo de áudio como som surround.
Adicionar campos de som ambisônico ao app
A maneira mais simples de reproduzir campos de som ambisônico é carregando o arquivo com
um MediaPlayer
. Como o som ambisônico se aplica a todo o som ambiente, não
é necessário especificar um Entity
para fornecer uma posição. Em vez disso, crie uma
instância do SoundFieldAttributes
com a
ordem ambisônica adequada especificando o número de canais.
Exemplo de ambionics
O exemplo a seguir reproduz um campo de som ambisônico usando MediaPlayer
.
// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
// The session has spatial audio capabilities
val soundFieldAttributes =
SoundFieldAttributes(SpatializerConstants.AMBISONICS_ORDER_FIRST_ORDER)
val mediaPlayer = MediaPlayer()
val soundFieldAudio = appContext.assets.openFd("sounds/foa_basketball_16bit.wav")
mediaPlayer.reset()
mediaPlayer.setDataSource(soundFieldAudio)
val audioAttributes =
AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.setUsage(AudioAttributes.USAGE_MEDIA)
.build()
SpatialMediaPlayer.setSoundFieldAttributes(
xrSession,
mediaPlayer,
soundFieldAttributes)
mediaPlayer.setAudioAttributes(audioAttributes)
mediaPlayer.prepare()
mediaPlayer.start()
} else {
// The session does not have spatial audio capabilities
}
Pontos principais sobre o código
- Assim como nos snippets anteriores, a primeira etapa é verificar se os recursos de áudio espacial
estão disponíveis usando
getSpatialCapabilities()
. - O contentType e o usage são puramente informativos.
- O
AMBISONICS_ORDER_FIRST_ORDER
sinaliza para o SceneCore que o arquivo de campo de som define quatro canais.