Android: функция MediaPlayer setVolume - PullRequest
53 голосов
/ 07 марта 2011

о параметрах Установите, чтобы проигрыватель не звучал и не звучал полноценно

Спасибо

Ответы [ 10 ]

111 голосов
/ 22 августа 2012

Эта функция действительно замечательная. Благодаря этому вы можете создать шкалу громкости с любым количеством шагов!

Предположим, вы хотите 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 для установки громкости! Это вызовет множество побочных эффектов, таких как отключение бесшумного режима, что приведет ваших пользователей в бешенство!

50 голосов
/ 30 августа 2012

После 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 в этом примере.

41 голосов
/ 07 марта 2011

Для Android MediaPlayer.setVolume, при поиске в Интернете 0.0f отсутствует звук, 1.0f - полный звук.

12 голосов
/ 13 декабря 2015

Другие ответы здесь не верны - или, по крайней мере, они не настроены должным образом.

Выполните следующий тест, используя их код (например, код 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+ часа достаточно, чтобы потратить на такую ​​проблему за один день)

Редактировать

После тщательного прослушивания и сравнения эффекта затухания громкости с помощью:

  1. Просто отправьте желаемую громкость в метод SetVolume.
  2. Укажите (в основном) желаемую громкость перед отправкой, чтобы сделать его значением Amplitude (или подобным), которое метод SetVolume говорит, что он ожидает.

Я считаю, что вариант 1, похоже, ближе к линейному постепенному увеличению громкости!Другими словами ... из фактического прослушивания и сравнения базового подхода с различными подходами преобразования, показанными здесь, кажется, что документация неверна, а метод SetVolume фактически просто ожидает значение громкости в линейном масштабе.(возможно, они обновили его, чтобы он стал более интуитивно понятным в одной из последних версий API, но не обновили документы?)

Если это так, то это действительно облегчает задачу.Это то, с чем я собираюсь сейчас.(хотя я оставлю подход возведения в степень / фиксации масштаба как настройку программы, я полагаю, просто для того, чтобы иметь оправдание сохранить какой-то результат всего этого затраченного времени!)

8 голосов
/ 07 апреля 2016

Рекомендуемый ответ неверен, как заявлено Venryx. Логика математики работает не так (приходится вычитать, а не делить журналы, чтобы заставить их работать так, как вы хотите).

Неважно, похоже, что громкость Android теперь линейно пропорциональна громкости ... так что 0,5 - это 50% громкости, как 1,0, и 0,1 - 10% и т. Д. Нет необходимости в сложной математической функции для преобразования децибел в громкость. , Просто установите его линейно, как это интуитивно понятно большинству людей.

5 голосов
/ 14 августа 2012

Я пробовал Android MediaPlayer.setVolume, но эта функция бесполезна.

Я думаю, что мы должны использовать функцию ниже

AudioManager mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume * mLastProgress / 10, 0);
1 голос
/ 02 ноября 2018

Все, что я видел здесь, не оправдало моих ожиданий.Основная проблема, с которой я столкнулся, заключалась в том, что по шкале от 0 до 50 25 никогда не находились посередине, а гораздо ближе к максимальному звучанию.Функции журнала, предложенные здесь, для меня почти не имели значения.

Чтобы узнать больше по математике, см. этот ответ .

Переменные

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

Результаты этой функции

1 голос
/ 23 октября 2018

Этот код разбивает громкость на 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)

0 голосов
/ 14 мая 2019

Ну, я сделал следующий код, и он немного работает:

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);
            }
        });
    }
}
0 голосов
/ 20 февраля 2015

Зачем делать это так сложно? Я использую эту простую формулу:

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

и установка этого значения в медиаплеере, например:

player.setVolume(getVolume(), getVolume());
...