OpenShot Audio Library | OpenShotAudio 0.4.0
juce_AudioBlock.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce::dsp
27{
28
29#ifndef DOXYGEN
30namespace SampleTypeHelpers // Internal classes needed for handling sample type classes
31{
32 template <typename T, bool = std::is_floating_point_v<T>>
33 struct ElementType
34 {
35 using Type = T;
36 };
37
38 template <typename T>
39 struct ElementType<const T, false>
40 {
41 using Type = const typename T::value_type;
42 };
43
44 template <typename T>
45 struct ElementType<T, false>
46 {
47 using Type = typename T::value_type;
48 };
49}
50#endif
51
52//==============================================================================
66template <typename SampleType>
68{
69private:
70 template <typename OtherSampleType>
71 using MayUseConvertingConstructor =
72 std::enable_if_t<std::is_same_v<std::remove_const_t<SampleType>,
73 std::remove_const_t<OtherSampleType>>
74 && std::is_const_v<SampleType>
75 && ! std::is_const_v<OtherSampleType>,
76 int>;
77
78public:
79 //==============================================================================
80 using NumericType = typename SampleTypeHelpers::ElementType<SampleType>::Type;
81
82 //==============================================================================
84 AudioBlock() noexcept = default;
85
91 constexpr AudioBlock (SampleType* const* channelData,
92 size_t numberOfChannels, size_t numberOfSamples) noexcept
93 : channels (channelData),
94 numChannels (static_cast<ChannelCountType> (numberOfChannels)),
95 numSamples (numberOfSamples)
96 {
97 }
98
104 constexpr AudioBlock (SampleType* const* channelData, size_t numberOfChannels,
105 size_t startSampleIndex, size_t numberOfSamples) noexcept
106 : channels (channelData),
107 numChannels (static_cast<ChannelCountType> (numberOfChannels)),
108 startSample (startSampleIndex),
109 numSamples (numberOfSamples)
110 {
111 }
112
118 AudioBlock (HeapBlock<char>& heapBlockToUseForAllocation,
119 size_t numberOfChannels, size_t numberOfSamples,
120 size_t alignmentInBytes = defaultAlignment) noexcept
121 : numChannels (static_cast<ChannelCountType> (numberOfChannels)),
122 numSamples (numberOfSamples)
123 {
124 auto roundedUpNumSamples = (numberOfSamples + elementMask) & ~elementMask;
125 auto channelSize = sizeof (SampleType) * roundedUpNumSamples;
126 auto channelListBytes = sizeof (SampleType*) * numberOfChannels;
127 auto extraBytes = alignmentInBytes - 1;
128
129 heapBlockToUseForAllocation.malloc (channelListBytes + extraBytes + channelSize * numberOfChannels);
130
131 auto* chanArray = unalignedPointerCast<SampleType**> (heapBlockToUseForAllocation.getData());
132 channels = chanArray;
133
134 auto* data = unalignedPointerCast<SampleType*> (addBytesToPointer (chanArray, channelListBytes));
135 data = snapPointerToAlignment (data, alignmentInBytes);
136
137 for (ChannelCountType i = 0; i < numChannels; ++i)
138 {
139 chanArray[i] = data;
140 data += roundedUpNumSamples;
141 }
142 }
143
149 template <typename OtherSampleType>
150 constexpr AudioBlock (AudioBuffer<OtherSampleType>& buffer) noexcept
151 : channels (buffer.getArrayOfWritePointers()),
152 numChannels (static_cast<ChannelCountType> (buffer.getNumChannels())),
153 numSamples (static_cast<size_t> (buffer.getNumSamples()))
154 {
155 }
156
162 template <typename OtherSampleType>
163 constexpr AudioBlock (const AudioBuffer<OtherSampleType>& buffer) noexcept
164 : channels (buffer.getArrayOfReadPointers()),
165 numChannels (static_cast<ChannelCountType> (buffer.getNumChannels())),
166 numSamples (static_cast<size_t> (buffer.getNumSamples()))
167 {
168 }
169
175 template <typename OtherSampleType>
176 AudioBlock (AudioBuffer<OtherSampleType>& buffer, size_t startSampleIndex) noexcept
177 : channels (buffer.getArrayOfWritePointers()),
178 numChannels (static_cast<ChannelCountType> (buffer.getNumChannels())),
179 startSample (startSampleIndex),
180 numSamples (static_cast<size_t> (buffer.getNumSamples()) - startSampleIndex)
181 {
182 jassert (startSample < static_cast<size_t> (buffer.getNumSamples()));
183 }
184
185 AudioBlock (const AudioBlock& other) noexcept = default;
186 AudioBlock& operator= (const AudioBlock& other) noexcept = default;
187
188 template <typename OtherSampleType, MayUseConvertingConstructor<OtherSampleType> = 0>
189 AudioBlock (const AudioBlock<OtherSampleType>& other) noexcept
190 : channels { other.channels },
191 numChannels { other.numChannels },
192 startSample { other.startSample },
193 numSamples { other.numSamples }
194 {
195 }
196
197 template <typename OtherSampleType, MayUseConvertingConstructor<OtherSampleType> = 0>
198 AudioBlock& operator= (const AudioBlock<OtherSampleType>& other) noexcept
199 {
200 AudioBlock blockCopy { other };
201 swap (blockCopy);
202 return *this;
203 }
204
205 void swap (AudioBlock& other) noexcept
206 {
207 std::swap (other.channels, channels);
208 std::swap (other.numChannels, numChannels);
209 std::swap (other.startSample, startSample);
210 std::swap (other.numSamples, numSamples);
211 }
212
213 //==============================================================================
214 template <typename OtherSampleType>
215 constexpr bool operator== (const AudioBlock<OtherSampleType>& other) const noexcept
216 {
217 return std::equal (channels,
218 channels + numChannels,
219 other.channels,
220 other.channels + other.numChannels)
221 && startSample == other.startSample
222 && numSamples == other.numSamples;
223 }
224
225 template <typename OtherSampleType>
226 constexpr bool operator!= (const AudioBlock<OtherSampleType>& other) const noexcept
227 {
228 return ! (*this == other);
229 }
230
231 //==============================================================================
233 constexpr size_t getNumChannels() const noexcept { return static_cast<size_t> (numChannels); }
234
236 constexpr size_t getNumSamples() const noexcept { return numSamples; }
237
239 SampleType* getChannelPointer (size_t channel) const noexcept
240 {
241 jassert (channel < numChannels);
242 jassert (numSamples > 0);
243 return channels[channel] + startSample;
244 }
245
247 AudioBlock getSingleChannelBlock (size_t channel) const noexcept
248 {
249 jassert (channel < numChannels);
250 return AudioBlock (channels + channel, 1, startSample, numSamples);
251 }
252
257 AudioBlock getSubsetChannelBlock (size_t channelStart, size_t numChannelsToUse) const noexcept
258 {
259 jassert (channelStart < numChannels);
260 jassert ((channelStart + numChannelsToUse) <= numChannels);
261
262 return AudioBlock (channels + channelStart, numChannelsToUse, startSample, numSamples);
263 }
264
270 SampleType getSample (int channel, int sampleIndex) const noexcept
271 {
272 jassert (isPositiveAndBelow (channel, numChannels));
273 jassert (isPositiveAndBelow (sampleIndex, numSamples));
274 return channels[channel][(size_t) startSample + (size_t) sampleIndex];
275 }
276
282 void setSample (int destChannel, int destSample, SampleType newValue) const noexcept
283 {
284 jassert (isPositiveAndBelow (destChannel, numChannels));
285 jassert (isPositiveAndBelow (destSample, numSamples));
286 channels[destChannel][(size_t) startSample + (size_t) destSample] = newValue;
287 }
288
294 void addSample (int destChannel, int destSample, SampleType valueToAdd) const noexcept
295 {
296 jassert (isPositiveAndBelow (destChannel, numChannels));
297 jassert (isPositiveAndBelow (destSample, numSamples));
298 channels[destChannel][(size_t) startSample + (size_t) destSample] += valueToAdd;
299 }
300
301 //==============================================================================
303 AudioBlock& clear() noexcept { clearInternal(); return *this; }
304 const AudioBlock& clear() const noexcept { clearInternal(); return *this; }
305
307 AudioBlock& JUCE_VECTOR_CALLTYPE fill (NumericType value) noexcept { fillInternal (value); return *this; }
308 const AudioBlock& JUCE_VECTOR_CALLTYPE fill (NumericType value) const noexcept { fillInternal (value); return *this; }
309
311 template <typename OtherSampleType>
312 AudioBlock& copyFrom (const AudioBlock<OtherSampleType>& src) noexcept { copyFromInternal (src); return *this; }
313 template <typename OtherSampleType>
314 const AudioBlock& copyFrom (const AudioBlock<OtherSampleType>& src) const noexcept { copyFromInternal (src); return *this; }
315
322 template <typename OtherNumericType>
324 size_t srcPos = 0, size_t dstPos = 0,
325 size_t numElements = std::numeric_limits<size_t>::max()) { copyFromInternal (src, srcPos, dstPos, numElements); return *this; }
326 template <typename OtherNumericType>
328 size_t srcPos = 0, size_t dstPos = 0,
329 size_t numElements = std::numeric_limits<size_t>::max()) const { copyFromInternal (src, srcPos, dstPos, numElements); return *this; }
330
331
338 void copyTo (AudioBuffer<std::remove_const_t<NumericType>>& dst, size_t srcPos = 0, size_t dstPos = 0,
339 size_t numElements = std::numeric_limits<size_t>::max()) const
340 {
341 auto dstlen = static_cast<size_t> (dst.getNumSamples()) / sizeFactor;
342 auto n = jmin (numSamples - srcPos, dstlen - dstPos, numElements) * sizeFactor;
343 auto maxChannels = jmin (static_cast<size_t> (dst.getNumChannels()), static_cast<size_t> (numChannels));
344
345 for (size_t ch = 0; ch < maxChannels; ++ch)
346 FloatVectorOperations::copy (dst.getWritePointer ((int) ch, (int) (dstPos * sizeFactor)),
347 getDataPointer (ch) + (srcPos * sizeFactor),
348 n);
349 }
350
354 AudioBlock& move (size_t srcPos, size_t dstPos,
355 size_t numElements = std::numeric_limits<size_t>::max()) noexcept { moveInternal (srcPos, dstPos, numElements); return *this; }
356 const AudioBlock& move (size_t srcPos, size_t dstPos,
357 size_t numElements = std::numeric_limits<size_t>::max()) const noexcept { moveInternal (srcPos, dstPos, numElements); return *this; }
358
359 //==============================================================================
369 AudioBlock getSubBlock (size_t newOffset, size_t newLength) const noexcept
370 {
371 jassert (newOffset < numSamples);
372 jassert (newOffset + newLength <= numSamples);
373
374 return AudioBlock (channels, numChannels, startSample + newOffset, newLength);
375 }
376
387 AudioBlock getSubBlock (size_t newOffset) const noexcept
388 {
389 return getSubBlock (newOffset, getNumSamples() - newOffset);
390 }
391
392 //==============================================================================
394 AudioBlock& JUCE_VECTOR_CALLTYPE add (NumericType value) noexcept { addInternal (value); return *this; }
395 const AudioBlock& JUCE_VECTOR_CALLTYPE add (NumericType value) const noexcept { addInternal (value); return *this; }
396
398 template <typename OtherSampleType>
399 AudioBlock& add (AudioBlock<OtherSampleType> src) noexcept { addInternal (src); return *this; }
400 template <typename OtherSampleType>
401 const AudioBlock& add (AudioBlock<OtherSampleType> src) const noexcept { addInternal (src); return *this; }
402
404 template <typename OtherSampleType>
405 AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithSumOf (AudioBlock<OtherSampleType> src, NumericType value) noexcept { replaceWithSumOfInternal (src, value); return *this; }
406 template <typename OtherSampleType>
407 const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithSumOf (AudioBlock<OtherSampleType> src, NumericType value) const noexcept { replaceWithSumOfInternal (src, value); return *this; }
408
410 template <typename Src1SampleType, typename Src2SampleType>
411 AudioBlock& replaceWithSumOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithSumOfInternal (src1, src2); return *this; }
412 template <typename Src1SampleType, typename Src2SampleType>
413 const AudioBlock& replaceWithSumOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithSumOfInternal (src1, src2); return *this; }
414
415 //==============================================================================
417 AudioBlock& JUCE_VECTOR_CALLTYPE subtract (NumericType value) noexcept { subtractInternal (value); return *this; }
418 const AudioBlock& JUCE_VECTOR_CALLTYPE subtract (NumericType value) const noexcept { subtractInternal (value); return *this; }
419
421 template <typename OtherSampleType>
422 AudioBlock& subtract (AudioBlock<OtherSampleType> src) noexcept { subtractInternal (src); return *this; }
423 template <typename OtherSampleType>
424 const AudioBlock& subtract (AudioBlock<OtherSampleType> src) const noexcept { subtractInternal (src); return *this; }
425
427 template <typename OtherSampleType>
428 AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf (AudioBlock<OtherSampleType> src, NumericType value) noexcept { replaceWithDifferenceOfInternal (src, value); return *this; }
429 template <typename OtherSampleType>
430 const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf (AudioBlock<OtherSampleType> src, NumericType value) const noexcept { replaceWithDifferenceOfInternal (src, value); return *this; }
431
433 template <typename Src1SampleType, typename Src2SampleType>
434 AudioBlock& replaceWithDifferenceOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithDifferenceOfInternal (src1, src2); return *this; }
435 template <typename Src1SampleType, typename Src2SampleType>
436 const AudioBlock& replaceWithDifferenceOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithDifferenceOfInternal (src1, src2); return *this; }
437
438 //==============================================================================
440 AudioBlock& JUCE_VECTOR_CALLTYPE multiplyBy (NumericType value) noexcept { multiplyByInternal (value); return *this; }
441 const AudioBlock& JUCE_VECTOR_CALLTYPE multiplyBy (NumericType value) const noexcept { multiplyByInternal (value); return *this; }
442
444 template <typename OtherSampleType>
445 AudioBlock& multiplyBy (AudioBlock<OtherSampleType> src) noexcept { multiplyByInternal (src); return *this; }
446 template <typename OtherSampleType>
447 const AudioBlock& multiplyBy (AudioBlock<OtherSampleType> src) const noexcept { multiplyByInternal (src); return *this; }
448
450 template <typename OtherSampleType>
451 AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithProductOf (AudioBlock<OtherSampleType> src, NumericType value) noexcept { replaceWithProductOfInternal (src, value); return *this; }
452 template <typename OtherSampleType>
453 const AudioBlock& JUCE_VECTOR_CALLTYPE replaceWithProductOf (AudioBlock<OtherSampleType> src, NumericType value) const noexcept { replaceWithProductOfInternal (src, value); return *this; }
454
456 template <typename Src1SampleType, typename Src2SampleType>
457 AudioBlock& replaceWithProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithProductOfInternal (src1, src2); return *this; }
458 template <typename Src1SampleType, typename Src2SampleType>
459 const AudioBlock& replaceWithProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithProductOfInternal (src1, src2); return *this; }
460
461 //==============================================================================
463 template <typename OtherSampleType, typename SmoothingType>
464 AudioBlock& multiplyBy (SmoothedValue<OtherSampleType, SmoothingType>& value) noexcept { multiplyByInternal (value); return *this; }
465 template <typename OtherSampleType, typename SmoothingType>
466 const AudioBlock& multiplyBy (SmoothedValue<OtherSampleType, SmoothingType>& value) const noexcept { multiplyByInternal (value); return *this; }
467
469 template <typename BlockSampleType, typename SmootherSampleType, typename SmoothingType>
470 AudioBlock& replaceWithProductOf (AudioBlock<BlockSampleType> src, SmoothedValue<SmootherSampleType, SmoothingType>& value) noexcept { replaceWithProductOfInternal (src, value); return *this; }
471 template <typename BlockSampleType, typename SmootherSampleType, typename SmoothingType>
472 const AudioBlock& replaceWithProductOf (AudioBlock<BlockSampleType> src, SmoothedValue<SmootherSampleType, SmoothingType>& value) const noexcept { replaceWithProductOfInternal (src, value); return *this; }
473
474 //==============================================================================
476 template <typename OtherSampleType>
477 AudioBlock& JUCE_VECTOR_CALLTYPE addProductOf (AudioBlock<OtherSampleType> src, NumericType factor) noexcept { addProductOfInternal (src, factor); return *this; }
478 template <typename OtherSampleType>
479 const AudioBlock& JUCE_VECTOR_CALLTYPE addProductOf (AudioBlock<OtherSampleType> src, NumericType factor) const noexcept { addProductOfInternal (src, factor); return *this; }
480
482 template <typename Src1SampleType, typename Src2SampleType>
483 AudioBlock& addProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { addProductOfInternal (src1, src2); return *this; }
484 template <typename Src1SampleType, typename Src2SampleType>
485 const AudioBlock& addProductOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { addProductOfInternal (src1, src2); return *this; }
486
487 //==============================================================================
489 AudioBlock& negate() noexcept { negateInternal(); return *this; }
490 const AudioBlock& negate() const noexcept { negateInternal(); return *this; }
491
493 template <typename OtherSampleType>
494 AudioBlock& replaceWithNegativeOf (AudioBlock<OtherSampleType> src) noexcept { replaceWithNegativeOfInternal (src); return *this; }
495 template <typename OtherSampleType>
496 const AudioBlock& replaceWithNegativeOf (AudioBlock<OtherSampleType> src) const noexcept { replaceWithNegativeOfInternal (src); return *this; }
497
499 template <typename OtherSampleType>
500 AudioBlock& replaceWithAbsoluteValueOf (AudioBlock<OtherSampleType> src) noexcept { replaceWithAbsoluteValueOfInternal (src); return *this; }
501 template <typename OtherSampleType>
502 const AudioBlock& replaceWithAbsoluteValueOf (AudioBlock<OtherSampleType> src) const noexcept { replaceWithAbsoluteValueOfInternal (src); return *this; }
503
504 //==============================================================================
506 template <typename Src1SampleType, typename Src2SampleType>
507 AudioBlock& replaceWithMinOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithMinOfInternal (src1, src2); return *this; }
508 template <typename Src1SampleType, typename Src2SampleType>
509 const AudioBlock& replaceWithMinOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithMinOfInternal (src1, src2); return *this; }
510
512 template <typename Src1SampleType, typename Src2SampleType>
513 AudioBlock& replaceWithMaxOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) noexcept { replaceWithMaxOfInternal (src1, src2); return *this; }
514 template <typename Src1SampleType, typename Src2SampleType>
515 const AudioBlock& replaceWithMaxOf (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept { replaceWithMaxOfInternal (src1, src2); return *this; }
516
517 //==============================================================================
520 {
521 if (numChannels == 0)
522 return {};
523
524 auto n = numSamples * sizeFactor;
525 auto minmax = FloatVectorOperations::findMinAndMax (getDataPointer (0), n);
526
527 for (size_t ch = 1; ch < numChannels; ++ch)
528 minmax = minmax.getUnionWith (FloatVectorOperations::findMinAndMax (getDataPointer (ch), n));
529
530 return minmax;
531 }
532
533 //==============================================================================
534 // Convenient operator wrappers.
535 AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (NumericType value) noexcept { return add (value); }
536 const AudioBlock& JUCE_VECTOR_CALLTYPE operator+= (NumericType value) const noexcept { return add (value); }
537
538 AudioBlock& operator+= (AudioBlock src) noexcept { return add (src); }
539 const AudioBlock& operator+= (AudioBlock src) const noexcept { return add (src); }
540
541 AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (NumericType value) noexcept { return subtract (value); }
542 const AudioBlock& JUCE_VECTOR_CALLTYPE operator-= (NumericType value) const noexcept { return subtract (value); }
543
544 AudioBlock& operator-= (AudioBlock src) noexcept { return subtract (src); }
545 const AudioBlock& operator-= (AudioBlock src) const noexcept { return subtract (src); }
546
547 AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (NumericType value) noexcept { return multiplyBy (value); }
548 const AudioBlock& JUCE_VECTOR_CALLTYPE operator*= (NumericType value) const noexcept { return multiplyBy (value); }
549
550 AudioBlock& operator*= (AudioBlock src) noexcept { return multiplyBy (src); }
551 const AudioBlock& operator*= (AudioBlock src) const noexcept { return multiplyBy (src); }
552
553 template <typename OtherSampleType, typename SmoothingType>
554 AudioBlock& operator*= (SmoothedValue<OtherSampleType, SmoothingType>& value) noexcept { return multiplyBy (value); }
555 template <typename OtherSampleType, typename SmoothingType>
556 const AudioBlock& operator*= (SmoothedValue<OtherSampleType, SmoothingType>& value) const noexcept { return multiplyBy (value); }
557
558 //==============================================================================
559 // This class can only be used with floating point types
560 static_assert (std::is_same_v<std::remove_const_t<SampleType>, float>
561 || std::is_same_v<std::remove_const_t<SampleType>, double>
562 #if JUCE_USE_SIMD
563 || std::is_same_v<std::remove_const_t<SampleType>, SIMDRegister<float>>
564 || std::is_same_v<std::remove_const_t<SampleType>, SIMDRegister<double>>
565 #endif
566 , "AudioBlock only supports single or double precision floating point types");
567
568 //==============================================================================
573 template <typename Src1SampleType, typename Src2SampleType, typename FunctionType>
574 static void process (AudioBlock<Src1SampleType> inBlock, AudioBlock<Src2SampleType> outBlock, FunctionType&& function)
575 {
576 auto len = inBlock.getNumSamples();
577 auto numChans = inBlock.getNumChannels();
578
579 jassert (len == outBlock.getNumSamples());
580 jassert (numChans == outBlock.getNumChannels());
581
582 for (ChannelCountType c = 0; c < numChans; ++c)
583 {
584 auto* src = inBlock.getChannelPointer (c);
585 auto* dst = outBlock.getChannelPointer (c);
586
587 for (size_t i = 0; i < len; ++i)
588 dst[i] = function (src[i]);
589 }
590 }
591
592private:
593 NumericType* getDataPointer (size_t channel) const noexcept
594 {
595 return reinterpret_cast<NumericType*> (getChannelPointer (channel));
596 }
597
598 //==============================================================================
599 void JUCE_VECTOR_CALLTYPE clearInternal() const noexcept
600 {
601 auto n = numSamples * sizeFactor;
602
603 for (size_t ch = 0; ch < numChannels; ++ch)
604 FloatVectorOperations::clear (getDataPointer (ch), n);
605 }
606
607 void JUCE_VECTOR_CALLTYPE fillInternal (NumericType value) const noexcept
608 {
609 auto n = numSamples * sizeFactor;
610
611 for (size_t ch = 0; ch < numChannels; ++ch)
612 FloatVectorOperations::fill (getDataPointer (ch), value, n);
613 }
614
615 template <typename OtherSampleType>
616 void copyFromInternal (const AudioBlock<OtherSampleType>& src) const noexcept
617 {
618 auto maxChannels = jmin (src.numChannels, numChannels);
619 auto n = jmin (src.numSamples * src.sizeFactor, numSamples * sizeFactor);
620
621 for (size_t ch = 0; ch < maxChannels; ++ch)
622 FloatVectorOperations::copy (getDataPointer (ch), src.getDataPointer (ch), n);
623 }
624
625 template <typename OtherNumericType>
626 void copyFromInternal (const AudioBuffer<OtherNumericType>& src, size_t srcPos, size_t dstPos, size_t numElements) const
627 {
628 auto srclen = static_cast<size_t> (src.getNumSamples()) / sizeFactor;
629 auto n = jmin (srclen - srcPos, numSamples - dstPos, numElements) * sizeFactor;
630 auto maxChannels = jmin (static_cast<size_t> (src.getNumChannels()), static_cast<size_t> (numChannels));
631
632 for (size_t ch = 0; ch < maxChannels; ++ch)
633 FloatVectorOperations::copy (getDataPointer (ch) + (dstPos * sizeFactor),
634 src.getReadPointer ((int) ch, (int) (srcPos * sizeFactor)),
635 n);
636 }
637
638 void moveInternal (size_t srcPos, size_t dstPos,
639 size_t numElements = std::numeric_limits<size_t>::max()) const noexcept
640 {
641 jassert (srcPos <= numSamples && dstPos <= numSamples);
642 auto len = jmin (numSamples - srcPos, numSamples - dstPos, numElements) * sizeof (SampleType);
643
644 if (len != 0)
645 for (size_t ch = 0; ch < numChannels; ++ch)
646 ::memmove (getChannelPointer (ch) + dstPos,
647 getChannelPointer (ch) + srcPos, len);
648 }
649
650 //==============================================================================
651 void JUCE_VECTOR_CALLTYPE addInternal (NumericType value) const noexcept
652 {
653 auto n = numSamples * sizeFactor;
654
655 for (size_t ch = 0; ch < numChannels; ++ch)
656 FloatVectorOperations::add (getDataPointer (ch), value, n);
657 }
658
659 template <typename OtherSampleType>
660 void addInternal (AudioBlock<OtherSampleType> src) const noexcept
661 {
662 jassert (numChannels == src.numChannels);
663 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
664
665 for (size_t ch = 0; ch < numChannels; ++ch)
666 FloatVectorOperations::add (getDataPointer (ch), src.getDataPointer (ch), n);
667 }
668
669 template <typename OtherSampleType>
670 void JUCE_VECTOR_CALLTYPE replaceWithSumOfInternal (AudioBlock<OtherSampleType> src, NumericType value) const noexcept
671 {
672 jassert (numChannels == src.numChannels);
673 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
674
675 for (size_t ch = 0; ch < numChannels; ++ch)
676 FloatVectorOperations::add (getDataPointer (ch), src.getDataPointer (ch), value, n);
677 }
678
679 template <typename Src1SampleType, typename Src2SampleType>
680 void replaceWithSumOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
681 {
682 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
683 auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
684
685 for (size_t ch = 0; ch < numChannels; ++ch)
686 FloatVectorOperations::add (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
687 }
688
689 //==============================================================================
690 constexpr void JUCE_VECTOR_CALLTYPE subtractInternal (NumericType value) const noexcept
691 {
692 addInternal (value * static_cast<NumericType> (-1.0));
693 }
694
695 template <typename OtherSampleType>
696 void subtractInternal (AudioBlock<OtherSampleType> src) const noexcept
697 {
698 jassert (numChannels == src.numChannels);
699 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
700
701 for (size_t ch = 0; ch < numChannels; ++ch)
702 FloatVectorOperations::subtract (getDataPointer (ch), src.getDataPointer (ch), n);
703 }
704
705 template <typename OtherSampleType>
706 void JUCE_VECTOR_CALLTYPE replaceWithDifferenceOfInternal (AudioBlock<OtherSampleType> src, NumericType value) const noexcept
707 {
708 replaceWithSumOfInternal (src, static_cast<NumericType> (-1.0) * value);
709 }
710
711 template <typename Src1SampleType, typename Src2SampleType>
712 void replaceWithDifferenceOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
713 {
714 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
715 auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
716
717 for (size_t ch = 0; ch < numChannels; ++ch)
718 FloatVectorOperations::subtract (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
719 }
720
721 //==============================================================================
722 void JUCE_VECTOR_CALLTYPE multiplyByInternal (NumericType value) const noexcept
723 {
724 auto n = numSamples * sizeFactor;
725
726 for (size_t ch = 0; ch < numChannels; ++ch)
727 FloatVectorOperations::multiply (getDataPointer (ch), value, n);
728 }
729
730 template <typename OtherSampleType>
731 void multiplyByInternal (AudioBlock<OtherSampleType> src) const noexcept
732 {
733 jassert (numChannels == src.numChannels);
734 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
735
736 for (size_t ch = 0; ch < numChannels; ++ch)
737 FloatVectorOperations::multiply (getDataPointer (ch), src.getDataPointer (ch), n);
738 }
739
740 template <typename OtherSampleType>
741 void JUCE_VECTOR_CALLTYPE replaceWithProductOfInternal (AudioBlock<OtherSampleType> src, NumericType value) const noexcept
742 {
743 jassert (numChannels == src.numChannels);
744 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
745
746 for (size_t ch = 0; ch < numChannels; ++ch)
747 FloatVectorOperations::multiply (getDataPointer (ch), src.getDataPointer (ch), value, n);
748 }
749
750 template <typename Src1SampleType, typename Src2SampleType>
751 void replaceWithProductOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
752 {
753 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
754 auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
755
756 for (size_t ch = 0; ch < numChannels; ++ch)
757 FloatVectorOperations::multiply (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
758 }
759
760 template <typename OtherSampleType, typename SmoothingType>
761 void multiplyByInternal (SmoothedValue<OtherSampleType, SmoothingType>& value) const noexcept
762 {
763 if (! value.isSmoothing())
764 {
765 multiplyByInternal ((NumericType) value.getTargetValue());
766 }
767 else
768 {
769 for (size_t i = 0; i < numSamples; ++i)
770 {
771 const auto scaler = (NumericType) value.getNextValue();
772
773 for (size_t ch = 0; ch < numChannels; ++ch)
774 getDataPointer (ch)[i] *= scaler;
775 }
776 }
777 }
778
779 template <typename BlockSampleType, typename SmootherSampleType, typename SmoothingType>
780 void replaceWithProductOfInternal (AudioBlock<BlockSampleType> src, SmoothedValue<SmootherSampleType, SmoothingType>& value) const noexcept
781 {
782 jassert (numChannels == src.numChannels);
783
784 if (! value.isSmoothing())
785 {
786 replaceWithProductOfInternal (src, (NumericType) value.getTargetValue());
787 }
788 else
789 {
790 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
791
792 for (size_t i = 0; i < n; ++i)
793 {
794 const auto scaler = (NumericType) value.getNextValue();
795
796 for (size_t ch = 0; ch < numChannels; ++ch)
797 getDataPointer (ch)[i] = scaler * src.getChannelPointer (ch)[i];
798 }
799 }
800 }
801
802 //==============================================================================
803 template <typename OtherSampleType>
804 void JUCE_VECTOR_CALLTYPE addProductOfInternal (AudioBlock<OtherSampleType> src, NumericType factor) const noexcept
805 {
806 jassert (numChannels == src.numChannels);
807 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
808
809 for (size_t ch = 0; ch < numChannels; ++ch)
810 FloatVectorOperations::addWithMultiply (getDataPointer (ch), src.getDataPointer (ch), factor, n);
811 }
812
813 template <typename Src1SampleType, typename Src2SampleType>
814 void addProductOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
815 {
816 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
817 auto n = jmin (numSamples, src1.numSamples, src2.numSamples) * sizeFactor;
818
819 for (size_t ch = 0; ch < numChannels; ++ch)
820 FloatVectorOperations::addWithMultiply (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
821 }
822
823 //==============================================================================
824 constexpr void negateInternal() const noexcept
825 {
826 multiplyByInternal (static_cast<NumericType> (-1.0));
827 }
828
829 template <typename OtherSampleType>
830 void replaceWithNegativeOfInternal (AudioBlock<OtherSampleType> src) const noexcept
831 {
832 jassert (numChannels == src.numChannels);
833 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
834
835 for (size_t ch = 0; ch < numChannels; ++ch)
836 FloatVectorOperations::negate (getDataPointer (ch), src.getDataPointer (ch), n);
837 }
838
839 template <typename OtherSampleType>
840 void replaceWithAbsoluteValueOfInternal (AudioBlock<OtherSampleType> src) const noexcept
841 {
842 jassert (numChannels == src.numChannels);
843 auto n = jmin (numSamples, src.numSamples) * sizeFactor;
844
845 for (size_t ch = 0; ch < numChannels; ++ch)
846 FloatVectorOperations::abs (getDataPointer (ch), src.getDataPointer (ch), n);
847 }
848
849 //==============================================================================
850 template <typename Src1SampleType, typename Src2SampleType>
851 void replaceWithMinOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
852 {
853 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
854 auto n = jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor;
855
856 for (size_t ch = 0; ch < numChannels; ++ch)
857 FloatVectorOperations::min (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
858 }
859
860 template <typename Src1SampleType, typename Src2SampleType>
861 void replaceWithMaxOfInternal (AudioBlock<Src1SampleType> src1, AudioBlock<Src2SampleType> src2) const noexcept
862 {
863 jassert (numChannels == src1.numChannels && src1.numChannels == src2.numChannels);
864 auto n = jmin (src1.numSamples, src2.numSamples, numSamples) * sizeFactor;
865
866 for (size_t ch = 0; ch < numChannels; ++ch)
867 FloatVectorOperations::max (getDataPointer (ch), src1.getDataPointer (ch), src2.getDataPointer (ch), n);
868 }
869
870 //==============================================================================
871 using ChannelCountType = unsigned int;
872
873 //==============================================================================
874 static constexpr size_t sizeFactor = sizeof (SampleType) / sizeof (NumericType);
875 static constexpr size_t elementMask = sizeFactor - 1;
876 static constexpr size_t byteMask = (sizeFactor * sizeof (NumericType)) - 1;
877
878 #if JUCE_USE_SIMD
879 static constexpr size_t defaultAlignment = sizeof (SIMDRegister<NumericType>);
880 #else
881 static constexpr size_t defaultAlignment = sizeof (NumericType);
882 #endif
883
884 SampleType* const* channels;
885 ChannelCountType numChannels = 0;
886 size_t startSample = 0, numSamples = 0;
887
888 template <typename OtherSampleType>
889 friend class AudioBlock;
890};
891
892} // namespace juce::dsp
AudioBlock & addProductOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
AudioBlock & copyFrom(const AudioBuffer< OtherNumericType > &src, size_t srcPos=0, size_t dstPos=0, size_t numElements=std::numeric_limits< size_t >::max())
static void process(AudioBlock< Src1SampleType > inBlock, AudioBlock< Src2SampleType > outBlock, FunctionType &&function)
AudioBlock getSubBlock(size_t newOffset, size_t newLength) const noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE subtract(NumericType value) noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithProductOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
AudioBlock getSubsetChannelBlock(size_t channelStart, size_t numChannelsToUse) const noexcept
void setSample(int destChannel, int destSample, SampleType newValue) const noexcept
AudioBlock & replaceWithDifferenceOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
constexpr size_t getNumChannels() const noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithSumOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
AudioBlock & replaceWithMaxOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
void copyTo(AudioBuffer< std::remove_const_t< NumericType > > &dst, size_t srcPos=0, size_t dstPos=0, size_t numElements=std::numeric_limits< size_t >::max()) const
SampleType * getChannelPointer(size_t channel) const noexcept
AudioBlock & negate() noexcept
AudioBlock & replaceWithNegativeOf(AudioBlock< OtherSampleType > src) noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
AudioBlock & replaceWithSumOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
AudioBlock(AudioBuffer< OtherSampleType > &buffer, size_t startSampleIndex) noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE multiplyBy(NumericType value) noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE add(NumericType value) noexcept
constexpr AudioBlock(AudioBuffer< OtherSampleType > &buffer) noexcept
AudioBlock & add(AudioBlock< OtherSampleType > src) noexcept
AudioBlock & move(size_t srcPos, size_t dstPos, size_t numElements=std::numeric_limits< size_t >::max()) noexcept
AudioBlock & replaceWithProductOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
AudioBlock & multiplyBy(SmoothedValue< OtherSampleType, SmoothingType > &value) noexcept
AudioBlock & replaceWithAbsoluteValueOf(AudioBlock< OtherSampleType > src) noexcept
AudioBlock & copyFrom(const AudioBlock< OtherSampleType > &src) noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE addProductOf(AudioBlock< OtherSampleType > src, NumericType factor) noexcept
AudioBlock getSingleChannelBlock(size_t channel) const noexcept
constexpr AudioBlock(const AudioBuffer< OtherSampleType > &buffer) noexcept
SampleType getSample(int channel, int sampleIndex) const noexcept
AudioBlock & subtract(AudioBlock< OtherSampleType > src) noexcept
AudioBlock getSubBlock(size_t newOffset) const noexcept
AudioBlock & replaceWithMinOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
constexpr size_t getNumSamples() const noexcept
void addSample(int destChannel, int destSample, SampleType valueToAdd) const noexcept
AudioBlock & clear() noexcept
AudioBlock() noexcept=default
AudioBlock &JUCE_VECTOR_CALLTYPE fill(NumericType value) noexcept
constexpr AudioBlock(SampleType *const *channelData, size_t numberOfChannels, size_t startSampleIndex, size_t numberOfSamples) noexcept
AudioBlock(HeapBlock< char > &heapBlockToUseForAllocation, size_t numberOfChannels, size_t numberOfSamples, size_t alignmentInBytes=defaultAlignment) noexcept
AudioBlock & replaceWithProductOf(AudioBlock< BlockSampleType > src, SmoothedValue< SmootherSampleType, SmoothingType > &value) noexcept
Range< std::remove_const_t< NumericType > > findMinAndMax() const noexcept
AudioBlock & multiplyBy(AudioBlock< OtherSampleType > src) noexcept