Jamba  3.0.2
AudioBuffer.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 pongasoft
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  *
16  * @author Yan Pujante
17  */
18 #pragma once
19 
20 #include <pluginterfaces/vst/ivstaudioprocessor.h>
21 #include <pongasoft/logging/logging.h>
22 #include <algorithm>
23 
24 #include "AudioUtils.h"
25 
26 namespace pongasoft {
27 namespace VST {
28 
29 using namespace Steinberg;
30 using namespace Steinberg::Vst;
31 
32 // defines the default setup channels (0 is left, 1 is right)
33 constexpr int32 DEFAULT_LEFT_CHANNEL = 0;
34 constexpr int32 DEFAULT_RIGHT_CHANNEL = 1;
35 
41 template<typename SampleType>
43 {
44 public:
45  class Channel
46  {
47  public:
48  Channel(AudioBuffers &iBuffers, int32 iChannel) : fBuffers{iBuffers}, fChannel{iChannel}
49  {
50  }
51 
55  inline int32 getNumSamples() const
56  {
57  return fBuffers.getNumSamples();
58  }
59 
69  inline SampleType *getBuffer() const
70  {
71  return fChannel < fBuffers.getNumChannels() ? fBuffers.getBuffer()[fChannel] : nullptr;
72  }
73 
77  inline bool isSilent() const { return fBuffers.isSilent(fChannel); }
78 
82  inline void setSilenceFlag(bool iSilent)
83  {
84  fBuffers.setSilenceFlag(fChannel, iSilent);
85  }
86 
90  inline bool isActive() const
91  {
92  return fChannel < fBuffers.getNumChannels() && getBuffer() != nullptr;
93  }
94 
98  inline tresult copyTo(Channel &toChannel) const { return toChannel.copyFrom(*this); };
99 
103  tresult copyFrom(Channel const &fromChannel)
104  {
105  int32 numSamples = std::min(getNumSamples(), fromChannel.getNumSamples());
106 
107  auto ptrFrom = fromChannel.getBuffer();
108  auto ptrTo = getBuffer();
109 
110  // sanity check
111  if(!ptrFrom || !ptrTo)
112  return kResultFalse;
113 
114  std::copy(ptrFrom, ptrFrom + numSamples, ptrTo);
115 
116  return kResultOk;
117  }
118 
121  inline void clear()
122  {
123  auto buffer = getBuffer();
124 
125  // sanity check
126  if(!buffer)
127  return;
128 
129  std::fill(buffer, buffer + getNumSamples(), 0);
130 
131  setSilenceFlag(true);
132  }
133 
134  private:
136  int32 fChannel;
137  };
138 
140 
141 
142 public:
143  AudioBuffers(AudioBusBuffers &buffer, int32 numSamples) : fBuffer(buffer), fNumSamples(numSamples)
144  {}
145 
146  // returns true if the buffer is silent (meaning all channels are silent => set to 1) (according to silenceFlags)
147  inline bool isSilent() const
148  {
149  return fBuffer.numChannels == 0 || fBuffer.silenceFlags == (static_cast<uint64>(1) << fBuffer.numChannels) - 1;
150  }
151 
156  inline bool adjustSilenceFlags()
157  {
158  uint64 silenceFlags = 0;
159 
160  auto buffer = getBuffer();
161 
162  for(int32 channel = 0; channel < getNumChannels(); channel++)
163  {
164  bool silent = true;
165 
166  auto ptr = buffer[channel];
167 
168  if(!ptr)
169  continue;
170 
171  for(int j = 0; j < getNumSamples(); ++j, ptr++)
172  {
173  auto sample = *ptr;
174 
175  if(silent && !pongasoft::VST::isSilent(sample))
176  silent = false;
177  }
178 
179  if(silent)
180  BIT_SET(silenceFlags, channel);
181  }
182 
183  fBuffer.silenceFlags = silenceFlags;
184 
185  return isSilent();
186  }
187 
188  // getSilenceFlags
189  inline uint64 getSilenceFlags() const { return fBuffer.silenceFlags; }
190 
191  // setSilenceFlags
192  inline void setSilenceFlags(uint64 iFlags) const { fBuffer.silenceFlags = iFlags; }
193 
197  inline void setSilenceFlag(int32 iChannel, bool iSilent)
198  {
199  if(iChannel < getNumChannels())
200  {
201  if(iSilent)
202  BIT_SET(fBuffer.silenceFlags, iChannel);
203  else
204  BIT_CLEAR(fBuffer.silenceFlags, iChannel);
205  }
206  }
207 
211  inline bool isSilent(int32 iChannel) const
212  {
213  if(iChannel < getNumChannels())
214  {
215  return BIT_TEST(fBuffer.silenceFlags, iChannel);
216  }
217  return true;
218  }
219 
223  inline Channel getAudioChannel(int32 iChannel)
224  {
225  return Channel{*this, iChannel};
226  }
227 
231  inline Channel getLeftChannel() { return getAudioChannel(DEFAULT_LEFT_CHANNEL); }
232 
236  inline Channel getRightChannel() { return getAudioChannel(DEFAULT_RIGHT_CHANNEL); }
237 
238  // returns the underlying buffer
239  inline SampleType **getBuffer() const;
240 
244  inline int32 getNumChannels() const { return fBuffer.numChannels; }
245 
249  inline int32 getNumSamples() const { return fNumSamples; }
250 
254  inline tresult copyTo(class_type &toBuffer) const { return toBuffer.copyFrom(*this); };
255 
259  tresult copyFrom(class_type const &fromBuffer)
260  {
261  SampleType **fromSamples = fromBuffer.getBuffer();
262  SampleType **toSamples = getBuffer();
263 
264  // there are cases when the 2 buffers could be identical.. no need to copy
265  if(fromSamples == toSamples)
266  return kResultOk;
267 
268  // sanity check
269  if(!fromSamples || !toSamples)
270  return kResultFalse;
271 
272  int32 numChannels = std::min(getNumChannels(), fromBuffer.getNumChannels());
273  int32 numSamples = std::min(getNumSamples(), fromBuffer.getNumSamples());
274 
275  for(int32 channel = 0; channel < numChannels; channel++)
276  {
277  auto ptrFrom = fromSamples[channel];
278  auto ptrTo = toSamples[channel];
279 
280  // sanity check
281  if(!ptrFrom || !ptrTo)
282  continue;
283 
284  std::copy(ptrFrom, ptrFrom + numSamples, ptrTo);
285  }
286 
287  return kResultOk;
288  }
289 
293  inline SampleType absoluteMax()
294  {
295  SampleType max = 0;
296 
297  auto buffer = getBuffer();
298 
299  // sanity check
300  if(!buffer)
301  return max;
302 
303  for(int32 channel = 0; channel < getNumChannels(); channel++)
304  {
305  auto ptr = buffer[channel];
306 
307  // sanity check
308  if(!ptr)
309  continue;
310 
311  for(int j = 0; j < getNumSamples(); ++j, ptr++)
312  {
313  auto sample = *ptr;
314  if(sample < 0)
315  sample -= sample;
316 
317  max = std::max(max, sample);
318  }
319  }
320 
321  return max;
322  }
323 
326  inline tresult clear()
327  {
328  auto buffer = getBuffer();
329 
330  // sanity check
331  if(!buffer)
332  return kResultFalse;
333 
334  for(int32 channel = 0; channel < getNumChannels(); channel++)
335  {
336  auto ptr = buffer[channel];
337 
338  // sanity check
339  if(!ptr)
340  continue;
341 
342  std::fill(ptr, ptr + getNumSamples(), 0);
343  }
344 
345  if(getNumChannels() > 0)
346  fBuffer.silenceFlags = (static_cast<uint64>(1) << getNumChannels()) - 1;
347 
348  return kResultOk;
349  }
350 
351 private:
352  AudioBusBuffers &fBuffer;
353  const int32 fNumSamples;
354 };
355 
356 template<>
357 inline Sample32 **AudioBuffers<Sample32>::getBuffer() const { return fBuffer.channelBuffers32; }
358 
359 template<>
360 inline Sample64 **AudioBuffers<Sample64>::getBuffer() const { return fBuffer.channelBuffers64; }
361 
364 
365 }
366 }
Definition: AudioBuffer.h:42
constexpr int32 DEFAULT_RIGHT_CHANNEL
Definition: AudioBuffer.h:34
AudioBuffers< Sample64 > AudioBuffers64
Definition: AudioBuffer.h:363
Definition: AudioBuffer.h:45
tresult clear()
Definition: AudioBuffer.h:326
AudioBuffers< Sample32 > AudioBuffers32
Definition: AudioBuffer.h:362
SampleType absoluteMax()
Definition: AudioBuffer.h:293
tresult copyTo(Channel &toChannel) const
Definition: AudioBuffer.h:98
bool isActive() const
Definition: AudioBuffer.h:90
Definition: Clock.h:22
AudioBuffers< SampleType > class_type
Definition: AudioBuffer.h:139
uint64 getSilenceFlags() const
Definition: AudioBuffer.h:189
int32 getNumSamples() const
Definition: AudioBuffer.h:55
tresult copyTo(class_type &toBuffer) const
Definition: AudioBuffer.h:254
int32 fChannel
Definition: AudioBuffer.h:136
bool adjustSilenceFlags()
Definition: AudioBuffer.h:156
tresult copyFrom(Channel const &fromChannel)
Definition: AudioBuffer.h:103
SampleType * getBuffer() const
Definition: AudioBuffer.h:69
int32 getNumSamples() const
Definition: AudioBuffer.h:249
AudioBusBuffers & fBuffer
Definition: AudioBuffer.h:352
Channel getLeftChannel()
Definition: AudioBuffer.h:231
#define BIT_CLEAR(a, b)
Definition: AudioUtils.h:31
bool isSilent() const
Definition: AudioBuffer.h:77
bool isSilent(Sample32 value)
Definition: AudioUtils.h:49
int32 getNumChannels() const
Definition: AudioBuffer.h:244
void setSilenceFlag(bool iSilent)
Definition: AudioBuffer.h:82
#define BIT_TEST(a, b)
Definition: AudioUtils.h:32
tresult copyFrom(class_type const &fromBuffer)
Definition: AudioBuffer.h:259
constexpr int32 DEFAULT_LEFT_CHANNEL
Definition: AudioBuffer.h:33
void clear()
Definition: AudioBuffer.h:121
SampleType ** getBuffer() const
#define BIT_SET(a, b)
Definition: AudioUtils.h:30
Channel(AudioBuffers &iBuffers, int32 iChannel)
Definition: AudioBuffer.h:48
void setSilenceFlag(int32 iChannel, bool iSilent)
Definition: AudioBuffer.h:197
void setSilenceFlags(uint64 iFlags) const
Definition: AudioBuffer.h:192
bool isSilent() const
Definition: AudioBuffer.h:147
Channel getAudioChannel(int32 iChannel)
Definition: AudioBuffer.h:223
AudioBuffers(AudioBusBuffers &buffer, int32 numSamples)
Definition: AudioBuffer.h:143
AudioBuffers & fBuffers
Definition: AudioBuffer.h:135
Channel getRightChannel()
Definition: AudioBuffer.h:236
const int32 fNumSamples
Definition: AudioBuffer.h:353
bool isSilent(int32 iChannel) const
Definition: AudioBuffer.h:211