Android: funkcja MediaPlayer setVolume

O params Ustaw co zrobić, aby odtwarzacz nie miał dźwięku i pełnego dźwięku

Thanks

Author: Qing, 2011-03-07

7 answers

Ta funkcja jest naprawdę cudowna. Dzięki niemu możesz stworzyć skalę głośności z dowolną liczbą kroków!

Załóżmy, że chcesz 50 kroków:

int maxVolume = 50;

Następnie, aby ustawić setVolume na dowolną wartość z tego zakresu (0-49), robisz to:

float log1=(float)(Math.log(maxVolume-currVolume)/Math.log(maxVolume));
yourMediaPlayer.setVolume(1-log1);
Spokojnie! I nie używaj Audiomanagera do ustawiania głośności! Spowoduje to wiele skutków ubocznych, takich jak wyłączenie trybu cichego, co sprawi, że użytkownicy oszaleją!
 105
Author: ssuukk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-22 14:56:16

Following user100858 solution I just post my exact code that works:

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 to głośność, którą chcesz ustawić, między 0 a MAX_VOLUME. Więc między 0 a 100 w tym przykładzie.

 47
Author: Tomasz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-28 00:28:28

Dla Android MediaPlayer.setVolume, wyszukiwanie w sieci wydaje się wskazywać 0.0f na brak dźwięku, 1.0f na pełny dźwięk.

 40
Author: typo.pl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-14 12:31:16

Inne odpowiedzi tutaj nie są poprawne--a przynajmniej nie są poprawnie skonfigurowane.

Wykonaj następujący test, używając ich kodu (np. Tomasza lub ssuukka):

1) Ustaw 100 jako "max volume" /ilość kroków, i prześlij głośność 50.

Zwraca: 0.150514997831991

2) Ustaw 1000 jako "max volume" /ilość kroków, i prześlij głośność 500.

Co zwraca? Ta sama wartość, 0.150514997831991, prawda?

Nie. Zamiast, jest to: 0.100343331887994

Innymi słowy, istniejące odpowiedzi zmieniają sposób, w jaki skalują procent objętości wejściowej (tj. krzywą transformacji) na podstawie liczby kroków wolumenu ustawionych.

Spędziłem ostatnie kilka godzin, przyglądając się temu problemowi; na tyle, że nie mam ochoty wchodzić w zbyt wiele szczegółów wyjaśniających problem. Zamiast tego po prostu wrzucę duży blok kodu/komentarza do mojego programu. (jest w C#, dla Xamarin Android, ale funkcjonalność powinna być to samo dla Javy)

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);
}

Podsumowanie

Dokumentacja jest niewielka, więc nie mogę być pewien, czy mam odpowiedni system skalowania / typ jednostki, którego oczekuje metoda SetVolume.

Zakładając, że oczekuje wartości amplitudy, powyższy kod może być dla niego prawidłowym kodem ustawiającym głośność. (biorąc pożądaną głośność, liniową, jako wejście i wyprowadzając / ustawiając wartość amplitudy potrzebną dla wbudowanej metody SetVolume)

Nie jestem pewien, czy to prawda, ale jestem zbyt zmęczony żeby potwierdzić. Jeśli ktoś ma inne przemyślenia, proszę je dodać. (3 + godziny wystarczą, aby wydać na taki problem w ciągu jednego dnia)

Edit

Po uważnym wysłuchaniu i porównaniu efektu loudness-fade przez:

  1. wystarczy przesłać żądaną głośność do metody SetVolume.
  2. wykładnicza (zasadniczo) pożądanej głośności przed wysłaniem go, aby uczynić ją amplitudą (lub podobną) wartość, którą mówi metoda SetVolume oczekuje.

Uważam, że opcja 1 wydaje się być bliżej liniowego zaniku głośności! Innymi słowy... słuchając i porównując podstawowe podejście, z pokazanymi tutaj różnymi podejściami transformacji, wydaje się, że dokumentacja jest błędna i metoda SetVolume w rzeczywistości oczekuje tylko wartości głośności w skali liniowej. (być może zaktualizowali go, aby działał bardziej intuicyjnie w jednej z ostatnich wersji API, ale nie zaktualizowali dokumentów?)

Jeśli tak, to pewnie to ułatwia sprawę. To jest to, co zamierzam teraz. (chociaż zachowam podejście wykładnicze/ustalanie skali jako ustawienie programu, przypuszczam, tylko po to, aby mieć pretekst, aby zachować jakiś wynik całego tego czasu zainwestowanego!)

 10
Author: Venryx,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-13 17:59:12

Próbowałem Android MediaPlayer.setVolume, ale ta funkcja jest bezużyteczna.

Myślę, że powinniśmy użyć funkcji poniżej

AudioManager mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume * mLastProgress / 10, 0);
 5
Author: Allen Zhang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-30 07:00:11

Zalecana odpowiedź jest błędna, jak stwierdził Venryx. Log math nie działa w ten sposób (musisz odejmować, a nie dzielić dzienniki, aby działały tak, jak chcesz).

Nieważne, wygląda na to, że ustawienie głośności Androida jest teraz proporcjonalne do głośności liniowo... więc 0.5 to 50% tak głośne jak 1.0, A 0.1 to 10% itd. Nie ma potrzeby skomplikowanej matematyki logów, aby przekonwertować decybele na głośność. Po prostu ustaw go liniowo, ponieważ jest intuicyjny dla większości ludzi.

 5
Author: najak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-07 09:34:41

Dlaczego to takie skomplikowane? Używam tego prostego wzoru:

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

I ustawienie tej wartości w odtwarzaczu multimedialnym, jak:

player.setVolume(getVolume(), getVolume());
 0
Author: Jan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-04 18:58:21