About the params, what do I need to do to make the player make no sound and to make full sound.
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(log1,log1); //set volume takes two paramater
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!
setVolume(float, float)
. How are you getting away with one? –
Fernandes MediaPlayer.setVolume(x : Float) {...}
–
Sheedy 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. –
Chump 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. –
Yes 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.
soundVolume
? Where does it originate ? –
Saturday For Android MediaPlayer.setVolume
,
searching the web seems to show 0.0f
for no sound, 1.0f
for full sound.
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. –
Trudi 0.5
is 50% as loud as 1
, which makes it easy. (the docs do appear to be outdated on this, but you can confirm it by doing careful by-ear testing/comparison -- which is what matters in the end anyway) –
Nudity 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:
- Just submitting the desired loudness to the SetVolume method.
- 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.
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);
MediaPlayer.setVolume
useless? What weren't you able to do? –
Henrieta Everything I have seen here has fallen short of my expectations. The main problem I had was that on a scale of 0 to 50, 25 was never in the middle but rather much closer to the maximum sound. The log functions proposed here made almost no difference for me.
To read more on the math, see this answer.
Variables
Linear input value = x // User-specified input value
Linear scale min,max = x1,x2 // My pre-determined range of 0-50 on my UI
Log scale min,max = y1,y2 // Normalizes the log result to between 0-1
Log value result = z // The output to pass to the setVolume() method
Formula where change decelerates as value goes up (simplest form)
Problem with this approach is that this is the opposite of what we want with android because it seems to already be doing this by default. It's already incrementing too fast when the values are still low when you pass linear values and this accentuates this effect even further.
x1 + (log(x) - log(x1)) / (log(x2) - log(x1)) * (y2 - y1) = z
Formula where change accelerates as value goes up
This is the approach that works for me; flipping the input to keep the same rate of change, but inversed. With this, I get just about a perfect mid-volume at around 25 and it's a very smooth hearing experience from 0 all the way to 50.
y2 - (x1 + (log(x2 + x1 - x) - log(x1)) / (log(x2) - log(x1)) * (y2 - y1)) = z
This code breaks down volume into 10 equal sections and increase or descrease volume.
Button decreaseVolButton = (Button) findViewById(R.id.decrease_volumn);
Button increaseVolButton = (Button) findViewById(R.id.increase_volumn);
final MediaPlayer mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.sample);
decreaseVolButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
volume = (float) (volume - 0.1);
mediaPlayer.setVolume(volume, volume);
}
});
increaseVolButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
volume = (float) (volume + 0.1);
mediaPlayer.setVolume(volume, volume);
}
});
If you want to set the volume to no sound then pass (0f,0f)
If you want to set the volume to full sound then pass (1f,1f)
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());
Since volume scales linearly, needless for complicated log function. Adjust the maxVolume, it's 100 steps in the sample code below, accordingly to the step you prefer and it should work. Hope this would help.
MediaPlayer myPlayer = MediaPlayer.create(MainActivity.this, R.raw.myAudioResource);
final float maxVolume = 100.0f;
float currentVolume = 5.0f;
myPlayer.setVolume(currentVolume/maxVolume, currentVolume/maxVolume);
myPlayer.start();
Well, I made the following code and it slightly works:
public class MainActivity extends Activity {
float volumeLevel = 0.5f;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
volumeUp = findViewById(R.id.volUp);
volumeDown = findViewById(R.id.volDown);
song = MediaPlayer.create(this, R.raw.audioFile);
volumeUp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
volumeLevel = volumeLevel + 0.1f;
song.setVolume(volumeLevel,volumeLevel);
}
});
volumeDown.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
volumeLevel = volumeLevel - 0.1f;
song.setVolume(volumeLevel,volumeLevel);
}
});
}
}
© 2022 - 2024 — McMap. All rights reserved.