Jamba C++ API 7.5.0
Loading...
Searching...
No Matches
AudioBuffer.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018-2019 pongasoft
3 *
4 * Licensed under the Apache License, Version 2.0 or the MIT license,
5 * at your option. You may not use this file except in compliance with
6 * one of these licenses. You may obtain copies of the licenses at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 * https://opensource.org/licenses/MIT
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 *
17 * @author Yan Pujante
18 */
19#pragma once
20
21#include <pluginterfaces/vst/ivstaudioprocessor.h>
22#include <pongasoft/logging/logging.h>
23#include <algorithm>
24
25#include "AudioUtils.h"
26
27namespace pongasoft {
28namespace VST {
29
30using namespace Steinberg;
31using namespace Steinberg::Vst;
32
33// defines the default setup channels (0 is left, 1 is right)
34constexpr int32 DEFAULT_LEFT_CHANNEL = 0;
35constexpr int32 DEFAULT_RIGHT_CHANNEL = 1;
36
42template<typename SampleType>
44{
45public:
50 {
51 void operator()(SampleType iSample)
52 {
53 fAbsoluteMax = std::max(fAbsoluteMax, iSample < 0 ? -iSample : iSample);
54 }
55
56 SampleType fAbsoluteMax = 0;
57 };
58
66 class Channel
67 {
68 public:
69 Channel(AudioBuffers &iBuffers, int32 iChannel) : fBuffers{iBuffers}, fChannel{iChannel}
70 {
71 }
72
76 inline int32 getNumSamples() const
77 {
78 return fBuffers.getNumSamples();
79 }
80
92 inline SampleType *getBuffer()
93 {
94 return fChannel < fBuffers.getNumChannels() ? fBuffers.getBuffer()[fChannel] : nullptr;
95 }
96
108 inline SampleType const *getBuffer() const
109 {
110 return fChannel < fBuffers.getNumChannels() ? fBuffers.getBuffer()[fChannel] : nullptr;
111 }
112
116 inline bool isSilent() const { return fBuffers.isSilent(fChannel); }
117
121 inline void setSilenceFlag(bool iSilent)
122 {
123 fBuffers.setSilenceFlag(fChannel, iSilent);
124 }
125
129 inline bool isActive() const
130 {
131 return fChannel < fBuffers.getNumChannels() && getBuffer() != nullptr;
132 }
133
137 inline tresult copyTo(Channel &toChannel) const { return toChannel.copyFrom(*this); };
138
142 tresult copyFrom(Channel const &fromChannel)
143 {
144 int32 numSamples = std::min(getNumSamples(), fromChannel.getNumSamples());
145
146 auto ptrFrom = fromChannel.getBuffer();
147 auto ptrTo = getBuffer();
148
149 // sanity check
150 if(!ptrFrom || !ptrTo)
151 return kResultFalse;
152
153 std::copy(ptrFrom, ptrFrom + numSamples, ptrTo);
154
155 return kResultOk;
156 }
157
161 inline SampleType absoluteMax() const
162 {
163 return forEachSample(AbsoluteMaxOp()).fAbsoluteMax;
164 }
165
168 inline void clear()
169 {
170 auto buffer = getBuffer();
171
172 // sanity check
173 if(!buffer)
174 return;
175
176 std::fill(buffer, buffer + getNumSamples(), 0);
177
178 setSilenceFlag(true);
179 }
180
193 template<typename UnaryFunction>
194 inline UnaryFunction forEachSample(UnaryFunction f)
195 {
196 auto buffer = getBuffer();
197
198 if(buffer)
199 {
200 return std::for_each(buffer, buffer + getNumSamples(), f);
201 }
202 else
203 return f;
204 }
205
218 template<typename UnaryFunction>
219 inline UnaryFunction forEachSample(UnaryFunction f) const
220 {
221 auto buffer = getBuffer();
222
223 if(buffer)
224 {
225 return std::for_each(buffer, buffer + getNumSamples(), f);
226 }
227 else
228 return f;
229 }
230
251 template<typename UnaryOperation>
252 inline UnaryOperation copyFrom(Channel const &iFromChannel, UnaryOperation f)
253 {
254 auto outputBuffer = getBuffer();
255 auto inputBuffer = iFromChannel.getBuffer();
256
257 if(outputBuffer && inputBuffer)
258 {
259 int32 const numSamples = std::min(getNumSamples(), iFromChannel.getNumSamples());
260
261 // implementation note: adding 'UnaryOperation &' as the template type forces f to be passed
262 // by reference otherwise it would be copied which would loose the state (ex: for functors).
263 std::transform<decltype(inputBuffer), decltype(outputBuffer), UnaryOperation &>(inputBuffer, inputBuffer + numSamples, outputBuffer, f);
264 }
265
266 return f;
267 }
268
272 template<typename UnaryOperation>
273 inline UnaryOperation copyTo(Channel &oToChannel, UnaryOperation f) const
274 {
275 return oToChannel.copyFrom(*this, f);
276 }
277
278 private:
280 int32 fChannel;
281 };
282
284
285
286public:
287 AudioBuffers(AudioBusBuffers &buffer, int32 numSamples) : fBuffer(buffer), fNumSamples(numSamples)
288 {}
289
290 // returns true if the buffer is silent (meaning all channels are silent => set to 1) (according to silenceFlags)
291 inline bool isSilent() const
292 {
293 return fBuffer.numChannels == 0 || fBuffer.silenceFlags == (static_cast<uint64>(1) << fBuffer.numChannels) - 1;
294 }
295
300 inline bool adjustSilenceFlags()
301 {
302 uint64 silenceFlags = 0;
303
304 auto buffer = getBuffer();
305
306 for(int32 channel = 0; channel < getNumChannels(); channel++)
307 {
308 bool silent = true;
309
310 auto ptr = buffer[channel];
311
312 if(!ptr)
313 continue;
314
315 for(int j = 0; j < getNumSamples(); ++j, ptr++)
316 {
317 auto sample = *ptr;
318
319 if(silent && !pongasoft::VST::isSilent(sample))
320 silent = false;
321 }
322
323 if(silent)
324 BIT_SET(silenceFlags, channel);
325 }
326
327 fBuffer.silenceFlags = silenceFlags;
328
329 return isSilent();
330 }
331
332 // getSilenceFlags
333 inline uint64 getSilenceFlags() const { return fBuffer.silenceFlags; }
334
335 // setSilenceFlags
336 inline void setSilenceFlags(uint64 iFlags) const { fBuffer.silenceFlags = iFlags; }
337
341 inline void setSilenceFlag(int32 iChannel, bool iSilent)
342 {
343 if(iChannel < getNumChannels())
344 {
345 if(iSilent)
346 BIT_SET(fBuffer.silenceFlags, iChannel);
347 else
348 BIT_CLEAR(fBuffer.silenceFlags, iChannel);
349 }
350 }
351
356 inline void clearSilentFlag()
357 {
358 fBuffer.silenceFlags = 0;
359 }
360
364 inline bool isSilent(int32 iChannel) const
365 {
366 if(iChannel < getNumChannels())
367 {
368 return BIT_TEST(fBuffer.silenceFlags, iChannel);
369 }
370 return true;
371 }
372
379 inline Channel getAudioChannel(int32 iChannel)
380 {
381 return Channel{*this, iChannel};
382 }
383
390 inline const Channel getAudioChannel(int32 iChannel) const
391 {
392 // implementation note: removing const since Channel accepts only non const
393 return Channel{*const_cast<class_type *>(this), iChannel};
394 }
395
400
404 inline const Channel getLeftChannel() const { return getAudioChannel(DEFAULT_LEFT_CHANNEL); }
405
410
414 inline const Channel getRightChannel() const { return getAudioChannel(DEFAULT_RIGHT_CHANNEL); }
415
417 inline SampleType **getBuffer();
418
419 // returns the underlying (sample) buffer (const version)
420 inline SampleType const * const *getBuffer() const;
421
423 inline AudioBusBuffers &getAudioBusBuffers() { return fBuffer; }
424
426 inline AudioBusBuffers const &getAudioBusBuffers() const { return fBuffer; }
427
431 inline int32 getNumChannels() const { return fBuffer.numChannels; }
432
436 inline int32 getNumSamples() const { return fNumSamples; }
437
450 template<typename UnaryFunction>
451 inline UnaryFunction forEachSample(UnaryFunction f)
452 {
453 for(int32 channel = 0; channel < getNumChannels(); channel++)
454 {
455 f = getAudioChannel(channel).forEachSample(f);
456 }
457
458 return f;
459 }
460
473 template<typename UnaryFunction>
474 inline UnaryFunction forEachSample(UnaryFunction f) const
475 {
476 for(int32 channel = 0; channel < getNumChannels(); channel++)
477 {
478 f = getAudioChannel(channel).forEachSample(f);
479 }
480
481 return f;
482 }
483
487 inline tresult copyTo(class_type &toBuffer) const { return toBuffer.copyFrom(*this); };
488
492 tresult copyFrom(class_type const &fromBuffer)
493 {
494 auto fromSamples = fromBuffer.getBuffer();
495 auto toSamples = getBuffer();
496
497 // there are cases when the 2 buffers could be identical.. no need to copy
498 if(fromSamples == toSamples)
499 return kResultOk;
500
501 // sanity check
502 if(!fromSamples || !toSamples)
503 return kResultFalse;
504
505 int32 numChannels = std::min(getNumChannels(), fromBuffer.getNumChannels());
506 int32 numSamples = std::min(getNumSamples(), fromBuffer.getNumSamples());
507
508 for(int32 channel = 0; channel < numChannels; channel++)
509 {
510 auto ptrFrom = fromSamples[channel];
511 auto ptrTo = toSamples[channel];
512
513 // sanity check
514 if(!ptrFrom || !ptrTo)
515 continue;
516
517 std::copy(ptrFrom, ptrFrom + numSamples, ptrTo);
518 }
519
520 return kResultOk;
521 }
522
541 template<typename UnaryOperation>
542 inline UnaryOperation copyFrom(class_type const &iFromBuffer, UnaryOperation f)
543 {
544 int32 numChannels = std::min(getNumChannels(), iFromBuffer.getNumChannels());
545
546 for(int32 channel = 0; channel < numChannels; channel++)
547 {
548 f = getAudioChannel(channel).copyFrom(iFromBuffer.getAudioChannel(channel), f);
549 }
550
551 return f;
552 }
553
557 template<typename UnaryOperation>
558 inline UnaryOperation copyTo(class_type &iToBuffer, UnaryOperation f) const { return iToBuffer.copyFrom(*this, f); };
559
563 inline SampleType absoluteMax() const
564 {
565 return forEachSample(AbsoluteMaxOp()).fAbsoluteMax;
566 }
567
570 inline tresult clear()
571 {
572 for(int32 channel = 0; channel < getNumChannels(); channel++)
573 {
574 getAudioChannel(channel).clear();
575 }
576
577 return kResultOk;
578 }
579
580private:
581 AudioBusBuffers &fBuffer;
582 const int32 fNumSamples;
583};
584
585template<>
586inline Sample32 const * const *AudioBuffers<Sample32>::getBuffer() const { return fBuffer.channelBuffers32; }
587
588template<>
589inline Sample64 const * const *AudioBuffers<Sample64>::getBuffer() const { return fBuffer.channelBuffers64; }
590
591template<>
592inline Sample32 **AudioBuffers<Sample32>::getBuffer() { return fBuffer.channelBuffers32; }
593
594template<>
595inline Sample64 **AudioBuffers<Sample64>::getBuffer() { return fBuffer.channelBuffers64; }
596
599
600}
601}
#define BIT_TEST(a, b)
Definition AudioUtils.h:34
#define BIT_CLEAR(a, b)
Definition AudioUtils.h:33
#define BIT_SET(a, b)
Definition AudioUtils.h:32
UnaryOperation copyFrom(Channel const &iFromChannel, UnaryOperation f)
Copy iFromChannel to this channel, applying f to each sample or in other words, for each sample.
Definition AudioBuffer.h:252
SampleType const * getBuffer() const
Note that this pointer is NOT guaranteed to be not null as demonstrated by this piece of logic in the...
Definition AudioBuffer.h:108
bool isActive() const
Definition AudioBuffer.h:129
UnaryOperation copyTo(Channel &oToChannel, UnaryOperation f) const
Same as copyFrom with the roles reversed.
Definition AudioBuffer.h:273
bool isSilent() const
Definition AudioBuffer.h:116
void setSilenceFlag(bool iSilent)
Sets a single channel silence flag.
Definition AudioBuffer.h:121
int32 fChannel
Definition AudioBuffer.h:280
SampleType absoluteMax() const
Definition AudioBuffer.h:161
SampleType * getBuffer()
Note that this pointer is NOT guaranteed to be not null as demonstrated by this piece of logic in the...
Definition AudioBuffer.h:92
tresult copyFrom(Channel const &fromChannel)
Copy the content of the provided channel to THIS channel (up to num samples).
Definition AudioBuffer.h:142
int32 getNumSamples() const
Definition AudioBuffer.h:76
UnaryFunction forEachSample(UnaryFunction f)
Applies the provided unary function to each sample (if the channel is active).
Definition AudioBuffer.h:194
UnaryFunction forEachSample(UnaryFunction f) const
Applies the provided unary function to each sample (if the channel is active).
Definition AudioBuffer.h:219
AudioBuffers & fBuffers
Definition AudioBuffer.h:279
void clear()
Clears the channel (and sets the silence flag).
Definition AudioBuffer.h:168
tresult copyTo(Channel &toChannel) const
Copy the content of THIS channel to the provided channel (up to num samples).
Definition AudioBuffer.h:137
Channel(AudioBuffers &iBuffers, int32 iChannel)
Definition AudioBuffer.h:69
Represents all the buffers (example for a stereo channel there is 2 underlying sample buffers).
Definition AudioBuffer.h:44
Channel getRightChannel()
Definition AudioBuffer.h:409
AudioBusBuffers & fBuffer
Definition AudioBuffer.h:581
Channel getLeftChannel()
Definition AudioBuffer.h:399
tresult clear()
Clears the buffer (and sets the silence flag).
Definition AudioBuffer.h:570
Channel getAudioChannel(int32 iChannel)
Return the audio channel for the provided channel.
Definition AudioBuffer.h:379
void setSilenceFlag(int32 iChannel, bool iSilent)
Sets a single channel silence flag.
Definition AudioBuffer.h:341
const Channel getAudioChannel(int32 iChannel) const
Return the audio channel for the provided channel.
Definition AudioBuffer.h:390
bool isSilent(int32 iChannel) const
Definition AudioBuffer.h:364
uint64 getSilenceFlags() const
Definition AudioBuffer.h:333
bool isSilent() const
Definition AudioBuffer.h:291
AudioBusBuffers const & getAudioBusBuffers() const
Returns the AudioBusBuffers original buffer (const version).
Definition AudioBuffer.h:426
AudioBusBuffers & getAudioBusBuffers()
Returns the AudioBusBuffers original buffer.
Definition AudioBuffer.h:423
SampleType absoluteMax() const
Definition AudioBuffer.h:563
tresult copyTo(class_type &toBuffer) const
Copy the content of THIS buffer to the provided buffer (up to num samples).
Definition AudioBuffer.h:487
void clearSilentFlag()
Makes the buffer NON silent (by setting the flag to 0).
Definition AudioBuffer.h:356
int32 getNumSamples() const
Definition AudioBuffer.h:436
void setSilenceFlags(uint64 iFlags) const
Definition AudioBuffer.h:336
SampleType ** getBuffer()
Returns the underlying (sample) buffer.
UnaryFunction forEachSample(UnaryFunction f)
Applies the provided unary function to each sample of each channel.
Definition AudioBuffer.h:451
UnaryFunction forEachSample(UnaryFunction f) const
Applies the provided unary function to each sample of each channel.
Definition AudioBuffer.h:474
const int32 fNumSamples
Definition AudioBuffer.h:582
AudioBuffers< SampleType > class_type
Definition AudioBuffer.h:283
SampleType const *const * getBuffer() const
const Channel getRightChannel() const
Definition AudioBuffer.h:414
int32 getNumChannels() const
Definition AudioBuffer.h:431
tresult copyFrom(class_type const &fromBuffer)
Copy the content of the provided buffer to THIS buffer (up to num samples).
Definition AudioBuffer.h:492
const Channel getLeftChannel() const
Definition AudioBuffer.h:404
UnaryOperation copyTo(class_type &iToBuffer, UnaryOperation f) const
Same as copyFrom with the roles reversed.
Definition AudioBuffer.h:558
AudioBuffers(AudioBusBuffers &buffer, int32 numSamples)
Definition AudioBuffer.h:287
UnaryOperation copyFrom(class_type const &iFromBuffer, UnaryOperation f)
Copy iFromBuffer to this buffer, applying f to each sample for each channel or in other words,...
Definition AudioBuffer.h:542
bool adjustSilenceFlags()
Computes and adjust the silence flags.
Definition AudioBuffer.h:300
Definition Clock.h:24
constexpr int32 DEFAULT_RIGHT_CHANNEL
Definition AudioBuffer.h:35
bool isSilent(Sample32 value)
Definition AudioUtils.h:63
AudioBuffers< Sample64 > AudioBuffers64
Definition AudioBuffer.h:598
constexpr int32 DEFAULT_LEFT_CHANNEL
Definition AudioBuffer.h:34
AudioBuffers< Sample32 > AudioBuffers32
Definition AudioBuffer.h:597
Definition Clock.h:23
Unary operator adapter for computing the absolute max.
Definition AudioBuffer.h:50
SampleType fAbsoluteMax
Definition AudioBuffer.h:56
void operator()(SampleType iSample)
Definition AudioBuffer.h:51