Os recursos de áudio espacial no Jetpack SceneCore permitem criar experiências de áudio imersivas nos aplicativos Android XR.
O áudio espacial simula como os usuários percebem o som em um ambiente 3D. Ele cria a sensação de que o som 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 atuais 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 será emitido pelo painel em que a interface do app é renderizada. Por exemplo, se um timer disparar em um app de relógio, o áudio vai soar como se estivesse vindo da posição do painel do app. O Android XR vai alterar 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 o áudio espacial, leia Adicionar som estéreo e surround ao app nesta página.
Se você estiver otimizando o app para XR, o Jetpack SceneCore vai fornecer ferramentas para personalização avançada de áudio espacial. É possível posicionar sons com precisão no ambiente 3D, usar áudio ambissô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 ambissônico.
Áudio posicional
Um áudio posicional pode ser posicionado para reprodução em um ponto específico no espaço 3D. Por exemplo, é possível ter um modelo 3D de um cachorro latindo no canto do seu ambiente virtual. Você pode ter várias entidades emitindo som de cada uma das 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 são compatíveis com som posicional, estéreo e surround. Além desses formatos, os dispositivos Android XR podem oferecer suporte a formatos de áudio Dolby Atmos, Dolby Digital e Dolby Digital+.
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 configurações. Os dados de som de cada canal estão associados a um alto-falante. Por exemplo, ao reproduzir 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 televisão 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 voando pode usar canais diferentes em sequência para dar a sensação de que o helicóptero está voando pelo espaço 3D.
Áudio ambissônico
O áudio ambissônico (ou ambissônicos) é como um skybox para áudio,
oferecendo uma paisagem sonora imersiva para os usuários. Use ambissônicos para sons ambientais de fundo ou outros cenários em que você queira replicar um campo de som esférico completo que envolva o ouvinte. O Android XR oferece suporte ao
AmbiX formato de áudio ambissônico 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 de áudio espacial com o Jetpack SceneCore envolve a verificação de recursos espaciais e a escolha de uma API para carregar áudio espacial.
Verificar recursos espaciais
Antes de usar os recursos de áudio espacial, verifique se a Session oferece suporte a
áudio espacial. Em todos os snippets de código nas seções a seguir, os recursos são verificados antes de tentar reproduzir áudio espacializado.
Carregar áudio espacial
É possível usar qualquer uma das APIs a seguir para carregar áudio espacial para uso no Jetpack SceneCore.
SoundPool: ideal para efeitos sonoros curtos com menos de 1 MB de tamanho. Eles são carregados com antecedência e os sons podem ser usados repetidamente. Essa é uma ótima maneira de carregar áudio para áudio posicional.ExoPlayer: ideal para carregar conteúdo estéreo e 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 ambissônico.AudioTrack: oferece mais controle sobre como carregar dados de áudio. Permite gravar buffers de áudio diretamente ou se você sintetizou ou decodificou seus próprios arquivos de áudio.
Verificar o suporte ao formato de mídia
Alguns formatos de mídia são compatíveis com a plataforma Android. No entanto, um
dispositivo Android XR específico pode oferecer suporte a outros formatos, como
Dolby Atmos. Para consultar o suporte ao formato de mídia, use
AudioCapabilities do ExoPlayer:
val audioCapabilities = AudioCapabilities.getCapabilities( context, androidx.media3.common.AudioAttributes.DEFAULT, null, emptyList() ) if (audioCapabilities.supportsEncoding(C.ENCODING_AC3)) { // Device supports playback of the Dolby Digital media format. } if (audioCapabilities.supportsEncoding(C.ENCODING_E_AC3)) { // Device supports playback of the Dolby Digital Plus media format. } if (audioCapabilities.supportsEncoding(C.ENCODING_E_AC3_JOC)) { // Device supports playback of the Dolby Digital Plus with Dolby Atmos media format. }
A verificação desses recursos pode envolver o bloqueio de chamadas e não deve ser chamada na linha de execução principal.
Adicionar áudio posicional ao app
As fontes de som posicionais são definidas por PointSourceParams e uma
associada Entity. A posição e a orientação da Entity determinam onde o PointSourceParams é renderizado no espaço 3D. Chame
setPointSourceParams no
SpatialMediaPlayer para definir o PointSourceParams e
a entity associada em uma instância MediaPlayer.
Exemplo de áudio posicional
O exemplo a seguir carrega um arquivo de áudio de efeito sonoro em um pool de som e o reproduz na posição da Entity.
// Check spatial capabilities before using spatial audio if (session.scene.spatialCapabilities.contains(SpatialCapability.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 = PointSourceParams() 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 = session, entity = entity, soundPool = soundPool, soundID = pointSoundId, params = pointSource, volume = maxVolume, priority = lowPriority, loop = infiniteLoop, rate = normalSpeed ) } } } else { // The session does not have spatial audio capabilities }
Principais pontos sobre o código
- A primeira etapa é verificar se os recursos de áudio espacial estão
disponíveis usando
spatialCapabilities. - Definir o contentType como
CONTENT_TYPE_SONIFICATIONe o uso comoUSAGE_ASSISTANCE_SONIFICATIONpermite 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 necessário.
Adicionar som estéreo e surround ao app
A maneira recomendada de adicionar som estéreo e surround ao 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 som surround
Com o posicionamento de alto-falantes de som surround, os alto-falantes virtuais de som surround 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 na do app's
mainPanelEntity. Isso inclui apps para dispositivos móveis que têm o áudio espacializado automaticamente pelo Android XR.
Para estéreo, o posicionamento do alto-falante é semelhante ao som surround, exceto que apenas os canais esquerdo e direito são posicionados nos lados 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 outra Entity, use o PointSourceAttributes para definir o local do canal central. Os canais restantes serão colocados conforme mencionado anteriormente. Nessas
situações, você também precisa usar MediaPlayer.
À medida que o usuário se move pelo espaço, os alto-falantes virtuais estéreo e som surround vão se mover e se ajustar para garantir que os alto-falantes estejam sempre em uma posição ideal.
Se você tiver configurado o MediaPlayer ou ExoPlayer para continuar
reproduzindo som estéreo ou som 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 (ou seja, ele é "bloqueado 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 uma Entity.
// Check spatial capabilities before using spatial audio if (session.scene.spatialCapabilities.contains(SpatialCapability.SPATIAL_AUDIO)) { // The session has spatial audio capabilities val pointSourceAttributes = PointSourceParams() 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.setPointSourceParams( session, mediaPlayer, pointSourceAttributes, entity = session.scene.mainPanelEntity, ) mediaPlayer.setAudioAttributes(audioAttributes) mediaPlayer.prepare() mediaPlayer.start() } else { // The session does not have spatial audio capabilities }
Principais pontos sobre o código
- Assim como no exemplo de áudio posicional, a primeira etapa é verificar se
os recursos de áudio espacial estão disponíveis usando
spatialCapabilities. - Definir o
contentTypeparaAudioAttributes.CONTENT_TYPE_MUSICe o uso paraAudioAttributes.USAGE_MEDIApermite que o sistema trate esse arquivo de áudio como som surround.
Adicionar campos de som ambissônicos ao app
A maneira mais simples de reproduzir campos de som ambissônicos é carregar o arquivo com um MediaPlayer. Como o som ambissônico se aplica a toda a paisagem sonora, não é necessário especificar uma Entity para fornecer uma posição. Em vez disso, crie uma
instância de SoundFieldAttributes com a ordem ambissônica
apropriada especificando o número de canais.
Exemplo de ambissônicos
O exemplo a seguir reproduz um campo de som ambissônico usando MediaPlayer.
// Check spatial capabilities before using spatial audio if (session.scene.spatialCapabilities.contains(SpatialCapability.SPATIAL_AUDIO)) { // The session has spatial audio capabilities val soundFieldAttributes = SoundFieldAttributes(SpatializerConstants.AmbisonicsOrder.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( session, mediaPlayer, soundFieldAttributes ) mediaPlayer.setAudioAttributes(audioAttributes) mediaPlayer.prepare() mediaPlayer.start() } else { // The session does not have spatial audio capabilities }
Principais pontos sobre o código
- Assim como nos snippets anteriores, a primeira etapa é verificar se os recursos de áudio espacial
estão disponíveis usando
hasCapability(). - O
contentTypee o uso são puramente informativos. - O
AMBISONICS_ORDER_FIRST_ORDERsinaliza para o SceneCore que o arquivo de campo de som define quatro canais.