OpenShot Audio Library | OpenShotAudio 0.3.2

Loading...
Searching...
No Matches
juce_AudioSampleBuffer.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
23 namespace juce
24{
25
26//==============================================================================
32 template <typename Type>
33 class AudioBuffer
34{
35 public:
36 //==============================================================================
38 AudioBuffer() noexcept
39 : channels (static_cast<Type**> (preallocatedChannelSpace))
40 {
41 }
42
43 //==============================================================================
53 AudioBuffer (int numChannelsToAllocate,
54 int numSamplesToAllocate)
55 : numChannels (numChannelsToAllocate),
56 size (numSamplesToAllocate)
57 {
58 jassert (size >= 0 && numChannels >= 0);
59 allocateData();
60 }
61
77 AudioBuffer (Type* const* dataToReferTo,
78 int numChannelsToUse,
79 int numSamples)
80 : numChannels (numChannelsToUse),
81 size (numSamples)
82 {
83 jassert (dataToReferTo != nullptr);
84 jassert (numChannelsToUse >= 0 && numSamples >= 0);
85 allocateChannels (dataToReferTo, 0);
86 }
87
104 AudioBuffer (Type* const* dataToReferTo,
105 int numChannelsToUse,
106 int startSample,
107 int numSamples)
108 : numChannels (numChannelsToUse),
109 size (numSamples)
110 {
111 jassert (dataToReferTo != nullptr);
112 jassert (numChannelsToUse >= 0 && startSample >= 0 && numSamples >= 0);
113 allocateChannels (dataToReferTo, startSample);
114 }
115
122 AudioBuffer (const AudioBuffer& other)
123 : numChannels (other.numChannels),
124 size (other.size),
125 allocatedBytes (other.allocatedBytes)
126 {
127 if (allocatedBytes == 0)
128 {
129 allocateChannels (other.channels, 0);
130 }
131 else
132 {
133 allocateData();
134
135 if (other.isClear)
136 {
137 clear();
138 }
139 else
140 {
141 for (int i = 0; i < numChannels; ++i)
142 FloatVectorOperations::copy (channels[i], other.channels[i], size);
143 }
144 }
145 }
146
150 AudioBuffer& operator= (const AudioBuffer& other)
151 {
152 if (this != &other)
153 {
154 setSize (other.getNumChannels(), other.getNumSamples(), false, false, false);
155
156 if (other.isClear)
157 {
158 clear();
159 }
160 else
161 {
162 isClear = false;
163
164 for (int i = 0; i < numChannels; ++i)
165 FloatVectorOperations::copy (channels[i], other.channels[i], size);
166 }
167 }
168
169 return *this;
170 }
171
175 ~AudioBuffer() = default;
176
178 AudioBuffer (AudioBuffer&& other) noexcept
179 : numChannels (other.numChannels),
180 size (other.size),
181 allocatedBytes (other.allocatedBytes),
182 allocatedData (std::move (other.allocatedData)),
183 isClear (other.isClear.load())
184 {
185 if (numChannels < (int) numElementsInArray (preallocatedChannelSpace))
186 {
187 channels = preallocatedChannelSpace;
188
189 for (int i = 0; i < numChannels; ++i)
190 preallocatedChannelSpace[i] = other.channels[i];
191 }
192 else
193 {
194 channels = other.channels;
195 }
196
197 other.numChannels = 0;
198 other.size = 0;
199 other.allocatedBytes = 0;
200 }
201
203 AudioBuffer& operator= (AudioBuffer&& other) noexcept
204 {
205 numChannels = other.numChannels;
206 size = other.size;
207 allocatedBytes = other.allocatedBytes;
208 allocatedData = std::move (other.allocatedData);
209 isClear = other.isClear.load();
210
211 if (numChannels < (int) numElementsInArray (preallocatedChannelSpace))
212 {
213 channels = preallocatedChannelSpace;
214
215 for (int i = 0; i < numChannels; ++i)
216 preallocatedChannelSpace[i] = other.channels[i];
217 }
218 else
219 {
220 channels = other.channels;
221 }
222
223 other.numChannels = 0;
224 other.size = 0;
225 other.allocatedBytes = 0;
226 return *this;
227 }
228
229 //==============================================================================
233 int getNumChannels() const noexcept { return numChannels; }
234
238 int getNumSamples() const noexcept { return size; }
239
247 const Type* getReadPointer (int channelNumber) const noexcept
248 {
249 jassert (isPositiveAndBelow (channelNumber, numChannels));
250 return channels[channelNumber];
251 }
252
260 const Type* getReadPointer (int channelNumber, int sampleIndex) const noexcept
261 {
262 jassert (isPositiveAndBelow (channelNumber, numChannels));
263 jassert (isPositiveAndBelow (sampleIndex, size));
264 return channels[channelNumber] + sampleIndex;
265 }
266
273 Type* getWritePointer (int channelNumber) noexcept
274 {
275 jassert (isPositiveAndBelow (channelNumber, numChannels));
276 isClear = false;
277 return channels[channelNumber];
278 }
279
286 Type* getWritePointer (int channelNumber, int sampleIndex) noexcept
287 {
288 jassert (isPositiveAndBelow (channelNumber, numChannels));
289 jassert (isPositiveAndBelow (sampleIndex, size));
290 isClear = false;
291 return channels[channelNumber] + sampleIndex;
292 }
293
299 const Type** getArrayOfReadPointers() const noexcept { return const_cast<const Type**> (channels); }
300
306 Type** getArrayOfWritePointers() noexcept { isClear = false; return channels; }
307
308 //==============================================================================
331 void setSize (int newNumChannels,
332 int newNumSamples,
333 bool keepExistingContent = false,
334 bool clearExtraSpace = false,
335 bool avoidReallocating = false)
336 {
337 jassert (newNumChannels >= 0);
338 jassert (newNumSamples >= 0);
339
340 if (newNumSamples != size || newNumChannels != numChannels)
341 {
342 auto allocatedSamplesPerChannel = ((size_t) newNumSamples + 3) & ~3u;
343 auto channelListSize = ((static_cast<size_t> (1 + newNumChannels) * sizeof (Type*)) + 15) & ~15u;
344 auto newTotalBytes = ((size_t) newNumChannels * (size_t) allocatedSamplesPerChannel * sizeof (Type))
345 + channelListSize + 32;
346
347 if (keepExistingContent)
348 {
349 if (avoidReallocating && newNumChannels <= numChannels && newNumSamples <= size)
350 {
351 // no need to do any remapping in this case, as the channel pointers will remain correct!
352 }
353 else
354 {
355 HeapBlock<char, true> newData;
356 newData.allocate (newTotalBytes, clearExtraSpace || isClear);
357
358 auto numSamplesToCopy = (size_t) jmin (newNumSamples, size);
359
360 auto newChannels = reinterpret_cast<Type**> (newData.get());
361 auto newChan = reinterpret_cast<Type*> (newData + channelListSize);
362
363 for (int j = 0; j < newNumChannels; ++j)
364 {
365 newChannels[j] = newChan;
366 newChan += allocatedSamplesPerChannel;
367 }
368
369 if (! isClear)
370 {
371 auto numChansToCopy = jmin (numChannels, newNumChannels);
372
373 for (int i = 0; i < numChansToCopy; ++i)
374 FloatVectorOperations::copy (newChannels[i], channels[i], (int) numSamplesToCopy);
375 }
376
377 allocatedData.swapWith (newData);
378 allocatedBytes = newTotalBytes;
379 channels = newChannels;
380 }
381 }
382 else
383 {
384 if (avoidReallocating && allocatedBytes >= newTotalBytes)
385 {
386 if (clearExtraSpace || isClear)
387 allocatedData.clear (newTotalBytes);
388 }
389 else
390 {
391 allocatedBytes = newTotalBytes;
392 allocatedData.allocate (newTotalBytes, clearExtraSpace || isClear);
393 channels = reinterpret_cast<Type**> (allocatedData.get());
394 }
395
396 auto* chan = reinterpret_cast<Type*> (allocatedData + channelListSize);
397
398 for (int i = 0; i < newNumChannels; ++i)
399 {
400 channels[i] = chan;
401 chan += allocatedSamplesPerChannel;
402 }
403 }
404
405 channels[newNumChannels] = nullptr;
406 size = newNumSamples;
407 numChannels = newNumChannels;
408 }
409 }
410
430 void setDataToReferTo (Type** dataToReferTo,
431 int newNumChannels,
432 int newStartSample,
433 int newNumSamples)
434 {
435 jassert (dataToReferTo != nullptr);
436 jassert (newNumChannels >= 0 && newNumSamples >= 0);
437
438 if (allocatedBytes != 0)
439 {
440 allocatedBytes = 0;
441 allocatedData.free();
442 }
443
444 numChannels = newNumChannels;
445 size = newNumSamples;
446
447 allocateChannels (dataToReferTo, newStartSample);
448 jassert (! isClear);
449 }
450
469 void setDataToReferTo (Type** dataToReferTo,
470 int newNumChannels,
471 int newNumSamples)
472 {
473 setDataToReferTo (dataToReferTo, newNumChannels, 0, newNumSamples);
474 }
475
480 template <typename OtherType>
481 void makeCopyOf (const AudioBuffer<OtherType>& other, bool avoidReallocating = false)
482 {
483 setSize (other.getNumChannels(), other.getNumSamples(), false, false, avoidReallocating);
484
485 if (other.hasBeenCleared())
486 {
487 clear();
488 }
489 else
490 {
491 isClear = false;
492
493 for (int chan = 0; chan < numChannels; ++chan)
494 {
495 auto* dest = channels[chan];
496 auto* src = other.getReadPointer (chan);
497
498 for (int i = 0; i < size; ++i)
499 dest[i] = static_cast<Type> (src[i]);
500 }
501 }
502 }
503
504 //==============================================================================
506 void clear() noexcept
507 {
508 if (! isClear)
509 {
510 for (int i = 0; i < numChannels; ++i)
511 FloatVectorOperations::clear (channels[i], size);
512
513 isClear = true;
514 }
515 }
516
522 void clear (int startSample, int numSamples) noexcept
523 {
524 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
525
526 if (! isClear)
527 {
528 if (startSample == 0 && numSamples == size)
529 isClear = true;
530
531 for (int i = 0; i < numChannels; ++i)
532 FloatVectorOperations::clear (channels[i] + startSample, numSamples);
533 }
534 }
535
541 void clear (int channel, int startSample, int numSamples) noexcept
542 {
543 jassert (isPositiveAndBelow (channel, numChannels));
544 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
545
546 if (! isClear)
547 FloatVectorOperations::clear (channels[channel] + startSample, numSamples);
548 }
549
556 bool hasBeenCleared() const noexcept { return isClear; }
557
558 //==============================================================================
564 Type getSample (int channel, int sampleIndex) const noexcept
565 {
566 jassert (isPositiveAndBelow (channel, numChannels));
567 jassert (isPositiveAndBelow (sampleIndex, size));
568 return *(channels[channel] + sampleIndex);
569 }
570
576 void setSample (int destChannel, int destSample, Type newValue) noexcept
577 {
578 jassert (isPositiveAndBelow (destChannel, numChannels));
579 jassert (isPositiveAndBelow (destSample, size));
580 *(channels[destChannel] + destSample) = newValue;
581 isClear = false;
582 }
583
589 void addSample (int destChannel, int destSample, Type valueToAdd) noexcept
590 {
591 jassert (isPositiveAndBelow (destChannel, numChannels));
592 jassert (isPositiveAndBelow (destSample, size));
593 *(channels[destChannel] + destSample) += valueToAdd;
594 isClear = false;
595 }
596
602 void applyGain (int channel, int startSample, int numSamples, Type gain) noexcept
603 {
604 jassert (isPositiveAndBelow (channel, numChannels));
605 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
606
607 if (gain != Type (1) && ! isClear)
608 {
609 auto* d = channels[channel] + startSample;
610
611 if (gain == Type())
612 FloatVectorOperations::clear (d, numSamples);
613 else
614 FloatVectorOperations::multiply (d, gain, numSamples);
615 }
616 }
617
623 void applyGain (int startSample, int numSamples, Type gain) noexcept
624 {
625 for (int i = 0; i < numChannels; ++i)
626 applyGain (i, startSample, numSamples, gain);
627 }
628
630 void applyGain (Type gain) noexcept
631 {
632 applyGain (0, size, gain);
633 }
634
644 void applyGainRamp (int channel, int startSample, int numSamples,
645 Type startGain, Type endGain) noexcept
646 {
647 if (! isClear)
648 {
649 if (startGain == endGain)
650 {
651 applyGain (channel, startSample, numSamples, startGain);
652 }
653 else
654 {
655 jassert (isPositiveAndBelow (channel, numChannels));
656 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
657
658 const auto increment = (endGain - startGain) / (float) numSamples;
659 auto* d = channels[channel] + startSample;
660
661 while (--numSamples >= 0)
662 {
663 *d++ *= startGain;
664 startGain += increment;
665 }
666 }
667 }
668 }
669
679 void applyGainRamp (int startSample, int numSamples,
680 Type startGain, Type endGain) noexcept
681 {
682 for (int i = 0; i < numChannels; ++i)
683 applyGainRamp (i, startSample, numSamples, startGain, endGain);
684 }
685
699 void addFrom (int destChannel,
700 int destStartSample,
701 const AudioBuffer& source,
702 int sourceChannel,
703 int sourceStartSample,
704 int numSamples,
705 Type gainToApplyToSource = Type (1)) noexcept
706 {
707 jassert (&source != this || sourceChannel != destChannel);
708 jassert (isPositiveAndBelow (destChannel, numChannels));
709 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
710 jassert (isPositiveAndBelow (sourceChannel, source.numChannels));
711 jassert (sourceStartSample >= 0 && sourceStartSample + numSamples <= source.size);
712
713 if (gainToApplyToSource != 0 && numSamples > 0 && ! source.isClear)
714 {
715 auto* d = channels[destChannel] + destStartSample;
716 auto* s = source.channels[sourceChannel] + sourceStartSample;
717
718 if (isClear)
719 {
720 isClear = false;
721
722 if (gainToApplyToSource != Type (1))
723 FloatVectorOperations::copyWithMultiply (d, s, gainToApplyToSource, numSamples);
724 else
725 FloatVectorOperations::copy (d, s, numSamples);
726 }
727 else
728 {
729 if (gainToApplyToSource != Type (1))
730 FloatVectorOperations::addWithMultiply (d, s, gainToApplyToSource, numSamples);
731 else
732 FloatVectorOperations::add (d, s, numSamples);
733 }
734 }
735 }
736
748 void addFrom (int destChannel,
749 int destStartSample,
750 const Type* source,
751 int numSamples,
752 Type gainToApplyToSource = Type (1)) noexcept
753 {
754 jassert (isPositiveAndBelow (destChannel, numChannels));
755 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
756 jassert (source != nullptr);
757
758 if (gainToApplyToSource != 0 && numSamples > 0)
759 {
760 auto* d = channels[destChannel] + destStartSample;
761
762 if (isClear)
763 {
764 isClear = false;
765
766 if (gainToApplyToSource != Type (1))
767 FloatVectorOperations::copyWithMultiply (d, source, gainToApplyToSource, numSamples);
768 else
769 FloatVectorOperations::copy (d, source, numSamples);
770 }
771 else
772 {
773 if (gainToApplyToSource != Type (1))
774 FloatVectorOperations::addWithMultiply (d, source, gainToApplyToSource, numSamples);
775 else
776 FloatVectorOperations::add (d, source, numSamples);
777 }
778 }
779 }
780
781
793 void addFromWithRamp (int destChannel,
794 int destStartSample,
795 const Type* source,
796 int numSamples,
797 Type startGain,
798 Type endGain) noexcept
799 {
800 if (startGain == endGain)
801 {
802 addFrom (destChannel, destStartSample, source, numSamples, startGain);
803 }
804 else
805 {
806 jassert (isPositiveAndBelow (destChannel, numChannels));
807 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
808 jassert (source != nullptr);
809
810 if (numSamples > 0)
811 {
812 isClear = false;
813 const auto increment = (endGain - startGain) / numSamples;
814 auto* d = channels[destChannel] + destStartSample;
815
816 while (--numSamples >= 0)
817 {
818 *d++ += startGain * *source++;
819 startGain += increment;
820 }
821 }
822 }
823 }
824
836 void copyFrom (int destChannel,
837 int destStartSample,
838 const AudioBuffer& source,
839 int sourceChannel,
840 int sourceStartSample,
841 int numSamples) noexcept
842 {
843 jassert (&source != this || sourceChannel != destChannel);
844 jassert (isPositiveAndBelow (destChannel, numChannels));
845 jassert (destStartSample >= 0 && destStartSample + numSamples <= size);
846 jassert (isPositiveAndBelow (sourceChannel, source.numChannels));
847 jassert (sourceStartSample >= 0 && numSamples >= 0 && sourceStartSample + numSamples <= source.size);
848
849 if (numSamples > 0)
850 {
851 if (source.isClear)
852 {
853 if (! isClear)
854 FloatVectorOperations::clear (channels[destChannel] + destStartSample, numSamples);
855 }
856 else
857 {
858 isClear = false;
859 FloatVectorOperations::copy (channels[destChannel] + destStartSample,
860 source.channels[sourceChannel] + sourceStartSample,
861 numSamples);
862 }
863 }
864 }
865
875 void copyFrom (int destChannel,
876 int destStartSample,
877 const Type* source,
878 int numSamples) noexcept
879 {
880 jassert (isPositiveAndBelow (destChannel, numChannels));
881 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
882 jassert (source != nullptr);
883
884 if (numSamples > 0)
885 {
886 isClear = false;
887 FloatVectorOperations::copy (channels[destChannel] + destStartSample, source, numSamples);
888 }
889 }
890
901 void copyFrom (int destChannel,
902 int destStartSample,
903 const Type* source,
904 int numSamples,
905 Type gain) noexcept
906 {
907 jassert (isPositiveAndBelow (destChannel, numChannels));
908 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
909 jassert (source != nullptr);
910
911 if (numSamples > 0)
912 {
913 auto* d = channels[destChannel] + destStartSample;
914
915 if (gain != Type (1))
916 {
917 if (gain == Type())
918 {
919 if (! isClear)
920 FloatVectorOperations::clear (d, numSamples);
921 }
922 else
923 {
924 isClear = false;
925 FloatVectorOperations::copyWithMultiply (d, source, gain, numSamples);
926 }
927 }
928 else
929 {
930 isClear = false;
931 FloatVectorOperations::copy (d, source, numSamples);
932 }
933 }
934 }
935
949 void copyFromWithRamp (int destChannel,
950 int destStartSample,
951 const Type* source,
952 int numSamples,
953 Type startGain,
954 Type endGain) noexcept
955 {
956 if (startGain == endGain)
957 {
958 copyFrom (destChannel, destStartSample, source, numSamples, startGain);
959 }
960 else
961 {
962 jassert (isPositiveAndBelow (destChannel, numChannels));
963 jassert (destStartSample >= 0 && numSamples >= 0 && destStartSample + numSamples <= size);
964 jassert (source != nullptr);
965
966 if (numSamples > 0)
967 {
968 isClear = false;
969 const auto increment = (endGain - startGain) / numSamples;
970 auto* d = channels[destChannel] + destStartSample;
971
972 while (--numSamples >= 0)
973 {
974 *d++ = startGain * *source++;
975 startGain += increment;
976 }
977 }
978 }
979 }
980
987 Range<Type> findMinMax (int channel, int startSample, int numSamples) const noexcept
988 {
989 jassert (isPositiveAndBelow (channel, numChannels));
990 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
991
992 if (isClear)
993 return { Type (0), Type (0) };
994
995 return FloatVectorOperations::findMinAndMax (channels[channel] + startSample, numSamples);
996 }
997
999 Type getMagnitude (int channel, int startSample, int numSamples) const noexcept
1000 {
1001 jassert (isPositiveAndBelow (channel, numChannels));
1002 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1003
1004 if (isClear)
1005 return Type (0);
1006
1007 auto r = findMinMax (channel, startSample, numSamples);
1008
1009 return jmax (r.getStart(), -r.getStart(), r.getEnd(), -r.getEnd());
1010 }
1011
1013 Type getMagnitude (int startSample, int numSamples) const noexcept
1014 {
1015 Type mag (0);
1016
1017 if (! isClear)
1018 for (int i = 0; i < numChannels; ++i)
1019 mag = jmax (mag, getMagnitude (i, startSample, numSamples));
1020
1021 return mag;
1022 }
1023
1025 Type getRMSLevel (int channel, int startSample, int numSamples) const noexcept
1026 {
1027 jassert (isPositiveAndBelow (channel, numChannels));
1028 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1029
1030 if (numSamples <= 0 || channel < 0 || channel >= numChannels || isClear)
1031 return Type (0);
1032
1033 auto* data = channels[channel] + startSample;
1034 double sum = 0.0;
1035
1036 for (int i = 0; i < numSamples; ++i)
1037 {
1038 auto sample = data[i];
1039 sum += sample * sample;
1040 }
1041
1042 return static_cast<Type> (std::sqrt (sum / numSamples));
1043 }
1044
1046 void reverse (int channel, int startSample, int numSamples) const noexcept
1047 {
1048 jassert (isPositiveAndBelow (channel, numChannels));
1049 jassert (startSample >= 0 && numSamples >= 0 && startSample + numSamples <= size);
1050
1051 if (! isClear)
1052 std::reverse (channels[channel] + startSample,
1053 channels[channel] + startSample + numSamples);
1054 }
1055
1057 void reverse (int startSample, int numSamples) const noexcept
1058 {
1059 for (int i = 0; i < numChannels; ++i)
1060 reverse (i, startSample, numSamples);
1061 }
1062
1063 //==============================================================================
1065 using SampleType = Type;
1066
1067 private:
1068 //==============================================================================
1069 int numChannels = 0, size = 0;
1070 size_t allocatedBytes = 0;
1071 Type** channels;
1072 HeapBlock<char, true> allocatedData;
1073 Type* preallocatedChannelSpace[32];
1074 std::atomic<bool> isClear { false };
1075
1076 void allocateData()
1077 {
1078 static_assert (std::alignment_of<Type>::value <= std::alignment_of<std::max_align_t>::value,
1079 "AudioBuffer cannot hold types with alignment requirements larger than that guaranteed by malloc");
1080 jassert (size >= 0);
1081
1082 auto channelListSize = (size_t) (numChannels + 1) * sizeof (Type*);
1083 auto requiredSampleAlignment = std::alignment_of<Type>::value;
1084 size_t alignmentOverflow = channelListSize % requiredSampleAlignment;
1085
1086 if (alignmentOverflow != 0)
1087 channelListSize += requiredSampleAlignment - alignmentOverflow;
1088
1089 allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (Type) + channelListSize + 32;
1090 allocatedData.malloc (allocatedBytes);
1091 channels = reinterpret_cast<Type**> (allocatedData.get());
1092 auto chan = reinterpret_cast<Type*> (allocatedData + channelListSize);
1093
1094 for (int i = 0; i < numChannels; ++i)
1095 {
1096 channels[i] = chan;
1097 chan += size;
1098 }
1099
1100 channels[numChannels] = nullptr;
1101 isClear = false;
1102 }
1103
1104 void allocateChannels (Type* const* dataToReferTo, int offset)
1105 {
1106 jassert (offset >= 0);
1107
1108 // (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools)
1109 if (numChannels < (int) numElementsInArray (preallocatedChannelSpace))
1110 {
1111 channels = static_cast<Type**> (preallocatedChannelSpace);
1112 }
1113 else
1114 {
1115 allocatedData.malloc (numChannels + 1, sizeof (Type*));
1116 channels = reinterpret_cast<Type**> (allocatedData.get());
1117 }
1118
1119 for (int i = 0; i < numChannels; ++i)
1120 {
1121 // you have to pass in the same number of valid pointers as numChannels
1122 jassert (dataToReferTo[i] != nullptr);
1123 channels[i] = dataToReferTo[i] + offset;
1124 }
1125
1126 channels[numChannels] = nullptr;
1127 isClear = false;
1128 }
1129
1130 JUCE_LEAK_DETECTOR (AudioBuffer)
1131};
1132
1133//==============================================================================
1143 using AudioSampleBuffer = AudioBuffer<float>;
1144
1145} // namespace juce
juce::AudioBuffer
Definition: juce_AudioSampleBuffer.h:34
juce::AudioBuffer::AudioBuffer
AudioBuffer(Type *const *dataToReferTo, int numChannelsToUse, int startSample, int numSamples)
Definition: juce_AudioSampleBuffer.h:104
juce::AudioBuffer::setSize
void setSize(int newNumChannels, int newNumSamples, bool keepExistingContent=false, bool clearExtraSpace=false, bool avoidReallocating=false)
Definition: juce_AudioSampleBuffer.h:331
juce::AudioBuffer::getMagnitude
Type getMagnitude(int channel, int startSample, int numSamples) const noexcept
Definition: juce_AudioSampleBuffer.h:999
juce::AudioBuffer::AudioBuffer
AudioBuffer(Type *const *dataToReferTo, int numChannelsToUse, int numSamples)
Definition: juce_AudioSampleBuffer.h:77
juce::AudioBuffer::getSample
Type getSample(int channel, int sampleIndex) const noexcept
Definition: juce_AudioSampleBuffer.h:564
juce::AudioBuffer::applyGain
void applyGain(Type gain) noexcept
Definition: juce_AudioSampleBuffer.h:630
juce::AudioBuffer::findMinMax
Range< Type > findMinMax(int channel, int startSample, int numSamples) const noexcept
Definition: juce_AudioSampleBuffer.h:987
juce::AudioBuffer::AudioBuffer
AudioBuffer(const AudioBuffer &other)
Definition: juce_AudioSampleBuffer.h:122
juce::AudioBuffer::getReadPointer
const Type * getReadPointer(int channelNumber, int sampleIndex) const noexcept
Definition: juce_AudioSampleBuffer.h:260
juce::AudioBuffer::makeCopyOf
void makeCopyOf(const AudioBuffer< OtherType > &other, bool avoidReallocating=false)
Definition: juce_AudioSampleBuffer.h:481
juce::AudioBuffer::applyGain
void applyGain(int startSample, int numSamples, Type gain) noexcept
Definition: juce_AudioSampleBuffer.h:623
juce::AudioBuffer::setDataToReferTo
void setDataToReferTo(Type **dataToReferTo, int newNumChannels, int newNumSamples)
Definition: juce_AudioSampleBuffer.h:469
juce::AudioBuffer::copyFromWithRamp
void copyFromWithRamp(int destChannel, int destStartSample, const Type *source, int numSamples, Type startGain, Type endGain) noexcept
Definition: juce_AudioSampleBuffer.h:949
juce::AudioBuffer::addSample
void addSample(int destChannel, int destSample, Type valueToAdd) noexcept
Definition: juce_AudioSampleBuffer.h:589
juce::AudioBuffer::getRMSLevel
Type getRMSLevel(int channel, int startSample, int numSamples) const noexcept
Definition: juce_AudioSampleBuffer.h:1025
juce::AudioBuffer::getWritePointer
Type * getWritePointer(int channelNumber) noexcept
Definition: juce_AudioSampleBuffer.h:273
juce::AudioBuffer::copyFrom
void copyFrom(int destChannel, int destStartSample, const Type *source, int numSamples) noexcept
Definition: juce_AudioSampleBuffer.h:875
juce::AudioBuffer::getNumChannels
int getNumChannels() const noexcept
Definition: juce_AudioSampleBuffer.h:233
juce::AudioBuffer::getWritePointer
Type * getWritePointer(int channelNumber, int sampleIndex) noexcept
Definition: juce_AudioSampleBuffer.h:286
juce::AudioBuffer::getNumSamples
int getNumSamples() const noexcept
Definition: juce_AudioSampleBuffer.h:238
juce::AudioBuffer::clear
void clear() noexcept
Definition: juce_AudioSampleBuffer.h:506
juce::AudioBuffer::clear
void clear(int channel, int startSample, int numSamples) noexcept
Definition: juce_AudioSampleBuffer.h:541
juce::AudioBuffer::copyFrom
void copyFrom(int destChannel, int destStartSample, const Type *source, int numSamples, Type gain) noexcept
Definition: juce_AudioSampleBuffer.h:901
juce::AudioBuffer::~AudioBuffer
~AudioBuffer()=default
juce::AudioBuffer::applyGainRamp
void applyGainRamp(int channel, int startSample, int numSamples, Type startGain, Type endGain) noexcept
Definition: juce_AudioSampleBuffer.h:644
juce::AudioBuffer::setDataToReferTo
void setDataToReferTo(Type **dataToReferTo, int newNumChannels, int newStartSample, int newNumSamples)
Definition: juce_AudioSampleBuffer.h:430
juce::AudioBuffer::copyFrom
void copyFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples) noexcept
Definition: juce_AudioSampleBuffer.h:836
juce::AudioBuffer::reverse
void reverse(int startSample, int numSamples) const noexcept
Definition: juce_AudioSampleBuffer.h:1057
juce::AudioBuffer::addFromWithRamp
void addFromWithRamp(int destChannel, int destStartSample, const Type *source, int numSamples, Type startGain, Type endGain) noexcept
Definition: juce_AudioSampleBuffer.h:793
juce::AudioBuffer::getMagnitude
Type getMagnitude(int startSample, int numSamples) const noexcept
Definition: juce_AudioSampleBuffer.h:1013
juce::AudioBuffer::reverse
void reverse(int channel, int startSample, int numSamples) const noexcept
Definition: juce_AudioSampleBuffer.h:1046
juce::AudioBuffer::setSample
void setSample(int destChannel, int destSample, Type newValue) noexcept
Definition: juce_AudioSampleBuffer.h:576
juce::AudioBuffer::addFrom
void addFrom(int destChannel, int destStartSample, const AudioBuffer &source, int sourceChannel, int sourceStartSample, int numSamples, Type gainToApplyToSource=Type(1)) noexcept
Definition: juce_AudioSampleBuffer.h:699
juce::AudioBuffer::hasBeenCleared
bool hasBeenCleared() const noexcept
Definition: juce_AudioSampleBuffer.h:556
juce::AudioBuffer::getReadPointer
const Type * getReadPointer(int channelNumber) const noexcept
Definition: juce_AudioSampleBuffer.h:247
juce::AudioBuffer::operator=
AudioBuffer & operator=(const AudioBuffer &other)
Definition: juce_AudioSampleBuffer.h:150
juce::AudioBuffer::AudioBuffer
AudioBuffer(AudioBuffer &&other) noexcept
Definition: juce_AudioSampleBuffer.h:178
juce::AudioBuffer::SampleType
Type SampleType
Definition: juce_AudioSampleBuffer.h:1065
juce::AudioBuffer::AudioBuffer
AudioBuffer() noexcept
Definition: juce_AudioSampleBuffer.h:38
juce::AudioBuffer::clear
void clear(int startSample, int numSamples) noexcept
Definition: juce_AudioSampleBuffer.h:522
juce::AudioBuffer::getArrayOfReadPointers
const Type ** getArrayOfReadPointers() const noexcept
Definition: juce_AudioSampleBuffer.h:299
juce::AudioBuffer::AudioBuffer
AudioBuffer(int numChannelsToAllocate, int numSamplesToAllocate)
Definition: juce_AudioSampleBuffer.h:53
juce::AudioBuffer::addFrom
void addFrom(int destChannel, int destStartSample, const Type *source, int numSamples, Type gainToApplyToSource=Type(1)) noexcept
Definition: juce_AudioSampleBuffer.h:748
juce::AudioBuffer::applyGainRamp
void applyGainRamp(int startSample, int numSamples, Type startGain, Type endGain) noexcept
Definition: juce_AudioSampleBuffer.h:679
juce::AudioBuffer::getArrayOfWritePointers
Type ** getArrayOfWritePointers() noexcept
Definition: juce_AudioSampleBuffer.h:306
juce::AudioBuffer::applyGain
void applyGain(int channel, int startSample, int numSamples, Type gain) noexcept
Definition: juce_AudioSampleBuffer.h:602
juce::FloatVectorOperations::multiply
static void JUCE_CALLTYPE multiply(float *dest, const float *src, int numValues) noexcept
Definition: juce_FloatVectorOperations.cpp:754
juce::FloatVectorOperations::clear
static void JUCE_CALLTYPE clear(float *dest, int numValues) noexcept
Definition: juce_FloatVectorOperations.cpp:502
juce::FloatVectorOperations::copyWithMultiply
static void JUCE_CALLTYPE copyWithMultiply(float *dest, const float *src, float multiplier, int numValues) noexcept
Definition: juce_FloatVectorOperations.cpp:550
juce::FloatVectorOperations::copy
static void JUCE_CALLTYPE copy(float *dest, const float *src, int numValues) noexcept
Definition: juce_FloatVectorOperations.cpp:540
juce::FloatVectorOperations::addWithMultiply
static void JUCE_CALLTYPE addWithMultiply(float *dest, const float *src, float multiplier, int numValues) noexcept
Definition: juce_FloatVectorOperations.cpp:682
juce::FloatVectorOperations::findMinAndMax
static Range< float > JUCE_CALLTYPE findMinAndMax(const float *src, int numValues) noexcept
Definition: juce_FloatVectorOperations.cpp:977
juce::FloatVectorOperations::add
static void JUCE_CALLTYPE add(float *dest, float amountToAdd, int numValues) noexcept
Definition: juce_FloatVectorOperations.cpp:572
juce::HeapBlock
Definition: juce_HeapBlock.h:87
juce::HeapBlock::clear
void clear(SizeType numElements) noexcept
Definition: juce_HeapBlock.h:320
juce::HeapBlock::swapWith
void swapWith(HeapBlock< ElementType, otherBlockThrows > &other) noexcept
Definition: juce_HeapBlock.h:310
juce::HeapBlock::malloc
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Definition: juce_HeapBlock.h:252
juce::HeapBlock::get
ElementType * get() const noexcept
Definition: juce_HeapBlock.h:188
juce::HeapBlock::allocate
void allocate(SizeType newNumElements, bool initialiseToZero)
Definition: juce_HeapBlock.h:275
juce::HeapBlock::free
void free() noexcept
Definition: juce_HeapBlock.h:300
juce::Range
Definition: juce_Range.h:40