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.

663 lines
21KB

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