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
qaudioformat.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 "qaudioformat.h"
5
6#include <QtCore/qdebug.h>
7
8QT_BEGIN_NAMESPACE
9
10/*!
11 \class QAudioFormat
12 \brief The QAudioFormat class stores audio stream parameter information.
13
14 \inmodule QtMultimedia
15 \ingroup multimedia
16 \ingroup multimedia_audio
17
18 An audio format specifies how data in a raw audio stream is arranged. For
19 example, how the stream is to be interpreted.
20
21 QAudioFormat contains parameters that specify how the audio sample data
22 is arranged. These are the frequency, the number of channels, and the
23 sample format. The following table describes these in more detail.
24
25 \table
26 \header
27 \li Parameter
28 \li Description
29 \row
30 \li Sample Rate
31 \li Samples per second of audio data in Hertz.
32 \row
33 \li Number of channels
34 \li The number of audio channels (typically one for mono
35 or two for stereo). These are the amount of consecutive
36 samples that together form one frame in the stream
37 \row
38 \li Sample format
39 \li The format of the audio samples in the stream
40 \endtable
41
42 This class is used in conjunction with QAudioSource or
43 QAudioSink to allow you to specify the parameters of the audio
44 stream being read or written, or with QAudioBuffer when dealing with
45 samples in memory.
46
47 You can obtain audio formats compatible with the audio device used
48 through functions in QAudioDevice. This class also lets you
49 query available parameter values for a device, so that you can set
50 the parameters yourself. See the \l QAudioDevice class
51 description for details. You need to know the format of the audio
52 streams you wish to play or record.
53
54 Samples for all channels will be interleaved.
55 One sample for each channel for the same instant in time is referred
56 to as a frame in Qt Multimedia (and other places).
57*/
58
59/*!
60 \fn QAudioFormat::QAudioFormat()
61
62 Constructs a new audio format.
63
64 Values are initialized as follows:
65 \list
66 \li sampleRate() = 0
67 \li channelCount() = 0
68 \li sampleFormat() = QAudioFormat::Unknown
69 \endlist
70*/
71
72/*!
73 \fn QAudioFormat::QAudioFormat(const QAudioFormat &other)
74
75 Construct a new audio format using \a other.
76*/
77
78/*!
79 \fn QAudioFormat::~QAudioFormat()
80
81 Destroy this audio format.
82*/
83
84/*!
85 \fn bool QAudioFormat::operator==(const QAudioFormat &a, const QAudioFormat &b)
86
87 Returns \c true if audio format \a a is equal to \a b, otherwise returns \c false.
88*/
89
90/*!
91 \fn bool QAudioFormat::operator!=(const QAudioFormat &a, const QAudioFormat &b)
92
93 Returns \c true if audio format \a a is not equal to \a b, otherwise returns \c false.
94*/
95
96/*!
97 \fn bool QAudioFormat::isValid() const
98
99 Returns \c true if all of the parameters are valid.
100*/
101
102/*!
103 \fn void QAudioFormat::setSampleRate(int samplerate)
104
105 Sets the sample rate to \a samplerate in Hertz.
106*/
107
108/*!
109 \fn int QAudioFormat::sampleRate() const
110
111 Returns the current sample rate in Hertz.
112*/
113
114/*!
115 \enum QAudioFormat::AudioChannelPosition
116
117 Describes the possible audio channel positions. These follow the standard
118 definition used in the 22.2 surround sound configuration.
119
120 \value UnknownPosition Unknown position
121 \value FrontLeft
122 \value FrontRight
123 \value FrontCenter
124 \value LFE Low Frequency Effect channel (Subwoofer)
125 \value BackLeft
126 \value BackRight
127 \value FrontLeftOfCenter
128 \value FrontRightOfCenter
129 \value BackCenter
130 \value LFE2
131 \value SideLeft
132 \value SideRight
133 \value TopFrontLeft
134 \value TopFrontRight
135 \value TopFrontCenter
136 \value TopCenter
137 \value TopBackLeft
138 \value TopBackRight
139 \value TopSideLeft
140 \value TopSideRight
141 \value TopBackCenter
142 \value BottomFrontCenter
143 \value BottomFrontLeft
144 \value BottomFrontRight
145*/
146/*!
147 \variable QAudioFormat::NChannelPositions
148 \internal
149*/
150
151/*!
152 \enum QAudioFormat::ChannelConfig
153
154 This enum describes a standardized audio channel layout. The most common
155 configurations are Mono, Stereo, 2.1 (stereo plus low frequency), 5.1 surround,
156 and 7.1 surround configurations.
157
158 \value ChannelConfigUnknown The channel configuration is not known.
159 \value ChannelConfigMono The audio has one Center channel.
160 \value ChannelConfigStereo The audio has two channels, Left and Right.
161 \value ChannelConfig2Dot1 The audio has three channels, Left, Right and
162 LFE (low frequency effect).
163 \value ChannelConfig3Dot0 The audio has three channels, Left, Right, and
164 Center.
165 \value ChannelConfig3Dot1 The audio has four channels, Left, Right, Center,
166 and LFE (low frequency effect).
167 \value ChannelConfigSurround5Dot0 The audio has five channels, Left, Right,
168 Center, BackLeft, and BackRight.
169 \value ChannelConfigSurround5Dot1 The audio has 6 channels, Left, Right,
170 Center, LFE, BackLeft, and BackRight.
171 \value ChannelConfigSurround7Dot0 The audio has 7 channels, Left, Right,
172 Center, BackLeft, BackRight, SideLeft, and SideRight.
173 \value ChannelConfigSurround7Dot1 The audio has 8 channels, Left, Right,
174 Center, LFE, BackLeft, BackRight, SideLeft, and SideRight.
175*/
176
177/*!
178 Sets the channel configuration to \a config.
179
180 Sets the channel configuration of the audio format to one of the standard
181 audio channel configurations.
182
183 \note that this will also modify the channel count.
184*/
185void QAudioFormat::setChannelConfig(ChannelConfig config) noexcept
186{
187 m_channelConfig = config;
188 if (config != ChannelConfigUnknown)
189 m_channelCount = qPopulationCount(config);
190}
191
192/*!
193 Returns the position of a certain audio \a channel inside an audio frame
194 for the given format.
195 Returns -1 if the channel does not exist for this format or the channel
196 configuration is unknown.
197*/
198int QAudioFormat::channelOffset(AudioChannelPosition channel) const noexcept
199{
200 if (!(m_channelConfig & (1u << channel)))
201 return -1;
202
203 uint maskedChannels = m_channelConfig & ((1u << channel) - 1);
204 return qPopulationCount(maskedChannels);
205}
206
207/*!
208 \fn void QAudioFormat::setChannelCount(int channels)
209
210 Sets the channel count to \a channels. Setting this also sets the channel
211 config to ChannelConfigUnknown.
212*/
213
214/*!
215 \fn template <typename... Args> QAudioFormat::ChannelConfig QAudioFormat::channelConfig(Args... channels)
216
217 Returns the current channel configuration for the given \a channels.
218*/
219/*!
220 \fn QAudioFormat::ChannelConfig QAudioFormat::channelConfig() const noexcept
221
222 Returns the current channel configuration.
223*/
224
225/*!
226 \fn int QAudioFormat::channelCount() const
227
228 Returns the current channel count value.
229
230*/
231
232/*!
233 \fn void QAudioFormat::setSampleFormat(SampleFormat format)
234
235 Sets the sample format to \a format.
236
237 \sa QAudioFormat::SampleFormat
238*/
239
240/*!
241 \fn QAudioFormat::SampleFormat QAudioFormat::sampleFormat() const
242 Returns the current sample format.
243
244 \sa setSampleFormat()
245*/
246
247/*!
248 Returns the number of bytes required for this audio format for \a microseconds.
249
250 Returns 0 if this format is not valid.
251
252 Note that some rounding may occur if \a microseconds is not an exact fraction of the
253 sampleRate().
254
255 \sa durationForBytes()
256 */
257qint32 QAudioFormat::bytesForDuration(qint64 microseconds) const
258{
259 return bytesPerFrame() * framesForDuration(microseconds);
260}
261
262/*!
263 Returns the number of microseconds represented by \a bytes in this format.
264
265 Returns 0 if this format is not valid.
266
267 Note that some rounding may occur if \a bytes is not an exact multiple
268 of the number of bytes per frame.
269
270 \sa bytesForDuration()
271*/
272qint64 QAudioFormat::durationForBytes(qint32 bytes) const
273{
274 if (!isValid() || bytes <= 0)
275 return 0;
276
277 // We round the byte count to ensure whole frames
278
279 const int bytesPerFrame = this->bytesPerFrame();
280 const int sampleRate = this->sampleRate();
281 Q_PRESUME(bytesPerFrame > 0);
282 Q_PRESUME(sampleRate > 0);
283 return qint64(1000000LL * (bytes / bytesPerFrame)) / sampleRate;
284}
285
286/*!
287 Returns the number of bytes required for \a frameCount frames of this format.
288
289 Returns 0 if this format is not valid.
290
291 \sa bytesForDuration()
292*/
293qint32 QAudioFormat::bytesForFrames(qint32 frameCount) const
294{
295 return frameCount * bytesPerFrame();
296}
297
298/*!
299 Returns the number of frames represented by \a byteCount in this format.
300
301 Note that some rounding may occur if \a byteCount is not an exact multiple
302 of the number of bytes per frame.
303
304 Each frame has one sample per channel.
305
306 \sa framesForDuration()
307*/
308qint32 QAudioFormat::framesForBytes(qint32 byteCount) const
309{
310 int size = bytesPerFrame();
311
312 // bitshifting to avoid integer division
313 switch (size) {
314 case 0:
315 return 0;
316 case 1:
317 return byteCount;
318 case 2:
319 return byteCount / 2;
320 case 4:
321 return byteCount / 4;
322 case 8:
323 return byteCount / 8;
324 case 16:
325 return byteCount / 16;
326 default:
327 return byteCount / size;
328 }
329}
330
331/*!
332 Returns the number of frames required to represent \a microseconds in this format.
333
334 Note that some rounding may occur if \a microseconds is not an exact fraction of the
335 \l sampleRate().
336*/
337qint32 QAudioFormat::framesForDuration(qint64 microseconds) const
338{
339 if (!isValid())
340 return 0;
341
342 return qint32((microseconds * sampleRate()) / 1000000LL);
343}
344
345/*!
346 Return the number of microseconds represented by \a frameCount frames in this format.
347*/
348qint64 QAudioFormat::durationForFrames(qint32 frameCount) const
349{
350 if (!isValid() || frameCount <= 0)
351 return 0;
352
353 return (frameCount * 1000000LL) / sampleRate();
354}
355
356/*!
357 \fn int QAudioFormat::bytesPerFrame() const
358
359 Returns the number of bytes required to represent one frame
360 (a sample in each channel) in this format.
361
362 Returns 0 if this format is invalid.
363*/
364
365/*!
366 \fn int QAudioFormat::bytesPerSample() const
367 Returns the number of bytes required to represent one sample in this format.
368
369 Returns 0 if this format is invalid.
370*/
371
372/*!
373 Normalizes the \a sample value to a number between -1 and 1.
374 The method depends on the QaudioFormat.
375*/
376float QAudioFormat::normalizedSampleValue(const void *sample) const
377{
378 switch (m_sampleFormat) {
379 case UInt8:
380 return ((float)*reinterpret_cast<const quint8 *>(sample))
381 / (float)std::numeric_limits<qint8>::max()
382 - 1.;
383 case Int16:
384 return ((float)*reinterpret_cast<const qint16 *>(sample))
385 / (float)std::numeric_limits<qint16>::max();
386 case Int32:
387 return ((float)*reinterpret_cast<const qint32 *>(sample))
388 / (float)std::numeric_limits<qint32>::max();
389 case Float:
390 return *reinterpret_cast<const float *>(sample);
391 case Unknown:
392 case NSampleFormats:
393 break;
394 }
395
396 return 0.;
397}
398
399/*!
400 Returns a default channel configuration for \a channelCount.
401
402 Default configurations are defined for up to 8 channels, and correspond to
403 standard Mono, Stereo and Surround configurations. For higher channel counts,
404 this simply uses the first \a channelCount audio channels defined in
405 \l QAudioFormat::AudioChannelPosition.
406*/
407QAudioFormat::ChannelConfig QAudioFormat::defaultChannelConfigForChannelCount(int channelCount)
408{
409 QAudioFormat::ChannelConfig config;
410 switch (channelCount) {
411 case 0:
412 config = QAudioFormat::ChannelConfigUnknown;
413 break;
414 case 1:
415 config = QAudioFormat::ChannelConfigMono;
416 break;
417 case 2:
418 config = QAudioFormat::ChannelConfigStereo;
419 break;
420 case 3:
421 config = QAudioFormat::ChannelConfig2Dot1;
422 break;
423 case 4:
424 config = QAudioFormat::channelConfig(QAudioFormat::FrontLeft, QAudioFormat::FrontRight,
425 QAudioFormat::BackLeft, QAudioFormat::BackRight);
426 break;
427 case 5:
428 config = QAudioFormat::ChannelConfigSurround5Dot0;
429 break;
430 case 6:
431 config = QAudioFormat::ChannelConfigSurround5Dot1;
432 break;
433 case 7:
434 config = QAudioFormat::ChannelConfigSurround7Dot0;
435 break;
436 case 8:
437 config = QAudioFormat::ChannelConfigSurround7Dot1;
438 break;
439 default:
440 // give up, simply use the first n channels
441 config = QAudioFormat::ChannelConfig(((1 << channelCount) - 1) << 1);
442 }
443 return config;
444}
445
446/*!
447 \enum QAudioFormat::SampleFormat
448
449 Qt will always expect and use samples in the endianness of the host platform.
450 When processing audio data from external sources yourself, ensure you convert
451 them to the correct endianness before writing them to a QAudioSink or
452 QAudioBuffer.
453
454 \value Unknown Not Set
455 \value UInt8 Samples are 8 bit unsigned integers
456 \value Int16 Samples are 16 bit signed integers
457 \value Int32 Samples are 32 bit signed integers
458 \value Float Samples are floats
459 \omitvalue NSampleFormats
460*/
461
462#ifndef QT_NO_DEBUG_STREAM
463QDebug operator<<(QDebug dbg, QAudioFormat::SampleFormat type)
464{
465 QDebugStateSaver saver(dbg);
466 dbg.nospace();
467 switch (type) {
468 case QAudioFormat::UInt8:
469 dbg << "UInt8";
470 break;
471 case QAudioFormat::Int16:
472 dbg << "Int16";
473 break;
474 case QAudioFormat::Int32:
475 dbg << "Int32";
476 break;
477 case QAudioFormat::Float:
478 dbg << "Float";
479 break;
480 default:
481 dbg << "Unknown";
482 break;
483 }
484 return dbg;
485}
486
487QDebug operator<<(QDebug dbg, const QAudioFormat &f)
488{
489 QDebugStateSaver s(dbg);
490 dbg.nospace();
491 dbg << "QAudioFormat(" << f.sampleRate() << "Hz, " << f.channelCount() << " Channels, "
492 << f.sampleFormat() << "Format)";
493 return dbg;
494}
495#endif
496
497QT_END_NAMESPACE