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 sample(ch_cnt_t channel, f_cnt_t frame) const noexcept -> T&
353 {
354 return framePtr(frame)[channel];
355 }
356
358 constexpr auto frame(f_cnt_t index) const noexcept
359 {
360 if constexpr (channelCount == DynamicChannelCount)
361 {
362 return std::span<T>{framePtr(index), Base::channels()};
363 }
364 else
365 {
366 return std::span<T, channelCount>{framePtr(index), Base::channels()};
367 }
368 }
369
374 constexpr auto framePtr(f_cnt_t index) const noexcept -> T*
375 {
376 assert(index < this->m_frames);
377 return this->m_data + index * Base::channels();
378 }
379
384 constexpr auto operator[](f_cnt_t index) const noexcept -> T*
385 {
386 return framePtr(index);
387 }
388
391 {
392 assert(offset <= this->m_frames);
394 if constexpr (channelCount == DynamicChannelCount)
395 {
396 return {this->m_data + offset * Base::channels(), Base::channels(), frames};
397 }
398 else
399 {
400 return {this->m_data + offset * Base::channels(), frames};
401 }
402 }
403
405 constexpr auto framesView() const noexcept -> std::ranges::subrange<ConstFrameIter, const T*>
406 {
407 const T* end = this->m_data + Base::channels() * this->m_frames;
408 if constexpr (channelCount == DynamicChannelCount)
409 {
410 return std::ranges::subrange{ConstFrameIter{this->m_data, Base::channels()}, end};
411 }
412 else
413 {
414 return std::ranges::subrange{ConstFrameIter{this->m_data}, end};
415 }
416 }
417
419 constexpr auto framesView() noexcept -> std::ranges::subrange<FrameIter, T*>
420 {
421 T* end = this->m_data + Base::channels() * this->m_frames;
422 if constexpr (channelCount == DynamicChannelCount)
423 {
424 return std::ranges::subrange{FrameIter{this->m_data, Base::channels()}, end};
425 }
426 else
427 {
428 return std::ranges::subrange{FrameIter{this->m_data}, end};
429 }
430 }
431
432 auto sampleFrameAt(f_cnt_t index) noexcept -> SampleFrame&
433 requires (std::is_same_v<T, float> && channelCount == 2)
434 {
435 assert(index < this->m_frames);
436 return reinterpret_cast<SampleFrame*>(this->m_data)[index];
437 }
438
439 auto sampleFrameAt(f_cnt_t index) const noexcept -> const SampleFrame&
440 requires (std::is_same_v<T, const float> && channelCount == 2)
441 {
442 assert(index < this->m_frames);
443 return reinterpret_cast<const SampleFrame*>(this->m_data)[index];
444 }
445
447 requires (std::is_same_v<T, float> && channelCount == 2)
448 {
449 return {reinterpret_cast<SampleFrame*>(this->m_data), this->m_frames};
450 }
451
453 requires (std::is_same_v<T, const float> && channelCount == 2)
454 {
455 return {reinterpret_cast<const SampleFrame*>(this->m_data), this->m_frames};
456 }
457
459 static constexpr bool Interleaved = true;
460};
461
462// Check that the std::span-like space optimization works
464static_assert(sizeof(InterleavedBufferView<float, 2>) == sizeof(void*) + sizeof(f_cnt_t));
465
466// Deduction guides
469
470
479template<SampleType T, ch_cnt_t channelCount = DynamicChannelCount>
480class PlanarBufferView : public detail::BufferViewData<T* const, channelCount>
481{
483
484public:
485 using Base::Base;
486
488 template<typename U = T> requires (std::is_const_v<U> && channelCount != DynamicChannelCount)
489 constexpr PlanarBufferView(PlanarBufferView<std::remove_const_t<U>, channelCount> other) noexcept
490 : Base{other.data(), other.frames()}
491 {
492 }
493
495 template<typename U = T> requires (std::is_const_v<U> && channelCount == DynamicChannelCount)
496 constexpr PlanarBufferView(PlanarBufferView<std::remove_const_t<U>, channelCount> other) noexcept
497 : Base{other.data(), other.channels(), other.frames()}
498 {
499 }
500
502 template<ch_cnt_t otherChannels>
503 requires (channelCount == DynamicChannelCount && otherChannels != DynamicChannelCount)
505 : Base{other.data(), otherChannels, other.frames()}
506 {
507 }
508
509 constexpr auto empty() const noexcept -> bool
510 {
511 return !this->m_data || Base::channels() == 0 || this->m_frames == 0;
512 }
513
515 constexpr auto sample(ch_cnt_t channel, f_cnt_t frame) const noexcept -> T&
516 {
517 return bufferPtr(channel)[frame];
518 }
519
521 constexpr auto buffer(ch_cnt_t channel) const noexcept -> std::span<T>
522 {
523 return {bufferPtr(channel), this->m_frames};
524 }
525
527 template<ch_cnt_t channel> requires (channelCount != DynamicChannelCount)
528 constexpr auto buffer() const noexcept -> std::span<T>
529 {
530 return {bufferPtr<channel>(), this->m_frames};
531 }
532
537 constexpr auto bufferPtr(ch_cnt_t channel) const noexcept -> T*
538 {
539 assert(channel < Base::channels());
540 assert(this->m_data != nullptr);
541 return this->m_data[channel];
542 }
543
548 template<ch_cnt_t channel> requires (channelCount != DynamicChannelCount)
549 constexpr auto bufferPtr() const noexcept -> T*
550 {
551 static_assert(channel < channelCount);
552 assert(this->m_data != nullptr);
553 return this->m_data[channel];
554 }
555
560 constexpr auto operator[](ch_cnt_t channel) const noexcept -> T*
561 {
562 return bufferPtr(channel);
563 }
564
566 static constexpr bool Interleaved = false;
567};
568
569// Check that the std::span-like space optimization works
570static_assert(sizeof(PlanarBufferView<float>) > sizeof(PlanarBufferView<float, 2>));
571static_assert(sizeof(PlanarBufferView<float, 2>) == sizeof(void**) + sizeof(f_cnt_t));
572
573
575template<class T, typename U, ch_cnt_t channels = DynamicChannelCount>
576concept AudioBufferView = SampleType<U> && (std::convertible_to<T, InterleavedBufferView<U, channels>>
577 || std::convertible_to<T, PlanarBufferView<U, channels>>);
578
579
581template<class T, ch_cnt_t inputs, ch_cnt_t outputs>
583 InterleavedBufferView<std::remove_const_t<T>, outputs> dst)
584{
585 assert(src.frames() == dst.frames());
586 if constexpr (inputs == DynamicChannelCount || outputs == DynamicChannelCount)
587 {
588 assert(src.channels() == dst.channels());
589 }
590 else { static_assert(inputs == outputs); }
591
592 for (f_cnt_t frame = 0; frame < dst.frames(); ++frame)
593 {
594 auto* framePtr = dst.framePtr(frame);
595 for (ch_cnt_t channel = 0; channel < dst.channels(); ++channel)
596 {
597 framePtr[channel] = src.bufferPtr(channel)[frame];
598 }
599 }
600}
601
603template<class T, ch_cnt_t inputs, ch_cnt_t outputs>
605 PlanarBufferView<std::remove_const_t<T>, outputs> dst)
606{
607 assert(src.frames() == dst.frames());
608 if constexpr (inputs == DynamicChannelCount || outputs == DynamicChannelCount)
609 {
610 assert(src.channels() == dst.channels());
611 }
612 else { static_assert(inputs == outputs); }
613
614 for (ch_cnt_t channel = 0; channel < dst.channels(); ++channel)
615 {
616 auto* channelPtr = dst.bufferPtr(channel);
617 for (f_cnt_t frame = 0; frame < dst.frames(); ++frame)
618 {
619 channelPtr[frame] = src.framePtr(frame)[channel];
620 }
621 }
622}
623
624} // namespace lmms
625
626#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:452
constexpr auto sample(ch_cnt_t channel, f_cnt_t frame) const noexcept -> T &
Definition AudioBufferView.h:352
constexpr auto subspan(f_cnt_t offset, f_cnt_t frames) const -> InterleavedBufferView< T, channelCount >
Definition AudioBufferView.h:390
static constexpr bool Interleaved
Use to distinguish between InterleavedBufferView and PlanarBufferView when using AudioBufferView.
Definition AudioBufferView.h:459
detail::InterleavedFrameIterator< T, channelCount > FrameIter
Definition AudioBufferView.h:294
constexpr auto framePtr(f_cnt_t index) const noexcept -> T *
Definition AudioBufferView.h:374
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:419
auto asSampleFrames() noexcept -> std::span< SampleFrame >
Definition AudioBufferView.h:446
auto sampleFrameAt(f_cnt_t index) noexcept -> SampleFrame &
Definition AudioBufferView.h:432
constexpr auto framesView() const noexcept -> std::ranges::subrange< ConstFrameIter, const T * >
Definition AudioBufferView.h:405
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:384
constexpr auto frame(f_cnt_t index) const noexcept
Definition AudioBufferView.h:358
auto sampleFrameAt(f_cnt_t index) const noexcept -> const SampleFrame &
Definition AudioBufferView.h:439
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:481
detail::BufferViewData< T *const, channelCount > Base
Definition AudioBufferView.h:482
constexpr auto empty() const noexcept -> bool
Definition AudioBufferView.h:509
constexpr auto bufferPtr(ch_cnt_t channel) const noexcept -> T *
Definition AudioBufferView.h:537
constexpr PlanarBufferView(PlanarBufferView< T, otherChannels > other) noexcept
Construct dynamic channel count from static.
Definition AudioBufferView.h:504
constexpr auto operator[](ch_cnt_t channel) const noexcept -> T *
Definition AudioBufferView.h:560
constexpr auto sample(ch_cnt_t channel, f_cnt_t frame) const noexcept -> T &
Definition AudioBufferView.h:515
constexpr auto bufferPtr() const noexcept -> T *
Definition AudioBufferView.h:549
constexpr auto buffer(ch_cnt_t channel) const noexcept -> std::span< T >
Definition AudioBufferView.h:521
constexpr PlanarBufferView(PlanarBufferView< std::remove_const_t< U >, channelCount > other) noexcept
Construct const from mutable (static channel count).
Definition AudioBufferView.h:489
constexpr auto buffer() const noexcept -> std::span< T >
Definition AudioBufferView.h:528
static constexpr bool Interleaved
Use to distinguish between InterleavedBufferView and PlanarBufferView when using AudioBufferView.
Definition AudioBufferView.h:566
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:576
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:582
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:604
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