You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

450 lines
19KB

  1. #include "SubmarineFree.hpp"
  2. namespace rack_plugin_SubmarineFree {
  3. namespace SubmarineAO {
  4. typedef float (*func_t)(float, float, float);
  5. struct Functor {
  6. std::string name;
  7. func_t func;
  8. };
  9. #define sMIN(a,b) (((a)>(b))?(b):(a))
  10. #define sMAX(a,b) (((a)>(b))?(a):(b))
  11. #define LAMBDA(e) [](float x, float y, float c)->float { return e ; }
  12. #define X "X" // X
  13. #define Y "Y" // Y
  14. #define C "C" // C
  15. #define A "+" // Addition symbol
  16. #define S "-" // Subtraction symbol
  17. #define O "%" // Modulo symbol
  18. #define OP "(" // Open Parenthesis
  19. #define CP ")" // Close Parenthesis
  20. #define P "|" // Pipe symbol
  21. #define M "\xe2\xa8\xaf"
  22. #define D "\xc3\xb7" // Division symbol
  23. #define R "\xe2\x88\x9a" // Root symbol
  24. #define S2 "\xc2\xb2" // Superscript 2
  25. #define S3 "\xc2\xb3" // Superscript 3
  26. #define s0 "\xe2\x82\x80" // Subscript 0
  27. #define s1 "\xe2\x82\x81" // Subscript 1
  28. #define s2 "\xe2\x82\x82" // Subscript 2
  29. #define E "\xe2\x84\xaf" // e
  30. #define SA "\xe2\x81\xba" // Superscript +
  31. #define SX "\xcb\xa3" // Superscript x
  32. #define SY "\xca\xb8" // Superscript y
  33. #define SC "\xe1\xb6\x9c" // Superscript c
  34. #define MIN "min" // Minimum function
  35. #define MAX "max" // Maximum function
  36. #define COMMA "," // Comma symbol
  37. #define SIN "sin" // sine function
  38. #define COS "cos" // cosine function
  39. #define TAN "tan" // tangent function
  40. #define ASIN "asin" // arcsine function
  41. #define ACOS "acos" // arcosine function
  42. #define ATAN "atan" // arctangent function
  43. #define LOG "log" // log function
  44. #define LOG2 LOG s2 // base-2 log function
  45. #define LOG10 LOG s1 s0 // base-10 log function
  46. #define IF "if " // if conditional
  47. #define G ">" // Greater Than symbol
  48. #define L "<" // Less Than symbol
  49. #define Q "=" // Equality symbol
  50. #define Z "0" // Zero
  51. #define W "1" // One
  52. #define T "\xe2\x86\xa3" // Right arrow
  53. #define H "/" // Slash
  54. #define Pi "\xcf\x80" // PI
  55. #define TAU "\xcf\x84" // TAU
  56. std::vector<Functor> functions {
  57. { "", LAMBDA( 0 ) }, // Passthrough
  58. { C, LAMBDA( c ) }, // Addition
  59. { X A C, LAMBDA( x + c ) },
  60. { Y A C, LAMBDA( y + c ) },
  61. { X A Y A C, LAMBDA( x + y + c ) },
  62. { C S X, LAMBDA( c - x ) }, // Subtraction
  63. { C S Y, LAMBDA( c - y ) },
  64. { X S OP Y A C CP, LAMBDA( x - ( y + c ) ) },
  65. { OP X A C CP S Y, LAMBDA( ( x + c ) - y ) },
  66. { Y S OP X A C CP, LAMBDA( y - ( x + c ) ) },
  67. { OP Y A C CP S X, LAMBDA( ( y + c ) - x ) },
  68. { OP X M Y CP A C, LAMBDA( ( x * y ) + c ) }, // Multiplication
  69. { OP X A C CP M Y, LAMBDA( ( x + c ) * y ) },
  70. { X M OP Y A C CP, LAMBDA( x * ( y + c ) ) },
  71. { X M C, LAMBDA( x * c ) },
  72. { Y M C, LAMBDA( y * c ) },
  73. { X M Y M C, LAMBDA( x * y * c ) },
  74. { Pi M OP X A C CP, LAMBDA( M_PI * ( x + c ) ) },
  75. { Pi M OP Y A C CP, LAMBDA( M_PI * ( y + c ) ) },
  76. { TAU M OP X A C CP, LAMBDA( 2 * M_PI * ( x + c ) ) },
  77. { TAU M OP Y A C CP, LAMBDA( 2 * M_PI * ( y + c ) ) },
  78. { X D C, LAMBDA( x / c ) }, // Division
  79. { C D X, LAMBDA( c / x ) },
  80. { Y D C, LAMBDA( y / c ) },
  81. { C D Y, LAMBDA( c / y ) },
  82. { C A OP X D Y CP, LAMBDA( c + ( x / y ) ) },
  83. { C A OP Y D X CP, LAMBDA( c + ( y / x ) ) },
  84. { X A OP Y D C CP, LAMBDA( x + ( y / c ) ) },
  85. { X A OP C D Y CP, LAMBDA( x + ( c / y ) ) },
  86. { Y A OP X D C CP, LAMBDA( y + ( x / c ) ) },
  87. { Y A OP C D X CP, LAMBDA( y + ( c / x ) ) },
  88. { OP X A C CP D Y, LAMBDA( ( x + c ) / y ) },
  89. { X D OP Y A C CP, LAMBDA( x / ( y + c ) ) },
  90. { OP Y A C CP D X, LAMBDA( ( y + c ) / x ) },
  91. { Y D OP X A C CP, LAMBDA( y / ( x + c ) ) },
  92. { OP X A C CP O Y, LAMBDA( fmodf( x + c , y ) ) }, // Modulo
  93. { OP Y A C CP O X, LAMBDA( fmodf( y + c , x ) ) },
  94. { X O OP Y A C CP, LAMBDA( fmodf( x , y + c ) ) },
  95. { Y O OP X A C CP, LAMBDA( fmodf( y , x + c) ) },
  96. { X O C, LAMBDA( fmodf( x , c ) ) },
  97. { Y O C, LAMBDA( fmodf( y , c ) ) },
  98. { X S2 A C, LAMBDA( x * x + c ) }, // Quadratic
  99. { Y S2 A C, LAMBDA( y * y + c ) },
  100. { OP X A C CP S2, LAMBDA( ( x + c ) * ( x + c ) ) },
  101. { OP Y A C CP S2, LAMBDA( ( y + c ) * ( y + c ) ) },
  102. { X S2 A Y A C, LAMBDA( x * x + y + c ) },
  103. { Y S2 A X A C, LAMBDA( y * y + x + c ) },
  104. { X S2 A C Y, LAMBDA( x * x + c * y ) },
  105. { Y S2 A C X, LAMBDA( y * y + c * x ) },
  106. { R OP X A C CP, LAMBDA( sqrt( x + c ) ) }, // Square Root
  107. { R OP Y A C CP, LAMBDA( sqrt( y + c ) ) },
  108. { C SX, LAMBDA( powf( c , x ) ) }, // Powers
  109. { C SY, LAMBDA( powf( c , y ) ) },
  110. { C SX SA SY, LAMBDA( powf( c , x + y ) ) },
  111. { C SX SY, LAMBDA( powf( c , x * y ) ) },
  112. { X SC, LAMBDA( powf( x , c ) ) },
  113. { Y SC, LAMBDA( powf( y , c ) ) },
  114. { X SY SA SC, LAMBDA( powf( x , y + c ) ) },
  115. { Y SX SA SC, LAMBDA( powf( y , x + c ) ) },
  116. { X SC SY, LAMBDA( powf( x , c * y ) ) },
  117. { Y SC SX, LAMBDA( powf( y , c * x ) ) },
  118. { P X A C P, LAMBDA( abs( x + c ) ) }, // Modulus
  119. { P Y A C P, LAMBDA( abs( y + c ) ) },
  120. { MIN OP X A C COMMA Y CP, LAMBDA( sMIN( x + c, y ) ) }, // Minmax
  121. { MIN OP X COMMA C CP, LAMBDA( sMIN( x, c ) ) },
  122. { MIN OP Y COMMA C CP, LAMBDA( sMIN( y, c ) ) },
  123. { MAX OP X A C COMMA Y CP, LAMBDA( sMAX( x + c, y ) ) },
  124. { MAX OP X COMMA C CP, LAMBDA( sMAX( x, c ) ) },
  125. { MAX OP Y COMMA C CP, LAMBDA( sMAX( y, c ) ) },
  126. { SIN OP X A C CP, LAMBDA( sin( x + c ) ) }, // Trigonometric
  127. { SIN OP Y A C CP, LAMBDA( sin( y + c ) ) },
  128. { SIN OP X A Y CP, LAMBDA( sin( x + y ) ) },
  129. { SIN OP C X CP, LAMBDA( sin( c * x ) ) },
  130. { SIN OP C Y CP, LAMBDA( sin( c * y ) ) },
  131. { SIN OP X Y CP, LAMBDA( sin( x * y ) ) },
  132. { COS OP X A C CP, LAMBDA( cos( x + c ) ) },
  133. { COS OP Y A C CP, LAMBDA( cos( y + c ) ) },
  134. { COS OP X A Y CP, LAMBDA( cos( x + y ) ) },
  135. { COS OP C X CP, LAMBDA( cos( c * x ) ) },
  136. { COS OP C Y CP, LAMBDA( cos( c * y ) ) },
  137. { COS OP X Y CP, LAMBDA( cos( x * y ) ) },
  138. { TAN OP X A C CP, LAMBDA( tan( x + c ) ) },
  139. { TAN OP Y A C CP, LAMBDA( tan( y + c ) ) },
  140. { TAN OP X A Y CP, LAMBDA( tan( x + y ) ) },
  141. { TAN OP C X CP, LAMBDA( tan( c * x ) ) },
  142. { TAN OP C Y CP, LAMBDA( tan( c * y ) ) },
  143. { TAN OP X Y CP, LAMBDA( tan( x * y ) ) },
  144. { ASIN OP X A C CP, LAMBDA( asin( x + c ) ) },
  145. { ASIN OP Y A C CP, LAMBDA( asin( y + c ) ) },
  146. { ASIN OP X A Y CP, LAMBDA( asin( x + y ) ) },
  147. { ASIN OP C X CP, LAMBDA( asin( c * x ) ) },
  148. { ASIN OP C Y CP, LAMBDA( asin( c * y ) ) },
  149. { ASIN OP X Y CP, LAMBDA( asin( x * y ) ) },
  150. { ACOS OP X A C CP, LAMBDA( acos( x + c ) ) },
  151. { ACOS OP Y A C CP, LAMBDA( acos( y + c ) ) },
  152. { ACOS OP X A Y CP, LAMBDA( acos( x + y ) ) },
  153. { ACOS OP C X CP, LAMBDA( acos( c * x ) ) },
  154. { ACOS OP C Y CP, LAMBDA( acos( c * y ) ) },
  155. { ACOS OP X Y CP, LAMBDA( acos( x * y ) ) },
  156. { ATAN OP X A C CP, LAMBDA( atan( x + c ) ) },
  157. { ATAN OP Y A C CP, LAMBDA( atan( y + c ) ) },
  158. { ATAN OP X A Y CP, LAMBDA( atan( x + y ) ) },
  159. { ATAN OP C X CP, LAMBDA( atan( c * x ) ) },
  160. { ATAN OP C Y CP, LAMBDA( atan( c * y ) ) },
  161. { ATAN OP X Y CP, LAMBDA( atan( x * y ) ) },
  162. { LOG OP X A C CP, LAMBDA( log( x + c ) ) }, // Logarithmic
  163. { LOG OP Y A C CP, LAMBDA( log( y + c ) ) },
  164. { LOG2 OP X A C CP, LAMBDA( log2( x + c ) ) },
  165. { LOG2 OP Y A C CP, LAMBDA( log2( y + c ) ) },
  166. { LOG10 OP X A C CP, LAMBDA( log10( x + c ) ) },
  167. { LOG10 OP Y A C CP, LAMBDA( log10( y + c ) ) },
  168. { E SX SA SC, LAMBDA( exp( x + c ) ) }, // Exponential
  169. { E SY SA SC, LAMBDA( exp( y + c ) ) },
  170. { E SC SX, LAMBDA( exp( c * x ) ) },
  171. { E SC SY, LAMBDA( exp( c * y ) ) },
  172. { "2" SX SA SC, LAMBDA( powf( 2, x + c ) ) },
  173. { "2" SY SA SC, LAMBDA( powf( 2, y + c ) ) },
  174. { "2" SC SX, LAMBDA( powf( 2, c * x ) ) },
  175. { "2" SC SY, LAMBDA( powf( 2, c * y ) ) },
  176. { "10" SX SA SC, LAMBDA( powf( 10, x + c ) ) },
  177. { "10" SY SA SC, LAMBDA( powf( 10, y + c ) ) },
  178. { "10" SC SX, LAMBDA( powf( 10, c * x ) ) },
  179. { "10" SC SY, LAMBDA( powf( 10, c * y ) ) },
  180. { IF X G Z T Y H C, LAMBDA( (x > 0) ? y : c ) }, // Conditional
  181. { IF X L Z T Y H C, LAMBDA( (x < 0) ? y : c ) },
  182. { IF X Q Z T Y H C, LAMBDA( (x == 0) ? y : c ) },
  183. { IF X G Z T C H Y, LAMBDA( (x > 0) ? c : y ) },
  184. { IF X L Z T C H Y, LAMBDA( (x < 0) ? c : y ) },
  185. { IF X Q Z T C H Y, LAMBDA( (x == 0) ? c : y ) },
  186. { IF X G Z T W H Z, LAMBDA( (x > 0) ? 1 : 0 ) },
  187. { IF X L Z T W H Z, LAMBDA( (x < 0) ? 1 : 0 ) },
  188. { IF X Q Z T W H Z, LAMBDA( (x == 0) ? 1 : 0 ) },
  189. { IF X G Z T X H C, LAMBDA( (x > 0) ? x : c ) },
  190. { IF X L Z T X H C, LAMBDA( (x < 0) ? x : c ) },
  191. { IF X Q Z T X H C, LAMBDA( (x == 0) ? x : c ) },
  192. { IF X G Z T C H X, LAMBDA( (x > 0) ? c : x ) },
  193. { IF X L Z T C H X, LAMBDA( (x < 0) ? c : x ) },
  194. { IF X Q Z T C H X, LAMBDA( (x == 0) ? c : x ) },
  195. { IF Y G Z T X H C, LAMBDA( (y > 0) ? x : c ) },
  196. { IF Y L Z T X H C, LAMBDA( (y < 0) ? x : c ) },
  197. { IF Y Q Z T X H C, LAMBDA( (y == 0) ? x : c ) },
  198. { IF Y G Z T C H X, LAMBDA( (y > 0) ? c : x ) },
  199. { IF Y L Z T C H X, LAMBDA( (y < 0) ? c : x ) },
  200. { IF Y Q Z T C H X, LAMBDA( (y == 0) ? c : x ) },
  201. { IF Y G Z T W H Z, LAMBDA( (y > 0) ? 1 : 0 ) },
  202. { IF Y L Z T W H Z, LAMBDA( (y < 0) ? 1 : 0 ) },
  203. { IF Y Q Z T W H Z, LAMBDA( (y == 0) ? 1 : 0 ) },
  204. { IF Y G Z T Y H C, LAMBDA( (y > 0) ? y : c ) },
  205. { IF Y L Z T Y H C, LAMBDA( (y < 0) ? y : c ) },
  206. { IF Y Q Z T Y H C, LAMBDA( (y == 0) ? y : c ) },
  207. { IF Y G Z T C H Y, LAMBDA( (y > 0) ? c : y ) },
  208. { IF Y L Z T C H Y, LAMBDA( (y < 0) ? c : y ) },
  209. { IF Y Q Z T C H Y, LAMBDA( (y == 0) ? c : y ) },
  210. { IF X G Y T C H Z, LAMBDA( (x > y) ? c : 0 ) },
  211. { IF X L Y T C H Z, LAMBDA( (x < y) ? c : 0 ) },
  212. { IF X Q Y T C H Z, LAMBDA( (x == y) ? c : 0 ) },
  213. { IF Y G X T C H Z, LAMBDA( (y > x) ? c : 0 ) },
  214. { IF Y L X T C H Z, LAMBDA( (y < x) ? c : 0 ) },
  215. { IF X G Y T X H Z, LAMBDA( (x > y) ? x : 0 ) },
  216. { IF X L Y T X H Z, LAMBDA( (x < y) ? x : 0 ) },
  217. { IF X Q Y T X H Z, LAMBDA( (x == y) ? x : 0 ) },
  218. { IF Y G X T X H Z, LAMBDA( (y > x) ? x : 0 ) },
  219. { IF Y L X T X H Z, LAMBDA( (y < x) ? x : 0 ) },
  220. { IF X G Y T Y H Z, LAMBDA( (x > y) ? y : 0 ) },
  221. { IF X L Y T Y H Z, LAMBDA( (x < y) ? y : 0 ) },
  222. { IF X Q Y T Y H Z, LAMBDA( (x == y) ? y : 0 ) },
  223. { IF Y G X T Y H Z, LAMBDA( (y > x) ? y : 0 ) },
  224. { IF Y L X T Y H Z, LAMBDA( (y < x) ? y : 0 ) },
  225. { IF X G C T Y H Z, LAMBDA( (x > c) ? y : 0 ) },
  226. { IF X L C T Y H Z, LAMBDA( (x < c) ? y : 0 ) },
  227. { IF X Q C T Y H Z, LAMBDA( (x == c) ? y : 0 ) },
  228. { IF C G X T Y H Z, LAMBDA( (c > x) ? y : 0 ) },
  229. { IF C L X T Y H Z, LAMBDA( (c < x) ? y : 0 ) },
  230. { IF X G C T X H Z, LAMBDA( (x > c) ? x : 0 ) },
  231. { IF X L C T X H Z, LAMBDA( (x < c) ? x : 0 ) },
  232. { IF X Q C T X H Z, LAMBDA( (x == c) ? x : 0 ) },
  233. { IF C G X T X H Z, LAMBDA( (c > x) ? x : 0 ) },
  234. { IF C L X T X H Z, LAMBDA( (c < x) ? x : 0 ) },
  235. { IF X G C T X H Y, LAMBDA( (x > c) ? x : y ) },
  236. { IF X L C T X H Y, LAMBDA( (x < c) ? x : y ) },
  237. { IF X Q C T X H Y, LAMBDA( (x == c) ? x : y ) },
  238. { IF C G X T X H Y, LAMBDA( (c > x) ? x : y ) },
  239. { IF C L X T X H Y, LAMBDA( (c < x) ? x : y ) },
  240. { IF Y G C T X H Z, LAMBDA( (y > c) ? x : 0 ) },
  241. { IF Y L C T X H Z, LAMBDA( (y < c) ? x : 0 ) },
  242. { IF Y Q C T X H Z, LAMBDA( (y == c) ? x : 0 ) },
  243. { IF C G Y T X H Z, LAMBDA( (c > y) ? x : 0 ) },
  244. { IF C L Y T X H Z, LAMBDA( (c < y) ? x : 0 ) },
  245. { IF Y G C T Y H Z, LAMBDA( (y > c) ? y : 0 ) },
  246. { IF Y L C T Y H Z, LAMBDA( (y < c) ? y : 0 ) },
  247. { IF Y Q C T Y H Z, LAMBDA( (y == c) ? y : 0 ) },
  248. { IF C G Y T Y H Z, LAMBDA( (c > y) ? y : 0 ) },
  249. { IF C L Y T Y H Z, LAMBDA( (c < y) ? y : 0 ) },
  250. { IF Y G C T Y H X, LAMBDA( (y > c) ? y : x ) },
  251. { IF Y L C T Y H X, LAMBDA( (y < c) ? y : x ) },
  252. { IF Y Q C T Y H X, LAMBDA( (y == c) ? y : x ) },
  253. { IF C G Y T Y H X, LAMBDA( (c > y) ? y : x ) },
  254. { IF C L Y T Y H X, LAMBDA( (c < y) ? y : x ) },
  255. };
  256. #undef X
  257. #undef Y
  258. #undef C
  259. #undef A
  260. #undef S
  261. #undef O
  262. #undef OP
  263. #undef CP
  264. #undef P
  265. #undef M
  266. #undef D
  267. #undef R
  268. #undef S2
  269. #undef S3
  270. #undef s0
  271. #undef s1
  272. #undef s2
  273. #undef E
  274. #undef SA
  275. #undef SX
  276. #undef SY
  277. #undef SC
  278. #undef COMMA
  279. #undef MIN
  280. #undef MAX
  281. #undef SIN
  282. #undef COS
  283. #undef TAN
  284. #undef ASIN
  285. #undef ACOS
  286. #undef ATAN
  287. #undef LOG
  288. #undef LOG2
  289. #undef LOG10
  290. #undef IF
  291. #undef G
  292. #undef L
  293. #undef Q
  294. #undef Z
  295. #undef W
  296. #undef T
  297. #undef H
  298. #undef Pi
  299. #undef TAU
  300. } // end namespace SubmarineA0
  301. struct AOFuncDisplay : Knob {
  302. std::shared_ptr<Font> font;
  303. AOFuncDisplay() {
  304. box.size.x = 80;
  305. box.size.y = 15;
  306. snap = true;
  307. smooth = false;
  308. speed = 0.5f;
  309. font = Font::load(assetGlobal("res/fonts/DejaVuSans.ttf"));
  310. }
  311. void draw(NVGcontext *vg) override {
  312. nvgFontSize(vg, 16);
  313. nvgFontFaceId(vg, font->handle);
  314. nvgFillColor(vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff));
  315. nvgTextAlign(vg, NVG_ALIGN_CENTER);
  316. nvgText(vg, 41.5, 13, SubmarineAO::functions[value].name.c_str(), NULL);
  317. }
  318. };
  319. struct AOConstDisplay : Knob {
  320. std::shared_ptr<Font> font;
  321. AOConstDisplay() {
  322. box.size.x = 80;
  323. box.size.y = 15;
  324. snap = true;
  325. speed = 0.005;
  326. font = Font::load(assetGlobal("res/fonts/DejaVuSans.ttf"));
  327. }
  328. void draw(NVGcontext *vg) override {
  329. char mtext[41];
  330. sprintf(mtext, "C=%4.2f", ((int)value)/100.0f);
  331. nvgFontSize(vg, 16);
  332. nvgFontFaceId(vg, font->handle);
  333. nvgFillColor(vg, nvgRGBA(0x28, 0xb0, 0xf3, 0xff));
  334. nvgTextAlign(vg, NVG_ALIGN_CENTER);
  335. nvgText(vg, 41.5, 13, mtext, NULL);
  336. }
  337. };
  338. template <unsigned int x, unsigned int y>
  339. struct AO1 : Module {
  340. enum ParamIds {
  341. PARAM_FUNC_1,
  342. PARAM_CONST_1 = x * y,
  343. NUM_PARAMS = 2 * x * y
  344. };
  345. enum InputIds {
  346. INPUT_X_1,
  347. INPUT_Y_1 = x,
  348. NUM_INPUTS = x + y
  349. };
  350. enum OutputIds {
  351. OUTPUT_X_1,
  352. OUTPUT_Y_1 = x,
  353. NUM_OUTPUTS = x + y
  354. };
  355. enum LightIds {
  356. NUM_LIGHTS
  357. };
  358. AO1() : Module(NUM_PARAMS, NUM_INPUTS, NUM_OUTPUTS, NUM_LIGHTS) {}
  359. void step() override {
  360. float vx[x];
  361. for (unsigned int ix = 0; ix < x; ix++) {
  362. vx[ix] = inputs[INPUT_X_1 + ix].value;
  363. }
  364. for (unsigned int iy = 0; iy < y; iy++) {
  365. float vy = inputs[INPUT_Y_1 + iy].value;
  366. for (unsigned int ix = 0; ix < x; ix++) {
  367. unsigned int f = params[PARAM_FUNC_1 + ix + iy * x].value;
  368. if (f >= SubmarineAO::functions.size())
  369. f = SubmarineAO::functions.size() - 1;
  370. if (f > 0)
  371. vy = vx[ix] = SubmarineAO::functions[f].func(vx[ix], vy, ((int)params[PARAM_CONST_1 + ix + iy * x].value)/100.0f);
  372. // if f is equal to 0, then both x and y pass (crossing) through the module unchanged.
  373. }
  374. outputs[OUTPUT_Y_1 + iy].value = std::isfinite(vy)?vy:0.0f;
  375. }
  376. for (unsigned int ix = 0; ix < x; ix++) {
  377. outputs[OUTPUT_X_1 + ix].value = std::isfinite(vx[ix])?vx[ix]:0.0f;
  378. }
  379. }
  380. };
  381. template <unsigned int x, unsigned int y>
  382. struct AOWidget : ModuleWidget {
  383. AOWidget(AO1<x,y> *module) : ModuleWidget(module) {
  384. setPanel(SubHelper::LoadPanel(plugin, "AO-1", x*y));
  385. for (unsigned int ix = 0; ix < x; ix++) {
  386. addInput(Port::create<SilverPort>(Vec(4, 61 + ix * 46), Port::INPUT, module, AO1<x,y>::INPUT_X_1 + ix));
  387. addOutput(Port::create<SilverPort>(Vec(46 + y * 90, 61 + ix * 46), Port::OUTPUT, module, AO1<x,y>::OUTPUT_X_1 + ix));
  388. }
  389. for (unsigned int iy = 0; iy < y; iy++) {
  390. addInput(Port::create<SilverPort>(Vec(70 + 90 * iy, 19), Port::INPUT, module, AO1<x,y>::INPUT_Y_1 + iy));
  391. addOutput(Port::create<SilverPort>(Vec(70 + 90 * iy, 335), Port::OUTPUT, module, AO1<x,y>::OUTPUT_Y_1 + iy));
  392. }
  393. for (unsigned int iy = 0; iy < y; iy++) {
  394. for (unsigned int ix = 0; ix < x; ix++) {
  395. addParam(ParamWidget::create<AOFuncDisplay>(Vec(42.5 + 90 * iy, 59 + 46 * ix), module, AO1<x,y>::PARAM_FUNC_1 + ix + iy * x, 0.0f, SubmarineAO::functions.size() - 1.0f, 0.0f ));
  396. addParam(ParamWidget::create<AOConstDisplay>(Vec(42.5 + 90 * iy, 78 + 46 * ix), module, AO1<x,y>::PARAM_CONST_1 + ix + iy * x, -10000.0f, 10000.0f, 0.0f));
  397. }
  398. }
  399. }
  400. };
  401. } // namespace rack_plugin_SubmarineFree
  402. using namespace rack_plugin_SubmarineFree;
  403. RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO106) {
  404. Model *modelAO106 = Model::create<AO1<6,1>, AOWidget<6,1>>("Submarine (Free)", "A0-106", "A0-106 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG);
  405. return modelAO106;
  406. }
  407. RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO112) {
  408. Model *modelAO112 = Model::create<AO1<6,2>, AOWidget<6,2>>("Submarine (Free)", "A0-112", "A0-112 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG);
  409. return modelAO112;
  410. }
  411. RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO118) {
  412. Model *modelAO118 = Model::create<AO1<6,3>, AOWidget<6,3>>("Submarine (Free)", "A0-118", "A0-118 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG);
  413. return modelAO118;
  414. }
  415. RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO124) {
  416. Model *modelAO124 = Model::create<AO1<6,4>, AOWidget<6,4>>("Submarine (Free)", "A0-124", "A0-124 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG);
  417. return modelAO124;
  418. }
  419. RACK_PLUGIN_MODEL_INIT(SubmarineFree, AO136) {
  420. Model *modelAO136 = Model::create<AO1<6,6>, AOWidget<6,6>>("Submarine (Free)", "A0-136", "A0-136 Arithmetic Operators", UTILITY_TAG, MULTIPLE_TAG);
  421. return modelAO136;
  422. }