LMMS
Loading...
Searching...
No Matches
AudioBufferView.h
Go to the documentation of this file.
1/*
2 * AudioBufferView.h - Non-owning views for interleaved and
3 * non-interleaved (planar) buffers
4 *
5 * Copyright (c) 2025 Dalton Messmer <messmer.dalton/at/gmail.com>
6 *
7 * This file is part of LMMS - https://lmms.io
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program (see COPYING); if not, write to the
21 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301 USA.
23 *
24 */
25
26#ifndef LMMS_AUDIO_BUFFER_VIEW_H
27#define LMMS_AUDIO_BUFFER_VIEW_H
28
29#include <cassert>
30#include <concepts>
31#include <ranges>
32#include <span>
33#include <type_traits>
34
35#include "LmmsTypes.h"
36#include "SampleFrame.h"
37
38namespace lmms
39{
40
42inline constexpr auto DynamicChannelCount = static_cast<ch_cnt_t>(-1);
43
44
45namespace detail {
46
47// For buffer views with static channel count
48template<typename T, ch_cnt_t channelCount>
50{
51public:
52 constexpr BufferViewData() = default;
53 constexpr BufferViewData(const BufferViewData&) = default;
54
55 constexpr BufferViewData(T* data, [[maybe_unused]] ch_cnt_t channels, f_cnt_t frames) noexcept
56 : m_data{data}
58 {
59 assert(channels == channelCount);
60 }
61
63 : m_data{data}
65 {
66 }
67
68 constexpr auto data() const noexcept -> T* { return m_data; }
69 static constexpr auto channels() noexcept -> ch_cnt_t { return channelCount; }
70 constexpr auto frames() const noexcept -> f_cnt_t { return m_frames; }
71
72protected:
73 T* m_data = nullptr;
75};
76
77// For buffer views with dynamic channel count
78template<typename T>
80{
81public:
82 constexpr BufferViewData() = default;
83 constexpr BufferViewData(const BufferViewData&) = default;
84
92
93 constexpr auto data() const noexcept -> T* { return m_data; }
94 constexpr auto channels() const noexcept -> ch_cnt_t { return m_channels; }
95 constexpr auto frames() const noexcept -> f_cnt_t { return m_frames; }
96
97protected:
98 T* m_data = nullptr;
101};
102
103// For interleaved frame iterators with static channel count
104template<typename T, ch_cnt_t channelCount>
106{
107public:
108 constexpr InterleavedFrameIteratorData() = default;
110
112 : m_data{data}
113 {
114 }
115
116 static constexpr auto channels() noexcept -> ch_cnt_t { return channelCount; }
117
118protected:
119 T* m_data = nullptr;
120};
121
122// For interleaved frame iterators with dynamic channel count
123template<typename T>
125{
126public:
127 constexpr InterleavedFrameIteratorData() = default;
129
131 : m_data{data}
132 , m_channels{channels}
133 {
134 }
135
136 constexpr auto channels() const noexcept -> ch_cnt_t { return m_channels; }
137
138protected:
139 T* m_data = nullptr;
141};
142
143// Allows for iterating over the frames of `InterleavedBufferView`
144template<typename T, ch_cnt_t channelCount = DynamicChannelCount>
146{
148
149public:
150 using iterator_concept = std::random_access_iterator_tag;
151 using value_type = T*;
152 using difference_type = std::ptrdiff_t;
153
154 using Base::Base;
155
156 constexpr auto operator*() const noexcept -> value_type { return this->m_data; }
157
158 constexpr auto operator[](difference_type frames) const noexcept -> value_type
159 {
160 return this->m_data[frames * Base::channels()];
161 }
162
164 {
165 this->m_data += Base::channels();
166 return *this;
167 }
168
169 constexpr auto operator++(int) noexcept -> InterleavedFrameIterator
170 {
171 auto temp = *this;
172 ++(*this);
173 return temp;
174 }
175
177 {
178 this->m_data -= Base::channels();
179 return *this;
180 }
181
182 constexpr auto operator--(int) noexcept -> InterleavedFrameIterator
183 {
184 auto temp = *this;
185 --(*this);
186 return temp;
187 }
188
190 {
191 this->m_data += channels * Base::channels();
192 return *this;
193 }
194
196 {
197 this->m_data -= channels * Base::channels();
198 return *this;
199 }
200
201 friend constexpr auto operator+(InterleavedFrameIterator iter, difference_type frames) noexcept
203 {
204 if constexpr (channelCount == DynamicChannelCount)
205 {
206 return {iter.m_data + frames * Base::channels(), Base::channels()};
207 }
208 else
209 {
210 return InterleavedFrameIterator{iter.m_data + frames * Base::channels()};
211 }
212 }
213
214 friend constexpr auto operator+(difference_type frames, InterleavedFrameIterator iter) noexcept
216 {
217 return iter + frames;
218 }
219
220 constexpr auto operator-(difference_type frames) const noexcept -> InterleavedFrameIterator
221 {
222 if constexpr (channelCount == DynamicChannelCount)
223 {
224 return {this->m_data - frames * Base::channels(), Base::channels()};
225 }
226 else
227 {
228 return InterleavedFrameIterator{this->m_data - frames * Base::channels()};
229 }
230 }
231
232 constexpr auto operator-(InterleavedFrameIterator other) const noexcept -> difference_type
233 {
234 return this->m_data - other.m_data;
235 }
236
237 constexpr auto operator<=>(InterleavedFrameIterator other) const noexcept
238 {
239 return this->m_data <=> other.m_data;
240 }
241
242 constexpr auto operator==(InterleavedFrameIterator other) const noexcept -> bool
243 {
244 return this->m_data == other.m_data;
245 }
246
247 constexpr auto operator<=>(T* sentinel) const noexcept
248 {
249 return this->m_data <=> sentinel;
250 }
251
252 constexpr auto operator==(T* sentinel) const noexcept -> bool
253 {
254 return this->m_data == sentinel;
255 }
256
257 constexpr auto base() const noexcept -> T* { return this->m_data; }
258};
259
260static_assert(std::random_access_iterator<InterleavedFrameIterator<float, 2>>);
261
262template<typename T, typename... AllowedTs>
263inline constexpr bool OneOf = (std::is_same_v<T, AllowedTs> || ...);
264
265} // namespace detail
266
267
269template<typename T>
271 float,
272 double,
273 std::int8_t,
274 std::uint8_t,
275 std::int16_t,
276 std::uint16_t,
277 std::int32_t,
278 std::uint32_t,
279 std::int64_t,
280 std::uint64_t
281>;
282
283
289template<SampleType T, ch_cnt_t channelCount = DynamicChannelCount>
290class InterleavedBufferView : public detail::BufferViewData<T, channelCount>
291{
293
296
297public:
298 using Base::Base;
299
301 template<typename U = T> requires (std::is_const_v<U> && channelCount != DynamicChannelCount)
302 constexpr InterleavedBufferView(InterleavedBufferView<std::remove_const_t<U>, channelCount> other) noexcept
303 : Base{other.data(), other.frames()}
304 {
305 }
306
308 template<typename U = T> requires (std::is_const_v<U> && channelCount == DynamicChannelCount)
309 constexpr InterleavedBufferView(InterleavedBufferView<std::remove_const_t<U>, channelCount> other) noexcept
310 : Base{other.data(), other.channels(), other.frames()}
311 {
312 }
313
315 template<ch_cnt_t otherChannels>
316 requires (channelCount == DynamicChannelCount && otherChannels != DynamicChannelCount)
318 : Base{other.data(), otherChannels, other.frames()}
319 {
320 }
321
324 requires (std::is_same_v<std::remove_const_t<T>, float> && channelCount == 2)
325 : Base{reinterpret_cast<float*>(data), frames}
326 {
327 }
328
331 requires (std::is_same_v<T, const float> && channelCount == 2)
332 : Base{reinterpret_cast<const float*>(data), frames}
333 {
334 }
335
336 constexpr auto empty() const noexcept -> bool
337 {
338 return !this->m_data || Base::channels() == 0 || this->m_frames == 0;
339 }
340
341 constexpr auto dataSizeBytes() const noexcept -> std::size_t
342 {
343 return Base::channels() * this->m_frames * sizeof(T);
344 }
345
346 constexpr auto dataView() noexcept -> std::span<T>
347 {
348 return std::span<T>{this->m_data, this->m_frames * Base::channels()};
349 }
350
352 constexpr auto frame(f_cnt_t index) const noexcept
353 {
354 if constexpr (channelCount == DynamicChannelCount)
355 {
356 return std::span<T>{framePtr(index), Base::channels()};
357 }
358 else
359 {
360 return std::span<T, channelCount>{framePtr(index), Base::channels()};
361 }
362 }
363
368 constexpr auto framePtr(f_cnt_t index) const noexcept -> T*
369 {
370 assert(index < this->m_frames);
371 return this->m_data + index * Base::channels();
372 }
373
378 constexpr auto operator[](f_cnt_t index) const noexcept -> T*
379 {
380 return framePtr(index);
381 }
382
385 {
386 assert(offset <= this->m_frames);
388 if constexpr (channelCount == DynamicChannelCount)
389 {
390 return {this->m_data + offset * Base::channels(), Base::channels(), frames};
391 }
392 else
393 {
394 return {this->m_data + offset * Base::channels(), frames};
395 }
396 }
397
399 constexpr auto framesView() const noexcept -> std::ranges::subrange<ConstFrameIter, const T*>
400 {
401 const T* end = this->m_data + Base::channels() * this->m_frames;
402 if constexpr (channelCount == DynamicChannelCount)
403 {
404 return std::ranges::subrange{ConstFrameIter{this->m_data, Base::channels()}, end};
405 }
406 else
407 {
408 return std::ranges::subrange{ConstFrameIter{this->m_data}, end};
409 }
410 }
411
413 constexpr auto framesView() noexcept -> std::ranges::subrange<FrameIter, T*>
414 {
415 T* end = this->m_data + Base::channels() * this->m_frames;
416 if constexpr (channelCount == DynamicChannelCount)
417 {
418 return std::ranges::subrange{FrameIter{this->m_data, Base::channels()}, end};
419 }
420 else
421 {
422 return std::ranges::subrange{FrameIter{this->m_data}, end};
423 }
424 }
425
426 auto sampleFrameAt(f_cnt_t index) noexcept -> SampleFrame&
427 requires (std::is_same_v<T, float> && channelCount == 2)
428 {
429 assert(index < this->m_frames);
430 return reinterpret_cast<SampleFrame*>(this->m_data)[index];
431 }
432
433 auto sampleFrameAt(f_cnt_t index) const noexcept -> const SampleFrame&
434 requires (std::is_same_v<T, const float> && channelCount == 2)
435 {
436 assert(index < this->m_frames);
437 return reinterpret_cast<const SampleFrame*>(this->m_data)[index];
438 }
439
441 requires (std::is_same_v<T, float> && channelCount == 2)
442 {
443 return {reinterpret_cast<SampleFrame*>(this->m_data), this->m_frames};
444 }
445
447 requires (std::is_same_v<T, const float> && channelCount == 2)
448 {
449 return {reinterpret_cast<const SampleFrame*>(this->m_data), this->m_frames};
450 }
451
453 static constexpr bool Interleaved = true;
454};
455
456// Check that the std::span-like space optimization works
458static_assert(sizeof(InterleavedBufferView<float, 2>) == sizeof(void*) + sizeof(f_cnt_t));
459
460// Deduction guides
463
464
473template<SampleType T, ch_cnt_t channelCount = DynamicChannelCount>
474class PlanarBufferView : public detail::BufferViewData<T* const, channelCount>
475{
477
478public:
479 using Base::Base;
480
482 template<typename U = T> requires (std::is_const_v<U> && channelCount != DynamicChannelCount)
483 constexpr PlanarBufferView(PlanarBufferView<std::remove_const_t<U>, channelCount> other) noexcept
484 : Base{other.data(), other.frames()}
485 {
486 }
487
489 template<typename U = T> requires (std::is_const_v<U> && channelCount == DynamicChannelCount)
490 constexpr PlanarBufferView(PlanarBufferView<std::remove_const_t<U>, channelCount> other) noexcept
491 : Base{other.data(), other.channels(), other.frames()}
492 {
493 }
494
496 template<ch_cnt_t otherChannels>
497 requires (channelCount == DynamicChannelCount && otherChannels != DynamicChannelCount)
499 : Base{other.data(), otherChannels, other.frames()}
500 {
501 }
502
503 constexpr auto empty() const noexcept -> bool
504 {
505 return !this->m_data || Base::channels() == 0 || this->m_frames == 0;
506 }
507
509 constexpr auto buffer(ch_cnt_t channel) const noexcept -> std::span<T>
510 {
511 return {bufferPtr(channel), this->m_frames};
512 }
513
515 template<ch_cnt_t channel> requires (channelCount != DynamicChannelCount)
516 constexpr auto buffer() const noexcept -> std::span<T>
517 {
518 return {bufferPtr<channel>(), this->m_frames};
519 }
520
525 constexpr auto bufferPtr(ch_cnt_t channel) const noexcept -> T*
526 {
527 assert(channel < Base::channels());
528 assert(this->m_data != nullptr);
529 return this->m_data[channel];
530 }
531
536 template<ch_cnt_t channel> requires (channelCount != DynamicChannelCount)
537 constexpr auto bufferPtr() const noexcept -> T*
538 {
539 static_assert(channel < channelCount);
540 assert(this->m_data != nullptr);
541 return this->m_data[channel];
542 }
543
548 constexpr auto operator[](ch_cnt_t channel) const noexcept -> T*
549 {
550 return bufferPtr(channel);
551 }
552
554 static constexpr bool Interleaved = false;
555};
556
557// Check that the std::span-like space optimization works
558static_assert(sizeof(PlanarBufferView<float>) > sizeof(PlanarBufferView<float, 2>));
559static_assert(sizeof(PlanarBufferView<float, 2>) == sizeof(void**) + sizeof(f_cnt_t));
560
561
563template<class T, typename U, ch_cnt_t channels = DynamicChannelCount>
564concept AudioBufferView = SampleType<U> && (std::convertible_to<T, InterleavedBufferView<U, channels>>
565 || std::convertible_to<T, PlanarBufferView<U, channels>>);
566
567
569template<class T, ch_cnt_t inputs, ch_cnt_t outputs>
571 InterleavedBufferView<std::remove_const_t<T>, outputs> dst)
572{
573 assert(src.frames() == dst.frames());
574 if constexpr (inputs == DynamicChannelCount || outputs == DynamicChannelCount)
575 {
576 assert(src.channels() == dst.channels());
577 }
578 else { static_assert(inputs == outputs); }
579
580 for (f_cnt_t frame = 0; frame < dst.frames(); ++frame)
581 {
582 auto* framePtr = dst.framePtr(frame);
583 for (ch_cnt_t channel = 0; channel < dst.channels(); ++channel)
584 {
585 framePtr[channel] = src.bufferPtr(channel)[frame];
586 }
587 }
588}
589
591template<class T, ch_cnt_t inputs, ch_cnt_t outputs>
593 PlanarBufferView<std::remove_const_t<T>, outputs> dst)
594{
595 assert(src.frames() == dst.frames());
596 if constexpr (inputs == DynamicChannelCount || outputs == DynamicChannelCount)
597 {
598 assert(src.channels() == dst.channels());
599 }
600 else { static_assert(inputs == outputs); }
601
602 for (ch_cnt_t channel = 0; channel < dst.channels(); ++channel)
603 {
604 auto* channelPtr = dst.bufferPtr(channel);
605 for (f_cnt_t frame = 0; frame < dst.frames(); ++frame)
606 {
607 channelPtr[frame] = src.framePtr(frame)[channel];
608 }
609 }
610}
611
612} // namespace lmms
613
614#endif // LMMS_AUDIO_BUFFER_VIEW_H
#define noexcept
Definition DistrhoDefines.h:72
assert(0)
Definition AudioBufferView.h:291
InterleavedBufferView(SampleFrame *data, f_cnt_t frames) noexcept
Construct from SampleFrame*.
Definition AudioBufferView.h:323
constexpr InterleavedBufferView(InterleavedBufferView< std::remove_const_t< U >, channelCount > other) noexcept
Construct const from mutable (static channel count).
Definition AudioBufferView.h:302
auto asSampleFrames() const noexcept -> std::span< const SampleFrame >
Definition AudioBufferView.h:446
constexpr auto subspan(f_cnt_t offset, f_cnt_t frames) const -> InterleavedBufferView< T, channelCount >
Definition AudioBufferView.h:384
static constexpr bool Interleaved
Use to distinguish between InterleavedBufferView and PlanarBufferView when using AudioBufferView.
Definition AudioBufferView.h:453
detail::InterleavedFrameIterator< T, channelCount > FrameIter
Definition AudioBufferView.h:294
constexpr auto framePtr(f_cnt_t index) const noexcept -> T *
Definition AudioBufferView.h:368
constexpr InterleavedBufferView(InterleavedBufferView< T, otherChannels > other) noexcept
Construct dynamic channel count from static.
Definition AudioBufferView.h:317
constexpr auto framesView() noexcept -> std::ranges::subrange< FrameIter, T * >
Definition AudioBufferView.h:413
auto asSampleFrames() noexcept -> std::span< SampleFrame >
Definition AudioBufferView.h:440
auto sampleFrameAt(f_cnt_t index) noexcept -> SampleFrame &
Definition AudioBufferView.h:426
constexpr auto framesView() const noexcept -> std::ranges::subrange< ConstFrameIter, const T * >
Definition AudioBufferView.h:399
detail::InterleavedFrameIterator< const T, channelCount > ConstFrameIter
Definition AudioBufferView.h:295
constexpr auto dataSizeBytes() const noexcept -> std::size_t
Definition AudioBufferView.h:341
constexpr auto operator[](f_cnt_t index) const noexcept -> T *
Definition AudioBufferView.h:378
constexpr auto frame(f_cnt_t index) const noexcept
Definition AudioBufferView.h:352
auto sampleFrameAt(f_cnt_t index) const noexcept -> const SampleFrame &
Definition AudioBufferView.h:433
InterleavedBufferView(const SampleFrame *data, f_cnt_t frames) noexcept
Construct from const SampleFrame*.
Definition AudioBufferView.h:330
constexpr auto dataView() noexcept -> std::span< T >
Definition AudioBufferView.h:346
constexpr auto empty() const noexcept -> bool
Definition AudioBufferView.h:336
detail::BufferViewData< T, channelCount > Base
Definition AudioBufferView.h:292
Definition AudioBufferView.h:475
detail::BufferViewData< T *const, channelCount > Base
Definition AudioBufferView.h:476
constexpr auto empty() const noexcept -> bool
Definition AudioBufferView.h:503
constexpr auto bufferPtr(ch_cnt_t channel) const noexcept -> T *
Definition AudioBufferView.h:525
constexpr PlanarBufferView(PlanarBufferView< T, otherChannels > other) noexcept
Construct dynamic channel count from static.
Definition AudioBufferView.h:498
constexpr auto operator[](ch_cnt_t channel) const noexcept -> T *
Definition AudioBufferView.h:548
constexpr auto bufferPtr() const noexcept -> T *
Definition AudioBufferView.h:537
constexpr auto buffer(ch_cnt_t channel) const noexcept -> std::span< T >
Definition AudioBufferView.h:509
constexpr PlanarBufferView(PlanarBufferView< std::remove_const_t< U >, channelCount > other) noexcept
Construct const from mutable (static channel count).
Definition AudioBufferView.h:483
constexpr auto buffer() const noexcept -> std::span< T >
Definition AudioBufferView.h:516
static constexpr bool Interleaved
Use to distinguish between InterleavedBufferView and PlanarBufferView when using AudioBufferView.
Definition AudioBufferView.h:554
Definition SampleFrame.h:41
constexpr BufferViewData(T *data, ch_cnt_t channels, f_cnt_t frames) noexcept
Definition AudioBufferView.h:85
f_cnt_t m_frames
Definition AudioBufferView.h:100
constexpr auto data() const noexcept -> T *
Definition AudioBufferView.h:93
constexpr BufferViewData(const BufferViewData &)=default
constexpr auto channels() const noexcept -> ch_cnt_t
Definition AudioBufferView.h:94
ch_cnt_t m_channels
Definition AudioBufferView.h:99
constexpr auto frames() const noexcept -> f_cnt_t
Definition AudioBufferView.h:95
Definition AudioBufferView.h:50
constexpr BufferViewData()=default
constexpr BufferViewData(T *data, ch_cnt_t channels, f_cnt_t frames) noexcept
Definition AudioBufferView.h:55
constexpr auto frames() const noexcept -> f_cnt_t
Definition AudioBufferView.h:70
constexpr BufferViewData(T *data, f_cnt_t frames) noexcept
Definition AudioBufferView.h:62
f_cnt_t m_frames
Definition AudioBufferView.h:74
constexpr BufferViewData(const BufferViewData &)=default
constexpr auto data() const noexcept -> T *
Definition AudioBufferView.h:68
static constexpr auto channels() noexcept -> ch_cnt_t
Definition AudioBufferView.h:69
constexpr InterleavedFrameIteratorData(const InterleavedFrameIteratorData &)=default
constexpr InterleavedFrameIteratorData(T *data, ch_cnt_t channels) noexcept
Definition AudioBufferView.h:130
constexpr auto channels() const noexcept -> ch_cnt_t
Definition AudioBufferView.h:136
T * m_data
Definition AudioBufferView.h:119
constexpr InterleavedFrameIteratorData(const InterleavedFrameIteratorData &)=default
constexpr InterleavedFrameIteratorData(T *data) noexcept
Definition AudioBufferView.h:111
static constexpr auto channels() noexcept -> ch_cnt_t
Definition AudioBufferView.h:116
constexpr InterleavedFrameIteratorData()=default
Definition AudioBufferView.h:146
constexpr auto operator+=(difference_type channels) noexcept -> InterleavedFrameIterator &
Definition AudioBufferView.h:189
constexpr auto operator<=>(InterleavedFrameIterator other) const noexcept
Definition AudioBufferView.h:237
constexpr auto base() const noexcept -> T *
Definition AudioBufferView.h:257
constexpr auto operator--(int) noexcept -> InterleavedFrameIterator
Definition AudioBufferView.h:182
constexpr auto operator==(T *sentinel) const noexcept -> bool
Definition AudioBufferView.h:252
InterleavedFrameIteratorData< T, channelCount > Base
Definition AudioBufferView.h:147
constexpr auto operator[](difference_type frames) const noexcept -> value_type
Definition AudioBufferView.h:158
constexpr auto operator-=(difference_type channels) noexcept -> InterleavedFrameIterator &
Definition AudioBufferView.h:195
friend constexpr auto operator+(difference_type frames, InterleavedFrameIterator iter) noexcept -> InterleavedFrameIterator
Definition AudioBufferView.h:214
constexpr auto operator--() noexcept -> InterleavedFrameIterator &
Definition AudioBufferView.h:176
constexpr auto operator-(InterleavedFrameIterator other) const noexcept -> difference_type
Definition AudioBufferView.h:232
constexpr auto operator==(InterleavedFrameIterator other) const noexcept -> bool
Definition AudioBufferView.h:242
constexpr auto operator++(int) noexcept -> InterleavedFrameIterator
Definition AudioBufferView.h:169
T * value_type
Definition AudioBufferView.h:151
std::ptrdiff_t difference_type
Definition AudioBufferView.h:152
constexpr auto operator*() const noexcept -> value_type
Definition AudioBufferView.h:156
constexpr auto operator-(difference_type frames) const noexcept -> InterleavedFrameIterator
Definition AudioBufferView.h:220
std::random_access_iterator_tag iterator_concept
Definition AudioBufferView.h:150
friend constexpr auto operator+(InterleavedFrameIterator iter, difference_type frames) noexcept -> InterleavedFrameIterator
Definition AudioBufferView.h:201
constexpr auto operator++() noexcept -> InterleavedFrameIterator &
Definition AudioBufferView.h:163
constexpr auto operator<=>(T *sentinel) const noexcept
Definition AudioBufferView.h:247
Concept for any audio buffer view, interleaved or planar.
Definition AudioBufferView.h:564
Recognized sample types, either const or non-const.
Definition AudioBufferView.h:270
JSAMPIMAGE data
Definition jpeglib.h:945
Definition AudioBufferView.h:45
constexpr bool OneOf
Definition AudioBufferView.h:263
Definition AudioAlsa.cpp:35
std::uint16_t ch_cnt_t
Definition LmmsTypes.h:44
InterleavedBufferView(const SampleFrame *, f_cnt_t) -> InterleavedBufferView< const float, 2 >
constexpr void toInterleaved(PlanarBufferView< T, inputs > src, InterleavedBufferView< std::remove_const_t< T >, outputs > dst)
Converts planar buffers to interleaved buffers.
Definition AudioBufferView.h:570
std::uint64_t f_cnt_t
Definition LmmsTypes.h:43
constexpr void toPlanar(InterleavedBufferView< T, inputs > src, PlanarBufferView< std::remove_const_t< T >, outputs > dst)
Converts interleaved buffers to planar buffers.
Definition AudioBufferView.h:592
constexpr auto DynamicChannelCount
Use when the number of channels is not known at compile time.
Definition AudioBufferView.h:42
Definition juce_Uuid.h:141
#define const
Definition zconf.h:137