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