Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qpulsehelpers.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 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#include "qpulsehelpers_p.h"
5
7
8Q_LOGGING_CATEGORY(qLcPulseAudioOut, "qt.multimedia.pulseaudio.output")
9Q_LOGGING_CATEGORY(qLcPulseAudioIn, "qt.multimedia.pulseaudio.input")
10Q_LOGGING_CATEGORY(qLcPulseAudioEngine, "qt.multimedia.pulseaudio.engine")
11
13{
15{
16 pa_sample_spec spec;
17
18 spec.rate = format.sampleRate();
19 spec.channels = format.channelCount();
20 spec.format = PA_SAMPLE_INVALID;
21 const bool isBigEndian = QSysInfo::ByteOrder == QSysInfo::BigEndian;
22
23 if (format.sampleFormat() == QAudioFormat::UInt8) {
24 spec.format = PA_SAMPLE_U8;
25 } else if (format.sampleFormat() == QAudioFormat::Int16) {
26 spec.format = isBigEndian ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE;
27 } else if (format.sampleFormat() == QAudioFormat::Int32) {
28 spec.format = isBigEndian ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
29 } else if (format.sampleFormat() == QAudioFormat::Float) {
30 spec.format = isBigEndian ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE;
31 }
32
33 return spec;
34}
35
37{
38 pa_channel_map map;
39 map.channels = 0;
40
41 auto config = format.channelConfig();
44
46 map.channels = 1;
47 map.map[0] = PA_CHANNEL_POSITION_MONO;
48 } else {
50 map.map[map.channels++] = PA_CHANNEL_POSITION_FRONT_LEFT;
52 map.map[map.channels++] = PA_CHANNEL_POSITION_FRONT_RIGHT;
54 map.map[map.channels++] = PA_CHANNEL_POSITION_FRONT_CENTER;
56 map.map[map.channels++] = PA_CHANNEL_POSITION_LFE;
58 map.map[map.channels++] = PA_CHANNEL_POSITION_REAR_LEFT;
60 map.map[map.channels++] = PA_CHANNEL_POSITION_REAR_RIGHT;
62 map.map[map.channels++] = PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER;
64 map.map[map.channels++] = PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER;
66 map.map[map.channels++] = PA_CHANNEL_POSITION_REAR_CENTER;
68 map.map[map.channels++] = PA_CHANNEL_POSITION_LFE;
70 map.map[map.channels++] = PA_CHANNEL_POSITION_SIDE_LEFT;
72 map.map[map.channels++] = PA_CHANNEL_POSITION_SIDE_RIGHT;
74 map.map[map.channels++] = PA_CHANNEL_POSITION_TOP_FRONT_LEFT;
76 map.map[map.channels++] = PA_CHANNEL_POSITION_TOP_FRONT_RIGHT;
78 map.map[map.channels++] = PA_CHANNEL_POSITION_TOP_FRONT_CENTER;
80 map.map[map.channels++] = PA_CHANNEL_POSITION_TOP_CENTER;
82 map.map[map.channels++] = PA_CHANNEL_POSITION_TOP_REAR_LEFT;
84 map.map[map.channels++] = PA_CHANNEL_POSITION_TOP_REAR_RIGHT;
86 map.map[map.channels++] = PA_CHANNEL_POSITION_AUX0;
88 map.map[map.channels++] = PA_CHANNEL_POSITION_AUX1;
90 map.map[map.channels++] = PA_CHANNEL_POSITION_TOP_REAR_CENTER;
92 map.map[map.channels++] = PA_CHANNEL_POSITION_AUX2;
94 map.map[map.channels++] = PA_CHANNEL_POSITION_AUX3;
96 map.map[map.channels++] = PA_CHANNEL_POSITION_AUX4;
97 }
98
99 Q_ASSERT(qPopulationCount(config) == map.channels);
100 return map;
101}
102
104{
105 quint32 config = 0;
106 for (int i = 0; i < map.channels; ++i) {
107 switch (map.map[i]) {
108 case PA_CHANNEL_POSITION_MONO:
109 case PA_CHANNEL_POSITION_FRONT_CENTER:
111 break;
112 case PA_CHANNEL_POSITION_FRONT_LEFT:
114 break;
115 case PA_CHANNEL_POSITION_FRONT_RIGHT:
117 break;
118 case PA_CHANNEL_POSITION_REAR_CENTER:
120 break;
121 case PA_CHANNEL_POSITION_REAR_LEFT:
123 break;
124 case PA_CHANNEL_POSITION_REAR_RIGHT:
126 break;
127 case PA_CHANNEL_POSITION_LFE:
129 break;
130 case PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER:
132 break;
133 case PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER:
135 break;
136 case PA_CHANNEL_POSITION_SIDE_LEFT:
138 break;
139 case PA_CHANNEL_POSITION_SIDE_RIGHT:
141 break;
142
143 case PA_CHANNEL_POSITION_TOP_CENTER:
145 break;
146 case PA_CHANNEL_POSITION_TOP_FRONT_LEFT:
148 break;
149 case PA_CHANNEL_POSITION_TOP_FRONT_RIGHT:
151 break;
152 case PA_CHANNEL_POSITION_TOP_FRONT_CENTER:
154 break;
155 case PA_CHANNEL_POSITION_TOP_REAR_LEFT:
157 break;
158 case PA_CHANNEL_POSITION_TOP_REAR_RIGHT:
160 break;
161 case PA_CHANNEL_POSITION_TOP_REAR_CENTER:
163 break;
164 default:
165 break;
166 }
167 }
169}
170
171QAudioFormat sampleSpecToAudioFormat(const pa_sample_spec &spec)
172{
174
175 format.setSampleRate(spec.rate);
176 format.setChannelCount(spec.channels);
177 QAudioFormat::SampleFormat sampleFormat;
178 switch (spec.format) {
179 case PA_SAMPLE_U8:
180 sampleFormat = QAudioFormat::UInt8;
181 break;
182 case PA_SAMPLE_S16LE:
183 case PA_SAMPLE_S16BE:
184 sampleFormat = QAudioFormat::Int16;
185 break;
186 case PA_SAMPLE_FLOAT32LE:
187 case PA_SAMPLE_FLOAT32BE:
188 sampleFormat = QAudioFormat::Float;
189 break;
190 case PA_SAMPLE_S32LE:
191 case PA_SAMPLE_S32BE:
192 sampleFormat = QAudioFormat::Int32;
193 break;
194 default:
195 return {};
196 }
197
198 format.setSampleFormat(sampleFormat);
199 return format;
200}
201
203{
204 return pa_strerror(pa_context_errno(context));
205}
206
208{
209 return currentError(pa_stream_get_context(stream));
210}
211
212} // namespace QPulseAudioInternal
213
215{
216 using namespace Qt::StringLiterals;
217 switch (state)
218 {
219 case PA_STREAM_UNCONNECTED: return "Unconnected"_L1;
220 case PA_STREAM_CREATING: return "Creating"_L1;
221 case PA_STREAM_READY: return "Ready"_L1;
222 case PA_STREAM_FAILED: return "Failed"_L1;
223 case PA_STREAM_TERMINATED: return "Terminated"_L1;
224 default: Q_UNREACHABLE_RETURN("Unknown stream state"_L1);
225 }
226}
227
229{
230 using namespace Qt::StringLiterals;
231 switch (format)
232 {
233 case PA_SAMPLE_U8: return "Unsigned 8 Bit PCM."_L1;
234 case PA_SAMPLE_ALAW: return "8 Bit a-Law "_L1;
235 case PA_SAMPLE_ULAW: return "8 Bit mu-Law"_L1;
236 case PA_SAMPLE_S16LE: return "Signed 16 Bit PCM, little endian (PC)."_L1;
237 case PA_SAMPLE_S16BE: return "Signed 16 Bit PCM, big endian."_L1;
238 case PA_SAMPLE_FLOAT32LE: return "32 Bit IEEE floating point, little endian (PC), range -1.0 to 1.0"_L1;
239 case PA_SAMPLE_FLOAT32BE: return "32 Bit IEEE floating point, big endian, range -1.0 to 1.0"_L1;
240 case PA_SAMPLE_S32LE: return "Signed 32 Bit PCM, little endian (PC)."_L1;
241 case PA_SAMPLE_S32BE: return "Signed 32 Bit PCM, big endian."_L1;
242 case PA_SAMPLE_S24LE: return "Signed 24 Bit PCM packed, little endian (PC)."_L1;
243 case PA_SAMPLE_S24BE: return "Signed 24 Bit PCM packed, big endian."_L1;
244 case PA_SAMPLE_S24_32LE: return "Signed 24 Bit PCM in LSB of 32 Bit words, little endian (PC)."_L1;
245 case PA_SAMPLE_S24_32BE: return "Signed 24 Bit PCM in LSB of 32 Bit words, big endian."_L1;
246 case PA_SAMPLE_MAX: return "Upper limit of valid sample types."_L1;
247 case PA_SAMPLE_INVALID: return "Invalid sample format"_L1;
248 default: Q_UNREACHABLE_RETURN("Unknown sample format"_L1);
249 }
250}
251
253{
254 using namespace Qt::StringLiterals;
255 switch (state)
256 {
257 case PA_CONTEXT_UNCONNECTED: return "Unconnected"_L1;
258 case PA_CONTEXT_CONNECTING: return "Connecting"_L1;
259 case PA_CONTEXT_AUTHORIZING: return "Authorizing"_L1;
260 case PA_CONTEXT_SETTING_NAME: return "Setting Name"_L1;
261 case PA_CONTEXT_READY: return "Ready"_L1;
262 case PA_CONTEXT_FAILED: return "Failed"_L1;
263 case PA_CONTEXT_TERMINATED: return "Terminated"_L1;
264 default: Q_UNREACHABLE_RETURN("Unknown context state"_L1);
265 }
266}
267
268
269QDebug operator<<(QDebug dbg, pa_stream_state_t state)
270{
271 return dbg << stateToQStringView(state);
272}
273
274QDebug operator<<(QDebug dbg, pa_sample_format format)
275{
276 return dbg << sampleFormatToQStringView(format);
277}
278
279QDebug operator<<(QDebug dbg, pa_context_state_t state)
280{
281 return dbg << stateToQStringView(state);
282}
283
The QAudioFormat class stores audio stream parameter information.
constexpr void setSampleRate(int sampleRate) noexcept
Sets the sample rate to samplerate in Hertz.
static Q_MULTIMEDIA_EXPORT ChannelConfig defaultChannelConfigForChannelCount(int channelCount)
Returns a default channel configuration for channelCount.
SampleFormat
Qt will always expect and use samples in the endianness of the host platform.
constexpr ChannelConfig channelConfig() const noexcept
Returns the current channel configuration.
ChannelConfig
\variable QAudioFormat::NChannelPositions
\inmodule QtCore
@ BigEndian
Definition qsysinfo.h:29
@ ByteOrder
Definition qsysinfo.h:34
QMap< QString, QString > map
[6]
else opt state
[0]
QUtf8StringView currentError(const pa_context *context)
pa_channel_map channelMapForAudioFormat(const QAudioFormat &format)
QAudioFormat::ChannelConfig channelConfigFromMap(const pa_channel_map &map)
QAudioFormat sampleSpecToAudioFormat(const pa_sample_spec &spec)
pa_sample_spec audioFormatToSampleSpec(const QAudioFormat &format)
Combined button and popup list for selecting options.
Q_DECL_CONST_FUNCTION QT_POPCOUNT_CONSTEXPR uint qPopulationCount(quint32 v) noexcept
static void * context
EGLStreamKHR stream
EGLConfig config
#define Q_LOGGING_CATEGORY(name,...)
GLint GLsizei GLsizei GLenum format
GLenum GLenum GLenum input
static QLatin1StringView stateToQStringView(pa_stream_state_t state)
static QLatin1StringView sampleFormatToQStringView(pa_sample_format format)
QDebug operator<<(QDebug dbg, pa_stream_state_t state)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
unsigned int quint32
Definition qtypes.h:50
QJSEngine engine
[0]