Android : MediaPlayer setVolume 함수
매개 변수 정보 플레이어에서 소리가 나지 않고 전체 소리가 나도록 설정
감사
이 기능은 실제로 훌륭합니다. 덕분에 여러 단계로 볼륨 스케일을 만들 수 있습니다!
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를 사용하여 볼륨을 설정하지 마십시오! 자동 모드 비활성화와 같은 많은 부작용이 발생하여 사용자를 화나게 할 것입니다!
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 사이입니다.
의 경우 Android MediaPlayer.setVolume
웹을 검색하면 0.0f
소리가 들리지 않고 1.0f
전체 소리가 나는 것으로 보입니다 .
여기에있는 다른 답변은 정확하지 않거나 적어도 제대로 구성되지 않았습니다.
해당 코드 (예 : Tomasz 또는 ssuukk의 코드)를 사용하여 다음 테스트를 수행합니다.
1) 100을 '최대 볼륨'/ 단계 수로 설정하고 볼륨 50을 제출합니다.
반환 : 0.150514997831991
2) 1000을 "최대 볼륨"/ 단계 수로 설정하고 볼륨 500을 제출합니다.
무엇을 반환합니까? 같은 값, 0.150514997831991 맞죠?
아니. 대신 0.100343331887994입니다.
즉, 기존 답변은 설정 한 볼륨 단계 수에 따라 입력 볼륨 비율 (즉, 변환 곡선)을 조정하는 방법을 변경합니다 .
지난 몇 시간 동안이 문제를 조사했습니다. 문제를 너무 자세하게 설명하고 싶지 않을 정도로 충분합니다. 대신에 그것에 관한 내 프로그램에 큰 코드 / 주석 블록을 게시 할 것입니다. (Xamarin Android의 경우 C #에 있지만 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 메서드가 예상하는 올바른 스케일링 시스템 / 유닛 유형이 있는지 확인할 수 없습니다.
Amplitude 값을 예상한다고 가정하면 위의 코드가 올바른 볼륨 설정 코드 일 수 있습니다. (원하는 Loudness, 선형을 입력으로 취하고 내장 된 SetVolume 메소드에 필요한 Amplitude 값을 출력 / 설정)
그래도 정확하지 않고 확인하기에는 너무 피곤합니다. 추가 생각이있는 사람이 있으면 자유롭게 추가하십시오. (하루에 이와 같은 문제에 3 시간 이상이면 충분합니다.)
편집하다
주의 깊게 듣고 라우드니스 페이드 효과를 비교 한 후 :
- 원하는 음량을 SetVolume 메서드에 제출하기 만하면됩니다.
- SetVolume 메서드가 예상하는 진폭 (또는 유사) 값으로 만들기 위해 원하는 크기를 (기본적으로) 지수화하여 전송합니다.
옵션 1이 선형 라우드니스 페이드 인에 더 가까운 것 같습니다! 즉 ... 실제로 듣고 기본 접근 방식을 여기에 표시된 다양한 변환 접근 방식과 비교하면 문서가 잘못된 것으로 보이며 SetVolume 메서드는 실제로 선형 스케일에서 음량 값을 기대합니다. (아마도 최신 API 버전 중 하나에서 더 직관적으로 작동하도록 업데이트했지만 문서를 업데이트하지 않았습니까?)
그렇다면 확실히 쉽게 할 수 있습니다. 그게 지금 제가 할 일입니다. (나는 프로그램 설정으로 지수화 / 스케일 고정 접근 방식을 유지할 것이지만, 투자 된 모든 시간의 결과를 유지하기위한 변명을 가질 것입니다!)
Venryx가 언급했듯이 권장 답변은 잘못되었습니다. 로그 수학은 그런 방식으로 작동하지 않습니다 (원하는 방식으로 작동하도록 로그를 나누지 말고 빼야합니다).
어쨌든 Android 볼륨 설정은 이제 라우드니스에 선형 적으로 비례하는 것처럼 보입니다. 0.5는 1.0의 50 %, 0.1은 10 % 등입니다. 데시벨을 라우드니스로 변환하기 위해 복잡한 로그 수학이 필요하지 않습니다. 대부분의 사람들에게 직관적 인 것처럼 선형 적으로 설정하십시오.
Android를 사용해 MediaPlayer.setVolume
보았지만이 기능은 쓸모가 없습니다.
아래 기능을 사용해야한다고 생각합니다
AudioManager mAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, maxVolume * mLastProgress / 10, 0);
이 코드는 볼륨을 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에서 50까지의 척도에서 25는 중간에 있지 않고 오히려 최대 사운드에 훨씬 더 가깝다는 것입니다. 여기에서 제안한 로그 함수는 거의 차이가 없었습니다.
To read more on the math, see this answer.
Variables
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
Formula where change decelerates as value goes up (simplest form)
Problem with this approach is that this is the opposite of what we want with android because it seems to already be doing this by default. It's already incrementing too fast when the values are still low when you pass linear values and this accentuates this effect even further.
x1 + (log(x) - log(x1)) / (log(x2) - log(x1)) * (y2 - y1) = z
Formula where change accelerates as value goes up
This is the approach that works for me; flipping the input to keep the same rate of change, but inversed. With this, I get just about a perfect mid-volume at around 25 and it's a very smooth hearing experience from 0 all the way to 50.
y2 - (x1 + (log(x2 + x1 - x) - log(x1)) / (log(x2) - log(x1)) * (y2 - y1)) = z
Why making it so complicated? I am using this simple formula:
public float getVolume() {
float currVolume = (float) sp.getInt("volume", 10);
float maxVolume = 15.0f;
float result = currVolume / maxVolume;
return result;
}
and setting this value in media player, like:
player.setVolume(getVolume(), getVolume());
Well, I made the following code and it slightly works:
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);
}
});
}
}
ReferenceURL : https://stackoverflow.com/questions/5215459/android-mediaplayer-setvolume-function
'programing' 카테고리의 다른 글
div 요소를 편집 가능하게 만들려면 어떻게해야합니까 (클릭 할 때 텍스트 영역처럼)? (0) | 2021.01.16 |
---|---|
instanceof-호환되지 않는 조건부 피연산자 유형 (0) | 2021.01.16 |
자바 InputStream 모의 (0) | 2021.01.16 |
삼항 연산자에 사용하는 코딩 스타일은 무엇입니까? (0) | 2021.01.16 |
왼쪽 / 오른쪽과 위 / 아래 사이의 스 와이프 방향을 감지하는 방법 (0) | 2021.01.16 |