Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qaudioringbuffer_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4//
5// W A R N I N G
6// -------------
7//
8// This file is not part of the Qt API. It exists for the convenience
9// of a number of Qt sources files. This header file may change from
10// version to version without notice, or even be removed.
11//
12// We mean it.
13//
14
15#ifndef QAUDIORINGBUFFER_P_H
16#define QAUDIORINGBUFFER_P_H
17
18#include <QtCore/qspan.h>
19#include <QtCore/qtclasshelpermacros.h>
20#include <QtMultimedia/private/qaudio_qspan_support_p.h>
21
22#include <algorithm>
23#include <atomic>
24#include <cstdlib>
25#include <limits>
26#include <type_traits>
27
28QT_BEGIN_NAMESPACE
29
30namespace QtPrivate {
31
32// Single-producer, single-consumer wait-free queue
33template <typename T>
35{
36 static constexpr bool isTriviallyDestructible = std::is_trivially_destructible_v<T>;
37
38public:
39 using ValueType = T;
40 using Region = QSpan<T>;
41 using ConstRegion = QSpan<const T>;
42
43 explicit QAudioRingBuffer(int bufferSize) : m_bufferSize(bufferSize)
44 {
45 if (bufferSize)
46 m_buffer = reinterpret_cast<T *>(
47 ::operator new(sizeof(T) * bufferSize, std::align_val_t(alignof(T))));
48 }
49
51
53 {
54 if constexpr (!isTriviallyDestructible) {
55 consumeAll([](auto /* elements*/) {
56 });
57 }
58
59 ::operator delete(reinterpret_cast<void *>(m_buffer), std::align_val_t(alignof(T)));
60 }
61
63 {
64 using namespace QtMultimediaPrivate; // drop
65 return produceSome([&](Region writeRegion) {
69
70 return Region{
73 };
74 });
75 }
76
78 {
79 return produceOne([&] {
80 return std::move(element);
81 });
82 }
83
84 template <typename Functor>
86#ifdef __cpp_concepts
89#endif
90 {
92 if (writeRegion.isEmpty())
93 return false;
95 new (writeElement) T{ producer() };
97 return true;
98 }
99
100 template <typename Functor>
127
128 template <typename Functor>
130 {
131 return consumeSome([&](Region region) {
133 return region;
134 });
135 }
136
137 template <typename Functor>
151
152 // consumer has to return the region it has consumed
153 template <typename Functor>
182
183 // CAVEAT: beware of the thread safety
186
187 int size() const { return m_bufferSize; }
188
189 void reset()
190#ifdef __cpp_concepts
192#endif
193 {
194 m_readPos = 0;
195 m_writePos = 0;
197 }
198
199private:
201 {
203
205 if (free > 0) {
208 } else {
209 output = Region();
210 }
211 return output;
212 }
213
215 {
218 }
219
221 {
223
224 if (used > 0) {
225 const int readSize = qMin(size, qMin(m_bufferSize - m_readPos, used));
226 return readSize > 0 ? Region(m_buffer + m_readPos, readSize) : Region();
227 }
228
229 return Region();
230 }
231
232 // WARNING: we need to ensure that all elements are destroyed
234 {
237 }
238
239 const int m_bufferSize;
240 int m_readPos{};
241 int m_writePos{};
242 T *m_buffer{};
243 std::atomic_int m_bufferUsed{};
244};
245
246} // namespace QtPrivate
247
248QT_END_NAMESPACE
249
250#endif // QAUDIORINGBUFFER_P_H