Introduciendo efectos de audio con SoundPool

Hemos aprendido a utilizar la clase MediaPlayer para reproducir audio y video. En un primer ejercicio vamos a aprender a utilizarla para introducir efectos de audio en Asteroides. Como veremos esta clase no resulta adecuada para este uso. A continuación se introducirá la clase SoundPool y se mostrará mediante un ejercicio como esta sí que resulta eficiente para nuestro juego.

Ejercicio paso a paso: Introduciendo efectos de audio con MediaPlayer en Asteroides.

1. Abre el proyecto Asteroides.

2. Copia los siguientes ficheros a la carpeta res/raw  disparo.mp3  y explosion.mp3. [1].

3. Abre la clase VistaJuego y añade las siguientes variables:

MediaPlayer mpDisparo, mpExplosion;

4. En el constructor de la clase inicialízalas de la siguiente forma:.

mpDisparo = MediaPlayer.create(context, R.raw.disparo);

      mpExplosion = MediaPlayer.create(context, R.raw.explosion);

5. Añade en el método ActivaMisil() de VistaJuego:

    mpDisparo.start();

6.  Añade en el método destruyeAsteroide() de VistaJuego:

    mpExplosion.start();

7.  Ejecuta el programa y verifica el resultado. ¿Qué pasa cuando disparamos o destruimos un asteroide? ¿El sonido se oye de forma inmediata?

La clase SoundPool maneja y reproduce de forma rápida recursos de audio en las aplicaciones.

Un SoundPool es una colección de pistas de audio que se pueden cargar en la memoria desde un recurso (dentro de la APK) o desde el sistema de archivos. SoundPool utiliza el servicio de la clase MediaPlayer para descodificar el audio en un formato crudo (PCM de16 bits), lo que después permite reproducirlo rápidamente por el hardware sin tener que decodificarlas cada vez.

Los sonidos pueden repetirse en un bucle una cantidad establecida de veces, definiendo el valor al reproducirlo, o dejarse reproduciendo en un bucle infinito con -1. En este caso, será necesario detenerlo con el método stop().

La velocidad de reproducción también se puede cambiar. El rango de velocidad de reproducción va de 0.5 a 2.0. Una tasa de reproducción de 1.0 hace que el sonido se reproduzca en su frecuencia original. Una tasa de reproducción de 2.0 hace que el sonido se reproduzca al doble de su frecuencia original, y una tasa de reproducción de 0.5 hace que se reproduzca a la mitad de su frecuencia original.

Cuando se crea un SoundPool hay que establecer en un parámetro del constructor el máximo de pistas que se pueden reproducir simultáneamente. Este parámetro no tiene por qué coincidir con el número de pistas cargadas. Cuando se pone una pista en reproducción (método play()) hay que indicar una prioridad. Esta prioridad se utiliza para decidir que se hará cuando el número de reproducciones activas exceda el valor máximo establecido en el constructor. En este caso, se detendrá el flujo con la prioridad mas baja, y en caso de que haya varios, se detendrá el más antiguo. En caso de que el nuevo flujo sea el de menor prioridad, este no se reproducirá.

Una lisita de todos los métodos de esta clase la puedes encontrar en el siguiente link:

http://developer.android.com/reference/android/media/SoundPool.html

 

Ejercicio paso a paso: Introduciendo efectos de audio con SoundPool en Asteroides

1.  En proyecto Asteroides elimina todo el código introducido a partir del punto 3, del ejercicio anterior.

2.  Abre la clase VistaJuego y añade las siguientes variables:

// //// MULTIMEDIA //////

SoundPool soundPool;

int idDisparo, idExplosion;

3.  En el constructor de la clase inicialízalas de la siguiente forma:

soundPool = new SoundPool( 5, AudioManager.STREAM_MUSIC , 0);

idDisparo = soundPool.load(context, R.raw.disparo, 0);

idExplosion = soundPool.load(context, R.raw.explosion, 0);

En el constructor de SoundPool hay que indicar tres parámetros. El primero corresponde al máximo de reproducciones simultáneas. El segundo es el tipo de stream de audio (normalmente STREAM_MUSIC). El tercero es la calidad de reproducción, aunque actualmente no se implementa.

Cada una de las pistas ha de ser cargada mediante el método load(). Existen muchas sobrecargas para este método. La versión utilizada en el ejemplo permite cargar las pistas desde los recursos. El último parámetro corresponde a la prioridad, aunque actualmente no tiene ninguna utilidad.

4. Añade en el método ActivaMisil() de VistaJuego:

soundPool.play(idDisparo, 1, 1, 1, 0, 1);

El método play() permite reproducir una pista. Hay que indicarle el identificador de pista; el volumen para el canal izquierdo y derecho (0.0 a 1.0); La prioridad; El número de repeticiones (-1= siempre, 0=solo una vez, 1=repetir una vez, …  )  y el ratio de reproducción, con el que podremos modificar la velocidad o pitch (1.0 reproducción normal, rango: 0.5 a 2.0)

5.  Añade en el método destruyeAsteroide() de VistaJuego:

       soundPool.play(idExplosion, 1, 1, 0, 0, 1);

Los parámetros utilizados para la explosión son similares, solo hemos introducido una prioridad menor. La consecuencia será que si ya hay un total de 5 (ver constructor) pistas reproduciéndose y se pide la reproducción de un nuevo disparo. El sistema detendrá la reproducción de la explosión más antigua, por tener esta menos prioridad.

7 Ejecuta el programa y verifica el resultado. ¿Qué pasa cuando disparamos o destruimos un asteroide? ¿El sonido se oye de forma inmediata?

8.  Modifica algunos de los parámetros del método play() y verifica el resultado.