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.

298 lines
12KB

  1. //
  2. // VecAmalgam.cpp
  3. // BitCombiner
  4. //
  5. // Created by Dale Johnson on 26/11/2018.
  6. // Copyright © 2018 Dale Johnson. All rights reserved.
  7. //
  8. #include "VecAmalgam.hpp"
  9. VecAmalgam::VecAmalgam() {
  10. __zeros = _mm_set1_ps(0.f);
  11. __ones = _mm_set1_ps(1.f);
  12. __negOnes = _mm_set1_ps(-1.f);
  13. __halfs = _mm_set1_ps(0.5f);
  14. __ffTarget = __zeros;
  15. __high = _mm_castsi128_ps(_mm_set1_epi32(0xFFFFFFFF));
  16. __x = __zeros;
  17. __y = __zeros;
  18. __z = __zeros;
  19. __xFolded = __zeros;
  20. __yFolded = __zeros;
  21. __zero16 = Dmm_set1_pi16(0);
  22. __one16 = Dmm_set1_pi16(1);
  23. __a = __zero16;
  24. __b = __zero16;
  25. __c = __zero16;
  26. __aPrev = __zero16;
  27. __bPrev = __zero16;
  28. __aREdge = __zero16;
  29. __bREdge = __zero16;
  30. __count = Dmm_set1_pi16(0xFFFF);
  31. _step = 1.f;
  32. __xDS = __zeros;
  33. __yDS = __zeros;
  34. __zDS = __zeros;
  35. p[RING_MOD_1_MODE] = &VecAmalgam::ringMod1;
  36. p[RING_MOD_2_MODE] = &VecAmalgam::ringMod2;
  37. p[RING_MOD_3_MODE] = &VecAmalgam::ringMod3;
  38. p[DIODE_RING_MOD_MODE] = &VecAmalgam::diodeRingMod;
  39. p[MIN_MAX_MODE] = &VecAmalgam::minMax;
  40. p[SIGN_SWITCH_1_MODE] = &VecAmalgam::signSwitch1;
  41. p[SIGN_SWITCH_2_MODE] = &VecAmalgam::signSwitch2;
  42. p[X_FADE_MODE] = &VecAmalgam::xFade;
  43. p[FLIP_FLOP_MODE] = &VecAmalgam::flipFlop;
  44. p[ALPHA_PWM_MODE] = &VecAmalgam::alphaPWM;
  45. p[BIT_AND_MODE] = &VecAmalgam::bitAND;
  46. p[BIT_XOR_MODE] = &VecAmalgam::bitXOR;
  47. p[BIT_INTERLEAVE_MODE] = &VecAmalgam::bitInterleave;
  48. p[BIT_HACK_MODE] = &VecAmalgam::bitHack;
  49. p[BIT_AND_FLOAT_MODE] = &VecAmalgam::bitANDFloat;
  50. p[BIT_INTERLEAVE_FLOAT_MODE] = &VecAmalgam::bitInterleaveFloat;
  51. p[BIT_HACK_FLOAT_MODE] = &VecAmalgam::bitHackFloat;
  52. _mode = RING_MOD_1_MODE;
  53. std::srand(std::time(NULL));
  54. for(auto i = 0; i < 4; ++i) {
  55. _z[i] = std::rand();
  56. _w[i] = std::rand();
  57. _k[i] = 0;
  58. }
  59. setSampleRate(44100.f);
  60. }
  61. void VecAmalgam::setMode(int mode) {
  62. _mode = mode;
  63. if(_mode < 0) {
  64. _mode = 0;
  65. }
  66. else if(_mode >= NUM_MODES) {
  67. _mode = NUM_MODES - 1;
  68. }
  69. }
  70. void VecAmalgam::setSampleRate(float sampleRate) {
  71. _engineSampleRate = sampleRate;
  72. _quarterNyquist = _engineSampleRate / 32.f;
  73. calcStepSize();
  74. }
  75. void VecAmalgam::calcStepSize() {
  76. _internalSampleRate = _quarterNyquist * powf(2.f, (_updateRate * 5.f));
  77. _stepSize = _internalSampleRate / _engineSampleRate;
  78. }
  79. __m128 VecAmalgam::ringMod1(const __m128& x, const __m128& y, float paramA, float paramB) {
  80. __z = _mm_or_ps(_mm_cmpgt_ps(y, _mm_set1_ps(paramB * 1.066f)),
  81. _mm_cmplt_ps(y, _mm_set1_ps(paramB * -1.066f)));
  82. __z = _mm_and_ps(y, __z);
  83. return _mm_mul_ps(_mm_add_ps(_mm_mul_ps(x, _mm_set1_ps(1.f - 0.5f * paramA)),
  84. _mm_set1_ps(paramA * 0.5f)), __z);
  85. }
  86. __m128 VecAmalgam::ringMod2(const __m128& x, const __m128& y, float paramA, float paramB) {
  87. __xFolded = _mm_add_ps(_mm_mul_ps(x, __halfs), __halfs);
  88. __yFolded = _mm_add_ps(_mm_mul_ps(y, __halfs), __halfs);
  89. __xFolded = _mm_mirror_ps(__xFolded, _mm_set1_ps(paramA + 0.00001f));
  90. __yFolded = _mm_mirror_ps(__yFolded, _mm_set1_ps(paramB + 0.00001f));
  91. __xFolded = _mm_mul_ps(_mm_add_ps(__xFolded, _mm_set1_ps(-0.5f)),_mm_set1_ps(2.f));
  92. __yFolded = _mm_mul_ps(_mm_add_ps(__yFolded, _mm_set1_ps(-0.5f)),_mm_set1_ps(2.f));
  93. return _mm_mul_ps(__xFolded, __yFolded);
  94. }
  95. __m128 VecAmalgam::ringMod3(const __m128& x, const __m128& y, float paramA, float paramB) {
  96. __xFolded = _mm_add_ps(_mm_mul_ps(x, __halfs), __halfs);
  97. __yFolded = _mm_add_ps(_mm_mul_ps(y, __halfs), __halfs);
  98. __xFolded = _mm_mirror_ps(__xFolded, _mm_set1_ps(paramA + 0.00001f));
  99. __yFolded = _mm_mirror_ps(__yFolded, _mm_set1_ps(paramA + 0.00001f));
  100. __xFolded = _mm_mul_ps(_mm_add_ps(__xFolded, _mm_set1_ps(-0.5f)),_mm_set1_ps(2.f));
  101. __yFolded = _mm_mul_ps(_mm_add_ps(__yFolded, _mm_set1_ps(-0.5f)),_mm_set1_ps(-2.f));
  102. __xLogic = _mm_cmpgt_ps(__xFolded, __zeros);
  103. __yLogic = _mm_cmpgt_ps(__yFolded, __zeros);
  104. __zLogic = _mm_xor_ps(__xLogic, __yLogic);
  105. __z = _mm_and_ps(__zLogic, __ones);
  106. __z = _mm_add_ps(_mm_mul_ps(__z, _mm_set1_ps(-2.f)), __ones);
  107. return _mm_linterp_ps(_mm_mul_ps(__xFolded, __yFolded), __z, _mm_set1_ps(paramB));
  108. }
  109. __m128 VecAmalgam::diodeRingMod(const __m128& x, const __m128& y, float paramA, float paramB) {
  110. return _d.process(x, y, paramA, paramB);
  111. }
  112. __m128 VecAmalgam::minMax(const __m128& x, const __m128& y, float paramA, float paramB) {
  113. __m128 select = _mm_cmpgt_ps(x, y);
  114. __m128 max = _mm_switch_ps(y, x, select);
  115. __m128 min = _mm_switch_ps(x, y, select);
  116. __m128 delta = _mm_sub_ps(max, min);
  117. __z = _mm_linterp_ps(min, max, _mm_set1_ps(paramA));
  118. return _mm_linterp_ps(__z, _mm_mul_ps(__z, delta), _mm_set1_ps(paramB));
  119. }
  120. __m128 VecAmalgam::signSwitch1(const __m128& x, const __m128& y, float paramA, float paramB) {
  121. __m128 midPoint = _mm_set1_ps(paramA * 2.f - 1.f);
  122. __m128 thresh = _mm_set1_ps(paramB);
  123. return _mm_add_ps(_mm_and_ps(x, _mm_cmpge_ps(x, _mm_add_ps(midPoint, thresh))),
  124. _mm_and_ps(y, _mm_cmplt_ps(y,_mm_sub_ps(midPoint, thresh))));
  125. }
  126. __m128 VecAmalgam::signSwitch2(const __m128& x, const __m128& y, float paramA, float paramB) {
  127. __m128 midPoint = _mm_set1_ps(paramA * 2.f - 1.f);
  128. __m128 thresh = _mm_set1_ps(paramB);
  129. __z = _mm_switch_ps(__zeros, x, _mm_cmpgt_ps(x, _mm_add_ps(midPoint, thresh)));
  130. return _mm_switch_ps(__z, y, _mm_cmplt_ps(y, _mm_sub_ps(midPoint, thresh)));
  131. }
  132. __m128 VecAmalgam::xFade(const __m128& x, const __m128& y, float paramA, float paramB) {
  133. __m128 xScaled = _mm_add_ps(_mm_mul_ps(x, __halfs), __halfs);
  134. xScaled = _mm_mul_ps(xScaled, _mm_set1_ps(paramB));
  135. return _mm_linterp_ps(x,y, _mm_clamp_ps(_mm_add_ps(_mm_set1_ps(paramA), xScaled), __zeros, __ones));
  136. }
  137. __m128 VecAmalgam::flipFlop(const __m128& x, const __m128& y, float paramA, float paramB) {
  138. __m128 thresh = _mm_set1_ps(paramB);
  139. for(auto i = 0; i < 4; ++i) {
  140. _k[i] = (float)mwcRand(_z[i], _w[i]) / (float)UINT32_MAX;
  141. }
  142. __chanceX = _mm_loadu_ps(_k);
  143. __chanceX = _mm_and_ps(_mm_cmpgt_ps(__chanceX, _mm_set1_ps(paramA)), __high);
  144. for(auto i = 0; i < 4; ++i) {
  145. _k[i] = (float)mwcRand(_z[i], _w[i]) / (float)UINT32_MAX;
  146. }
  147. __chanceY = _mm_loadu_ps(_k);
  148. __chanceY = _mm_and_ps(_mm_cmpgt_ps(__chanceY, _mm_set1_ps(1.f - paramA)), __high);
  149. __xREdge = _mm_and_ps(_mm_cmpgt_ps(x, thresh), _mm_cmple_ps(__xPrev, thresh));
  150. __yREdge = _mm_and_ps(_mm_cmpgt_ps(y, thresh), _mm_cmple_ps(__yPrev, thresh));
  151. __xREdge = _mm_and_ps(__xREdge, __chanceX);
  152. __yREdge = _mm_and_ps(__yREdge, __chanceY);
  153. __ffTarget = _mm_switch_ps(__ffTarget, __zeros, __xREdge);
  154. __ffTarget = _mm_switch_ps(__ffTarget, __high, __yREdge);
  155. __xPrev = x;
  156. __yPrev = y;
  157. return _mm_switch_ps(x, y, __ffTarget);
  158. }
  159. __m128 VecAmalgam::alphaPWM(const __m128& x, const __m128& y, float paramA, float paramB) {
  160. __z = _mm_mul_ps(_mm_abs_ps(x), __halfs);
  161. __z = _mm_mul_ps(__z, _mm_add_ps(_mm_mul_ps(_mm_set1_ps(paramA), _mm_set1_ps(16.f)), __ones));
  162. __m128i xInt = _mm_cvttps_epi32(__z);
  163. __m128 xIntF = _mm_cvtepi32_ps(xInt);
  164. __z = _mm_sub_ps(__z, xIntF);
  165. return _mm_mul_ps(_mm_switch_ps(x, _mm_set1_ps(0.f), _mm_cmpgt_ps(__z, _mm_set1_ps(1.f - paramB))), y);
  166. }
  167. __m128 VecAmalgam::bitAND(const __m128& x, const __m128& y, float paramA, float paramB) {
  168. paramA = 1.f - paramA * 0.8f;
  169. paramA *= paramA;
  170. downSample(_mm_varStep_ps(x, _mm_set1_ps(1.f - paramA)),_mm_varStep_ps(y, _mm_set1_ps(1.f - paramA)));
  171. __a32 = _mm_cvttps_epi32(_mm_mul_ps(__xDS, _mm_set1_ps(0x7FFFFFFF)));
  172. __b32 = _mm_cvttps_epi32(_mm_mul_ps(__yDS, _mm_set1_ps(0x7FFFFFFF)));
  173. __c32 = _mm_and_si128(__a32, __b32);
  174. return _mm_div_ps(_mm_cvtepi32_ps(__c32), _mm_set1_ps(0x7FFFFFFF));
  175. }
  176. __m128 VecAmalgam::bitXOR(const __m128& x, const __m128& y, float paramA, float paramB) {
  177. paramA = 1.f - paramA * 0.8f;
  178. paramA *= paramA;
  179. downSample(_mm_varStep_ps(x, _mm_set1_ps(1.f - paramA)),_mm_varStep_ps(y, _mm_set1_ps(1.f - paramA)));
  180. __a32 = _mm_cvttps_epi32(_mm_mul_ps(__xDS, _mm_set1_ps(0x7FFFFFFF)));
  181. __b32 = _mm_cvttps_epi32(_mm_mul_ps(__yDS, _mm_set1_ps(0x7FFFFFFF)));
  182. __c32 = _mm_xor_si128(__a32, __b32);
  183. return _mm_div_ps(_mm_cvtepi32_ps(__c32), _mm_set1_ps(0x7FFFFFFF));
  184. }
  185. __m128 VecAmalgam::bitInterleave(const __m128& x, const __m128& y, float paramA, float paramB) {
  186. paramA = 1.f - paramA * 0.8f;
  187. paramA *= paramA;
  188. downSample(_mm_varStep_ps(x, _mm_set1_ps(1.f - paramA)),_mm_varStep_ps(y, _mm_set1_ps(1.f - paramA)));
  189. __a32 = _mm_cvttps_epi32(_mm_mul_ps(__xDS, _mm_set1_ps(0x7FFFFFFF)));
  190. __b32 = _mm_cvttps_epi32(_mm_mul_ps(__yDS, _mm_set1_ps(0x7FFFFFFF)));
  191. __c32 = _mm_xor_si128(__a32, __b32);
  192. __c32 = _mm_or_si128(_mm_and_si128(__a32, _mm_set1_epi32(0x55555555)), _mm_and_si128(__b32, _mm_set1_epi32(0xAAAAAAAA)));
  193. return _mm_div_ps(_mm_cvtepi32_ps(__c32), _mm_set1_ps(0x7FFFFFFF));
  194. }
  195. __m128 VecAmalgam::bitHack(const __m128& x, const __m128& y, float paramA, float paramB) {
  196. __chance32 = __high;
  197. int random = 0;
  198. for(auto i = 0; i < 4; ++i) {
  199. random = mwcRand(_z[i], _w[i]);
  200. _k32[i] = (float)random / (float)UINT32_MAX > (0.5f - paramA * paramA * 0.5f) ? random : 0xFFFFFFFF;
  201. }
  202. __chance32 = _mm_castsi128_ps(_mm_set_epi32(_k32[3], _k32[2], _k32[1], _k32[0]));
  203. downSample(x,y);
  204. __a32 = _mm_cvttps_epi32(_mm_mul_ps(__xDS, _mm_set1_ps(0x7FFFFFFF)));
  205. __b32 = _mm_cvttps_epi32(_mm_mul_ps(__yDS, _mm_set1_ps(0x7FFFFFFF)));
  206. __c32 = _mm_and_si128(_mm_or_si128(__c32, _mm_and_si128(__a32, __b32)), _mm_castps_si128(__chance32)); // Make 1 if a == 1 AND b == 1
  207. #ifdef _MSC_VER
  208. {
  209. // workaround for MSVC "error C2675: unary '~': '__m128i' does not define this operator or a conversion to a type acceptable to the predefined operator"
  210. __m128i a32inv;
  211. a32inv.m128i_u64[0] = ~__a32.m128i_u64[0];
  212. a32inv.m128i_u64[1] = ~__a32.m128i_u64[1];
  213. __m128i b32inv;
  214. b32inv.m128i_u64[0] = ~__b32.m128i_u64[0];
  215. b32inv.m128i_u64[1] = ~__b32.m128i_u64[1];
  216. __m128i tinv = _mm_and_si128(_mm_and_si128(a32inv, b32inv), _mm_castps_si128(__chance32));
  217. tinv.m128i_u64[0] = ~tinv.m128i_u64[0];
  218. tinv.m128i_u64[1] = ~tinv.m128i_u64[1];
  219. __c32 = _mm_and_si128(__c32, tinv); // Make 0 if a == 0 AND b == 0
  220. }
  221. #else
  222. __c32 = _mm_and_si128(__c32, ~_mm_and_si128(_mm_and_si128(~__a32, ~__b32), _mm_castps_si128(__chance32))); // Make 0 if a == 0 AND b == 0
  223. #endif
  224. __z = _mm_div_ps(_mm_cvtepi32_ps(__c32), _mm_set1_ps(0x7FFFFFFF));
  225. __zDS = _mm_switch_ps(__zDS, __z, __sample);
  226. return __zDS;
  227. }
  228. __m128 VecAmalgam::bitANDFloat(const __m128& x, const __m128& y, float paramA, float paramB) {
  229. __chance32 = __high;
  230. int random = 0;
  231. for(auto i = 0; i < 4; ++i) {
  232. random = mwcRand(_z[i], _w[i]);
  233. _k32[i] = (float)random / (float)UINT32_MAX > (0.5f - paramA * paramA * 0.5f) ? random : 0xFFFFFFFF;
  234. }
  235. __chance32 = _mm_castsi128_ps(_mm_set_epi32(_k32[3], _k32[2], _k32[1], _k32[0]));
  236. downSample(x,y);
  237. __z = _mm_and_ps(_mm_and_ps(__xDS,__yDS), __chance32);
  238. __zDS = _mm_switch_ps(__zDS, __z, __sample);
  239. return __zDS;
  240. }
  241. __m128 VecAmalgam::bitInterleaveFloat(const __m128& x, const __m128& y, float paramA, float paramB) {
  242. paramA = 1.f - paramA * 0.8f;
  243. paramA *= paramA;
  244. downSample(_mm_varStep_ps(x, _mm_set1_ps(1.f - paramA)),_mm_varStep_ps(y, _mm_set1_ps(1.f - paramA)));
  245. return _mm_or_ps(_mm_and_ps(__xDS, _mm_castsi128_ps(_mm_set1_epi32(0x55555555))),
  246. _mm_and_ps(__yDS, _mm_castsi128_ps(_mm_set1_epi32(0xAAAAAAAA))));
  247. }
  248. __m128 VecAmalgam::bitHackFloat(const __m128& x, const __m128& y, float paramA, float paramB) {
  249. __chance32 = __high;
  250. int random = 0;
  251. for(auto i = 0; i < 4; ++i) {
  252. random = mwcRand(_z[i], _w[i]);
  253. _k32[i] = (float)random / (float)UINT32_MAX > (0.5f - paramA * paramA * 0.5f) ? random : 0xFFFFFFFF;
  254. }
  255. __chance32 = _mm_castsi128_ps(_mm_set_epi32(_k32[3], _k32[2], _k32[1], _k32[0]));
  256. downSample(x,y);
  257. __z = _mm_and_ps(_mm_or_ps(__z, _mm_and_ps(__xDS,__yDS)), __chance32);
  258. __z = _mm_andnot_ps(_mm_and_ps(_mm_and_ps(_mm_xor_ps(__xDS, __high), _mm_xor_ps(__yDS, __high)),__chance32), __z);
  259. __zDS = _mm_switch_ps(__zDS, __z, __sample);
  260. return __zDS;
  261. }