Wednesday, February 6, 2013

Simple SoundPool example

I needed it for timer which plays beep on every 15 to 30 seconds. Since I am using remote shutter release and doing manual tracking, astrophotography, I can’t check how long exposure is until now and go back to tracking if it is not long enough.
SoundPool is intended to load audio from resources in APK, and MediaPlayer service immediately decodes audio to raw 16 bit PCM which stays loaded in memory. Multiple audio streams can be played simultaneously, they can’t be started simultaneously but they can be overlapping. Anyway, take a look at documentation http://developer.android.com/reference/android/media/SoundPool.html
Doing research on the Web I concluded that Ogg Vorbis is preferred file format to use for audio files and that they should not be longer than few seconds. To convert audio files to Ogg Vorbis I am using Audacity http://audacity.sourceforge.net/ works on all major operating systems.
So here is the code for very simple player:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    player = new SoundPool(2, AudioManager.STREAM_MUSIC, 100);
    soundList = new SparseIntArray();
    soundList.put(1, player.load(this, R.raw.biska, 1));
    Button button1 = (Button)findViewById(R.id.button1);
    button1.setOnClickListener(button1OnClickListener);
}


We have SoundPool for max two streams, type is music stream and quality 100%. Next we associate known key with result of loading audio from resource.
To play it we want to set volume so it matches current media volume on target phone:

Button.OnClickListener button1OnClickListener
= new Button.OnClickListener(){
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
        float curVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        float maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        float volume = curVolume/maxVolume;
        player.play(soundList.get(1), volume, volume, 1, 0, 1f);
    }
};


Proper cleanup would consist from calling release() method of instance of SoundPool and setting reference to it to null.
Here is the link to complete example https://docs.google.com/file/d/0B0cIChfVrJ7WRW10SWFmd2ZZUzg/edit?usp=sharing included Ogg Vorbis is about 5 seconds long. If you click twice play button you can “enjoy” simultaneous play of two streams.

No comments:

Post a Comment