Другие ответы здесь не верны - или, по крайней мере, они не настроены должным образом.
Выполните следующий тест, используя их код (например, код 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.
Предполагая, что он ожидает значение амплитуды, приведенный выше код может быть правильным кодом настройки громкости для него.(принимая желаемую громкость, линейную, в качестве входа и выводя / устанавливая значение амплитуды, необходимое для встроенного метода SetVolume)
Я не уверен, что это правильно, но слишком устал, чтобы подтверждать.Если у кого-то есть дальнейшие мысли, не стесняйтесь добавлять их.(3+ часа достаточно, чтобы потратить на такую проблему за один день)
Редактировать
После тщательного прослушивания и сравнения эффекта затухания громкости с помощью:
- Просто отправьте желаемую громкость в метод SetVolume.
- Укажите (в основном) желаемую громкость перед отправкой, чтобы сделать его значением Amplitude (или подобным), которое метод SetVolume говорит, что он ожидает.
Я считаю, что вариант 1, похоже, ближе к линейному постепенному увеличению громкости!Другими словами ... из фактического прослушивания и сравнения базового подхода с различными подходами преобразования, показанными здесь, кажется, что документация неверна, а метод SetVolume фактически просто ожидает значение громкости в линейном масштабе.(возможно, они обновили его, чтобы он стал более интуитивно понятным в одной из последних версий API, но не обновили документы?)
Если это так, то это действительно облегчает задачу.Это то, с чем я собираюсь сейчас.(хотя я оставлю подход возведения в степень / фиксации масштаба как настройку программы, я полагаю, просто для того, чтобы иметь оправдание сохранить какой-то результат всего этого затраченного времени!)