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.

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