OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
juce_AudioDataConverters.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
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
23namespace juce
24{
25
26//==============================================================================
35class JUCE_API AudioData
36{
37public:
38 //==============================================================================
39 // These types can be used as the SampleFormat template parameter for the AudioData::Pointer class.
40
41 class Int8;
42 class UInt8;
43 class Int16;
44 class Int24;
45 class Int32;
46 class Float32;
48 //==============================================================================
49 // These types can be used as the Endianness template parameter for the AudioData::Pointer class.
50
51 class BigEndian;
52 class LittleEndian;
53 class NativeEndian;
55 //==============================================================================
56 // These types can be used as the InterleavingType template parameter for the AudioData::Pointer class.
57
58 class NonInterleaved;
59 class Interleaved;
61 //==============================================================================
62 // These types can be used as the Constness template parameter for the AudioData::Pointer class.
63
64 class NonConst;
65 class Const;
67 #ifndef DOXYGEN
68 //==============================================================================
70 {
71 public:
72 template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatBE(); }
73 template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatBE (newValue); }
74 template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32BE(); }
75 template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32BE (newValue); }
76 template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromBE (source); }
77 enum { isBigEndian = 1 };
78 };
79
80 class LittleEndian
81 {
82 public:
83 template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatLE(); }
84 template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatLE (newValue); }
85 template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32LE(); }
86 template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32LE (newValue); }
87 template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromLE (source); }
88 enum { isBigEndian = 0 };
89 };
90
91 #if JUCE_BIG_ENDIAN
92 class NativeEndian : public BigEndian {};
93 #else
94 class NativeEndian : public LittleEndian {};
95 #endif
96
97 //==============================================================================
98 class Int8
99 {
100 public:
101 inline Int8 (void* d) noexcept : data (static_cast<int8*> (d)) {}
102
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; }
118
119 int8* data;
120 enum { bytesPerSample = 1, maxValue = 0x7f, resolution = (1 << 24), isFloat = 0 };
121 };
122
123 class UInt8
124 {
125 public:
126 inline UInt8 (void* d) noexcept : data (static_cast<uint8*> (d)) {}
127
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; }
143
144 uint8* data;
145 enum { bytesPerSample = 1, maxValue = 0x7f, resolution = (1 << 24), isFloat = 0 };
146 };
147
148 class Int16
149 {
150 public:
151 inline Int16 (void* d) noexcept : data (static_cast<uint16*> (d)) {}
152
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; }
168
169 uint16* data;
170 enum { bytesPerSample = 2, maxValue = 0x7fff, resolution = (1 << 16), isFloat = 0 };
171 };
172
173 class Int24
174 {
175 public:
176 inline Int24 (void* d) noexcept : data (static_cast<char*> (d)) {}
177
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]; }
193
194 char* data;
195 enum { bytesPerSample = 3, maxValue = 0x7fffff, resolution = (1 << 8), isFloat = 0 };
196 };
197
198 class Int32
199 {
200 public:
201 inline Int32 (void* d) noexcept : data (static_cast<uint32*> (d)) {}
202
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; }
218
219 uint32* data;
220 enum { bytesPerSample = 4, maxValue = 0x7fffffff, resolution = 1, isFloat = 0 };
221 };
222
224 class Int24in32 : public Int32
225 {
226 public:
227 inline Int24in32 (void* d) noexcept : Int32 (d) {}
228
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; }
240
241 enum { bytesPerSample = 4, maxValue = 0x7fffff, resolution = (1 << 8), isFloat = 0 };
242 };
243
244 class Float32
245 {
246 public:
247 inline Float32 (void* d) noexcept : data (static_cast<float*> (d)) {}
248
249 inline void advance() noexcept { ++data; }
250 inline void skip (int numSamples) noexcept { data += numSamples; }
251 #if JUCE_BIG_ENDIAN
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); }
256 #else
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); }
261 #endif
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; }
271
272 float* data;
273 enum { bytesPerSample = 4, maxValue = 0x7fffffff, resolution = (1 << 8), isFloat = 1 };
274 };
275
276 //==============================================================================
277 class NonInterleaved
278 {
279 public:
280 inline NonInterleaved() = default;
281 inline NonInterleaved (const NonInterleaved&) = default;
282 inline NonInterleaved (const 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> inline static int getNumBytesBetweenSamples (const SampleFormatType&) noexcept { return SampleFormatType::bytesPerSample; }
288
289 enum { isInterleavedType = 0, numInterleavedChannels = 1 };
290 };
291
292 class Interleaved
293 {
294 public:
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 };
305 };
306
307 //==============================================================================
308 class NonConst
309 {
310 public:
311 using VoidType = void;
312 static inline void* toVoidPtr (VoidType* v) noexcept { return v; }
313 enum { isConst = 0 };
314 };
315
316 class Const
317 {
318 public:
319 using VoidType = const void;
320 static inline void* toVoidPtr (VoidType* v) noexcept { return const_cast<void*> (v); }
321 enum { isConst = 1 };
322 };
323 #endif
324
325 //==============================================================================
350 template <typename SampleFormat,
351 typename Endianness,
352 typename InterleavingType,
353 typename Constness>
354 class Pointer : private InterleavingType // (inherited for EBCO)
355 {
356 public:
357 //==============================================================================
362 Pointer (typename Constness::VoidType* sourceData) noexcept
363 : data (Constness::toVoidPtr (sourceData))
364 {
365 // If you're using interleaved data, call the other constructor! If you're using non-interleaved data,
366 // you should pass NonInterleaved as the template parameter for the interleaving type!
367 static_assert (InterleavingType::isInterleavedType == 0, "Incorrect constructor for interleaved data");
368 }
369
373 Pointer (typename Constness::VoidType* sourceData, int numInterleaved) noexcept
374 : InterleavingType (numInterleaved), data (Constness::toVoidPtr (sourceData))
375 {
376 }
377
380 : InterleavingType (other), data (other.data)
381 {
382 }
383
384 Pointer& operator= (const Pointer& other) noexcept
385 {
386 InterleavingType::operator= (other);
387 data = other.data;
388 return *this;
389 }
390
391 //==============================================================================
396 inline float getAsFloat() const noexcept { return Endianness::getAsFloat (data); }
397
405 inline void setAsFloat (float newValue) noexcept
406 {
407 // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead!
408 static_assert (Constness::isConst == 0, "Attempt to write to a const pointer");
409 Endianness::setAsFloat (data, newValue);
410 }
411
418 inline int32 getAsInt32() const noexcept { return Endianness::getAsInt32 (data); }
419
423 inline void setAsInt32 (int32 newValue) noexcept
424 {
425 // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead!
426 static_assert (Constness::isConst == 0, "Attempt to write to a const pointer");
427 Endianness::setAsInt32 (data, newValue);
428 }
429
431 inline Pointer& operator++() noexcept { advance(); return *this; }
432
434 inline Pointer& operator--() noexcept { this->advanceDataBy (data, -1); return *this; }
435
437 Pointer& operator+= (int samplesToJump) noexcept { this->advanceDataBy (data, samplesToJump); return *this; }
438
442 void convertSamples (Pointer source, int numSamples) const noexcept
443 {
444 // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead!
445 static_assert (Constness::isConst == 0, "Attempt to write to a const pointer");
446
447 for (Pointer dest (*this); --numSamples >= 0;)
448 {
449 dest.data.copyFromSameType (source.data);
450 dest.advance();
451 source.advance();
452 }
453 }
454
458 template <class OtherPointerType>
459 void convertSamples (OtherPointerType source, int numSamples) const noexcept
460 {
461 // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead!
462 static_assert (Constness::isConst == 0, "Attempt to write to a const pointer");
463
464 Pointer dest (*this);
465
466 if (source.getRawData() != getRawData() || source.getNumBytesBetweenSamples() >= getNumBytesBetweenSamples())
467 {
468 while (--numSamples >= 0)
469 {
470 Endianness::copyFrom (dest.data, source);
471 dest.advance();
472 ++source;
473 }
474 }
475 else // copy backwards if we're increasing the sample width..
476 {
477 dest += numSamples;
478 source += numSamples;
479
480 while (--numSamples >= 0)
481 Endianness::copyFrom ((--dest).data, --source);
482 }
483 }
484
486 void clearSamples (int numSamples) const noexcept
487 {
488 Pointer dest (*this);
489 dest.clear (dest.data, numSamples);
490 }
491
493 Range<float> findMinAndMax (size_t numSamples) const noexcept
494 {
495 if (numSamples == 0)
496 return Range<float>();
497
498 Pointer dest (*this);
499
500 if (isFloatingPoint())
501 {
502 float mn = dest.getAsFloat();
503 dest.advance();
504 float mx = mn;
505
506 while (--numSamples > 0)
507 {
508 const float v = dest.getAsFloat();
509 dest.advance();
510
511 if (mx < v) mx = v;
512 if (v < mn) mn = v;
513 }
514
515 return Range<float> (mn, mx);
516 }
517
518 int32 mn = dest.getAsInt32();
519 dest.advance();
520 int32 mx = mn;
521
522 while (--numSamples > 0)
523 {
524 const int v = dest.getAsInt32();
525 dest.advance();
526
527 if (mx < v) mx = v;
528 if (v < mn) mn = v;
529 }
530
531 return Range<float> (mn * (float) (1.0 / (1.0 + (double) Int32::maxValue)),
532 mx * (float) (1.0 / (1.0 + (double) Int32::maxValue)));
533 }
534
536 void findMinAndMax (size_t numSamples, float& minValue, float& maxValue) const noexcept
537 {
538 Range<float> r (findMinAndMax (numSamples));
539 minValue = r.getStart();
540 maxValue = r.getEnd();
541 }
542
544 static bool isFloatingPoint() noexcept { return (bool) SampleFormat::isFloat; }
545
547 static bool isBigEndian() noexcept { return (bool) Endianness::isBigEndian; }
548
550 static int getBytesPerSample() noexcept { return (int) SampleFormat::bytesPerSample; }
551
553 int getNumInterleavedChannels() const noexcept { return (int) this->numInterleavedChannels; }
554
556 int getNumBytesBetweenSamples() const noexcept { return InterleavingType::getNumBytesBetweenSamples (data); }
557
563 static int get32BitResolution() noexcept { return (int) SampleFormat::resolution; }
564
566 const void* getRawData() const noexcept { return data.data; }
567
568 private:
569 //==============================================================================
570 SampleFormat data;
571
572 inline void advance() noexcept { this->advanceData (data); }
573
574 Pointer operator++ (int); // private to force you to use the more efficient pre-increment!
575 Pointer operator-- (int);
576 };
577
578 //==============================================================================
588 {
589 public:
590 virtual ~Converter() = default;
591
593 virtual void convertSamples (void* destSamples, const void* sourceSamples, int numSamples) const = 0;
594
599 virtual void convertSamples (void* destSamples, int destSubChannel,
600 const void* sourceSamples, int sourceSubChannel, int numSamples) const = 0;
601 };
602
603 //==============================================================================
612 template <class SourceSampleType, class DestSampleType>
614 {
615 public:
617 : sourceChannels (numSourceChannels), destChannels (numDestChannels)
618 {}
619
620 void convertSamples (void* dest, const void* source, int numSamples) const override
621 {
622 SourceSampleType s (source, sourceChannels);
623 DestSampleType d (dest, destChannels);
624 d.convertSamples (s, numSamples);
625 }
626
627 void convertSamples (void* dest, int destSubChannel,
628 const void* source, int sourceSubChannel, int numSamples) const override
629 {
630 jassert (destSubChannel < destChannels && sourceSubChannel < sourceChannels);
631
632 SourceSampleType s (addBytesToPointer (source, sourceSubChannel * SourceSampleType::getBytesPerSample()), sourceChannels);
633 DestSampleType d (addBytesToPointer (dest, destSubChannel * DestSampleType::getBytesPerSample()), destChannels);
634 d.convertSamples (s, numSamples);
635 }
636
637 private:
638 JUCE_DECLARE_NON_COPYABLE (ConverterInstance)
639
640 const int sourceChannels, destChannels;
641 };
642};
643
644
645
646//==============================================================================
657{
658public:
659 //==============================================================================
660 static void convertFloatToInt16LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 2);
661 static void convertFloatToInt16BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 2);
662
663 static void convertFloatToInt24LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 3);
664 static void convertFloatToInt24BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 3);
665
666 static void convertFloatToInt32LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4);
667 static void convertFloatToInt32BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4);
668
669 static void convertFloatToFloat32LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4);
670 static void convertFloatToFloat32BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4);
671
672 //==============================================================================
673 static void convertInt16LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 2);
674 static void convertInt16BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 2);
675
676 static void convertInt24LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 3);
677 static void convertInt24BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 3);
678
679 static void convertInt32LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4);
680 static void convertInt32BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4);
681
682 static void convertFloat32LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4);
683 static void convertFloat32BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4);
684
685 //==============================================================================
686 enum DataFormat
687 {
688 int16LE,
689 int16BE,
690 int24LE,
691 int24BE,
692 int32LE,
693 int32BE,
694 float32LE,
695 float32BE,
696 };
697
698 static void convertFloatToFormat (DataFormat destFormat,
699 const float* source, void* dest, int numSamples);
700
701 static void convertFormatToFloat (DataFormat sourceFormat,
702 const void* source, float* dest, int numSamples);
703
704 //==============================================================================
705 static void interleaveSamples (const float** source, float* dest,
706 int numSamples, int numChannels);
707
708 static void deinterleaveSamples (const float* source, float** dest,
709 int numSamples, int numChannels);
710
711private:
713 JUCE_DECLARE_NON_COPYABLE (AudioDataConverters)
714};
715
716} // namespace juce
ElementType * data() noexcept
Definition juce_Array.h:360
void convertSamples(void *dest, const void *source, int numSamples) const override
void convertSamples(void *dest, int destSubChannel, const void *source, int sourceSubChannel, int numSamples) const override
virtual void convertSamples(void *destSamples, int destSubChannel, const void *sourceSamples, int sourceSubChannel, int numSamples) const =0
virtual void convertSamples(void *destSamples, const void *sourceSamples, int numSamples) const =0
int getNumBytesBetweenSamples() const noexcept
void setAsInt32(int32 newValue) noexcept
void clearSamples(int numSamples) const noexcept
static int getBytesPerSample() noexcept
const void * getRawData() const noexcept
void convertSamples(OtherPointerType source, int numSamples) const noexcept
int getNumInterleavedChannels() const noexcept
Pointer(const Pointer &other) noexcept
void convertSamples(Pointer source, int numSamples) const noexcept
int32 getAsInt32() const noexcept
void setAsFloat(float newValue) noexcept
Range< float > findMinAndMax(size_t numSamples) const noexcept
Pointer(typename Constness::VoidType *sourceData, int numInterleaved) noexcept
static bool isFloatingPoint() noexcept
float getAsFloat() const noexcept
Pointer(typename Constness::VoidType *sourceData) noexcept
void findMinAndMax(size_t numSamples, float &minValue, float &maxValue) const noexcept
static int get32BitResolution() noexcept
static bool isBigEndian() noexcept