アナログシンセ掲示板ログ閲覧所
Library of BBS for DIYers of Analog Synth

[ トップページへ / 一覧表示 / 最新記事 / 管理用 ]
[ to Top Page / Title List ]


設計と製作 指数変換
#8812
この記事の投稿者にメールを送信 takeda (2008年01月07日19時37分)
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を低とした対数が得られそうです。

[この記事の元になった記事]

Re[2]:ソフトウエアEGの仕様 : takeda (2007年12月27日21時32分)

[この記事に対する返事]

指数変換実装編part1 : takeda (2008年01月07日19時41分)Re:指数変換 : RJB (2008年01月07日22時39分)