New Class to handle UI
[juce-lv2.git] / juce / source / src / audio / dsp / juce_AudioDataConverters.cpp
blobff547b1469370ffb7f42770a2b476972cf3c3ffe
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 #include "../../core/juce_StandardHeader.h"
28 BEGIN_JUCE_NAMESPACE
30 #include "juce_AudioDataConverters.h"
33 //==============================================================================
34 void AudioDataConverters::convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
36 const double maxVal = (double) 0x7fff;
37 char* intData = static_cast <char*> (dest);
39 if (dest != (void*) source || destBytesPerSample <= 4)
41 for (int i = 0; i < numSamples; ++i)
43 *(uint16*) intData = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
44 intData += destBytesPerSample;
47 else
49 intData += destBytesPerSample * numSamples;
51 for (int i = numSamples; --i >= 0;)
53 intData -= destBytesPerSample;
54 *(uint16*) intData = ByteOrder::swapIfBigEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
59 void AudioDataConverters::convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
61 const double maxVal = (double) 0x7fff;
62 char* intData = static_cast <char*> (dest);
64 if (dest != (void*) source || destBytesPerSample <= 4)
66 for (int i = 0; i < numSamples; ++i)
68 *(uint16*) intData = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
69 intData += destBytesPerSample;
72 else
74 intData += destBytesPerSample * numSamples;
76 for (int i = numSamples; --i >= 0;)
78 intData -= destBytesPerSample;
79 *(uint16*) intData = ByteOrder::swapIfLittleEndian ((uint16) (short) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
84 void AudioDataConverters::convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
86 const double maxVal = (double) 0x7fffff;
87 char* intData = static_cast <char*> (dest);
89 if (dest != (void*) source || destBytesPerSample <= 4)
91 for (int i = 0; i < numSamples; ++i)
93 ByteOrder::littleEndian24BitToChars ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
94 intData += destBytesPerSample;
97 else
99 intData += destBytesPerSample * numSamples;
101 for (int i = numSamples; --i >= 0;)
103 intData -= destBytesPerSample;
104 ByteOrder::littleEndian24BitToChars ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
109 void AudioDataConverters::convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
111 const double maxVal = (double) 0x7fffff;
112 char* intData = static_cast <char*> (dest);
114 if (dest != (void*) source || destBytesPerSample <= 4)
116 for (int i = 0; i < numSamples; ++i)
118 ByteOrder::bigEndian24BitToChars ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
119 intData += destBytesPerSample;
122 else
124 intData += destBytesPerSample * numSamples;
126 for (int i = numSamples; --i >= 0;)
128 intData -= destBytesPerSample;
129 ByteOrder::bigEndian24BitToChars ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])), intData);
134 void AudioDataConverters::convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
136 const double maxVal = (double) 0x7fffffff;
137 char* intData = static_cast <char*> (dest);
139 if (dest != (void*) source || destBytesPerSample <= 4)
141 for (int i = 0; i < numSamples; ++i)
143 *(uint32*)intData = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
144 intData += destBytesPerSample;
147 else
149 intData += destBytesPerSample * numSamples;
151 for (int i = numSamples; --i >= 0;)
153 intData -= destBytesPerSample;
154 *(uint32*)intData = ByteOrder::swapIfBigEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
159 void AudioDataConverters::convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
161 const double maxVal = (double) 0x7fffffff;
162 char* intData = static_cast <char*> (dest);
164 if (dest != (void*) source || destBytesPerSample <= 4)
166 for (int i = 0; i < numSamples; ++i)
168 *(uint32*)intData = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
169 intData += destBytesPerSample;
172 else
174 intData += destBytesPerSample * numSamples;
176 for (int i = numSamples; --i >= 0;)
178 intData -= destBytesPerSample;
179 *(uint32*)intData = ByteOrder::swapIfLittleEndian ((uint32) roundToInt (jlimit (-maxVal, maxVal, maxVal * source[i])));
184 void AudioDataConverters::convertFloatToFloat32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
186 jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data!
188 char* d = static_cast <char*> (dest);
190 for (int i = 0; i < numSamples; ++i)
192 *(float*) d = source[i];
194 #if JUCE_BIG_ENDIAN
195 *(uint32*) d = ByteOrder::swap (*(uint32*) d);
196 #endif
198 d += destBytesPerSample;
202 void AudioDataConverters::convertFloatToFloat32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample)
204 jassert (dest != (void*) source || destBytesPerSample <= 4); // This op can't be performed on in-place data!
206 char* d = static_cast <char*> (dest);
208 for (int i = 0; i < numSamples; ++i)
210 *(float*) d = source[i];
212 #if JUCE_LITTLE_ENDIAN
213 *(uint32*) d = ByteOrder::swap (*(uint32*) d);
214 #endif
216 d += destBytesPerSample;
220 //==============================================================================
221 void AudioDataConverters::convertInt16LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
223 const float scale = 1.0f / 0x7fff;
224 const char* intData = static_cast <const char*> (source);
226 if (source != (void*) dest || srcBytesPerSample >= 4)
228 for (int i = 0; i < numSamples; ++i)
230 dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*(uint16*)intData);
231 intData += srcBytesPerSample;
234 else
236 intData += srcBytesPerSample * numSamples;
238 for (int i = numSamples; --i >= 0;)
240 intData -= srcBytesPerSample;
241 dest[i] = scale * (short) ByteOrder::swapIfBigEndian (*(uint16*)intData);
246 void AudioDataConverters::convertInt16BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
248 const float scale = 1.0f / 0x7fff;
249 const char* intData = static_cast <const char*> (source);
251 if (source != (void*) dest || srcBytesPerSample >= 4)
253 for (int i = 0; i < numSamples; ++i)
255 dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*(uint16*)intData);
256 intData += srcBytesPerSample;
259 else
261 intData += srcBytesPerSample * numSamples;
263 for (int i = numSamples; --i >= 0;)
265 intData -= srcBytesPerSample;
266 dest[i] = scale * (short) ByteOrder::swapIfLittleEndian (*(uint16*)intData);
271 void AudioDataConverters::convertInt24LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
273 const float scale = 1.0f / 0x7fffff;
274 const char* intData = static_cast <const char*> (source);
276 if (source != (void*) dest || srcBytesPerSample >= 4)
278 for (int i = 0; i < numSamples; ++i)
280 dest[i] = scale * (short) ByteOrder::littleEndian24Bit (intData);
281 intData += srcBytesPerSample;
284 else
286 intData += srcBytesPerSample * numSamples;
288 for (int i = numSamples; --i >= 0;)
290 intData -= srcBytesPerSample;
291 dest[i] = scale * (short) ByteOrder::littleEndian24Bit (intData);
296 void AudioDataConverters::convertInt24BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
298 const float scale = 1.0f / 0x7fffff;
299 const char* intData = static_cast <const char*> (source);
301 if (source != (void*) dest || srcBytesPerSample >= 4)
303 for (int i = 0; i < numSamples; ++i)
305 dest[i] = scale * (short) ByteOrder::bigEndian24Bit (intData);
306 intData += srcBytesPerSample;
309 else
311 intData += srcBytesPerSample * numSamples;
313 for (int i = numSamples; --i >= 0;)
315 intData -= srcBytesPerSample;
316 dest[i] = scale * (short) ByteOrder::bigEndian24Bit (intData);
321 void AudioDataConverters::convertInt32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
323 const float scale = 1.0f / 0x7fffffff;
324 const char* intData = static_cast <const char*> (source);
326 if (source != (void*) dest || srcBytesPerSample >= 4)
328 for (int i = 0; i < numSamples; ++i)
330 dest[i] = scale * (int) ByteOrder::swapIfBigEndian (*(uint32*) intData);
331 intData += srcBytesPerSample;
334 else
336 intData += srcBytesPerSample * numSamples;
338 for (int i = numSamples; --i >= 0;)
340 intData -= srcBytesPerSample;
341 dest[i] = scale * (int) ByteOrder::swapIfBigEndian (*(uint32*) intData);
346 void AudioDataConverters::convertInt32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
348 const float scale = 1.0f / 0x7fffffff;
349 const char* intData = static_cast <const char*> (source);
351 if (source != (void*) dest || srcBytesPerSample >= 4)
353 for (int i = 0; i < numSamples; ++i)
355 dest[i] = scale * (int) ByteOrder::swapIfLittleEndian (*(uint32*) intData);
356 intData += srcBytesPerSample;
359 else
361 intData += srcBytesPerSample * numSamples;
363 for (int i = numSamples; --i >= 0;)
365 intData -= srcBytesPerSample;
366 dest[i] = scale * (int) ByteOrder::swapIfLittleEndian (*(uint32*) intData);
371 void AudioDataConverters::convertFloat32LEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
373 const char* s = static_cast <const char*> (source);
375 for (int i = 0; i < numSamples; ++i)
377 dest[i] = *(float*)s;
379 #if JUCE_BIG_ENDIAN
380 uint32* const d = (uint32*) (dest + i);
381 *d = ByteOrder::swap (*d);
382 #endif
384 s += srcBytesPerSample;
388 void AudioDataConverters::convertFloat32BEToFloat (const void* const source, float* const dest, int numSamples, const int srcBytesPerSample)
390 const char* s = static_cast <const char*> (source);
392 for (int i = 0; i < numSamples; ++i)
394 dest[i] = *(float*)s;
396 #if JUCE_LITTLE_ENDIAN
397 uint32* const d = (uint32*) (dest + i);
398 *d = ByteOrder::swap (*d);
399 #endif
401 s += srcBytesPerSample;
406 //==============================================================================
407 void AudioDataConverters::convertFloatToFormat (const DataFormat destFormat,
408 const float* const source,
409 void* const dest,
410 const int numSamples)
412 switch (destFormat)
414 case int16LE: convertFloatToInt16LE (source, dest, numSamples); break;
415 case int16BE: convertFloatToInt16BE (source, dest, numSamples); break;
416 case int24LE: convertFloatToInt24LE (source, dest, numSamples); break;
417 case int24BE: convertFloatToInt24BE (source, dest, numSamples); break;
418 case int32LE: convertFloatToInt32LE (source, dest, numSamples); break;
419 case int32BE: convertFloatToInt32BE (source, dest, numSamples); break;
420 case float32LE: convertFloatToFloat32LE (source, dest, numSamples); break;
421 case float32BE: convertFloatToFloat32BE (source, dest, numSamples); break;
422 default: jassertfalse; break;
426 void AudioDataConverters::convertFormatToFloat (const DataFormat sourceFormat,
427 const void* const source,
428 float* const dest,
429 const int numSamples)
431 switch (sourceFormat)
433 case int16LE: convertInt16LEToFloat (source, dest, numSamples); break;
434 case int16BE: convertInt16BEToFloat (source, dest, numSamples); break;
435 case int24LE: convertInt24LEToFloat (source, dest, numSamples); break;
436 case int24BE: convertInt24BEToFloat (source, dest, numSamples); break;
437 case int32LE: convertInt32LEToFloat (source, dest, numSamples); break;
438 case int32BE: convertInt32BEToFloat (source, dest, numSamples); break;
439 case float32LE: convertFloat32LEToFloat (source, dest, numSamples); break;
440 case float32BE: convertFloat32BEToFloat (source, dest, numSamples); break;
441 default: jassertfalse; break;
445 //==============================================================================
446 void AudioDataConverters::interleaveSamples (const float** const source,
447 float* const dest,
448 const int numSamples,
449 const int numChannels)
451 for (int chan = 0; chan < numChannels; ++chan)
453 int i = chan;
454 const float* src = source [chan];
456 for (int j = 0; j < numSamples; ++j)
458 dest [i] = src [j];
459 i += numChannels;
464 void AudioDataConverters::deinterleaveSamples (const float* const source,
465 float** const dest,
466 const int numSamples,
467 const int numChannels)
469 for (int chan = 0; chan < numChannels; ++chan)
471 int i = chan;
472 float* dst = dest [chan];
474 for (int j = 0; j < numSamples; ++j)
476 dst [j] = source [i];
477 i += numChannels;
483 //==============================================================================
484 #if JUCE_UNIT_TESTS
486 #include "../../utilities/juce_UnitTest.h"
487 #include "../../maths/juce_Random.h"
489 class AudioConversionTests : public UnitTest
491 public:
492 AudioConversionTests() : UnitTest ("Audio data conversion") {}
494 template <class F1, class E1, class F2, class E2>
495 struct Test5
497 static void test (UnitTest& unitTest)
499 test (unitTest, false);
500 test (unitTest, true);
503 static void test (UnitTest& unitTest, bool inPlace)
505 const int numSamples = 2048;
506 int32 original [numSamples], converted [numSamples], reversed [numSamples];
509 AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> d (original);
510 bool clippingFailed = false;
512 for (int i = 0; i < numSamples / 2; ++i)
514 d.setAsFloat (Random::getSystemRandom().nextFloat() * 2.2f - 1.1f);
516 if (! d.isFloatingPoint())
517 clippingFailed = d.getAsFloat() > 1.0f || d.getAsFloat() < -1.0f || clippingFailed;
519 ++d;
520 d.setAsInt32 (Random::getSystemRandom().nextInt());
521 ++d;
524 unitTest.expect (! clippingFailed);
527 // convert data from the source to dest format..
528 ScopedPointer<AudioData::Converter> conv (new AudioData::ConverterInstance <AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const>,
529 AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::NonConst> >());
530 conv->convertSamples (inPlace ? reversed : converted, original, numSamples);
532 // ..and back again..
533 conv = new AudioData::ConverterInstance <AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>,
534 AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::NonConst> >();
535 if (! inPlace)
536 zeromem (reversed, sizeof (reversed));
538 conv->convertSamples (reversed, inPlace ? reversed : converted, numSamples);
541 int biggestDiff = 0;
542 AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d1 (original);
543 AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const> d2 (reversed);
545 const int errorMargin = 2 * AudioData::Pointer<F1, E1, AudioData::NonInterleaved, AudioData::Const>::get32BitResolution()
546 + AudioData::Pointer<F2, E2, AudioData::NonInterleaved, AudioData::Const>::get32BitResolution();
548 for (int i = 0; i < numSamples; ++i)
550 biggestDiff = jmax (biggestDiff, std::abs (d1.getAsInt32() - d2.getAsInt32()));
551 ++d1;
552 ++d2;
555 unitTest.expect (biggestDiff <= errorMargin);
560 template <class F1, class E1, class FormatType>
561 struct Test3
563 static void test (UnitTest& unitTest)
565 Test5 <F1, E1, FormatType, AudioData::BigEndian>::test (unitTest);
566 Test5 <F1, E1, FormatType, AudioData::LittleEndian>::test (unitTest);
570 template <class FormatType, class Endianness>
571 struct Test2
573 static void test (UnitTest& unitTest)
575 Test3 <FormatType, Endianness, AudioData::Int8>::test (unitTest);
576 Test3 <FormatType, Endianness, AudioData::UInt8>::test (unitTest);
577 Test3 <FormatType, Endianness, AudioData::Int16>::test (unitTest);
578 Test3 <FormatType, Endianness, AudioData::Int24>::test (unitTest);
579 Test3 <FormatType, Endianness, AudioData::Int32>::test (unitTest);
580 Test3 <FormatType, Endianness, AudioData::Float32>::test (unitTest);
584 template <class FormatType>
585 struct Test1
587 static void test (UnitTest& unitTest)
589 Test2 <FormatType, AudioData::BigEndian>::test (unitTest);
590 Test2 <FormatType, AudioData::LittleEndian>::test (unitTest);
594 void runTest()
596 beginTest ("Round-trip conversion: Int8");
597 Test1 <AudioData::Int8>::test (*this);
598 beginTest ("Round-trip conversion: Int16");
599 Test1 <AudioData::Int16>::test (*this);
600 beginTest ("Round-trip conversion: Int24");
601 Test1 <AudioData::Int24>::test (*this);
602 beginTest ("Round-trip conversion: Int32");
603 Test1 <AudioData::Int32>::test (*this);
604 beginTest ("Round-trip conversion: Float32");
605 Test1 <AudioData::Float32>::test (*this);
609 static AudioConversionTests audioConversionUnitTests;
611 #endif
614 END_JUCE_NAMESPACE