quinta-feira, 17 de novembro de 2011

Android: Utilizando Sons: E quando precisa que vários arquivos mp3 estejam prontos para tocar a qualquer hora?

A classe MediaPlayer é muito boa para tocar e gerenciar música, entretanto quando é necessário tocar uma grande quantidade de MP3 e agilidade, acaba sendo lenta demais.

Para nos salvar, temos a classe SoundPool, que diferente do MediaPlayer, não só permite que os arquivos tocam de forma ágil, como também gerencia os arquivos que foram carregados.

Para utilizar esse método, primeiro instanciaremos normalmente, sendo que o construtor tem três parâmetros: o primeiro a quantidade máxima que o SoundPool será capaz de executar ao mesmo tempo. O segundo é o tipo de Stream que será utilizado, geralmente uma constante da classe AudioManager. O terceiro ainda não tem efeito.




SoundPool sons = new SoundPool(qtdSom,AudioManager.STREAM_MUSIC,0);

Para carregar a música, utilizamos o método load(). Existem três métodos load() que são os seguintes:
  • load(AssetFileDescriptor afd, int priority):Carrega um som apartir de um Descritor de Arquivo Asset;
  • load(Context context, int resId, int priority): Carrega utilizando um arquivo do Resource;
  • load(String path, int priority): Carrega um som a partir de um caminho específico.
Nota-se que todos possui uma prioridade, que é utilizado quando o número de sons que está sendo executado excede a quantidade de som especificado no construtor. Quando o arquivo é carregado, ele retornará um id do som, que será utilizado para dar os comandos de manipulação do som. Exemplo de uma linha carrega:
 
int id = sons.load(context,R.raw.arquivo,1);

Para iniciar a reprodução do som, utilizamos o método play(). Esse método possui 6 argumentos: o primeiro é o id do som que vai ser reproduzido e que foi fornecido quando executou o load. O segundo e o terceiro é o volume da "caixa de som" esquerdo e direito respectivamente. O quarto argumento é a prioridade, enquanto o quinto é a quantidade de vezes que vai repetir (-1 irá repetir indefinidamente). O último argumento é a velocidade que será reproduzido, sendo o 1 a velocidade original, enquanto 0.5 tornará 50% mais lento, 2.0 será duas vezes mais rápido e assim por diante. A nossa linha de reprodução ficará assim:

int streamId = sons.play(id,1,1,1,-1,1.0); 


O método play() retorna o Id da Stream. Diferente do id do som que é retornado no método load(), esse id serve para dar os outros comandos de controle do som. Esses métodos de comando são o stop(), pause() e resume() que tem como parâmetro, o ID da stream.

sons.pause(streamId);  //Pausa a execução, 
                       //permitindo a continuação no ponto em que parou
sons.resume(streamId); //Continua a execução de um som pausado  
sons.stop(streamId);   //Interrompe a execução
 
E dois métodos que podem ser úteis são: autoPause() e autoResume(). A funcionalidades são as mesmas dos métodos pause() e resume(), só que será aplicado a todos os sons que o SoundPool estiver carregado (lembrando que esses dois métodos estão disponíveis a partir da API 8).

Por fim, depois que o SoundPool não for mais necessário, utiliza-se o método release() para liberar os recursos.

SoundPool vs MediaPlayer
Mas qual usar qual?  Músicas compridas sem dúvida MediaPlayer. Se um som comprido demais for carregado no SoundPool, é provável que ocorra um Overflow. Enquanto sons menores, breve, como um clique de um botão, esses sim pode utilizar um SoundPool tranquilamente e com a vantagem que não terá as preocupações do MediaPlayer (Estados da mídia por exemplo).

Links úteis:
http://developer.android.com/reference/android/media/SoundPool.html

2 comentários:

  1. olá! Parabéns pelo post!!!
    Eu fiz exatamente o que você postou, porém no logCat estou com o seguinte erro: 03-31 22:48:59.777: WARN/SoundPool(342): sample 1 not READY
    Esse é o meu código:
    sons = new SoundPool(10,AudioManager.STREAM_MUSIC,0);
    BipForte = sons.load(context,R.raw.forte,1);
    idSondForte = sons.play(BipForte, 1, 1, 1,-1, 1);

    você sabe me dizer onde estou errando?

    Desde ja agradeço a atenção!

    ResponderExcluir
  2. Boa tarde, muito bom seu post
    estou niciando e gostaria de uma ajuda
    tenho uma aplicacao que necessita falar o valor por extenso
    ja tenhos os .wav mas como vou coloca--los para falar
    muito obrigado

    ResponderExcluir