0

3 days ago I started messing around with Android Studio, now I want to make a soundboard for Overwatch heroes. I selected 15 voice files for every one of these 21 heroes, so it will be >300 voice files.

For every hero I have a seperate activity in which there are 15 buttons for each voice file.

The XML files are all done to my liking.

The bit I'm having second thoughts about is my method of playing sounds.

First, I used the MediaPlayer for each sound. But then I read that the MediaPlayer is not intended for ~3 second sounds and that I should use the SoundPool. The MediaPlayer worked fine, but if I spam one button there is a humongous (10 second) delay until I can play sounds again. I wanted to try out the SoundPool lib but everytime I want to play a sound it tells me that sample 1 isn't ready. Doesn't matter how long I wait, it never finishes loading. I know I can add a onLoadCompleteListener but I would have to do this for all 315 buttons seperately...

I'm a little lost as you can see.

Here's my code: (Just one activity class since the others still use the MediaPlayer...

package eleumnoyce.newsoundboard;

import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

import java.util.HashMap;

public class genji extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_genji);
    }

    public void genjiClick(View v) { //genjiClick is the OnClick in my XML

        int afterthis = 1;


        SoundPool genjiPool;
        HashMap<Integer, Integer> genjiMap;
        setVolumeControlStream(AudioManager.STREAM_MUSIC);
        genjiPool = new SoundPool(14, AudioManager.STREAM_MUSIC, 100);
        genjiMap = new HashMap<Integer, Integer>();

        genjiMap.put(afterthis, genjiPool.load(this, R.raw.genjiafterthis, 1));

        switch (v.getId()) {
            case R.id.genji1:  genjiPool.play(genjiMap.get(afterthis), 1, 1, 0, 0, 1);

            /*case R.id.genji2:
                mPlayer = MediaPlayer.create(this, R.raw.genjiasteadyblade);
                mPlayer.start();
                break;

            case R.id.genji3:
                mPlayer = MediaPlayer.create(this, R.raw.genjifatesmiles);
                mPlayer.start();
                break;

            case R.id.genji4:
                mPlayer = MediaPlayer.create(this, R.raw.genjiflowlike);
                mPlayer.start();
                break;

            case R.id.genji5:
                mPlayer = MediaPlayer.create(this, R.raw.genjiiamcertain);
                mPlayer.start();
                break;

            case R.id.genji6:
                mPlayer = MediaPlayer.create(this, R.raw.genjiinbalancefind);
                mPlayer.start();
                break;

            case R.id.genji7:
                mPlayer = MediaPlayer.create(this, R.raw.genjijustmystyle);
                mPlayer.start();
                break;

            case R.id.genji8:
                mPlayer = MediaPlayer.create(this, R.raw.genjijustsettingfoot);
                mPlayer.start();
                break;

            case R.id.genji9:
                mPlayer = MediaPlayer.create(this, R.raw.genjimeasuretwice);
                mPlayer.start();
                break;

            case R.id.genji10:
                mPlayer = MediaPlayer.create(this, R.raw.genjimybladeis);
                mPlayer.start();
                break;

            case R.id.genji11:
                mPlayer = MediaPlayer.create(this, R.raw.genjirevenge);
                mPlayer.start();
                break;

            case R.id.genji12:
                mPlayer = MediaPlayer.create(this, R.raw.genjisomehingfor);
                mPlayer.start();
                break;

            case R.id.genji13:
                mPlayer = MediaPlayer.create(this, R.raw.genjitheresnotime);
                mPlayer.start();
                break;

            case R.id.genji14:
                mPlayer = MediaPlayer.create(this, R.raw.genjitoknowyourself);
                mPlayer.start();
                break;*/
        }
    }
}

If you want to help me further: Is there a better, more elegant way to do this?

Necrophades
  • 605
  • 7
  • 21
  • Construct the soundpool in `onCreate` (or `onStart` or `onResume` - also don't forget to destory it in the opposing method, e.g. `onDestroy`), then merely play sounds from the existing pool in your click handler. That way it has time to load. – zapl May 14 '16 at 22:56
  • You needn't create separate activities for the 21 heroes. From your 'baseactivity' a bundle is sent to your 'soundlistactivity' with the name of the hero. The 'soundlistactivity' checks the name in the bundle and sets the data in all the places with relevant files. – suku May 14 '16 at 22:57
  • But if I create it in onCreate, my onClick method won't know what I mean by "genjiPool.play(somefile)", will it? – Necrophades May 15 '16 at 12:51

1 Answers1

1

First of all, if you are using wav or something like that, DON't. Use .ogg files to play with SoundPool. This decreases delay and increases performance remarkablely.

Then you should split your 315 sounds. Every soundpool object should responsible about 15-20 sounds. Using this method you can easily load 315 sounds however this can be problem some older devices.

In addition, because of Android limitiations you can't play more than 24-25 sounds in the same time. (Ref: AudioFlinger could not create track. status: -12)

Note: You should use SoundPool in this format:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        AudioAttributes attributes = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_MEDIA)
                .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build();

        mSoundPool = new SoundPool.Builder().setAudioAttributes(attributes).setMaxStreams(6).build();
    } else {
        mSoundPool = new SoundPool(6, AudioManager.STREAM_MUSIC, 0);
    }

6 is the stream sound that is max playable sound number simultaneously.

Community
  • 1
  • 1
Aykut Uludağ
  • 1,876
  • 5
  • 18
  • 34