Fix crash when host does not support midi-in; Add missing file
[juce-lv2.git] / juce / source / src / audio / dsp / juce_AudioDataConverters.h
blobbdcacdc4fd30a9e46cc0dd52debfcf41428fe4df
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
27 #define __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
30 //==============================================================================
31 /**
32 This class a container which holds all the classes pertaining to the AudioData::Pointer
33 audio sample format class.
35 @see AudioData::Pointer.
37 class JUCE_API AudioData
39 public:
40 //==============================================================================
41 // These types can be used as the SampleFormat template parameter for the AudioData::Pointer class.
43 class Int8; /**< Used as a template parameter for AudioData::Pointer. Indicates an 8-bit integer packed data format. */
44 class UInt8; /**< Used as a template parameter for AudioData::Pointer. Indicates an 8-bit unsigned integer packed data format. */
45 class Int16; /**< Used as a template parameter for AudioData::Pointer. Indicates an 16-bit integer packed data format. */
46 class Int24; /**< Used as a template parameter for AudioData::Pointer. Indicates an 24-bit integer packed data format. */
47 class Int32; /**< Used as a template parameter for AudioData::Pointer. Indicates an 32-bit integer packed data format. */
48 class Float32; /**< Used as a template parameter for AudioData::Pointer. Indicates an 32-bit float data format. */
50 //==============================================================================
51 // These types can be used as the Endianness template parameter for the AudioData::Pointer class.
53 class BigEndian; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are stored in big-endian order. */
54 class LittleEndian; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are stored in little-endian order. */
55 class NativeEndian; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are stored in the CPU's native endianness. */
57 //==============================================================================
58 // These types can be used as the InterleavingType template parameter for the AudioData::Pointer class.
60 class NonInterleaved; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are stored contiguously. */
61 class Interleaved; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples are interleaved with a number of other channels. */
63 //==============================================================================
64 // These types can be used as the Constness template parameter for the AudioData::Pointer class.
66 class NonConst; /**< Used as a template parameter for AudioData::Pointer. Indicates that the pointer can be used for non-const data. */
67 class Const; /**< Used as a template parameter for AudioData::Pointer. Indicates that the samples can only be used for const data.. */
69 #ifndef DOXYGEN
70 //==============================================================================
71 class BigEndian
73 public:
74 template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatBE(); }
75 template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatBE (newValue); }
76 template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32BE(); }
77 template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32BE (newValue); }
78 template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromBE (source); }
79 enum { isBigEndian = 1 };
82 class LittleEndian
84 public:
85 template <class SampleFormatType> static inline float getAsFloat (SampleFormatType& s) noexcept { return s.getAsFloatLE(); }
86 template <class SampleFormatType> static inline void setAsFloat (SampleFormatType& s, float newValue) noexcept { s.setAsFloatLE (newValue); }
87 template <class SampleFormatType> static inline int32 getAsInt32 (SampleFormatType& s) noexcept { return s.getAsInt32LE(); }
88 template <class SampleFormatType> static inline void setAsInt32 (SampleFormatType& s, int32 newValue) noexcept { s.setAsInt32LE (newValue); }
89 template <class SourceType, class DestType> static inline void copyFrom (DestType& dest, SourceType& source) noexcept { dest.copyFromLE (source); }
90 enum { isBigEndian = 0 };
93 #if JUCE_BIG_ENDIAN
94 class NativeEndian : public BigEndian {};
95 #else
96 class NativeEndian : public LittleEndian {};
97 #endif
99 //==============================================================================
100 class Int8
102 public:
103 inline Int8 (void* data_) noexcept : data (static_cast <int8*> (data_)) {}
105 inline void advance() noexcept { ++data; }
106 inline void skip (int numSamples) noexcept { data += numSamples; }
107 inline float getAsFloatLE() const noexcept { return (float) (*data * (1.0 / (1.0 + maxValue))); }
108 inline float getAsFloatBE() const noexcept { return getAsFloatLE(); }
109 inline void setAsFloatLE (float newValue) noexcept { *data = (int8) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))); }
110 inline void setAsFloatBE (float newValue) noexcept { setAsFloatLE (newValue); }
111 inline int32 getAsInt32LE() const noexcept { return (int) (*data << 24); }
112 inline int32 getAsInt32BE() const noexcept { return getAsInt32LE(); }
113 inline void setAsInt32LE (int newValue) noexcept { *data = (int8) (newValue >> 24); }
114 inline void setAsInt32BE (int newValue) noexcept { setAsInt32LE (newValue); }
115 inline void clear() noexcept { *data = 0; }
116 inline void clearMultiple (int num) noexcept { zeromem (data, num * bytesPerSample) ;}
117 template <class SourceType> inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); }
118 template <class SourceType> inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); }
119 inline void copyFromSameType (Int8& source) noexcept { *data = *source.data; }
121 int8* data;
122 enum { bytesPerSample = 1, maxValue = 0x7f, resolution = (1 << 24), isFloat = 0 };
125 class UInt8
127 public:
128 inline UInt8 (void* data_) noexcept : data (static_cast <uint8*> (data_)) {}
130 inline void advance() noexcept { ++data; }
131 inline void skip (int numSamples) noexcept { data += numSamples; }
132 inline float getAsFloatLE() const noexcept { return (float) ((*data - 128) * (1.0 / (1.0 + maxValue))); }
133 inline float getAsFloatBE() const noexcept { return getAsFloatLE(); }
134 inline void setAsFloatLE (float newValue) noexcept { *data = (uint8) jlimit (0, 255, 128 + roundToInt (newValue * (1.0 + maxValue))); }
135 inline void setAsFloatBE (float newValue) noexcept { setAsFloatLE (newValue); }
136 inline int32 getAsInt32LE() const noexcept { return (int) ((*data - 128) << 24); }
137 inline int32 getAsInt32BE() const noexcept { return getAsInt32LE(); }
138 inline void setAsInt32LE (int newValue) noexcept { *data = (uint8) (128 + (newValue >> 24)); }
139 inline void setAsInt32BE (int newValue) noexcept { setAsInt32LE (newValue); }
140 inline void clear() noexcept { *data = 128; }
141 inline void clearMultiple (int num) noexcept { memset (data, 128, num) ;}
142 template <class SourceType> inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); }
143 template <class SourceType> inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); }
144 inline void copyFromSameType (UInt8& source) noexcept { *data = *source.data; }
146 uint8* data;
147 enum { bytesPerSample = 1, maxValue = 0x7f, resolution = (1 << 24), isFloat = 0 };
150 class Int16
152 public:
153 inline Int16 (void* data_) noexcept : data (static_cast <uint16*> (data_)) {}
155 inline void advance() noexcept { ++data; }
156 inline void skip (int numSamples) noexcept { data += numSamples; }
157 inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int16) ByteOrder::swapIfBigEndian (*data)); }
158 inline float getAsFloatBE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int16) ByteOrder::swapIfLittleEndian (*data)); }
159 inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue)))); }
160 inline void setAsFloatBE (float newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint16) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue)))); }
161 inline int32 getAsInt32LE() const noexcept { return (int32) (ByteOrder::swapIfBigEndian ((uint16) *data) << 16); }
162 inline int32 getAsInt32BE() const noexcept { return (int32) (ByteOrder::swapIfLittleEndian ((uint16) *data) << 16); }
163 inline void setAsInt32LE (int32 newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) (newValue >> 16)); }
164 inline void setAsInt32BE (int32 newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint16) (newValue >> 16)); }
165 inline void clear() noexcept { *data = 0; }
166 inline void clearMultiple (int num) noexcept { zeromem (data, num * bytesPerSample) ;}
167 template <class SourceType> inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); }
168 template <class SourceType> inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); }
169 inline void copyFromSameType (Int16& source) noexcept { *data = *source.data; }
171 uint16* data;
172 enum { bytesPerSample = 2, maxValue = 0x7fff, resolution = (1 << 16), isFloat = 0 };
175 class Int24
177 public:
178 inline Int24 (void* data_) noexcept : data (static_cast <char*> (data_)) {}
180 inline void advance() noexcept { data += 3; }
181 inline void skip (int numSamples) noexcept { data += 3 * numSamples; }
182 inline float getAsFloatLE() const noexcept { return (float) (ByteOrder::littleEndian24Bit (data) * (1.0 / (1.0 + maxValue))); }
183 inline float getAsFloatBE() const noexcept { return (float) (ByteOrder::bigEndian24Bit (data) * (1.0 / (1.0 + maxValue))); }
184 inline void setAsFloatLE (float newValue) noexcept { ByteOrder::littleEndian24BitToChars (jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))), data); }
185 inline void setAsFloatBE (float newValue) noexcept { ByteOrder::bigEndian24BitToChars (jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))), data); }
186 inline int32 getAsInt32LE() const noexcept { return (int32) ByteOrder::littleEndian24Bit (data) << 8; }
187 inline int32 getAsInt32BE() const noexcept { return (int32) ByteOrder::bigEndian24Bit (data) << 8; }
188 inline void setAsInt32LE (int32 newValue) noexcept { ByteOrder::littleEndian24BitToChars (newValue >> 8, data); }
189 inline void setAsInt32BE (int32 newValue) noexcept { ByteOrder::bigEndian24BitToChars (newValue >> 8, data); }
190 inline void clear() noexcept { data[0] = 0; data[1] = 0; data[2] = 0; }
191 inline void clearMultiple (int num) noexcept { zeromem (data, num * bytesPerSample) ;}
192 template <class SourceType> inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); }
193 template <class SourceType> inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); }
194 inline void copyFromSameType (Int24& source) noexcept { data[0] = source.data[0]; data[1] = source.data[1]; data[2] = source.data[2]; }
196 char* data;
197 enum { bytesPerSample = 3, maxValue = 0x7fffff, resolution = (1 << 8), isFloat = 0 };
200 class Int32
202 public:
203 inline Int32 (void* data_) noexcept : data (static_cast <uint32*> (data_)) {}
205 inline void advance() noexcept { ++data; }
206 inline void skip (int numSamples) noexcept { data += numSamples; }
207 inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); }
208 inline float getAsFloatBE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfLittleEndian (*data)); }
209 inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); }
210 inline void setAsFloatBE (float newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); }
211 inline int32 getAsInt32LE() const noexcept { return (int32) ByteOrder::swapIfBigEndian (*data); }
212 inline int32 getAsInt32BE() const noexcept { return (int32) ByteOrder::swapIfLittleEndian (*data); }
213 inline void setAsInt32LE (int32 newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) newValue); }
214 inline void setAsInt32BE (int32 newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) newValue); }
215 inline void clear() noexcept { *data = 0; }
216 inline void clearMultiple (int num) noexcept { zeromem (data, num * bytesPerSample) ;}
217 template <class SourceType> inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); }
218 template <class SourceType> inline void copyFromBE (SourceType& source) noexcept { setAsInt32BE (source.getAsInt32()); }
219 inline void copyFromSameType (Int32& source) noexcept { *data = *source.data; }
221 uint32* data;
222 enum { bytesPerSample = 4, maxValue = 0x7fffffff, resolution = 1, isFloat = 0 };
225 class Float32
227 public:
228 inline Float32 (void* data_) noexcept : data (static_cast <float*> (data_)) {}
230 inline void advance() noexcept { ++data; }
231 inline void skip (int numSamples) noexcept { data += numSamples; }
232 #if JUCE_BIG_ENDIAN
233 inline float getAsFloatBE() const noexcept { return *data; }
234 inline void setAsFloatBE (float newValue) noexcept { *data = newValue; }
235 inline float getAsFloatLE() const noexcept { union { uint32 asInt; float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data); return n.asFloat; }
236 inline void setAsFloatLE (float newValue) noexcept { union { uint32 asInt; float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); }
237 #else
238 inline float getAsFloatLE() const noexcept { return *data; }
239 inline void setAsFloatLE (float newValue) noexcept { *data = newValue; }
240 inline float getAsFloatBE() const noexcept { union { uint32 asInt; float asFloat; } n; n.asInt = ByteOrder::swap (*(uint32*) data); return n.asFloat; }
241 inline void setAsFloatBE (float newValue) noexcept { union { uint32 asInt; float asFloat; } n; n.asFloat = newValue; *(uint32*) data = ByteOrder::swap (n.asInt); }
242 #endif
243 inline int32 getAsInt32LE() const noexcept { return (int32) roundToInt (jlimit (-1.0, 1.0, (double) getAsFloatLE()) * (double) maxValue); }
244 inline int32 getAsInt32BE() const noexcept { return (int32) roundToInt (jlimit (-1.0, 1.0, (double) getAsFloatBE()) * (double) maxValue); }
245 inline void setAsInt32LE (int32 newValue) noexcept { setAsFloatLE ((float) (newValue * (1.0 / (1.0 + maxValue)))); }
246 inline void setAsInt32BE (int32 newValue) noexcept { setAsFloatBE ((float) (newValue * (1.0 / (1.0 + maxValue)))); }
247 inline void clear() noexcept { *data = 0; }
248 inline void clearMultiple (int num) noexcept { zeromem (data, num * bytesPerSample) ;}
249 template <class SourceType> inline void copyFromLE (SourceType& source) noexcept { setAsFloatLE (source.getAsFloat()); }
250 template <class SourceType> inline void copyFromBE (SourceType& source) noexcept { setAsFloatBE (source.getAsFloat()); }
251 inline void copyFromSameType (Float32& source) noexcept { *data = *source.data; }
253 float* data;
254 enum { bytesPerSample = 4, maxValue = 0x7fffffff, resolution = (1 << 8), isFloat = 1 };
257 //==============================================================================
258 class NonInterleaved
260 public:
261 inline NonInterleaved() noexcept {}
262 inline NonInterleaved (const NonInterleaved&) noexcept {}
263 inline NonInterleaved (const int) noexcept {}
264 inline void copyFrom (const NonInterleaved&) noexcept {}
265 template <class SampleFormatType> inline void advanceData (SampleFormatType& s) noexcept { s.advance(); }
266 template <class SampleFormatType> inline void advanceDataBy (SampleFormatType& s, int numSamples) noexcept { s.skip (numSamples); }
267 template <class SampleFormatType> inline void clear (SampleFormatType& s, int numSamples) noexcept { s.clearMultiple (numSamples); }
268 template <class SampleFormatType> inline static int getNumBytesBetweenSamples (const SampleFormatType&) noexcept { return SampleFormatType::bytesPerSample; }
270 enum { isInterleavedType = 0, numInterleavedChannels = 1 };
273 class Interleaved
275 public:
276 inline Interleaved() noexcept : numInterleavedChannels (1) {}
277 inline Interleaved (const Interleaved& other) noexcept : numInterleavedChannels (other.numInterleavedChannels) {}
278 inline Interleaved (const int numInterleavedChannels_) noexcept : numInterleavedChannels (numInterleavedChannels_) {}
279 inline void copyFrom (const Interleaved& other) noexcept { numInterleavedChannels = other.numInterleavedChannels; }
280 template <class SampleFormatType> inline void advanceData (SampleFormatType& s) noexcept { s.skip (numInterleavedChannels); }
281 template <class SampleFormatType> inline void advanceDataBy (SampleFormatType& s, int numSamples) noexcept { s.skip (numInterleavedChannels * numSamples); }
282 template <class SampleFormatType> inline void clear (SampleFormatType& s, int numSamples) noexcept { while (--numSamples >= 0) { s.clear(); s.skip (numInterleavedChannels); } }
283 template <class SampleFormatType> inline int getNumBytesBetweenSamples (const SampleFormatType&) const noexcept { return numInterleavedChannels * SampleFormatType::bytesPerSample; }
284 int numInterleavedChannels;
285 enum { isInterleavedType = 1 };
288 //==============================================================================
289 class NonConst
291 public:
292 typedef void VoidType;
293 static inline void* toVoidPtr (VoidType* v) noexcept { return v; }
294 enum { isConst = 0 };
297 class Const
299 public:
300 typedef const void VoidType;
301 static inline void* toVoidPtr (VoidType* v) noexcept { return const_cast<void*> (v); }
302 enum { isConst = 1 };
304 #endif
306 //==============================================================================
308 A pointer to a block of audio data with a particular encoding.
310 This object can be used to read and write from blocks of encoded audio samples. To create one, you specify
311 the audio format as a series of template parameters, e.g.
312 @code
313 // this creates a pointer for reading from a const array of 16-bit little-endian packed samples.
314 AudioData::Pointer <AudioData::Int16,
315 AudioData::LittleEndian,
316 AudioData::NonInterleaved,
317 AudioData::Const> pointer (someRawAudioData);
319 // These methods read the sample that is being pointed to
320 float firstSampleAsFloat = pointer.getAsFloat();
321 int32 firstSampleAsInt = pointer.getAsInt32();
322 ++pointer; // moves the pointer to the next sample.
323 pointer += 3; // skips the next 3 samples.
324 @endcode
326 The convertSamples() method lets you copy a range of samples from one format to another, automatically
327 converting its format.
329 @see AudioData::Converter
331 template <typename SampleFormat,
332 typename Endianness,
333 typename InterleavingType,
334 typename Constness>
335 class Pointer
337 public:
338 //==============================================================================
339 /** Creates a non-interleaved pointer from some raw data in the appropriate format.
340 This constructor is only used if you've specified the AudioData::NonInterleaved option -
341 for interleaved formats, use the constructor that also takes a number of channels.
343 Pointer (typename Constness::VoidType* sourceData) noexcept
344 : data (Constness::toVoidPtr (sourceData))
346 // If you're using interleaved data, call the other constructor! If you're using non-interleaved data,
347 // you should pass NonInterleaved as the template parameter for the interleaving type!
348 static_jassert (InterleavingType::isInterleavedType == 0);
351 /** Creates a pointer from some raw data in the appropriate format with the specified number of interleaved channels.
352 For non-interleaved data, use the other constructor.
354 Pointer (typename Constness::VoidType* sourceData, int numInterleavedChannels) noexcept
355 : data (Constness::toVoidPtr (sourceData)),
356 interleaving (numInterleavedChannels)
360 /** Creates a copy of another pointer. */
361 Pointer (const Pointer& other) noexcept
362 : data (other.data),
363 interleaving (other.interleaving)
367 Pointer& operator= (const Pointer& other) noexcept
369 data = other.data;
370 interleaving.copyFrom (other.interleaving);
371 return *this;
374 //==============================================================================
375 /** Returns the value of the first sample as a floating point value.
376 The value will be in the range -1.0 to 1.0 for integer formats. For floating point
377 formats, the value could be outside that range, although -1 to 1 is the standard range.
379 inline float getAsFloat() const noexcept { return Endianness::getAsFloat (data); }
381 /** Sets the value of the first sample as a floating point value.
383 (This method can only be used if the AudioData::NonConst option was used).
384 The value should be in the range -1.0 to 1.0 - for integer formats, values outside that
385 range will be clipped. For floating point formats, any value passed in here will be
386 written directly, although -1 to 1 is the standard range.
388 inline void setAsFloat (float newValue) noexcept
390 static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead!
391 Endianness::setAsFloat (data, newValue);
394 /** Returns the value of the first sample as a 32-bit integer.
395 The value returned will be in the range 0x80000000 to 0x7fffffff, and shorter values will be
396 shifted to fill this range (e.g. if you're reading from 24-bit data, the values will be shifted up
397 by 8 bits when returned here). If the source data is floating point, values beyond -1.0 to 1.0 will
398 be clipped so that -1.0 maps onto -0x7fffffff and 1.0 maps to 0x7fffffff.
400 inline int32 getAsInt32() const noexcept { return Endianness::getAsInt32 (data); }
402 /** Sets the value of the first sample as a 32-bit integer.
403 This will be mapped to the range of the format that is being written - see getAsInt32().
405 inline void setAsInt32 (int32 newValue) noexcept
407 static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead!
408 Endianness::setAsInt32 (data, newValue);
411 /** Moves the pointer along to the next sample. */
412 inline Pointer& operator++() noexcept { advance(); return *this; }
414 /** Moves the pointer back to the previous sample. */
415 inline Pointer& operator--() noexcept { interleaving.advanceDataBy (data, -1); return *this; }
417 /** Adds a number of samples to the pointer's position. */
418 Pointer& operator+= (int samplesToJump) noexcept { interleaving.advanceDataBy (data, samplesToJump); return *this; }
420 /** Writes a stream of samples into this pointer from another pointer.
421 This will copy the specified number of samples, converting between formats appropriately.
423 void convertSamples (Pointer source, int numSamples) const noexcept
425 static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead!
427 Pointer dest (*this);
428 while (--numSamples >= 0)
430 dest.data.copyFromSameType (source.data);
431 dest.advance();
432 source.advance();
436 /** Writes a stream of samples into this pointer from another pointer.
437 This will copy the specified number of samples, converting between formats appropriately.
439 template <class OtherPointerType>
440 void convertSamples (OtherPointerType source, int numSamples) const noexcept
442 static_jassert (Constness::isConst == 0); // trying to write to a const pointer! For a writeable one, use AudioData::NonConst instead!
444 Pointer dest (*this);
446 if (source.getRawData() != getRawData() || source.getNumBytesBetweenSamples() >= getNumBytesBetweenSamples())
448 while (--numSamples >= 0)
450 Endianness::copyFrom (dest.data, source);
451 dest.advance();
452 ++source;
455 else // copy backwards if we're increasing the sample width..
457 dest += numSamples;
458 source += numSamples;
460 while (--numSamples >= 0)
461 Endianness::copyFrom ((--dest).data, --source);
465 /** Sets a number of samples to zero. */
466 void clearSamples (int numSamples) const noexcept
468 Pointer dest (*this);
469 dest.interleaving.clear (dest.data, numSamples);
472 /** Returns true if the pointer is using a floating-point format. */
473 static bool isFloatingPoint() noexcept { return (bool) SampleFormat::isFloat; }
475 /** Returns true if the format is big-endian. */
476 static bool isBigEndian() noexcept { return (bool) Endianness::isBigEndian; }
478 /** Returns the number of bytes in each sample (ignoring the number of interleaved channels). */
479 static int getBytesPerSample() noexcept { return (int) SampleFormat::bytesPerSample; }
481 /** Returns the number of interleaved channels in the format. */
482 int getNumInterleavedChannels() const noexcept { return (int) this->numInterleavedChannels; }
484 /** Returns the number of bytes between the start address of each sample. */
485 int getNumBytesBetweenSamples() const noexcept { return interleaving.getNumBytesBetweenSamples (data); }
487 /** Returns the accuracy of this format when represented as a 32-bit integer.
488 This is the smallest number above 0 that can be represented in the sample format, converted to
489 a 32-bit range. E,g. if the format is 8-bit, its resolution is 0x01000000; if the format is 24-bit,
490 its resolution is 0x100.
492 static int get32BitResolution() noexcept { return (int) SampleFormat::resolution; }
494 /** Returns a pointer to the underlying data. */
495 const void* getRawData() const noexcept { return data.data; }
497 private:
498 //==============================================================================
499 SampleFormat data;
500 InterleavingType interleaving; // annoyingly, making the interleaving type a superclass to take
501 // advantage of EBCO causes an internal compiler error in VC6..
503 inline void advance() noexcept { interleaving.advanceData (data); }
505 Pointer operator++ (int); // private to force you to use the more efficient pre-increment!
506 Pointer operator-- (int);
509 //==============================================================================
510 /** A base class for objects that are used to convert between two different sample formats.
512 The AudioData::ConverterInstance implements this base class and can be templated, so
513 you can create an instance that converts between two particular formats, and then
514 store this in the abstract base class.
516 @see AudioData::ConverterInstance
518 class Converter
520 public:
521 virtual ~Converter() {}
523 /** Converts a sequence of samples from the converter's source format into the dest format. */
524 virtual void convertSamples (void* destSamples, const void* sourceSamples, int numSamples) const = 0;
526 /** Converts a sequence of samples from the converter's source format into the dest format.
527 This method takes sub-channel indexes, which can be used with interleaved formats in order to choose a
528 particular sub-channel of the data to be used.
530 virtual void convertSamples (void* destSamples, int destSubChannel,
531 const void* sourceSamples, int sourceSubChannel, int numSamples) const = 0;
534 //==============================================================================
536 A class that converts between two templated AudioData::Pointer types, and which
537 implements the AudioData::Converter interface.
539 This can be used as a concrete instance of the AudioData::Converter abstract class.
541 @see AudioData::Converter
543 template <class SourceSampleType, class DestSampleType>
544 class ConverterInstance : public Converter
546 public:
547 ConverterInstance (int numSourceChannels = 1, int numDestChannels = 1)
548 : sourceChannels (numSourceChannels), destChannels (numDestChannels)
551 ~ConverterInstance() {}
553 void convertSamples (void* dest, const void* source, int numSamples) const
555 SourceSampleType s (source, sourceChannels);
556 DestSampleType d (dest, destChannels);
557 d.convertSamples (s, numSamples);
560 void convertSamples (void* dest, int destSubChannel,
561 const void* source, int sourceSubChannel, int numSamples) const
563 jassert (destSubChannel < destChannels && sourceSubChannel < sourceChannels);
565 SourceSampleType s (addBytesToPointer (source, sourceSubChannel * SourceSampleType::getBytesPerSample()), sourceChannels);
566 DestSampleType d (addBytesToPointer (dest, destSubChannel * DestSampleType::getBytesPerSample()), destChannels);
567 d.convertSamples (s, numSamples);
570 private:
571 JUCE_DECLARE_NON_COPYABLE (ConverterInstance);
573 const int sourceChannels, destChannels;
579 //==============================================================================
581 A set of routines to convert buffers of 32-bit floating point data to and from
582 various integer formats.
584 Note that these functions are deprecated - the AudioData class provides a much more
585 flexible set of conversion classes now.
587 class JUCE_API AudioDataConverters
589 public:
590 //==============================================================================
591 static void convertFloatToInt16LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 2);
592 static void convertFloatToInt16BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 2);
594 static void convertFloatToInt24LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 3);
595 static void convertFloatToInt24BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 3);
597 static void convertFloatToInt32LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4);
598 static void convertFloatToInt32BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4);
600 static void convertFloatToFloat32LE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4);
601 static void convertFloatToFloat32BE (const float* source, void* dest, int numSamples, int destBytesPerSample = 4);
603 //==============================================================================
604 static void convertInt16LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 2);
605 static void convertInt16BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 2);
607 static void convertInt24LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 3);
608 static void convertInt24BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 3);
610 static void convertInt32LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4);
611 static void convertInt32BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4);
613 static void convertFloat32LEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4);
614 static void convertFloat32BEToFloat (const void* source, float* dest, int numSamples, int srcBytesPerSample = 4);
616 //==============================================================================
617 enum DataFormat
619 int16LE,
620 int16BE,
621 int24LE,
622 int24BE,
623 int32LE,
624 int32BE,
625 float32LE,
626 float32BE,
629 static void convertFloatToFormat (DataFormat destFormat,
630 const float* source, void* dest, int numSamples);
632 static void convertFormatToFloat (DataFormat sourceFormat,
633 const void* source, float* dest, int numSamples);
635 //==============================================================================
636 static void interleaveSamples (const float** source, float* dest,
637 int numSamples, int numChannels);
639 static void deinterleaveSamples (const float* source, float** dest,
640 int numSamples, int numChannels);
642 private:
643 AudioDataConverters();
644 JUCE_DECLARE_NON_COPYABLE (AudioDataConverters);
648 #endif // __JUCE_AUDIODATACONVERTERS_JUCEHEADER__