The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

687 lines
26KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. namespace juce
  20. {
  21. namespace dsp
  22. {
  23. namespace SIMDRegister_test_internal
  24. {
  25. template <typename type>
  26. static void fillRandom (type* dst, const int size, Random& random)
  27. {
  28. bool is_signed = std::is_signed<type>::value;
  29. for (int i = 0; i < size; ++i)
  30. {
  31. if (is_signed)
  32. {
  33. *dst++ = static_cast<type> ((random.nextFloat() * 16.0) - 8.0);
  34. }
  35. else
  36. {
  37. *dst++ = static_cast<type> (random.nextFloat() * 8.0);
  38. }
  39. }
  40. }
  41. template <typename type>
  42. static void fillRandom (std::complex<type>* dst, const int size, Random& random)
  43. {
  44. for (int i = 0; i < size; ++i)
  45. {
  46. type real, imag;
  47. real = static_cast<type> ((random.nextFloat() * 16.0) - 8.0);
  48. imag = static_cast<type> ((random.nextFloat() * 16.0) - 8.0);
  49. *dst++ = std::complex<type> (real, imag);
  50. }
  51. }
  52. // Avoid visual studio warning
  53. template <typename type>
  54. static type safeAbs (type a)
  55. {
  56. return static_cast<type> (std::abs (static_cast<double> (a)));
  57. }
  58. template <typename type>
  59. static type safeAbs (std::complex<type> a)
  60. {
  61. return std::abs (a);
  62. }
  63. template <typename type>
  64. static double difference (type a)
  65. {
  66. return static_cast<double> (safeAbs (a));
  67. }
  68. template <typename type>
  69. static double difference (type a, type b)
  70. {
  71. return difference (a - b);
  72. }
  73. }
  74. // These tests need to be strictly run on all platforms supported by JUCE as the
  75. // SIMD code is highly platform dependant.
  76. class SIMDRegisterUnitTests : public UnitTest
  77. {
  78. public:
  79. SIMDRegisterUnitTests() : UnitTest ("SIMDRegister UnitTests", "DSP") {}
  80. //==============================================================================
  81. // Some helper classes
  82. template <typename type>
  83. static bool allValuesEqualTo (const SIMDRegister<type>& vec, const type scalar)
  84. {
  85. // as we do not want to rely on the access operator we cast this to a primitive pointer
  86. const type* ptr = reinterpret_cast<const type*> (&vec);
  87. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  88. if (ptr[i] != scalar) return false;
  89. return true;
  90. }
  91. template <typename type>
  92. static bool vecEqualToArray (const SIMDRegister<type>& vec, const type* array)
  93. {
  94. HeapBlock<type> vecElementsStorage (SIMDRegister<type>::SIMDNumElements * 2);
  95. auto* ptr = SIMDRegister<type>::getNextSIMDAlignedPtr (vecElementsStorage.getData());
  96. vec.copyToRawArray (ptr);
  97. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  98. {
  99. double delta = SIMDRegister_test_internal::difference (ptr[i], array[i]);
  100. if (delta > 1e-4)
  101. {
  102. DBG ("a: " << SIMDRegister_test_internal::difference (ptr[i]) << " b: " << SIMDRegister_test_internal::difference (array[i]) << " difference: " << delta);
  103. return false;
  104. }
  105. }
  106. return true;
  107. }
  108. template <typename type>
  109. static void copy (SIMDRegister<type>& vec, const type* ptr)
  110. {
  111. if (SIMDRegister<type>::isSIMDAligned (ptr))
  112. {
  113. vec = SIMDRegister<type>::fromRawArray (ptr);
  114. }
  115. else
  116. {
  117. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  118. vec[i] = ptr[i];
  119. }
  120. }
  121. //==============================================================================
  122. // Someuseful operations to test
  123. struct Addition
  124. {
  125. template <typename typeOne, typename typeTwo>
  126. static void inplace (typeOne& a, const typeTwo& b)
  127. {
  128. a += b;
  129. }
  130. template <typename typeOne, typename typeTwo>
  131. static typeOne outofplace (const typeOne& a, const typeTwo& b)
  132. {
  133. return a + b;
  134. }
  135. };
  136. struct Subtraction
  137. {
  138. template <typename typeOne, typename typeTwo>
  139. static void inplace (typeOne& a, const typeTwo& b)
  140. {
  141. a -= b;
  142. }
  143. template <typename typeOne, typename typeTwo>
  144. static typeOne outofplace (const typeOne& a, const typeTwo& b)
  145. {
  146. return a - b;
  147. }
  148. };
  149. struct Multiplication
  150. {
  151. template <typename typeOne, typename typeTwo>
  152. static void inplace (typeOne& a, const typeTwo& b)
  153. {
  154. a *= b;
  155. }
  156. template <typename typeOne, typename typeTwo>
  157. static typeOne outofplace (const typeOne& a, const typeTwo& b)
  158. {
  159. return a * b;
  160. }
  161. };
  162. struct BitAND
  163. {
  164. template <typename typeOne, typename typeTwo>
  165. static void inplace (typeOne& a, const typeTwo& b)
  166. {
  167. a &= b;
  168. }
  169. template <typename typeOne, typename typeTwo>
  170. static typeOne outofplace (const typeOne& a, const typeTwo& b)
  171. {
  172. return a & b;
  173. }
  174. };
  175. struct BitOR
  176. {
  177. template <typename typeOne, typename typeTwo>
  178. static void inplace (typeOne& a, const typeTwo& b)
  179. {
  180. a |= b;
  181. }
  182. template <typename typeOne, typename typeTwo>
  183. static typeOne outofplace (const typeOne& a, const typeTwo& b)
  184. {
  185. return a | b;
  186. }
  187. };
  188. struct BitXOR
  189. {
  190. template <typename typeOne, typename typeTwo>
  191. static void inplace (typeOne& a, const typeTwo& b)
  192. {
  193. a ^= b;
  194. }
  195. template <typename typeOne, typename typeTwo>
  196. static typeOne outofplace (const typeOne& a, const typeTwo& b)
  197. {
  198. return a ^ b;
  199. }
  200. };
  201. //==============================================================================
  202. // the individual tests
  203. struct InitializationTest
  204. {
  205. template <typename type>
  206. static void run (UnitTest& u, Random& random)
  207. {
  208. u.expect (allValuesEqualTo<type> (SIMDRegister<type>::expand (static_cast<type> (23)), 23));
  209. {
  210. SIMDRegister<type> a;
  211. type* ptr = reinterpret_cast<type*>(&a);
  212. SIMDRegister_test_internal::fillRandom (ptr, SIMDRegister<type>::SIMDNumElements, random);
  213. u.expect (vecEqualToArray (SIMDRegister<type> (a), ptr));
  214. }
  215. }
  216. };
  217. struct AccessTest
  218. {
  219. template <typename type>
  220. static void run (UnitTest& u, Random& random)
  221. {
  222. // set-up
  223. SIMDRegister<type> a;
  224. type array [SIMDRegister<type>::SIMDNumElements];
  225. SIMDRegister_test_internal::fillRandom (array, SIMDRegister<type>::SIMDNumElements, random);
  226. // Test non-const access operator
  227. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  228. a[i] = array[i];
  229. u.expect (vecEqualToArray (a, array));
  230. // Test const access operator
  231. const SIMDRegister<type>& b = a;
  232. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  233. u.expect (b[i] == array[i]);
  234. }
  235. };
  236. template <class Operation>
  237. struct OperatorTests
  238. {
  239. template <typename type>
  240. static void run (UnitTest& u, Random& random)
  241. {
  242. for (int n = 0; n < 100; ++n)
  243. {
  244. // set-up
  245. SIMDRegister<type> a, b, c;
  246. type array_a [SIMDRegister<type>::SIMDNumElements];
  247. type array_b [SIMDRegister<type>::SIMDNumElements];
  248. type array_c [SIMDRegister<type>::SIMDNumElements];
  249. SIMDRegister_test_internal::fillRandom (array_a, SIMDRegister<type>::SIMDNumElements, random);
  250. SIMDRegister_test_internal::fillRandom (array_b, SIMDRegister<type>::SIMDNumElements, random);
  251. SIMDRegister_test_internal::fillRandom (array_c, SIMDRegister<type>::SIMDNumElements, random);
  252. copy (a, array_a); copy (b, array_b); copy (c, array_c);
  253. // test in-place with both params being vectors
  254. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  255. Operation::template inplace<type, type> (array_a[i], array_b[i]);
  256. Operation::template inplace<SIMDRegister<type>, SIMDRegister<type>> (a, b);
  257. u.expect (vecEqualToArray (a, array_a));
  258. u.expect (vecEqualToArray (b, array_b));
  259. SIMDRegister_test_internal::fillRandom (array_a, SIMDRegister<type>::SIMDNumElements, random);
  260. SIMDRegister_test_internal::fillRandom (array_b, SIMDRegister<type>::SIMDNumElements, random);
  261. SIMDRegister_test_internal::fillRandom (array_c, SIMDRegister<type>::SIMDNumElements, random);
  262. copy (a, array_a); copy (b, array_b); copy (c, array_c);
  263. // test in-place with one param being scalar
  264. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  265. Operation::template inplace<type, type> (array_b[i], static_cast<type> (2));
  266. Operation::template inplace<SIMDRegister<type>, type> (b, 2);
  267. u.expect (vecEqualToArray (a, array_a));
  268. u.expect (vecEqualToArray (b, array_b));
  269. // set-up again
  270. SIMDRegister_test_internal::fillRandom (array_a, SIMDRegister<type>::SIMDNumElements, random);
  271. SIMDRegister_test_internal::fillRandom (array_b, SIMDRegister<type>::SIMDNumElements, random);
  272. SIMDRegister_test_internal::fillRandom (array_c, SIMDRegister<type>::SIMDNumElements, random);
  273. copy (a, array_a); copy (b, array_b); copy (c, array_c);
  274. // test out-of-place with both params being vectors
  275. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  276. array_c[i] = Operation::template outofplace<type, type> (array_a[i], array_b[i]);
  277. c = Operation::template outofplace<SIMDRegister<type>, SIMDRegister<type>> (a, b);
  278. u.expect (vecEqualToArray (a, array_a));
  279. u.expect (vecEqualToArray (b, array_b));
  280. u.expect (vecEqualToArray (c, array_c));
  281. // test out-of-place with one param being scalar
  282. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  283. array_c[i] = Operation::template outofplace<type, type> (array_b[i], static_cast<type> (2));
  284. c = Operation::template outofplace<SIMDRegister<type>, type> (b, 2);
  285. u.expect (vecEqualToArray (a, array_a));
  286. u.expect (vecEqualToArray (b, array_b));
  287. u.expect (vecEqualToArray (c, array_c));
  288. }
  289. }
  290. };
  291. template <class Operation>
  292. struct BitOperatorTests
  293. {
  294. template <typename type>
  295. static void run (UnitTest& u, Random& random)
  296. {
  297. typedef typename SIMDRegister<type>::vMaskType vMaskType;
  298. typedef typename SIMDRegister<type>::MaskType MaskType;
  299. for (int n = 0; n < 100; ++n)
  300. {
  301. // Check flip sign bit and using as a union
  302. {
  303. type array_a [SIMDRegister<type>::SIMDNumElements];
  304. union
  305. {
  306. SIMDRegister<type> floatVersion;
  307. vMaskType intVersion;
  308. } a, b;
  309. vMaskType bitmask = vMaskType::expand (static_cast<MaskType> (1) << (sizeof (MaskType) - 1));
  310. SIMDRegister_test_internal::fillRandom (array_a, SIMDRegister<type>::SIMDNumElements, random);
  311. copy (a.floatVersion, array_a);
  312. copy (b.floatVersion, array_a);
  313. Operation::template inplace<SIMDRegister<type>, vMaskType> (a.floatVersion, bitmask);
  314. Operation::template inplace<vMaskType, vMaskType> (b.intVersion, bitmask);
  315. u.expect (vecEqualToArray (a.floatVersion, reinterpret_cast<const type*> (&b.floatVersion)));
  316. }
  317. // set-up
  318. SIMDRegister<type> a, c;
  319. vMaskType b;
  320. MaskType array_a [SIMDRegister<MaskType>::SIMDNumElements];
  321. MaskType array_b [SIMDRegister<MaskType>::SIMDNumElements];
  322. MaskType array_c [SIMDRegister<MaskType>::SIMDNumElements];
  323. type* conv_a = reinterpret_cast<type*> (array_a);
  324. type* conv_c = reinterpret_cast<type*> (array_c);
  325. SIMDRegister_test_internal::fillRandom (conv_a, SIMDRegister<type>::SIMDNumElements, random);
  326. SIMDRegister_test_internal::fillRandom (array_b, SIMDRegister<MaskType>::SIMDNumElements, random);
  327. SIMDRegister_test_internal::fillRandom (conv_c, SIMDRegister<type>::SIMDNumElements, random);
  328. copy (a, conv_a); copy (b, array_b); copy (c, conv_c);
  329. // test in-place with both params being vectors
  330. for (size_t i = 0; i < SIMDRegister<MaskType>::SIMDNumElements; ++i)
  331. Operation::template inplace<MaskType, MaskType> (array_a[i], array_b[i]);
  332. Operation::template inplace<SIMDRegister<type>, vMaskType> (a, b);
  333. u.expect (vecEqualToArray (a, conv_a));
  334. u.expect (vecEqualToArray (b, array_b));
  335. SIMDRegister_test_internal::fillRandom (conv_a, SIMDRegister<type>::SIMDNumElements, random);
  336. SIMDRegister_test_internal::fillRandom (array_b, SIMDRegister<MaskType>::SIMDNumElements, random);
  337. SIMDRegister_test_internal::fillRandom (conv_c, SIMDRegister<type>::SIMDNumElements, random);
  338. copy (a, conv_a); copy (b, array_b); copy (c, conv_c);
  339. // test in-place with one param being scalar
  340. for (size_t i = 0; i < SIMDRegister<MaskType>::SIMDNumElements; ++i)
  341. Operation::template inplace<MaskType, MaskType> (array_a[i], static_cast<MaskType> (9));
  342. Operation::template inplace<SIMDRegister<type>, MaskType> (a, static_cast<MaskType> (9));
  343. u.expect (vecEqualToArray (a, conv_a));
  344. u.expect (vecEqualToArray (b, array_b));
  345. // set-up again
  346. SIMDRegister_test_internal::fillRandom (conv_a, SIMDRegister<type>::SIMDNumElements, random);
  347. SIMDRegister_test_internal::fillRandom (array_b, SIMDRegister<MaskType>::SIMDNumElements, random);
  348. SIMDRegister_test_internal::fillRandom (conv_c, SIMDRegister<type>::SIMDNumElements, random);
  349. copy (a, conv_a); copy (b, array_b); copy (c, conv_c);
  350. // test out-of-place with both params being vectors
  351. for (size_t i = 0; i < SIMDRegister<MaskType>::SIMDNumElements; ++i)
  352. {
  353. array_c[i] =
  354. Operation::template outofplace<MaskType, MaskType> (array_a[i], array_b[i]);
  355. }
  356. c = Operation::template outofplace<SIMDRegister<type>, vMaskType> (a, b);
  357. u.expect (vecEqualToArray (a, conv_a));
  358. u.expect (vecEqualToArray (b, array_b));
  359. u.expect (vecEqualToArray (c, conv_c));
  360. // test out-of-place with one param being scalar
  361. for (size_t i = 0; i < SIMDRegister<MaskType>::SIMDNumElements; ++i)
  362. array_c[i] = Operation::template outofplace<MaskType, MaskType> (array_a[i], static_cast<MaskType> (9));
  363. c = Operation::template outofplace<SIMDRegister<type>, MaskType> (a, static_cast<MaskType> (9));
  364. u.expect (vecEqualToArray (a, conv_a));
  365. u.expect (vecEqualToArray (b, array_b));
  366. u.expect (vecEqualToArray (c, conv_c));
  367. }
  368. }
  369. };
  370. struct CheckComparisonOps
  371. {
  372. template <typename type>
  373. static void run (UnitTest& u, Random& random)
  374. {
  375. typedef typename SIMDRegister<type>::vMaskType vMaskType;
  376. typedef typename SIMDRegister<type>::MaskType MaskType;
  377. for (int i = 0; i < 100; ++i)
  378. {
  379. // set-up
  380. type array_a [SIMDRegister<type>::SIMDNumElements];
  381. type array_b [SIMDRegister<type>::SIMDNumElements];
  382. MaskType array_eq [SIMDRegister<type>::SIMDNumElements];
  383. MaskType array_neq [SIMDRegister<type>::SIMDNumElements];
  384. MaskType array_lt [SIMDRegister<type>::SIMDNumElements];
  385. MaskType array_le [SIMDRegister<type>::SIMDNumElements];
  386. MaskType array_gt [SIMDRegister<type>::SIMDNumElements];
  387. MaskType array_ge [SIMDRegister<type>::SIMDNumElements];
  388. SIMDRegister_test_internal::fillRandom (array_a, SIMDRegister<type>::SIMDNumElements, random);
  389. SIMDRegister_test_internal::fillRandom (array_b, SIMDRegister<type>::SIMDNumElements, random);
  390. // do check
  391. for (size_t j = 0; j < SIMDRegister<type>::SIMDNumElements; ++j)
  392. {
  393. array_eq [j] = (array_a[j] == array_b[j]) ? static_cast<MaskType> (-1) : 0;
  394. array_neq [j] = (array_a[j] != array_b[j]) ? static_cast<MaskType> (-1) : 0;
  395. array_lt [j] = (array_a[j] < array_b[j]) ? static_cast<MaskType> (-1) : 0;
  396. array_le [j] = (array_a[j] <= array_b[j]) ? static_cast<MaskType> (-1) : 0;
  397. array_gt [j] = (array_a[j] > array_b[j]) ? static_cast<MaskType> (-1) : 0;
  398. array_ge [j] = (array_a[j] >= array_b[j]) ? static_cast<MaskType> (-1) : 0;
  399. }
  400. SIMDRegister<type> a, b;
  401. vMaskType eq, neq, lt, le, gt, ge;
  402. copy (a, array_a);
  403. copy (b, array_b);
  404. eq = SIMDRegister<type>::equal (a, b);
  405. neq = SIMDRegister<type>::notEqual (a, b);
  406. lt = SIMDRegister<type>::lessThan (a, b);
  407. le = SIMDRegister<type>::lessThanOrEqual (a, b);
  408. gt = SIMDRegister<type>::greaterThan (a, b);
  409. ge = SIMDRegister<type>::greaterThanOrEqual (a, b);
  410. u.expect (vecEqualToArray (eq, array_eq ));
  411. u.expect (vecEqualToArray (neq, array_neq));
  412. u.expect (vecEqualToArray (lt, array_lt ));
  413. u.expect (vecEqualToArray (le, array_le ));
  414. u.expect (vecEqualToArray (gt, array_gt ));
  415. u.expect (vecEqualToArray (ge, array_ge ));
  416. }
  417. }
  418. };
  419. struct CheckMultiplyAdd
  420. {
  421. template <typename type>
  422. static void run (UnitTest& u, Random& random)
  423. {
  424. // set-up
  425. type array_a [SIMDRegister<type>::SIMDNumElements];
  426. type array_b [SIMDRegister<type>::SIMDNumElements];
  427. type array_c [SIMDRegister<type>::SIMDNumElements];
  428. type array_d [SIMDRegister<type>::SIMDNumElements];
  429. SIMDRegister_test_internal::fillRandom (array_a, SIMDRegister<type>::SIMDNumElements, random);
  430. SIMDRegister_test_internal::fillRandom (array_b, SIMDRegister<type>::SIMDNumElements, random);
  431. SIMDRegister_test_internal::fillRandom (array_c, SIMDRegister<type>::SIMDNumElements, random);
  432. SIMDRegister_test_internal::fillRandom (array_d, SIMDRegister<type>::SIMDNumElements, random);
  433. // check
  434. for (size_t i = 0; i < SIMDRegister<type>::SIMDNumElements; ++i)
  435. array_d[i] = array_a[i] + (array_b[i] * array_c[i]);
  436. SIMDRegister<type> a, b, c, d;
  437. copy (a, array_a);
  438. copy (b, array_b);
  439. copy (c, array_c);
  440. d = SIMDRegister<type>::multiplyAdd (a, b, c);
  441. u.expect (vecEqualToArray (d, array_d));
  442. }
  443. };
  444. struct CheckMinMax
  445. {
  446. template <typename type>
  447. static void run (UnitTest& u, Random& random)
  448. {
  449. for (int i = 0; i < 100; ++i)
  450. {
  451. type array_a [SIMDRegister<type>::SIMDNumElements];
  452. type array_b [SIMDRegister<type>::SIMDNumElements];
  453. type array_min [SIMDRegister<type>::SIMDNumElements];
  454. type array_max [SIMDRegister<type>::SIMDNumElements];
  455. for (size_t j = 0; j < SIMDRegister<type>::SIMDNumElements; ++j)
  456. {
  457. array_a[j] = static_cast<type> (random.nextInt (127));
  458. array_b[j] = static_cast<type> (random.nextInt (127));
  459. }
  460. for (size_t j = 0; j < SIMDRegister<type>::SIMDNumElements; ++j)
  461. {
  462. array_min[j] = (array_a[j] < array_b[j]) ? array_a[j] : array_b[j];
  463. array_max[j] = (array_a[j] > array_b[j]) ? array_a[j] : array_b[j];
  464. }
  465. SIMDRegister<type> a, b, vMin, vMax;
  466. copy (a, array_a);
  467. copy (b, array_b);
  468. vMin = jmin (a, b);
  469. vMax = jmax (a, b);
  470. u.expect (vecEqualToArray (vMin, array_min));
  471. u.expect (vecEqualToArray (vMax, array_max));
  472. copy (vMin, array_a);
  473. copy (vMax, array_a);
  474. vMin = SIMDRegister<type>::min (a, b);
  475. vMax = SIMDRegister<type>::max (a, b);
  476. u.expect (vecEqualToArray (vMin, array_min));
  477. u.expect (vecEqualToArray (vMax, array_max));
  478. }
  479. }
  480. };
  481. struct CheckSum
  482. {
  483. template <typename type>
  484. static void run (UnitTest& u, Random& random)
  485. {
  486. type array [SIMDRegister<type>::SIMDNumElements];
  487. type sumCheck = 0;
  488. SIMDRegister_test_internal::fillRandom (array, SIMDRegister<type>::SIMDNumElements, random);
  489. for (size_t j = 0; j < SIMDRegister<type>::SIMDNumElements; ++j)
  490. {
  491. sumCheck += array[j];
  492. }
  493. SIMDRegister<type> a;
  494. copy (a, array);
  495. u.expect (SIMDRegister_test_internal::difference (sumCheck, a.sum()) < 1e-4);
  496. }
  497. };
  498. //==============================================================================
  499. template <class TheTest>
  500. void runTestForAllTypes (const char* unitTestName)
  501. {
  502. beginTest (unitTestName);
  503. Random random = getRandom();
  504. TheTest::template run<float> (*this, random);
  505. TheTest::template run<double> (*this, random);
  506. TheTest::template run<int8_t> (*this, random);
  507. TheTest::template run<uint8_t> (*this, random);
  508. TheTest::template run<int16_t> (*this, random);
  509. TheTest::template run<uint16_t>(*this, random);
  510. TheTest::template run<int32_t> (*this, random);
  511. TheTest::template run<uint32_t>(*this, random);
  512. TheTest::template run<int64_t> (*this, random);
  513. TheTest::template run<uint64_t>(*this, random);
  514. TheTest::template run<std::complex<float>> (*this, random);
  515. TheTest::template run<std::complex<double>> (*this, random);
  516. }
  517. template <class TheTest>
  518. void runTestNonComplex (const char* unitTestName)
  519. {
  520. beginTest (unitTestName);
  521. Random random = getRandom();
  522. TheTest::template run<float> (*this, random);
  523. TheTest::template run<double> (*this, random);
  524. TheTest::template run<int8_t> (*this, random);
  525. TheTest::template run<uint8_t> (*this, random);
  526. TheTest::template run<int16_t> (*this, random);
  527. TheTest::template run<uint16_t>(*this, random);
  528. TheTest::template run<int32_t> (*this, random);
  529. TheTest::template run<uint32_t>(*this, random);
  530. TheTest::template run<int64_t> (*this, random);
  531. TheTest::template run<uint64_t>(*this, random);
  532. }
  533. void runTest()
  534. {
  535. runTestForAllTypes<InitializationTest> ("InitializationTest");
  536. runTestForAllTypes<AccessTest> ("AccessTest");
  537. runTestForAllTypes<OperatorTests<Addition>> ("AdditionOperators");
  538. runTestForAllTypes<OperatorTests<Subtraction>> ("SubtractionOperators");
  539. runTestForAllTypes<OperatorTests<Multiplication>> ("MultiplicationOperators");
  540. runTestForAllTypes<BitOperatorTests<BitAND>> ("BitANDOperators");
  541. runTestForAllTypes<BitOperatorTests<BitOR>> ("BitOROperators");
  542. runTestForAllTypes<BitOperatorTests<BitXOR>> ("BitXOROperators");
  543. runTestNonComplex<CheckComparisonOps> ("CheckComparisons");
  544. runTestNonComplex<CheckMinMax> ("CheckMinMax");
  545. runTestForAllTypes<CheckMultiplyAdd> ("CheckMultiplyAdd");
  546. runTestForAllTypes<CheckSum> ("CheckSum");
  547. }
  548. };
  549. static SIMDRegisterUnitTests SIMDRegisterUnitTests;
  550. } // namespace dsp
  551. } // namespace juce