audio - Android: функция MediaPlayer setVolume





media-player (7)


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

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

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

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

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

благодаря




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

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

AudioManager mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume * mLastProgress / 10, 0);



Следуя решению 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 в этом примере.




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

Предположим, вы хотите 50 шагов:

int maxVolume = 50;

Затем, чтобы установить setVolume в любое значение в этом диапазоне (0-49), вы выполните следующее:

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

Легко и приятно! И НЕ используйте AudioManager для установки громкости! Это вызовет много побочных эффектов, таких как отключение бесшумного режима, что сделает ваши пользователи безумными!




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

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




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

Выполните следующий тест, используя свой код (например, 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. Экспоненциальная (в основном) желаемая громкость перед отправкой в ​​нее, чтобы сделать это значение амплитуды (или тому подобное), которое, по мнению метода SetVolume, ожидает.

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

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




Мой коллега написал статью, объясняющую состояние приложения на устройствах Android, включая пояснения о жизненном SharedPreferences активности и информации о состоянии, сохранении информации о состоянии и сохранении в State Bundle и SharedPreferences и взгляните сюда .

В статье рассматриваются три подхода:

Хранить данные локального varible / UI для времени жизни приложения (т.е. временно) с использованием пакета State State State Bundle

[Code sample – Store State in State Bundle]
@Override
public void onSaveInstanceState(Bundle savedInstanceState) 
{
  // Store UI state to the savedInstanceState.
  // This bundle will be passed to onCreate on next call.  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  savedInstanceState.putString(“Name”, strName);
  savedInstanceState.putString(“Email”, strEmail);
  savedInstanceState.putBoolean(“TandC”, blnTandC);

  super.onSaveInstanceState(savedInstanceState);
}

Хранить данные локального переменного / пользовательского интерфейса между экземплярами приложения (т.е. постоянно) с использованием общих настроек

[Code sample – Store State in SharedPreferences]
@Override
protected void onPause() 
{
  super.onPause();

  // Store values between instances here
  SharedPreferences preferences = getPreferences(MODE_PRIVATE);
  SharedPreferences.Editor editor = preferences.edit();  // Put the values from the UI
  EditText txtName = (EditText)findViewById(R.id.txtName);
  String strName = txtName.getText().toString();

  EditText txtEmail = (EditText)findViewById(R.id.txtEmail);
  String strEmail = txtEmail.getText().toString();

  CheckBox chkTandC = (CheckBox)findViewById(R.id.chkTandC);
  boolean blnTandC = chkTandC.isChecked();

  editor.putString(“Name”, strName); // value to store
  editor.putString(“Email”, strEmail); // value to store
  editor.putBoolean(“TandC”, blnTandC); // value to store    
  // Commit to storage
  editor.commit();
}

Сохранение экземпляров объектов в памяти между действиями в течение жизненного цикла приложения с использованием экземпляра остаточной неконфигурации

[Code sample – store object instance]
private cMyClassType moInstanceOfAClass;// Store the instance of an object
@Override
public Object onRetainNonConfigurationInstance() 
{
  if (moInstanceOfAClass != null) // Check that the object exists
      return(moInstanceOfAClass);
  return super.onRetainNonConfigurationInstance();
}




android audio media-player volume