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.

608 lines
21KB

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