Chackさんのソースを拝見しながら色々Wikiペディアとかで勉強したり、やすださんがご紹介くださった http://www.musicdsp.org/showmany.php のなかから Exponential parameter mapping http://www.musicdsp.org/showone.php?id=87 を参考に色々勉強してます。
ロボット関係とか、モーターの回転数とかで、似たような計算をやってる方多いはずなんで、ちゃんとアルゴリズムを書いておくのもあれかなとか、いいわけくさいけど、マジ勉強中です、勘違いとかありましたら、ご教授いただければ幸いです。 速攻で必要な結論へ飛びつかず、どう、底へ到るかなアルゴリズムをちゃんと明らかにしとけば、幾らでもバリエーションが得られそうだという、3歩進んで5歩下がる式。
それはともかく、上記の Exponential parameter mapping 、 float logmax = log10f( mMax ); float logmin = log10f( mMin ); は、乗数の範囲を求めるもので、昨年末のエクセルのカーブをで言うところの1倍のカーブなのか、50倍のカーブなのかを決める計算なので、たとえば、EGとかの時間設定なら、固定の定数になりますから、あらかじめ定数で用意すればOK。毎回やらなきゃいけない計算は、 float logdata = (mParam * (logmax-logmin)) + logmin; mData = powf( 10.0f, logdata ); の2つ。最初のは普通に掛け算。mDataは、logmax 、logminを10を底としたから、10の何とか乗。logmax 、logminを自然対数でとれば、ここは、2.718の何とか乗でもOK。
たとえば、LFOのタイミングの設定として、最低を0.3Hz最長を16Hzとして、最低時間が何倍になれば、最長になるかを計算すると53.3倍。(ここは単純に割り算) ブレゼンハムで計算するとして、傾きが53.3/53.3(要するに1だけど)から、1/53.3まで変化すればOK。1と、53.3の自然対数はそれぞれ、0と3.976。これが、2.718の乗数として0から3.976までリニアに変化する値を突っ込むと、1から53.3までで出てくる数列が、いま求めてるカーブのついたデータになりそう。
で問題は、2.718の3.976乗。小数点の乗算が面倒だぞと。たとえば、1.5乗なら、浮動小数点ライブラリがあれば、 pow(2.718, 1.5); または、exp(1.5); perlなら、 2.718 ** 1.5
Chackさんの計算法は、1.5という乗数をばらして、2.718の1乗X2.718の0.5乗とする。 http://www.kdcnet.ac.jp/college/buturi/kougi/suugaku/zennki/exp1/exp1.htm の「指数法則」参照。ちなみに、2.718の3.5乗は、(2.718の1乗)の3乗X(2.718の0.5乗)。
ってのが、実数での計算の話で、手元の8bitのちびCPUにどうインプリメントするか、がもう1ひねり。
まず、計算全体の底を10とか2.718じゃなくて2にしても同じ結果がえられそうだぞと。で、小数点のついた面倒な乗算部分はテーブルから引っ張っちゃう。あとは整数乗だから普通に掛け算すればOK。逆に言えば、テーブルで持たなきゃいけないのは、0から1までの小数点の部分だけで済む。さらに、底が2なら掛け算、シフト計算でいけそーだぞと。
http://www.kdcnet.ac.jp/college/buturi/kougi/suugaku/zennki/log1/log1.html の「◆対数の性質」4番で手元の処理系の対数の関数の底が何であっても2を低とした対数が得られそうです。
|
|