2017-02-21 3 views
0

オーディオ入力の線形スケーリングを各チャンネルで同じスケーリングで実行しようとしています。スケーリング音Java

全体の効果は、入力ストリームがサイレントになるまで振幅が徐々に減少することです。したがって、私の最初のサンプルは同じままで、最後のサンプルは振幅の点で0になります。私はあなたがこれをどのように実装するのだろうと思っていた

これまでのところ、これはスケーリングコードのものであり、16桁の2の補数範囲の間にあるようにサンプルをスケールする必要があるかどうかは不思議でした。

for (int i=0; i<data.length; ++i){ // data[i] is sample in intger form 
     data[i] = (int) (data[i]*(something/something)); 
} 

特定の要素に合わせることが説明できる場合は役立つでしょうか?

ありがとうございます!

+1

実際の質問は何ですか?スケーリングを正確に行い、振幅を減少させるだけであれば、自動的に16ビットの範囲になります。しかし、あなたのコードは間違っています - なぜ最大値でサンプルを倍数にする必要があります - それは32ビットの範囲とはるかに大きい?ループの最初の繰り返しでゼロで割った場合、どうなりますか?あなたはコードを実行しましたか? –

+0

@erwin bolwidt私の質問はどのように線形に0にスケールするのですか?私は0で各サンプルを分けるだけですか? – Hawwa

答えて

1

あなたのオーディオデータの短い値([-32768.3.3767]など)で作業していて、バイトとの変換が他の場所で処理されているとします。

分数「何か/何か」において、分子は分母に等しい値からゼロまでの範囲にあり、分母は固定値のままです。

例では、音量範囲を128ステップに分割すると、最も大きな音量は128/128になり、最も音量が小さいものは0/128になります。

分割を避けるには、1/128に等しい係数を事前に計算し、[0..128]の範囲内の値で乗算します。

次に、 "something * precalculatedFactor"がありますが、これは少し速く動作するかもしれません。

しかし、線形のボリュームスケーリングには問題があります。実際に知覚される音量は直線的には追跡されません。したがって、Xのボリューム間隔は、ハイエンドではボリューム差をほとんど生成しないが、不連続性を引き起こし、ローエンドでクリックするほど大きくなる。

私は人々が指数関数を使ってボリュームを線形入力にマップすることがよくあると思います。どちらが最善であるかについては意見の相違があります。しかし、あなたのボリュームダイヤルが[0..1]から行くと仮定します。例えば、値を適用する前に値をキューブすると、ラウドネスの1/2を作成しようとして0.5を入力すると(0.5 * 0.5 * 0.5)=> 0.125となり、0.5よりもラウドネスが1/2に近くなります。

したがって、「something * something * something * precalculatedFactorCubed」がうまくいくかもしれません。

+0

2つのチャンネルを使用してスケーリングを行うにはどうすればよいですか? – Hawwa

+0

チャンネルが左右に交互に表示されます。 2つの値のそれぞれに同じ係数と計算を適用します。 –