見出し画像

900円でEnvelope Generator モジュラーシンセ自作

Arduinoプログラミングに挑戦しつつ、モジュラーシンセサイザーのEGモジュールを自作したので、その備忘録。

背景
Arduinoのプログラミングも3作品目となる。
目標は完全に1から自分でプログラミングをする(他の人の資産を使わない)のと、DAコンバータを使って何か作りたいなと思った。

LFOは以前作成したので、EGに白羽の矢が立った。
どうせなら高機能の物がほしく、モジュラーシンセで有名なMake Noise MATHSに近い機能の物を作ろうと思った。

制作物のスペック
ユーロラック規格 3U 6HPサイズ
電源:5V 55mA (arduinoの電源回路により12V動作可能)
波形:log / exp , ベジェ曲線 , inverse log / exp
A/D周期:8ms ~ 4min
振幅:0~5Vp-p
スイッチでEGモード、LFOモード選択可能。
マニュアルトリガー付き
総額:900円

特徴的なのがベジェ曲線。
この曲線を出力する市販のモジュールは、自分の知る限り無い。
なぜベジェ曲線なのかというと、数式が比較的簡単(後述)かつ、有機的な曲線を描くことが可能だからだ。自分オリジナルの要素を、なんとしてでも入れたかったこともある。

プログラム
波形は曲線なので、Arduinoで処理してやるには数式が複雑になる。
よって、あらかじめエクセルで波形を作成し、テーブルの数値を参照することとした。
テーブルに波形を保存しているので、全く異なる波形を出力することができる。
分解能は100。5Vp-pなので、50mVの階段状の波形となる。聴感テストの結果、分解能があれば十分と判断した。

トリガーINの検出は、割り込みではなく、digitalReadによる常時監視とした。
割り込み制御で動かしていると、稀に動作が不安定になる。EGのように割り込みが頻繁だと、不安定になる可能性も高くなる。
そのため、プログラムは若干めんどくさくなるが、割り込みを使わない形とした。

ベジェ曲線の数式は難しいが、始点が(0,0)、終点が(1,1)で固定してやると、簡単な式に近似できる。下のwebページを大いに参考にさせてもらった。


ハードウェア
ArduinoはAliexpressから購入したArduino nanoクローン。
DACは秋月電子から購入したMCP4911である。
ICはそんなところで、残りの電子部品はすべてAliexpressから購入し費用を900円に抑えた。
デジタルの良さ、それは安価で高性能で、そしてはんだ付けが少ないことだ。

画像1

画像2

画像3

画像4

オシロスコープはDSO nano v3が非常に使いやすい。おすすめ。


ソースコード
初心者のコードなので悪いところはあると思うが、まあ普通に動く。

/*
 bezie curve EG with MCP 4911
*/
 #include  <SPI.h>

const int LDAC = 9;                       // ラッチ動作出力ピン
byte Trigger = 0;
byte Old_trigger = 0;
byte aut_trigger = 0;//オートトリガーSW。0でOFF,1でON

//----波形選択--------
//table_sw1&2の状態を見て、select_tableを設定
//sw1=1,sw2=0でlog/exp
//sw1=0,sw2=1でbezie
//sw1=0,sw2=0でind.log/exp

//byte select_table = 0;//選択した波形[0=log/exp][1=bezie][2=ind.log.exp]
byte table_sw1 = 1;//
byte table_sw2 = 0;//


//----form選択------
//byte form = 4;//9ある形状。form_knobのAD値によって変わる。
int form_knob = 5012;//form_knobの読み取り値。初期はform=4とする。
int old_form_knob = 0;//ノイズ対策。oldと現在が30以下ならば、form_knobはoldと同じ値とする。


//----AD設定-----

byte select_AD = 0 ;//0=A,1=D
byte A_table;//アタックのテーブル
byte D_table;//ディケイのテーブル


//-----time----------
int ta = 600; //timetable倍率。VRで可変できるようにする。
int td = 600; //timetable倍率。VRで可変できるようにする。
int t_knob = 0;  //VR入力値
int old_t_knob = 0;//EG出力中の数値変更に対応
int t_CV = 0;  //CV入力値
int old_t_CV = 0;//EG出力中の数値変更に対応
const byte t_CV_rate = 1;//CV感度チューニング用
int t = 0;//t_cal計算のもと
int t_cal = 600; //time_knobとtime_cvの計算値。のちにt=ta or tdで設定する。


//テーブル変数
int i = 0; //table用内蔵データ
int ja = 0; //table用変数、VRで0~9の値を取る、アタック用
int jd = 0; //table用変数、VRで0~9の値を取る、ディケイ用
int ka = 0; //timetable用内蔵データ、アタック用
int kd = 0; //timetable用内蔵データ、ディケイ用

//log/expテーブルファイル table_1
const static word wavetable_1[9][101] PROGMEM = { //
{0,30,60,89,117,145,173,200,226,252,277,301,325,349,372,394,416,438,458,479,499,518,537,555,573,591,608,625,641,656,672,686,701,715,728,742,754,767,779,790,802,812,823,833,843,852,861,870,879,887,895,902,909,916,923,929,935,941,947,952,957,962,966,971,975,979,982,986,989,992,995,998,1000,1002,1005,1007,1008,1010,1012,1013,1014,1015,1017,1017,1018,1019,1020,1020,1021,1021,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1023},
{0,27,54,80,106,131,156,180,203,226,249,271,293,314,335,355,375,394,413,432,450,467,484,501,517,533,549,564,579,593,607,621,634,647,660,672,684,695,706,717,728,738,748,758,767,776,785,794,802,810,818,825,833,840,847,853,860,866,872,878,883,889,894,899,904,909,913,918,922,926,930,934,938,942,945,949,952,956,959,962,965,968,971,974,977,980,983,986,988,991,994,997,999,1002,1005,1008,1011,1014,1016,1019,1023},
{0,24,48,71,94,116,138,160,181,201,221,241,261,279,298,316,334,351,368,384,401,416,432,447,461,476,490,504,517,530,543,555,567,579,591,602,613,624,634,644,654,664,673,683,692,700,709,717,725,733,741,749,756,763,770,777,784,791,797,804,810,816,822,828,833,839,845,850,855,861,866,871,876,881,886,891,896,901,906,911,916,921,926,931,936,941,946,951,956,961,966,971,977,982,988,993,999,1005,1010,1016,1023},
{0,21,42,62,82,102,121,140,158,176,194,211,228,245,261,277,292,308,323,337,351,365,379,392,405,418,431,443,455,467,478,489,500,511,522,532,542,552,562,571,581,590,599,607,616,624,633,641,649,657,664,672,680,687,694,701,708,716,722,729,736,743,749,756,763,769,776,782,789,795,802,808,814,821,827,834,840,847,854,860,867,874,881,888,895,902,909,916,924,931,939,946,954,962,970,979,987,996,1004,1013,1023},
{0,15,30,44,58,73,86,100,113,126,139,151,163,175,187,199,210,221,232,243,253,264,274,284,294,303,313,322,331,340,349,358,367,376,384,392,401,409,417,425,433,441,449,457,465,473,480,488,496,503,511,519,526,534,542,549,557,565,573,581,589,597,605,613,621,630,638,646,655,664,673,682,691,700,709,719,728,738,748,758,769,779,790,801,812,823,835,847,859,871,883,896,909,922,936,949,964,978,992,1007,1023},
{0,9,18,26,35,43,52,60,68,76,83,91,98,106,113,120,127,134,141,148,155,162,168,175,182,188,195,201,208,214,220,227,233,240,246,253,259,266,273,279,286,293,300,306,314,321,328,335,342,350,358,365,373,381,389,398,406,415,423,432,441,451,460,470,480,490,500,511,522,533,544,555,567,579,591,604,617,630,643,657,671,685,699,714,730,745,761,777,794,811,828,846,864,882,901,920,940,960,980,1001,1023},
{0,6,12,17,23,29,34,40,45,51,56,61,66,71,76,81,86,91,96,101,106,111,116,121,126,131,136,141,146,151,156,161,167,172,177,183,189,194,200,206,212,218,225,231,238,245,252,259,266,273,281,289,297,305,313,322,330,339,349,358,368,378,388,398,409,420,431,443,455,467,479,492,505,518,532,546,561,575,590,606,621,638,654,671,688,706,724,743,761,781,801,821,841,862,884,906,928,951,974,998,1023},
{0,3,6,8,11,14,17,20,23,25,28,31,34,36,39,42,45,48,51,54,57,60,63,66,70,73,77,80,84,88,92,96,100,104,109,113,118,123,128,133,139,144,150,156,162,169,175,182,189,197,204,212,220,228,237,246,255,264,274,284,294,305,316,327,338,350,362,375,388,401,415,429,443,458,473,489,505,521,538,555,572,590,609,628,647,667,687,708,729,751,773,796,819,842,866,891,916,942,968,995,1023},
{0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,7,8,9,10,12,14,15,17,20,22,24,27,30,33,36,40,43,47,51,56,60,65,70,75,81,87,93,99,106,113,120,127,135,143,152,161,170,179,189,199,210,220,232,243,255,268,280,294,307,321,336,350,366,381,397,414,431,449,467,485,504,523,543,564,584,606,628,650,673,697,721,745,770,796,822,849,877,905,933,962,992,1023}
};

const static word timetable_1[9][102] PROGMEM = { //[列は1多めに設けて、最後の値はその一個前と同じとする。for用。
{0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,5,7,8,9,10,12,14,15,17,20,22,24,27,30,33,36,40,43,47,51,56,60,65,70,75,81,87,93,99,106,113,120,127,135,143,152,161,170,179,189,199,210,220,232,243,255,268,280,294,307,321,336,350,366,381,397,414,431,449,467,485,504,523,543,564,584,606,628,650,673,697,721,745,770,796,822,849,877,905,933,962,992,1023,1023},
{0,3,6,8,11,14,17,20,23,25,28,31,34,36,39,42,45,48,51,54,57,60,63,66,70,73,77,80,84,88,92,96,100,104,109,113,118,123,128,133,139,144,150,156,162,169,175,182,189,197,204,212,220,228,237,246,255,264,274,284,294,305,316,327,338,350,362,375,388,401,415,429,443,458,473,489,505,521,538,555,572,590,609,628,647,667,687,708,729,751,773,796,819,842,866,891,916,942,968,995,1023,1023},
{0,6,12,17,23,29,34,40,45,51,56,61,66,71,76,81,86,91,96,101,106,111,116,121,126,131,136,141,146,151,156,161,167,172,177,183,189,194,200,206,212,218,225,231,238,245,252,259,266,273,281,289,297,305,313,322,330,339,349,358,368,378,388,398,409,420,431,443,455,467,479,492,505,518,532,546,561,575,590,606,621,638,654,671,688,706,724,743,761,781,801,821,841,862,884,906,928,951,974,998,1023,1023},
{0,9,18,26,35,43,52,60,68,76,83,91,98,106,113,120,127,134,141,148,155,162,168,175,182,188,195,201,208,214,220,227,233,240,246,253,259,266,273,279,286,293,300,306,314,321,328,335,342,350,358,365,373,381,389,398,406,415,423,432,441,451,460,470,480,490,500,511,522,533,544,555,567,579,591,604,617,630,643,657,671,685,699,714,730,745,761,777,794,811,828,846,864,882,901,920,940,960,980,1001,1023,1023},
{0,15,30,44,58,73,86,100,113,126,139,151,163,175,187,199,210,221,232,243,253,264,274,284,294,303,313,322,331,340,349,358,367,376,384,392,401,409,417,425,433,441,449,457,465,473,480,488,496,503,511,519,526,534,542,549,557,565,573,581,589,597,605,613,621,630,638,646,655,664,673,682,691,700,709,719,728,738,748,758,769,779,790,801,812,823,835,847,859,871,883,896,909,922,936,949,964,978,992,1007,1023,1023},
{0,21,42,62,82,102,121,140,158,176,194,211,228,245,261,277,292,308,323,337,351,365,379,392,405,418,431,443,455,467,478,489,500,511,522,532,542,552,562,571,581,590,599,607,616,624,633,641,649,657,664,672,680,687,694,701,708,716,722,729,736,743,749,756,763,769,776,782,789,795,802,808,814,821,827,834,840,847,854,860,867,874,881,888,895,902,909,916,924,931,939,946,954,962,970,979,987,996,1004,1013,1023,1023},
{0,24,48,71,94,116,138,160,181,201,221,241,261,279,298,316,334,351,368,384,401,416,432,447,461,476,490,504,517,530,543,555,567,579,591,602,613,624,634,644,654,664,673,683,692,700,709,717,725,733,741,749,756,763,770,777,784,791,797,804,810,816,822,828,833,839,845,850,855,861,866,871,876,881,886,891,896,901,906,911,916,921,926,931,936,941,946,951,956,961,966,971,977,982,988,993,999,1005,1010,1016,1023,1023},
{0,27,54,80,106,131,156,180,203,226,249,271,293,314,335,355,375,394,413,432,450,467,484,501,517,533,549,564,579,593,607,621,634,647,660,672,684,695,706,717,728,738,748,758,767,776,785,794,802,810,818,825,833,840,847,853,860,866,872,878,883,889,894,899,904,909,913,918,922,926,930,934,938,942,945,949,952,956,959,962,965,968,971,974,977,980,983,986,988,991,994,997,999,1002,1005,1008,1011,1014,1016,1019,1023,1023},
{0,30,60,89,117,145,173,200,226,252,277,301,325,349,372,394,416,438,458,479,499,518,537,555,573,591,608,625,641,656,672,686,701,715,728,742,754,767,779,790,802,812,823,833,843,852,861,870,879,887,895,902,909,916,923,929,935,941,947,952,957,962,966,971,975,979,982,986,989,992,995,998,1000,1002,1005,1007,1008,1010,1012,1013,1014,1015,1017,1017,1018,1019,1020,1020,1021,1021,1021,1022,1022,1022,1022,1022,1022,1022,1022,1022,1023,1023}

};


//bezieテーブルファイル table_2


const static word wavetable_2[9][101] PROGMEM = { //
 {0, 3, 7, 11, 16, 21, 26, 32, 39, 46, 53, 61, 69, 77, 86, 95, 104, 114, 124, 135, 145, 156, 167, 179, 191, 203, 215, 227, 240, 253, 266, 279, 292, 306, 319, 333, 347, 361, 375, 389, 404, 418, 433, 447, 462, 476, 491, 506, 520, 535, 549, 564, 578, 593, 607, 622, 636, 650, 664, 678, 692, 706, 719, 732, 746, 759, 772, 784, 797, 809, 821, 833, 844, 855, 866, 877, 887, 898, 907, 917, 926, 935, 943, 951, 959, 966, 973, 980, 986, 991, 997, 1001, 1006, 1010, 1013, 1016, 1018, 1020, 1021, 1022, 1023},
 {0, 9, 18, 28, 38, 48, 59, 70, 80, 91, 103, 114, 126, 137, 149, 161, 174, 186, 198, 211, 224, 237, 249, 263, 276, 289, 302, 315, 329, 342, 356, 369, 383, 397, 410, 424, 438, 451, 465, 479, 492, 506, 519, 533, 546, 560, 573, 587, 600, 613, 626, 639, 652, 665, 677, 690, 702, 715, 727, 739, 751, 762, 774, 785, 797, 808, 818, 829, 839, 850, 860, 869, 879, 888, 897, 906, 914, 923, 931, 938, 946, 953, 959, 966, 972, 978, 983, 989, 994, 998, 1002, 1006, 1009, 1012, 1015, 1017, 1019, 1021, 1022, 1022, 1023},
 {0, 15, 30, 46, 61, 76, 91, 107, 122, 137, 152, 168, 183, 198, 213, 228, 243, 258, 273, 288, 302, 317, 332, 346, 361, 375, 389, 404, 418, 432, 446, 460, 474, 488, 501, 515, 528, 541, 555, 568, 581, 593, 606, 619, 631, 643, 656, 668, 679, 691, 703, 714, 726, 737, 748, 758, 769, 779, 790, 800, 810, 819, 829, 838, 847, 856, 865, 874, 882, 890, 898, 906, 913, 921, 928, 935, 941, 948, 954, 960, 965, 971, 976, 981, 985, 990, 994, 998, 1001, 1005, 1008, 1010, 1013, 1015, 1017, 1019, 1020, 1021, 1022, 1022, 1023},
 {0, 21, 42, 63, 83, 104, 124, 144, 164, 183, 202, 221, 240, 258, 276, 294, 312, 330, 347, 364, 381, 397, 414, 430, 446, 461, 477, 492, 507, 522, 536, 551, 565, 578, 592, 605, 619, 631, 644, 657, 669, 681, 693, 704, 716, 727, 738, 749, 759, 769, 780, 789, 799, 808, 818, 827, 836, 844, 853, 861, 869, 876, 884, 891, 898, 905, 912, 919, 925, 931, 937, 943, 948, 953, 958, 963, 968, 973, 977, 981, 985, 989, 992, 995, 999, 1001, 1004, 1007, 1009, 1011, 1013, 1015, 1017, 1018, 1019, 1020, 1021, 1022, 1022, 1022, 1023},
 {0, 30, 60, 89, 117, 145, 173, 200, 226, 252, 277, 301, 325, 349, 372, 394, 416, 438, 458, 479, 499, 518, 537, 555, 573, 591, 608, 625, 641, 656, 672, 686, 701, 715, 728, 742, 754, 767, 779, 790, 802, 812, 823, 833, 843, 852, 861, 870, 879, 887, 895, 902, 909, 916, 923, 929, 935, 941, 947, 952, 957, 962, 966, 971, 975, 979, 982, 986, 989, 992, 995, 998, 1000, 1002, 1005, 1007, 1008, 1010, 1012, 1013, 1014, 1015, 1017, 1017, 1018, 1019, 1020, 1020, 1021, 1021, 1021, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1023},
 {0, 30, 59, 88, 116, 142, 169, 194, 219, 243, 266, 288, 310, 331, 351, 371, 390, 408, 426, 443, 459, 475, 491, 505, 520, 533, 547, 559, 571, 583, 594, 605, 615, 625, 635, 644, 653, 661, 669, 676, 684, 691, 697, 704, 710, 716, 721, 726, 732, 736, 741, 746, 750, 754, 758, 762, 766, 770, 773, 777, 780, 784, 787, 790, 794, 797, 800, 804, 807, 811, 814, 818, 822, 826, 830, 834, 838, 843, 847, 852, 857, 862, 868, 874, 880, 886, 893, 899, 907, 914, 922, 930, 939, 948, 957, 967, 977, 988, 999, 1010, 1023},
 {0, 30, 59, 87, 115, 141, 167, 191, 215, 238, 260, 281, 302, 322, 341, 359, 377, 393, 410, 425, 440, 454, 468, 480, 493, 505, 516, 527, 537, 546, 556, 564, 573, 580, 588, 595, 602, 608, 614, 619, 625, 630, 635, 639, 643, 647, 651, 655, 658, 661, 664, 667, 670, 673, 676, 679, 681, 684, 687, 689, 692, 695, 697, 700, 703, 706, 710, 713, 717, 720, 724, 728, 733, 737, 742, 748, 753, 759, 765, 772, 779, 786, 794, 802, 810, 819, 829, 839, 850, 861, 872, 885, 897, 911, 925, 939, 955, 970, 987, 1004, 1023},
 {0, 30, 59, 87, 114, 140, 165, 188, 211, 233, 255, 275, 294, 313, 330, 347, 363, 379, 393, 407, 420, 433, 444, 455, 466, 476, 485, 494, 502, 510, 517, 524, 530, 536, 541, 546, 551, 555, 559, 563, 566, 569, 572, 574, 577, 579, 581, 583, 585, 586, 588, 589, 591, 592, 594, 595, 597, 598, 600, 602, 603, 606, 608, 610, 613, 616, 619, 622, 626, 630, 634, 639, 644, 649, 655, 661, 668, 675, 683, 691, 700, 709, 719, 730, 741, 753, 765, 779, 793, 807, 823, 839, 856, 874, 892, 912, 932, 953, 975, 998, 1023},
 {0, 30, 58, 86, 113, 138, 162, 186, 208, 229, 249, 268, 286, 304, 320, 336, 350, 364, 377, 389, 401, 411, 421, 430, 439, 447, 454, 461, 467, 473, 478, 483, 487, 491, 494, 497, 500, 502, 504, 506, 507, 508, 509, 510, 510, 510, 511, 511, 511, 511, 511, 511, 511, 511, 511, 512, 512, 512, 513, 514, 515, 516, 518, 520, 522, 525, 528, 531, 535, 539, 544, 549, 555, 561, 568, 575, 583, 592, 601, 611, 621, 633, 645, 658, 672, 686, 702, 718, 736, 754, 773, 793, 814, 836, 860, 884, 909, 936, 964, 992, 1023}
};

const static word timetable_2[9][102] PROGMEM = { //[列は1多めに設けて、最後の値はその一個前と同じとする。for用。
 {0, 30, 59, 86, 113, 139, 163, 187, 210, 231, 252, 272, 290, 308, 325, 341, 357, 371, 385, 398, 410, 422, 433, 443, 453, 461, 470, 478, 485, 491, 498, 503, 509, 513, 518, 522, 525, 528, 531, 534, 536, 538, 540, 542, 543, 545, 546, 547, 548, 549, 549, 550, 551, 552, 552, 553, 554, 555, 556, 558, 559, 561, 563, 565, 567, 570, 573, 577, 580, 584, 589, 594, 599, 605, 611, 618, 625, 633, 642, 651, 661, 671, 682, 694, 706, 720, 734, 748, 764, 780, 798, 816, 835, 855, 876, 898, 921, 945, 969, 995, 1023, 1023},
 {0, 30, 59, 87, 114, 140, 166, 190, 213, 236, 257, 278, 298, 317, 336, 353, 370, 386, 401, 416, 430, 443, 456, 468, 479, 490, 500, 510, 519, 528, 536, 544, 551, 558, 564, 571, 576, 581, 586, 591, 595, 599, 603, 607, 610, 613, 616, 619, 621, 624, 626, 628, 631, 633, 635, 637, 639, 641, 643, 645, 648, 650, 653, 655, 658, 661, 664, 667, 671, 675, 679, 683, 688, 693, 699, 704, 711, 717, 724, 731, 739, 748, 757, 766, 776, 786, 797, 809, 821, 834, 847, 862, 877, 892, 908, 925, 943, 962, 981, 1001, 1023, 1023},
 {0, 30, 59, 87, 115, 142, 168, 193, 217, 240, 263, 285, 306, 326, 346, 365, 383, 401, 418, 434, 450, 465, 479, 493, 506, 519, 531, 543, 554, 565, 575, 585, 594, 603, 611, 619, 627, 634, 641, 648, 654, 660, 666, 671, 676, 681, 686, 691, 695, 699, 703, 707, 710, 714, 717, 720, 724, 727, 730, 733, 736, 739, 742, 745, 748, 752, 755, 758, 762, 766, 769, 773, 777, 782, 786, 791, 796, 801, 806, 812, 818, 824, 831, 838, 845, 853, 861, 869, 878, 887, 897, 907, 918, 929, 941, 953, 966, 979, 993, 1007, 1023, 1023},
 {0, 30, 59, 88, 116, 143, 170, 195, 220, 245, 268, 291, 314, 335, 356, 377, 396, 415, 434, 452, 469, 486, 502, 518, 533, 548, 562, 576, 589, 601, 614, 625, 637, 648, 658, 668, 678, 687, 696, 705, 713, 721, 729, 736, 743, 750, 756, 762, 768, 774, 780, 785, 790, 795, 799, 804, 808, 813, 817, 821, 824, 828, 832, 835, 839, 842, 846, 849, 853, 856, 860, 863, 866, 870, 873, 877, 881, 885, 888, 892, 896, 901, 905, 910, 914, 919, 924, 930, 935, 941, 947, 953, 960, 966, 973, 981, 988, 996, 1005, 1013, 1023, 1023},
 {0, 30, 60, 89, 117, 145, 173, 200, 226, 252, 277, 301, 325, 349, 372, 394, 416, 438, 458, 479, 499, 518, 537, 555, 573, 591, 608, 625, 641, 656, 672, 686, 701, 715, 728, 742, 754, 767, 779, 790, 802, 812, 823, 833, 843, 852, 861, 870, 879, 887, 895, 902, 909, 916, 923, 929, 935, 941, 947, 952, 957, 962, 966, 971, 975, 979, 982, 986, 989, 992, 995, 998, 1000, 1002, 1005, 1007, 1008, 1010, 1012, 1013, 1014, 1015, 1017, 1017, 1018, 1019, 1020, 1020, 1021, 1021, 1021, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1023, 1023},
 {0, 18, 36, 54, 72, 90, 108, 125, 143, 160, 177, 194, 211, 228, 245, 261, 278, 294, 310, 326, 342, 357, 373, 388, 403, 418, 433, 448, 462, 477, 491, 505, 519, 533, 547, 560, 573, 586, 599, 612, 625, 637, 649, 662, 673, 685, 697, 708, 719, 730, 741, 752, 762, 773, 783, 793, 802, 812, 821, 830, 839, 848, 856, 865, 873, 881, 889, 896, 903, 911, 918, 924, 931, 937, 943, 949, 955, 960, 965, 970, 975, 980, 984, 988, 992, 996, 999, 1002, 1005, 1008, 1010, 1013, 1015, 1017, 1018, 1019, 1021, 1021, 1022, 1022, 1023, 1023},
 {0, 12, 24, 37, 50, 62, 75, 88, 101, 114, 128, 141, 154, 168, 181, 195, 208, 222, 236, 249, 263, 277, 291, 304, 318, 332, 346, 360, 373, 387, 401, 415, 428, 442, 456, 469, 483, 496, 510, 523, 536, 550, 563, 576, 589, 602, 614, 627, 640, 652, 664, 677, 689, 701, 713, 724, 736, 747, 758, 769, 780, 791, 802, 812, 822, 832, 842, 851, 861, 870, 879, 888, 896, 904, 912, 920, 928, 935, 942, 949, 955, 962, 968, 973, 979, 984, 989, 993, 997, 1001, 1005, 1008, 1011, 1014, 1016, 1018, 1020, 1021, 1022, 1022, 1023, 1023},
 {0, 6, 13, 20, 27, 35, 43, 51, 60, 69, 78, 87, 97, 107, 118, 128, 139, 150, 161, 173, 184, 196, 208, 221, 233, 246, 258, 271, 284, 297, 311, 324, 338, 351, 365, 378, 392, 406, 420, 434, 448, 462, 476, 490, 504, 518, 532, 546, 560, 574, 588, 602, 615, 629, 642, 656, 669, 682, 696, 708, 721, 734, 747, 759, 771, 783, 795, 807, 818, 829, 840, 851, 861, 872, 882, 891, 901, 910, 919, 927, 936, 944, 951, 959, 966, 972, 978, 984, 990, 995, 999, 1004, 1008, 1011, 1014, 1017, 1019, 1020, 1022, 1022, 1023, 1023},
 {0, 0, 1, 2, 4, 7, 10, 14, 18, 23, 28, 34, 40, 47, 54, 62, 70, 78, 87, 96, 106, 116, 126, 137, 148, 159, 171, 183, 195, 208, 220, 233, 247, 260, 274, 288, 302, 316, 330, 345, 360, 374, 389, 404, 419, 435, 450, 465, 480, 496, 511, 526, 542, 557, 572, 587, 603, 618, 633, 648, 662, 677, 692, 706, 720, 734, 748, 762, 775, 789, 802, 814, 827, 839, 851, 863, 874, 885, 896, 906, 916, 926, 935, 944, 952, 960, 968, 975, 982, 988, 994, 999, 1004, 1008, 1012, 1015, 1018, 1020, 1021, 1022, 1023, 1023}

};


void setup() {
 // 制御するピンは全て出力に設定する
 pinMode(LDAC, OUTPUT) ;
 pinMode(SS, OUTPUT) ;

 Serial.begin(9600);

 SPI.begin();
 SPI.setBitOrder(MSBFIRST) ;          // ビットオーダー
 SPI.setClockDivider(SPI_CLOCK_DIV8) ;// クロック(CLK)をシステムクロックの1/8で使用(16MHz/8)
 SPI.setDataMode(SPI_MODE0) ;         // クロック極性0(LOW) クロック位相0
 delay(50);

 WriteRegister(i);//起動時の出力電圧を0にする。
}


void loop() {

 select_AD = digitalRead(4);
 set_AD (select_AD);

//  Serial.println(t_knob);//開発用

 //------------トリガー検出とEG突入----------------------

 aut_trigger = digitalRead(5);
 
 if ( aut_trigger == 0 ){   //オートトリガーOFF 
 Old_trigger = Trigger ;//古いトリガー電圧を記憶  
 Trigger = digitalRead(2);//トリガー電圧読む
 }

 else if ( aut_trigger == 1 ){//オートトリガーON
         goto retrigger;
 }
 
 if (Trigger == 1 && Old_trigger == 0 ) { //トリガー電圧0→1の場合に、EG出力開始
 retrigger://リトリガー時に戻ってくる
set_AD (select_AD);

////-----------テーブル出力A------------
//-----log/exp-------------------------------
   if (A_table == 0) {

     for (i = 0; i < 101 ; i = i + 1) {

       //アタック途中にリトリガーされた場合、リトリガーに戻る
       Old_trigger = Trigger ;
       Trigger = digitalRead(2);
       if (Trigger == 1 && Old_trigger == 0 ) {
         goto retrigger;
       }

         //EG中にtimeが変わった場合、timeを変更させる
         old_t_knob = t_knob;
         t_knob = analogRead(3);
        if ( abs( old_t_knob - t_knob ) > 1 && select_AD == 0){
          set_time();
          ta = t_cal;
        }
 
        old_t_CV = t_CV;
         t_CV = analogRead(5);
         if ( abs( old_t_CV - t_CV ) > 1 && select_AD == 0){
           set_time();
          ta = t_cal;
         }

       WriteRegister(pgm_read_word(&(wavetable_1[ja][i])));

       for (ka = 0; ka < ta; ka = ka + 1) { //変数tの回数delayを繰り返す。
         delayMicroseconds ((pgm_read_word(&(timetable_1[ja][i + 1])) - pgm_read_word(&timetable_1[ja][i])));
       }
     }
   }

//-----bezie-------------------------------
   else if (A_table == 1) {

     for (i = 0; i < 101 ; i = i + 1) {

       //アタック途中にリトリガーされた場合、リトリガーに戻る
       Old_trigger = Trigger ;
       Trigger = digitalRead(2);
       if (Trigger == 1 && Old_trigger == 0 ) {
         goto retrigger;
       }

         //EG中にtimeが変わった場合、timeを変更させる
         old_t_knob = t_knob;
         t_knob = analogRead(3);
        if ( abs( old_t_knob - t_knob ) > 1 && select_AD == 0){
          set_time();
          ta = t_cal;
        }
 
        old_t_CV = t_CV;
         t_CV = analogRead(5);
         if ( abs( old_t_CV - t_CV ) > 1 && select_AD == 0){
           set_time();
           ta = t_cal;
         }

       WriteRegister(pgm_read_word(&(wavetable_2[ja][i])));

       for (ka = 0; ka < ta; ka = ka + 1) { //変数tの回数delayを繰り返す。
         delayMicroseconds ((pgm_read_word(&(timetable_2[ja][i + 1])) - pgm_read_word(&timetable_2[ja][i])));
       }
     }
   }

//-----inv.log/exp-------------------------------
   else if (A_table == 2) {

     for (i = 100; i > -1 ; i = i - 1) {//インディビジュアルなので、ディケイのfor文となっている

       //アタック途中にリトリガーされた場合、リトリガーに戻る
       Old_trigger = Trigger ;
       Trigger = digitalRead(2);
       if (Trigger == 1 && Old_trigger == 0 && select_AD == 0) {
         goto retrigger;
       }

         //EG中にtimeが変わった場合、timeを変更させる
         old_t_knob = t_knob;
         t_knob = analogRead(3);
        if ( abs( old_t_knob - t_knob ) > 1 && select_AD == 0){
          set_time();
          ta = t_cal;
        }
 
        old_t_CV = t_CV;
         t_CV = analogRead(5);
         if ( abs( old_t_CV - t_CV ) > 1 ){
           set_time();
           ta = t_cal;
         }

       WriteRegister(pgm_read_word(&(wavetable_1[ja][i])));

       for (ka = ta; ka > 0; ka = ka - 1) { //変数tの回数delayを繰り返す。
         delayMicroseconds ((pgm_read_word(&(timetable_1[ja][i + 1])) - pgm_read_word(&timetable_1[ja][i])));
       }
     }
   }


//-----------テーブル出力D------------
//-----log/exp-------------------------------
   if (D_table == 0) {
     for (i = 100; i > -1 ; i = i - 1) {

       //アタック途中にリトリガーされた場合、リトリガーに戻る
       Old_trigger = Trigger ;
       Trigger = digitalRead(2);
       if (Trigger == 1 && Old_trigger == 0 ) {
         goto retrigger;
       }

         //EG中にtimeが変わった場合、timeを変更させる
         old_t_knob = t_knob;
         t_knob = analogRead(3);
        if ( abs( old_t_knob - t_knob ) > 1 && select_AD == 1){
          set_time();
          td = t_cal;
        }
 
        old_t_CV = t_CV;
         t_CV = analogRead(5);
         if ( abs( old_t_CV - t_CV ) > 1 && select_AD == 1){
           set_time();
           td = t_cal;
         }        
       
       WriteRegister(pgm_read_word(&(wavetable_1[jd][i])));

       for (kd = td; kd > 0; kd = kd - 1) { //変数tの回数delayを繰り返す。
         delayMicroseconds ((pgm_read_word(&(timetable_1[jd][i + 1])) - pgm_read_word(&timetable_1[jd][i])));
       }
     }
   }
 

//-----bezie-------------------------------
   else if (D_table == 1) {
     for (i = 100; i > -1 ; i = i - 1) {

       //アタック途中にリトリガーされた場合、リトリガーに戻る
       Old_trigger = Trigger ;
       Trigger = digitalRead(2);
       if (Trigger == 1 && Old_trigger == 0 ) {
         goto retrigger;
         td = t_cal;
       }

         //EG中にtimeが変わった場合、timeを変更させる
         old_t_knob = t_knob;
         t_knob = analogRead(3);
        if ( abs( old_t_knob - t_knob ) > 1 && select_AD == 1){
          set_time();
          td = t_cal;
        }
 
        old_t_CV = t_CV;
         t_CV = analogRead(5);
         if ( abs( old_t_CV - t_CV ) > 1 && select_AD == 1){
           set_time();
           td = t_cal;
         }
       
       WriteRegister(pgm_read_word(&(wavetable_2[jd][i])));

       for (kd = td; kd > 0; kd = kd - 1) { //変数tの回数delayを繰り返す。
         delayMicroseconds ((pgm_read_word(&(timetable_2[jd][i + 1])) - pgm_read_word(&timetable_2[jd][i])));
       }
     }
   }

//-----ind.log/exp-------------------------------
   else if (D_table == 2) {
     for (i = 0; i < 101 ; i = i + 1) {

       //アタック途中にリトリガーされた場合、リトリガーに戻る
       Old_trigger = Trigger ;
       Trigger = digitalRead(2);
       if (Trigger == 1 && Old_trigger == 0 ) {
         goto retrigger;
       }

         //EG中にtimeが変わった場合、timeを変更させる
         old_t_knob = t_knob;
         t_knob = analogRead(3);
        if ( abs( old_t_knob - t_knob ) > 1 && select_AD == 1){
          set_time();
          td = t_cal;
        }
 
        old_t_CV = t_CV;
         t_CV = analogRead(5);
         if ( abs( old_t_CV - t_CV ) > 1 && select_AD == 1){
           set_time();
           td = t_cal;
         }        
       
       WriteRegister(pgm_read_word(&(wavetable_1[jd][i])));

       for (kd = 0; kd < td; kd = kd + 1) { //変数tの回数delayを繰り返す。
         delayMicroseconds ((pgm_read_word(&(timetable_1[jd][i + 1])) - pgm_read_word(&timetable_1[jd][i])));
       }
     }
   }

 
 
 }  

 

}//void loopおわり


//-----------ADのパラメータセット---------

void set_AD (byte select_AD){

//---------------form読み込み-------------------
 old_form_knob = form_knob;
 form_knob = analogRead(1);
 
 if(abs(old_form_knob - form_knob) < 30 ){//ノイズ対策
   form_knob = old_form_knob;
 }

//---------------time読み込み-------------------
set_time();


   //----------------波形選択-------------------
 table_sw1 = digitalRead(6);
 table_sw2 = digitalRead(7);

if ( select_AD == 0 ){//---------------------------------アタック設定

 ta = t_cal;
 
 if ( table_sw1 == 1 && table_sw2 == 0) {
   A_table = 0; //log/exp
 }
 else if ( table_sw1 == 0 && table_sw2 == 1) {
   A_table = 2;  //bezie
 }
 else if ( table_sw1 == 0 && table_sw2 == 0) {
   A_table = 1;  //ind.log/exp
 }

   if( form_knob < 113){
   ja = 0;
 }
 else if ( form_knob > 114 && form_knob < 227 ){
   ja = 1;
 }
 else if ( form_knob > 228 && form_knob < 340 ){
   ja = 2;
 }
 else if ( form_knob > 341 && form_knob < 454 ){
   ja = 3;
 }
 else if ( form_knob > 455 && form_knob < 568 ){
   ja = 4;
 }
 else if ( form_knob > 569 && form_knob < 682 ){
   ja = 5;
 }
 else if ( form_knob > 683 && form_knob < 795 ){
   ja = 6;
 }
 else if ( form_knob > 786 && form_knob < 909 ){
   ja = 7;
 }
 else if ( form_knob > 910 && form_knob < 1023 ){
   ja = 8;
 }
 
}

if ( select_AD == 1 ){//---------------------------------ディケイ設定

 td = t_cal;
 
 if ( table_sw1 == 1 && table_sw2 == 0) {
   D_table = 0; //log/exp
 }
 else if ( table_sw1 == 0 && table_sw2 == 1) {
   D_table = 2;  //bezie
 }
 else if ( table_sw1 == 0 && table_sw2 == 0) {
   D_table = 1;  //ind.log/exp
 }

   if( form_knob < 113){
   jd = 0;
 }
 else if ( form_knob > 114 && form_knob < 227 ){
   jd = 1;
 }
 else if ( form_knob > 228 && form_knob < 340 ){
   jd = 2;
 }
 else if ( form_knob > 341 && form_knob < 454 ){
   jd = 3;
 }
 else if ( form_knob > 455 && form_knob < 568 ){
   jd = 4;
 }
 else if ( form_knob > 569 && form_knob < 682 ){
   jd = 5;
 }
 else if ( form_knob > 683 && form_knob < 795 ){
   jd = 6;
 }
 else if ( form_knob > 786 && form_knob < 909 ){
   jd = 7;
 }
 else if ( form_knob > 910 && form_knob < 1023 ){
   jd = 8;
 }
 
}

 
}

void set_time (){

 t_knob = analogRead(3);
//  t_CV = 0;//開発用
 t_CV = analogRead(5);

 if ( t_CV > 10 ){
 t_CV = t_CV / t_CV_rate -200;
 }

 if ( t_knob < 30 ){//不感帯域設定
   t_cal = 0 ;    
 }
 else if ( t_knob >=30 && t_knob < 700 ){
   t_knob = t_knob-30;
   t_cal = pow((( t_knob + t_CV )/4), 1.4);
 }
   else if ( t_knob >= 700 ){
   t_knob = t_knob-30;
   t_cal = pow((( t_knob + t_CV )/4), 1.8)-8000;
 }
 
//  if(abs(old_form_knob - form_knob) < 30 ){//ノイズ対策
//    form_knob = old_form_knob;
//  }

}

//------------DAC通信------------------------
void WriteRegister(int dat) {
 digitalWrite(LDAC, HIGH) ;
 digitalWrite(SS, LOW) ;
 SPI.transfer((dat >> 6) | 0x30) ;   // Highバイト(0x30=OUTA/BUFなし/1x/シャットダウンなし)
 SPI.transfer((dat << 2) & 0xff) ;        // Lowバイトの出力
 digitalWrite(SS, HIGH) ;
 digitalWrite(LDAC, LOW) ;     // ラッチ信号を出す

//  Serial.println(pgm_read_word(&(wavetable_1[j][i])));//開発用
}

この記事が気に入ったらサポートをしてみませんか?