Jamba C++ API 8.0.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 <algorithm>
23
25#include "AudioUtils.h"
26
27namespace pongasoft {
28
29using namespace Utils;
30
31namespace VST {
32
33using namespace Steinberg;
34using namespace Steinberg::Vst;
35
36// defines the default setup channels (0 is left, 1 is right)
37constexpr int32 DEFAULT_LEFT_CHANNEL = 0;
38constexpr int32 DEFAULT_RIGHT_CHANNEL = 1;
39
45template<std::floating_point SampleType>
47{
48public:
53 {
54 void operator()(SampleType iSample)
55 {
56 fAbsoluteMax = std::max(fAbsoluteMax, iSample < 0 ? -iSample : iSample);
57 }
58
59 SampleType fAbsoluteMax = 0;
60 };
61
69 class Channel
70 {
71 public:
72 Channel(AudioBuffers &iBuffers, int32 iChannel) : fBuffers{iBuffers}, fChannel{iChannel}
73 {
74 }
75
79 int32 getNumSamples() const
80 {
81 return fBuffers.getNumSamples();
82 }
83
95 SampleType *getBuffer()
96 {
97 return fChannel < fBuffers.getNumChannels() ? fBuffers.getBuffer()[fChannel] : nullptr;
98 }
99
111 SampleType const *getBuffer() const
112 {
113 return fChannel < fBuffers.getNumChannels() ? fBuffers.getBuffer()[fChannel] : nullptr;
114 }
115
119 bool isSilent() const { return fBuffers.isSilent(fChannel); }
120
124 void setSilenceFlag(bool iSilent)
125 {
126 fBuffers.setSilenceFlag(fChannel, iSilent);
127 }
128
132 bool isActive() const
133 {
134 return fChannel < fBuffers.getNumChannels() && getBuffer() != nullptr;
135 }
136
140 tresult copyTo(Channel &toChannel) const { return toChannel.copyFrom(*this); }
141
145 tresult copyFrom(Channel const &fromChannel)
146 {
147 int32 numSamples = std::min(getNumSamples(), fromChannel.getNumSamples());
148
149 auto ptrFrom = fromChannel.getBuffer();
150 auto ptrTo = getBuffer();
151
152 // sanity check
153 if(!ptrFrom || !ptrTo)
154 return kResultFalse;
155
156 std::copy(ptrFrom, ptrFrom + numSamples, ptrTo);
157
158 return kResultOk;
159 }
160
164 SampleType absoluteMax() const
165 {
166 return forEachSample(AbsoluteMaxOp()).fAbsoluteMax;
167 }
168
171 void clear()
172 {
173 auto buffer = getBuffer();
174
175 // sanity check
176 if(!buffer)
177 return;
178
179 std::fill(buffer, buffer + getNumSamples(), 0);
180
181 setSilenceFlag(true);
182 }
183
196 template<UnaryModifier<SampleType> F>
198 {
199 auto buffer = getBuffer();
200
201 if(buffer)
202 {
203 return std::for_each(buffer, buffer + getNumSamples(), f);
204 }
205 else
206 return f;
207 }
208
221 template<UnaryFunction<SampleType> F>
222 F forEachSample(F f) const
223 {
224 auto buffer = getBuffer();
225
226 if(buffer)
227 {
228 return std::for_each(buffer, buffer + getNumSamples(), f);
229 }
230 else
231 return f;
232 }
233
254 template<UnaryTransformer<SampleType> F>
255 F copyFrom(Channel const &iFromChannel, F f)
256 {
257 auto outputBuffer = getBuffer();
258 auto inputBuffer = iFromChannel.getBuffer();
259
260 if(outputBuffer && inputBuffer)
261 {
262 int32 const numSamples = std::min(getNumSamples(), iFromChannel.getNumSamples());
263
264 // implementation note: adding 'F &' as the template type forces f to be passed
265 // by reference otherwise it would be copied which would loose the state (ex: for functors).
266 std::transform<decltype(inputBuffer), decltype(outputBuffer), F &>(inputBuffer, inputBuffer + numSamples, outputBuffer, f);
267 }
268
269 return f;
270 }
271
275 template<UnaryTransformer<SampleType> F>
276 F copyTo(Channel &oToChannel, F f) const
277 {
278 return oToChannel.copyFrom(*this, f);
279 }
280
281 private:
283 int32 fChannel;
284 };
285
287
288
289public:
290 AudioBuffers(AudioBusBuffers &buffer, int32 numSamples) : fBuffer(buffer), fNumSamples(numSamples)
291 {}
292
293 // returns true if the buffer is silent (meaning all channels are silent => set to 1) (according to silenceFlags)
294 bool isSilent() const
295 {
296 return fBuffer.numChannels == 0 || fBuffer.silenceFlags == (static_cast<uint64>(1) << fBuffer.numChannels) - 1;
297 }
298
304 {
305 uint64 silenceFlags = 0;
306
307 auto buffer = getBuffer();
308
309 for(int32 channel = 0; channel < getNumChannels(); channel++)
310 {
311 bool silent = true;
312
313 auto ptr = buffer[channel];
314
315 if(!ptr)
316 continue;
317
318 for(int j = 0; j < getNumSamples(); ++j, ptr++)
319 {
320 auto sample = *ptr;
321
322 if(silent && !pongasoft::VST::isSilent(sample))
323 silent = false;
324 }
325
326 if(silent)
327 BIT_SET(silenceFlags, channel);
328 }
329
330 fBuffer.silenceFlags = silenceFlags;
331
332 return isSilent();
333 }
334
335 // getSilenceFlags
336 uint64 getSilenceFlags() const { return fBuffer.silenceFlags; }
337
338 // setSilenceFlags
339 void setSilenceFlags(uint64 iFlags) { fBuffer.silenceFlags = iFlags; }
340
344 void setSilenceFlag(int32 iChannel, bool iSilent)
345 {
346 if(iChannel < getNumChannels())
347 {
348 if(iSilent)
349 BIT_SET(fBuffer.silenceFlags, iChannel);
350 else
351 BIT_CLEAR(fBuffer.silenceFlags, iChannel);
352 }
353 }
354
360 {
361 fBuffer.silenceFlags = 0;
362 }
363
367 bool isSilent(int32 iChannel) const
368 {
369 if(iChannel < getNumChannels())
370 {
371 return BIT_TEST(fBuffer.silenceFlags, iChannel);
372 }
373 return true;
374 }
375
382 Channel getAudioChannel(int32 iChannel)
383 {
384 return Channel{*this, iChannel};
385 }
386
393 Channel getAudioChannel(int32 iChannel) const
394 {
395 // implementation note: removing const since Channel accepts only non const
396 return Channel{*const_cast<class_type *>(this), iChannel};
397 }
398
403
408
413
418
420 SampleType **getBuffer();
421
422 // returns the underlying (sample) buffer (const version)
423 SampleType const * const *getBuffer() const;
424
426 AudioBusBuffers &getAudioBusBuffers() { return fBuffer; }
427
429 AudioBusBuffers const &getAudioBusBuffers() const { return fBuffer; }
430
434 int32 getNumChannels() const { return fBuffer.numChannels; }
435
439 int32 getNumSamples() const { return fNumSamples; }
440
453 template<UnaryModifier<SampleType> F>
455 {
456 for(int32 channel = 0; channel < getNumChannels(); channel++)
457 {
458 f = getAudioChannel(channel).forEachSample(f);
459 }
460
461 return f;
462 }
463
476 template<UnaryFunction<SampleType> F>
477 F forEachSample(F f) const
478 {
479 for(int32 channel = 0; channel < getNumChannels(); channel++)
480 {
481 f = getAudioChannel(channel).forEachSample(f);
482 }
483
484 return f;
485 }
486
490 tresult copyTo(class_type &toBuffer) const { return toBuffer.copyFrom(*this); };
491
495 tresult copyFrom(class_type const &fromBuffer)
496 {
497 auto fromSamples = fromBuffer.getBuffer();
498 auto toSamples = getBuffer();
499
500 // there are cases when the 2 buffers could be identical.. no need to copy
501 if(fromSamples == toSamples)
502 return kResultOk;
503
504 // sanity check
505 if(!fromSamples || !toSamples)
506 return kResultFalse;
507
508 int32 numChannels = std::min(getNumChannels(), fromBuffer.getNumChannels());
509 int32 numSamples = std::min(getNumSamples(), fromBuffer.getNumSamples());
510
511 for(int32 channel = 0; channel < numChannels; channel++)
512 {
513 auto ptrFrom = fromSamples[channel];
514 auto ptrTo = toSamples[channel];
515
516 // sanity check
517 if(!ptrFrom || !ptrTo)
518 continue;
519
520 std::copy(ptrFrom, ptrFrom + numSamples, ptrTo);
521 }
522
523 return kResultOk;
524 }
525
544 template<UnaryTransformer<SampleType> F>
545 F copyFrom(class_type const &iFromBuffer, F f)
546 {
547 int32 numChannels = std::min(getNumChannels(), iFromBuffer.getNumChannels());
548
549 for(int32 channel = 0; channel < numChannels; channel++)
550 {
551 f = getAudioChannel(channel).copyFrom(iFromBuffer.getAudioChannel(channel), f);
552 }
553
554 return f;
555 }
556
560 template<UnaryTransformer<SampleType> F>
561 F copyTo(class_type &iToBuffer, F f) const { return iToBuffer.copyFrom(*this, f); }
562
566 SampleType absoluteMax() const
567 {
568 return forEachSample(AbsoluteMaxOp()).fAbsoluteMax;
569 }
570
573 tresult clear()
574 {
575 for(int32 channel = 0; channel < getNumChannels(); channel++)
576 {
577 getAudioChannel(channel).clear();
578 }
579
580 return kResultOk;
581 }
582
583private:
584 AudioBusBuffers &fBuffer;
585 const int32 fNumSamples;
586};
587
588template<>
589inline Sample32 const * const *AudioBuffers<Sample32>::getBuffer() const { return fBuffer.channelBuffers32; }
590
591template<>
592inline Sample64 const * const *AudioBuffers<Sample64>::getBuffer() const { return fBuffer.channelBuffers64; }
593
594template<>
595inline Sample32 **AudioBuffers<Sample32>::getBuffer() { return fBuffer.channelBuffers32; }
596
597template<>
598inline Sample64 **AudioBuffers<Sample64>::getBuffer() { return fBuffer.channelBuffers64; }
599
602
603}
604}
#define BIT_TEST(a, b)
Definition AudioUtils.h:35
#define BIT_CLEAR(a, b)
Definition AudioUtils.h:34
#define BIT_SET(a, b)
Definition AudioUtils.h:33
F forEachSample(F f)
Applies the provided unary function to each sample (if the channel is active).
Definition AudioBuffer.h:197
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:111
bool isActive() const
Definition AudioBuffer.h:132
bool isSilent() const
Definition AudioBuffer.h:119
void setSilenceFlag(bool iSilent)
Sets a single channel silence flag.
Definition AudioBuffer.h:124
int32 fChannel
Definition AudioBuffer.h:283
SampleType absoluteMax() const
Definition AudioBuffer.h:164
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:95
tresult copyFrom(Channel const &fromChannel)
Copy the content of the provided channel to THIS channel (up to num samples).
Definition AudioBuffer.h:145
int32 getNumSamples() const
Definition AudioBuffer.h:79
F copyFrom(Channel const &iFromChannel, F f)
Copy iFromChannel to this channel, applying f to each sample or in other words, for each sample.
Definition AudioBuffer.h:255
F copyTo(Channel &oToChannel, F f) const
Same as copyFrom with the roles reversed.
Definition AudioBuffer.h:276
AudioBuffers & fBuffers
Definition AudioBuffer.h:282
void clear()
Clears the channel (and sets the silence flag).
Definition AudioBuffer.h:171
F forEachSample(F f) const
Applies the provided unary function to each sample (if the channel is active).
Definition AudioBuffer.h:222
tresult copyTo(Channel &toChannel) const
Copy the content of THIS channel to the provided channel (up to num samples).
Definition AudioBuffer.h:140
Channel(AudioBuffers &iBuffers, int32 iChannel)
Definition AudioBuffer.h:72
Represents all the buffers (example for a stereo channel there is 2 underlying sample buffers).
Definition AudioBuffer.h:47
F copyTo(class_type &iToBuffer, F f) const
Same as copyFrom with the roles reversed.
Definition AudioBuffer.h:561
F forEachSample(F f)
Applies the provided unary function to each sample of each channel.
Definition AudioBuffer.h:454
Channel getRightChannel()
Definition AudioBuffer.h:412
AudioBusBuffers & fBuffer
Definition AudioBuffer.h:584
Channel getLeftChannel()
Definition AudioBuffer.h:402
tresult clear()
Clears the buffer (and sets the silence flag).
Definition AudioBuffer.h:573
AudioBuffers class_type
Definition AudioBuffer.h:286
Channel getAudioChannel(int32 iChannel)
Return the audio channel for the provided channel.
Definition AudioBuffer.h:382
void setSilenceFlag(int32 iChannel, bool iSilent)
Sets a single channel silence flag.
Definition AudioBuffer.h:344
bool isSilent(int32 iChannel) const
Definition AudioBuffer.h:367
uint64 getSilenceFlags() const
Definition AudioBuffer.h:336
F copyFrom(class_type const &iFromBuffer, F f)
Copy iFromBuffer to this buffer, applying f to each sample for each channel or in other words,...
Definition AudioBuffer.h:545
bool isSilent() const
Definition AudioBuffer.h:294
AudioBusBuffers const & getAudioBusBuffers() const
Returns the AudioBusBuffers original buffer (const version).
Definition AudioBuffer.h:429
AudioBusBuffers & getAudioBusBuffers()
Returns the AudioBusBuffers original buffer.
Definition AudioBuffer.h:426
SampleType absoluteMax() const
Definition AudioBuffer.h:566
tresult copyTo(class_type &toBuffer) const
Copy the content of THIS buffer to the provided buffer (up to num samples).
Definition AudioBuffer.h:490
void clearSilentFlag()
Makes the buffer NON silent (by setting the flag to 0).
Definition AudioBuffer.h:359
int32 getNumSamples() const
Definition AudioBuffer.h:439
SampleType ** getBuffer()
Returns the underlying (sample) buffer.
const int32 fNumSamples
Definition AudioBuffer.h:585
Channel getLeftChannel() const
Definition AudioBuffer.h:407
SampleType const *const * getBuffer() const
Channel getAudioChannel(int32 iChannel) const
Return the audio channel for the provided channel.
Definition AudioBuffer.h:393
Channel getRightChannel() const
Definition AudioBuffer.h:417
int32 getNumChannels() const
Definition AudioBuffer.h:434
void setSilenceFlags(uint64 iFlags)
Definition AudioBuffer.h:339
F forEachSample(F f) const
Applies the provided unary function to each sample of each channel.
Definition AudioBuffer.h:477
tresult copyFrom(class_type const &fromBuffer)
Copy the content of the provided buffer to THIS buffer (up to num samples).
Definition AudioBuffer.h:495
AudioBuffers(AudioBusBuffers &buffer, int32 numSamples)
Definition AudioBuffer.h:290
bool adjustSilenceFlags()
Computes and adjust the silence flags.
Definition AudioBuffer.h:303
Definition CircularBuffer.h:27
Definition Clock.h:24
constexpr int32 DEFAULT_RIGHT_CHANNEL
Definition AudioBuffer.h:38
bool isSilent(Sample32 value)
Definition AudioUtils.h:64
AudioBuffers< Sample64 > AudioBuffers64
Definition AudioBuffer.h:601
constexpr int32 DEFAULT_LEFT_CHANNEL
Definition AudioBuffer.h:37
AudioBuffers< Sample32 > AudioBuffers32
Definition AudioBuffer.h:600
Definition Clock.h:23
Unary operator adapter for computing the absolute max.
Definition AudioBuffer.h:53
SampleType fAbsoluteMax
Definition AudioBuffer.h:59
void operator()(SampleType iSample)
Definition AudioBuffer.h:54