OpenShot Audio Library | OpenShotAudio  0.6.0
juce_AudioDataConverters.cpp
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2022 - Raw Material Software Limited
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE ("-Wdeprecated-declarations")
27 JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
28 
29 void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, int destBytesPerSample)
30 {
31  auto maxVal = (double) 0x7fff;
32  auto intData = static_cast<char*> (dest);
33 
34  if (dest != (void*) source || destBytesPerSample <= 4)
35  {
36  for (int i = 0; i < numSamples; ++i)
37  {
38  *unalignedPointerCast<uint16*> (intData) = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
39  intData += destBytesPerSample;
40  }
41  }
42  else
43  {
44  intData += destBytesPerSample * numSamples;
45 
46  for (int i = numSamples; --i >= 0;)
47  {
48  intData -= destBytesPerSample;
49  *unalignedPointerCast<uint16*> (intData) = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
50  }
51  }
52 }
53 
54 void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest, int numSamples, int destBytesPerSample)
55 {
56  auto maxVal = (double) 0x7fff;
57  auto intData = static_cast<char*> (dest);
58 
59  if (dest != (void*) source || destBytesPerSample <= 4)
60  {
61  for (int i = 0; i < numSamples; ++i)
62  {
63  *unalignedPointerCast<uint16*> (intData) = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
64  intData += destBytesPerSample;
65  }
66  }
67  else
68  {
69  intData += destBytesPerSample * numSamples;
70 
71  for (int i = numSamples; --i >= 0;)
72  {
73  intData -= destBytesPerSample;
74  *unalignedPointerCast<uint16*> (intData) = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
75  }
76  }
77 }
78 
79 void AudioDataConverters::convertFloatToInt24LE (const float* source, void* dest, int numSamples, int destBytesPerSample)
80 {
81  auto maxVal = (double) 0x7fffff;
82  auto intData = static_cast<char*> (dest);
83 
84  if (dest != (void*) source || destBytesPerSample <= 4)
85  {
86  for (int i = 0; i < numSamples; ++i)
87  {
88  ByteOrder::littleEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
89  intData += destBytesPerSample;
90  }
91  }
92  else
93  {
94  intData += destBytesPerSample * numSamples;
95 
96  for (int i = numSamples; --i >= 0;)
97  {
98  intData -= destBytesPerSample;
99  ByteOrder::littleEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
100  }
101  }
102 }
103 
104 void AudioDataConverters::convertFloatToInt24BE (const float* source, void* dest, int numSamples, int destBytesPerSample)
105 {
106  auto maxVal = (double) 0x7fffff;
107  auto intData = static_cast<char*> (dest);
108 
109  if (dest != (void*) source || destBytesPerSample <= 4)
110  {
111  for (int i = 0; i < numSamples; ++i)
112  {
113  ByteOrder::bigEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
114  intData += destBytesPerSample;
115  }
116  }
117  else
118  {
119  intData += destBytesPerSample * numSamples;
120 
121  for (int i = numSamples; --i >= 0;)
122  {
123  intData -= destBytesPerSample;
124  ByteOrder::bigEndian24BitToChars (roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
125  }
126  }
127 }
128 
129 void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest, int numSamples, int destBytesPerSample)
130 {
131  auto maxVal = (double) 0x7fffffff;
132  auto intData = static_cast<char*> (dest);
133 
134  if (dest != (void*) source || destBytesPerSample <= 4)
135  {
136  for (int i = 0; i < numSamples; ++i)
137  {
138  *unalignedPointerCast<uint32*> (intData) = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
139  intData += destBytesPerSample;
140  }
141  }
142  else
143  {
144  intData += destBytesPerSample * numSamples;
145 
146  for (int i = numSamples; --i >= 0;)
147  {
148  intData -= destBytesPerSample;
149  *unalignedPointerCast<uint32*> (intData) = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
150  }
151  }
152 }
153 
154 void AudioDataConverters::convertFloatToInt32BE (const float* source, void* dest, int numSamples, int destBytesPerSample)
155 {
156  auto maxVal = (double) 0x7fffffff;
157  auto intData = static_cast<char*> (dest);
158 
159  if (dest != (void*) source || destBytesPerSample <= 4)
160  {
161  for (int i = 0; i < numSamples; ++i)
162  {
163  *unalignedPointerCast<uint32*> (intData) = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
164  intData += destBytesPerSample;
165  }
166  }
167  else
168  {
169  intData += destBytesPerSample * numSamples;
170 
171  for (int i = numSamples; --i >= 0;)
172  {
173  intData -= destBytesPerSample;
174  *unalignedPointerCast<uint32*> (intData) = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
175  }
176  }
177 }
178 
179 void AudioDataConverters::convertFloatToFloat32LE (const float* source, void* dest, int numSamples, int destBytesPerSample)
180 {
181  jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data!
182 
183  char* d = static_cast<char*> (dest);
184 
185  for (int i = 0; i < numSamples; ++i)
186  {
187  *unalignedPointerCast<float*> (d) = source[i];
188 
189  #if JUCE_BIG_ENDIAN
190  *unalignedPointerCast<uint32*> (d) = ByteOrder::swap (*unalignedPointerCast<uint32*> (d));
191  #endif
192 
193  d += destBytesPerSample;
194  }
195 }
196 
197 void AudioDataConverters::convertFloatToFloat32BE (const float* source, void* dest, int numSamples, int destBytesPerSample)
198 {
199  jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data!
200 
201  auto d = static_cast<char*> (dest);
202 
203  for (int i = 0; i < numSamples; ++i)
204  {
205  *unalignedPointerCast<float*> (d) = source[i];
206 
207  #if JUCE_LITTLE_ENDIAN
208  *unalignedPointerCast<uint32*> (d) = ByteOrder::swap (*unalignedPointerCast<uint32*> (d));
209  #endif
210 
211  d += destBytesPerSample;
212  }
213 }
214 
215 //==============================================================================
216 void AudioDataConverters::convertInt16LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample)
217 {
218  const float scale = 1.0f / 0x7fff;
219  auto intData = static_cast<const char*> (source);
220 
221  if (source != (void*) dest || srcBytesPerSample >= 4)
222  {
223  for (int i = 0; i < numSamples; ++i)
224  {
225  dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*unalignedPointerCast<const uint16*> (intData));
226  intData += srcBytesPerSample;
227  }
228  }
229  else
230  {
231  intData += srcBytesPerSample * numSamples;
232 
233  for (int i = numSamples; --i >= 0;)
234  {
235  intData -= srcBytesPerSample;
236  dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*unalignedPointerCast<const uint16*> (intData));
237  }
238  }
239 }
240 
241 void AudioDataConverters::convertInt16BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample)
242 {
243  const float scale = 1.0f / 0x7fff;
244  auto intData = static_cast<const char*> (source);
245 
246  if (source != (void*) dest || srcBytesPerSample >= 4)
247  {
248  for (int i = 0; i < numSamples; ++i)
249  {
250  dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*unalignedPointerCast<const uint16*> (intData));
251  intData += srcBytesPerSample;
252  }
253  }
254  else
255  {
256  intData += srcBytesPerSample * numSamples;
257 
258  for (int i = numSamples; --i >= 0;)
259  {
260  intData -= srcBytesPerSample;
261  dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*unalignedPointerCast<const uint16*> (intData));
262  }
263  }
264 }
265 
266 void AudioDataConverters::convertInt24LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample)
267 {
268  const float scale = 1.0f / 0x7fffff;
269  auto intData = static_cast<const char*> (source);
270 
271  if (source != (void*) dest || srcBytesPerSample >= 4)
272  {
273  for (int i = 0; i < numSamples; ++i)
274  {
275  dest[i] = scale * (short) ByteOrder::littleEndian24Bit (intData);
276  intData += srcBytesPerSample;
277  }
278  }
279  else
280  {
281  intData += srcBytesPerSample * numSamples;
282 
283  for (int i = numSamples; --i >= 0;)
284  {
285  intData -= srcBytesPerSample;
286  dest[i] = scale * (short) ByteOrder::littleEndian24Bit (intData);
287  }
288  }
289 }
290 
291 void AudioDataConverters::convertInt24BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample)
292 {
293  const float scale = 1.0f / 0x7fffff;
294  auto intData = static_cast<const char*> (source);
295 
296  if (source != (void*) dest || srcBytesPerSample >= 4)
297  {
298  for (int i = 0; i < numSamples; ++i)
299  {
300  dest[i] = scale * (short) ByteOrder::bigEndian24Bit (intData);
301  intData += srcBytesPerSample;
302  }
303  }
304  else
305  {
306  intData += srcBytesPerSample * numSamples;
307 
308  for (int i = numSamples; --i >= 0;)
309  {
310  intData -= srcBytesPerSample;
311  dest[i] = scale * (short) ByteOrder::bigEndian24Bit (intData);
312  }
313  }
314 }
315 
316 void AudioDataConverters::convertInt32LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample)
317 {
318  const float scale = 1.0f / (float) 0x7fffffff;
319  auto intData = static_cast<const char*> (source);
320 
321  if (source != (void*) dest || srcBytesPerSample >= 4)
322  {
323  for (int i = 0; i < numSamples; ++i)
324  {
325  dest[i] = scale * (float) ByteOrder::swapIfBigEndian (*unalignedPointerCast<const uint32*> (intData));
326  intData += srcBytesPerSample;
327  }
328  }
329  else
330  {
331  intData += srcBytesPerSample * numSamples;
332 
333  for (int i = numSamples; --i >= 0;)
334  {
335  intData -= srcBytesPerSample;
336  dest[i] = scale * (float) ByteOrder::swapIfBigEndian (*unalignedPointerCast<const uint32*> (intData));
337  }
338  }
339 }
340 
341 void AudioDataConverters::convertInt32BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample)
342 {
343  const float scale = 1.0f / (float) 0x7fffffff;
344  auto intData = static_cast<const char*> (source);
345 
346  if (source != (void*) dest || srcBytesPerSample >= 4)
347  {
348  for (int i = 0; i < numSamples; ++i)
349  {
350  dest[i] = scale * (float) ByteOrder::swapIfLittleEndian (*unalignedPointerCast<const uint32*> (intData));
351  intData += srcBytesPerSample;
352  }
353  }
354  else
355  {
356  intData += srcBytesPerSample * numSamples;
357 
358  for (int i = numSamples; --i >= 0;)
359  {
360  intData -= srcBytesPerSample;
361  dest[i] = scale * (float) ByteOrder::swapIfLittleEndian (*unalignedPointerCast<const uint32*> (intData));
362  }
363  }
364 }
365 
366 void AudioDataConverters::convertFloat32LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample)
367 {
368  auto s = static_cast<const char*> (source);
369 
370  for (int i = 0; i < numSamples; ++i)
371  {
372  dest[i] = *unalignedPointerCast<const float*> (s);
373 
374  #if JUCE_BIG_ENDIAN
375  auto d = unalignedPointerCast<uint32*> (dest + i);
376  *d = ByteOrder::swap (*d);
377  #endif
378 
379  s += srcBytesPerSample;
380  }
381 }
382 
383 void AudioDataConverters::convertFloat32BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample)
384 {
385  auto s = static_cast<const char*> (source);
386 
387  for (int i = 0; i < numSamples; ++i)
388  {
389  dest[i] = *unalignedPointerCast<const float*> (s);
390 
391  #if JUCE_LITTLE_ENDIAN
392  auto d = unalignedPointerCast<uint32*> (dest + i);
393  *d = ByteOrder::swap (*d);
394  #endif
395 
396  s += srcBytesPerSample;
397  }
398 }
399 
400 
401 //==============================================================================
402 void AudioDataConverters::convertFloatToFormat (DataFormat destFormat, const float* source, void* dest, int numSamples)
403 {
404  switch (destFormat)
405  {
406  case int16LE: convertFloatToInt16LE (source, dest, numSamples); break;
407  case int16BE: convertFloatToInt16BE (source, dest, numSamples); break;
408  case int24LE: convertFloatToInt24LE (source, dest, numSamples); break;
409  case int24BE: convertFloatToInt24BE (source, dest, numSamples); break;
410  case int32LE: convertFloatToInt32LE (source, dest, numSamples); break;
411  case int32BE: convertFloatToInt32BE (source, dest, numSamples); break;
412  case float32LE: convertFloatToFloat32LE (source, dest, numSamples); break;
413  case float32BE: convertFloatToFloat32BE (source, dest, numSamples); break;
414  default: jassertfalse; break;
415  }
416 }
417 
418 void AudioDataConverters::convertFormatToFloat (DataFormat sourceFormat, const void* source, float* dest, int numSamples)
419 {
420  switch (sourceFormat)
421  {
422  case int16LE: convertInt16LEToFloat (source, dest, numSamples); break;
423  case int16BE: convertInt16BEToFloat (source, dest, numSamples); break;
424  case int24LE: convertInt24LEToFloat (source, dest, numSamples); break;
425  case int24BE: convertInt24BEToFloat (source, dest, numSamples); break;
426  case int32LE: convertInt32LEToFloat (source, dest, numSamples); break;
427  case int32BE: convertInt32BEToFloat (source, dest, numSamples); break;
428  case float32LE: convertFloat32LEToFloat (source, dest, numSamples); break;
429  case float32BE: convertFloat32BEToFloat (source, dest, numSamples); break;
430  default: jassertfalse; break;
431  }
432 }
433 
434 //==============================================================================
435 void AudioDataConverters::interleaveSamples (const float** source, float* dest, int numSamples, int numChannels)
436 {
437  using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
438 
439  AudioData::interleaveSamples (AudioData::NonInterleavedSource<Format> { source, numChannels },
440  AudioData::InterleavedDest<Format> { dest, numChannels },
441  numSamples);
442 }
443 
444 void AudioDataConverters::deinterleaveSamples (const float* source, float** dest, int numSamples, int numChannels)
445 {
446  using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
447 
448  AudioData::deinterleaveSamples (AudioData::InterleavedSource<Format> { source, numChannels },
449  AudioData::NonInterleavedDest<Format> { dest, numChannels },
450  numSamples);
451 }
452 
453 //==============================================================================
454 //==============================================================================
455 #if JUCE_UNIT_TESTS
456 
457 class AudioConversionTests final : public UnitTest
458 {
459 public:
460  AudioConversionTests()
461  : UnitTest ("Audio data conversion", UnitTestCategories::audio)
462  {}
463 
464  template <class F1, class E1, class F2, class E2>
465  struct Test5
466  {
467  static void test (UnitTest& unitTest, Random& r)
468  {
469  test (unitTest, false, r);
470  test (unitTest, true, r);
471  }
472 
473  JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6262)
474  static void test (UnitTest& unitTest, bool inPlace, Random& r)
475  {
476  const int numSamples = 2048;
477  int32 original [(size_t) numSamples],
478  converted[(size_t) numSamples],
479  reversed [(size_t) numSamples];
480 
481  {
482  AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> d (original);
483  bool clippingFailed = false;
484 
485  for (int i = 0; i < numSamples / 2; ++i)
486  {
487  d.setAsFloat (r.nextFloat() * 2.2f - 1.1f);
488 
489  if (! d.isFloatingPoint())
490  clippingFailed = d.getAsFloat() > 1.0f || d.getAsFloat() < -1.0f || clippingFailed;
491 
492  ++d;
493  d.setAsInt32 (r.nextInt());
494  ++d;
495  }
496 
497  unitTest.expect (! clippingFailed);
498  }
499 
500  // convert data from the source to dest format..
501  std::unique_ptr<AudioData::Converter> conv (new AudioData::ConverterInstance<AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const>,
502  AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::NonConst>>());
503  conv->convertSamples (inPlace ? reversed : converted, original, numSamples);
504 
505  // ..and back again..
506  conv.reset (new AudioData::ConverterInstance<AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>,
507  AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst>>());
508  if (! inPlace)
509  zeromem (reversed, sizeof (reversed));
510 
511  conv->convertSamples (reversed, inPlace ? reversed : converted, numSamples);
512 
513  {
514  int biggestDiff = 0;
515  AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d1 (original);
516  AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d2 (reversed);
517 
520 
521  for (int i = 0; i < numSamples; ++i)
522  {
523  biggestDiff = jmax (biggestDiff, std::abs (d1.getAsInt32() - d2.getAsInt32()));
524  ++d1;
525  ++d2;
526  }
527 
528  unitTest.expect (biggestDiff <= errorMargin);
529  }
530  }
531  JUCE_END_IGNORE_WARNINGS_MSVC
532  };
533 
534  template <class F1, class E1, class FormatType>
535  struct Test3
536  {
537  static void test (UnitTest& unitTest, Random& r)
538  {
539  Test5 <F1, E1, FormatType, AudioData::BigEndian>::test (unitTest, r);
540  Test5 <F1, E1, FormatType, AudioData::LittleEndian>::test (unitTest, r);
541  }
542  };
543 
544  template <class FormatType, class Endianness>
545  struct Test2
546  {
547  static void test (UnitTest& unitTest, Random& r)
548  {
549  Test3 <FormatType, Endianness, AudioData::Int8>::test (unitTest, r);
550  Test3 <FormatType, Endianness, AudioData::UInt8>::test (unitTest, r);
551  Test3 <FormatType, Endianness, AudioData::Int16>::test (unitTest, r);
552  Test3 <FormatType, Endianness, AudioData::Int24>::test (unitTest, r);
553  Test3 <FormatType, Endianness, AudioData::Int32>::test (unitTest, r);
554  Test3 <FormatType, Endianness, AudioData::Float32>::test (unitTest, r);
555  }
556  };
557 
558  template <class FormatType>
559  struct Test1
560  {
561  static void test (UnitTest& unitTest, Random& r)
562  {
563  Test2 <FormatType, AudioData::BigEndian>::test (unitTest, r);
564  Test2 <FormatType, AudioData::LittleEndian>::test (unitTest, r);
565  }
566  };
567 
568  void runTest() override
569  {
570  auto r = getRandom();
571  beginTest ("Round-trip conversion: Int8");
572  Test1 <AudioData::Int8>::test (*this, r);
573  beginTest ("Round-trip conversion: Int16");
574  Test1 <AudioData::Int16>::test (*this, r);
575  beginTest ("Round-trip conversion: Int24");
576  Test1 <AudioData::Int24>::test (*this, r);
577  beginTest ("Round-trip conversion: Int32");
578  Test1 <AudioData::Int32>::test (*this, r);
579  beginTest ("Round-trip conversion: Float32");
580  Test1 <AudioData::Float32>::test (*this, r);
581 
582  using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
583 
584  beginTest ("Interleaving");
585  {
586  constexpr auto numChannels = 4;
587  constexpr auto numSamples = 512;
588 
589  AudioBuffer<float> sourceBuffer { numChannels, numSamples },
590  destBuffer { 1, numChannels * numSamples };
591 
592  for (int ch = 0; ch < numChannels; ++ch)
593  for (int i = 0; i < numSamples; ++i)
594  sourceBuffer.setSample (ch, i, r.nextFloat());
595 
596  AudioData::interleaveSamples (AudioData::NonInterleavedSource<Format> { sourceBuffer.getArrayOfReadPointers(), numChannels },
597  AudioData::InterleavedDest<Format> { destBuffer.getWritePointer (0), numChannels },
598  numSamples);
599 
600  for (int ch = 0; ch < numChannels; ++ch)
601  for (int i = 0; i < numSamples; ++i)
602  expectEquals (destBuffer.getSample (0, ch + (i * numChannels)), sourceBuffer.getSample (ch, i));
603  }
604 
605  beginTest ("Deinterleaving");
606  {
607  constexpr auto numChannels = 4;
608  constexpr auto numSamples = 512;
609 
610  AudioBuffer<float> sourceBuffer { 1, numChannels * numSamples },
611  destBuffer { numChannels, numSamples };
612 
613  for (int ch = 0; ch < numChannels; ++ch)
614  for (int i = 0; i < numSamples; ++i)
615  sourceBuffer.setSample (0, ch + (i * numChannels), r.nextFloat());
616 
617  AudioData::deinterleaveSamples (AudioData::InterleavedSource<Format> { sourceBuffer.getReadPointer (0), numChannels },
618  AudioData::NonInterleavedDest<Format> { destBuffer.getArrayOfWritePointers(), numChannels },
619  numSamples);
620 
621  for (int ch = 0; ch < numChannels; ++ch)
622  for (int i = 0; i < numSamples; ++i)
623  expectEquals (sourceBuffer.getSample (0, ch + (i * numChannels)), destBuffer.getSample (ch, i));
624  }
625  }
626 };
627 
628 static AudioConversionTests audioConversionUnitTests;
629 
630 #endif
631 
632 JUCE_END_IGNORE_WARNINGS_MSVC
633 JUCE_END_IGNORE_WARNINGS_GCC_LIKE
634 
635 } // namespace juce
static int get32BitResolution() noexcept
static void interleaveSamples(NonInterleavedSource< SourceFormat... > source, InterleavedDest< DestFormat... > dest, int numSamples)
static void deinterleaveSamples(InterleavedSource< SourceFormat... > source, NonInterleavedDest< DestFormat... > dest, int numSamples)
static Type swapIfLittleEndian(Type value) noexcept
static void littleEndian24BitToChars(int32 value, void *destBytes) noexcept
constexpr static uint16 swap(uint16 value) noexcept
static void bigEndian24BitToChars(int32 value, void *destBytes) noexcept
constexpr static int littleEndian24Bit(const void *bytes) noexcept
static Type swapIfBigEndian(Type value) noexcept
constexpr static int bigEndian24Bit(const void *bytes) noexcept