由于
答案 0 :(得分:110)
这个功能非常精彩。多亏了它,你可以用任意数量的步骤创建一个音量表!
我们假设您需要50个步骤:
int maxVolume = 50;
然后将setVolume设置为此范围内的任何值(0-49),执行以下操作:
float log1=(float)(Math.log(maxVolume-currVolume)/Math.log(maxVolume));
yourMediaPlayer.setVolume(log1,log1); //set volume takes two paramater
美好而轻松!并且不要使用AudioManager来设置音量!它会导致许多副作用,例如禁用静音模式,这会让你的用户发疯!
答案 1 :(得分:48)
在 user100858 解决方案之后,我发布了我的确切代码:
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是您要设置的音量,介于0和MAX_VOLUME之间。 所以在这个例子中0到100之间。
答案 2 :(得分:40)
Android MediaPlayer.setVolume
,
搜索网络似乎显示0.0f
没有声音,1.0f
表示完整的声音。
答案 3 :(得分:12)
此处的其他答案不正确 - 或者至少,它们未正确配置。
使用他们的代码(例如Tomasz或ssuukk的代码)执行以下测试:
1)将100设置为"最大音量" /步数,并提交音量50。
返回:0.150514997831991
2)将1000设置为"最大音量" /步数,并提交音量500.
它返回什么?相同的值,0.150514997831991,对吧?
不。相反,它是:0.100343331887994
换句话说,现有答案会根据您设置的音量步数来改变输入音量百分比(即转换曲线)的缩放方式。
我花了最后几个小时研究这个问题;足以让我不想详细解释这个问题。相反,我只是在我的程序中发布大型代码/注释块。 (它在C#中,对于Xamarin Android,但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);
}
文档很少,所以我无法确定我是否拥有SetVolume方法所期望的正确的缩放系统/单位类型。
假设它需要一个Amplitude值,上面的代码可能是正确的音量设置代码。 (获取所需的响度,线性,作为输入,并输出/设置内置SetVolume方法所需的Amplitude值)
但是,我不确定它是否正确,而且我太累了,不能确认。如果有人有进一步的想法,请随意添加它们。 (3个多小时足以在一天之内花在这样的问题上)仔细聆听后,通过以下方式比较响度衰减效果:
我发现选项1似乎更接近线性响度淡入!换句话说......从实际收听和比较基本方法,到这里显示的各种转换方法,似乎文档是错误的,而SetVolume方法实际上只是期望线性标度上的响度值。 (也许他们已经更新了它,以便在最新的API版本中更直观地工作,但还没有更新文档?)
如果是这样,那确实很容易。这就是我现在要做的事情。 (虽然我会将指数/缩放比例方法作为一个程序设置,但我想,只是有借口保留所有时间投入的结果!)
答案 4 :(得分:7)
正如Venryx所述,建议的答案是错误的。日志数学不起作用(你必须减去,而不是分割日志以使它们按你想要的方式工作)。
无论如何,看起来Android音量设置现在与Loudness线性相称...所以0.5是大声为1.0的50%,0.1是10%等等。不需要复杂的日志数学来将分贝转换为响度。只需对大多数人进行线性设置即可。
答案 5 :(得分:5)
我尝试过Android MediaPlayer.setVolume
,但此功能无用。
我认为我们应该使用下面的功能
AudioManager mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume * mLastProgress / 10, 0);
答案 6 :(得分:1)
我在这里看到的一切都达不到我的期望。我遇到的主要问题是,在0到50的范围内,25从来不在中间,而是更接近最大声音。这里提出的log函数对我几乎没有影响。
要详细了解数学,请参见this answer。
变量
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
公式,其值随值的增加而减小(最简单的形式)
这种方法的问题是,这与我们想要的android相反,因为默认情况下它似乎已经在这样做。当您传递线性值时,如果值仍然很低,则增量已经过快,这进一步加剧了这种影响。
x1 + (log(x) - log(x1)) / (log(x2) - log(x1)) * (y2 - y1) = z
随着价值的增长,变化加速的公式
这是对我有效的方法;翻转输入以保持相同的变化率,但是相反。有了这个,我在25左右的音量下就达到了完美的音量,从0一直到50都是非常流畅的听力体验。
y2 - (x1 + (log(x2 + x1 - x) - log(x1)) / (log(x2) - log(x1)) * (y2 - y1)) = z
答案 7 :(得分:0)
为什么要这么复杂?我使用这个简单的公式:
public float getVolume() {
float currVolume = (float) sp.getInt("volume", 10);
float maxVolume = 15.0f;
float result = currVolume / maxVolume;
return result;
}
并在媒体播放器中设置此值,例如:
player.setVolume(getVolume(), getVolume());
答案 8 :(得分:0)
此代码将音量分为10个相等的部分,并增加或减少音量。
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);
}
});
如果要将音量设置为无声音,则通过(0f,0f)
如果您想将音量设置为全声音,则通过(1f,1f)
答案 9 :(得分:0)
好吧,我编写了下面的代码,它稍微起作用了:
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);
}
});
}
}
答案 10 :(得分:0)
由于体积是线性缩放的,因此对于复杂的对数函数而言是不必要的。调整maxVolume,这是下面的示例代码中的100个步骤,根据您喜欢的步骤,它应该可以工作。希望这会有所帮助。
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();