72 template <
class SampleFormatType>
static float getAsFloat (SampleFormatType& s)
noexcept {
return s.getAsFloatBE(); }
73 template <
class SampleFormatType>
static void setAsFloat (SampleFormatType& s,
float newValue)
noexcept { s.setAsFloatBE (newValue); }
74 template <
class SampleFormatType>
static int32 getAsInt32 (SampleFormatType& s)
noexcept {
return s.getAsInt32BE(); }
75 template <
class SampleFormatType>
static void setAsInt32 (SampleFormatType& s, int32 newValue)
noexcept { s.setAsInt32BE (newValue); }
76 template <
class SourceType,
class DestType>
static void copyFrom (DestType& dest, SourceType& source)
noexcept { dest.copyFromBE (source); }
77 enum { isBigEndian = 1 };
83 template <
class SampleFormatType>
static float getAsFloat (SampleFormatType& s)
noexcept {
return s.getAsFloatLE(); }
84 template <
class SampleFormatType>
static void setAsFloat (SampleFormatType& s,
float newValue)
noexcept { s.setAsFloatLE (newValue); }
85 template <
class SampleFormatType>
static int32 getAsInt32 (SampleFormatType& s)
noexcept {
return s.getAsInt32LE(); }
86 template <
class SampleFormatType>
static void setAsInt32 (SampleFormatType& s, int32 newValue)
noexcept { s.setAsInt32LE (newValue); }
87 template <
class SourceType,
class DestType>
static void copyFrom (DestType& dest, SourceType& source)
noexcept { dest.copyFromLE (source); }
88 enum { isBigEndian = 0 };
92 class NativeEndian :
public BigEndian {};
94 class NativeEndian :
public LittleEndian {};
101 inline Int8 (
void* d) noexcept : data (
static_cast<int8*
> (d)) {}
103 inline void advance() noexcept { ++data; }
104 inline void skip (
int numSamples)
noexcept { data += numSamples; }
105 inline float getAsFloatLE() const noexcept {
return (
float) (*data * (1.0 / (1.0 + (double) maxValue))); }
106 inline float getAsFloatBE() const noexcept {
return getAsFloatLE(); }
107 inline void setAsFloatLE (
float newValue)
noexcept { *data = (int8) jlimit ((
int) -maxValue, (
int) maxValue, roundToInt (newValue * (1.0 + (
double) maxValue))); }
108 inline void setAsFloatBE (
float newValue)
noexcept { setAsFloatLE (newValue); }
109 inline int32 getAsInt32LE() const noexcept {
return (
int) (*((uint8*) data) << 24); }
110 inline int32 getAsInt32BE() const noexcept {
return getAsInt32LE(); }
111 inline void setAsInt32LE (
int newValue)
noexcept { *data = (int8) (newValue >> 24); }
112 inline void setAsInt32BE (
int newValue)
noexcept { setAsInt32LE (newValue); }
113 inline void clear() noexcept { *data = 0; }
114 inline void clearMultiple (
int num)
noexcept { zeromem (data, (
size_t) (num * bytesPerSample)) ;}
115 template <
class SourceType>
inline void copyFromLE (SourceType& source)
noexcept { setAsInt32LE (source.getAsInt32()); }
116 template <
class SourceType>
inline void copyFromBE (SourceType& source)
noexcept { setAsInt32BE (source.getAsInt32()); }
117 inline void copyFromSameType (Int8& source)
noexcept { *data = *source.data; }
120 enum { bytesPerSample = 1, maxValue = 0x7f, resolution = (1 << 24), isFloat = 0 };
126 inline UInt8 (
void* d) noexcept : data (
static_cast<uint8*
> (d)) {}
128 inline void advance() noexcept { ++data; }
129 inline void skip (
int numSamples)
noexcept { data += numSamples; }
130 inline float getAsFloatLE() const noexcept {
return (
float) ((*data - 128) * (1.0 / (1.0 + (double) maxValue))); }
131 inline float getAsFloatBE() const noexcept {
return getAsFloatLE(); }
132 inline void setAsFloatLE (
float newValue)
noexcept { *data = (uint8) jlimit (0, 255, 128 + roundToInt (newValue * (1.0 + (
double) maxValue))); }
133 inline void setAsFloatBE (
float newValue)
noexcept { setAsFloatLE (newValue); }
134 inline int32 getAsInt32LE() const noexcept {
return (
int) (((uint8) (*data - 128)) << 24); }
135 inline int32 getAsInt32BE() const noexcept {
return getAsInt32LE(); }
136 inline void setAsInt32LE (
int newValue)
noexcept { *data = (uint8) (128 + (newValue >> 24)); }
137 inline void setAsInt32BE (
int newValue)
noexcept { setAsInt32LE (newValue); }
138 inline void clear() noexcept { *data = 128; }
139 inline void clearMultiple (
int num)
noexcept { memset (data, 128, (
size_t) num) ;}
140 template <
class SourceType>
inline void copyFromLE (SourceType& source)
noexcept { setAsInt32LE (source.getAsInt32()); }
141 template <
class SourceType>
inline void copyFromBE (SourceType& source)
noexcept { setAsInt32BE (source.getAsInt32()); }
142 inline void copyFromSameType (UInt8& source)
noexcept { *data = *source.data; }
145 enum { bytesPerSample = 1, maxValue = 0x7f, resolution = (1 << 24), isFloat = 0 };
151 inline Int16 (
void* d) noexcept : data (
static_cast<uint16*
> (d)) {}
153 inline void advance() noexcept { ++data; }
154 inline void skip (
int numSamples)
noexcept { data += numSamples; }
155 inline float getAsFloatLE() const noexcept {
return (
float) ((1.0 / (1.0 + (double) maxValue)) * (int16) ByteOrder::swapIfBigEndian (*data)); }
156 inline float getAsFloatBE() const noexcept {
return (
float) ((1.0 / (1.0 + (double) maxValue)) * (int16) ByteOrder::swapIfLittleEndian (*data)); }
157 inline void setAsFloatLE (
float newValue)
noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) jlimit ((
int) -maxValue, (
int) maxValue, roundToInt (newValue * (1.0 + (
double) maxValue)))); }
158 inline void setAsFloatBE (
float newValue)
noexcept { *data = ByteOrder::swapIfLittleEndian ((uint16) jlimit ((
int) -maxValue, (
int) maxValue, roundToInt (newValue * (1.0 + (
double) maxValue)))); }
159 inline int32 getAsInt32LE() const noexcept {
return (int32) (ByteOrder::swapIfBigEndian ((uint16) *data) << 16); }
160 inline int32 getAsInt32BE() const noexcept {
return (int32) (ByteOrder::swapIfLittleEndian ((uint16) *data) << 16); }
161 inline void setAsInt32LE (int32 newValue)
noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) (newValue >> 16)); }
162 inline void setAsInt32BE (int32 newValue)
noexcept { *data = ByteOrder::swapIfLittleEndian ((uint16) (newValue >> 16)); }
163 inline void clear() noexcept { *data = 0; }
164 inline void clearMultiple (
int num)
noexcept { zeromem (data, (
size_t) (num * bytesPerSample)) ;}
165 template <
class SourceType>
inline void copyFromLE (SourceType& source)
noexcept { setAsInt32LE (source.getAsInt32()); }
166 template <
class SourceType>
inline void copyFromBE (SourceType& source)
noexcept { setAsInt32BE (source.getAsInt32()); }
167 inline void copyFromSameType (Int16& source)
noexcept { *data = *source.data; }
170 enum { bytesPerSample = 2, maxValue = 0x7fff, resolution = (1 << 16), isFloat = 0 };
176 inline Int24 (
void* d) noexcept : data (
static_cast<char*
> (d)) {}
178 inline void advance() noexcept { data += 3; }
179 inline void skip (
int numSamples)
noexcept { data += 3 * numSamples; }
180 inline float getAsFloatLE() const noexcept {
return (
float) (ByteOrder::littleEndian24Bit (data) * (1.0 / (1.0 + (double) maxValue))); }
181 inline float getAsFloatBE() const noexcept {
return (
float) (ByteOrder::bigEndian24Bit (data) * (1.0 / (1.0 + (double) maxValue))); }
182 inline void setAsFloatLE (
float newValue)
noexcept { ByteOrder::littleEndian24BitToChars (jlimit ((
int) -maxValue, (
int) maxValue, roundToInt (newValue * (1.0 + (
double) maxValue))), data); }
183 inline void setAsFloatBE (
float newValue)
noexcept { ByteOrder::bigEndian24BitToChars (jlimit ((
int) -maxValue, (
int) maxValue, roundToInt (newValue * (1.0 + (
double) maxValue))), data); }
184 inline int32 getAsInt32LE() const noexcept {
return (int32) (((
unsigned int) ByteOrder::littleEndian24Bit (data)) << 8); }
185 inline int32 getAsInt32BE() const noexcept {
return (int32) (((
unsigned int) ByteOrder::bigEndian24Bit (data)) << 8); }
186 inline void setAsInt32LE (int32 newValue)
noexcept { ByteOrder::littleEndian24BitToChars (newValue >> 8, data); }
187 inline void setAsInt32BE (int32 newValue)
noexcept { ByteOrder::bigEndian24BitToChars (newValue >> 8, data); }
188 inline void clear() noexcept { data[0] = 0; data[1] = 0; data[2] = 0; }
189 inline void clearMultiple (
int num)
noexcept { zeromem (data, (
size_t) (num * bytesPerSample)) ;}
190 template <
class SourceType>
inline void copyFromLE (SourceType& source)
noexcept { setAsInt32LE (source.getAsInt32()); }
191 template <
class SourceType>
inline void copyFromBE (SourceType& source)
noexcept { setAsInt32BE (source.getAsInt32()); }
192 inline void copyFromSameType (Int24& source)
noexcept { data[0] = source.data[0]; data[1] = source.data[1]; data[2] = source.data[2]; }
195 enum { bytesPerSample = 3, maxValue = 0x7fffff, resolution = (1 << 8), isFloat = 0 };
201 inline Int32 (
void* d) noexcept : data (
static_cast<uint32*
> (d)) {}
203 inline void advance() noexcept { ++data; }
204 inline void skip (
int numSamples)
noexcept { data += numSamples; }
205 inline float getAsFloatLE() const noexcept {
return (
float) ((1.0 / (1.0 + (double) maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); }
206 inline float getAsFloatBE() const noexcept {
return (
float) ((1.0 / (1.0 + (double) maxValue)) * (int32) ByteOrder::swapIfLittleEndian (*data)); }
207 inline void setAsFloatLE (
float newValue)
noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) (int32) ((
double) maxValue * jlimit (-1.0, 1.0, (
double) newValue))); }
208 inline void setAsFloatBE (
float newValue)
noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) (int32) ((
double) maxValue * jlimit (-1.0, 1.0, (
double) newValue))); }
209 inline int32 getAsInt32LE() const noexcept {
return (int32) ByteOrder::swapIfBigEndian (*data); }
210 inline int32 getAsInt32BE() const noexcept {
return (int32) ByteOrder::swapIfLittleEndian (*data); }
211 inline void setAsInt32LE (int32 newValue)
noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) newValue); }
212 inline void setAsInt32BE (int32 newValue)
noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) newValue); }
213 inline void clear() noexcept { *data = 0; }
214 inline void clearMultiple (
int num)
noexcept { zeromem (data, (
size_t) (num * bytesPerSample)) ;}
215 template <
class SourceType>
inline void copyFromLE (SourceType& source)
noexcept { setAsInt32LE (source.getAsInt32()); }
216 template <
class SourceType>
inline void copyFromBE (SourceType& source)
noexcept { setAsInt32BE (source.getAsInt32()); }
217 inline void copyFromSameType (Int32& source)
noexcept { *data = *source.data; }
220 enum { bytesPerSample = 4, maxValue = 0x7fffffff, resolution = 1, isFloat = 0 };
227 inline Int24in32 (
void* d) noexcept : Int32 (d) {}
229 inline float getAsFloatLE()
const noexcept {
return (
float) ((1.0 / (1.0 + (double) maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); }
230 inline float getAsFloatBE()
const noexcept {
return (
float) ((1.0 / (1.0 + (double) maxValue)) * (int32) ByteOrder::swapIfLittleEndian (*data)); }
231 inline void setAsFloatLE (
float newValue)
noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) ((
double) maxValue * jlimit (-1.0, 1.0, (
double) newValue))); }
232 inline void setAsFloatBE (
float newValue)
noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) ((
double) maxValue * jlimit (-1.0, 1.0, (
double) newValue))); }
233 inline int32 getAsInt32LE()
const noexcept {
return (int32) ByteOrder::swapIfBigEndian (*data) << 8; }
234 inline int32 getAsInt32BE()
const noexcept {
return (int32) ByteOrder::swapIfLittleEndian (*data) << 8; }
235 inline void setAsInt32LE (int32 newValue)
noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) newValue >> 8); }
236 inline void setAsInt32BE (int32 newValue)
noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) newValue >> 8); }
237 template <
class SourceType>
inline void copyFromLE (SourceType& source)
noexcept { setAsInt32LE (source.getAsInt32()); }
238 template <
class SourceType>
inline void copyFromBE (SourceType& source)
noexcept { setAsInt32BE (source.getAsInt32()); }
239 inline void copyFromSameType (
Int24in32& source)
noexcept { *data = *source.data; }
241 enum { bytesPerSample = 4, maxValue = 0x7fffff, resolution = (1 << 8), isFloat = 0 };
247 inline Float32 (
void* d) noexcept : data (
static_cast<float*
> (d)) {}
249 inline void advance() noexcept { ++data; }
250 inline void skip (
int numSamples)
noexcept { data += numSamples; }
252 inline float getAsFloatBE() const noexcept {
return *data; }
253 inline void setAsFloatBE (
float newValue)
noexcept { *data = newValue; }
254 inline float getAsFloatLE() const noexcept {
union { uint32 asInt;
float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data);
return n.asFloat; }
255 inline void setAsFloatLE (
float newValue)
noexcept {
union { uint32 asInt;
float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); }
257 inline float getAsFloatLE() const noexcept {
return *data; }
258 inline void setAsFloatLE (
float newValue)
noexcept { *data = newValue; }
259 inline float getAsFloatBE() const noexcept {
union { uint32 asInt;
float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data);
return n.asFloat; }
260 inline void setAsFloatBE (
float newValue)
noexcept {
union { uint32 asInt;
float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); }
262 inline int32 getAsInt32LE() const noexcept {
return (int32) roundToInt (jlimit (-1.0, 1.0, (
double) getAsFloatLE()) * (
double) maxValue); }
263 inline int32 getAsInt32BE() const noexcept {
return (int32) roundToInt (jlimit (-1.0, 1.0, (
double) getAsFloatBE()) * (
double) maxValue); }
264 inline void setAsInt32LE (int32 newValue)
noexcept { setAsFloatLE ((
float) (newValue * (1.0 / (1.0 + (
double) maxValue)))); }
265 inline void setAsInt32BE (int32 newValue)
noexcept { setAsFloatBE ((
float) (newValue * (1.0 / (1.0 + (
double) maxValue)))); }
266 inline void clear() noexcept { *data = 0; }
267 inline void clearMultiple (
int num)
noexcept { zeromem (data, (
size_t) (num * bytesPerSample)) ;}
268 template <
class SourceType>
inline void copyFromLE (SourceType& source)
noexcept { setAsFloatLE (source.getAsFloat()); }
269 template <
class SourceType>
inline void copyFromBE (SourceType& source)
noexcept { setAsFloatBE (source.getAsFloat()); }
270 inline void copyFromSameType (Float32& source)
noexcept { *data = *source.data; }
273 enum { bytesPerSample = 4, maxValue = 0x7fffffff, resolution = (1 << 8), isFloat = 1 };
280 inline NonInterleaved() =
default;
281 inline NonInterleaved (
const NonInterleaved&) =
default;
282 inline NonInterleaved (
int)
noexcept {}
283 inline void copyFrom (
const NonInterleaved&)
noexcept {}
284 template <
class SampleFormatType>
inline void advanceData (SampleFormatType& s)
noexcept { s.advance(); }
285 template <
class SampleFormatType>
inline void advanceDataBy (SampleFormatType& s,
int numSamples)
noexcept { s.skip (numSamples); }
286 template <
class SampleFormatType>
inline void clear (SampleFormatType& s,
int numSamples)
noexcept { s.clearMultiple (numSamples); }
287 template <
class SampleFormatType>
static int getNumBytesBetweenSamples (
const SampleFormatType&)
noexcept {
return SampleFormatType::bytesPerSample; }
289 enum { isInterleavedType = 0, numInterleavedChannels = 1 };
295 inline Interleaved() noexcept {}
296 inline Interleaved (
const Interleaved& other) =
default;
297 inline Interleaved (
const int numInterleavedChans) noexcept : numInterleavedChannels (numInterleavedChans) {}
298 inline void copyFrom (
const Interleaved& other)
noexcept { numInterleavedChannels = other.numInterleavedChannels; }
299 template <
class SampleFormatType>
inline void advanceData (SampleFormatType& s)
noexcept { s.skip (numInterleavedChannels); }
300 template <
class SampleFormatType>
inline void advanceDataBy (SampleFormatType& s,
int numSamples)
noexcept { s.skip (numInterleavedChannels * numSamples); }
301 template <
class SampleFormatType>
inline void clear (SampleFormatType& s,
int numSamples)
noexcept {
while (--numSamples >= 0) { s.clear(); s.skip (numInterleavedChannels); } }
302 template <
class SampleFormatType>
inline int getNumBytesBetweenSamples (
const SampleFormatType&)
const noexcept {
return numInterleavedChannels * SampleFormatType::bytesPerSample; }
303 int numInterleavedChannels = 1;
304 enum { isInterleavedType = 1 };
311 using VoidType = void;
312 static void* toVoidPtr (VoidType* v)
noexcept {
return v; }
313 enum { isConst = 0 };
319 using VoidType =
const void;
320 static void* toVoidPtr (VoidType* v)
noexcept {
return const_cast<void*
> (v); }
321 enum { isConst = 1 };
350 template <
typename SampleFormat,
352 typename InterleavingType,
362 Pointer (
typename Constness::VoidType* sourceData) noexcept
363 : data (Constness::toVoidPtr (sourceData))
367 static_assert (InterleavingType::isInterleavedType == 0,
"Incorrect constructor for interleaved data");
373 Pointer (
typename Constness::VoidType* sourceData,
int numInterleaved) noexcept
374 : InterleavingType (numInterleaved), data (Constness::toVoidPtr (sourceData))
380 : InterleavingType (other), data (other.data)
386 InterleavingType::operator= (other);
396 inline float getAsFloat() const noexcept {
return Endianness::getAsFloat (data); }
408 static_assert (Constness::isConst == 0,
"Attempt to write to a const pointer");
409 Endianness::setAsFloat (data, newValue);
418 inline int32
getAsInt32() const noexcept {
return Endianness::getAsInt32 (data); }
426 static_assert (Constness::isConst == 0,
"Attempt to write to a const pointer");
427 Endianness::setAsInt32 (data, newValue);
437 Pointer& operator+= (
int samplesToJump)
noexcept { this->advanceDataBy (data, samplesToJump);
return *
this; }
440 Pointer operator+ (
int samplesToJump)
const {
return Pointer { *
this } += samplesToJump; }
448 static_assert (Constness::isConst == 0,
"Attempt to write to a const pointer");
450 for (
Pointer dest (*
this); --numSamples >= 0;)
452 dest.data.copyFromSameType (source.data);
461 template <
class OtherPo
interType>
465 static_assert (Constness::isConst == 0,
"Attempt to write to a const pointer");
469 if (source.getRawData() != getRawData() || source.getNumBytesBetweenSamples() >= getNumBytesBetweenSamples())
471 while (--numSamples >= 0)
473 Endianness::copyFrom (dest.data, source);
481 source += numSamples;
483 while (--numSamples >= 0)
484 Endianness::copyFrom ((--dest).data, --source);
492 dest.clear (dest.data, numSamples);
503 if (isFloatingPoint())
509 while (--numSamples > 0)
525 while (--numSamples > 0)
534 return Range<float> ((
float) mn * (
float) (1.0 / (1.0 + (
double) Int32::maxValue)),
535 (
float) mx * (
float) (1.0 / (1.0 + (
double) Int32::maxValue)));
539 void findMinAndMax (
size_t numSamples,
float& minValue,
float& maxValue)
const noexcept
550 static bool isBigEndian() noexcept {
return (
bool) Endianness::isBigEndian; }
569 const void*
getRawData() const noexcept {
return data.data; }
575 inline void advance() noexcept { this->advanceData (data); }
577 Pointer operator++ (
int);
578 Pointer operator-- (
int);
596 virtual void convertSamples (
void* destSamples,
const void* sourceSamples,
int numSamples)
const = 0;
603 const void* sourceSamples,
int sourceSubChannel,
int numSamples)
const = 0;
615 template <
class SourceSampleType,
class DestSampleType>
620 : sourceChannels (numSourceChannels), destChannels (numDestChannels)
623 void convertSamples (
void* dest,
const void* source,
int numSamples)
const override
625 SourceSampleType s (source, sourceChannels);
626 DestSampleType d (dest, destChannels);
627 d.convertSamples (s, numSamples);
631 const void* source,
int sourceSubChannel,
int numSamples)
const override
633 jassert (destSubChannel < destChannels && sourceSubChannel < sourceChannels);
635 SourceSampleType s (addBytesToPointer (source, sourceSubChannel * SourceSampleType::getBytesPerSample()), sourceChannels);
636 DestSampleType d (addBytesToPointer (dest, destSubChannel * DestSampleType::getBytesPerSample()), destChannels);
637 d.convertSamples (s, numSamples);
643 const int sourceChannels, destChannels;
652 template <
typename DataFormatIn,
typename EndiannessIn>
655 using DataFormat = DataFormatIn;
656 using Endianness = EndiannessIn;
660 template <
bool IsInterleaved,
bool IsConst,
typename...>
661 struct ChannelDataSubtypes;
663 template <
bool IsInterleaved,
bool IsConst,
typename DataFormat,
typename Endianness>
664 struct ChannelDataSubtypes<IsInterleaved, IsConst, DataFormat, Endianness>
666 using ElementType = std::remove_pointer_t<
decltype (DataFormat::data)>;
667 using ChannelType = std::conditional_t<IsConst, const ElementType*, ElementType*>;
668 using DataType = std::conditional_t<IsInterleaved, ChannelType, ChannelType const*>;
669 using PointerType =
Pointer<DataFormat,
671 std::conditional_t<IsInterleaved, Interleaved, NonInterleaved>,
672 std::conditional_t<IsConst, Const, NonConst>>;
675 template <
bool IsInterleaved,
bool IsConst,
typename DataFormat,
typename Endianness>
676 struct ChannelDataSubtypes<IsInterleaved, IsConst, Format<DataFormat, Endianness>>
678 using Subtypes = ChannelDataSubtypes<IsInterleaved, IsConst, DataFormat, Endianness>;
679 using DataType =
typename Subtypes::DataType;
680 using PointerType =
typename Subtypes::PointerType;
683 template <
bool IsInterleaved,
bool IsConst,
typename... Format>
686 using Subtypes = ChannelDataSubtypes<IsInterleaved, IsConst, Format...>;
687 using DataType =
typename Subtypes::DataType;
688 using PointerType =
typename Subtypes::PointerType;
722 template <
typename... SourceFormat,
typename... DestFormat>
727 using SourceType =
typename decltype (source)::PointerType;
728 using DestType =
typename decltype (dest) ::PointerType;
730 for (
int i = 0; i < dest.channels; ++i)
732 const DestType destType (addBytesToPointer (dest.data, i * DestType::getBytesPerSample()), dest.channels);
734 if (i < source.channels)
736 if (*source.data !=
nullptr)
738 destType.convertSamples (SourceType { *source.data }, numSamples);
744 destType.clearSamples (numSamples);
766 template <
typename... SourceFormat,
typename... DestFormat>
771 using SourceType =
typename decltype (source)::PointerType;
772 using DestType =
typename decltype (dest) ::PointerType;
774 for (
int i = 0; i < dest.channels; ++i)
776 if (
auto* targetChan = dest.data[i])
778 const DestType destType (targetChan);
780 if (i < source.channels)
781 destType.convertSamples (SourceType (addBytesToPointer (source.data, i * SourceType::getBytesPerSample()), source.channels), numSamples);
783 destType.clearSamples (numSamples);