パラメータについてプレイヤーに音を出さず、完全な音にするための設定
ありがとう
この機能は本当に素晴らしいです。そのおかげで、任意のステップ数でボリュームスケールを作成できます!
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を使用して音量を設定しないでください!サイレントモードを無効にするなど、多くの副作用を引き起こし、ユーザーを怒らせます!
次のser100858ソリューション
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メソッドが期待する正しいスケーリングシステム/ユニットのタイプがあるかどうかはわかりません。
振幅値を想定していると仮定すると、上記のコードはそのための正しいボリューム設定コードである可能性があります。 (入力として希望するラウドネス、リニアを取得し、組み込みのSetVolumeメソッドに必要な振幅値を出力/設定します)
しかし、それが正しいかどうかはわかりませんが、確認するには疲れすぎています。誰か他に考えがあれば、気軽に追加してください。 (このような問題に1日で費やすには3時間以上あれば十分です)
注意深く聞いて、音量フェード効果を次のように比較した後:
オプション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が決して真ん中にあるのではなく、最大音にかなり近いということでした。ここで提案したログ関数は、私にとってほとんど違いはありませんでした。
数学の詳細については、 this answer を参照してください。
変数
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
なぜそんなに複雑にするのですか?私はこの単純な式を使用しています:
public float getVolume() {
float currVolume = (float) sp.getInt("volume", 10);
float maxVolume = 15.0f;
float result = currVolume / maxVolume;
return result;
}
次のように、メディアプレーヤーでこの値を設定します。
player.setVolume(getVolume(), getVolume());
さて、私は次のコードを作成し、わずかに動作します:
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);
}
});
}
}