about the params Set what to make the player no sound and full sound

Thanks

7 Answers 11

For Android MediaPlayer.setVolume, searching the web seems to show 0.0f for no sound, 1.0f for full sound.

11 upvote
  flag
This is not the correct solution. It does not scale the volume lineally. I mean the volume grows quickly between 0 and 0.5 but very slowly between 0.5 and 1.0. Check user100858 solution below, it works great. – Tomasz
upvote
  flag
@Tomasz...You are correct :) – Sreekanth Karumanaghat
upvote
  flag
1.0f is for full sound of the stream volume of AudioManager. For example, if the stream volume is set 20%, the MediaPlayer volume is set 1.0f, the volume will be 20% of max volume. – Light

I have tried Android MediaPlayer.setVolume, but this function is useless.

I think we should use the function below

AudioManager mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume * mLastProgress / 10, 0);
8 upvote
  flag
What made MediaPlayer.setVolume useless? What weren't you able to do? – dg123
1 upvote
  flag
AudioManager will set the system volume, which you don't want to do. If the user has their phone on silent, and you suddenly blast out music, they won't appreciate it ;) – enyciaa
up vote 93 down vote accepted

This function is actualy wonderful. Thanks to it you can create a volume scale with any number of steps!

Let's assume you want 50 steps:

int maxVolume = 50;

Then to set setVolume to any value in this range (0-49) you do this:

float log1=(float)(Math.log(maxVolume-currVolume)/Math.log(maxVolume));
yourMediaPlayer.setVolume(1-log1);

Nice and easy! And DON'T use AudioManager to set volume! It will cause many side effects such as disabling silent mode, which will make your users mad!

7 upvote
  flag
+1000 I've been looking for this solution for some time. Fantastic. Thanks! – Tomasz
upvote
  flag
+1 Worked like a charm! Thanks mate. – Sajmon
upvote
  flag
I have to use AudioManager when trying to mute in Text to Speech. Is there any better way to set mute in Text to Speech? – Jacky
upvote
  flag
Have you tried manipulating AudioManager.STREAM_MUSIC stream? – ssuukk
upvote
  flag
@ssuukk setVolume method has two parameters setVolume(float, float). How are you getting away with one? – Sudhir Khanger
upvote
  flag
You're right. Maybe I've taken a shortcut writing this, maybe it's a code applying volume to some custom media player class. Note that if you've used Kotlin instead of Java you could write an extension function to MediaPlayer that does this: MediaPlayer.setVolume(x : Float) {...} – ssuukk
upvote
  flag
log(maxVolume - currVolume) will return float infinity when (maxVolume == currVolum), so it's better to check this – Vadim
upvote
  flag
@ssuukk What is the formula if currVolume is a float varying between 0 and 1. I am using an animation to hide a view, and simultaneously lowers the volume on player. Animation is value animator (1F -> 0F), and I do not want to make a redundant conversion from animation value to integer volume mentioned in this answer. – h.nodehi
1 upvote
  flag
@Vadim currVolume is an integer in the range [0,maxVolume-1] so it should not be possible for it to have the value of maxVolume. Note that for currVolume == maxVolume-1 you get log1 == 0 and setVolume(1) (or, using the current signature of the method: setVolume(1,1)), meaning full volume. – et_l

Following user100858 solution I just post my exact code that works:

private final static int MAX_VOLUME = 100;
...
...
final float volume = (float) (1 - (Math.log(MAX_VOLUME - soundVolume) / Math.log(MAX_VOLUME)));
mediaPlayer.setVolume(volume, volume);

soundVolume is the volume you would like to set, between 0 and MAX_VOLUME. So between 0 and 100 in this example.

4 upvote
  flag
what is soundVolume ? Where does it originate ? – Someone Somewhere
3 upvote
  flag
@SomeoneSomewhere... It Comes from SomeWhere.. :P – Sreekanth Karumanaghat
2 upvote
  flag
Dude that is the volume we want to set... :P – Sreekanth Karumanaghat
2 upvote
  flag
Works like magic,thanks Tomasz :) – Sreekanth Karumanaghat
3 upvote
  flag
To those of you wondering, soundVolume is the variable between 0-100 that you want the volume to be. If you want a finer adjusted tune, consider setting the maxVolume up to 1000 and of course keep the soundVolume between 0-1000 then. – Andreas Rudolph
upvote
  flag
+1 Worked like a charm, thanks mate. – Sajmon

Why making it so complicated? I am using this simple formula:

public float getVolume() {
    float currVolume = (float) sp.getInt("volume", 10);
    float maxVolume = 15.0f;
    float result = currVolume / maxVolume;
    return result;
}

and setting this value in media player, like:

player.setVolume(getVolume(), getVolume());
1 upvote
  flag
What's sp in this code snippet above? SharedPreferences? – FuzzyAmi
upvote
  flag
MediaPlayer documentation recommends: "Note that the passed volume values are raw scalars in range 0.0 to 1.0. UI controls should be scaled logarithmically.". – Paweł Nadolski
upvote
  flag
FuzzyAmi , yes sp is shared preference. – Jan
upvote
  flag
@PawełNadolski after dividing it with max volume , the result will be equal or less than 1.0. – Jan
upvote
  flag
@Jan, yes, but it won't be scaled logarithmically :) So, your approach is correct, but not recommended by official documentation. – Paweł Nadolski

The other answers here are not correct--or at least, they're not configured properly.

Perform the following test, using their code (e.g. that of Tomasz or ssuukk):

1) Set 100 as the "max volume"/number of steps, and submit the volume 50.

It returns: 0.150514997831991

2) Set 1000 as the "max volume"/number of steps, and submit the volume 500.

What does it return? The same value, 0.150514997831991, right?

Nope. Instead, it's: 0.100343331887994

In other words, the existing answers change how they scale the input volume-percent (i.e. the transformation curve) based on how many volume-steps you set.

I've spent the last few hours looking into this issue; enough that I don't feel like going into too much detail explaining the issue. Instead I'll just post the large code/comment block in my program concerning it. (it's in C#, for Xamarin Android, but the functionality should be the same for Java)

public enum VolumeScaleType
{
    //Energy, // what MediaPlayer possibly treats passed values as
    Amplitude, // what MediaPlayer most likely treats passed values as
    Loudness // what people treat everyday volume values as (as in "that sounded 2 times as loud")
}

// MediaPlayer
/*public static void SetVolume_IncorrectSOApproach(this MediaPlayer s, double volume, VolumeScaleType volumeType = VolumeScaleType.Loudness)
{
    const int maxVolume = 100;
    var volume_toScale = volume * maxVolume;
    double volume_scalar = volumeType == VolumeScaleType.Amplitude ? volume : (1 - (Math.Log(maxVolume - volume_toScale) / Math.Log(maxVolume)));
    s.SetVolume((float)volume_scalar, (float)volume_scalar);
}*/

public static void SetVolume_MyPossiblyCorrectApproach(this MediaPlayer s, double volume, VolumeScaleType volumeType = VolumeScaleType.Loudness)
{
    // Links:
    // 1) http://en.wikipedia.org/wiki/Decibel
    // 2) http://trace.wisc.edu/docs/2004-About-dB
    // 3) http://hyperphysics.phy-astr.gsu.edu/hbase/sound/loud.html
    // 4) http://www.animations.physics.unsw.edu.au/jw/dB.htm
    // 5) http://www.soundmaskingblog.com/2012/06/saved_by_the_bell
    // 6) http://www.campanellaacoustics.com/faq.html
    // 7) http://physics.stackexchange.com/questions/9113/how-sound-intensity-db-and-sound-pressure-level-db-are-related
    // 8) http://www.sengpielaudio.com/calculator-loudness.htm (note: page uses terms 'power/intensity' and 'pressure' differently; power/intensity: for whole shell at distance, pressure: field-quantity?)
    // basic idea: you can think of one decibel (of gain), + or -, as *translating into* the given changes-in/multipliers-for energy, amplitude, or loudness
    // (i.e. one decibel provides a specific amount to multiply energy, amplitude, and loudness values, such that they remain aligned realistically)
    // note: the 'one decibel' unit is set up to correspond roughly to a change in loudness just substantial enough to be noticeable
    // note: the 'quietest perceivable sound' example (standard) base has these absolute values: 'e' is 1 pico-watt per square-foot, 'a' is 20 micropascals, 'l' is the quietest-perceivable-loudness

    // references (for q.p.s. base)   | db (gain) | energy           | amplitude            | loudness
    // ===============================================================================================
    // actual silence                 | -inf      | 0                | 0                    | 0
    // (a seeming silence)            | -20       | e / 100          | a / 10               | 0 (would be l / 4, if 'l' weren't already for the quietest-perceivable-sound)
    // (a seeming silence)            | -10       | e / 10           | a / 3.16227/sqrt(10) | 0 (would be l / 2, if 'l' weren't already for the quietest-perceivable-sound)
    // quietest perceivable sound     | 0         | e                | a                    | l
    // ?                              | 1         | e * 1.258925     | a * 1.122018         | l * 1.071773
    // rustling leaves                | 10        | e * 10           | a * 3.16227/sqrt(10) | l * 2
    // whisper, or rural nighttime    | 20        | e * 100          | a * 10               | l * 4
    // watch ticking                  | 30        | e * 1000         | a * 31.622/sqrt(100) | l * 8
    // quiet speech, or rural daytime | 40        | e * 10000        | a * 100              | l * 16
    // dishwasher in next room        | 50        | e * 100000       | a * 316/sqrt(100000) | l * 32
    // ordinary conversation          | 60        | e * 1000000      | a * 1000             | l * 64
    // ===============================================================================================

    // assuming MediaPlayer.SetVolume treats passed values as Amplitude
    Func<double, double> convertLoudnessToAmplitude = loudness=>Math.Pow(10, Math.Log(loudness, 4));
    var volume_amplitude = volumeType == VolumeScaleType.Amplitude ? volume : convertLoudnessToAmplitude(volume);
    s.SetVolume((float)volume_amplitude, (float)volume_amplitude);
    // assuming MediaPlayer.SetVolume treats passed values as Energy
    //Func<double, double> convertLoudnessToEnergy = loudness=>Math.Pow(100, Math.Log(loudness, 4));
    //var volume_energy = volumeType == VolumeScaleType.Energy ? volume : convertLoudnessToEnergy(volume);
    //s.SetVolume((float)volume_energy, (float)volume_energy);
}

Conclusion

The documentation is sparse, so I can't know for sure if I have the right scaling-system/type-of-unit the SetVolume method expects.

Assuming it expects an Amplitude value, the code above may be the correct volume setting code for it. (taking desired Loudness, linear, as an input, and outputting/setting the Amplitude value needed for the built-in SetVolume method)

I'm not sure it's correct, though, and am too tired to confirm. If anyone has further thoughts, feel free to add them. (3+ hours is enough to spend on an issue like this, in one day)

Edit

After listening carefully, and comparing the loudness-fade effect by:

  1. Just submitting the desired loudness to the SetVolume method.
  2. Exponentiating (basically) the desired-loudness before sending it in, to make it an Amplitude (or the like) value that the SetVolume method says it expects.

I find that option 1 seems to be closer to a linear loudness fade-in! In other words... from actually listening and comparing the basic approach, with the various transformation approaches shown here, it seems the documentation is wrong and the SetVolume method does in fact just expect the loudness value on a linear scale. (perhaps they've updated it to work more intuitively in one of the recent API versions, but haven't updated the docs?)

If so, that sure makes it easy. That's what I'm going with for now. (though I'll keep the exponentiation/scale-fixing approach as a program setting, I suppose, just to have an excuse to keep some result of all that time invested!)

The recommended answer is wrong, as stated Venryx. Log math doesn't work that way (you have to subtract, not divide logs to make them work how you want).

No matter, it looks like Android Volume setting is now proportionate to Loudness linearly... so 0.5 is 50% as loud as 1.0, and 0.1 is 10%, etc. No need for complicated Log math to convert decibels to loudness. Just set it linearly as is intuitive to most people.

Not the answer you're looking for? Browse other questions tagged or ask your own question.