Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android SoundPool doesn't play same sound for second time until playing another sound

Here is my Activity:

public class MainActivity extends AppCompatActivity {

    private SoundPool soundPool;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        setVolumeControlStream(AudioManager.STREAM_MUSIC);

        soundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0);
        final int sound1 = soundPool.load(this, R.raw.whack, 1);
        final int sound2 = soundPool.load(this, R.raw.miss, 1);

        Button b1 = (Button) findViewById(R.id.b1);
        Button b2 = (Button) findViewById(R.id.b2);

        b1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                playSound(sound1);
            }
        });
        b2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                playSound(sound2);
            }
        });
    }

    private void playSound(int soundId) {

        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        float volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
        soundPool.play(soundId, volume, volume, 1, 0, 1);
    }
}

The problem is when I click on Button1, sound1 is played. Then when I click on Button1 again and again, nothing is played until I click on Button2. When I do that, sound2 is played. Then if I click on Button1, sound1 is played. Same scenario happens when I click on Button2 over and over. So what is the problem here?

like image 685
Misagh Emamverdi Avatar asked Jan 27 '17 11:01

Misagh Emamverdi


3 Answers

According to SoundPool.play() documentation volume value must be from 0.0 to 1.0. But audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) returns bigger value (for example 12). So, you should set right volume value. Below work code:

public static void playAudio(Context context, SoundPool player, int soundId, float speed){
        AudioManager mgr = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        float actualVolume=(float) mgr.getStreamVolume(AudioManager.STREAM_MUSIC);
        float maxVolume=(float) mgr.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
        float volume= actualVolume/maxVolume;
        player.play(soundId, volume, volume, 1, 0, speed);
    }
like image 50
Michael Kazarian Avatar answered Oct 06 '22 00:10

Michael Kazarian


Have the same issue with Android version 7.0, you may try to fix it by changing this part of the code:

float volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

into

float volume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) /
               audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

Hope this can solve the issue you're facing. :)

like image 20
Julius Lin Avatar answered Oct 06 '22 00:10

Julius Lin


We had the same problem and we found a workaround for this exact problem. Not the cleanest way to do it, but if it works, it ain't stupid!

It only works with a max number of streams set to 1. We play a silent sound at volume 0 just before playing our normal sound. Its priority is also 0. Yes it is that ugly!

This is Xamarin so it's C# code, but Java would be extremely similar.

Initialisation of our AudioService :

_soundPool = new SoundPool.Builder().SetMaxStreams(1).Build();
_silentSoundId = _soundPool.Load(Application.Context, Resource.Raw.Silent, 0);
_soundId = _soundPool.Load(Application.Context, Resource.Raw.Sound, 1);

And when it comes to play a sound :

_soundPool.Play(_silentSoundId, 0, 0, 0, 0, 1f);
_soundPool.Play(_soundId, 15, 15, 1, 0, 1f);
like image 20
Agathia Avatar answered Oct 06 '22 01:10

Agathia