26JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE (
"-Wdeprecated-declarations")
27JUCE_BEGIN_IGNORE_WARNINGS_MSVC (4996)
29void AudioDataConverters::convertFloatToInt16LE (const
float* source,
void* dest,
int numSamples,
int destBytesPerSample)
31 auto maxVal = (
double) 0x7fff;
32 auto intData =
static_cast<char*
> (dest);
34 if (dest != (
void*) source || destBytesPerSample <= 4)
36 for (
int i = 0; i < numSamples; ++i)
46 for (
int i = numSamples; --i >= 0;)
54void AudioDataConverters::convertFloatToInt16BE (
const float* source,
void* dest,
int numSamples,
int destBytesPerSample)
57 auto intData =
static_cast<char*
> (dest);
61 for (
int i = 0; i < numSamples; ++i)
71 for (
int i = numSamples; --i >= 0;)
79void AudioDataConverters::convertFloatToInt24LE (
const float* source,
void* dest,
int numSamples,
int destBytesPerSample)
82 auto intData =
static_cast<char*
> (dest);
86 for (
int i = 0; i < numSamples; ++i)
96 for (
int i = numSamples; --i >= 0;)
104void AudioDataConverters::convertFloatToInt24BE (
const float* source,
void* dest,
int numSamples,
int destBytesPerSample)
107 auto intData =
static_cast<char*
> (dest);
111 for (
int i = 0; i < numSamples; ++i)
121 for (
int i = numSamples; --i >= 0;)
129void AudioDataConverters::convertFloatToInt32LE (
const float* source,
void* dest,
int numSamples,
int destBytesPerSample)
132 auto intData =
static_cast<char*
> (dest);
136 for (
int i = 0; i < numSamples; ++i)
146 for (
int i = numSamples; --i >= 0;)
154void AudioDataConverters::convertFloatToInt32BE (
const float* source,
void* dest,
int numSamples,
int destBytesPerSample)
157 auto intData =
static_cast<char*
> (dest);
161 for (
int i = 0; i < numSamples; ++i)
171 for (
int i = numSamples; --i >= 0;)
179void AudioDataConverters::convertFloatToFloat32LE (
const float* source,
void* dest,
int numSamples,
int destBytesPerSample)
183 char* d =
static_cast<char*
> (dest);
185 for (
int i = 0; i < numSamples; ++i)
197void AudioDataConverters::convertFloatToFloat32BE (
const float* source,
void* dest,
int numSamples,
int destBytesPerSample)
201 auto d =
static_cast<char*
> (dest);
203 for (
int i = 0; i < numSamples; ++i)
207 #if JUCE_LITTLE_ENDIAN
216void AudioDataConverters::convertInt16LEToFloat (
const void* source,
float* dest,
int numSamples,
int srcBytesPerSample)
218 const float scale = 1.0f / 0x7fff;
219 auto intData =
static_cast<const char*
> (source);
223 for (
int i = 0; i < numSamples; ++i)
233 for (
int i = numSamples; --i >= 0;)
241void AudioDataConverters::convertInt16BEToFloat (
const void* source,
float* dest,
int numSamples,
int srcBytesPerSample)
243 const float scale = 1.0f / 0x7fff;
244 auto intData =
static_cast<const char*
> (source);
248 for (
int i = 0; i < numSamples; ++i)
258 for (
int i = numSamples; --i >= 0;)
266void AudioDataConverters::convertInt24LEToFloat (
const void* source,
float* dest,
int numSamples,
int srcBytesPerSample)
268 const float scale = 1.0f / 0x7fffff;
269 auto intData =
static_cast<const char*
> (source);
273 for (
int i = 0; i < numSamples; ++i)
283 for (
int i = numSamples; --i >= 0;)
291void AudioDataConverters::convertInt24BEToFloat (
const void* source,
float* dest,
int numSamples,
int srcBytesPerSample)
293 const float scale = 1.0f / 0x7fffff;
294 auto intData =
static_cast<const char*
> (source);
298 for (
int i = 0; i < numSamples; ++i)
308 for (
int i = numSamples; --i >= 0;)
316void AudioDataConverters::convertInt32LEToFloat (
const void* source,
float* dest,
int numSamples,
int srcBytesPerSample)
318 const float scale = 1.0f / (
float) 0x7fffffff;
319 auto intData =
static_cast<const char*
> (source);
323 for (
int i = 0; i < numSamples; ++i)
333 for (
int i = numSamples; --i >= 0;)
341void AudioDataConverters::convertInt32BEToFloat (
const void* source,
float* dest,
int numSamples,
int srcBytesPerSample)
343 const float scale = 1.0f / (
float) 0x7fffffff;
344 auto intData =
static_cast<const char*
> (source);
348 for (
int i = 0; i < numSamples; ++i)
358 for (
int i = numSamples; --i >= 0;)
366void AudioDataConverters::convertFloat32LEToFloat (
const void* source,
float* dest,
int numSamples,
int srcBytesPerSample)
368 auto s =
static_cast<const char*
> (source);
370 for (
int i = 0; i < numSamples; ++i)
383void AudioDataConverters::convertFloat32BEToFloat (
const void* source,
float* dest,
int numSamples,
int srcBytesPerSample)
385 auto s =
static_cast<const char*
> (source);
387 for (
int i = 0; i < numSamples; ++i)
391 #if JUCE_LITTLE_ENDIAN
402void AudioDataConverters::convertFloatToFormat (DataFormat
destFormat,
const float* source,
void* dest,
int numSamples)
418void AudioDataConverters::convertFormatToFloat (DataFormat
sourceFormat,
const void* source,
float* dest,
int numSamples)
435void AudioDataConverters::interleaveSamples (
const float** source,
float* dest,
int numSamples,
int numChannels)
437 using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
440 AudioData::InterleavedDest<Format> { dest, numChannels },
444void AudioDataConverters::deinterleaveSamples (
const float* source,
float** dest,
int numSamples,
int numChannels)
446 using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
449 AudioData::NonInterleavedDest<Format> { dest, numChannels },
464 template <
class F1,
class E1,
class F2,
class E2>
467 static void test (UnitTest& unitTest, Random& r)
469 test (unitTest,
false, r);
470 test (unitTest,
true, r);
473 JUCE_BEGIN_IGNORE_WARNINGS_MSVC (6262)
474 static
void test (UnitTest& unitTest,
bool inPlace, Random& r)
476 const int numSamples = 2048;
477 int32 original [(
size_t) numSamples],
478 converted[(
size_t) numSamples],
479 reversed [(
size_t) numSamples];
482 AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> d (original);
483 bool clippingFailed =
false;
485 for (
int i = 0; i < numSamples / 2; ++i)
487 d.setAsFloat (r.nextFloat() * 2.2f - 1.1f);
489 if (! d.isFloatingPoint())
490 clippingFailed = d.getAsFloat() > 1.0f || d.getAsFloat() < -1.0f || clippingFailed;
493 d.setAsInt32 (r.nextInt());
497 unitTest.expect (! clippingFailed);
502 AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::NonConst>>());
503 conv->convertSamples (inPlace ? reversed : converted, original, numSamples);
506 conv.reset (
new AudioData::ConverterInstance<AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>,
507 AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst>>());
509 zeromem (reversed,
sizeof (reversed));
511 conv->convertSamples (reversed, inPlace ? reversed : converted, numSamples);
515 AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d1 (original);
516 AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d2 (reversed);
518 const int errorMargin = 2 * AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const>::get32BitResolution()
519 + AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>::get32BitResolution();
521 for (
int i = 0; i < numSamples; ++i)
523 biggestDiff =
jmax (biggestDiff, std::abs (d1.getAsInt32() - d2.getAsInt32()));
528 unitTest.expect (biggestDiff <= errorMargin);
531 JUCE_END_IGNORE_WARNINGS_MSVC
534 template <
class F1,
class E1,
class FormatType>
537 static void test (UnitTest& unitTest, Random& r)
539 Test5 <F1, E1, FormatType, AudioData::BigEndian>::test (unitTest, r);
540 Test5 <F1, E1, FormatType, AudioData::LittleEndian>::test (unitTest, r);
544 template <
class FormatType,
class Endianness>
547 static void test (UnitTest& unitTest, Random& r)
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);
558 template <
class FormatType>
561 static void test (UnitTest& unitTest, Random& r)
563 Test2 <FormatType, AudioData::BigEndian>::test (unitTest, r);
564 Test2 <FormatType, AudioData::LittleEndian>::test (unitTest, r);
568 void runTest()
override
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);
582 using Format = AudioData::Format<AudioData::Float32, AudioData::NativeEndian>;
584 beginTest (
"Interleaving");
586 constexpr auto numChannels = 4;
587 constexpr auto numSamples = 512;
589 AudioBuffer<float>
sourceBuffer { numChannels, numSamples },
592 for (
int ch = 0;
ch < numChannels; ++
ch)
593 for (
int i = 0; i < numSamples; ++i)
597 AudioData::InterleavedDest<Format> {
destBuffer.getWritePointer (0), numChannels },
600 for (
int ch = 0;
ch < numChannels; ++
ch)
601 for (
int i = 0; i < numSamples; ++i)
605 beginTest (
"Deinterleaving");
607 constexpr auto numChannels = 4;
608 constexpr auto numSamples = 512;
610 AudioBuffer<float>
sourceBuffer { 1, numChannels * numSamples },
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());
618 AudioData::NonInterleavedDest<Format> {
destBuffer.getArrayOfWritePointers(), numChannels },
621 for (
int ch = 0;
ch < numChannels; ++
ch)
622 for (
int i = 0; i < numSamples; ++i)
632JUCE_END_IGNORE_WARNINGS_MSVC
633JUCE_END_IGNORE_WARNINGS_GCC_LIKE
static void interleaveSamples(NonInterleavedSource< SourceFormat... > source, InterleavedDest< DestFormat... > dest, int numSamples)
A helper function for converting a sequence of samples from a non-interleaved source to an interleave...
static void deinterleaveSamples(InterleavedSource< SourceFormat... > source, NonInterleavedDest< DestFormat... > dest, int numSamples)
A helper function for converting a sequence of samples from an interleaved source to a non-interleave...
static Type swapIfLittleEndian(Type value) noexcept
Swaps the byte order of a signed or unsigned integer if the CPU is little-endian.
static void littleEndian24BitToChars(int32 value, void *destBytes) noexcept
Copies a 24-bit number to 3 little-endian bytes.
static constexpr uint16 swap(uint16 value) noexcept
Swaps the upper and lower bytes of a 16-bit integer.
static void bigEndian24BitToChars(int32 value, void *destBytes) noexcept
Copies a 24-bit number to 3 big-endian bytes.
static constexpr int littleEndian24Bit(const void *bytes) noexcept
Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits).
static Type swapIfBigEndian(Type value) noexcept
Swaps the byte order of a signed or unsigned integer if the CPU is big-endian.
static constexpr int bigEndian24Bit(const void *bytes) noexcept
Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits).
unsigned short uint16
A platform-independent 16-bit unsigned integer type.
constexpr Type jmax(Type a, Type b)
Returns the larger of two values.
Type jlimit(Type lowerLimit, Type upperLimit, Type valueToConstrain) noexcept
Constrains a value to keep it within a given range.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
unsigned int uint32
A platform-independent 32-bit unsigned integer type.
int roundToInt(const FloatType value) noexcept
Fast floating-point-to-integer conversion.
void zeromem(void *memory, size_t numBytes) noexcept
Fills a block of memory with zeros.