導出方法を考えてみた
32個あるオペレータの出力値を決めるレジスタ(0x60~0x7f)に書き込まれる値は、次の式で求まる.
このうち、表が巨大になった、、の値を導出するアルゴリズムを考えた。計測値とも一致した。
:Level Scalingによる減衰量
VCEDのLevel Scaling(0~99)とMIDIノート番号(0~127)が与えられた時の減衰量を整数部7bit+小数部1bitで返す手続きを示す。
int attLS(int ls, int note) { int table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,11,14,16,19,23,28,33,39,47,57,67,80,95,113,134,160,190,224,255 }; int index = 0; if (note < 24) { index = 0; } else if (note <= 108) { index = (note-24)/3; } else if (note < 121) { index = (note-12-24)/3; } else { index = (note-24-24)/3; } return (table[index] * (ls*165/64) ) >>8; }
:Key Velocity Sensitivityによる減衰量
VCEDのKVS(0~7)とMIDIのvelocity値(0~127)が与えられた時の減衰量を整数部7bit+小数部1bitで返す手続きを示す。
int attKVS(int kvs, int velocity) { int table[] = { 192,180,174,168,162,158,152,148,144,141,138,134,130,128,125,122, 119,116,114,112,109,107,105,103,101, 99, 97, 95, 93, 92, 90, 88, 86, 85, 83, 82, 81, 79, 78, 76, 75, 74, 72, 71, 70, 68, 67, 66, 65, 64, 63, 62, 60, 59, 58, 57, 56, 55, 54, 53, 52, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 26, 25, 24, 23, 22, 22, 21, 20, 19, 18, 18, 17, 16, 16, 15, 14, 14, 13, 12, 12, 11, 11, 10, 9, 9, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0 // [0]~[126] }; return kvs == 0 ? 0 : (( kvs * table[velocity-1] + (7 - kvs)*16)>>3) +1; // +1は四捨五入のため }
:ブレスコントロールによる減衰量
VCEDのBCEG Bias(0~99)、EBS(0~7)およびMIDIのCC#2の値(0~127)が与えられた時の減衰量を整数部7bit+小数部1bitで返す手続きを示す。
int attEBS(int bias, int ebs, int cc2) { int table[] = { 255,255,224,205,192,181,173,166,160,154,149,145,141,137,134,130, 128,125,122,120,117,115,113,111,109,107,105,103,102,100, 98, 97, 96, 94, 93, 91, 90, 89, 88, 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 70, 69, 68, 67, 66, 66, 65, 64, 64, 63, 62, 61, 61, 60, 59, 59, 58, 57, 57, 56, 56, 55, 54, 54, 53, 53, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 42, 41, 41, 40, 40, 39, 39, 38, 38, 38, 37, 37, 36, 36, 36, 35, 35, 34, 34, 34, 33, 33, 33, 32, 32, 32, 31, 31, 30, 30, 30, 29, 29, 29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25, 25, 24, 24, 24, 24, 23, 23, 23, 22, 22, 22, 21, 21, 21, 21, 20, 20, 20, 19, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 14, 14, 14, 14, 13, 13, 13, 13, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 }; int b3[] = { 0, 37, 73, 110, 146, 183, 219, 255 }; int index1 = bias * 165 / 64; int index2 = index1 - index1 * cc2 / 128; int index3 = index2 * b3[ebs] / 256; int index = 255 - index3; return table[index]; }
ひと月ほどかけてExcelであっちを増やしこっちを減らししながら法則を見つけていった。最後はシンプルな式になるのが面白かった。