AVISO: o OpenSL ES foi descontinuado. Os desenvolvedores precisam usar a biblioteca Oboe de código aberto, que está disponível no GitHub. O Oboe é um wrapper C++ que fornece uma API parecida com a AAudio. O Oboe chama o AAudio quando ele está disponível e usa o OpenSL ES se o AAudio não estiver disponível.
Esta seção fornece as informações necessárias para começar a usar as APIs OpenSL ES.
Adicionar o OpenSL ES ao app
Você pode chamar o OpenSL ES por código C e C++. Para adicionar o principal conjunto de recursos
do OpenSL ES ao aplicativo, inclua o arquivo principal OpenSLES.h
:
#include <SLES/OpenSLES.h>
Para adicionar as extensões para Android do OpenSL ES
também, inclua o arquivo principal OpenSLES_Android.h
:
#include <SLES/OpenSLES_Android.h>
Ao incluir o arquivo principal OpenSLES_Android.h
, os seguintes cabeçalhos são incluídos automaticamente:
#include <SLES/OpenSLES_AndroidConfiguration.h> #include <SLES/OpenSLES_AndroidMetadata.h>
Observação: esses cabeçalhos não são obrigatórios, mas são mostrados como auxiliar de aprendizado da API.
Criar e depurar
Para incorporar o OpenSL ES ao seu build, especifique-o no
arquivo Android.mk
que atua como um dos
makefiles do sistema de compilação do NDK. Adicione a linha a seguir a
Android.mk
:
LOCAL_LDLIBS += -lOpenSLES
Para depuração robusta, recomendamos examinar o valor SLresult
que a maioria das
APIs OpenSL ES retornam. É possível usar
declarações
ou lógica de tratamento de erros mais avançada para a depuração. Nenhuma das duas opções oferece
vantagem inerente por trabalhar com o OpenSL ES, embora uma delas possa ser mais adequada
a determinados casos de uso.
Usamos declarações nos nossos exemplos porque elas ajudam a capturar condições irrealistas que indicariam um erro no código. Usamos tratamento de erros explícito para outras condições mais propensas a ocorrer na produção.
Muitos erros de API geram uma entrada de registro, além de um código de resultado diferente de zero. Esses registros podem fornecer detalhes adicionais especialmente úteis para APIs relativamente complexas, como Engine::CreateAudioPlayer
.
Você pode exibir o registro pela linha de comando ou pelo Android Studio. Para examinar o registro pela linha de comando, digite o seguinte:
$ adb logcat
Para examinar o registro no Android Studio, selecione View > Tool Windows > Logcat. Para saber mais sobre os registros, consulte Gravar e visualizar registros com o Logcat.
Exemplo de código
Recomendamos usar exemplo de código compatível e testado que possa ser usado como modelo do seu próprio código, encontrado nas pastas audio-echo e native-audio do repositório android-ndk (links em inglês) do GitHub.
Atenção: a especificação do OpenSL ES 1.0.1 contém exemplos de código nos anexos. Consulte Registro do Khronos OpenSL ES (link em inglês) para saber mais. No entanto, os exemplos do Apêndice B: amostra de código e do Apêndice C: amostra de código de caso de uso usam recursos não compatíveis com o Android. Alguns exemplos também contêm erros tipográficos ou usam APIs que provavelmente mudarão. Referencie-os com cuidado. Apesar de o código poder ser útil para entender todo o padrão OpenSL ES, ele não pode ser usado da forma que se encontra com o Android.
Conteúdo de áudio
Veja a seguir algumas das diversas maneiras de empacotar conteúdo de áudio para o aplicativo:
- Recursos: ao colocar os arquivos de áudio na pasta
res/raw/
, é possível acessá-los facilmente pelas APIs associadas paraResources
. Porém, não há acesso nativo direto aos recursos, por isso você precisa programar código em Java para copiá-los antes de usar. - Recursos: ao colocar os arquivos de áudio na pasta
assets/
, eles ficam diretamente acessíveis pelas APIs gerenciadoras de ativos nativos do Android. Veja os arquivos principaisandroid/asset_manager.h
eandroid/asset_manager_jni.h
para saber mais sobre essas APIs. O exemplo de código localizado no repositório android-ndk (link em inglês) do GitHub usa essas APIs gerenciadoras de ativos nativos do Android em conjunto com o localizador de dados de descritor de arquivos do Android. - Rede: você pode usar o localizador de dados de URI para reproduzir conteúdo de áudio diretamente da rede. No entanto, leia Segurança e permissões.
- Sistema de arquivos local: o localizador de dados do URI é compatível com o esquema
file:
para arquivos locais, desde que os arquivos sejam acessíveis pelo aplicativo. Observe que o framework de segurança do Android restringe o acesso aos arquivos pelos mecanismos de ID de usuário e ID de grupo do Linux. - Gravado: seu aplicativo pode gravar dados de áudio pela entrada de microfone, armazenar esse conteúdo e reproduzi-lo no futuro. O código de exemplo usa esse método para o clipe Reprodução.
- Compilado e vinculado in-line: você pode vincular seu conteúdo de áudio diretamente na biblioteca compartilhada e reproduzi-lo usando um player de áudio com um localizador de dados de fila do buffer. Esse método é mais adequado para clipes curtos em formato PCM. O exemplo de código usa essa técnica para os clipes Hello e Android. Os dados em PCM foram convertidos em strings hexadecimais usando uma ferramenta
bin2c
(não fornecida). - Síntese em tempo real: o aplicativo pode sintetizar dados PCM imediatamente e reproduzi-los usando um player de áudio com o localizador de dados da fila do buffer. Essa é uma técnica relativamente avançada, e os detalhes da síntese de áudio estão além do âmbito deste artigo.
Observação: encontrar ou criar conteúdo de áudio útil para o aplicativo não faz parte do escopo deste artigo. Você pode usar termos de pesquisa na Web, como áudio interativo, áudio para jogos, design de som e programação de áudio, para conseguir mais informações.
Cuidado: você é totalmente responsável por garantir que tenha permissão legal para reproduzir ou gravar conteúdo. Pode haver considerações de privacidade para gravar conteúdo.
Exemplos de código
Estes apps de amostra estão disponíveis na nossa página do GitHub (links em inglês):
- audio-echo cria uma viagem de ida e volta, da entrada para a saída, em loop.
- native-audio é um gravador/reprodutor de áudio simples.
A implementação do OpenSL ES do Android NDK é diferente da especificação de referência do OpenSL ES 1.0.1 em diversos aspectos. Essas diferenças são um motivo importante para explicar por que os exemplos de código copiados diretamente da especificação de referência do OpenSL ES podem não funcionar no seu app Android.
Para saber mais sobre as diferenças entre a especificação de referência e a implementação Android, consulte OpenSL ES para Android.