Android: Fonction MediaPlayer setVolume

A propos des params Définir quoi faire le Joueur pas de son et le son complet

Merci

48
demandé sur Qing 2011-03-07 06:17:15

7 réponses

cette fonction est en fait merveilleuse. Grâce à lui, vous pouvez créer une échelle de volume avec n'importe quel nombre d'étapes!

supposons que vous voulez 50 pas:

int maxVolume = 50;

ensuite pour définir setVolume à n'importe quelle valeur dans cette gamme (0-49) vous faites ceci:

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

Agréable et facile! Et N'utilisez pas AudioManager pour régler le volume! Il causera de nombreux effets secondaires tels que la désactivation du mode silencieux, ce qui rendra vos utilisateurs fous!

105
répondu ssuukk 2012-08-22 14:56:16

suite user100858 solution je viens de poster mon code exact qui fonctionne:

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 est le volume que vous souhaitez définir, entre 0 et MAX_VOLUME. Donc entre 0 et 100 dans cet exemple.

47
répondu Tomasz 2013-06-28 00:28:28

pour Android MediaPlayer.setVolume , la recherche sur le web semble indiquer 0.0f pour aucun son, 1.0f pour le son complet.

40
répondu typo.pl 2012-05-14 12:31:16

les autres réponses ici ne sont pas correctes--ou du moins, elles ne sont pas configurées correctement.

effectuer l'essai suivant, en utilisant leur code (par exemple celui de Tomasz ou de ssuukk):

1) Définissez 100 comme"volume maximal" /nombre d'étapes, et soumettez le volume 50.

il retourne: 0.150514997831991

2) Définissez 1000 comme le"volume maximal" /nombre d'étapes, et soumettez le volume 500.

quoi est-il de retour? La même valeur, 0.150514997831991, c'est ça?

Non. Au lieu de cela, c'est: 0.100343331887994

en d'autres termes, les réponses existantes changent la façon dont elles ajustent le pourcentage du volume d'entrée (c.-à-d. la courbe de transformation) en fonction du nombre d'étapes du volume que vous définissez .

j'ai passé les dernières heures à étudier cette question; assez pour ne pas avoir envie d'entrer dans les détails en expliquant la question. Au lieu de cela, je vais juste poster le grand bloc de code / commentaire dans mon programme à ce sujet. (c'est en C#, pour Xamarin Android, mais la fonctionnalité devrait être la même pour 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

la documentation est clairsemée, donc je ne peux pas savoir avec certitude si j'ai le bon système d'échelle/type d'unité que la méthode SetVolume attend.

en supposant qu'il s'attend à une valeur D'Amplitude, le code ci-dessus peut être le réglage de volume correct. code pour cela. (prise de la sonie désirée, linéaire, comme entrée, et sortie/réglage de la valeur D'Amplitude nécessaire pour la méthode SetVolume intégrée)

Je ne suis pas sûr que ce soit correct, cependant, et je suis trop fatigué pour le confirmer. Si quelqu'un a d'autres propositions, n'hésitez pas à les ajouter. (3+ heures sont suffisantes pour passer sur une question comme celle-ci, en une journée)

Modifier

après avoir écouté attentivement, et en comparant l'effet de bruissement-fondu par:

  1. Juste la soumission de l'intensité souhaitée à l'SetVolume méthode.
  2. exponentielle (fondamentalement) la sonie désirée avant de l'Envoyer, pour en faire une valeur D'Amplitude (ou similaire) que la méthode SetVolume indique qu'elle attend.

je trouve que l'option 1 semble plus proche d'une diminution linéaire de la sonie! En d'autres termes... de fait l'écoute et la comparaison de l'approche de base, avec les différents transformation les approches montrées ici, il semble que la documentation est erronée et la méthode SetVolume ne s'attend en fait qu'à la valeur de la sonie sur une échelle linéaire. (peut-être l'ont-ils mis à jour pour fonctionner plus intuitivement dans l'une des versions récentes de L'API, mais n'ont-ils pas mis à jour les docs?)

si c'est le cas, c'est facile. C'est ce que je vais faire avec pour l'instant. (bien que je garde l'approche exponentiation / scale-fixing comme un cadre de programme, je suppose, juste pour avoir une excuse pour garder un certain résultat de tout ce temps investi!)

10
répondu Venryx 2015-12-13 17:59:12

j'ai essayé Android MediaPlayer.setVolume , mais cette fonction est inutile.

je pense que nous devrions utiliser la fonction ci-dessous

AudioManager mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume * mLastProgress / 10, 0);
5
répondu Allen Zhang 2013-08-30 07:00:11

la réponse recommandée est fausse, comme L'a déclaré Venryx. Le calcul des logs ne fonctionne pas de cette façon (vous devez soustraire les logs, pas les diviser pour les faire fonctionner comme vous le voulez).

peu importe, il semble que le réglage du Volume Android est maintenant proportionnel à la sonie linéairement... donc 0,5 est 50% aussi fort que 1,0, et 0,1 est 10%, etc. Pas besoin de calculs compliqués pour convertir les décibels en intensité sonore. Il suffit de le mettre linéairement comme est intuitif pour la plupart des gens.

5
répondu najak 2016-04-07 09:34:41

pourquoi rendre les choses si compliquées? J'utilise cette formule simple:

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

et le réglage de cette valeur dans media player, comme:

player.setVolume(getVolume(), getVolume());
0
répondu Jan 2016-02-04 18:58:21