#include int attack_time = 0; int decay_time = 10; int release_time = 128; int susteen_level = 128; int numerator = 131; int denominators[256] = { 0x0083, 0x0182, 0x0281, 0x0381, 0x0480, 0x057f, 0x067f, 0x077e, 0x087d, 0x097d, 0x0a7c, 0x0b7b, 0x0c7b, 0x0d7a, 0x0e79, 0x0f79, 0x1078, 0x1177, 0x1277, 0x1376, 0x1475, 0x1575, 0x1674, 0x1773, 0x1873, 0x1972, 0x1a72, 0x1b71, 0x1c70, 0x1d70, 0x1e6f, 0x1f6e, 0x206e, 0x216d, 0x226c, 0x236c, 0x246b, 0x256a, 0x266a, 0x2769, 0x2868, 0x2968, 0x2a67, 0x2b66, 0x2c66, 0x2d65, 0x2e64, 0x2f64, 0x3063, 0x3163, 0x3262, 0x3361, 0x3461, 0x3560, 0x365f, 0x375f, 0x385e, 0x395d, 0x3a5d, 0x3b5c, 0x3c5b, 0x3d5b, 0x3e5a, 0x3f59, 0x4059, 0x4158, 0x4257, 0x4357, 0x4456, 0x4555, 0x4655, 0x4754, 0x4854, 0x4953, 0x4a52, 0x4b52, 0x4c51, 0x4d50, 0x4e50, 0x4f4f, 0x504e, 0x514e, 0x524d, 0x534c, 0x544c, 0x554b, 0x564a, 0x574a, 0x5849, 0x5948, 0x5a48, 0x5b47, 0x5c46, 0x5d46, 0x5e45, 0x5f45, 0x6044, 0x6143, 0x6243, 0x6342, 0x6441, 0x6541, 0x6640, 0x673f, 0x683f, 0x693e, 0x6a3d, 0x6b3d, 0x6c3c, 0x6d3b, 0x6e3b, 0x6f3a, 0x7039, 0x7139, 0x7238, 0x7337, 0x7437, 0x7536, 0x7636, 0x7735, 0x7834, 0x7934, 0x7a33, 0x7b32, 0x7c32, 0x7d31, 0x7e30, 0x7f30, 0x802f, 0x812e, 0x822e, 0x832d, 0x842c, 0x852c, 0x862b, 0x872a, 0x882a, 0x8929, 0x8a28, 0x8b28, 0x8c27, 0x8d27, 0x8e26, 0x8f25, 0x9025, 0x9124, 0x9223, 0x9323, 0x9422, 0x9521, 0x9621, 0x9720, 0x981f, 0x991f, 0x9a1e, 0x9b1d, 0x9c1d, 0x9d1c, 0x9e1b, 0x9f1b, 0xa01a, 0xa119, 0xa219, 0xa318, 0xa418, 0xa517, 0xa616, 0xa716, 0xa815, 0xa914, 0xaa14, 0xab13, 0xac12, 0xad12, 0xae11, 0xaf10, 0xb010, 0xb10f, 0xb20e, 0xb30e, 0xb40d, 0xb50c, 0xb60c, 0xb70b, 0xb80a, 0xb90a, 0xba09, 0xbb09, 0xbc08, 0xbd07, 0xbe07, 0xbf06, 0xc005, 0xc105, 0xc204, 0xc303, 0xc403, 0xc502, 0xc601, 0xc701, 0xc800, 0xc8ff, 0xc9ff, 0xcafe, 0xcbfd, 0xccfd, 0xcdfc, 0xcefb, 0xcffb, 0xd0fa, 0xd1fa, 0xd2f9, 0xd3f8, 0xd4f8, 0xd5f7, 0xd6f6, 0xd7f6, 0xd8f5, 0xd9f4, 0xdaf4, 0xdbf3, 0xdcf2, 0xddf2, 0xdef1, 0xdff0, 0xe0f0, 0xe1ef, 0xe2ee, 0xe3ee, 0xe4ed, 0xe5ec, 0xe6ec, 0xe7eb, 0xe8eb, 0xe9ea, 0xeae9, 0xebe9, 0xece8, 0xede7, 0xeee7, 0xefe6, 0xf0e5, 0xf1e5, 0xf2e4, 0xf3e3, 0xf4e3, 0xf5e2, 0xf6e1, 0xf7e1, 0xf8e0, 0xf9df, 0xfadf, 0xfbde, 0xfcdd, 0xfddd, 0xfedc, }; int eg(int gate) { static int current_e = 0; static int current_level = 0 ; static int current_stat = 0; /* 0:idole, 1:attack, 2:decay, 3:susteen, 4:release */ static int last_gate = 0 ; if (last_gate != gate ){ /*add multitriger proccess here if you need */ if (last_gate == 1 ){ current_stat =4; /*start release*/ }else{ current_stat =1; /*start attack*/ } last_gate = gate; /*keep now gate status*/ current_e= 0; } switch (current_stat){ case 1: /*attak */ current_e += numerator; if (current_e>= denominators[attack_time] ){ current_e -= denominators[attack_time] ; current_level++; } if (current_level > 255 ){ /*max should be 256*/ current_stat =2; current_e = 0; } break; case 2: /*decay */ current_e += numerator; if (current_e>= denominators[decay_time] ){ current_e -= denominators[decay_time] ; current_level--; } if (current_level < susteen_level ){ current_stat=3; } break; case 3: /* susteen */ current_level = susteen_level; /*there may be changing levels of susteen by UI*/ break; case 4: /*relsease */ current_e += numerator; if (current_e>= denominators[release_time] ){ current_e -= denominators[release_time] ; current_level--; } if (current_level == 0 ){ current_e= 0; } break; default: /*do nothing*/ break; } return current_level; } main () { int i; int cnt = 0; int gt = 0; for (i = 0 ; i < 6000 ; i++ ){ if (i == 5 ){ gt = 1 ; } if (i == 4500 ){ gt = 0 ; } printf ("%d\n", eg(gt) ); } } /** ソフトウエアEGほしいぞ.. ブレゼンハムのアルゴリズムという、デジタルの画面に線分を描画するアルゴリズム使って、ソフトウエアEGを実装してみた。 ADSR包絡線をX軸を時間に、Y軸を出力レベルに見立てたグラフを描画してみようという狙い。 簡単に言えば、一定時間を単位時間に分割して、その時間の変わり目に出力をワンステップアップするかどうかを判断するという技法。単位時間内にしなきゃいけない演算が少なくて、ローコストなアルゴリズムかなと。線分の傾きがそのままADRのタイミングになります。欠点は、最少のタイミングをそんなに早く出来ない点。 アルゴリズム自体の解説はこちらに詳しい。 http://dencha.ojaru.jp/programs_07/pg_graphic_07.html 包絡線は、あくまで直線。コンデンサの放電特性のシミュレーションは必要ならテーブル化。 時間軸上に描画するグラフの線分の始点と終点のy座標は、0か、最大値で固定。X軸はADコンバートでえた時間の長さ。256点しかないのだから傾きの計算に必要な割り算はあらかじめやっておいてテーブル化しちゃう。上記URLの草案2というソース内の、eという変数。 もう、足し算と引き算だけ、まるでひらがなだけで書くソフトウエア、takeda向きだよね。 */