4

You can play a sound with MediaPlayer or SoundPool on Android. Two of our Android devices play the same sound much louder when MediaPlayer is used. On the third device, the volume sounds the same.

Do you know why? Can I make SoundPool to play sounds as loud as MediaPlayer?

Devices in question:

Code: play mp3 sound with SoundPool

private void playSoundPool() {
    int MAX_STREAMS = 2;
    SoundPool soundPool = new SoundPool(MAX_STREAMS, AudioManager.STREAM_MUSIC, 0);
    soundPool.setOnLoadCompleteListener(new OnLoadCompleteListener() {
        @Override
        public void onLoadComplete(SoundPool soundPool, int soundId, int status) {
            int loop = 0;
            int priority = 0;
            float rate = 1.f;
            soundPool.play(soundId, 1, 1, priority, loop, rate);                    
        }
    });
    soundPool.load(this, R.raw.test, 1);
}

Code: play mp3 sound with MediaPlayer

private void playMediaPlayer() {
    MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.test);
    mediaPlayer.setVolume(1, 1);
    mediaPlayer.start();
}

You are welcome to download test project.

Pavel
  • 2,610
  • 3
  • 31
  • 50
  • What happens when you use `1.0f` as the volume for `soundPool.play`? I'd think you'd want to use the same volume level if you want the same volume. – ianhanniballake Oct 04 '14 at 06:00
  • It's just the same. I've put 0.99f because someone adviced back in 2010 to keep SoundPool volume in [0, 0.99f] range. I've updated the code with "1" to keep it simple. – Pavel Oct 04 '14 at 06:05
  • maybe it has something to do with MediaPlayer.setAudioStreamType ? – pskink Oct 04 '14 at 06:17
  • I've just tried setting mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); before mediaPlayer.start(). Doesn't make any difference :( – Pavel Oct 04 '14 at 06:34
  • Hi, are you solved this problem now? – Riki Aug 11 '17 at 03:56

2 Answers2

1

Possible Solution:

You need to create AudioManager for getting, changing the global media volume set by user in phone and changing the volume for our own app independently by changing stream volume in soundPool.

AudioManager mgr = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);

int streamVolume = mgr.getStreamVolume(AudioManager.STREAM_MUSIC);

streamVolume = streamVolume / AudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);

Note:

if I set 0.5 for volume in soundpool, the actual volume will be always half of the global one. Very easy to reproduce:

  • set global media volume in phone settings to max
  • set volume in activity using soundpool.play to 0.5 - play sound
  • set volume in soundpool.play to 1 - play sound, it will be two times louder

So volume passed to SoundPool.play method really a multiplier to the global volume! **So If you want to play a sound at the current volume setting just pass "1" as the volume or change it as per the requirement **

may be media player class using global media volume for playing the audio file. you are using hard-coded soundPool.play(soundId, 1, 1, priority, loop, rate); values !

we need try with

MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.test);
mediaPlayer.setVolume(streamVolume,streamVolume);
mediaPlayer.start();

Some more Texts :

SoundPool:

SoundPool is designed for short clips which can be kept in memory decompressed for quick access, this is best suited for sound effects in apps or games. Using this method with soundboards is a bad idea as you will be loading lots of “medium” sized sounds into the memory and you may exceed your limit (16Mb) and get an OutOfMemoryException. SoundPool load music files using a separate thread, the operation of the main thread does not block the UI. it can be used to play short sound clips say like gun shots during a game (something like less than 3 seconds long). A nice feature that sound pool comes with is that you can play many sounds simultaneously which happens a lot when you think of a game. So you first build a Sound Pool object to load all media files. MediaPlayer:"

MediaPlayer is designed for longer sound files or streams, this is best suited for music files or larger files. The files will be loaded from disk each time create is called, this will save on memory space but introduce a small delay (not really noticeable).

Ref: SO

Community
  • 1
  • 1
LOG_TAG
  • 19,894
  • 12
  • 72
  • 105
-1

Mechanism difference is there, as you can say that due to compression and decompression the sound quality and volume could go below the actual one, and when you compare it with MediaPlayer. So it is better to use MediaPlayer for better sound quality and volume in your case.

SoundPool

SoundPool is designed for short clips which can be kept in memory decompressed for quick access, this is best suited for sound effects in apps or games. Using this method with soundboards is a bad idea as you will be loading lots of “medium” sized sounds into the memory and you may exceed your limit (16Mb) and get an OutOfMemoryException.

MediaPlayer

MediaPlayer is designed for longer sound files or streams, this is best suited for music files or larger files. The files will be loaded from disk each time create is called, this will save on memory space but introduce a small delay (not really noticeable).

Hamad
  • 5,096
  • 13
  • 37
  • 65
  • SoundPool is used in our app for two reasons. 1. Gapless sound loops - MediaPlayer is not able to play a truly gapless loop, there is always a noticeable break. 2. For the reason you mentioned - many small sound effects that need to be played quickly. Why do you think SoundPool uses compression/decompression and MediaPlayer doesn't? – Pavel Oct 27 '14 at 09:21
  • have you tried this to play sound lound with SoudPool?: AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE); audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.getStreamMaxVolume(), 0); – Hamad Oct 27 '14 at 09:44
  • Also see this SoundPool has other problems too! http://stackoverflow.com/questions/7266298/android-sound-api-deterministic-low-latency – Hamad Oct 27 '14 at 09:47
  • Thanks for the help. The code you quoted just modifies the global sound volume for Music channel. One can change this via Android Options. Unfortunately, this is not the way to go. – Pavel Oct 27 '14 at 10:16
  • The post you quoted just praises SoundPool. What other kind of problems do you mean. This is confusing. It is recommended to use SoundPool for low latency sound playback. – Pavel Oct 27 '14 at 10:18