Audio plugin host https://kx.studio/carla
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.

601 lines
21KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2013 - Raw Material Software Ltd.
  5. Permission is granted to use this software under the terms of either:
  6. a) the GPL v2 (or any later version)
  7. b) the Affero GPL v3
  8. Details of these licenses can be found at: www.gnu.org/licenses
  9. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  12. ------------------------------------------------------------------------------
  13. To release a closed-source product which uses JUCE, commercial licenses are
  14. available: visit www.juce.com for more information.
  15. ==============================================================================
  16. */
  17. void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
  18. {
  19. const double maxVal = (double) 0x7fff;
  20. char* intData = static_cast<char*> (dest);
  21. if (dest != (void*) source || destBytesPerSample <= 4)
  22. {
  23. for (int i = 0; i < numSamples; ++i)
  24. {
  25. *(uint16*) intData = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
  26. intData += destBytesPerSample;
  27. }
  28. }
  29. else
  30. {
  31. intData += destBytesPerSample * numSamples;
  32. for (int i = numSamples; --i >= 0;)
  33. {
  34. intData -= destBytesPerSample;
  35. *(uint16*) intData = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
  36. }
  37. }
  38. }
  39. void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
  40. {
  41. const double maxVal = (double) 0x7fff;
  42. char* intData = static_cast<char*> (dest);
  43. if (dest != (void*) source || destBytesPerSample <= 4)
  44. {
  45. for (int i = 0; i < numSamples; ++i)
  46. {
  47. *(uint16*) intData = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
  48. intData += destBytesPerSample;
  49. }
  50. }
  51. else
  52. {
  53. intData += destBytesPerSample * numSamples;
  54. for (int i = numSamples; --i >= 0;)
  55. {
  56. intData -= destBytesPerSample;
  57. *(uint16*) intData = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
  58. }
  59. }
  60. }
  61. void AudioDataConverters::convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
  62. {
  63. const double maxVal = (double) 0x7fffff;
  64. char* intData = static_cast<char*> (dest);
  65. if (dest != (void*) source || destBytesPerSample <= 4)
  66. {
  67. for (int i = 0; i < numSamples; ++i)
  68. {
  69. ByteOrder::littleEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
  70. intData += destBytesPerSample;
  71. }
  72. }
  73. else
  74. {
  75. intData += destBytesPerSample * numSamples;
  76. for (int i = numSamples; --i >= 0;)
  77. {
  78. intData -= destBytesPerSample;
  79. ByteOrder::littleEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
  80. }
  81. }
  82. }
  83. void AudioDataConverters::convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
  84. {
  85. const double maxVal = (double) 0x7fffff;
  86. char* intData = static_cast<char*> (dest);
  87. if (dest != (void*) source || destBytesPerSample <= 4)
  88. {
  89. for (int i = 0; i < numSamples; ++i)
  90. {
  91. ByteOrder::bigEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
  92. intData += destBytesPerSample;
  93. }
  94. }
  95. else
  96. {
  97. intData += destBytesPerSample * numSamples;
  98. for (int i = numSamples; --i >= 0;)
  99. {
  100. intData -= destBytesPerSample;
  101. ByteOrder::bigEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
  102. }
  103. }
  104. }
  105. void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
  106. {
  107. const double maxVal = (double) 0x7fffffff;
  108. char* intData = static_cast<char*> (dest);
  109. if (dest != (void*) source || destBytesPerSample <= 4)
  110. {
  111. for (int i = 0; i < numSamples; ++i)
  112. {
  113. *(uint32*)intData = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
  114. intData += destBytesPerSample;
  115. }
  116. }
  117. else
  118. {
  119. intData += destBytesPerSample * numSamples;
  120. for (int i = numSamples; --i >= 0;)
  121. {
  122. intData -= destBytesPerSample;
  123. *(uint32*)intData = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
  124. }
  125. }
  126. }
  127. void AudioDataConverters::convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
  128. {
  129. const double maxVal = (double) 0x7fffffff;
  130. char* intData = static_cast<char*> (dest);
  131. if (dest != (void*) source || destBytesPerSample <= 4)
  132. {
  133. for (int i = 0; i < numSamples; ++i)
  134. {
  135. *(uint32*)intData = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
  136. intData += destBytesPerSample;
  137. }
  138. }
  139. else
  140. {
  141. intData += destBytesPerSample * numSamples;
  142. for (int i = numSamples; --i >= 0;)
  143. {
  144. intData -= destBytesPerSample;
  145. *(uint32*)intData = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
  146. }
  147. }
  148. }
  149. void AudioDataConverters::convertFloatToFloat32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
  150. {
  151. jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data!
  152. char* d = static_cast<char*> (dest);
  153. for (int i = 0; i < numSamples; ++i)
  154. {
  155. *(float*) d = source[i];
  156. #if JUCE_BIG_ENDIAN
  157. *(uint32*) d = ByteOrder::swap (*(uint32*) d);
  158. #endif
  159. d += destBytesPerSample;
  160. }
  161. }
  162. void AudioDataConverters::convertFloatToFloat32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
  163. {
  164. jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data!
  165. char* d = static_cast<char*> (dest);
  166. for (int i = 0; i < numSamples; ++i)
  167. {
  168. *(float*) d = source[i];
  169. #if JUCE_LITTLE_ENDIAN
  170. *(uint32*) d = ByteOrder::swap (*(uint32*) d);
  171. #endif
  172. d += destBytesPerSample;
  173. }
  174. }
  175. //==============================================================================
  176. void AudioDataConverters::convertInt16LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
  177. {
  178. const float scale = 1.0f / 0x7fff;
  179. const char* intData = static_cast<const char*> (source);
  180. if (source != (void*) dest || srcBytesPerSample >= 4)
  181. {
  182. for (int i = 0; i < numSamples; ++i)
  183. {
  184. dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*(uint16*)intData);
  185. intData += srcBytesPerSample;
  186. }
  187. }
  188. else
  189. {
  190. intData += srcBytesPerSample * numSamples;
  191. for (int i = numSamples; --i >= 0;)
  192. {
  193. intData -= srcBytesPerSample;
  194. dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*(uint16*)intData);
  195. }
  196. }
  197. }
  198. void AudioDataConverters::convertInt16BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
  199. {
  200. const float scale = 1.0f / 0x7fff;
  201. const char* intData = static_cast<const char*> (source);
  202. if (source != (void*) dest || srcBytesPerSample >= 4)
  203. {
  204. for (int i = 0; i < numSamples; ++i)
  205. {
  206. dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*(uint16*)intData);
  207. intData += srcBytesPerSample;
  208. }
  209. }
  210. else
  211. {
  212. intData += srcBytesPerSample * numSamples;
  213. for (int i = numSamples; --i >= 0;)
  214. {
  215. intData -= srcBytesPerSample;
  216. dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*(uint16*)intData);
  217. }
  218. }
  219. }
  220. void AudioDataConverters::convertInt24LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
  221. {
  222. const float scale = 1.0f / 0x7fffff;
  223. const char* intData = static_cast<const char*> (source);
  224. if (source != (void*) dest || srcBytesPerSample >= 4)
  225. {
  226. for (int i = 0; i < numSamples; ++i)
  227. {
  228. dest[i] = scale * (short) ByteOrder::littleEndian24Bit (intData);
  229. intData += srcBytesPerSample;
  230. }
  231. }
  232. else
  233. {
  234. intData += srcBytesPerSample * numSamples;
  235. for (int i = numSamples; --i >= 0;)
  236. {
  237. intData -= srcBytesPerSample;
  238. dest[i] = scale * (short) ByteOrder::littleEndian24Bit (intData);
  239. }
  240. }
  241. }
  242. void AudioDataConverters::convertInt24BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
  243. {
  244. const float scale = 1.0f / 0x7fffff;
  245. const char* intData = static_cast<const char*> (source);
  246. if (source != (void*) dest || srcBytesPerSample >= 4)
  247. {
  248. for (int i = 0; i < numSamples; ++i)
  249. {
  250. dest[i] = scale * (short) ByteOrder::bigEndian24Bit (intData);
  251. intData += srcBytesPerSample;
  252. }
  253. }
  254. else
  255. {
  256. intData += srcBytesPerSample * numSamples;
  257. for (int i = numSamples; --i >= 0;)
  258. {
  259. intData -= srcBytesPerSample;
  260. dest[i] = scale * (short) ByteOrder::bigEndian24Bit (intData);
  261. }
  262. }
  263. }
  264. void AudioDataConverters::convertInt32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
  265. {
  266. const float scale = 1.0f / 0x7fffffff;
  267. const char* intData = static_cast<const char*> (source);
  268. if (source != (void*) dest || srcBytesPerSample >= 4)
  269. {
  270. for (int i = 0; i < numSamples; ++i)
  271. {
  272. dest[i] = scale * (int) ByteOrder::swapIfBigEndian (*(uint32*) intData);
  273. intData += srcBytesPerSample;
  274. }
  275. }
  276. else
  277. {
  278. intData += srcBytesPerSample * numSamples;
  279. for (int i = numSamples; --i >= 0;)
  280. {
  281. intData -= srcBytesPerSample;
  282. dest[i] = scale * (int) ByteOrder::swapIfBigEndian (*(uint32*) intData);
  283. }
  284. }
  285. }
  286. void AudioDataConverters::convertInt32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
  287. {
  288. const float scale = 1.0f / 0x7fffffff;
  289. const char* intData = static_cast<const char*> (source);
  290. if (source != (void*) dest || srcBytesPerSample >= 4)
  291. {
  292. for (int i = 0; i < numSamples; ++i)
  293. {
  294. dest[i] = scale * (int) ByteOrder::swapIfLittleEndian (*(uint32*) intData);
  295. intData += srcBytesPerSample;
  296. }
  297. }
  298. else
  299. {
  300. intData += srcBytesPerSample * numSamples;
  301. for (int i = numSamples; --i >= 0;)
  302. {
  303. intData -= srcBytesPerSample;
  304. dest[i] = scale * (int) ByteOrder::swapIfLittleEndian (*(uint32*) intData);
  305. }
  306. }
  307. }
  308. void AudioDataConverters::convertFloat32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
  309. {
  310. const char* s = static_cast<const char*> (source);
  311. for (int i = 0; i < numSamples; ++i)
  312. {
  313. dest[i] = *(float*)s;
  314. #if JUCE_BIG_ENDIAN
  315. uint32* const d = (uint32*) (dest + i);
  316. *d = ByteOrder::swap (*d);
  317. #endif
  318. s += srcBytesPerSample;
  319. }
  320. }
  321. void AudioDataConverters::convertFloat32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
  322. {
  323. const char* s = static_cast<const char*> (source);
  324. for (int i = 0; i < numSamples; ++i)
  325. {
  326. dest[i] = *(float*)s;
  327. #if JUCE_LITTLE_ENDIAN
  328. uint32* const d = (uint32*) (dest + i);
  329. *d = ByteOrder::swap (*d);
  330. #endif
  331. s += srcBytesPerSample;
  332. }
  333. }
  334. //==============================================================================
  335. void AudioDataConverters::convertFloatToFormat (const DataFormat destFormat,
  336. const float* const source,
  337. void* const dest,
  338. const int numSamples)
  339. {
  340. switch (destFormat)
  341. {
  342. case int16LE: convertFloatToInt16LE (source, dest, numSamples); break;
  343. case int16BE: convertFloatToInt16BE (source, dest, numSamples); break;
  344. case int24LE: convertFloatToInt24LE (source, dest, numSamples); break;
  345. case int24BE: convertFloatToInt24BE (source, dest, numSamples); break;
  346. case int32LE: convertFloatToInt32LE (source, dest, numSamples); break;
  347. case int32BE: convertFloatToInt32BE (source, dest, numSamples); break;
  348. case float32LE: convertFloatToFloat32LE (source, dest, numSamples); break;
  349. case float32BE: convertFloatToFloat32BE (source, dest, numSamples); break;
  350. default: jassertfalse; break;
  351. }
  352. }
  353. void AudioDataConverters::convertFormatToFloat (const DataFormat sourceFormat,
  354. const void* const source,
  355. float* const dest,
  356. const int numSamples)
  357. {
  358. switch (sourceFormat)
  359. {
  360. case int16LE: convertInt16LEToFloat (source, dest, numSamples); break;
  361. case int16BE: convertInt16BEToFloat (source, dest, numSamples); break;
  362. case int24LE: convertInt24LEToFloat (source, dest, numSamples); break;
  363. case int24BE: convertInt24BEToFloat (source, dest, numSamples); break;
  364. case int32LE: convertInt32LEToFloat (source, dest, numSamples); break;
  365. case int32BE: convertInt32BEToFloat (source, dest, numSamples); break;
  366. case float32LE: convertFloat32LEToFloat (source, dest, numSamples); break;
  367. case float32BE: convertFloat32BEToFloat (source, dest, numSamples); break;
  368. default: jassertfalse; break;
  369. }
  370. }
  371. //==============================================================================
  372. void AudioDataConverters::interleaveSamples (const float** const source,
  373. float* const dest,
  374. const int numSamples,
  375. const int numChannels)
  376. {
  377. for (int chan = 0; chan < numChannels; ++chan)
  378. {
  379. int i = chan;
  380. const float* src = source [chan];
  381. for (int j = 0; j < numSamples; ++j)
  382. {
  383. dest [i] = src [j];
  384. i += numChannels;
  385. }
  386. }
  387. }
  388. void AudioDataConverters::deinterleaveSamples (const float* const source,
  389. float** const dest,
  390. const int numSamples,
  391. const int numChannels)
  392. {
  393. for (int chan = 0; chan < numChannels; ++chan)
  394. {
  395. int i = chan;
  396. float* dst = dest [chan];
  397. for (int j = 0; j < numSamples; ++j)
  398. {
  399. dst [j] = source [i];
  400. i += numChannels;
  401. }
  402. }
  403. }
  404. //==============================================================================
  405. #if JUCE_UNIT_TESTS
  406. class AudioConversionTests : public UnitTest
  407. {
  408. public:
  409. AudioConversionTests() : UnitTest ("Audio data conversion") {}
  410. template <class F1, class E1, class F2, class E2>
  411. struct Test5
  412. {
  413. static void test (UnitTest& unitTest, Random& r)
  414. {
  415. test (unitTest, false, r);
  416. test (unitTest, true, r);
  417. }
  418. static void test (UnitTest& unitTest, bool inPlace, Random& r)
  419. {
  420. const int numSamples = 2048;
  421. int32 original [numSamples], converted [numSamples], reversed [numSamples];
  422. {
  423. AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> d (original);
  424. bool clippingFailed = false;
  425. for (int i = 0; i < numSamples / 2; ++i)
  426. {
  427. d.setAsFloat (r.nextFloat() * 2.2f - 1.1f);
  428. if (! d.isFloatingPoint())
  429. clippingFailed = d.getAsFloat() > 1.0f || d.getAsFloat() < -1.0f || clippingFailed;
  430. ++d;
  431. d.setAsInt32 (r.nextInt());
  432. ++d;
  433. }
  434. unitTest.expect (! clippingFailed);
  435. }
  436. // convert data from the source to dest format..
  437. ScopedPointer<AudioData::Converter> conv (new AudioData::ConverterInstance <AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const>,
  438. AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::NonConst> >());
  439. conv->convertSamples (inPlace ? reversed : converted, original, numSamples);
  440. // ..and back again..
  441. conv = new AudioData::ConverterInstance <AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>,
  442. AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> >();
  443. if (! inPlace)
  444. zeromem (reversed, sizeof (reversed));
  445. conv->convertSamples (reversed, inPlace ? reversed : converted, numSamples);
  446. {
  447. int biggestDiff = 0;
  448. AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d1 (original);
  449. AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d2 (reversed);
  450. const int errorMargin = 2 * AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const>::get32BitResolution()
  451. + AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>::get32BitResolution();
  452. for (int i = 0; i < numSamples; ++i)
  453. {
  454. biggestDiff = jmax (biggestDiff, std::abs (d1.getAsInt32() - d2.getAsInt32()));
  455. ++d1;
  456. ++d2;
  457. }
  458. unitTest.expect (biggestDiff <= errorMargin);
  459. }
  460. }
  461. };
  462. template <class F1, class E1, class FormatType>
  463. struct Test3
  464. {
  465. static void test (UnitTest& unitTest, Random& r)
  466. {
  467. Test5 <F1, E1, FormatType, AudioData::BigEndian>::test (unitTest, r);
  468. Test5 <F1, E1, FormatType, AudioData::LittleEndian>::test (unitTest, r);
  469. }
  470. };
  471. template <class FormatType, class Endianness>
  472. struct Test2
  473. {
  474. static void test (UnitTest& unitTest, Random& r)
  475. {
  476. Test3 <FormatType, Endianness, AudioData::Int8>::test (unitTest, r);
  477. Test3 <FormatType, Endianness, AudioData::UInt8>::test (unitTest, r);
  478. Test3 <FormatType, Endianness, AudioData::Int16>::test (unitTest, r);
  479. Test3 <FormatType, Endianness, AudioData::Int24>::test (unitTest, r);
  480. Test3 <FormatType, Endianness, AudioData::Int32>::test (unitTest, r);
  481. Test3 <FormatType, Endianness, AudioData::Float32>::test (unitTest, r);
  482. }
  483. };
  484. template <class FormatType>
  485. struct Test1
  486. {
  487. static void test (UnitTest& unitTest, Random& r)
  488. {
  489. Test2 <FormatType, AudioData::BigEndian>::test (unitTest, r);
  490. Test2 <FormatType, AudioData::LittleEndian>::test (unitTest, r);
  491. }
  492. };
  493. void runTest()
  494. {
  495. Random r = getRandom();
  496. beginTest ("Round-trip conversion: Int8");
  497. Test1 <AudioData::Int8>::test (*this, r);
  498. beginTest ("Round-trip conversion: Int16");
  499. Test1 <AudioData::Int16>::test (*this, r);
  500. beginTest ("Round-trip conversion: Int24");
  501. Test1 <AudioData::Int24>::test (*this, r);
  502. beginTest ("Round-trip conversion: Int32");
  503. Test1 <AudioData::Int32>::test (*this, r);
  504. beginTest ("Round-trip conversion: Float32");
  505. Test1 <AudioData::Float32>::test (*this, r);
  506. }
  507. };
  508. static AudioConversionTests audioConversionUnitTests;
  509. #endif