OpenShot Audio Library | OpenShotAudio  0.6.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 
26 namespace juce::dsp
27 {
28 
29 #ifndef DOXYGEN
30 namespace 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 //==============================================================================
66 template <typename SampleType>
68 {
69 private:
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 
78 public:
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 
592 private:
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 & move(size_t srcPos, size_t dstPos, size_t numElements=std::numeric_limits< size_t >::max()) 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
AudioBlock & replaceWithAbsoluteValueOf(AudioBlock< OtherSampleType > src) noexcept
static void process(AudioBlock< Src1SampleType > inBlock, AudioBlock< Src2SampleType > outBlock, FunctionType &&function)
AudioBlock & replaceWithMinOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
AudioBlock getSubBlock(size_t newOffset, size_t newLength) const noexcept
SampleType * getChannelPointer(size_t channel) const noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE fill(NumericType value) noexcept
AudioBlock getSubsetChannelBlock(size_t channelStart, size_t numChannelsToUse) const noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithSumOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
void setSample(int destChannel, int destSample, SampleType newValue) const noexcept
constexpr size_t getNumChannels() const noexcept
AudioBlock & multiplyBy(AudioBlock< OtherSampleType > src) noexcept
AudioBlock & replaceWithDifferenceOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
AudioBlock & subtract(AudioBlock< OtherSampleType > src) noexcept
AudioBlock(AudioBuffer< OtherSampleType > &buffer, size_t startSampleIndex) noexcept
constexpr AudioBlock(AudioBuffer< OtherSampleType > &buffer) noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithProductOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
AudioBlock & add(AudioBlock< OtherSampleType > src) noexcept
AudioBlock & negate() noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE add(NumericType value) noexcept
AudioBlock & copyFrom(const AudioBlock< OtherSampleType > &src) noexcept
AudioBlock getSingleChannelBlock(size_t channel) const noexcept
constexpr AudioBlock(const AudioBuffer< OtherSampleType > &buffer) noexcept
SampleType getSample(int channel, int sampleIndex) const noexcept
AudioBlock & replaceWithSumOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
AudioBlock & replaceWithProductOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
AudioBlock & replaceWithProductOf(AudioBlock< BlockSampleType > src, SmoothedValue< SmootherSampleType, SmoothingType > &value) noexcept
AudioBlock getSubBlock(size_t newOffset) const noexcept
AudioBlock & multiplyBy(SmoothedValue< OtherSampleType, SmoothingType > &value) noexcept
AudioBlock & clear() noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE replaceWithDifferenceOf(AudioBlock< OtherSampleType > src, NumericType value) noexcept
constexpr size_t getNumSamples() const noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE subtract(NumericType value) noexcept
Range< std::remove_const_t< NumericType > > findMinAndMax() const noexcept
void addSample(int destChannel, int destSample, SampleType valueToAdd) const noexcept
AudioBlock() noexcept=default
AudioBlock & addProductOf(AudioBlock< Src1SampleType > src1, AudioBlock< Src2SampleType > src2) noexcept
constexpr AudioBlock(SampleType *const *channelData, size_t numberOfChannels, size_t startSampleIndex, size_t numberOfSamples) noexcept
AudioBlock &JUCE_VECTOR_CALLTYPE addProductOf(AudioBlock< OtherSampleType > src, NumericType factor) noexcept
AudioBlock(HeapBlock< char > &heapBlockToUseForAllocation, size_t numberOfChannels, size_t numberOfSamples, size_t alignmentInBytes=defaultAlignment) noexcept
AudioBlock & replaceWithMaxOf(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())
AudioBlock &JUCE_VECTOR_CALLTYPE multiplyBy(NumericType value) noexcept
AudioBlock & replaceWithNegativeOf(AudioBlock< OtherSampleType > src) noexcept